mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
# Backport This will backport the following commits from `main` to `8.7`: - [[Synthetics] only allow params to be saved against specific namespaces (#155759)](https://github.com/elastic/kibana/pull/155759) <!--- Backport version: 8.9.7 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Dominique Clarke","email":"dominique.clarke@elastic.co"},"sourceCommit":{"committedDate":"2023-04-26T02:10:41Z","message":"[Synthetics] only allow params to be saved against specific namespaces (#155759)\n\n## Summary\r\n\r\nThis PR prevents saving synthetics params to arbitrary Kibana spaces.\r\n\r\nPreviously, we accepted a `namespaces` array which could be used to save\r\na param to spaces that do not exist. In the past, the client would send\r\nthis value as `namespaces: ['*']` when a param is meant to e shared\r\nacross spaces.\r\n\r\nThis PR replaces the `namespaces` array with a simple\r\n`share_across_spaces` boolean.\r\n\r\nParams are now only allowed to be saved to the current active space, or\r\n`*`.\r\n\r\n---------\r\n\r\nCo-authored-by: shahzad31 <shahzad31comp@gmail.com>","sha":"ead18ac43742edb0406803985eab6b563702b320","branchLabelMapping":{"^v8.8.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["bug","release_note:fix","Team:uptime","uptime","ci:cloud-deploy","v8.8.0","v8.7.1"],"number":155759,"url":"https://github.com/elastic/kibana/pull/155759","mergeCommit":{"message":"[Synthetics] only allow params to be saved against specific namespaces (#155759)\n\n## Summary\r\n\r\nThis PR prevents saving synthetics params to arbitrary Kibana spaces.\r\n\r\nPreviously, we accepted a `namespaces` array which could be used to save\r\na param to spaces that do not exist. In the past, the client would send\r\nthis value as `namespaces: ['*']` when a param is meant to e shared\r\nacross spaces.\r\n\r\nThis PR replaces the `namespaces` array with a simple\r\n`share_across_spaces` boolean.\r\n\r\nParams are now only allowed to be saved to the current active space, or\r\n`*`.\r\n\r\n---------\r\n\r\nCo-authored-by: shahzad31 <shahzad31comp@gmail.com>","sha":"ead18ac43742edb0406803985eab6b563702b320"}},"sourceBranch":"main","suggestedTargetBranches":["8.7"],"targetPullRequestStates":[{"branch":"main","label":"v8.8.0","labelRegex":"^v8.8.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/155759","number":155759,"mergeCommit":{"message":"[Synthetics] only allow params to be saved against specific namespaces (#155759)\n\n## Summary\r\n\r\nThis PR prevents saving synthetics params to arbitrary Kibana spaces.\r\n\r\nPreviously, we accepted a `namespaces` array which could be used to save\r\na param to spaces that do not exist. In the past, the client would send\r\nthis value as `namespaces: ['*']` when a param is meant to e shared\r\nacross spaces.\r\n\r\nThis PR replaces the `namespaces` array with a simple\r\n`share_across_spaces` boolean.\r\n\r\nParams are now only allowed to be saved to the current active space, or\r\n`*`.\r\n\r\n---------\r\n\r\nCo-authored-by: shahzad31 <shahzad31comp@gmail.com>","sha":"ead18ac43742edb0406803985eab6b563702b320"}},{"branch":"8.7","label":"v8.7.1","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT-->
This commit is contained in:
parent
01746042a3
commit
efcababbe5
13 changed files with 406 additions and 57 deletions
|
@ -28,6 +28,8 @@ export type {
|
|||
|
||||
export type { AuthenticationServiceStart, AuthenticationServiceSetup } from './authentication';
|
||||
|
||||
export { ALL_SPACES_ID } from '../common/constants';
|
||||
|
||||
export const plugin: PluginInitializer<
|
||||
SecurityPluginSetup,
|
||||
SecurityPluginStart,
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import * as t from 'io-ts';
|
||||
|
||||
export const SyntheticsParamCode = t.intersection([
|
||||
export const SyntheticsParamSOCodec = t.intersection([
|
||||
t.interface({
|
||||
key: t.string,
|
||||
value: t.string,
|
||||
|
@ -19,4 +19,18 @@ export const SyntheticsParamCode = t.intersection([
|
|||
}),
|
||||
]);
|
||||
|
||||
export type SyntheticsParam = t.TypeOf<typeof SyntheticsParamCode>;
|
||||
export type SyntheticsParamSO = t.TypeOf<typeof SyntheticsParamSOCodec>;
|
||||
|
||||
export const SyntheticsParamRequestCodec = t.intersection([
|
||||
t.interface({
|
||||
key: t.string,
|
||||
value: t.string,
|
||||
}),
|
||||
t.partial({
|
||||
description: t.string,
|
||||
tags: t.array(t.string),
|
||||
share_across_spaces: t.boolean,
|
||||
}),
|
||||
]);
|
||||
|
||||
export type SyntheticsParamRequest = t.TypeOf<typeof SyntheticsParamRequestCodec>;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { ALL_SPACES_ID } from '@kbn/security-plugin/public';
|
||||
import {
|
||||
EuiFlyout,
|
||||
EuiFlyoutBody,
|
||||
|
@ -25,7 +26,7 @@ import { useDispatch } from 'react-redux';
|
|||
import { apiService } from '../../../../../utils/api_service';
|
||||
import { ClientPluginsStart } from '../../../../../plugin';
|
||||
import { ListParamItem } from './params_list';
|
||||
import { SyntheticsParam } from '../../../../../../common/runtime_types';
|
||||
import { SyntheticsParamSO } from '../../../../../../common/runtime_types';
|
||||
import { useFormWrapped } from '../../../../../hooks/use_form_wrapped';
|
||||
import { AddParamForm } from './add_param_form';
|
||||
import { SYNTHETICS_API_URLS } from '../../../../../../common/constants';
|
||||
|
@ -46,7 +47,7 @@ export const AddParamFlyout = ({
|
|||
|
||||
const { id, ...dataToSave } = isEditingItem ?? {};
|
||||
|
||||
const form = useFormWrapped<SyntheticsParam>({
|
||||
const form = useFormWrapped<SyntheticsParamSO>({
|
||||
mode: 'onSubmit',
|
||||
reValidateMode: 'onChange',
|
||||
shouldFocusError: true,
|
||||
|
@ -66,7 +67,7 @@ export const AddParamFlyout = ({
|
|||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [setIsEditingItem]);
|
||||
|
||||
const [paramData, setParamData] = useState<SyntheticsParam | null>(null);
|
||||
const [paramData, setParamData] = useState<SyntheticsParamSO | null>(null);
|
||||
|
||||
const { application } = useKibana<ClientPluginsStart>().services;
|
||||
|
||||
|
@ -74,15 +75,24 @@ export const AddParamFlyout = ({
|
|||
if (!paramData) {
|
||||
return;
|
||||
}
|
||||
const { namespaces, ...paramRequest } = paramData;
|
||||
const shareAcrossSpaces = namespaces?.includes(ALL_SPACES_ID);
|
||||
if (isEditingItem) {
|
||||
return apiService.put(SYNTHETICS_API_URLS.PARAMS, { id, ...paramData });
|
||||
return apiService.put(SYNTHETICS_API_URLS.PARAMS, {
|
||||
id,
|
||||
...paramRequest,
|
||||
share_across_spaces: shareAcrossSpaces,
|
||||
});
|
||||
}
|
||||
return apiService.post(SYNTHETICS_API_URLS.PARAMS, paramData);
|
||||
return apiService.post(SYNTHETICS_API_URLS.PARAMS, {
|
||||
...paramRequest,
|
||||
share_across_spaces: shareAcrossSpaces,
|
||||
});
|
||||
}, [paramData]);
|
||||
|
||||
const canSave = (application?.capabilities.uptime.save ?? false) as boolean;
|
||||
|
||||
const onSubmit = (formData: SyntheticsParam) => {
|
||||
const onSubmit = (formData: SyntheticsParamSO) => {
|
||||
setParamData(formData);
|
||||
};
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
import React from 'react';
|
||||
import { ALL_SPACES_ID } from '@kbn/security-plugin/public';
|
||||
import {
|
||||
EuiCheckbox,
|
||||
EuiComboBox,
|
||||
|
@ -15,7 +16,7 @@ import {
|
|||
} from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { Controller, useFormContext, useFormState } from 'react-hook-form';
|
||||
import { SyntheticsParam } from '../../../../../../common/runtime_types';
|
||||
import { SyntheticsParamSO } from '../../../../../../common/runtime_types';
|
||||
import { ListParamItem } from './params_list';
|
||||
|
||||
export const AddParamForm = ({
|
||||
|
@ -25,8 +26,8 @@ export const AddParamForm = ({
|
|||
items: ListParamItem[];
|
||||
isEditingItem: ListParamItem | null;
|
||||
}) => {
|
||||
const { register, control } = useFormContext<SyntheticsParam>();
|
||||
const { errors } = useFormState<SyntheticsParam>();
|
||||
const { register, control } = useFormContext<SyntheticsParamSO>();
|
||||
const { errors } = useFormState<SyntheticsParamSO>();
|
||||
|
||||
const tagsList = items.reduce((acc, item) => {
|
||||
const tags = item.tags || [];
|
||||
|
@ -112,7 +113,7 @@ export const AddParamForm = ({
|
|||
aria-label={NAMESPACES_LABEL}
|
||||
onChange={(e) => {
|
||||
if (e.target.checked) {
|
||||
field.onChange(['*']);
|
||||
field.onChange([ALL_SPACES_ID]);
|
||||
} else {
|
||||
field.onChange([]);
|
||||
}
|
||||
|
|
|
@ -24,12 +24,12 @@ import { EuiBasicTableColumn } from '@elastic/eui/src/components/basic_table/bas
|
|||
import { useDebounce } from 'react-use';
|
||||
import { TableTitle } from '../../common/components/table_title';
|
||||
import { ParamsText } from './params_text';
|
||||
import { SyntheticsParam } from '../../../../../../common/runtime_types';
|
||||
import { SyntheticsParamSO } from '../../../../../../common/runtime_types';
|
||||
import { useParamsList } from '../hooks/use_params_list';
|
||||
import { AddParamFlyout } from './add_param_flyout';
|
||||
import { DeleteParam } from './delete_param';
|
||||
|
||||
export interface ListParamItem extends SyntheticsParam {
|
||||
export interface ListParamItem extends SyntheticsParamSO {
|
||||
id: string;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,13 +8,13 @@
|
|||
import { useFetcher } from '@kbn/observability-plugin/public';
|
||||
import { SavedObject } from '@kbn/core-saved-objects-common';
|
||||
import { useMemo } from 'react';
|
||||
import { SyntheticsParam } from '../../../../../../common/runtime_types';
|
||||
import { SyntheticsParamSO } from '../../../../../../common/runtime_types';
|
||||
import { apiService } from '../../../../../utils/api_service';
|
||||
import { SYNTHETICS_API_URLS } from '../../../../../../common/constants';
|
||||
|
||||
export const useParamsList = (lastRefresh: number) => {
|
||||
const { data, loading } = useFetcher<
|
||||
Promise<{ data: Array<SavedObject<SyntheticsParam>> }>
|
||||
Promise<{ data: Array<SavedObject<SyntheticsParamSO>> }>
|
||||
>(() => {
|
||||
return apiService.get(SYNTHETICS_API_URLS.PARAMS);
|
||||
}, [lastRefresh]);
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
*/
|
||||
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { SyntheticsParam } from '../../../common/runtime_types';
|
||||
import { ALL_SPACES_ID } from '@kbn/security-plugin/common/constants';
|
||||
import { DEFAULT_SPACE_ID } from '@kbn/spaces-plugin/common';
|
||||
import { SyntheticsParamRequest, SyntheticsParamSO } from '../../../common/runtime_types';
|
||||
import { syntheticsParamType } from '../../../common/types/saved_objects';
|
||||
import { SyntheticsRestApiRouteFactory } from '../../legacy_uptime/routes/types';
|
||||
import { SYNTHETICS_API_URLS } from '../../../common/constants';
|
||||
|
@ -14,25 +16,35 @@ import { SYNTHETICS_API_URLS } from '../../../common/constants';
|
|||
export const addSyntheticsParamsRoute: SyntheticsRestApiRouteFactory = () => ({
|
||||
method: 'POST',
|
||||
path: SYNTHETICS_API_URLS.PARAMS,
|
||||
|
||||
validate: {
|
||||
body: schema.object({
|
||||
key: schema.string(),
|
||||
value: schema.string(),
|
||||
description: schema.maybe(schema.string()),
|
||||
tags: schema.maybe(schema.arrayOf(schema.string())),
|
||||
namespaces: schema.maybe(schema.arrayOf(schema.string())),
|
||||
share_across_spaces: schema.maybe(schema.boolean()),
|
||||
}),
|
||||
},
|
||||
writeAccess: true,
|
||||
handler: async ({ request, server, savedObjectsClient }): Promise<any> => {
|
||||
const { namespaces, ...data } = request.body as SyntheticsParam;
|
||||
const { id: spaceId } = await server.spaces.spacesService.getActiveSpace(request);
|
||||
handler: async ({ request, response, server, savedObjectsClient }): Promise<any> => {
|
||||
try {
|
||||
const { id: spaceId } = (await server.spaces?.spacesService.getActiveSpace(request)) ?? {
|
||||
id: DEFAULT_SPACE_ID,
|
||||
};
|
||||
const { share_across_spaces: shareAcrossSpaces, ...data } =
|
||||
request.body as SyntheticsParamRequest;
|
||||
|
||||
const result = await savedObjectsClient.create(syntheticsParamType, data, {
|
||||
initialNamespaces: (namespaces ?? []).length > 0 ? namespaces : [spaceId],
|
||||
});
|
||||
const result = await savedObjectsClient.create<SyntheticsParamSO>(syntheticsParamType, data, {
|
||||
initialNamespaces: shareAcrossSpaces ? [ALL_SPACES_ID] : [spaceId],
|
||||
});
|
||||
return { data: result };
|
||||
} catch (error) {
|
||||
if (error.output?.statusCode === 404) {
|
||||
const spaceId = server.spaces?.spacesService.getSpaceId(request) ?? DEFAULT_SPACE_ID;
|
||||
return response.notFound({ body: { message: `Kibana space '${spaceId}' does not exist` } });
|
||||
}
|
||||
|
||||
return { data: result };
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
*/
|
||||
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { SyntheticsParam } from '../../../common/runtime_types';
|
||||
import { DEFAULT_SPACE_ID } from '@kbn/spaces-plugin/common';
|
||||
import { SyntheticsParamRequest } from '../../../common/runtime_types';
|
||||
import { syntheticsParamType } from '../../../common/types/saved_objects';
|
||||
import { SyntheticsRestApiRouteFactory } from '../../legacy_uptime/routes/types';
|
||||
import { SYNTHETICS_API_URLS } from '../../../common/constants';
|
||||
|
@ -21,15 +22,33 @@ export const editSyntheticsParamsRoute: SyntheticsRestApiRouteFactory = () => ({
|
|||
value: schema.string(),
|
||||
description: schema.maybe(schema.string()),
|
||||
tags: schema.maybe(schema.arrayOf(schema.string())),
|
||||
namespaces: schema.maybe(schema.arrayOf(schema.string())),
|
||||
share_across_spaces: schema.maybe(schema.boolean()),
|
||||
}),
|
||||
},
|
||||
writeAccess: true,
|
||||
handler: async ({ savedObjectsClient, request, server }): Promise<any> => {
|
||||
const { namespaces, id, ...data } = request.body as SyntheticsParam & { id: string };
|
||||
handler: async ({ savedObjectsClient, request, response, server }): Promise<any> => {
|
||||
try {
|
||||
const { id: _spaceId } = (await server.spaces?.spacesService.getActiveSpace(request)) ?? {
|
||||
id: DEFAULT_SPACE_ID,
|
||||
};
|
||||
const {
|
||||
share_across_spaces: shareAcrossSpaces,
|
||||
id,
|
||||
...data
|
||||
} = request.body as SyntheticsParamRequest & {
|
||||
id: string;
|
||||
};
|
||||
|
||||
const result = await savedObjectsClient.update(syntheticsParamType, id, data);
|
||||
const result = await savedObjectsClient.update(syntheticsParamType, id, data);
|
||||
|
||||
return { data: result };
|
||||
return { data: result };
|
||||
} catch (error) {
|
||||
if (error.output?.statusCode === 404) {
|
||||
const spaceId = server.spaces?.spacesService.getSpaceId(request) ?? DEFAULT_SPACE_ID;
|
||||
return response.notFound({ body: { message: `Kibana space '${spaceId}' does not exist` } });
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
import { SavedObjectsFindResult } from '@kbn/core-saved-objects-api-server';
|
||||
import { DEFAULT_SPACE_ID } from '@kbn/spaces-plugin/common';
|
||||
import { syntheticsParamType } from '../../../common/types/saved_objects';
|
||||
import { SyntheticsRestApiRouteFactory } from '../../legacy_uptime/routes/types';
|
||||
import { SYNTHETICS_API_URLS } from '../../../common/constants';
|
||||
|
@ -14,35 +15,46 @@ export const getSyntheticsParamsRoute: SyntheticsRestApiRouteFactory = () => ({
|
|||
method: 'GET',
|
||||
path: SYNTHETICS_API_URLS.PARAMS,
|
||||
validate: {},
|
||||
handler: async ({ savedObjectsClient, request, server }): Promise<any> => {
|
||||
const encryptedSavedObjectsClient = server.encryptedSavedObjects.getClient();
|
||||
handler: async ({ savedObjectsClient, request, response, server }): Promise<any> => {
|
||||
try {
|
||||
const encryptedSavedObjectsClient = server.encryptedSavedObjects.getClient();
|
||||
|
||||
const spaceId = server.spaces.spacesService.getSpaceId(request);
|
||||
const { id: spaceId } = (await server.spaces?.spacesService.getActiveSpace(request)) ?? {
|
||||
id: DEFAULT_SPACE_ID,
|
||||
};
|
||||
|
||||
const canSave =
|
||||
(await server.coreStart?.capabilities.resolveCapabilities(request)).uptime.save ?? false;
|
||||
const canSave =
|
||||
(await server.coreStart?.capabilities.resolveCapabilities(request)).uptime.save ?? false;
|
||||
|
||||
if (canSave) {
|
||||
const finder =
|
||||
await encryptedSavedObjectsClient.createPointInTimeFinderDecryptedAsInternalUser({
|
||||
if (canSave) {
|
||||
const finder =
|
||||
await encryptedSavedObjectsClient.createPointInTimeFinderDecryptedAsInternalUser({
|
||||
type: syntheticsParamType,
|
||||
perPage: 1000,
|
||||
namespaces: [spaceId],
|
||||
});
|
||||
|
||||
const hits: SavedObjectsFindResult[] = [];
|
||||
for await (const result of finder.find()) {
|
||||
hits.push(...result.saved_objects);
|
||||
}
|
||||
|
||||
return { data: hits };
|
||||
} else {
|
||||
const data = await savedObjectsClient.find({
|
||||
type: syntheticsParamType,
|
||||
perPage: 1000,
|
||||
namespaces: [spaceId],
|
||||
perPage: 10000,
|
||||
});
|
||||
|
||||
const hits: SavedObjectsFindResult[] = [];
|
||||
for await (const result of finder.find()) {
|
||||
hits.push(...result.saved_objects);
|
||||
return { data: data.saved_objects };
|
||||
}
|
||||
} catch (error) {
|
||||
if (error.output?.statusCode === 404) {
|
||||
const spaceId = server.spaces?.spacesService.getSpaceId(request) ?? DEFAULT_SPACE_ID;
|
||||
return response.notFound({ body: { message: `Kibana space '${spaceId}' does not exist` } });
|
||||
}
|
||||
|
||||
return { data: hits };
|
||||
} else {
|
||||
const data = await savedObjectsClient.find({
|
||||
type: syntheticsParamType,
|
||||
perPage: 10000,
|
||||
});
|
||||
|
||||
return { data: data.saved_objects };
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -35,7 +35,7 @@ import {
|
|||
SyntheticsMonitor,
|
||||
SyntheticsMonitorWithId,
|
||||
SyntheticsMonitorWithSecrets,
|
||||
SyntheticsParam,
|
||||
SyntheticsParamSO,
|
||||
ThrottlingOptions,
|
||||
} from '../../common/runtime_types';
|
||||
import { getServiceLocations } from './get_service_locations';
|
||||
|
@ -476,7 +476,7 @@ export class SyntheticsService {
|
|||
const paramsBySpace: Record<string, Record<string, string>> = {};
|
||||
|
||||
const finder =
|
||||
await encryptedClient.createPointInTimeFinderDecryptedAsInternalUser<SyntheticsParam>({
|
||||
await encryptedClient.createPointInTimeFinderDecryptedAsInternalUser<SyntheticsParamSO>({
|
||||
type: syntheticsParamType,
|
||||
perPage: 1000,
|
||||
namespaces: spaceId ? [spaceId] : undefined,
|
||||
|
|
278
x-pack/test/api_integration/apis/synthetics/add_edit_params.ts
Normal file
278
x-pack/test/api_integration/apis/synthetics/add_edit_params.ts
Normal file
|
@ -0,0 +1,278 @@
|
|||
/*
|
||||
* 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 { v4 as uuidv4 } from 'uuid';
|
||||
import { SYNTHETICS_API_URLS } from '@kbn/synthetics-plugin/common/constants';
|
||||
import expect from '@kbn/expect';
|
||||
import { syntheticsParamType } from '@kbn/synthetics-plugin/common/types/saved_objects';
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
|
||||
export default function ({ getService }: FtrProviderContext) {
|
||||
describe('AddEditParams', function () {
|
||||
this.tags('skipCloud');
|
||||
const supertestAPI = getService('supertest');
|
||||
const kServer = getService('kibanaServer');
|
||||
const testParam = {
|
||||
key: 'test',
|
||||
value: 'test',
|
||||
};
|
||||
|
||||
before(async () => {
|
||||
await supertestAPI.post('/api/fleet/setup').set('kbn-xsrf', 'true').send().expect(200);
|
||||
await supertestAPI
|
||||
.post('/api/fleet/epm/packages/synthetics/0.12.0')
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send({ force: true })
|
||||
.expect(200);
|
||||
|
||||
await kServer.savedObjects.clean({ types: [syntheticsParamType] });
|
||||
});
|
||||
|
||||
it('adds a test param', async () => {
|
||||
await supertestAPI
|
||||
.post(SYNTHETICS_API_URLS.PARAMS)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send(testParam)
|
||||
.expect(200);
|
||||
|
||||
const getResponse = await supertestAPI
|
||||
.get(SYNTHETICS_API_URLS.PARAMS)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.expect(200);
|
||||
|
||||
expect(getResponse.body.data[0].attributes).eql(testParam);
|
||||
});
|
||||
|
||||
it('handles tags and description', async () => {
|
||||
const tagsAndDescription = {
|
||||
tags: ['a tag'],
|
||||
description: 'test description',
|
||||
};
|
||||
const testParam2 = {
|
||||
...testParam,
|
||||
...tagsAndDescription,
|
||||
};
|
||||
await supertestAPI
|
||||
.post(SYNTHETICS_API_URLS.PARAMS)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send(testParam2)
|
||||
.expect(200);
|
||||
|
||||
const getResponse = await supertestAPI
|
||||
.get(SYNTHETICS_API_URLS.PARAMS)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.expect(200);
|
||||
|
||||
expect(getResponse.body.data[0].attributes).eql(testParam2);
|
||||
});
|
||||
|
||||
it('handles editing a param', async () => {
|
||||
const updatedParam = {
|
||||
key: 'testUpdated',
|
||||
value: 'testUpdated',
|
||||
tags: ['a tag'],
|
||||
description: 'test description',
|
||||
};
|
||||
|
||||
await supertestAPI
|
||||
.post(SYNTHETICS_API_URLS.PARAMS)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send(testParam)
|
||||
.expect(200);
|
||||
|
||||
const getResponse = await supertestAPI
|
||||
.get(SYNTHETICS_API_URLS.PARAMS)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.expect(200);
|
||||
const param = getResponse.body.data[0];
|
||||
expect(param.attributes).eql(testParam);
|
||||
|
||||
await supertestAPI
|
||||
.put(SYNTHETICS_API_URLS.PARAMS)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send({ ...updatedParam, id: param.id })
|
||||
.expect(200);
|
||||
|
||||
const updatedGetResponse = await supertestAPI
|
||||
.get(SYNTHETICS_API_URLS.PARAMS)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.expect(200);
|
||||
const updatedParamSO = updatedGetResponse.body.data[0];
|
||||
expect(updatedParamSO.attributes).eql(updatedParam);
|
||||
});
|
||||
|
||||
it('handles spaces', async () => {
|
||||
const SPACE_ID = `test-space-${uuidv4()}`;
|
||||
const SPACE_NAME = `test-space-name ${uuidv4()}`;
|
||||
|
||||
await kServer.spaces.create({ id: SPACE_ID, name: SPACE_NAME });
|
||||
|
||||
await supertestAPI
|
||||
.post(`/s/${SPACE_ID}${SYNTHETICS_API_URLS.PARAMS}`)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send(testParam)
|
||||
.expect(200);
|
||||
|
||||
const getResponse = await supertestAPI
|
||||
.get(`/s/${SPACE_ID}${SYNTHETICS_API_URLS.PARAMS}`)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.expect(200);
|
||||
|
||||
expect(getResponse.body.data[0].namespaces).eql([SPACE_ID]);
|
||||
expect(getResponse.body.data[0].attributes).eql(testParam);
|
||||
});
|
||||
|
||||
it('handles editing a param in spaces', async () => {
|
||||
const SPACE_ID = `test-space-${uuidv4()}`;
|
||||
const SPACE_NAME = `test-space-name ${uuidv4()}`;
|
||||
|
||||
await kServer.spaces.create({ id: SPACE_ID, name: SPACE_NAME });
|
||||
|
||||
const updatedParam = {
|
||||
key: 'testUpdated',
|
||||
value: 'testUpdated',
|
||||
tags: ['a tag'],
|
||||
description: 'test description',
|
||||
};
|
||||
|
||||
await supertestAPI
|
||||
.post(`/s/${SPACE_ID}${SYNTHETICS_API_URLS.PARAMS}`)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send(testParam)
|
||||
.expect(200);
|
||||
|
||||
const getResponse = await supertestAPI
|
||||
.get(`/s/${SPACE_ID}${SYNTHETICS_API_URLS.PARAMS}`)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.expect(200);
|
||||
const param = getResponse.body.data[0];
|
||||
expect(param.attributes).eql(testParam);
|
||||
|
||||
await supertestAPI
|
||||
.put(`/s/${SPACE_ID}${SYNTHETICS_API_URLS.PARAMS}`)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send({ ...updatedParam, id: param.id })
|
||||
.expect(200);
|
||||
|
||||
const updatedGetResponse = await supertestAPI
|
||||
.get(`/s/${SPACE_ID}${SYNTHETICS_API_URLS.PARAMS}`)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.expect(200);
|
||||
const updatedParamSO = updatedGetResponse.body.data[0];
|
||||
expect(updatedParamSO.attributes).eql(updatedParam);
|
||||
});
|
||||
|
||||
it('does not allow editing a param in created in one space in a different space', async () => {
|
||||
const SPACE_ID = `test-space-${uuidv4()}`;
|
||||
const SPACE_NAME = `test-space-name ${uuidv4()}`;
|
||||
const SPACE_ID_TWO = `test-space-${uuidv4()}-two`;
|
||||
const SPACE_NAME_TWO = `test-space-name ${uuidv4()} 2`;
|
||||
|
||||
await kServer.spaces.create({ id: SPACE_ID, name: SPACE_NAME });
|
||||
await kServer.spaces.create({ id: SPACE_ID_TWO, name: SPACE_NAME_TWO });
|
||||
|
||||
const updatedParam = {
|
||||
key: 'testUpdated',
|
||||
value: 'testUpdated',
|
||||
tags: ['a tag'],
|
||||
description: 'test description',
|
||||
};
|
||||
|
||||
await supertestAPI
|
||||
.post(`/s/${SPACE_ID}${SYNTHETICS_API_URLS.PARAMS}`)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send(testParam)
|
||||
.expect(200);
|
||||
|
||||
const getResponse = await supertestAPI
|
||||
.get(`/s/${SPACE_ID}${SYNTHETICS_API_URLS.PARAMS}`)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.expect(200);
|
||||
const param = getResponse.body.data[0];
|
||||
expect(param.attributes).eql(testParam);
|
||||
|
||||
// space does exist so get request should be 200
|
||||
await supertestAPI
|
||||
.get(`/s/${SPACE_ID_TWO}${SYNTHETICS_API_URLS.PARAMS}`)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.expect(200);
|
||||
|
||||
await supertestAPI
|
||||
.put(`/s/${SPACE_ID_TWO}${SYNTHETICS_API_URLS.PARAMS}`)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send({ ...updatedParam, id: param.id })
|
||||
.expect(404);
|
||||
|
||||
const updatedGetResponse = await supertestAPI
|
||||
.get(`/s/${SPACE_ID}${SYNTHETICS_API_URLS.PARAMS}`)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.expect(200);
|
||||
const updatedParamSO = updatedGetResponse.body.data[0];
|
||||
expect(updatedParamSO.attributes).eql(testParam);
|
||||
});
|
||||
|
||||
it('handles invalid spaces', async () => {
|
||||
const SPACE_ID = `test-space-${uuidv4()}`;
|
||||
const SPACE_NAME = `test-space-name ${uuidv4()}`;
|
||||
|
||||
await kServer.spaces.create({ id: SPACE_ID, name: SPACE_NAME });
|
||||
|
||||
await supertestAPI
|
||||
.post(`/s/doesnotexist${SYNTHETICS_API_URLS.PARAMS}`)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send(testParam)
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
it('handles editing with invalid spaces', async () => {
|
||||
const updatedParam = {
|
||||
key: 'testUpdated',
|
||||
value: 'testUpdated',
|
||||
tags: ['a tag'],
|
||||
description: 'test description',
|
||||
};
|
||||
|
||||
await supertestAPI
|
||||
.post(SYNTHETICS_API_URLS.PARAMS)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send(testParam)
|
||||
.expect(200);
|
||||
const getResponse = await supertestAPI
|
||||
.get(SYNTHETICS_API_URLS.PARAMS)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.expect(200);
|
||||
const param = getResponse.body.data[0];
|
||||
expect(param.attributes).eql(testParam);
|
||||
|
||||
await supertestAPI
|
||||
.put(`/s/doesnotexist${SYNTHETICS_API_URLS.PARAMS}`)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send({ ...updatedParam, id: param.id })
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
it('handles share across spaces', async () => {
|
||||
const SPACE_ID = `test-space-${uuidv4()}`;
|
||||
const SPACE_NAME = `test-space-name ${uuidv4()}`;
|
||||
|
||||
await kServer.spaces.create({ id: SPACE_ID, name: SPACE_NAME });
|
||||
|
||||
await supertestAPI
|
||||
.post(`/s/${SPACE_ID}${SYNTHETICS_API_URLS.PARAMS}`)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send({ ...testParam, share_across_spaces: true })
|
||||
.expect(200);
|
||||
|
||||
const getResponse = await supertestAPI
|
||||
.get(`/s/${SPACE_ID}${SYNTHETICS_API_URLS.PARAMS}`)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.expect(200);
|
||||
|
||||
expect(getResponse.body.data[0].namespaces).eql(['*']);
|
||||
expect(getResponse.body.data[0].attributes).eql(testParam);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -29,5 +29,6 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) {
|
|||
loadTestFile(require.resolve('./delete_monitor_project'));
|
||||
loadTestFile(require.resolve('./synthetics_enablement'));
|
||||
loadTestFile(require.resolve('./sync_global_params'));
|
||||
loadTestFile(require.resolve('./add_edit_params'));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
import {
|
||||
ConfigKey,
|
||||
HTTPFields,
|
||||
SyntheticsParam,
|
||||
SyntheticsParamSO,
|
||||
} from '@kbn/synthetics-plugin/common/runtime_types';
|
||||
import { API_URLS, SYNTHETICS_API_URLS } from '@kbn/synthetics-plugin/common/constants';
|
||||
import { omit } from 'lodash';
|
||||
|
@ -151,7 +151,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
|
||||
expect(apiResponse.status).eql(200);
|
||||
|
||||
apiResponse.body.data.forEach(({ attributes }: SavedObject<SyntheticsParam>) => {
|
||||
apiResponse.body.data.forEach(({ attributes }: SavedObject<SyntheticsParamSO>) => {
|
||||
params[attributes.key] = attributes.value;
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue