[SLOs] Added createdBy and updatedBy fields in summary documents !! (#205784)

## Summary

Added createdBy and updatedBy fields in summary documents !!

This will make easier to identify which user have added the SLO and
which user last updated the SLO. It's especially helpful where there are
100s of SLOs defined.


<img width="1728" alt="image"
src="https://github.com/user-attachments/assets/ee7bb4d4-a8ea-40c4-8d91-06c32c9b0ba6"
/>

---------

Co-authored-by: Kevin Delemme <kdelemme@gmail.com>
Co-authored-by: Kevin Delemme <kevin.delemme@elastic.co>
This commit is contained in:
Shahzad 2025-01-20 13:38:04 +01:00 committed by GitHub
parent a555d57261
commit 39119b553e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
41 changed files with 391 additions and 142 deletions

View file

@ -77,23 +77,29 @@ function isValidId(id: string): boolean {
return validLength && /^[a-z0-9-_]+$/.test(id);
}
const sloDefinitionSchema = t.type({
id: sloIdSchema,
name: t.string,
description: t.string,
indicator: indicatorSchema,
timeWindow: timeWindowSchema,
budgetingMethod: budgetingMethodSchema,
objective: objectiveSchema,
settings: settingsSchema,
revision: t.number,
enabled: t.boolean,
tags: tagsSchema,
createdAt: dateType,
updatedAt: dateType,
groupBy: groupBySchema,
version: t.number,
});
const sloDefinitionSchema = t.intersection([
t.type({
id: sloIdSchema,
name: t.string,
description: t.string,
indicator: indicatorSchema,
timeWindow: timeWindowSchema,
budgetingMethod: budgetingMethodSchema,
objective: objectiveSchema,
settings: settingsSchema,
revision: t.number,
enabled: t.boolean,
tags: tagsSchema,
createdAt: dateType,
updatedAt: dateType,
groupBy: groupBySchema,
version: t.number,
}),
t.partial({
createdBy: t.string,
updatedBy: t.string,
}),
]);
export {
budgetingMethodSchema,

View file

@ -41104,7 +41104,6 @@
"xpack.slo.sloAlertsWrapper.sLOsIncludedFlexItemLabel": "{numOfSlos, number} {numOfSlos, plural, other {SLO}} inclus",
"xpack.slo.sloAlertsWrapper.sLOsIncludedFlexItemLabel.instancesCount": "({count, number} {count, plural, one {Instance} other {Instances}})",
"xpack.slo.sloAlertsWrapper.sLOsIncludedFlexItemLabel.withInstances": "{numOfSlos, number} {numOfSlos, plural, other {SLO}}{instances} inclus",
"xpack.slo.sloCardItem.euiPanel.lastUpdatedLabel": "{status}, dernière mise à jour : {value}",
"xpack.slo.sloCardItemBadges.remoteBadgeLabel": "Distant",
"xpack.slo.sloConfiguration.euiSwitch.showAllGroupByLabel": "Afficher toutes les instances de regroupement associées ",
"xpack.slo.sloCreatePageTitle": "Créer un nouveau SLO",
@ -41128,8 +41127,6 @@
"xpack.slo.sloDetails.headerControl.manageRules": "Gérer {count, plural, one {règle} other {règles}} du taux d'avancement",
"xpack.slo.sloDetails.headerTitle.calloutDescription": "Il s'agit d'un SLO distant qui appartient à une autre instance Kibana. Il est extrait du cluster distant : {remoteName} avec l'URL Kibana {kibanaUrl}.",
"xpack.slo.sloDetails.headerTitle.calloutMessage": "SLO distant",
"xpack.slo.sloDetails.headerTitle.createdMessage": "Créé le",
"xpack.slo.sloDetails.headerTitle.lastUpdatedMessage": "Dernière mise à jour le",
"xpack.slo.sloDetails.healthCallout.buttonTransformLabel": "Inspecter la transformation",
"xpack.slo.sloDetails.healthCallout.copyToClipboard": "Copier dans le presse-papiers",
"xpack.slo.sloDetails.healthCallout.description": "{count, plural, one {La transformation suivante est} other {Les transformations suivantes sont} } dans un état défectueux :",

View file

@ -40961,7 +40961,6 @@
"xpack.slo.sloAlertsWrapper.sLOsIncludedFlexItemLabel": "{numOfSlos, number} {numOfSlos, plural, other {SLO}}が含まれます",
"xpack.slo.sloAlertsWrapper.sLOsIncludedFlexItemLabel.instancesCount": "({count, number} {count, plural, other {インスタンス}})",
"xpack.slo.sloAlertsWrapper.sLOsIncludedFlexItemLabel.withInstances": "{numOfSlos, number} {numOfSlos, plural, other {SLO}}{instances}が含まれます",
"xpack.slo.sloCardItem.euiPanel.lastUpdatedLabel": "{status}、前回更新日:{value}",
"xpack.slo.sloCardItemBadges.remoteBadgeLabel": "リモート",
"xpack.slo.sloConfiguration.euiSwitch.showAllGroupByLabel": "インスタンス別にすべての関連するグループを表示",
"xpack.slo.sloCreatePageTitle": "新規SLOを作成",
@ -40985,8 +40984,6 @@
"xpack.slo.sloDetails.headerControl.manageRules": "バーンレート{count, plural, other {ルール}}を管理",
"xpack.slo.sloDetails.headerTitle.calloutDescription": "これは別のKibanaインスタンスに属するリモートSLOです。リモートクラスターから取得されますKibana URL {kibanaUrl}の{remoteName}。",
"xpack.slo.sloDetails.headerTitle.calloutMessage": "リモートSLO",
"xpack.slo.sloDetails.headerTitle.createdMessage": "作成日時",
"xpack.slo.sloDetails.headerTitle.lastUpdatedMessage": "最終更新日",
"xpack.slo.sloDetails.healthCallout.buttonTransformLabel": "変換を検査",
"xpack.slo.sloDetails.healthCallout.copyToClipboard": "クリップボードにコピー",
"xpack.slo.sloDetails.healthCallout.description": "次の{count, plural, other {変換は} }正常ではない状態です。",

View file

@ -40375,7 +40375,6 @@
"xpack.slo.sloAlertsWrapper.sLOsIncludedFlexItemLabel": "已包括 {numOfSlos, number} 个 {numOfSlos, plural, other {SLO}}",
"xpack.slo.sloAlertsWrapper.sLOsIncludedFlexItemLabel.instancesCount": "{count, number} 个{count, plural, other {实例}}",
"xpack.slo.sloAlertsWrapper.sLOsIncludedFlexItemLabel.withInstances": "已包括 {numOfSlos, number} 个 {numOfSlos, plural, other {SLO}}{instances}",
"xpack.slo.sloCardItem.euiPanel.lastUpdatedLabel": "{status},上次更新时间:{value}",
"xpack.slo.sloCardItemBadges.remoteBadgeLabel": "远程",
"xpack.slo.sloConfiguration.euiSwitch.showAllGroupByLabel": "显示所有相关分组依据实例",
"xpack.slo.sloCreatePageTitle": "创建新 SLO",
@ -40399,8 +40398,6 @@
"xpack.slo.sloDetails.headerControl.manageRules": "管理消耗速度{count, plural, other {规则}}",
"xpack.slo.sloDetails.headerTitle.calloutDescription": "这是一个远程 SLO它属于其他 Kibana 实例。它是使用 Kibana URL {kibanaUrl} 从远程集群 {remoteName} 提取的。",
"xpack.slo.sloDetails.headerTitle.calloutMessage": "远程 SLO",
"xpack.slo.sloDetails.headerTitle.createdMessage": "创建日期",
"xpack.slo.sloDetails.headerTitle.lastUpdatedMessage": "上次更新时间",
"xpack.slo.sloDetails.healthCallout.buttonTransformLabel": "检查转换",
"xpack.slo.sloDetails.healthCallout.copyToClipboard": "复制到剪贴板",
"xpack.slo.sloDetails.healthCallout.description": "以下{count, plural, other {转换}}处于运行不正常状态:",

View file

@ -54,7 +54,7 @@ export const SUPPRESSED_PRIORITY_ACTION = {
};
export const SLO_MODEL_VERSION = 2;
export const SLO_RESOURCES_VERSION = 3.3;
export const SLO_RESOURCES_VERSION = 3.4;
export const SLO_RESOURCES_VERSION_MAJOR = 3;
export const SLO_COMPONENT_TEMPLATE_MAPPINGS_NAME = '.slo-observability.sli-mappings';

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { EuiFlexGroup, EuiFlexItem, EuiSkeletonText, EuiText } from '@elastic/eui';
import { EuiFlexGroup, EuiFlexItem, EuiMarkdownFormat, EuiSkeletonText } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { SLOWithSummaryResponse } from '@kbn/slo-schema';
import moment from 'moment';
@ -37,30 +37,43 @@ export function HeaderTitle({ isLoading, slo }: Props) {
<SloStatusBadge slo={slo} />
<SloStateBadge slo={slo} />
<SloRemoteBadge slo={slo} />
<EuiFlexItem grow={false}>
<EuiText color="subdued" size="xs">
<strong>
{i18n.translate('xpack.slo.sloDetails.headerTitle.lastUpdatedMessage', {
defaultMessage: 'Last updated on',
<EuiFlexGroup
direction="row"
gutterSize="m"
alignItems="center"
justifyContent="flexStart"
responsive={false}
wrap={true}
>
<EuiFlexItem grow={false}>
<EuiMarkdownFormat textSize="xs" color="subdued">
{i18n.translate('xpack.slo.sloDetails.headerTitle.lastUpdatedLabel', {
defaultMessage: '**Last updated by** {updatedBy} **on** {updatedAt}',
values: {
updatedBy: slo.updatedBy ?? NOT_AVAILABLE_LABEL,
updatedAt: moment(slo.updatedAt).format('ll'),
},
})}
</strong>
&nbsp;
{moment(slo.updatedAt).format('ll')}
</EuiText>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiText color="subdued" size="xs">
<strong>
{i18n.translate('xpack.slo.sloDetails.headerTitle.createdMessage', {
defaultMessage: 'Created on',
</EuiMarkdownFormat>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiMarkdownFormat textSize="xs" color="subdued">
{i18n.translate('xpack.slo.sloDetails.headerTitle.createdLabel', {
defaultMessage: '**Created by** {createdBy} **on** {createdAt}',
values: {
createdBy: slo.createdBy ?? NOT_AVAILABLE_LABEL,
createdAt: moment(slo.createdAt).format('ll'),
},
})}
</strong>
&nbsp;
{moment(slo.createdAt).format('ll')}
</EuiText>
</EuiFlexItem>
</EuiMarkdownFormat>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexGroup>
<SLOGroupings slo={slo} />
</EuiFlexGroup>
);
}
const NOT_AVAILABLE_LABEL = i18n.translate('xpack.slo.sloDetails.headerTitle.notAvailableLabel', {
defaultMessage: 'n/a',
});

View file

@ -149,8 +149,8 @@ export function SloCardItem({ slo, rules, activeAlerts, historicalSummary, refet
`}
title={
slo.summary.summaryUpdatedAt
? i18n.translate('xpack.slo.sloCardItem.euiPanel.lastUpdatedLabel', {
defaultMessage: '{status}, Last updated: {value}',
? i18n.translate('xpack.slo.sloCardItem.euiPanel.lastSummaryUpdatedLabel', {
defaultMessage: '{status}, Last summary updated: {value}',
values: {
status: slo.summary.status,
value: moment(slo.summary.summaryUpdatedAt).fromNow(),

View file

@ -41,7 +41,7 @@ export function SLOCardItemInstanceBadge({ slo }: Props) {
data-test-subj="o11ySlosSeeAllInstanceIdsBadge"
>
{`${i18n.translate('xpack.slo.extraInstanceIds.badge', {
defaultMessage: '+{count, plural, one {# more instance} other {# more instances}}',
defaultMessage: '+{count, plural, one {# instance} other {# instances}}',
values: {
count: entries.length - 1,
},

View file

@ -68,7 +68,7 @@ export function SLOGroupings({ slo, direction = 'row', gutterSize = 's', truncat
<EuiButtonEmpty data-test-subj="accordion" flush="left">
{`(${i18n.translate('xpack.slo.andLabel', {
defaultMessage:
'and {count, plural, one {# more instance} other {# more instances}}',
'and {count, plural, one {# instance} other {# instances}}',
values: {
count: rest.length,
},

View file

@ -135,6 +135,20 @@ export const getSLOSummaryMappingsTemplate = (
},
},
},
createdAt: {
type: 'date',
format: 'date_optional_time||epoch_millis',
},
updatedAt: {
type: 'date',
format: 'date_optional_time||epoch_millis',
},
createdBy: {
type: 'keyword',
},
updatedBy: {
type: 'keyword',
},
},
},
sliValue: {

View file

@ -234,6 +234,21 @@ export const getSLOSummaryPipelineTemplate = (
source: getBurnRateSource('oneDayBurnRate'),
},
},
// >= 8.18: add updatedBy, createdBy
{
set: {
field: 'slo.updatedBy',
value: slo.updatedBy,
ignore_failure: true,
},
},
{
set: {
field: 'slo.createdBy',
value: slo.createdBy,
ignore_failure: true,
},
},
],
_meta: {
description: `Ingest pipeline for SLO summary data [id: ${slo.id}, revision: ${slo.revision}]`,

View file

@ -143,7 +143,7 @@ describe('slo transform template', () => {
},
defer_validation: true,
_meta: {
version: 3.3,
version: 3.4,
managed: true,
managed_by: 'observability',
},
@ -247,7 +247,7 @@ describe('slo transform template', () => {
},
defer_validation: true,
_meta: {
version: 3.3,
version: 3.4,
managed: true,
managed_by: 'observability',
},

View file

@ -86,12 +86,13 @@ const createSLORoute = createSloServerRoute({
},
},
params: createSLOParamsSchema,
handler: async ({ context, response, params, logger, request, plugins, corePlugins }) => {
handler: async ({ context, params, logger, request, plugins, corePlugins }) => {
await assertPlatinumLicense(plugins);
const sloContext = await context.slo;
const dataViews = await plugins.dataViews.start();
const core = await context.core;
const userId = core.security.authc.getCurrentUser()?.username!;
const scopedClusterClient = core.elasticsearch.client;
const esClient = core.elasticsearch.client.asCurrentUser;
const soClient = core.savedObjects.client;
@ -127,7 +128,8 @@ const createSLORoute = createSloServerRoute({
summaryTransformManager,
logger,
spaceId,
basePath
basePath,
userId
);
return await executeWithErrorHandler(() => createSLO.execute(params.body));
@ -153,6 +155,7 @@ const inspectSLORoute = createSloServerRoute({
const core = await context.core;
const scopedClusterClient = core.elasticsearch.client;
const esClient = core.elasticsearch.client.asCurrentUser;
const username = core.security.authc.getCurrentUser()?.username!;
const soClient = core.savedObjects.client;
const repository = new KibanaSavedObjectsSLORepository(soClient, logger);
const dataViewsService = await dataViews.dataViewsServiceFactory(soClient, esClient);
@ -181,7 +184,8 @@ const inspectSLORoute = createSloServerRoute({
summaryTransformManager,
logger,
spaceId,
basePath
basePath,
username
);
return await executeWithErrorHandler(() => createSLO.inspect(params.body));
@ -208,6 +212,8 @@ const updateSLORoute = createSloServerRoute({
const core = await context.core;
const scopedClusterClient = core.elasticsearch.client;
const esClient = core.elasticsearch.client.asCurrentUser;
const userId = core.security.authc.getCurrentUser()?.username!;
const soClient = core.savedObjects.client;
const dataViewsService = await dataViews.dataViewsServiceFactory(soClient, esClient);
const repository = new KibanaSavedObjectsSLORepository(soClient, logger);
@ -236,7 +242,8 @@ const updateSLORoute = createSloServerRoute({
scopedClusterClient,
logger,
spaceId,
basePath
basePath,
userId
);
return await executeWithErrorHandler(() => updateSLO.execute(params.path.id, params.body));
@ -320,8 +327,8 @@ const getSLORoute = createSloServerRoute({
const repository = new KibanaSavedObjectsSLORepository(soClient, logger);
const burnRatesClient = new DefaultBurnRatesClient(esClient);
const summaryClient = new DefaultSummaryClient(esClient, burnRatesClient);
const defintionClient = new SloDefinitionClient(repository, esClient, logger);
const getSLO = new GetSLO(defintionClient, summaryClient);
const definitionClient = new SloDefinitionClient(repository, esClient, logger);
const getSLO = new GetSLO(definitionClient, summaryClient);
return await executeWithErrorHandler(() =>
getSLO.execute(params.path.id, spaceId, params.query)

View file

@ -7,7 +7,7 @@ Array [
"description": "Ingest pipeline for SLO rollup data",
"managed": true,
"managed_by": "observability",
"version": 3.3,
"version": 3.4,
},
"description": "Ingest pipeline for SLO rollup data [id: unique-id, revision: 1]",
"id": ".slo-observability.sli.pipeline-unique-id-1",
@ -45,7 +45,7 @@ Array [
],
"date_rounding": "M",
"field": "@timestamp",
"index_name_prefix": ".slo-observability.sli-v3.3.",
"index_name_prefix": ".slo-observability.sli-v3.4.",
},
},
Object {
@ -120,6 +120,7 @@ Array [
"slo": Object {
"budgetingMethod": "occurrences",
"createdAt": "2024-01-01T00:00:00.000Z",
"createdBy": "some-user-id",
"description": "irrelevant",
"groupBy": "*",
"groupings": Object {},
@ -148,6 +149,7 @@ Array [
"type": "rolling",
},
"updatedAt": "2024-01-01T00:00:00.000Z",
"updatedBy": "some-user-id",
},
"spaceId": "some-space",
"status": "NO_DATA",
@ -160,7 +162,7 @@ Array [
},
},
"id": "slo-unique-id",
"index": ".slo-observability.summary-v3.3.temp",
"index": ".slo-observability.summary-v3.4.temp",
"refresh": true,
},
]

View file

@ -122,6 +122,7 @@ exports[`ResetSLO happy path resets all associated resources 6`] = `
Object {
"budgetingMethod": "occurrences",
"createdAt": 2023-01-01T00:00:00.000Z,
"createdBy": "irrelevant",
"description": "irrelevant",
"enabled": true,
"groupBy": "*",
@ -165,6 +166,7 @@ exports[`ResetSLO happy path resets all associated resources 6`] = `
"type": "rolling",
},
"updatedAt": 2023-01-01T00:00:00.000Z,
"updatedBy": "irrelevant",
"version": 1,
},
],
@ -203,7 +205,7 @@ exports[`ResetSLO happy path resets all associated resources 8`] = `
"description": "Ingest pipeline for SLO rollup data",
"managed": true,
"managed_by": "observability",
"version": 3.3,
"version": 3.4,
},
"description": "Ingest pipeline for SLO rollup data [id: irrelevant, revision: 1]",
"id": ".slo-observability.sli.pipeline-irrelevant-1",
@ -241,7 +243,7 @@ exports[`ResetSLO happy path resets all associated resources 8`] = `
],
"date_rounding": "M",
"field": "@timestamp",
"index_name_prefix": ".slo-observability.sli-v3.3.",
"index_name_prefix": ".slo-observability.sli-v3.4.",
},
},
Object {
@ -275,7 +277,7 @@ exports[`ResetSLO happy path resets all associated resources 8`] = `
"description": "Ingest pipeline for SLO summary data [id: irrelevant, revision: 1]",
"managed": true,
"managed_by": "observability",
"version": 3.3,
"version": 3.4,
},
"description": "Ingest pipeline for SLO summary data [id: irrelevant, revision: 1]",
"id": ".slo-observability.summary.pipeline-irrelevant-1",
@ -525,6 +527,20 @@ exports[`ResetSLO happy path resets all associated resources 8`] = `
}",
},
},
Object {
"set": Object {
"field": "slo.updatedBy",
"ignore_failure": true,
"value": "irrelevant",
},
},
Object {
"set": Object {
"field": "slo.createdBy",
"ignore_failure": true,
"value": "irrelevant",
},
},
],
},
],
@ -549,6 +565,7 @@ exports[`ResetSLO happy path resets all associated resources 9`] = `
Object {
"budgetingMethod": "occurrences",
"createdAt": 2023-01-01T00:00:00.000Z,
"createdBy": "irrelevant",
"description": "irrelevant",
"enabled": true,
"groupBy": "*",
@ -592,6 +609,7 @@ exports[`ResetSLO happy path resets all associated resources 9`] = `
"type": "rolling",
},
"updatedAt": 2023-01-01T00:00:00.000Z,
"updatedBy": "irrelevant",
"version": 1,
},
],
@ -668,6 +686,7 @@ exports[`ResetSLO happy path resets all associated resources 11`] = `
"slo": Object {
"budgetingMethod": "occurrences",
"createdAt": "2023-01-01T00:00:00.000Z",
"createdBy": "irrelevant",
"description": "irrelevant",
"groupBy": "*",
"groupings": Object {},
@ -700,6 +719,7 @@ exports[`ResetSLO happy path resets all associated resources 11`] = `
"type": "rolling",
},
"updatedAt": "2023-01-01T00:00:00.000Z",
"updatedBy": "irrelevant",
},
"spaceId": "some-space",
"status": "NO_DATA",
@ -712,7 +732,7 @@ exports[`ResetSLO happy path resets all associated resources 11`] = `
},
},
"id": "slo-irrelevant",
"index": ".slo-observability.summary-v3.3.temp",
"index": ".slo-observability.summary-v3.4.temp",
"refresh": true,
},
],

View file

@ -9,6 +9,7 @@ Object {
"slo": Object {
"budgetingMethod": "occurrences",
"createdAt": 2024-01-01T00:00:00.000Z,
"createdBy": "irrelevant",
"description": "irrelevant",
"enabled": true,
"groupBy": "*",
@ -54,6 +55,7 @@ Object {
"type": "rolling",
},
"updatedAt": 2024-01-01T00:00:00.000Z,
"updatedBy": "irrelevant",
"version": 1,
},
}

View file

@ -51,7 +51,8 @@ describe('CreateSLO', () => {
mockSummaryTransformManager,
mockLogger,
'some-space',
httpServiceMock.createStartContract().basePath
httpServiceMock.createStartContract().basePath,
'some-user-id'
);
});

View file

@ -40,7 +40,8 @@ export class CreateSLO {
private summaryTransformManager: TransformManager,
private logger: Logger,
private spaceId: string,
private basePath: IBasePath
private basePath: IBasePath,
private username: string
) {}
public async execute(params: CreateSLOParams): Promise<CreateSLOResponse> {
@ -217,6 +218,8 @@ export class CreateSLO {
tags: params.tags ?? [],
createdAt: now,
updatedAt: now,
createdBy: this.username,
updatedBy: this.username,
groupBy: !!params.groupBy ? params.groupBy : ALL_VALUE,
version: SLO_MODEL_VERSION,
};

View file

@ -58,6 +58,8 @@ describe('FindSLO', () => {
id: slo.id,
name: 'irrelevant',
description: 'irrelevant',
createdBy: 'irrelevant',
updatedBy: 'irrelevant',
budgetingMethod: 'occurrences',
indicator: {
params: {

View file

@ -206,6 +206,8 @@ export const createSLO = (params: Partial<SLODefinition> = {}): SLODefinition =>
revision: 1,
createdAt: now,
updatedAt: now,
createdBy: 'irrelevant',
updatedBy: 'irrelevant',
version: SLO_MODEL_VERSION,
...params,
});

View file

@ -63,6 +63,8 @@ describe('GetSLO', () => {
name: 'irrelevant',
description: 'irrelevant',
budgetingMethod: 'occurrences',
createdBy: 'irrelevant',
updatedBy: 'irrelevant',
indicator: {
params: {
environment: 'irrelevant',

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server';
import { SavedObject, SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server';
import { Logger } from '@kbn/core/server';
import { ALL_VALUE, Paginated, Pagination, sloDefinitionSchema } from '@kbn/slo-schema';
import { isLeft } from 'fp-ts/lib/Either';
@ -79,7 +79,7 @@ export class KibanaSavedObjectsSLORepository implements SLORepository {
throw new SLONotFound(`SLO [${id}] not found`);
}
const slo = this.toSLO(response.saved_objects[0].attributes);
const slo = this.toSLO(response.saved_objects[0]);
if (slo === undefined) {
throw new Error('Invalid stored SLO');
}
@ -116,7 +116,7 @@ export class KibanaSavedObjectsSLORepository implements SLORepository {
});
return response.saved_objects
.map((slo) => this.toSLO(slo.attributes))
.map((slo) => this.toSLO(slo))
.filter((slo) => slo !== undefined) as SLODefinition[];
}
@ -141,12 +141,13 @@ export class KibanaSavedObjectsSLORepository implements SLORepository {
perPage: response.per_page,
page: response.page,
results: response.saved_objects
.map((savedObject) => this.toSLO(savedObject.attributes))
.map((savedObject) => this.toSLO(savedObject))
.filter((slo) => slo !== undefined) as SLODefinition[],
};
}
toSLO(storedSLO: StoredSLODefinition): SLODefinition | undefined {
toSLO(storedSLOObject: SavedObject<StoredSLODefinition>): SLODefinition | undefined {
const storedSLO = storedSLOObject.attributes;
const result = sloDefinitionSchema.decode({
...storedSLO,
// groupBy was added in 8.10.0
@ -160,6 +161,8 @@ export class KibanaSavedObjectsSLORepository implements SLORepository {
{ preventInitialBackfill: false, syncDelay: '1m', frequency: '1m' },
storedSLO.settings
),
createdBy: storedSLO.createdBy ?? storedSLOObject.created_by,
updatedBy: storedSLO.updatedBy ?? storedSLOObject.updated_by,
});
if (isLeft(result)) {

View file

@ -5,12 +5,12 @@ Object {
"_meta": Object {
"managed": true,
"managed_by": "observability",
"version": 3.3,
"version": 3.4,
},
"defer_validation": true,
"description": "Summarise the rollup data of SLO: irrelevant [id: irrelevant, revision: 1].",
"dest": Object {
"index": ".slo-observability.summary-v3.3",
"index": ".slo-observability.summary-v3.4",
"pipeline": ".slo-observability.summary.pipeline-irrelevant-1",
},
"frequency": "1m",
@ -212,7 +212,7 @@ Object {
"unattended": true,
},
"source": Object {
"index": ".slo-observability.sli-v3.3*",
"index": ".slo-observability.sli-v3.4*",
"query": Object {
"bool": Object {
"filter": Array [
@ -253,12 +253,12 @@ Object {
"_meta": Object {
"managed": true,
"managed_by": "observability",
"version": 3.3,
"version": 3.4,
},
"defer_validation": true,
"description": "Summarise the rollup data of SLO: irrelevant [id: irrelevant, revision: 1].",
"dest": Object {
"index": ".slo-observability.summary-v3.3",
"index": ".slo-observability.summary-v3.4",
"pipeline": ".slo-observability.summary.pipeline-irrelevant-1",
},
"frequency": "1m",
@ -460,7 +460,7 @@ Object {
"unattended": true,
},
"source": Object {
"index": ".slo-observability.sli-v3.3*",
"index": ".slo-observability.sli-v3.4*",
"query": Object {
"bool": Object {
"filter": Array [
@ -501,12 +501,12 @@ Object {
"_meta": Object {
"managed": true,
"managed_by": "observability",
"version": 3.3,
"version": 3.4,
},
"defer_validation": true,
"description": "Summarise the rollup data of SLO: irrelevant [id: irrelevant, revision: 1].",
"dest": Object {
"index": ".slo-observability.summary-v3.3",
"index": ".slo-observability.summary-v3.4",
"pipeline": ".slo-observability.summary.pipeline-irrelevant-1",
},
"frequency": "1m",
@ -708,7 +708,7 @@ Object {
"unattended": true,
},
"source": Object {
"index": ".slo-observability.sli-v3.3*",
"index": ".slo-observability.sli-v3.4*",
"query": Object {
"bool": Object {
"filter": Array [

View file

@ -5,12 +5,12 @@ Object {
"_meta": Object {
"managed": true,
"managed_by": "observability",
"version": 3.3,
"version": 3.4,
},
"defer_validation": true,
"description": "Summarise the rollup data of SLO: irrelevant [id: irrelevant, revision: 1].",
"dest": Object {
"index": ".slo-observability.summary-v3.3",
"index": ".slo-observability.summary-v3.4",
"pipeline": ".slo-observability.summary.pipeline-irrelevant-1",
},
"frequency": "1m",
@ -236,7 +236,7 @@ Object {
"unattended": true,
},
"source": Object {
"index": ".slo-observability.sli-v3.3*",
"index": ".slo-observability.sli-v3.4*",
"query": Object {
"bool": Object {
"filter": Array [

View file

@ -5,12 +5,12 @@ Object {
"_meta": Object {
"managed": true,
"managed_by": "observability",
"version": 3.3,
"version": 3.4,
},
"defer_validation": true,
"description": "Summarise the rollup data of SLO: irrelevant [id: irrelevant, revision: 1].",
"dest": Object {
"index": ".slo-observability.summary-v3.3",
"index": ".slo-observability.summary-v3.4",
"pipeline": ".slo-observability.summary.pipeline-irrelevant-1",
},
"frequency": "1m",
@ -212,7 +212,7 @@ Object {
"unattended": true,
},
"source": Object {
"index": ".slo-observability.sli-v3.3*",
"index": ".slo-observability.sli-v3.4*",
"query": Object {
"bool": Object {
"filter": Array [

View file

@ -31,7 +31,7 @@ export interface EsSummaryDocument {
};
name: string | null;
};
// common fields
// SLO definition
slo: {
// >= 8.14: Add indicator.params on the temporary summary as well as real summary through summary pipeline
indicator: { type: IndicatorTypes } | Indicator;
@ -48,6 +48,8 @@ export interface EsSummaryDocument {
tags: string[];
createdAt?: string; // >= 8.14
updatedAt?: string; // >= 8.14
createdBy?: string; // >= 8.18
updatedBy?: string; // >= 8.18
};
goodEvents: number;
totalEvents: number;
@ -132,6 +134,9 @@ export function createTempSummaryDocument(
tags: slo.tags,
createdAt: slo.createdAt.toISOString(), // added in 8.14, i.e. might be undefined
updatedAt: slo.updatedAt.toISOString(), // added in 8.14, i.e. might be undefined
// Added in 8.18
createdBy: slo.createdBy,
updatedBy: slo.updatedBy,
},
goodEvents: 0,
totalEvents: 0,

View file

@ -360,12 +360,12 @@ Object {
"_meta": Object {
"managed": true,
"managed_by": "observability",
"version": 3.3,
"version": 3.4,
},
"defer_validation": true,
"description": "Rolled-up SLI data for SLO: irrelevant [id: irrelevant, revision: 1]",
"dest": Object {
"index": ".slo-observability.sli-v3.3",
"index": ".slo-observability.sli-v3.4",
"pipeline": ".slo-observability.sli.pipeline-irrelevant-1",
},
"frequency": "1m",
@ -508,12 +508,12 @@ Object {
"_meta": Object {
"managed": true,
"managed_by": "observability",
"version": 3.3,
"version": 3.4,
},
"defer_validation": true,
"description": "Rolled-up SLI data for SLO: irrelevant [id: irrelevant, revision: 1]",
"dest": Object {
"index": ".slo-observability.sli-v3.3",
"index": ".slo-observability.sli-v3.4",
"pipeline": ".slo-observability.sli.pipeline-irrelevant-1",
},
"frequency": "1m",
@ -656,12 +656,12 @@ Object {
"_meta": Object {
"managed": true,
"managed_by": "observability",
"version": 3.3,
"version": 3.4,
},
"defer_validation": true,
"description": "Rolled-up SLI data for SLO: irrelevant [id: irrelevant, revision: 1]",
"dest": Object {
"index": ".slo-observability.sli-v3.3",
"index": ".slo-observability.sli-v3.4",
"pipeline": ".slo-observability.sli.pipeline-irrelevant-1",
},
"frequency": "1m",

View file

@ -336,12 +336,12 @@ Object {
"_meta": Object {
"managed": true,
"managed_by": "observability",
"version": 3.3,
"version": 3.4,
},
"defer_validation": true,
"description": "Rolled-up SLI data for SLO: irrelevant [id: irrelevant, revision: 1]",
"dest": Object {
"index": ".slo-observability.sli-v3.3",
"index": ".slo-observability.sli-v3.4",
"pipeline": ".slo-observability.sli.pipeline-irrelevant-1",
},
"frequency": "1m",
@ -471,12 +471,12 @@ Object {
"_meta": Object {
"managed": true,
"managed_by": "observability",
"version": 3.3,
"version": 3.4,
},
"defer_validation": true,
"description": "Rolled-up SLI data for SLO: irrelevant [id: irrelevant, revision: 1]",
"dest": Object {
"index": ".slo-observability.sli-v3.3",
"index": ".slo-observability.sli-v3.4",
"pipeline": ".slo-observability.sli.pipeline-irrelevant-1",
},
"frequency": "1m",
@ -606,12 +606,12 @@ Object {
"_meta": Object {
"managed": true,
"managed_by": "observability",
"version": 3.3,
"version": 3.4,
},
"defer_validation": true,
"description": "Rolled-up SLI data for SLO: irrelevant [id: irrelevant, revision: 1]",
"dest": Object {
"index": ".slo-observability.sli-v3.3",
"index": ".slo-observability.sli-v3.4",
"pipeline": ".slo-observability.sli.pipeline-irrelevant-1",
},
"frequency": "1m",

View file

@ -77,12 +77,12 @@ Object {
"_meta": Object {
"managed": true,
"managed_by": "observability",
"version": 3.3,
"version": 3.4,
},
"defer_validation": true,
"description": "Rolled-up SLI data for SLO: irrelevant [id: irrelevant, revision: 1]",
"dest": Object {
"index": ".slo-observability.sli-v3.3",
"index": ".slo-observability.sli-v3.4",
"pipeline": ".slo-observability.sli.pipeline-irrelevant-1",
},
"frequency": "1m",
@ -206,12 +206,12 @@ Object {
"_meta": Object {
"managed": true,
"managed_by": "observability",
"version": 3.3,
"version": 3.4,
},
"defer_validation": true,
"description": "Rolled-up SLI data for SLO: irrelevant [id: irrelevant, revision: 1]",
"dest": Object {
"index": ".slo-observability.sli-v3.3",
"index": ".slo-observability.sli-v3.4",
"pipeline": ".slo-observability.sli.pipeline-irrelevant-1",
},
"frequency": "1m",
@ -335,12 +335,12 @@ Object {
"_meta": Object {
"managed": true,
"managed_by": "observability",
"version": 3.3,
"version": 3.4,
},
"defer_validation": true,
"description": "Rolled-up SLI data for SLO: irrelevant [id: irrelevant, revision: 1]",
"dest": Object {
"index": ".slo-observability.sli-v3.3",
"index": ".slo-observability.sli-v3.4",
"pipeline": ".slo-observability.sli.pipeline-irrelevant-1",
},
"frequency": "1m",

View file

@ -118,12 +118,12 @@ Object {
"_meta": Object {
"managed": true,
"managed_by": "observability",
"version": 3.3,
"version": 3.4,
},
"defer_validation": true,
"description": "Rolled-up SLI data for SLO: irrelevant [id: irrelevant, revision: 1]",
"dest": Object {
"index": ".slo-observability.sli-v3.3",
"index": ".slo-observability.sli-v3.4",
"pipeline": ".slo-observability.sli.pipeline-irrelevant-1",
},
"frequency": "1m",
@ -220,12 +220,12 @@ Object {
"_meta": Object {
"managed": true,
"managed_by": "observability",
"version": 3.3,
"version": 3.4,
},
"defer_validation": true,
"description": "Rolled-up SLI data for SLO: irrelevant [id: irrelevant, revision: 1]",
"dest": Object {
"index": ".slo-observability.sli-v3.3",
"index": ".slo-observability.sli-v3.4",
"pipeline": ".slo-observability.sli.pipeline-irrelevant-1",
},
"frequency": "1m",
@ -322,12 +322,12 @@ Object {
"_meta": Object {
"managed": true,
"managed_by": "observability",
"version": 3.3,
"version": 3.4,
},
"defer_validation": true,
"description": "Rolled-up SLI data for SLO: irrelevant [id: irrelevant, revision: 1]",
"dest": Object {
"index": ".slo-observability.sli-v3.3",
"index": ".slo-observability.sli-v3.4",
"pipeline": ".slo-observability.sli.pipeline-irrelevant-1",
},
"frequency": "1m",

View file

@ -117,12 +117,12 @@ Object {
"_meta": Object {
"managed": true,
"managed_by": "observability",
"version": 3.3,
"version": 3.4,
},
"defer_validation": true,
"description": "Rolled-up SLI data for SLO: irrelevant [id: irrelevant, revision: 1]",
"dest": Object {
"index": ".slo-observability.sli-v3.3",
"index": ".slo-observability.sli-v3.4",
"pipeline": ".slo-observability.sli.pipeline-irrelevant-1",
},
"frequency": "1m",
@ -257,12 +257,12 @@ Object {
"_meta": Object {
"managed": true,
"managed_by": "observability",
"version": 3.3,
"version": 3.4,
},
"defer_validation": true,
"description": "Rolled-up SLI data for SLO: irrelevant [id: irrelevant, revision: 1]",
"dest": Object {
"index": ".slo-observability.sli-v3.3",
"index": ".slo-observability.sli-v3.4",
"pipeline": ".slo-observability.sli.pipeline-irrelevant-1",
},
"frequency": "1m",

View file

@ -5,12 +5,12 @@ Object {
"_meta": Object {
"managed": true,
"managed_by": "observability",
"version": 3.3,
"version": 3.4,
},
"defer_validation": true,
"description": "Rolled-up SLI data for SLO: irrelevant [id: irrelevant, revision: 1]",
"dest": Object {
"index": ".slo-observability.sli-v3.3",
"index": ".slo-observability.sli-v3.4",
"pipeline": ".slo-observability.sli.pipeline-irrelevant-1",
},
"frequency": "1m",

View file

@ -33,12 +33,12 @@ Object {
"_meta": Object {
"managed": true,
"managed_by": "observability",
"version": 3.3,
"version": 3.4,
},
"defer_validation": true,
"description": "Rolled-up SLI data for SLO: irrelevant [id: irrelevant, revision: 1]",
"dest": Object {
"index": ".slo-observability.sli-v3.3",
"index": ".slo-observability.sli-v3.4",
"pipeline": ".slo-observability.sli.pipeline-irrelevant-1",
},
"frequency": "1m",
@ -224,12 +224,12 @@ Object {
"_meta": Object {
"managed": true,
"managed_by": "observability",
"version": 3.3,
"version": 3.4,
},
"defer_validation": true,
"description": "Rolled-up SLI data for SLO: irrelevant [id: irrelevant, revision: 1]",
"dest": Object {
"index": ".slo-observability.sli-v3.3",
"index": ".slo-observability.sli-v3.4",
"pipeline": ".slo-observability.sli.pipeline-irrelevant-1",
},
"frequency": "1m",

View file

@ -4,6 +4,7 @@ exports[`FromRemoteSummaryDocToSlo with kibana < v8.14 fallbacks to dummy indica
Object {
"budgetingMethod": "timeslices",
"createdAt": 2024-01-01T00:00:00.000Z,
"createdBy": undefined,
"description": "irrelevant",
"enabled": true,
"groupBy": "*",
@ -49,6 +50,7 @@ Object {
"type": "rolling",
},
"updatedAt": 2024-01-01T00:00:00.000Z,
"updatedBy": undefined,
"version": 1,
}
`;
@ -57,6 +59,7 @@ exports[`FromRemoteSummaryDocToSlo with kibana >= v8.14 uses the stringified ind
Object {
"budgetingMethod": "occurrences",
"createdAt": 2024-02-01T00:00:00.000Z,
"createdBy": undefined,
"description": "irrelevant",
"enabled": true,
"groupBy": "*",
@ -99,6 +102,59 @@ Object {
"type": "rolling",
},
"updatedAt": 2024-02-01T00:00:00.000Z,
"updatedBy": undefined,
"version": 1,
}
`;
exports[`FromRemoteSummaryDocToSlo with kibana >= v8.18 uses the provided updatedBy and createdBy 1`] = `
Object {
"budgetingMethod": "occurrences",
"createdAt": 2024-02-01T00:00:00.000Z,
"createdBy": "john",
"description": "irrelevant",
"enabled": true,
"groupBy": "*",
"id": "irrelevant",
"indicator": Object {
"params": Object {
"good": "irrelevant",
"index": "irrelvant",
"timestampField": "irrelevant",
"total": "irrelevant",
},
"type": "sli.kql.custom",
},
"name": "irrelevant",
"objective": Object {
"target": 0.9999,
"timesliceTarget": undefined,
"timesliceWindow": undefined,
},
"revision": 1,
"settings": Object {
"frequency": Duration {
"unit": "m",
"value": 1,
},
"preventInitialBackfill": false,
"syncDelay": Duration {
"unit": "m",
"value": 1,
},
},
"tags": Array [
"prod",
],
"timeWindow": Object {
"duration": Duration {
"unit": "d",
"value": 7,
},
"type": "rolling",
},
"updatedAt": 2024-02-01T00:00:00.000Z,
"updatedBy": "jane",
"version": 1,
}
`;

View file

@ -154,4 +154,79 @@ describe('FromRemoteSummaryDocToSlo', () => {
expect(slo).toMatchSnapshot();
});
});
describe('with kibana >= v8.18', () => {
it('uses the provided updatedBy and createdBy', () => {
const slo = fromRemoteSummaryDocumentToSloDefinition(
{
service: {
environment: null,
name: null,
},
transaction: {
name: null,
type: null,
},
monitor: {
name: null,
config_id: null,
},
observer: {
name: null,
geo: {
name: null,
},
},
slo: {
indicator: {
type: 'sli.kql.custom',
params: {
index: 'irrelvant',
good: 'irrelevant',
total: 'irrelevant',
timestampField: 'irrelevant',
}, // added in 8.14
},
timeWindow: {
duration: '7d',
type: 'rolling',
},
groupBy: ALL_VALUE,
groupings: {},
instanceId: ALL_VALUE,
name: 'irrelevant',
description: 'irrelevant',
id: 'irrelevant',
budgetingMethod: 'occurrences',
revision: 1,
objective: {
target: 0.9999,
},
tags: ['prod'],
createdAt: '2024-02-01T00:00:00.000Z', // added in 8.14
updatedAt: '2024-02-01T00:00:00.000Z', // added in 8.14
createdBy: 'john',
updatedBy: 'jane',
},
goodEvents: 0,
totalEvents: 0,
errorBudgetEstimated: false,
errorBudgetRemaining: 1,
errorBudgetConsumed: 0,
errorBudgetInitial: 1 - 0.9999,
sliValue: -1,
statusCode: 0,
status: 'NO_DATA',
isTempDoc: true,
spaceId: 'irrelevant',
kibanaUrl: 'http://kibana.com/base-path', // added in 8.14
summaryUpdatedAt: null,
latestSliTimestamp: null,
},
loggerMock
);
expect(slo).toMatchSnapshot();
});
});
});

View file

@ -42,6 +42,8 @@ export function fromRemoteSummaryDocumentToSloDefinition(
updatedAt: summaryDoc.slo.updatedAt ?? '2024-01-01T00:00:00.000Z', // fallback prior 8.14
groupBy: summaryDoc.slo.groupBy,
version: 1,
createdBy: summaryDoc.slo.createdBy,
updatedBy: summaryDoc.slo.updatedBy,
});
if (isLeft(res)) {

View file

@ -65,7 +65,8 @@ describe('UpdateSLO', () => {
mockScopedClusterClient,
mockLogger,
'some-space',
httpServiceMock.createStartContract().basePath
httpServiceMock.createStartContract().basePath,
'some-user-id'
);
});
@ -246,6 +247,7 @@ describe('UpdateSLO', () => {
name: 'updated name',
revision: 2,
updatedAt: expect.anything(),
updatedBy: 'some-user-id',
})
);
expectInstallationOfUpdatedSLOResources();
@ -262,7 +264,7 @@ describe('UpdateSLO', () => {
mockSummaryTransformManager.getVersion.mockResolvedValue(SLO_RESOURCES_VERSION);
});
it('consideres a settings change as a breaking change', async () => {
it('considers a settings change as a breaking change', async () => {
const slo = createSLO();
mockRepository.findById.mockResolvedValueOnce(slo);
@ -275,17 +277,12 @@ describe('UpdateSLO', () => {
expectDeletionOfOriginalSLOResources(slo);
expect(mockRepository.update).toHaveBeenCalledWith(
expect.objectContaining({
...slo,
settings: newSettings,
revision: 2,
updatedAt: expect.anything(),
})
expect.objectContaining({ settings: newSettings, revision: 2 })
);
expectInstallationOfUpdatedSLOResources();
});
it('consideres a budgeting method change as a breaking change', async () => {
it('considers a budgeting method change as a breaking change', async () => {
const slo = createSLO({ budgetingMethod: 'occurrences' });
mockRepository.findById.mockResolvedValueOnce(slo);
@ -302,7 +299,7 @@ describe('UpdateSLO', () => {
expectDeletionOfOriginalSLOResources(slo);
});
it('consideres a timeWindow change as a breaking change', async () => {
it('considers a timeWindow change as a breaking change', async () => {
const slo = createSLOWithTimeslicesBudgetingMethod();
mockRepository.findById.mockResolvedValueOnce(slo);
@ -314,7 +311,7 @@ describe('UpdateSLO', () => {
expectDeletionOfOriginalSLOResources(slo);
});
it('consideres a timeslice target change as a breaking change', async () => {
it('considers a timeslice target change as a breaking change', async () => {
const slo = createSLOWithTimeslicesBudgetingMethod();
mockRepository.findById.mockResolvedValueOnce(slo);
@ -330,7 +327,7 @@ describe('UpdateSLO', () => {
expectDeletionOfOriginalSLOResources(slo);
});
it('consideres a timeslice window change as a breaking change', async () => {
it('considers a timeslice window change as a breaking change', async () => {
const slo = createSLOWithTimeslicesBudgetingMethod();
mockRepository.findById.mockResolvedValueOnce(slo);
@ -346,7 +343,7 @@ describe('UpdateSLO', () => {
expectDeletionOfOriginalSLOResources(slo);
});
it('consideres an indicator change as a breaking change', async () => {
it('considers an indicator change as a breaking change', async () => {
const slo = createSLOWithTimeslicesBudgetingMethod();
mockRepository.findById.mockResolvedValueOnce(slo);
@ -358,7 +355,7 @@ describe('UpdateSLO', () => {
expectDeletionOfOriginalSLOResources(slo);
});
it('consideres a groupBy change as a breaking change', async () => {
it('considers a groupBy change as a breaking change', async () => {
const slo = createSLOWithTimeslicesBudgetingMethod();
mockRepository.findById.mockResolvedValueOnce(slo);
@ -450,6 +447,30 @@ describe('UpdateSLO', () => {
});
});
describe('Update also updates updatedBy field', () => {
beforeEach(() => {
mockEsClient.security.hasPrivileges.mockResolvedValue({
has_all_requested: true,
} as SecurityHasPrivilegesResponse);
});
it('updates the updatedBy field with the user id', async () => {
const originalSlo = createSLO({
id: 'original-id',
indicator: createAPMTransactionErrorRateIndicator({ environment: 'development' }),
});
mockRepository.findById.mockResolvedValueOnce(originalSlo);
const newIndicator = createAPMTransactionErrorRateIndicator({ environment: 'production' });
await updateSLO.execute(originalSlo.id, { indicator: newIndicator });
expect(mockRepository.update).toHaveBeenCalledWith(
expect.objectContaining({ updatedBy: 'some-user-id' })
);
});
});
function expectInstallationOfUpdatedSLOResources() {
expect(mockTransformManager.install).toHaveBeenCalled();
expect(mockTransformManager.start).toHaveBeenCalled();

View file

@ -39,7 +39,8 @@ export class UpdateSLO {
private scopedClusterClient: IScopedClusterClient,
private logger: Logger,
private spaceId: string,
private basePath: IBasePath
private basePath: IBasePath,
private userId: string
) {}
public async execute(sloId: string, params: UpdateSLOParams): Promise<UpdateSLOResponse> {
@ -58,6 +59,7 @@ export class UpdateSLO {
updatedSlo = Object.assign(updatedSlo, {
updatedAt: new Date(),
updatedBy: this.userId,
revision: requireRevisionBump ? originalSlo.revision + 1 : originalSlo.revision,
});

View file

@ -21,6 +21,7 @@ import {
TaskManagerStartContract,
} from '@kbn/task-manager-plugin/server';
import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/server';
import { SecurityPluginStart } from '@kbn/security-plugin/server';
import type { KibanaRequest } from '@kbn/core/server';
import type { SloClient } from './client';
@ -44,6 +45,7 @@ export interface SLOPluginSetupDependencies {
usageCollection: UsageCollectionSetup;
licensing: LicensingPluginSetup;
dataViews: DataViewsServerPluginStart;
security: SecurityPluginStart;
}
export interface SLOPluginStartDependencies {

View file

@ -102,5 +102,6 @@
"@kbn/server-route-repository-client",
"@kbn/security-plugin-types-public",
"@kbn/core-test-helpers-kbn-server",
"@kbn/security-plugin",
]
}

View file

@ -62,7 +62,9 @@ export default function ({ getService }: DeploymentAgnosticFtrProviderContext) {
expect(definitions.results[0]).eql({
budgetingMethod: 'occurrences',
updatedAt: definitions.results[0].updatedAt,
updatedBy: 'elastic_admin',
createdAt: definitions.results[0].createdAt,
createdBy: 'elastic_admin',
description: 'Fixture for api integration tests',
enabled: true,
groupBy: 'tags',
@ -98,7 +100,7 @@ export default function ({ getService }: DeploymentAgnosticFtrProviderContext) {
const rollUpTransformResponse = await transformHelper.assertExist(getSLOTransformId(id, 1));
expect(rollUpTransformResponse.transforms[0].source.index).eql(['kbn-data-forge*']);
expect(rollUpTransformResponse.transforms[0].dest).eql({
index: '.slo-observability.sli-v3.3',
index: '.slo-observability.sli-v3.4',
pipeline: `.slo-observability.sli.pipeline-${id}-1`,
});
expect(rollUpTransformResponse.transforms[0].pivot.group_by).eql({
@ -110,10 +112,10 @@ export default function ({ getService }: DeploymentAgnosticFtrProviderContext) {
getSLOSummaryTransformId(id, 1)
);
expect(summaryTransformResponse.transforms[0].source.index).eql([
'.slo-observability.sli-v3.3*',
'.slo-observability.sli-v3.4*',
]);
expect(summaryTransformResponse.transforms[0].dest).eql({
index: '.slo-observability.summary-v3.3',
index: '.slo-observability.summary-v3.4',
pipeline: `.slo-observability.summary.pipeline-${id}-1`,
});
});