mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[Asset Manager] Creates baseline public asset client for use in public plugins (#167191)
Closes #167075
## Summary
Adds a public asset client available in the `setup` lifecycle hook for
plugins that depend on this one. `getHosts` is the only method available
on this client for now.
TODO, before merge:
- [x] Add docs for the server client
- [x] Add docs for the public client
- [x] Remove REST docs from plugin docs, not needed
- [x] Add unit tests for public client
### Testing this PR
One way of testing this new client is to apply the attached
test-assets.patch file locally, adjust the date range in the getHosts
query that is added in the infra plugin, and then start Kibana and
navigate to the infra app. You should see print out in the browser
console.
[test-assets.patch](12718693/test-assets.patch
)
---------
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
424dec613f
commit
859ae9e50d
42 changed files with 753 additions and 297 deletions
|
@ -451,8 +451,7 @@ The plugin exposes the static DefaultEditorController class to consume.
|
|||
|
||||
|
||||
|{kib-repo}blob/{branch}/x-pack/plugins/asset_manager/README.md[assetManager]
|
||||
|This plugin provides access to the asset data stored in assets-* indices, primarily
|
||||
for inventory and topology purposes.
|
||||
|This plugin provides access to observed asset data, such as information about hosts, pods, containers, services, and more.
|
||||
|
||||
|
||||
|{kib-repo}blob/{branch}/x-pack/plugins/banners/README.md[banners]
|
||||
|
|
|
@ -4,6 +4,7 @@ pageLoadAssetSize:
|
|||
aiops: 10000
|
||||
alerting: 106936
|
||||
apm: 64385
|
||||
assetManager: 25000
|
||||
banners: 17946
|
||||
bfetch: 22837
|
||||
canvas: 1066647
|
||||
|
|
|
@ -197,6 +197,7 @@ export default function ({ getService }: PluginFunctionalProviderContext) {
|
|||
'xpack.apm.featureFlags.sourcemapApiAvailable (any)',
|
||||
'xpack.apm.featureFlags.storageExplorerAvailable (any)',
|
||||
'xpack.apm.serverless.enabled (any)', // It's a boolean (any because schema.conditional)
|
||||
'xpack.assetManager.alphaEnabled (boolean)',
|
||||
'xpack.observability_onboarding.serverless.enabled (any)', // It's a boolean (any because schema.conditional)
|
||||
'xpack.cases.files.allowedMimeTypes (array)',
|
||||
'xpack.cases.files.maxSize (number)',
|
||||
|
|
|
@ -1,39 +1,13 @@
|
|||
# Asset Manager Plugin
|
||||
|
||||
This plugin provides access to the asset data stored in assets-\* indices, primarily
|
||||
for inventory and topology purposes.
|
||||
This plugin provides access to observed asset data, such as information about hosts, pods, containers, services, and more.
|
||||
|
||||
## Documentation
|
||||
|
||||
See [docs for the provided APIs in the docs folder](./docs/index.md).
|
||||
### User Docs
|
||||
|
||||
## Running Tests
|
||||
For those interested in making use of the APIs provided by this plugin, see [our API docs](./docs/api.md).
|
||||
|
||||
There are integration tests for the endpoints implemented thus far as well as for
|
||||
the sample data tests. There is also a small set of tests meant to ensure that the
|
||||
plugin is not doing anything without the proper config value in place to enable
|
||||
the plugin fully. For more on enabling the plugin, see [the docs page](./docs/index.md).
|
||||
### Developer Docs
|
||||
|
||||
The "not enabled" tests are run by default in CI. To run them manually, do the following:
|
||||
|
||||
```shell
|
||||
$ node scripts/functional_tests_server --config x-pack/test/api_integration/apis/asset_manager/config_when_disabled.ts
|
||||
$ node scripts/functional_test_runner --config=x-pack/test/api_integration/apis/asset_manager/config_when_disabled.ts
|
||||
```
|
||||
|
||||
The "enabled" tests are NOT run by CI yet, to prevent blocking Kibana development for a
|
||||
test failure in this alpha, tech preview plugin. They will be moved into the right place
|
||||
to make them run for CI before the plugin is enabled by default. To run them manually:
|
||||
|
||||
```shell
|
||||
$ node scripts/functional_tests_server --config x-pack/test/api_integration/apis/asset_manager/config.ts
|
||||
$ node scripts/functional_test_runner --config=x-pack/test/api_integration/apis/asset_manager/config.ts
|
||||
```
|
||||
|
||||
## Using Sample Data
|
||||
|
||||
This plugin comes with a full "working set" of sample asset documents, meant
|
||||
to provide enough data in the correct schema format so that all of the API
|
||||
endpoints return expected values.
|
||||
|
||||
To create the sample data, follow [the instructions in the REST API docs](./docs/index.md#sample-data).
|
||||
For those working on this plugin directly and developing it, please see [our development docs](./docs/development.md).
|
||||
|
|
56
x-pack/plugins/asset_manager/common/config.ts
Normal file
56
x-pack/plugins/asset_manager/common/config.ts
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { schema, TypeOf } from '@kbn/config-schema';
|
||||
|
||||
export const INDEX_DEFAULTS = {
|
||||
logs: 'filebeat-*,logs-*',
|
||||
};
|
||||
|
||||
export const configSchema = schema.object({
|
||||
alphaEnabled: schema.maybe(schema.boolean()),
|
||||
// Designate where various types of data live.
|
||||
// NOTE: this should be handled in a centralized way for observability, so
|
||||
// that when a user configures these differently from the known defaults,
|
||||
// that value is propagated everywhere. For now, we duplicate the value here.
|
||||
sourceIndices: schema.object(
|
||||
{
|
||||
logs: schema.string({ defaultValue: INDEX_DEFAULTS.logs }),
|
||||
},
|
||||
{ defaultValue: INDEX_DEFAULTS }
|
||||
),
|
||||
// Choose an explicit source for asset queries.
|
||||
// NOTE: This will eventually need to be able to cleverly switch
|
||||
// between these values based on the availability of data in the
|
||||
// indices, and possibly for each asset kind/type value.
|
||||
// For now, we set this explicitly.
|
||||
lockedSource: schema.oneOf([schema.literal('assets'), schema.literal('signals')], {
|
||||
defaultValue: 'signals',
|
||||
}),
|
||||
});
|
||||
|
||||
export type AssetManagerConfig = TypeOf<typeof configSchema>;
|
||||
|
||||
/**
|
||||
* The following map is passed to the server plugin setup under the
|
||||
* exposeToBrowser: option, and controls which of the above config
|
||||
* keys are allow-listed to be available in the browser config.
|
||||
*
|
||||
* NOTE: anything exposed here will be visible in the UI dev tools,
|
||||
* and therefore MUST NOT be anything that is sensitive information!
|
||||
*/
|
||||
export const exposeToBrowserConfig = {
|
||||
alphaEnabled: true,
|
||||
} as const;
|
||||
|
||||
type ValidKeys = keyof {
|
||||
[K in keyof typeof exposeToBrowserConfig as typeof exposeToBrowserConfig[K] extends true
|
||||
? K
|
||||
: never]: true;
|
||||
};
|
||||
|
||||
export type AssetManagerPublicConfig = Pick<AssetManagerConfig, ValidKeys>;
|
18
x-pack/plugins/asset_manager/common/constants_routes.ts
Normal file
18
x-pack/plugins/asset_manager/common/constants_routes.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
export const ASSET_MANAGER_API_BASE = '/api/asset-manager';
|
||||
|
||||
function base(path: string) {
|
||||
return `${ASSET_MANAGER_API_BASE}${path}`;
|
||||
}
|
||||
|
||||
export const GET_ASSETS = base('/assets');
|
||||
export const GET_RELATED_ASSETS = base('/assets/related');
|
||||
export const GET_ASSETS_DIFF = base('/assets/diff');
|
||||
|
||||
export const GET_HOSTS = base('/assets/hosts');
|
|
@ -6,77 +6,111 @@
|
|||
*/
|
||||
|
||||
import * as rt from 'io-ts';
|
||||
import {
|
||||
dateRt,
|
||||
inRangeFromStringRt,
|
||||
datemathStringRt,
|
||||
createLiteralValueFromUndefinedRT,
|
||||
} from '@kbn/io-ts-utils';
|
||||
|
||||
export const assetTypeRT = rt.union([
|
||||
rt.literal('k8s.pod'),
|
||||
rt.literal('k8s.cluster'),
|
||||
rt.literal('k8s.node'),
|
||||
]);
|
||||
export const assetTypeRT = rt.keyof({
|
||||
'k8s.pod': null,
|
||||
'k8s.cluster': null,
|
||||
'k8s.node': null,
|
||||
});
|
||||
|
||||
export type AssetType = rt.TypeOf<typeof assetTypeRT>;
|
||||
|
||||
export const assetKindRT = rt.union([
|
||||
rt.literal('cluster'),
|
||||
rt.literal('host'),
|
||||
rt.literal('pod'),
|
||||
rt.literal('container'),
|
||||
rt.literal('service'),
|
||||
rt.literal('alert'),
|
||||
]);
|
||||
export const assetKindRT = rt.keyof({
|
||||
cluster: null,
|
||||
host: null,
|
||||
pod: null,
|
||||
container: null,
|
||||
service: null,
|
||||
alert: null,
|
||||
});
|
||||
|
||||
export type AssetKind = rt.TypeOf<typeof assetKindRT>;
|
||||
|
||||
export type AssetStatus =
|
||||
| 'CREATING'
|
||||
| 'ACTIVE'
|
||||
| 'DELETING'
|
||||
| 'FAILED'
|
||||
| 'UPDATING'
|
||||
| 'PENDING'
|
||||
| 'UNKNOWN';
|
||||
export type CloudProviderName = 'aws' | 'gcp' | 'azure' | 'other' | 'unknown' | 'none';
|
||||
export const assetStatusRT = rt.keyof({
|
||||
CREATING: null,
|
||||
ACTIVE: null,
|
||||
DELETING: null,
|
||||
FAILED: null,
|
||||
UPDATING: null,
|
||||
PENDING: null,
|
||||
UNKNOWN: null,
|
||||
});
|
||||
|
||||
interface WithTimestamp {
|
||||
'@timestamp': string;
|
||||
}
|
||||
export interface ECSDocument extends WithTimestamp {
|
||||
'kubernetes.namespace'?: string;
|
||||
'kubernetes.pod.name'?: string;
|
||||
'kubernetes.pod.uid'?: string;
|
||||
'kubernetes.pod.start_time'?: Date;
|
||||
'kubernetes.node.name'?: string;
|
||||
'kubernetes.node.start_time'?: Date;
|
||||
export type AssetStatus = rt.TypeOf<typeof assetStatusRT>;
|
||||
|
||||
'orchestrator.api_version'?: string;
|
||||
'orchestrator.namespace'?: string;
|
||||
'orchestrator.organization'?: string;
|
||||
'orchestrator.type'?: string;
|
||||
'orchestrator.cluster.id'?: string;
|
||||
'orchestrator.cluster.name'?: string;
|
||||
'orchestrator.cluster.url'?: string;
|
||||
'orchestrator.cluster.version'?: string;
|
||||
// https://github.com/gcanti/io-ts/blob/master/index.md#union-of-string-literals
|
||||
export const cloudProviderNameRT = rt.keyof({
|
||||
aws: null,
|
||||
gcp: null,
|
||||
azure: null,
|
||||
other: null,
|
||||
unknown: null,
|
||||
none: null,
|
||||
});
|
||||
|
||||
'cloud.provider'?: CloudProviderName;
|
||||
'cloud.instance.id'?: string;
|
||||
'cloud.region'?: string;
|
||||
'cloud.service.name'?: string;
|
||||
export type CloudProviderName = rt.TypeOf<typeof cloudProviderNameRT>;
|
||||
|
||||
'service.environment'?: string;
|
||||
}
|
||||
const withTimestampRT = rt.type({
|
||||
'@timestamp': rt.string,
|
||||
});
|
||||
|
||||
export interface Asset extends ECSDocument {
|
||||
'asset.collection_version'?: string;
|
||||
'asset.ean': string;
|
||||
'asset.id': string;
|
||||
'asset.kind': AssetKind;
|
||||
'asset.name'?: string;
|
||||
'asset.type'?: AssetType;
|
||||
'asset.status'?: AssetStatus;
|
||||
'asset.parents'?: string | string[];
|
||||
'asset.children'?: string | string[];
|
||||
'asset.references'?: string | string[];
|
||||
'asset.namespace'?: string;
|
||||
}
|
||||
export type WithTimestamp = rt.TypeOf<typeof withTimestampRT>;
|
||||
|
||||
export const ECSDocumentRT = rt.intersection([
|
||||
withTimestampRT,
|
||||
rt.partial({
|
||||
'kubernetes.namespace': rt.string,
|
||||
'kubernetes.pod.name': rt.string,
|
||||
'kubernetes.pod.uid': rt.string,
|
||||
'kubernetes.pod.start_time': rt.string,
|
||||
'kubernetes.node.name': rt.string,
|
||||
'kubernetes.node.start_time': rt.string,
|
||||
'orchestrator.api_version': rt.string,
|
||||
'orchestrator.namespace': rt.string,
|
||||
'orchestrator.organization': rt.string,
|
||||
'orchestrator.type': rt.string,
|
||||
'orchestrator.cluster.id': rt.string,
|
||||
'orchestrator.cluster.name': rt.string,
|
||||
'orchestrator.cluster.url': rt.string,
|
||||
'orchestrator.cluster.version': rt.string,
|
||||
'cloud.provider': cloudProviderNameRT,
|
||||
'cloud.instance.id': rt.string,
|
||||
'cloud.region': rt.string,
|
||||
'cloud.service.name': rt.string,
|
||||
'service.environment': rt.string,
|
||||
}),
|
||||
]);
|
||||
|
||||
export type ECSDocument = rt.TypeOf<typeof ECSDocumentRT>;
|
||||
|
||||
export const assetRT = rt.intersection([
|
||||
ECSDocumentRT,
|
||||
rt.type({
|
||||
'asset.ean': rt.string,
|
||||
'asset.id': rt.string,
|
||||
'asset.kind': assetKindRT,
|
||||
}),
|
||||
// mixed required and optional require separate hashes combined via intersection
|
||||
// https://github.com/gcanti/io-ts/blob/master/index.md#mixing-required-and-optional-props
|
||||
rt.partial({
|
||||
'asset.collection_version': rt.string,
|
||||
'asset.name': rt.string,
|
||||
'asset.type': assetTypeRT,
|
||||
'asset.status': assetStatusRT,
|
||||
'asset.parents': rt.union([rt.string, rt.array(rt.string)]),
|
||||
'asset.children': rt.union([rt.string, rt.array(rt.string)]),
|
||||
'asset.references': rt.union([rt.string, rt.array(rt.string)]),
|
||||
'asset.namespace': rt.string,
|
||||
}),
|
||||
]);
|
||||
|
||||
export type Asset = rt.TypeOf<typeof assetRT>;
|
||||
|
||||
export type AssetWithoutTimestamp = Omit<Asset, '@timestamp'>;
|
||||
|
||||
|
@ -156,3 +190,22 @@ export type RelationField = keyof Pick<
|
|||
Asset,
|
||||
'asset.children' | 'asset.parents' | 'asset.references'
|
||||
>;
|
||||
|
||||
export const sizeRT = rt.union([
|
||||
inRangeFromStringRt(1, 100),
|
||||
createLiteralValueFromUndefinedRT(10),
|
||||
]);
|
||||
export const assetDateRT = rt.union([dateRt, datemathStringRt]);
|
||||
export const getHostAssetsQueryOptionsRT = rt.exact(
|
||||
rt.partial({
|
||||
from: assetDateRT,
|
||||
to: assetDateRT,
|
||||
size: sizeRT,
|
||||
})
|
||||
);
|
||||
export type GetHostAssetsQueryOptions = rt.TypeOf<typeof getHostAssetsQueryOptionsRT>;
|
||||
|
||||
export const getHostAssetsResponseRT = rt.type({
|
||||
hosts: rt.array(assetRT),
|
||||
});
|
||||
export type GetHostAssetsResponse = rt.TypeOf<typeof getHostAssetsResponseRT>;
|
||||
|
|
17
x-pack/plugins/asset_manager/common/types_client.ts
Normal file
17
x-pack/plugins/asset_manager/common/types_client.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
export interface GetHostsOptionsPublic {
|
||||
from: string;
|
||||
to: string;
|
||||
}
|
||||
|
||||
export interface GetServicesOptionsPublic {
|
||||
from: string;
|
||||
to: string;
|
||||
parent?: string;
|
||||
}
|
187
x-pack/plugins/asset_manager/docs/api.md
Normal file
187
x-pack/plugins/asset_manager/docs/api.md
Normal file
|
@ -0,0 +1,187 @@
|
|||
# Asset Manager API Documentation
|
||||
|
||||
## Plugin configuration
|
||||
|
||||
This plugin is NOT fully enabled by default, even though it's always enabled
|
||||
by Kibana's definition of "enabled". However, without the following configuration,
|
||||
it will bail before it sets up any routes or returns anything from its
|
||||
start, setup, or stop hooks.
|
||||
|
||||
To fully enable the plugin, set the following config values in your kibana.yml file:
|
||||
|
||||
```yaml
|
||||
xpack.assetManager:
|
||||
alphaEnabled: true
|
||||
```
|
||||
|
||||
## Depending on an asset client in your packages
|
||||
|
||||
If you're creating a shared UI component or tool that needs to access asset data, you
|
||||
can create that code in a stateless Kibana package that can itself be imported into
|
||||
any Kibana plugin without any dependency restrictions. To gain access to the asset data,
|
||||
this component or tool can require the appropriate asset client to be passed in.
|
||||
|
||||
TODO: need to move main client types to a package so that they can be depended on by
|
||||
other packages that require an injected asset client. Then we can list that package name
|
||||
here and explain how to use those types in a package.
|
||||
|
||||
## Client APIs
|
||||
|
||||
This plugin provides asset clients for Kibana server and public usage. The differences between these
|
||||
two clients are described below in their sections, while the methods for both APIs are described
|
||||
in the Client Methods section.
|
||||
|
||||
These clients are set up in the following way. For a given "methodA":
|
||||
|
||||
```
|
||||
publicMethodA(...options: MethodAPublicOptions)
|
||||
-> browser client calls corresponding REST API method with MethodAPublicOptions
|
||||
-> REST API handler calls corresponding serverMethodA
|
||||
-> serverMethodA requires MethodAPublicOptions & AssetClientDependencies, and it also
|
||||
injects some internal dependencies from the plugin's config on your behalf
|
||||
```
|
||||
|
||||
The public and server clientss are both accessible to plugin dependants, but the REST API is NOT.
|
||||
|
||||
### Required dependency setup
|
||||
|
||||
To use either client, you must first add "assetManager" to your `"requiredDependencies"` array
|
||||
in your plugin's kibana.jsonc file.
|
||||
|
||||
TECH PREVIEW NOTE: While this plugin is in "tech preview", in both the server and public clients,
|
||||
the provided plugin dependencies can be undefined for this plugin if the proper configuration
|
||||
has not been set (see above). For that reason, the types will force you to guard against this
|
||||
undefined scenario. Once the tech preview gating is removed, this will no longer be the case.
|
||||
|
||||
### Server client usage
|
||||
|
||||
In your plugin's `setup` method, you can gain access to the client from the injected `plugins` map.
|
||||
Make sure you import the `AssetManagerServerPluginSetup` type from the plugin's server
|
||||
directory and add it to your own SetupPlugins type, as seen below.
|
||||
|
||||
```ts
|
||||
import { AssetManagerServerPluginSetup } from '@kbn/assetManager-plugin/server';
|
||||
|
||||
interface MyPluginSetupDeps {
|
||||
assetManager: AssetManagerServerPluginSetup;
|
||||
}
|
||||
|
||||
class MyPlugin {
|
||||
setup(core: CoreSetup, plugins: MyPluginSetupDeps) {
|
||||
// assetClient is found on plugins.assetManager.assetClient
|
||||
setupRoutes(router, plugins);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To use the server client in your server routes, you can use something like this:
|
||||
|
||||
```ts
|
||||
export function setupRoutes(router: IRouter, plugins: MyPluginDeps) {
|
||||
router.get<unknown, MyRouteOptions, unknown>(
|
||||
{
|
||||
path: '/my/path',
|
||||
validate: {},
|
||||
},
|
||||
async (context, req, res) => {
|
||||
// handle route
|
||||
// optionally, use asset client
|
||||
// NOTE: see below for important info on required server client args
|
||||
const hosts = await plugins.assetManager.assetClient.getHosts();
|
||||
}
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
#### Required parameters for server client methods
|
||||
|
||||
All methods called via the server client require some core Kibana clients to be passed in,
|
||||
so that they are pulled from the request context and properly scoped. If the asset manager
|
||||
plugin provided these clients internally, they would not be scoped to the user that made
|
||||
the API request, so they are required arguments for every server client method.
|
||||
|
||||
_Note: These required arguments are referred to as `AssetClientDependencies`, which can be
|
||||
seen in the [the server types file](../server/types.ts)._
|
||||
|
||||
For example:
|
||||
|
||||
```ts
|
||||
router.get<unknown, MyRouteOptions, unknown>(
|
||||
{
|
||||
path: '/my/path',
|
||||
validate: {},
|
||||
},
|
||||
async (context, req, res) => {
|
||||
// to use server asset client, you must get the following clients
|
||||
// from the request context and pass them to the client method
|
||||
// alongside whatever "public" arguments that method defines
|
||||
const coreContext = await context.core;
|
||||
const hostsOptions: PublicGetHostsOptions = {}; // these will be different for each method
|
||||
|
||||
const hosts = await plugins.assetManager.assetClient.getHosts({
|
||||
...hostsOptions,
|
||||
elasticsearchClient: coreContext.elasticsearch.client.asCurrentUser,
|
||||
savedObjectsClient: coreContext.savedObjects.client,
|
||||
});
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
### Public client usage
|
||||
|
||||
You should grab the public client in the same way as the server one, via the plugin dependencies
|
||||
in your `setup` lifecycle.
|
||||
|
||||
```ts
|
||||
import { AssetManagerPublicPluginStart } from '@kbn/assetManager-plugin/public';
|
||||
|
||||
interface MyPluginStartDeps {
|
||||
assetManager: AssetManagerPublicPluginStart;
|
||||
}
|
||||
|
||||
class MyPlugin {
|
||||
setup(core: CoreSetup) {
|
||||
core.application.register({
|
||||
id: 'my-other-plugin',
|
||||
title: '',
|
||||
appRoute: '/app/my-other-plugin',
|
||||
mount: async (params: AppMountParameters) => {
|
||||
// mount callback should not use setup dependencies, get start dependencies instead
|
||||
// so the pluginStart map passed to your renderApp method will be the start deps,
|
||||
// not the setup deps -- the same asset client is provided to both setup and start in public
|
||||
const [coreStart, , pluginStart] = await core.getStartServices();
|
||||
// assetClient is found on pluginStart.assetManager.assetClient
|
||||
return renderApp(coreStart, pluginStart, params);
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
All methods in the public client only require their public options (seen below), and don't require
|
||||
the "AssetClientDependencies" that are required for the server client versions of the same methods.
|
||||
This is because the public client will use the asset manager's internal REST API under the hood, where
|
||||
it will be able to pull the properly-scoped client dependencies off of that request context for you.
|
||||
|
||||
### Client methods
|
||||
|
||||
#### getHosts
|
||||
|
||||
Get a group of host assets found within a specified time range.
|
||||
|
||||
| Parameter | Type | Required? | Description |
|
||||
| :-------- | :-------------- | :-------- | :--------------------------------------------------------------------- |
|
||||
| from | datetime string | yes | ISO date string representing the START of the time range being queried |
|
||||
| to | datetime string | yes | ISO date string representing the END of the time range being queried |
|
||||
|
||||
**Response**
|
||||
|
||||
```json
|
||||
{
|
||||
"hosts": [
|
||||
...found host assets
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
TODO: Link to a centralized asset document example that each response can reference?
|
34
x-pack/plugins/asset_manager/docs/development.md
Normal file
34
x-pack/plugins/asset_manager/docs/development.md
Normal file
|
@ -0,0 +1,34 @@
|
|||
# Asset Manager Plugin Development
|
||||
|
||||
These docs contain information you might need if you are developing this plugin in Kibana. If you are interested in the APIs this plugin exposes, please see [./api.md](our API docs) instead.
|
||||
|
||||
## Running Tests
|
||||
|
||||
There are integration tests for the endpoints implemented thus far as well as for
|
||||
the sample data tests. There is also a small set of tests meant to ensure that the
|
||||
plugin is not doing anything without the proper config value in place to enable
|
||||
the plugin fully. For more on enabling the plugin, see [the docs page](./docs/index.md).
|
||||
|
||||
The "not enabled" tests are run by default in CI. To run them manually, do the following:
|
||||
|
||||
```shell
|
||||
$ node scripts/functional_tests_server --config x-pack/test/api_integration/apis/asset_manager/config_when_disabled.ts
|
||||
$ node scripts/functional_test_runner --config=x-pack/test/api_integration/apis/asset_manager/config_when_disabled.ts
|
||||
```
|
||||
|
||||
The "enabled" tests are NOT run by CI yet, to prevent blocking Kibana development for a
|
||||
test failure in this alpha, tech preview plugin. They will be moved into the right place
|
||||
to make them run for CI before the plugin is enabled by default. To run them manually:
|
||||
|
||||
```shell
|
||||
$ node scripts/functional_tests_server --config x-pack/test/api_integration/apis/asset_manager/config.ts
|
||||
$ node scripts/functional_test_runner --config=x-pack/test/api_integration/apis/asset_manager/config.ts
|
||||
```
|
||||
|
||||
## Using Sample Data
|
||||
|
||||
This plugin comes with a full "working set" of sample asset documents, meant
|
||||
to provide enough data in the correct schema format so that all of the API
|
||||
endpoints return expected values.
|
||||
|
||||
To create the sample data, follow [the instructions in the REST API docs](./docs/index.md#sample-data).
|
|
@ -1,24 +1,6 @@
|
|||
# Asset Manager Documentation
|
||||
## Deprecated REST API docs
|
||||
|
||||
_Note:_ To read about development guidance around testing, sample data, etc., see the
|
||||
[plugin's main README file](../README.md)
|
||||
|
||||
## Alpha Configuration
|
||||
|
||||
This plugin is NOT fully enabled by default, even though it's always enabled
|
||||
by Kibana's definition of "enabled". However, without the following configuration,
|
||||
it will bail before it sets up any routes or returns anything from its
|
||||
start, setup, or stop hooks.
|
||||
|
||||
To fully enable the plugin, set the following config value in your kibana.yml file:
|
||||
|
||||
```yaml
|
||||
xpack.assetManager.alphaEnabled: true
|
||||
```
|
||||
|
||||
## APIs
|
||||
|
||||
This plugin provides the following APIs.
|
||||
These docs are not being currently maintained because they pertain to an internal REST API. Please see [our docs for our API clients](./api.md) instead.
|
||||
|
||||
### Shared Types
|
||||
|
||||
|
@ -58,16 +40,16 @@ Returns a list of assets present within a given time range. Can be limited by as
|
|||
|
||||
##### Request
|
||||
|
||||
| Option | Type | Required? | Default | Description |
|
||||
| :------ | :------------ | :-------- | :------ | :--------------------------------------------------------------------------------- |
|
||||
| from | RangeDate | No | "now-24h" | Starting point for date range to search for assets within |
|
||||
| to | RangeDate | No | "now" | End point for date range to search for assets |
|
||||
| type | AssetType[] | No | all | Specify one or more types to restrict the query |
|
||||
| ean | AssetEan[] | No | all | Specify one or more EANs (specific assets) to restrict the query |
|
||||
| size | number | No | all | Limit the amount of assets returned |
|
||||
|
||||
| Option | Type | Required? | Default | Description |
|
||||
| :----- | :---------- | :-------- | :-------- | :--------------------------------------------------------------- |
|
||||
| from | RangeDate | No | "now-24h" | Starting point for date range to search for assets within |
|
||||
| to | RangeDate | No | "now" | End point for date range to search for assets |
|
||||
| type | AssetType[] | No | all | Specify one or more types to restrict the query |
|
||||
| ean | AssetEan[] | No | all | Specify one or more EANs (specific assets) to restrict the query |
|
||||
| size | number | No | all | Limit the amount of assets returned |
|
||||
|
||||
_Notes:_
|
||||
|
||||
- User cannot specify both type and ean at the same time.
|
||||
- For array types such as `type` and `ean`, user should specify the query parameter multiple times, e.g. `type=k8s.pod&type=k8s.node`
|
||||
|
||||
|
@ -410,15 +392,15 @@ GET kbn:/api/asset-manager/assets?from=2023-03-25T17:44:44.000Z&to=2023-03-25T18
|
|||
|
||||
Returns assets found in the two time ranges, split by what occurs in only either or in both.
|
||||
|
||||
#### Request
|
||||
#### Request
|
||||
|
||||
| Option | Type | Required? | Default | Description |
|
||||
| :--- | :--- | :--- | :--- | :--- |
|
||||
| aFrom | RangeDate | Yes | N/A | Starting point for baseline date range to search for assets within |
|
||||
| aTo | RangeDate | Yes | N/A | End point for baseline date range to search for assets within |
|
||||
| bFrom | RangeDate | Yes | N/A | Starting point for comparison date range |
|
||||
| bTo | RangeDate | Yes | N/A | End point for comparison date range |
|
||||
| type | AssetType[] | No | all | Restrict results to one or more asset.type value |
|
||||
| Option | Type | Required? | Default | Description |
|
||||
| :----- | :---------- | :-------- | :------ | :----------------------------------------------------------------- |
|
||||
| aFrom | RangeDate | Yes | N/A | Starting point for baseline date range to search for assets within |
|
||||
| aTo | RangeDate | Yes | N/A | End point for baseline date range to search for assets within |
|
||||
| bFrom | RangeDate | Yes | N/A | Starting point for comparison date range |
|
||||
| bTo | RangeDate | Yes | N/A | End point for comparison date range |
|
||||
| type | AssetType[] | No | all | Restrict results to one or more asset.type value |
|
||||
|
||||
#### Responses
|
||||
|
||||
|
@ -1044,14 +1026,14 @@ Returns assets related to the provided ean. The relation can be one of ancestors
|
|||
|
||||
#### Request
|
||||
|
||||
| Option | Type | Required? | Default | Description |
|
||||
| :--- | :--- | :--- | :--- | :--- |
|
||||
| relation | string | Yes | N/A | The type of related assets we're looking for. One of (ancestors|descendants|references) |
|
||||
| from | RangeDate | Yes | N/A | Starting point for date range to search for assets within |
|
||||
| to | RangeDate | No | "now" | End point for date range to search for assets |
|
||||
| ean | AssetEan | Yes | N/A | Single Elastic Asset Name representing the asset for which the related assets are being requested |
|
||||
| type | AssetType[] | No | all | Restrict results to one or more asset.type value |
|
||||
| maxDistance | number (1-5) | No | 1 | Maximum number of "hops" to search away from specified asset |
|
||||
| Option | Type | Required? | Default | Description |
|
||||
| :---------- | :----------- | :-------- | :------ | :------------------------------------------------------------------------------------------------ | ----------- | ----------- |
|
||||
| relation | string | Yes | N/A | The type of related assets we're looking for. One of (ancestors | descendants | references) |
|
||||
| from | RangeDate | Yes | N/A | Starting point for date range to search for assets within |
|
||||
| to | RangeDate | No | "now" | End point for date range to search for assets |
|
||||
| ean | AssetEan | Yes | N/A | Single Elastic Asset Name representing the asset for which the related assets are being requested |
|
||||
| type | AssetType[] | No | all | Restrict results to one or more asset.type value |
|
||||
| maxDistance | number (1-5) | No | 1 | Maximum number of "hops" to search away from specified asset |
|
||||
|
||||
#### Responses
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
"apmDataAccess",
|
||||
"metricsDataAccess"
|
||||
],
|
||||
"browser": false,
|
||||
"browser": true,
|
||||
"server": true,
|
||||
"requiredBundles": [
|
||||
]
|
||||
|
|
20
x-pack/plugins/asset_manager/public/index.ts
Normal file
20
x-pack/plugins/asset_manager/public/index.ts
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { PluginInitializer, PluginInitializerContext } from '@kbn/core/public';
|
||||
import { Plugin } from './plugin';
|
||||
import { AssetManagerPublicPluginSetup, AssetManagerPublicPluginStart } from './types';
|
||||
|
||||
export const plugin: PluginInitializer<
|
||||
AssetManagerPublicPluginSetup | undefined,
|
||||
AssetManagerPublicPluginStart | undefined
|
||||
> = (context: PluginInitializerContext) => {
|
||||
return new Plugin(context);
|
||||
};
|
||||
|
||||
export type { AssetManagerPublicPluginSetup, AssetManagerPublicPluginStart };
|
||||
export type AssetManagerAppId = 'assetManager';
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { HttpSetupMock } from '@kbn/core-http-browser-mocks';
|
||||
import { coreMock } from '@kbn/core/public/mocks';
|
||||
import { PublicAssetsClient } from './public_assets_client';
|
||||
import * as routePaths from '../../common/constants_routes';
|
||||
|
||||
describe('Public assets client', () => {
|
||||
let http: HttpSetupMock = coreMock.createSetup().http;
|
||||
|
||||
beforeEach(() => {
|
||||
http = coreMock.createSetup().http;
|
||||
});
|
||||
|
||||
describe('class instantiation', () => {
|
||||
it('should successfully instantiate', () => {
|
||||
new PublicAssetsClient(http);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getHosts', () => {
|
||||
it('should call the REST API', async () => {
|
||||
const client = new PublicAssetsClient(http);
|
||||
await client.getHosts({ from: 'x', to: 'y' });
|
||||
expect(http.get).toBeCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should include specified "from" and "to" parameters in http.get query', async () => {
|
||||
const client = new PublicAssetsClient(http);
|
||||
await client.getHosts({ from: 'x', to: 'y' });
|
||||
expect(http.get).toBeCalledWith(routePaths.GET_HOSTS, {
|
||||
query: { from: 'x', to: 'y' },
|
||||
});
|
||||
});
|
||||
|
||||
it('should return the direct results of http.get', async () => {
|
||||
const client = new PublicAssetsClient(http);
|
||||
http.get.mockResolvedValueOnce('my result');
|
||||
const result = await client.getHosts({ from: 'x', to: 'y' });
|
||||
expect(result).toBe('my result');
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { HttpStart } from '@kbn/core/public';
|
||||
import { GetHostsOptionsPublic } from '../../common/types_client';
|
||||
import { GetHostAssetsResponse } from '../../common/types_api';
|
||||
import { GET_HOSTS } from '../../common/constants_routes';
|
||||
import { IPublicAssetsClient } from '../types';
|
||||
|
||||
export class PublicAssetsClient implements IPublicAssetsClient {
|
||||
constructor(private readonly http: HttpStart) {}
|
||||
|
||||
async getHosts(options: GetHostsOptionsPublic) {
|
||||
const results = await this.http.get<GetHostAssetsResponse>(GET_HOSTS, {
|
||||
query: {
|
||||
...options,
|
||||
},
|
||||
});
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
51
x-pack/plugins/asset_manager/public/plugin.ts
Normal file
51
x-pack/plugins/asset_manager/public/plugin.ts
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { CoreSetup, CoreStart, PluginInitializerContext } from '@kbn/core/public';
|
||||
import { Logger } from '@kbn/logging';
|
||||
import { AssetManagerPluginClass } from './types';
|
||||
import { PublicAssetsClient } from './lib/public_assets_client';
|
||||
import type { AssetManagerPublicConfig } from '../common/config';
|
||||
|
||||
export class Plugin implements AssetManagerPluginClass {
|
||||
public config: AssetManagerPublicConfig;
|
||||
public logger: Logger;
|
||||
|
||||
constructor(context: PluginInitializerContext<{}>) {
|
||||
this.config = context.config.get();
|
||||
this.logger = context.logger.get();
|
||||
}
|
||||
|
||||
setup(core: CoreSetup) {
|
||||
// Check for config value and bail out if not "alpha-enabled"
|
||||
if (!this.config.alphaEnabled) {
|
||||
this.logger.debug('Public is NOT enabled');
|
||||
return;
|
||||
}
|
||||
|
||||
this.logger.debug('Public is enabled');
|
||||
|
||||
const publicAssetsClient = new PublicAssetsClient(core.http);
|
||||
return {
|
||||
publicAssetsClient,
|
||||
};
|
||||
}
|
||||
|
||||
start(core: CoreStart) {
|
||||
// Check for config value and bail out if not "alpha-enabled"
|
||||
if (!this.config.alphaEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
const publicAssetsClient = new PublicAssetsClient(core.http);
|
||||
return {
|
||||
publicAssetsClient,
|
||||
};
|
||||
}
|
||||
|
||||
stop() {}
|
||||
}
|
25
x-pack/plugins/asset_manager/public/types.ts
Normal file
25
x-pack/plugins/asset_manager/public/types.ts
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
import type { Plugin as PluginClass } from '@kbn/core/public';
|
||||
import { GetHostsOptionsPublic } from '../common/types_client';
|
||||
import { GetHostAssetsResponse } from '../common/types_api';
|
||||
export interface AssetManagerPublicPluginSetup {
|
||||
publicAssetsClient: IPublicAssetsClient;
|
||||
}
|
||||
|
||||
export interface AssetManagerPublicPluginStart {
|
||||
publicAssetsClient: IPublicAssetsClient;
|
||||
}
|
||||
|
||||
export type AssetManagerPluginClass = PluginClass<
|
||||
AssetManagerPublicPluginSetup | undefined,
|
||||
AssetManagerPublicPluginStart | undefined
|
||||
>;
|
||||
|
||||
export interface IPublicAssetsClient {
|
||||
getHosts: (options: GetHostsOptionsPublic) => Promise<GetHostAssetsResponse>;
|
||||
}
|
|
@ -6,4 +6,3 @@
|
|||
*/
|
||||
|
||||
export const ASSETS_INDEX_PREFIX = 'assets';
|
||||
export const ASSET_MANAGER_API_BASE = '/api/asset-manager';
|
||||
|
|
|
@ -6,11 +6,21 @@
|
|||
*/
|
||||
|
||||
import { PluginInitializerContext } from '@kbn/core-plugins-server';
|
||||
import { AssetManagerServerPlugin, config } from './plugin';
|
||||
import { AssetManagerConfig } from '../common/config';
|
||||
import {
|
||||
AssetManagerServerPlugin,
|
||||
AssetManagerServerPluginSetup,
|
||||
AssetManagerServerPluginStart,
|
||||
config,
|
||||
} from './plugin';
|
||||
import type { WriteSamplesPostBody } from './routes/sample_assets';
|
||||
import { AssetManagerConfig } from './types';
|
||||
|
||||
export type { AssetManagerConfig, WriteSamplesPostBody };
|
||||
export type {
|
||||
AssetManagerConfig,
|
||||
WriteSamplesPostBody,
|
||||
AssetManagerServerPluginSetup,
|
||||
AssetManagerServerPluginStart,
|
||||
};
|
||||
export { config };
|
||||
|
||||
export const plugin = (context: PluginInitializerContext<AssetManagerConfig>) =>
|
||||
|
|
|
@ -13,7 +13,7 @@ export async function getHostsByAssets(
|
|||
options: GetHostsOptionsInjected
|
||||
): Promise<{ hosts: Asset[] }> {
|
||||
const hosts = await getAssets({
|
||||
esClient: options.esClient,
|
||||
elasticsearchClient: options.elasticsearchClient,
|
||||
filters: {
|
||||
kind: 'host',
|
||||
from: options.from,
|
||||
|
|
|
@ -13,11 +13,11 @@ export async function getHostsBySignals(
|
|||
options: GetHostsOptionsInjected
|
||||
): Promise<{ hosts: Asset[] }> {
|
||||
const metricsIndices = await options.metricsClient.getMetricIndices({
|
||||
savedObjectsClient: options.soClient,
|
||||
savedObjectsClient: options.savedObjectsClient,
|
||||
});
|
||||
|
||||
const { assets } = await collectHosts({
|
||||
client: options.esClient,
|
||||
client: options.elasticsearchClient,
|
||||
from: options.from,
|
||||
to: options.to,
|
||||
sourceIndices: {
|
||||
|
|
|
@ -5,12 +5,11 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { AccessorOptions, OptionsWithInjectedValues } from '..';
|
||||
import type { AssetClientDependencies } from '../../../types';
|
||||
import type { GetHostsOptionsPublic } from '../../../../common/types_client';
|
||||
import type { OptionsWithInjectedValues } from '..';
|
||||
|
||||
export interface GetHostsOptions extends AccessorOptions {
|
||||
from: string;
|
||||
to: string;
|
||||
}
|
||||
export type GetHostsOptions = GetHostsOptionsPublic & AssetClientDependencies;
|
||||
export type GetHostsOptionsInjected = OptionsWithInjectedValues<GetHostsOptions>;
|
||||
|
||||
export interface HostIdentifier {
|
||||
|
|
|
@ -5,11 +5,10 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
|
||||
import { APMDataAccessConfig } from '@kbn/apm-data-access-plugin/server';
|
||||
import { MetricsDataClient } from '@kbn/metrics-data-access-plugin/server';
|
||||
import { SavedObjectsClientContract } from '@kbn/core/server';
|
||||
import { AssetManagerConfig } from '../../types';
|
||||
import { AssetManagerConfig } from '../../../common/config';
|
||||
|
||||
export interface InjectedValues {
|
||||
sourceIndices: AssetManagerConfig['sourceIndices'];
|
||||
|
@ -18,8 +17,3 @@ export interface InjectedValues {
|
|||
}
|
||||
|
||||
export type OptionsWithInjectedValues<T extends object> = T & InjectedValues;
|
||||
|
||||
export interface AccessorOptions {
|
||||
esClient: ElasticsearchClient;
|
||||
soClient: SavedObjectsClientContract;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ export async function getServicesByAssets(
|
|||
}
|
||||
|
||||
const services = await getAssets({
|
||||
esClient: options.esClient,
|
||||
elasticsearchClient: options.elasticsearchClient,
|
||||
filters: {
|
||||
kind: 'service',
|
||||
from: options.from,
|
||||
|
@ -32,7 +32,7 @@ export async function getServicesByAssets(
|
|||
async function getServicesByParent(
|
||||
options: GetServicesOptionsInjected
|
||||
): Promise<{ services: Asset[] }> {
|
||||
const { descendants } = await getAllRelatedAssets(options.esClient, {
|
||||
const { descendants } = await getAllRelatedAssets(options.elasticsearchClient, {
|
||||
from: options.from,
|
||||
to: options.to,
|
||||
maxDistance: 5,
|
||||
|
|
|
@ -26,9 +26,9 @@ export async function getServicesBySignals(
|
|||
});
|
||||
}
|
||||
|
||||
const apmIndices = await options.getApmIndices(options.soClient);
|
||||
const apmIndices = await options.getApmIndices(options.savedObjectsClient);
|
||||
const { assets } = await collectServices({
|
||||
client: options.esClient,
|
||||
client: options.elasticsearchClient,
|
||||
from: options.from,
|
||||
to: options.to,
|
||||
sourceIndices: {
|
||||
|
|
|
@ -5,13 +5,11 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { AccessorOptions, OptionsWithInjectedValues } from '..';
|
||||
import { AssetClientDependencies } from '../../../types';
|
||||
import { GetServicesOptionsPublic } from '../../../../common/types_client';
|
||||
import { OptionsWithInjectedValues } from '..';
|
||||
|
||||
export interface GetServicesOptions extends AccessorOptions {
|
||||
from: string;
|
||||
to: string;
|
||||
parent?: string;
|
||||
}
|
||||
export type GetServicesOptions = GetServicesOptionsPublic & AssetClientDependencies;
|
||||
export type GetServicesOptionsInjected = OptionsWithInjectedValues<GetServicesOptions>;
|
||||
|
||||
export interface ServiceIdentifier {
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
import { APMDataAccessConfig } from '@kbn/apm-data-access-plugin/server';
|
||||
import { MetricsDataClient } from '@kbn/metrics-data-access-plugin/server';
|
||||
import { SavedObjectsClientContract } from '@kbn/core/server';
|
||||
import { AssetManagerConfig } from '../../common/config';
|
||||
import { Asset } from '../../common/types_api';
|
||||
import { AssetManagerConfig } from '../types';
|
||||
import { OptionsWithInjectedValues } from './accessors';
|
||||
import { GetHostsOptions } from './accessors/hosts';
|
||||
import { GetServicesOptions } from './accessors/services';
|
||||
|
@ -18,28 +18,28 @@ import { getHostsBySignals } from './accessors/hosts/get_hosts_by_signals';
|
|||
import { getServicesByAssets } from './accessors/services/get_services_by_assets';
|
||||
import { getServicesBySignals } from './accessors/services/get_services_by_signals';
|
||||
|
||||
interface AssetAccessorClassOptions {
|
||||
interface AssetClientClassOptions {
|
||||
sourceIndices: AssetManagerConfig['sourceIndices'];
|
||||
source: AssetManagerConfig['lockedSource'];
|
||||
getApmIndices: (soClient: SavedObjectsClientContract) => Promise<APMDataAccessConfig['indices']>;
|
||||
metricsClient: MetricsDataClient;
|
||||
}
|
||||
|
||||
export class AssetAccessor {
|
||||
constructor(private options: AssetAccessorClassOptions) {}
|
||||
export class AssetClient {
|
||||
constructor(private baseOptions: AssetClientClassOptions) {}
|
||||
|
||||
injectOptions<T extends object = {}>(options: T): OptionsWithInjectedValues<T> {
|
||||
return {
|
||||
...options,
|
||||
sourceIndices: this.options.sourceIndices,
|
||||
getApmIndices: this.options.getApmIndices,
|
||||
metricsClient: this.options.metricsClient,
|
||||
sourceIndices: this.baseOptions.sourceIndices,
|
||||
getApmIndices: this.baseOptions.getApmIndices,
|
||||
metricsClient: this.baseOptions.metricsClient,
|
||||
};
|
||||
}
|
||||
|
||||
async getHosts(options: GetHostsOptions): Promise<{ hosts: Asset[] }> {
|
||||
const withInjected = this.injectOptions(options);
|
||||
if (this.options.source === 'assets') {
|
||||
if (this.baseOptions.source === 'assets') {
|
||||
return await getHostsByAssets(withInjected);
|
||||
} else {
|
||||
return await getHostsBySignals(withInjected);
|
||||
|
@ -48,7 +48,7 @@ export class AssetAccessor {
|
|||
|
||||
async getServices(options: GetServicesOptions): Promise<{ services: Asset[] }> {
|
||||
const withInjected = this.injectOptions(options);
|
||||
if (this.options.source === 'assets') {
|
||||
if (this.baseOptions.source === 'assets') {
|
||||
return await getServicesByAssets(withInjected);
|
||||
} else {
|
||||
return await getServicesBySignals(withInjected);
|
|
@ -26,13 +26,13 @@ interface GetAllRelatedAssetsOptions {
|
|||
}
|
||||
|
||||
export async function getAllRelatedAssets(
|
||||
esClient: ElasticsearchClient,
|
||||
elasticsearchClient: ElasticsearchClient,
|
||||
options: GetAllRelatedAssetsOptions
|
||||
) {
|
||||
// How to put size into this?
|
||||
const { ean, from, to, relation, maxDistance, kind = [] } = options;
|
||||
|
||||
const primary = await findPrimary(esClient, { ean, from, to });
|
||||
const primary = await findPrimary(elasticsearchClient, { ean, from, to });
|
||||
|
||||
let assetsToFetch = [primary];
|
||||
let currentDistance = 1;
|
||||
|
@ -52,7 +52,7 @@ export async function getAllRelatedAssets(
|
|||
|
||||
const results = flatten(
|
||||
await Promise.all(
|
||||
assetsToFetch.map((asset) => findRelatedAssets(esClient, asset, queryOptions))
|
||||
assetsToFetch.map((asset) => findRelatedAssets(elasticsearchClient, asset, queryOptions))
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -75,11 +75,11 @@ export async function getAllRelatedAssets(
|
|||
}
|
||||
|
||||
async function findPrimary(
|
||||
esClient: ElasticsearchClient,
|
||||
elasticsearchClient: ElasticsearchClient,
|
||||
{ ean, from, to }: Pick<GetAllRelatedAssetsOptions, 'ean' | 'from' | 'to'>
|
||||
): Promise<Asset> {
|
||||
const primaryResults = await getAssets({
|
||||
esClient,
|
||||
elasticsearchClient,
|
||||
size: 1,
|
||||
filters: { ean, from, to },
|
||||
});
|
||||
|
@ -101,7 +101,7 @@ type FindRelatedAssetsOptions = Pick<
|
|||
> & { visitedEans: string[] };
|
||||
|
||||
async function findRelatedAssets(
|
||||
esClient: ElasticsearchClient,
|
||||
elasticsearchClient: ElasticsearchClient,
|
||||
primary: Asset,
|
||||
{ relation, from, to, kind, visitedEans }: FindRelatedAssetsOptions
|
||||
): Promise<Asset[]> {
|
||||
|
@ -116,7 +116,7 @@ async function findRelatedAssets(
|
|||
const remainingEansToFind = without(directlyRelatedEans, ...visitedEans);
|
||||
if (remainingEansToFind.length > 0) {
|
||||
directlyRelatedAssets = await getAssets({
|
||||
esClient,
|
||||
elasticsearchClient,
|
||||
filters: { ean: remainingEansToFind, from, to, kind },
|
||||
});
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ async function findRelatedAssets(
|
|||
debug('Directly related assets found:', JSON.stringify(directlyRelatedAssets));
|
||||
|
||||
const indirectlyRelatedAssets = await getIndirectlyRelatedAssets({
|
||||
esClient,
|
||||
elasticsearchClient,
|
||||
ean: primary['asset.ean'],
|
||||
excludeEans: visitedEans.concat(directlyRelatedEans),
|
||||
relation,
|
||||
|
|
|
@ -19,7 +19,7 @@ interface GetAssetsOptions extends ElasticsearchAccessorOptions {
|
|||
}
|
||||
|
||||
export async function getAssets({
|
||||
esClient,
|
||||
elasticsearchClient,
|
||||
size = 100,
|
||||
filters = {},
|
||||
}: GetAssetsOptions): Promise<Asset[]> {
|
||||
|
@ -125,6 +125,6 @@ export async function getAssets({
|
|||
|
||||
debug('Performing Get Assets Query', '\n\n', JSON.stringify(dsl, null, 2));
|
||||
|
||||
const response = await esClient.search<Asset>(dsl);
|
||||
const response = await elasticsearchClient.search<Asset>(dsl);
|
||||
return response.hits.hits.map((hit) => hit._source).filter((asset): asset is Asset => !!asset);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ interface GetRelatedAssetsOptions extends ElasticsearchAccessorOptions {
|
|||
}
|
||||
|
||||
export async function getIndirectlyRelatedAssets({
|
||||
esClient,
|
||||
elasticsearchClient,
|
||||
size = 100,
|
||||
from = 'now-24h',
|
||||
to = 'now',
|
||||
|
@ -91,7 +91,7 @@ export async function getIndirectlyRelatedAssets({
|
|||
|
||||
debug('Performing Indirectly Related Asset Query', '\n\n', JSON.stringify(dsl, null, 2));
|
||||
|
||||
const response = await esClient.search<Asset>(dsl);
|
||||
const response = await elasticsearchClient.search<Asset>(dsl);
|
||||
return response.hits.hits.map((hit) => hit._source).filter((asset): asset is Asset => !!asset);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ interface WriteAssetsOptions extends ElasticsearchAccessorOptions {
|
|||
}
|
||||
|
||||
export async function writeAssets({
|
||||
esClient,
|
||||
elasticsearchClient,
|
||||
assetDocs,
|
||||
namespace = 'default',
|
||||
refresh = false,
|
||||
|
@ -33,5 +33,5 @@ export async function writeAssets({
|
|||
|
||||
debug('Performing Write Asset Query', '\n\n', JSON.stringify(dsl, null, 2));
|
||||
|
||||
return await esClient.bulk<{}>(dsl);
|
||||
return await elasticsearchClient.bulk<{}>(dsl);
|
||||
}
|
||||
|
|
|
@ -18,15 +18,16 @@ import {
|
|||
import { upsertTemplate } from './lib/manage_index_templates';
|
||||
import { setupRoutes } from './routes';
|
||||
import { assetsIndexTemplateConfig } from './templates/assets_template';
|
||||
import { AssetManagerConfig, configSchema } from './types';
|
||||
import { AssetAccessor } from './lib/asset_accessor';
|
||||
import { AssetClient } from './lib/asset_client';
|
||||
import { AssetManagerPluginSetupDependencies, AssetManagerPluginStartDependencies } from './types';
|
||||
import { AssetManagerConfig, configSchema, exposeToBrowserConfig } from '../common/config';
|
||||
|
||||
export type AssetManagerServerPluginSetup = ReturnType<AssetManagerServerPlugin['setup']>;
|
||||
export type AssetManagerServerPluginStart = ReturnType<AssetManagerServerPlugin['start']>;
|
||||
|
||||
export const config: PluginConfigDescriptor<AssetManagerConfig> = {
|
||||
schema: configSchema,
|
||||
exposeToBrowser: exposeToBrowserConfig,
|
||||
};
|
||||
|
||||
export class AssetManagerServerPlugin
|
||||
|
@ -49,13 +50,13 @@ export class AssetManagerServerPlugin
|
|||
public setup(core: CoreSetup, plugins: AssetManagerPluginSetupDependencies) {
|
||||
// Check for config value and bail out if not "alpha-enabled"
|
||||
if (!this.config.alphaEnabled) {
|
||||
this.logger.info('Asset manager plugin [tech preview] is NOT enabled');
|
||||
this.logger.info('Server is NOT enabled');
|
||||
return;
|
||||
}
|
||||
|
||||
this.logger.info('Asset manager plugin [tech preview] is enabled');
|
||||
this.logger.info('Server is enabled');
|
||||
|
||||
const assetAccessor = new AssetAccessor({
|
||||
const assetClient = new AssetClient({
|
||||
source: this.config.lockedSource,
|
||||
sourceIndices: this.config.sourceIndices,
|
||||
getApmIndices: plugins.apmDataAccess.getApmIndices,
|
||||
|
@ -63,10 +64,10 @@ export class AssetManagerServerPlugin
|
|||
});
|
||||
|
||||
const router = core.http.createRouter();
|
||||
setupRoutes<RequestHandlerContext>({ router, assetAccessor });
|
||||
setupRoutes<RequestHandlerContext>({ router, assetClient });
|
||||
|
||||
return {
|
||||
assetAccessor,
|
||||
assetClient,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -5,56 +5,37 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import * as rt from 'io-ts';
|
||||
import datemath from '@kbn/datemath';
|
||||
import {
|
||||
dateRt,
|
||||
inRangeFromStringRt,
|
||||
datemathStringRt,
|
||||
createRouteValidationFunction,
|
||||
createLiteralValueFromUndefinedRT,
|
||||
} from '@kbn/io-ts-utils';
|
||||
import { createRouteValidationFunction } from '@kbn/io-ts-utils';
|
||||
import { RequestHandlerContext } from '@kbn/core-http-request-handler-context-server';
|
||||
import { GetHostAssetsQueryOptions, getHostAssetsQueryOptionsRT } from '../../../common/types_api';
|
||||
import { debug } from '../../../common/debug_log';
|
||||
import { SetupRouteOptions } from '../types';
|
||||
import { ASSET_MANAGER_API_BASE } from '../../constants';
|
||||
import { getEsClientFromContext } from '../utils';
|
||||
|
||||
const sizeRT = rt.union([inRangeFromStringRt(1, 100), createLiteralValueFromUndefinedRT(10)]);
|
||||
const assetDateRT = rt.union([dateRt, datemathStringRt]);
|
||||
const getHostAssetsQueryOptionsRT = rt.exact(
|
||||
rt.partial({
|
||||
from: assetDateRT,
|
||||
to: assetDateRT,
|
||||
size: sizeRT,
|
||||
})
|
||||
);
|
||||
|
||||
export type GetHostAssetsQueryOptions = rt.TypeOf<typeof getHostAssetsQueryOptionsRT>;
|
||||
import * as routePaths from '../../../common/constants_routes';
|
||||
import { getClientsFromContext } from '../utils';
|
||||
|
||||
export function hostsRoutes<T extends RequestHandlerContext>({
|
||||
router,
|
||||
assetAccessor,
|
||||
assetClient,
|
||||
}: SetupRouteOptions<T>) {
|
||||
router.get<unknown, GetHostAssetsQueryOptions, unknown>(
|
||||
{
|
||||
path: `${ASSET_MANAGER_API_BASE}/assets/hosts`,
|
||||
path: routePaths.GET_HOSTS,
|
||||
validate: {
|
||||
query: createRouteValidationFunction(getHostAssetsQueryOptionsRT),
|
||||
},
|
||||
},
|
||||
async (context, req, res) => {
|
||||
const { from = 'now-24h', to = 'now' } = req.query || {};
|
||||
const esClient = await getEsClientFromContext(context);
|
||||
const coreContext = await context.core;
|
||||
const soClient = coreContext.savedObjects.client;
|
||||
|
||||
const { elasticsearchClient, savedObjectsClient } = await getClientsFromContext(context);
|
||||
|
||||
try {
|
||||
const response = await assetAccessor.getHosts({
|
||||
const response = await assetClient.getHosts({
|
||||
from: datemath.parse(from)!.toISOString(),
|
||||
to: datemath.parse(to)!.toISOString(),
|
||||
esClient,
|
||||
soClient,
|
||||
elasticsearchClient,
|
||||
savedObjectsClient,
|
||||
});
|
||||
|
||||
return res.ok({ body: response });
|
||||
|
|
|
@ -17,11 +17,11 @@ import {
|
|||
} from '@kbn/io-ts-utils';
|
||||
import { debug } from '../../../common/debug_log';
|
||||
import { assetTypeRT, assetKindRT, relationRT } from '../../../common/types_api';
|
||||
import { ASSET_MANAGER_API_BASE } from '../../constants';
|
||||
import { GET_ASSETS, GET_RELATED_ASSETS, GET_ASSETS_DIFF } from '../../../common/constants_routes';
|
||||
import { getAssets } from '../../lib/get_assets';
|
||||
import { getAllRelatedAssets } from '../../lib/get_all_related_assets';
|
||||
import { SetupRouteOptions } from '../types';
|
||||
import { getEsClientFromContext } from '../utils';
|
||||
import { getClientsFromContext } from '../utils';
|
||||
import { AssetNotFoundError } from '../../lib/errors';
|
||||
import { isValidRange } from '../../lib/utils';
|
||||
|
||||
|
@ -82,7 +82,7 @@ export function assetsRoutes<T extends RequestHandlerContext>({ router }: SetupR
|
|||
// GET /assets
|
||||
router.get<unknown, GetAssetsQueryOptions, unknown>(
|
||||
{
|
||||
path: `${ASSET_MANAGER_API_BASE}/assets`,
|
||||
path: GET_ASSETS,
|
||||
validate: {
|
||||
query: createRouteValidationFunction(getAssetsQueryOptionsRT),
|
||||
},
|
||||
|
@ -102,10 +102,10 @@ export function assetsRoutes<T extends RequestHandlerContext>({ router }: SetupR
|
|||
});
|
||||
}
|
||||
|
||||
const esClient = await getEsClientFromContext(context);
|
||||
const { elasticsearchClient } = await getClientsFromContext(context);
|
||||
|
||||
try {
|
||||
const results = await getAssets({ esClient, size, filters });
|
||||
const results = await getAssets({ elasticsearchClient, size, filters });
|
||||
return res.ok({ body: { results } });
|
||||
} catch (error: unknown) {
|
||||
debug('error looking up asset records', error);
|
||||
|
@ -120,7 +120,7 @@ export function assetsRoutes<T extends RequestHandlerContext>({ router }: SetupR
|
|||
// GET assets/related
|
||||
router.get<unknown, GetRelatedAssetsQueryOptions, unknown>(
|
||||
{
|
||||
path: `${ASSET_MANAGER_API_BASE}/assets/related`,
|
||||
path: GET_RELATED_ASSETS,
|
||||
validate: {
|
||||
query: createRouteValidationFunction(getRelatedAssetsQueryOptionsRT),
|
||||
},
|
||||
|
@ -129,7 +129,7 @@ export function assetsRoutes<T extends RequestHandlerContext>({ router }: SetupR
|
|||
// Add references into sample data and write integration tests
|
||||
|
||||
const { from, to, ean, relation, maxDistance, size, type, kind } = req.query || {};
|
||||
const esClient = await getEsClientFromContext(context);
|
||||
const { elasticsearchClient } = await getClientsFromContext(context);
|
||||
|
||||
if (to && !isValidRange(from, to)) {
|
||||
return res.badRequest({
|
||||
|
@ -140,7 +140,7 @@ export function assetsRoutes<T extends RequestHandlerContext>({ router }: SetupR
|
|||
try {
|
||||
return res.ok({
|
||||
body: {
|
||||
results: await getAllRelatedAssets(esClient, {
|
||||
results: await getAllRelatedAssets(elasticsearchClient, {
|
||||
ean,
|
||||
from,
|
||||
to,
|
||||
|
@ -165,7 +165,7 @@ export function assetsRoutes<T extends RequestHandlerContext>({ router }: SetupR
|
|||
// GET /assets/diff
|
||||
router.get<unknown, GetAssetsDiffQueryOptions, unknown>(
|
||||
{
|
||||
path: `${ASSET_MANAGER_API_BASE}/assets/diff`,
|
||||
path: GET_ASSETS_DIFF,
|
||||
validate: {
|
||||
query: createRouteValidationFunction(getAssetsDiffQueryOptionsRT),
|
||||
},
|
||||
|
@ -187,11 +187,11 @@ export function assetsRoutes<T extends RequestHandlerContext>({ router }: SetupR
|
|||
});
|
||||
}
|
||||
|
||||
const esClient = await getEsClientFromContext(context);
|
||||
const { elasticsearchClient } = await getClientsFromContext(context);
|
||||
|
||||
try {
|
||||
const resultsForA = await getAssets({
|
||||
esClient,
|
||||
elasticsearchClient,
|
||||
filters: {
|
||||
from: aFrom,
|
||||
to: aTo,
|
||||
|
@ -201,7 +201,7 @@ export function assetsRoutes<T extends RequestHandlerContext>({ router }: SetupR
|
|||
});
|
||||
|
||||
const resultsForB = await getAssets({
|
||||
esClient,
|
||||
elasticsearchClient,
|
||||
filters: {
|
||||
from: bFrom,
|
||||
to: bTo,
|
||||
|
|
|
@ -17,8 +17,8 @@ import {
|
|||
import { RequestHandlerContext } from '@kbn/core-http-request-handler-context-server';
|
||||
import { debug } from '../../../common/debug_log';
|
||||
import { SetupRouteOptions } from '../types';
|
||||
import { ASSET_MANAGER_API_BASE } from '../../constants';
|
||||
import { getEsClientFromContext } from '../utils';
|
||||
import { ASSET_MANAGER_API_BASE } from '../../../common/constants_routes';
|
||||
import { getClientsFromContext } from '../utils';
|
||||
|
||||
const sizeRT = rt.union([inRangeFromStringRt(1, 100), createLiteralValueFromUndefinedRT(10)]);
|
||||
const assetDateRT = rt.union([dateRt, datemathStringRt]);
|
||||
|
@ -35,7 +35,7 @@ export type GetServiceAssetsQueryOptions = rt.TypeOf<typeof getServiceAssetsQuer
|
|||
|
||||
export function servicesRoutes<T extends RequestHandlerContext>({
|
||||
router,
|
||||
assetAccessor,
|
||||
assetClient,
|
||||
}: SetupRouteOptions<T>) {
|
||||
// GET /assets/services
|
||||
router.get<unknown, GetServiceAssetsQueryOptions, unknown>(
|
||||
|
@ -47,16 +47,14 @@ export function servicesRoutes<T extends RequestHandlerContext>({
|
|||
},
|
||||
async (context, req, res) => {
|
||||
const { from = 'now-24h', to = 'now', parent } = req.query || {};
|
||||
const esClient = await getEsClientFromContext(context);
|
||||
const coreContext = await context.core;
|
||||
const soClient = coreContext.savedObjects.client;
|
||||
const { elasticsearchClient, savedObjectsClient } = await getClientsFromContext(context);
|
||||
try {
|
||||
const response = await assetAccessor.getServices({
|
||||
const response = await assetClient.getServices({
|
||||
from: datemath.parse(from)!.toISOString(),
|
||||
to: datemath.parse(to)!.toISOString(),
|
||||
parent,
|
||||
esClient,
|
||||
soClient,
|
||||
elasticsearchClient,
|
||||
savedObjectsClient,
|
||||
});
|
||||
|
||||
return res.ok({ body: response });
|
||||
|
|
|
@ -15,11 +15,11 @@ import { servicesRoutes } from './assets/services';
|
|||
|
||||
export function setupRoutes<T extends RequestHandlerContext>({
|
||||
router,
|
||||
assetAccessor,
|
||||
assetClient,
|
||||
}: SetupRouteOptions<T>) {
|
||||
pingRoute<T>({ router, assetAccessor });
|
||||
assetsRoutes<T>({ router, assetAccessor });
|
||||
sampleAssetsRoutes<T>({ router, assetAccessor });
|
||||
hostsRoutes<T>({ router, assetAccessor });
|
||||
servicesRoutes<T>({ router, assetAccessor });
|
||||
pingRoute<T>({ router, assetClient });
|
||||
assetsRoutes<T>({ router, assetClient });
|
||||
sampleAssetsRoutes<T>({ router, assetClient });
|
||||
hostsRoutes<T>({ router, assetClient });
|
||||
servicesRoutes<T>({ router, assetClient });
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import { RequestHandlerContextBase } from '@kbn/core-http-server';
|
||||
import { ASSET_MANAGER_API_BASE } from '../constants';
|
||||
import { ASSET_MANAGER_API_BASE } from '../../common/constants_routes';
|
||||
import { SetupRouteOptions } from './types';
|
||||
|
||||
export function pingRoute<T extends RequestHandlerContextBase>({ router }: SetupRouteOptions<T>) {
|
||||
|
|
|
@ -7,11 +7,11 @@
|
|||
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { RequestHandlerContext } from '@kbn/core/server';
|
||||
import { ASSET_MANAGER_API_BASE } from '../constants';
|
||||
import { ASSET_MANAGER_API_BASE } from '../../common/constants_routes';
|
||||
import { getSampleAssetDocs, sampleAssets } from '../lib/sample_assets';
|
||||
import { writeAssets } from '../lib/write_assets';
|
||||
import { SetupRouteOptions } from './types';
|
||||
import { getEsClientFromContext } from './utils';
|
||||
import { getClientsFromContext } from './utils';
|
||||
|
||||
export type WriteSamplesPostBody = {
|
||||
baseDateTime?: string | number;
|
||||
|
@ -62,12 +62,12 @@ export function sampleAssetsRoutes<T extends RequestHandlerContext>({
|
|||
},
|
||||
});
|
||||
}
|
||||
const esClient = await getEsClientFromContext(context);
|
||||
const { elasticsearchClient } = await getClientsFromContext(context);
|
||||
const assetDocs = getSampleAssetDocs({ baseDateTime: parsed, excludeEans });
|
||||
|
||||
try {
|
||||
const response = await writeAssets({
|
||||
esClient,
|
||||
elasticsearchClient,
|
||||
assetDocs,
|
||||
namespace: 'sample_data',
|
||||
refresh,
|
||||
|
@ -101,9 +101,9 @@ export function sampleAssetsRoutes<T extends RequestHandlerContext>({
|
|||
validate: {},
|
||||
},
|
||||
async (context, req, res) => {
|
||||
const esClient = await getEsClientFromContext(context);
|
||||
const { elasticsearchClient } = await getClientsFromContext(context);
|
||||
|
||||
const sampleDataStreams = await esClient.indices.getDataStream({
|
||||
const sampleDataStreams = await elasticsearchClient.indices.getDataStream({
|
||||
name: 'assets-*-sample_data',
|
||||
expand_wildcards: 'all',
|
||||
});
|
||||
|
@ -115,7 +115,7 @@ export function sampleAssetsRoutes<T extends RequestHandlerContext>({
|
|||
for (let i = 0; i < dataStreamsToDelete.length; i++) {
|
||||
const dsName = dataStreamsToDelete[i];
|
||||
try {
|
||||
await esClient.indices.deleteDataStream({ name: dsName });
|
||||
await elasticsearchClient.indices.deleteDataStream({ name: dsName });
|
||||
deletedDataStreams.push(dsName);
|
||||
} catch (error: any) {
|
||||
errorWhileDeleting =
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
*/
|
||||
|
||||
import { IRouter, RequestHandlerContextBase } from '@kbn/core-http-server';
|
||||
import { AssetAccessor } from '../lib/asset_accessor';
|
||||
import { AssetClient } from '../lib/asset_client';
|
||||
|
||||
export interface SetupRouteOptions<T extends RequestHandlerContextBase> {
|
||||
router: IRouter<T>;
|
||||
assetAccessor: AssetAccessor;
|
||||
assetClient: AssetClient;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,12 @@
|
|||
|
||||
import { RequestHandlerContext } from '@kbn/core/server';
|
||||
|
||||
export async function getEsClientFromContext<T extends RequestHandlerContext>(context: T) {
|
||||
return (await context.core).elasticsearch.client.asCurrentUser;
|
||||
export async function getClientsFromContext<T extends RequestHandlerContext>(context: T) {
|
||||
const coreContext = await context.core;
|
||||
|
||||
return {
|
||||
coreContext,
|
||||
elasticsearchClient: coreContext.elasticsearch.client.asCurrentUser,
|
||||
savedObjectsClient: coreContext.savedObjects.client,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { schema, TypeOf } from '@kbn/config-schema';
|
||||
import { ElasticsearchClient } from '@kbn/core/server';
|
||||
import { ElasticsearchClient, SavedObjectsClientContract } from '@kbn/core/server';
|
||||
import {
|
||||
ApmDataAccessPluginSetup,
|
||||
ApmDataAccessPluginStart,
|
||||
|
@ -14,37 +13,9 @@ import {
|
|||
import { MetricsDataPluginSetup } from '@kbn/metrics-data-access-plugin/server';
|
||||
|
||||
export interface ElasticsearchAccessorOptions {
|
||||
esClient: ElasticsearchClient;
|
||||
elasticsearchClient: ElasticsearchClient;
|
||||
}
|
||||
|
||||
export const INDEX_DEFAULTS = {
|
||||
logs: 'filebeat-*,logs-*',
|
||||
};
|
||||
|
||||
export const configSchema = schema.object({
|
||||
alphaEnabled: schema.maybe(schema.boolean()),
|
||||
// Designate where various types of data live.
|
||||
// NOTE: this should be handled in a centralized way for observability, so
|
||||
// that when a user configures these differently from the known defaults,
|
||||
// that value is propagated everywhere. For now, we duplicate the value here.
|
||||
sourceIndices: schema.object(
|
||||
{
|
||||
logs: schema.string({ defaultValue: INDEX_DEFAULTS.logs }),
|
||||
},
|
||||
{ defaultValue: INDEX_DEFAULTS }
|
||||
),
|
||||
// Choose an explicit source for asset queries.
|
||||
// NOTE: This will eventually need to be able to cleverly switch
|
||||
// between these values based on the availability of data in the
|
||||
// indices, and possibly for each asset kind/type value.
|
||||
// For now, we set this explicitly.
|
||||
lockedSource: schema.oneOf([schema.literal('assets'), schema.literal('signals')], {
|
||||
defaultValue: 'signals',
|
||||
}),
|
||||
});
|
||||
|
||||
export type AssetManagerConfig = TypeOf<typeof configSchema>;
|
||||
|
||||
export interface AssetManagerPluginSetupDependencies {
|
||||
apmDataAccess: ApmDataAccessPluginSetup;
|
||||
metricsDataAccess: MetricsDataPluginSetup;
|
||||
|
@ -52,3 +23,8 @@ export interface AssetManagerPluginSetupDependencies {
|
|||
export interface AssetManagerPluginStartDependencies {
|
||||
apmDataAccess: ApmDataAccessPluginStart;
|
||||
}
|
||||
|
||||
export interface AssetClientDependencies {
|
||||
elasticsearchClient: ElasticsearchClient;
|
||||
savedObjectsClient: SavedObjectsClientContract;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
"../../../typings/**/*",
|
||||
"common/**/*",
|
||||
"server/**/*",
|
||||
"public/**/*",
|
||||
"types/**/*"
|
||||
],
|
||||
"exclude": ["target/**/*"],
|
||||
|
@ -17,10 +18,11 @@
|
|||
"@kbn/core-http-server",
|
||||
"@kbn/core-elasticsearch-client-server-mocks",
|
||||
"@kbn/io-ts-utils",
|
||||
"@kbn/core-elasticsearch-server",
|
||||
"@kbn/core-http-request-handler-context-server",
|
||||
"@kbn/datemath",
|
||||
"@kbn/apm-data-access-plugin",
|
||||
"@kbn/core-http-browser-mocks",
|
||||
"@kbn/logging",
|
||||
"@kbn/metrics-data-access-plugin"
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue