-
Notifications
You must be signed in to change notification settings - Fork 8.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Infrastructure UI] Implement inventory views CRUD endpoints #154900
Changes from 26 commits
3ec7402
10e34e8
a7c9330
c3d9c8e
bab4c46
6df39b1
a6d9262
70a6f5f
e71d868
15b88a1
d21947a
85881d3
418b3b1
bfa86b9
6a18272
59e6e33
1af7672
426f924
8ba830c
2e3e551
547963f
5120167
8efe997
72086f1
ead0118
0b71493
88466a4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
/* | ||
* 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 { nonEmptyStringRt } from '@kbn/io-ts-utils'; | ||
import * as rt from 'io-ts'; | ||
import { either } from 'fp-ts/Either'; | ||
|
||
export const INVENTORY_VIEW_URL = '/api/infra/inventory_views'; | ||
export const INVENTORY_VIEW_URL_ENTITY = `${INVENTORY_VIEW_URL}/{inventoryViewId}`; | ||
export const getInventoryViewUrl = (inventoryViewId?: string) => | ||
[INVENTORY_VIEW_URL, inventoryViewId].filter(Boolean).join('/'); | ||
|
||
const inventoryViewIdRT = new rt.Type<string, string, unknown>( | ||
'InventoryViewId', | ||
rt.string.is, | ||
(u, c) => | ||
either.chain(rt.string.validate(u, c), (id) => { | ||
return id === '0' | ||
? rt.failure(u, c, `The inventory view with id ${id} is not configurable.`) | ||
: rt.success(id); | ||
}), | ||
String | ||
); | ||
|
||
export const inventoryViewRequestParamsRT = rt.type({ | ||
inventoryViewId: inventoryViewIdRT, | ||
}); | ||
|
||
export type InventoryViewRequestParams = rt.TypeOf<typeof inventoryViewRequestParamsRT>; | ||
|
||
export const inventoryViewRequestQueryRT = rt.partial({ | ||
sourceId: rt.string, | ||
}); | ||
|
||
export type InventoryViewRequestQuery = rt.TypeOf<typeof inventoryViewRequestQueryRT>; | ||
|
||
const inventoryViewAttributesResponseRT = rt.intersection([ | ||
rt.strict({ | ||
name: nonEmptyStringRt, | ||
isDefault: rt.boolean, | ||
isStatic: rt.boolean, | ||
Comment on lines
+43
to
+44
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. note:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can those values change using the API? For example, using the update endpoint to set another default view? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As those values are derived as:
They could insert those values triggering a manual request to the endpoint, but I guess is better to handle the case, I'll change that! |
||
}), | ||
rt.UnknownRecord, | ||
]); | ||
|
||
const inventoryViewResponseRT = rt.exact( | ||
rt.intersection([ | ||
rt.type({ | ||
id: rt.string, | ||
attributes: inventoryViewAttributesResponseRT, | ||
}), | ||
rt.partial({ | ||
updatedAt: rt.number, | ||
version: rt.string, | ||
}), | ||
]) | ||
); | ||
|
||
export const inventoryViewResponsePayloadRT = rt.type({ | ||
data: inventoryViewResponseRT, | ||
}); | ||
|
||
export type GetInventoryViewResponsePayload = rt.TypeOf<typeof inventoryViewResponsePayloadRT>; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/* | ||
* 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 { nonEmptyStringRt } from '@kbn/io-ts-utils'; | ||
import * as rt from 'io-ts'; | ||
|
||
export const createInventoryViewAttributesRequestPayloadRT = rt.intersection([ | ||
rt.type({ | ||
name: nonEmptyStringRt, | ||
}), | ||
rt.UnknownRecord, | ||
rt.exact(rt.partial({ isDefault: rt.undefined, isStatic: rt.undefined })), | ||
]); | ||
|
||
export type CreateInventoryViewAttributesRequestPayload = rt.TypeOf< | ||
typeof createInventoryViewAttributesRequestPayloadRT | ||
>; | ||
|
||
export const createInventoryViewRequestPayloadRT = rt.type({ | ||
attributes: createInventoryViewAttributesRequestPayloadRT, | ||
}); | ||
|
||
export type CreateInventoryViewRequestPayload = rt.TypeOf< | ||
typeof createInventoryViewRequestPayloadRT | ||
>; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/* | ||
* 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 { nonEmptyStringRt } from '@kbn/io-ts-utils'; | ||
import * as rt from 'io-ts'; | ||
|
||
export const findInventoryViewAttributesResponseRT = rt.strict({ | ||
name: nonEmptyStringRt, | ||
isDefault: rt.boolean, | ||
isStatic: rt.boolean, | ||
}); | ||
|
||
const findInventoryViewResponseRT = rt.exact( | ||
rt.intersection([ | ||
rt.type({ | ||
id: rt.string, | ||
attributes: findInventoryViewAttributesResponseRT, | ||
}), | ||
rt.partial({ | ||
updatedAt: rt.number, | ||
version: rt.string, | ||
}), | ||
]) | ||
); | ||
|
||
export const findInventoryViewResponsePayloadRT = rt.type({ | ||
data: rt.array(findInventoryViewResponseRT), | ||
}); | ||
|
||
export type FindInventoryViewResponsePayload = rt.TypeOf<typeof findInventoryViewResponsePayloadRT>; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
/* | ||
* 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 * as rt from 'io-ts'; | ||
|
||
export const getInventoryViewRequestParamsRT = rt.type({ | ||
inventoryViewId: rt.string, | ||
}); | ||
|
||
export type GetInventoryViewRequestParams = rt.TypeOf<typeof getInventoryViewRequestParamsRT>; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
/* | ||
* 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 * from './common'; | ||
export * from './get_inventory_view'; | ||
export * from './find_inventory_view'; | ||
export * from './create_inventory_view'; | ||
export * from './update_inventory_view'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/* | ||
* 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 { nonEmptyStringRt } from '@kbn/io-ts-utils'; | ||
import * as rt from 'io-ts'; | ||
|
||
export const updateInventoryViewAttributesRequestPayloadRT = rt.intersection([ | ||
rt.type({ | ||
name: nonEmptyStringRt, | ||
}), | ||
rt.UnknownRecord, | ||
rt.exact(rt.partial({ isDefault: rt.undefined, isStatic: rt.undefined })), | ||
]); | ||
|
||
export type UpdateInventoryViewAttributesRequestPayload = rt.TypeOf< | ||
typeof updateInventoryViewAttributesRequestPayloadRT | ||
>; | ||
|
||
export const updateInventoryViewRequestPayloadRT = rt.type({ | ||
attributes: updateInventoryViewAttributesRequestPayloadRT, | ||
}); | ||
|
||
export type UpdateInventoryViewRequestPayload = rt.TypeOf< | ||
typeof updateInventoryViewRequestPayloadRT | ||
>; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
/* | ||
* 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 * from './inventory_views/v1'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
/* | ||
* 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 { i18n } from '@kbn/i18n'; | ||
import type { NonEmptyString } from '@kbn/io-ts-utils'; | ||
import type { InventoryViewAttributes } from './types'; | ||
|
||
export const staticInventoryViewId = '0'; | ||
|
||
export const staticInventoryViewAttributes: InventoryViewAttributes = { | ||
name: i18n.translate('xpack.infra.savedView.defaultViewNameHosts', { | ||
defaultMessage: 'Default view', | ||
}) as NonEmptyString, | ||
isDefault: false, | ||
isStatic: true, | ||
metric: { | ||
type: 'cpu', | ||
}, | ||
groupBy: [], | ||
nodeType: 'host', | ||
view: 'map', | ||
customOptions: [], | ||
boundsOverride: { | ||
max: 1, | ||
min: 0, | ||
}, | ||
autoBounds: true, | ||
accountId: '', | ||
region: '', | ||
customMetrics: [], | ||
legend: { | ||
palette: 'cool', | ||
steps: 10, | ||
reverseColors: false, | ||
}, | ||
source: 'default', | ||
sort: { | ||
by: 'name', | ||
direction: 'desc', | ||
}, | ||
timelineOpen: false, | ||
filterQuery: { | ||
kind: 'kuery', | ||
expression: '', | ||
}, | ||
time: Date.now(), | ||
autoReload: false, | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
/* | ||
* 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 * from './defaults'; | ||
export * from './types'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/* | ||
* 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 { staticInventoryViewAttributes } from './defaults'; | ||
import type { InventoryView, InventoryViewAttributes } from './types'; | ||
|
||
export const createInventoryViewMock = ( | ||
id: string, | ||
attributes: InventoryViewAttributes, | ||
updatedAt?: number, | ||
version?: string | ||
): InventoryView => ({ | ||
id, | ||
attributes: { | ||
...staticInventoryViewAttributes, | ||
...attributes, | ||
}, | ||
updatedAt, | ||
version, | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/* | ||
* 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 { nonEmptyStringRt } from '@kbn/io-ts-utils'; | ||
import * as rt from 'io-ts'; | ||
|
||
export const inventoryViewAttributesRT = rt.intersection([ | ||
rt.strict({ | ||
name: nonEmptyStringRt, | ||
isDefault: rt.boolean, | ||
isStatic: rt.boolean, | ||
}), | ||
rt.UnknownRecord, | ||
]); | ||
|
||
export type InventoryViewAttributes = rt.TypeOf<typeof inventoryViewAttributesRT>; | ||
|
||
export const inventoryViewRT = rt.exact( | ||
rt.intersection([ | ||
rt.type({ | ||
id: rt.string, | ||
attributes: inventoryViewAttributesRT, | ||
}), | ||
rt.partial({ | ||
updatedAt: rt.number, | ||
version: rt.string, | ||
}), | ||
]) | ||
); | ||
|
||
export type InventoryView = rt.TypeOf<typeof inventoryViewRT>; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 { i18n } from '@kbn/i18n'; | ||
import type { NonEmptyString } from '@kbn/io-ts-utils'; | ||
import type { MetricsExplorerViewAttributes } from './types'; | ||
|
||
export const staticMetricsExplorerViewId = 'static'; | ||
|
||
export const staticMetricsExplorerViewAttributes: MetricsExplorerViewAttributes = { | ||
name: i18n.translate('xpack.infra.savedView.defaultViewNameHosts', { | ||
defaultMessage: 'Default view', | ||
}) as NonEmptyString, | ||
isDefault: false, | ||
isStatic: true, | ||
options: { | ||
aggregation: 'avg', | ||
metrics: [ | ||
{ | ||
aggregation: 'avg', | ||
field: 'system.cpu.total.norm.pct', | ||
color: 'color0', | ||
}, | ||
{ | ||
aggregation: 'avg', | ||
field: 'kubernetes.pod.cpu.usage.node.pct', | ||
color: 'color1', | ||
}, | ||
{ | ||
aggregation: 'avg', | ||
field: 'docker.cpu.total.pct', | ||
color: 'color2', | ||
}, | ||
], | ||
source: 'default', | ||
}, | ||
chartOptions: { | ||
type: 'line', | ||
yAxisMode: 'fromZero', | ||
stack: false, | ||
}, | ||
currentTimerange: { | ||
from: 'now-1h', | ||
to: 'now', | ||
interval: '>=10s', | ||
}, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note: for the attributes of this saved object, the configuration has always been dynamic and not strictly typed. As they can vary depending on the user usage on the page, I left it open to all the attributes as it was before, marking only those that I'm sure will be present in the response.
This applies to any other attributes definition you'll find for this attribute's saved object.