Skip to content

Commit

Permalink
Fixes tests with asset.kind intro
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonrhodes committed Jun 6, 2023
1 parent 157db38 commit 448fa13
Show file tree
Hide file tree
Showing 10 changed files with 108 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { elasticsearchClientMock } from '@kbn/core-elasticsearch-client-server-m
import { v4 as uuid } from 'uuid';
import { AssetWithoutTimestamp } from '../../common/types_api';
import { getAssets } from './get_assets'; // Mocked
import { getRelatedAssets } from './get_related_assets'; // Mocked
import { getRelatedAssets } from './get_indirectly_related_assets'; // Mocked
import { getAllRelatedAssets } from './get_all_related_assets';

const esClientMock = elasticsearchClientMock.createScopedClusterClient().asCurrentUser;
Expand Down
23 changes: 16 additions & 7 deletions x-pack/plugins/asset_manager/server/lib/get_all_related_assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@

import { ElasticsearchClient } from '@kbn/core/server';
import { flatten, without } from 'lodash';
import { debug } from '../../common/debug_log';
import { Asset, AssetType, AssetKind, Relation, RelationField } from '../../common/types_api';
import { getAssets } from './get_assets';
import { getRelatedAssets } from './get_related_assets';
import { getIndirectlyRelatedAssets } from './get_indirectly_related_assets';
import { AssetNotFoundError } from './errors';
import { toArray } from './utils';

Expand Down Expand Up @@ -102,21 +103,27 @@ type FindRelatedAssetsOptions = Pick<
async function findRelatedAssets(
esClient: ElasticsearchClient,
primary: Asset,
{ relation, from, to, kind = [], visitedEans }: FindRelatedAssetsOptions
{ relation, from, to, kind, visitedEans }: FindRelatedAssetsOptions
): Promise<Asset[]> {
const relationField = relationToDirectField(relation);
const directlyRelatedEans = toArray(primary[relationField]);
const directlyRelatedEans = toArray<string>(primary[relationField]);

debug('Directly Related EAN values found on primary asset', directlyRelatedEans);

let directlyRelatedAssets: Asset[] = [];
if (directlyRelatedEans.length) {
// get the directly related assets we haven't visited already

// get the directly related assets we haven't visited already
const remainingEansToFind = without(directlyRelatedEans, ...visitedEans);
if (remainingEansToFind.length > 0) {
directlyRelatedAssets = await getAssets({
esClient,
filters: { ean: without(directlyRelatedEans, ...visitedEans), from, to, kind },
filters: { ean: remainingEansToFind, from, to, kind },
});
}

const indirectlyRelatedAssets = await getRelatedAssets({
debug('Directly related assets found:', JSON.stringify(directlyRelatedAssets));

const indirectlyRelatedAssets = await getIndirectlyRelatedAssets({
esClient,
ean: primary['asset.ean'],
excludeEans: visitedEans.concat(directlyRelatedEans),
Expand All @@ -126,6 +133,8 @@ async function findRelatedAssets(
kind,
});

debug('Indirectly related assets found:', JSON.stringify(indirectlyRelatedAssets));

return [...directlyRelatedAssets, ...indirectlyRelatedAssets];
}

Expand Down
21 changes: 17 additions & 4 deletions x-pack/plugins/asset_manager/server/lib/get_assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { debug } from '../../common/debug_log';
import { Asset, AssetFilters } from '../../common/types_api';
import { ASSETS_INDEX_PREFIX } from '../constants';
import { ElasticsearchAccessorOptions } from '../types';
import { isStringOrNonEmptyArray } from './utils';

interface GetAssetsOptions extends ElasticsearchAccessorOptions {
size?: number;
Expand All @@ -24,6 +25,8 @@ export async function getAssets({
}: GetAssetsOptions): Promise<Asset[]> {
// Maybe it makes the most sense to validate the filters here?

debug('Get Assets Filters:', JSON.stringify(filters));

const { from = 'now-24h', to = 'now' } = filters;
const must: QueryDslQueryContainer[] = [];

Expand All @@ -36,23 +39,33 @@ export async function getAssets({
});
}

if (filters.type) {
if (isStringOrNonEmptyArray(filters.type)) {
debug(
'filters.type IS string or non empty array?',
typeof filters.type,
JSON.stringify(filters.type)
);
must.push({
terms: {
['asset.type']: Array.isArray(filters.type) ? filters.type : [filters.type],
},
});
}

if (filters.kind) {
if (isStringOrNonEmptyArray(filters.kind)) {
debug(
'filters.kind IS string or non empty array?',
typeof filters.kind,
JSON.stringify(filters.kind)
);
must.push({
terms: {
['asset.kind']: Array.isArray(filters.kind) ? filters.kind : [filters.kind],
},
});
}

if (filters.ean) {
if (isStringOrNonEmptyArray(filters.ean)) {
must.push({
terms: {
['asset.ean']: Array.isArray(filters.ean) ? filters.ean : [filters.ean],
Expand Down Expand Up @@ -121,7 +134,7 @@ export async function getAssets({
},
};

debug('Performing Asset Query', '\n\n', JSON.stringify(dsl, null, 2));
debug('Performing Get Assets Query', '\n\n', JSON.stringify(dsl, null, 2));

const response = await esClient.search<Asset>(dsl);
return response.hits.hits.map((hit) => hit._source).filter((asset): asset is Asset => !!asset);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { debug } from '../../common/debug_log';
import { Asset, AssetKind, Relation, RelationField } from '../../common/types_api';
import { ASSETS_INDEX_PREFIX } from '../constants';
import { ElasticsearchAccessorOptions } from '../types';
import { isStringOrNonEmptyArray } from './utils';

interface GetRelatedAssetsOptions extends ElasticsearchAccessorOptions {
size?: number;
Expand All @@ -18,10 +19,10 @@ interface GetRelatedAssetsOptions extends ElasticsearchAccessorOptions {
from?: string;
to?: string;
relation: Relation;
kind?: AssetKind[];
kind?: AssetKind | AssetKind[];
}

export async function getRelatedAssets({
export async function getIndirectlyRelatedAssets({
esClient,
size = 100,
from = 'now-24h',
Expand All @@ -40,10 +41,10 @@ export async function getRelatedAssets({
},
];

if (kind?.length) {
if (isStringOrNonEmptyArray(kind)) {
must.push({
terms: {
['asset.kind']: kind,
['asset.kind']: Array.isArray(kind) ? kind : [kind],
},
});
}
Expand Down Expand Up @@ -88,7 +89,7 @@ export async function getRelatedAssets({
},
};

debug('Performing Asset Query', '\n\n', JSON.stringify(dsl, null, 2));
debug('Performing Indirectly Related Asset Query', '\n\n', JSON.stringify(dsl, null, 2));

const response = await esClient.search<Asset>(dsl);
return response.hits.hits.map((hit) => hit._source).filter((asset): asset is Asset => !!asset);
Expand Down
66 changes: 33 additions & 33 deletions x-pack/plugins/asset_manager/server/lib/sample_assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const sampleK8sClusters: AssetWithoutTimestamp[] = [
'asset.kind': 'cluster',
'asset.id': 'cluster-001',
'asset.name': 'Cluster 001 (AWS EKS)',
'asset.ean': 'k8s.cluster:cluster-001',
'asset.ean': 'cluster:cluster-001',
'orchestrator.type': 'kubernetes',
'orchestrator.cluster.name': 'Cluster 001 (AWS EKS)',
'orchestrator.cluster.id': 'cluster-001',
Expand All @@ -46,7 +46,7 @@ const sampleK8sClusters: AssetWithoutTimestamp[] = [
'asset.kind': 'cluster',
'asset.id': 'cluster-002',
'asset.name': 'Cluster 002 (Azure AKS)',
'asset.ean': 'k8s.cluster:cluster-002',
'asset.ean': 'cluster:cluster-002',
'orchestrator.type': 'kubernetes',
'orchestrator.cluster.name': 'Cluster 002 (Azure AKS)',
'orchestrator.cluster.id': 'cluster-002',
Expand All @@ -62,8 +62,8 @@ const sampleK8sNodes: AssetWithoutTimestamp[] = [
'asset.kind': 'host',
'asset.id': 'node-101',
'asset.name': 'k8s-node-101-aws',
'asset.ean': 'k8s.node:node-101',
'asset.parents': ['k8s.cluster:cluster-001'],
'asset.ean': 'host:node-101',
'asset.parents': ['cluster:cluster-001'],
'orchestrator.type': 'kubernetes',
'orchestrator.cluster.name': 'Cluster 001 (AWS EKS)',
'orchestrator.cluster.id': 'cluster-001',
Expand All @@ -76,8 +76,8 @@ const sampleK8sNodes: AssetWithoutTimestamp[] = [
'asset.kind': 'host',
'asset.id': 'node-102',
'asset.name': 'k8s-node-102-aws',
'asset.ean': 'k8s.node:node-102',
'asset.parents': ['k8s.cluster:cluster-001'],
'asset.ean': 'host:node-102',
'asset.parents': ['cluster:cluster-001'],
'orchestrator.type': 'kubernetes',
'orchestrator.cluster.name': 'Cluster 001 (AWS EKS)',
'orchestrator.cluster.id': 'cluster-001',
Expand All @@ -90,8 +90,8 @@ const sampleK8sNodes: AssetWithoutTimestamp[] = [
'asset.kind': 'host',
'asset.id': 'node-103',
'asset.name': 'k8s-node-103-aws',
'asset.ean': 'k8s.node:node-103',
'asset.parents': ['k8s.cluster:cluster-001'],
'asset.ean': 'host:node-103',
'asset.parents': ['cluster:cluster-001'],
'orchestrator.type': 'kubernetes',
'orchestrator.cluster.name': 'Cluster 001 (AWS EKS)',
'orchestrator.cluster.id': 'cluster-001',
Expand All @@ -107,73 +107,73 @@ const sampleK8sPods: AssetWithoutTimestamp[] = [
'asset.kind': 'pod',
'asset.id': 'pod-200xrg1',
'asset.name': 'k8s-pod-200xrg1-aws',
'asset.ean': 'k8s.pod:pod-200xrg1',
'asset.parents': ['k8s.node:node-101'],
'asset.references': ['k8s.cluster:cluster-001'],
'asset.ean': 'pod:pod-200xrg1',
'asset.parents': ['host:node-101'],
'asset.references': ['cluster:cluster-001'],
},
{
'asset.type': 'k8s.pod',
'asset.kind': 'pod',
'asset.id': 'pod-200dfp2',
'asset.name': 'k8s-pod-200dfp2-aws',
'asset.ean': 'k8s.pod:pod-200dfp2',
'asset.parents': ['k8s.node:node-101'],
'asset.ean': 'pod:pod-200dfp2',
'asset.parents': ['host:node-101'],
},
{
'asset.type': 'k8s.pod',
'asset.kind': 'pod',
'asset.id': 'pod-200wwc3',
'asset.name': 'k8s-pod-200wwc3-aws',
'asset.ean': 'k8s.pod:pod-200wwc3',
'asset.parents': ['k8s.node:node-101'],
'asset.ean': 'pod:pod-200wwc3',
'asset.parents': ['host:node-101'],
},
{
'asset.type': 'k8s.pod',
'asset.kind': 'pod',
'asset.id': 'pod-200naq4',
'asset.name': 'k8s-pod-200naq4-aws',
'asset.ean': 'k8s.pod:pod-200naq4',
'asset.parents': ['k8s.node:node-102'],
'asset.ean': 'pod:pod-200naq4',
'asset.parents': ['host:node-102'],
},
{
'asset.type': 'k8s.pod',
'asset.kind': 'pod',
'asset.id': 'pod-200ohr5',
'asset.name': 'k8s-pod-200ohr5-aws',
'asset.ean': 'k8s.pod:pod-200ohr5',
'asset.parents': ['k8s.node:node-102'],
'asset.ean': 'pod:pod-200ohr5',
'asset.parents': ['host:node-102'],
},
{
'asset.type': 'k8s.pod',
'asset.kind': 'pod',
'asset.id': 'pod-200yyx6',
'asset.name': 'k8s-pod-200yyx6-aws',
'asset.ean': 'k8s.pod:pod-200yyx6',
'asset.parents': ['k8s.node:node-103'],
'asset.ean': 'pod:pod-200yyx6',
'asset.parents': ['host:node-103'],
},
{
'asset.type': 'k8s.pod',
'asset.kind': 'pod',
'asset.id': 'pod-200psd7',
'asset.name': 'k8s-pod-200psd7-aws',
'asset.ean': 'k8s.pod:pod-200psd7',
'asset.parents': ['k8s.node:node-103'],
'asset.ean': 'pod:pod-200psd7',
'asset.parents': ['host:node-103'],
},
{
'asset.type': 'k8s.pod',
'asset.kind': 'pod',
'asset.id': 'pod-200wmc8',
'asset.name': 'k8s-pod-200wmc8-aws',
'asset.ean': 'k8s.pod:pod-200wmc8',
'asset.parents': ['k8s.node:node-103'],
'asset.ean': 'pod:pod-200wmc8',
'asset.parents': ['host:node-103'],
},
{
'asset.type': 'k8s.pod',
'asset.kind': 'pod',
'asset.id': 'pod-200ugg9',
'asset.name': 'k8s-pod-200ugg9-aws',
'asset.ean': 'k8s.pod:pod-200ugg9',
'asset.parents': ['k8s.node:node-103'],
'asset.ean': 'pod:pod-200ugg9',
'asset.parents': ['host:node-103'],
},
];

Expand All @@ -183,30 +183,30 @@ const sampleCircularReferences: AssetWithoutTimestamp[] = [
'asset.kind': 'host',
'asset.id': 'node-203',
'asset.name': 'k8s-node-203-aws',
'asset.ean': 'k8s.node:node-203',
'asset.ean': 'host:node-203',
'orchestrator.type': 'kubernetes',
'orchestrator.cluster.name': 'Cluster 001 (AWS EKS)',
'orchestrator.cluster.id': 'cluster-001',
'cloud.provider': 'aws',
'cloud.region': 'us-east-1',
'cloud.service.name': 'eks',
'asset.references': ['k8s.pod:pod-203ugg9', 'k8s.pod:pod-203ugg5'],
'asset.references': ['pod:pod-203ugg9', 'pod:pod-203ugg5'],
},
{
'asset.type': 'k8s.pod',
'asset.kind': 'pod',
'asset.id': 'pod-203ugg5',
'asset.name': 'k8s-pod-203ugg5-aws',
'asset.ean': 'k8s.pod:pod-203ugg5',
'asset.references': ['k8s.node:node-203'],
'asset.ean': 'pod:pod-203ugg5',
'asset.references': ['host:node-203'],
},
{
'asset.type': 'k8s.pod',
'asset.kind': 'pod',
'asset.id': 'pod-203ugg9',
'asset.name': 'k8s-pod-203ugg9-aws',
'asset.ean': 'k8s.pod:pod-203ugg9',
'asset.references': ['k8s.node:node-203'],
'asset.ean': 'pod:pod-203ugg9',
'asset.references': ['host:node-203'],
},
];

Expand Down
12 changes: 12 additions & 0 deletions x-pack/plugins/asset_manager/server/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,15 @@ export const isValidRange = (from: string, to: string): boolean => {
}
return true;
};

export function isStringOrNonEmptyArray(
value: string | string[] | undefined
): value is string | string[] {
if (typeof value === 'undefined') {
return false;
}
if (Array.isArray(value) && value.length === 0) {
return false;
}
return true;
}
11 changes: 4 additions & 7 deletions x-pack/plugins/asset_manager/server/routes/assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,9 @@ export function assetsRoutes<T extends RequestHandlerContext>({ router }: SetupR
async (context, req, res) => {
// Add references into sample data and write integration tests

const { from, to, ean, relation, maxDistance, size } = req.query || {};
const { from, to, ean, relation, maxDistance, size, type, kind } = req.query || {};
const esClient = await getEsClientFromContext(context);

const type = toArray<AssetType>(req.query.type);
const kind = toArray<AssetKind>(req.query.kind);

if (to && !isValidRange(from, to)) {
return res.badRequest({
body: `Time range cannot move backwards in time. "to" (${to}) is before "from" (${from}).`,
Expand Down Expand Up @@ -176,9 +173,9 @@ export function assetsRoutes<T extends RequestHandlerContext>({ router }: SetupR
},
},
async (context, req, res) => {
const { aFrom, aTo, bFrom, bTo } = req.query;
const type = toArray<AssetType>(req.query.type);
const kind = toArray<AssetKind>(req.query.kind);
const { aFrom, aTo, bFrom, bTo, type, kind } = req.query;
// const type = toArray<AssetType>(req.query.type);
// const kind = toArray<AssetKind>(req.query.kind);

if (!isValidRange(aFrom, aTo)) {
return res.badRequest({
Expand Down
Loading

0 comments on commit 448fa13

Please sign in to comment.