Skip to content

Commit

Permalink
Add inventory metadata api with regions and accounts (#52660)
Browse files Browse the repository at this point in the history
* Add inventory metadata api with regions and accounts

* Comment magic number

* Refactor to be compat with new platform

* Fix types

* Use RequiredDataset to get account details. Fix hook decodes

* Remove unused import

* Update x-pack/legacy/plugins/infra/server/routes/inventory_metadata/lib/get_aws_metadata.ts

Co-Authored-By: Chris Cowan <[email protected]>

* Rename some things again

* Fix type
  • Loading branch information
phillipb authored Dec 16, 2019
1 parent 8b36eb4 commit aacbd1d
Show file tree
Hide file tree
Showing 19 changed files with 272 additions and 17 deletions.
28 changes: 28 additions & 0 deletions x-pack/legacy/plugins/infra/common/http_api/inventory_meta_api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import * as rt from 'io-ts';
import { ItemTypeRT } from '../inventory_models/types';

const AWSAccountRT = rt.type({
value: rt.string,
name: rt.string,
});

export const InventoryMetaResponseRT = rt.type({
accounts: rt.array(AWSAccountRT),
projects: rt.array(rt.string),
regions: rt.array(rt.string),
});

export const InventoryMetaRequestRT = rt.type({
sourceId: rt.string,
nodeType: ItemTypeRT,
});

export type InventoryMetaRequest = rt.TypeOf<typeof InventoryMetaRequestRT>;
export type InventoryMetaResponse = rt.TypeOf<typeof InventoryMetaResponseRT>;
export type InventoryAWSAccount = rt.TypeOf<typeof AWSAccountRT>;
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const awsEC2: InventoryModel = {
displayName: i18n.translate('xpack.infra.inventoryModels.awsEC2.displayName', {
defaultMessage: 'EC2 Instances',
}),
requiredModules: ['aws'],
requiredModule: 'aws',
crosslinkSupport: {
details: true,
logs: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const awsRDS: InventoryModel = {
displayName: i18n.translate('xpack.infra.inventoryModels.awsRDS.displayName', {
defaultMessage: 'RDS Databases',
}),
requiredModules: ['aws'],
requiredModule: 'aws',
crosslinkSupport: {
details: true,
logs: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const awsS3: InventoryModel = {
displayName: i18n.translate('xpack.infra.inventoryModels.awsS3.displayName', {
defaultMessage: 'S3 Buckets',
}),
requiredModules: ['aws'],
requiredModule: 'aws',
crosslinkSupport: {
details: true,
logs: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const awsSQS: InventoryModel = {
displayName: i18n.translate('xpack.infra.inventoryModels.awsSQS.displayName', {
defaultMessage: 'SQS Queues',
}),
requiredModules: ['aws'],
requiredModule: 'aws',
crosslinkSupport: {
details: true,
logs: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const container: InventoryModel = {
displayName: i18n.translate('xpack.infra.inventoryModel.container.displayName', {
defaultMessage: 'Docker Containers',
}),
requiredModules: ['docker'],
requiredModule: 'docker',
crosslinkSupport: {
details: true,
logs: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const host: InventoryModel = {
displayName: i18n.translate('xpack.infra.inventoryModel.host.displayName', {
defaultMessage: 'Hosts',
}),
requiredModules: ['system'],
requiredModule: 'system',
crosslinkSupport: {
details: true,
logs: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const pod: InventoryModel = {
displayName: i18n.translate('xpack.infra.inventoryModel.pod.displayName', {
defaultMessage: 'Kubernetes Pods',
}),
requiredModules: ['kubernetes'],
requiredModule: 'kubernetes',
crosslinkSupport: {
details: true,
logs: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ export interface InventoryMetrics {
export interface InventoryModel {
id: string;
displayName: string;
requiredModules: string[];
requiredModule: string;
fields: {
id: string;
name: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { NodesOverview } from '../nodes_overview';
import { Toolbar } from './toolbars/toolbar';
import { PageContent } from '../page';
import { useSnapshot } from '../../containers/waffle/use_snaphot';
import { useInventoryMeta } from '../../containers/inventory_metadata/use_inventory_meta';

export interface LayoutProps {
options: InfraWaffleMapOptions;
Expand All @@ -35,6 +36,7 @@ export interface LayoutProps {
}

export const Layout = (props: LayoutProps) => {
const { accounts, regions } = useInventoryMeta(props.sourceId, props.nodeType);
const { loading, nodes, reload } = useSnapshot(
props.filterQuery,
props.metric,
Expand All @@ -43,9 +45,10 @@ export const Layout = (props: LayoutProps) => {
props.sourceId,
props.currentTime
);

return (
<>
<Toolbar nodeType={props.nodeType} />
<Toolbar accounts={accounts} regions={regions} nodeType={props.nodeType} />
<PageContent>
<NodesOverview
nodes={nodes}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import React, { FunctionComponent } from 'react';
import { Action } from 'typescript-fsa';
import { EuiFlexItem } from '@elastic/eui';
import { InventoryAWSAccount } from '../../../../common/http_api/inventory_meta_api';
import { findToolbar } from '../../../../common/inventory_models/toolbars';
import {
InfraNodeType,
Expand Down Expand Up @@ -58,7 +59,12 @@ const wrapToolbarItems = (ToolbarItems: FunctionComponent<ToolbarProps>) => {
);
};

export const Toolbar = ({ nodeType }: { nodeType: InfraNodeType }) => {
interface Props {
nodeType: InfraNodeType;
regions: string[];
accounts: InventoryAWSAccount[];
}
export const Toolbar = ({ nodeType }: Props) => {
const ToolbarItems = findToolbar(nodeType);
return wrapToolbarItems(ToolbarItems);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { fold } from 'fp-ts/lib/Either';
import { identity } from 'fp-ts/lib/function';
import { pipe } from 'fp-ts/lib/pipeable';
import { useEffect } from 'react';
import { throwErrors, createPlainError } from '../../../common/runtime_types';
import { useHTTPRequest } from '../../hooks/use_http_request';
import {
InventoryMetaResponseRT,
InventoryMetaResponse,
} from '../../../common/http_api/inventory_meta_api';
import { InfraNodeType } from '../../graphql/types';

export function useInventoryMeta(sourceId: string, nodeType: InfraNodeType) {
const decodeResponse = (response: any) => {
return pipe(
InventoryMetaResponseRT.decode(response),
fold(throwErrors(createPlainError), identity)
);
};

const { error, loading, response, makeRequest } = useHTTPRequest<InventoryMetaResponse>(
'/api/infra/inventory/meta',
'POST',
JSON.stringify({
sourceId,
nodeType,
}),
decodeResponse
);

useEffect(() => {
makeRequest();
}, [makeRequest]);

return {
error,
loading,
accounts: response ? response.accounts : [],
regions: response ? response.regions : [],
makeRequest,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ export function useMetadata(
nodeId,
nodeType,
sourceId,
decodeResponse,
})
}),
decodeResponse
);

useEffect(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ export function useNodeDetails(
timerange,
cloudId,
sourceId,
decodeResponse,
})
}),
decodeResponse
);

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ export function useSnapshot(
timerange,
filterQuery,
sourceId,
decodeResponse,
})
}),
decodeResponse
);

useEffect(() => {
Expand Down
2 changes: 2 additions & 0 deletions x-pack/legacy/plugins/infra/server/infra_server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { initMetricExplorerRoute } from './routes/metrics_explorer';
import { initMetadataRoute } from './routes/metadata';
import { initSnapshotRoute } from './routes/snapshot';
import { initNodeDetailsRoute } from './routes/node_details';
import { initInventoryMetaRoute } from './routes/inventory_metadata';

export const initInfraServer = (libs: InfraBackendLibs) => {
const schema = makeExecutableSchema({
Expand All @@ -39,4 +40,5 @@ export const initInfraServer = (libs: InfraBackendLibs) => {
initValidateLogAnalysisIndicesRoute(libs);
initMetricExplorerRoute(libs);
initMetadataRoute(libs);
initInventoryMetaRoute(libs);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { schema } from '@kbn/config-schema';
import Boom from 'boom';
import { pipe } from 'fp-ts/lib/pipeable';
import { fold } from 'fp-ts/lib/Either';
import { identity } from 'fp-ts/lib/function';
import { InfraBackendLibs } from '../../lib/infra_types';
import { throwErrors } from '../../../common/runtime_types';
import { getAWSMetadata } from './lib/get_aws_metadata';
import {
InventoryMetaRequestRT,
InventoryMetaResponseRT,
} from '../../../common/http_api/inventory_meta_api';

const escapeHatch = schema.object({}, { allowUnknowns: true });

export const initInventoryMetaRoute = (libs: InfraBackendLibs) => {
const { framework } = libs;

framework.registerRoute(
{
method: 'post',
path: '/api/infra/inventory/meta',
validate: {
body: escapeHatch,
},
},
async (requestContext, request, response) => {
try {
const { sourceId, nodeType } = pipe(
InventoryMetaRequestRT.decode(request.body),
fold(throwErrors(Boom.badRequest), identity)
);

const { configuration } = await libs.sources.getSourceConfiguration(
requestContext,
sourceId
);
const awsMetadata = await getAWSMetadata(
framework,
requestContext,
configuration,
nodeType
);

return response.ok({
body: InventoryMetaResponseRT.encode(awsMetadata),
});
} catch (error) {
return response.internalError({
body: error.message,
});
}
}
);
};
Loading

0 comments on commit aacbd1d

Please sign in to comment.