Skip to content

Commit

Permalink
Get the assetClient ready for building inventory prototype (elastic#1…
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonrhodes authored Oct 4, 2023
1 parent 0f1a6e3 commit 88b85eb
Show file tree
Hide file tree
Showing 43 changed files with 700 additions and 445 deletions.
3 changes: 1 addition & 2 deletions .buildkite/ftr_configs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ disabled:
- x-pack/test/plugin_api_perf/config.js
- x-pack/test/screenshot_creation/config.ts
- x-pack/test/fleet_packages/config.ts
- x-pack/test/api_integration/apis/asset_manager/config_with_assets_source.ts

# Scalability testing config that we run in its own pipeline
- x-pack/test/scalability/config.ts
Expand Down Expand Up @@ -174,7 +173,7 @@ enabled:
- x-pack/test/api_integration/config_security_trial.ts
- x-pack/test/api_integration/apis/aiops/config.ts
- x-pack/test/api_integration/apis/asset_manager/config_when_disabled.ts
- x-pack/test/api_integration/apis/asset_manager/config_with_signals_source.ts
- x-pack/test/api_integration/apis/asset_manager/config_when_enabled.ts
- x-pack/test/api_integration/apis/cases/config.ts
- x-pack/test/api_integration/apis/cloud_security_posture/config.ts
- x-pack/test/api_integration/apis/console/config.ts
Expand Down
8 changes: 0 additions & 8 deletions x-pack/plugins/asset_manager/common/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,6 @@ export const configSchema = schema.object({
},
{ 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>;
Expand Down
1 change: 1 addition & 0 deletions x-pack/plugins/asset_manager/common/constants_routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ export const GET_RELATED_ASSETS = base('/assets/related');
export const GET_ASSETS_DIFF = base('/assets/diff');

export const GET_HOSTS = base('/assets/hosts');
export const GET_SERVICES = base('/assets/services');
23 changes: 22 additions & 1 deletion x-pack/plugins/asset_manager/common/types_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,10 @@ export const sizeRT = rt.union([
createLiteralValueFromUndefinedRT(10),
]);
export const assetDateRT = rt.union([dateRt, datemathStringRt]);

/**
* Hosts
*/
export const getHostAssetsQueryOptionsRT = rt.exact(
rt.partial({
from: assetDateRT,
Expand All @@ -204,8 +208,25 @@ export const getHostAssetsQueryOptionsRT = rt.exact(
})
);
export type GetHostAssetsQueryOptions = rt.TypeOf<typeof getHostAssetsQueryOptionsRT>;

export const getHostAssetsResponseRT = rt.type({
hosts: rt.array(assetRT),
});
export type GetHostAssetsResponse = rt.TypeOf<typeof getHostAssetsResponseRT>;

/**
* Services
*/
export const getServiceAssetsQueryOptionsRT = rt.exact(
rt.partial({
from: assetDateRT,
to: assetDateRT,
size: sizeRT,
parent: rt.string,
})
);

export type GetServiceAssetsQueryOptions = rt.TypeOf<typeof getServiceAssetsQueryOptionsRT>;
export const getServiceAssetsResponseRT = rt.type({
services: rt.array(assetRT),
});
export type GetServiceAssetsResponse = rt.TypeOf<typeof getServiceAssetsResponseRT>;
10 changes: 5 additions & 5 deletions x-pack/plugins/asset_manager/common/types_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
* 2.0.
*/

export interface GetHostsOptionsPublic {
export interface SharedAssetsOptionsPublic {
from: string;
to: string;
to?: string;
}

export interface GetServicesOptionsPublic {
from: string;
to: string;
export type GetHostsOptionsPublic = SharedAssetsOptionsPublic;

export interface GetServicesOptionsPublic extends SharedAssetsOptionsPublic {
parent?: string;
}
24 changes: 22 additions & 2 deletions x-pack/plugins/asset_manager/docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,11 @@ it will be able to pull the properly-scoped client dependencies off of that requ

### Client methods

TODO: Link to a centralized asset document example that each response can reference?

#### getHosts

Get a group of host assets found within a specified time range.
Get a list of host assets found within a specified time range.

| Parameter | Type | Required? | Description |
| :-------- | :-------------- | :-------- | :--------------------------------------------------------------------- |
Expand All @@ -184,4 +186,22 @@ Get a group of host assets found within a specified time range.
}
```

TODO: Link to a centralized asset document example that each response can reference?
#### getServices

Get a list of service 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 |
| parent | string | no | EAN value for a given parent service to filter services by |

**Response**

```json
{
"services": [
...found service assets
]
}
```
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,40 @@ describe('Public assets client', () => {

it('should return the direct results of http.get', async () => {
const client = new PublicAssetsClient(http);
http.get.mockResolvedValueOnce('my result');
http.get.mockResolvedValueOnce('my hosts');
const result = await client.getHosts({ from: 'x', to: 'y' });
expect(result).toBe('my result');
expect(result).toBe('my hosts');
});
});

describe('getServices', () => {
it('should call the REST API', async () => {
const client = new PublicAssetsClient(http);
await client.getServices({ 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.getServices({ from: 'x', to: 'y' });
expect(http.get).toBeCalledWith(routePaths.GET_SERVICES, {
query: { from: 'x', to: 'y' },
});
});

it('should include specified "parent" parameter in http.get query', async () => {
const client = new PublicAssetsClient(http);
await client.getServices({ from: 'x', to: 'y', parent: 'container:123' });
expect(http.get).toBeCalledWith(routePaths.GET_SERVICES, {
query: { from: 'x', to: 'y', parent: 'container:123' },
});
});

it('should return the direct results of http.get', async () => {
const client = new PublicAssetsClient(http);
http.get.mockResolvedValueOnce('my services');
const result = await client.getServices({ from: 'x', to: 'y' });
expect(result).toBe('my services');
});
});
});
16 changes: 13 additions & 3 deletions x-pack/plugins/asset_manager/public/lib/public_assets_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
*/

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 { GetHostsOptionsPublic, GetServicesOptionsPublic } from '../../common/types_client';
import { GetHostAssetsResponse, GetServiceAssetsResponse } from '../../common/types_api';
import { GET_HOSTS, GET_SERVICES } from '../../common/constants_routes';
import { IPublicAssetsClient } from '../types';

export class PublicAssetsClient implements IPublicAssetsClient {
Expand All @@ -23,4 +23,14 @@ export class PublicAssetsClient implements IPublicAssetsClient {

return results;
}

async getServices(options: GetServicesOptionsPublic) {
const results = await this.http.get<GetServiceAssetsResponse>(GET_SERVICES, {
query: {
...options,
},
});

return results;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,25 @@
*/

import { Asset } from '../../../../common/types_api';
import { GetHostsOptionsInjected } from '.';
import { collectHosts } from '../../collectors/hosts';
import { GetHostsOptionsPublic } from '../../../../common/types_client';
import {
AssetClientDependencies,
AssetClientOptionsWithInjectedValues,
} from '../../asset_client_types';

export async function getHostsBySignals(
options: GetHostsOptionsInjected
): Promise<{ hosts: Asset[] }> {
export type GetHostsOptions = GetHostsOptionsPublic & AssetClientDependencies;
export type GetHostsOptionsInjected = AssetClientOptionsWithInjectedValues<GetHostsOptions>;

export async function getHosts(options: GetHostsOptionsInjected): Promise<{ hosts: Asset[] }> {
const metricsIndices = await options.metricsClient.getMetricIndices({
savedObjectsClient: options.savedObjectsClient,
});

const { assets } = await collectHosts({
client: options.elasticsearchClient,
from: options.from,
to: options.to,
to: options.to || 'now',
sourceIndices: {
metrics: metricsIndices,
logs: options.sourceIndices.logs,
Expand Down

This file was deleted.

19 changes: 0 additions & 19 deletions x-pack/plugins/asset_manager/server/lib/accessors/hosts/index.ts

This file was deleted.

19 changes: 0 additions & 19 deletions x-pack/plugins/asset_manager/server/lib/accessors/index.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* 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 { Asset } from '../../../../common/types_api';
import { collectServices } from '../../collectors/services';
import { parseEan } from '../../parse_ean';
import { GetServicesOptionsPublic } from '../../../../common/types_client';
import {
AssetClientDependencies,
AssetClientOptionsWithInjectedValues,
} from '../../asset_client_types';

export type GetServicesOptions = GetServicesOptionsPublic & AssetClientDependencies;
export type GetServicesOptionsInjected = AssetClientOptionsWithInjectedValues<GetServicesOptions>;

export async function getServices(
options: GetServicesOptionsInjected
): Promise<{ services: Asset[] }> {
const filters = [];

if (options.parent) {
const { kind, id } = parseEan(options.parent);

if (kind === 'host') {
filters.push({
bool: {
should: [{ term: { 'host.name': id } }, { term: { 'host.hostname': id } }],
minimum_should_match: 1,
},
});
}

if (kind === 'container') {
filters.push({
bool: {
should: [{ term: { 'container.id': id } }],
minimum_should_match: 1,
},
});
}
}

const apmIndices = await options.getApmIndices(options.savedObjectsClient);
const { assets } = await collectServices({
client: options.elasticsearchClient,
from: options.from,
to: options.to || 'now',
sourceIndices: {
apm: apmIndices,
},
filters,
});

return { services: assets };
}
Loading

0 comments on commit 88b85eb

Please sign in to comment.