diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/synthetics_params.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/synthetics_params.ts index 078dfa7b45d04..9c2a5b1eb4ff1 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/synthetics_params.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/synthetics_params.ts @@ -7,10 +7,10 @@ import * as t from 'io-ts'; -export const SyntheticsParamSOCodec = t.intersection([ +export const SyntheticsParamsReadonlyCodec = t.intersection([ t.interface({ + id: t.string, key: t.string, - value: t.string, }), t.partial({ description: t.string, @@ -19,7 +19,23 @@ export const SyntheticsParamSOCodec = t.intersection([ }), ]); -export type SyntheticsParamSO = t.TypeOf; +export type SyntheticsParamsReadonly = t.TypeOf; + +export const SyntheticsParamsCodec = t.intersection([ + SyntheticsParamsReadonlyCodec, + t.interface({ value: t.string }), +]); + +export type SyntheticsParams = t.TypeOf; + +export type SyntheticsParamSOAttributes = t.TypeOf; + +export const DeleteParamsResponseCodec = t.interface({ + id: t.string, + deleted: t.boolean, +}); + +export type DeleteParamsResponse = t.TypeOf; export const SyntheticsParamRequestCodec = t.intersection([ t.interface({ diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/add_param_flyout.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/add_param_flyout.tsx index 4181afdfd6a3e..c79e5aec2177a 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/add_param_flyout.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/add_param_flyout.tsx @@ -31,7 +31,7 @@ import { } from '../../../state/global_params'; import { ClientPluginsStart } from '../../../../../plugin'; import { ListParamItem } from './params_list'; -import { SyntheticsParamSO } from '../../../../../../common/runtime_types'; +import { SyntheticsParams } from '../../../../../../common/runtime_types'; import { useFormWrapped } from '../../../../../hooks/use_form_wrapped'; import { AddParamForm } from './add_param_form'; import { syncGlobalParamsAction } from '../../../state/settings'; @@ -49,7 +49,7 @@ export const AddParamFlyout = ({ const { id, ...dataToSave } = isEditingItem ?? {}; - const form = useFormWrapped({ + const form = useFormWrapped({ mode: 'onSubmit', reValidateMode: 'onChange', shouldFocusError: true, @@ -77,7 +77,7 @@ export const AddParamFlyout = ({ const { isSaving, savedData } = useSelector(selectGlobalParamState); - const onSubmit = (formData: SyntheticsParamSO) => { + const onSubmit = (formData: SyntheticsParams) => { const { namespaces, ...paramRequest } = formData; const shareAcrossSpaces = namespaces?.includes(ALL_SPACES_ID); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/add_param_form.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/add_param_form.tsx index 240314dc3b06f..1b219a0f6fec4 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/add_param_form.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/add_param_form.tsx @@ -16,7 +16,7 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { Controller, useFormContext, useFormState } from 'react-hook-form'; -import { SyntheticsParamSO } from '../../../../../../common/runtime_types'; +import { SyntheticsParams } from '../../../../../../common/runtime_types'; import { ListParamItem } from './params_list'; export const AddParamForm = ({ @@ -26,8 +26,8 @@ export const AddParamForm = ({ items: ListParamItem[]; isEditingItem: ListParamItem | null; }) => { - const { register, control } = useFormContext(); - const { errors } = useFormState(); + const { register, control } = useFormContext(); + const { errors } = useFormState(); const tagsList = items.reduce((acc, item) => { const tags = item.tags || []; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/delete_param.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/delete_param.tsx index 21d3c158c3326..aa89829380044 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/delete_param.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/delete_param.tsx @@ -35,14 +35,14 @@ export const DeleteParam = ({ const { status } = useFetcher(() => { if (isDeleting) { - return deleteGlobalParams({ ids: items.map(({ id }) => id) }); + return deleteGlobalParams(items.map(({ id }) => id)); } }, [items, isDeleting]); const name = items .map(({ key }) => key) .join(', ') - .substr(0, 50); + .slice(0, 50); useEffect(() => { if (!isDeleting) { diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/params_list.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/params_list.tsx index fc8aef5d56732..58769a7e688fe 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/params_list.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/params_list.tsx @@ -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 { SyntheticsParamSO } from '../../../../../../common/runtime_types'; +import { SyntheticsParams } 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 SyntheticsParamSO { +export interface ListParamItem extends SyntheticsParams { id: string; } diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/hooks/use_params_list.ts b/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/hooks/use_params_list.ts index 4f86ca5eb8d80..40006c262923e 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/hooks/use_params_list.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/hooks/use_params_list.ts @@ -20,12 +20,7 @@ export const useParamsList = () => { return useMemo(() => { return { - items: - listOfParams?.map((item) => ({ - id: item.id, - ...item.attributes, - namespaces: item.namespaces, - })) ?? [], + items: listOfParams ?? [], isLoading, }; }, [listOfParams, isLoading]); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/state/certs/index.ts b/x-pack/plugins/synthetics/public/apps/synthetics/state/certs/index.ts index f21df69bcbbce..708e1bb004a74 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/state/certs/index.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/state/certs/index.ts @@ -6,7 +6,7 @@ */ import { createReducer } from '@reduxjs/toolkit'; -import { CertResult, SyntheticsParamSO } from '../../../../../common/runtime_types'; +import { CertResult, SyntheticsParams } from '../../../../../common/runtime_types'; import { IHttpSerializedFetchError } from '..'; import { getCertsListAction } from './actions'; @@ -15,7 +15,7 @@ export interface CertsListState { data?: CertResult; error: IHttpSerializedFetchError | null; isSaving?: boolean; - savedData?: SyntheticsParamSO; + savedData?: SyntheticsParams; } const initialState: CertsListState = { diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/actions.ts b/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/actions.ts index 14b5040282f52..b1388bc2674b9 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/actions.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/actions.ts @@ -5,15 +5,14 @@ * 2.0. */ -import { SavedObject } from '@kbn/core-saved-objects-common'; -import { SyntheticsParamRequest, SyntheticsParamSO } from '../../../../../common/runtime_types'; +import { SyntheticsParamRequest, SyntheticsParams } from '../../../../../common/runtime_types'; import { createAsyncAction } from '../utils/actions'; -export const getGlobalParamAction = createAsyncAction>>( +export const getGlobalParamAction = createAsyncAction( 'GET GLOBAL PARAMS' ); -export const addNewGlobalParamAction = createAsyncAction( +export const addNewGlobalParamAction = createAsyncAction( 'ADD NEW GLOBAL PARAM' ); @@ -22,5 +21,5 @@ export const editGlobalParamAction = createAsyncAction< id: string; paramRequest: SyntheticsParamRequest; }, - SyntheticsParamSO + SyntheticsParams >('EDIT GLOBAL PARAM'); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/api.ts b/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/api.ts index 3fd5e8678d94b..528921f1d5bf4 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/api.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/api.ts @@ -5,23 +5,28 @@ * 2.0. */ -import { SavedObject } from '@kbn/core-saved-objects-common'; import { SYNTHETICS_API_URLS } from '../../../../../common/constants'; -import { SyntheticsParamRequest, SyntheticsParamSO } from '../../../../../common/runtime_types'; +import { + DeleteParamsResponse, + SyntheticsParamRequest, + SyntheticsParams, + SyntheticsParamsCodec, + SyntheticsParamsReadonlyCodec, +} from '../../../../../common/runtime_types'; import { apiService } from '../../../../utils/api_service/api_service'; -export const getGlobalParams = async (): Promise>> => { - const result = (await apiService.get(SYNTHETICS_API_URLS.PARAMS)) as { - data: Array>; - }; - return result.data; +export const getGlobalParams = async (): Promise => { + return apiService.get( + SYNTHETICS_API_URLS.PARAMS, + undefined, + SyntheticsParamsReadonlyCodec + ); }; export const addGlobalParam = async ( paramRequest: SyntheticsParamRequest -): Promise => { - return apiService.post(SYNTHETICS_API_URLS.PARAMS, paramRequest); -}; +): Promise => + apiService.post(SYNTHETICS_API_URLS.PARAMS, paramRequest, SyntheticsParamsCodec); export const editGlobalParam = async ({ paramRequest, @@ -29,19 +34,17 @@ export const editGlobalParam = async ({ }: { id: string; paramRequest: SyntheticsParamRequest; -}): Promise => { - return apiService.put(SYNTHETICS_API_URLS.PARAMS, { - id, - ...paramRequest, - }); -}; +}): Promise => + apiService.put( + SYNTHETICS_API_URLS.PARAMS, + { + id, + ...paramRequest, + }, + SyntheticsParamsCodec + ); -export const deleteGlobalParams = async ({ - ids, -}: { - ids: string[]; -}): Promise => { - return apiService.delete(SYNTHETICS_API_URLS.PARAMS, { +export const deleteGlobalParams = async (ids: string[]): Promise => + apiService.delete(SYNTHETICS_API_URLS.PARAMS, { ids: JSON.stringify(ids), }); -}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/index.ts b/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/index.ts index 6555518b6c505..89b3a0b7e1904 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/index.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/index.ts @@ -6,18 +6,17 @@ */ import { createReducer } from '@reduxjs/toolkit'; -import { SavedObject } from '@kbn/core-saved-objects-common'; -import { SyntheticsParamSO } from '../../../../../common/runtime_types'; +import { SyntheticsParams } from '../../../../../common/runtime_types'; import { IHttpSerializedFetchError } from '..'; import { addNewGlobalParamAction, editGlobalParamAction, getGlobalParamAction } from './actions'; export interface GlobalParamsState { isLoading?: boolean; - listOfParams?: Array>; + listOfParams?: SyntheticsParams[]; addError: IHttpSerializedFetchError | null; editError: IHttpSerializedFetchError | null; isSaving?: boolean; - savedData?: SyntheticsParamSO; + savedData?: SyntheticsParams; } const initialState: GlobalParamsState = { diff --git a/x-pack/plugins/synthetics/public/utils/api_service/api_service.ts b/x-pack/plugins/synthetics/public/utils/api_service/api_service.ts index b73b353f708f2..9dead89809ee9 100644 --- a/x-pack/plugins/synthetics/public/utils/api_service/api_service.ts +++ b/x-pack/plugins/synthetics/public/utils/api_service/api_service.ts @@ -41,20 +41,7 @@ class ApiService { return ApiService.instance; } - public async get( - apiUrl: string, - params?: HttpFetchQuery, - decodeType?: any, - asResponse = false - ) { - const response = await this._http!.fetch({ - path: apiUrl, - query: params, - asResponse, - }); - - this.addInspectorRequest?.({ data: response, status: FETCH_STATUS.SUCCESS, loading: false }); - + private parseResponse(response: Awaited, apiUrl: string, decodeType?: any): T { if (decodeType) { const decoded = decodeType.decode(response); if (isRight(decoded)) { @@ -69,10 +56,26 @@ class ApiService { ); } } - return response; } + public async get( + apiUrl: string, + params?: HttpFetchQuery, + decodeType?: any, + asResponse = false + ) { + const response = await this._http!.fetch({ + path: apiUrl, + query: params, + asResponse, + }); + + this.addInspectorRequest?.({ data: response, status: FETCH_STATUS.SUCCESS, loading: false }); + + return this.parseResponse(response, apiUrl, decodeType); + } + public async post(apiUrl: string, data?: any, decodeType?: any, params?: HttpFetchQuery) { const response = await this._http!.post(apiUrl, { method: 'POST', @@ -82,18 +85,7 @@ class ApiService { this.addInspectorRequest?.({ data: response, status: FETCH_STATUS.SUCCESS, loading: false }); - if (decodeType) { - const decoded = decodeType.decode(response); - if (isRight(decoded)) { - return decoded.right as T; - } else { - // eslint-disable-next-line no-console - console.warn( - `API ${apiUrl} is not returning expected response, ${formatErrors(decoded.left)}` - ); - } - } - return response; + return this.parseResponse(response, apiUrl, decodeType); } public async put(apiUrl: string, data?: any, decodeType?: any) { @@ -102,18 +94,7 @@ class ApiService { body: JSON.stringify(data), }); - if (decodeType) { - const decoded = decodeType.decode(response); - if (isRight(decoded)) { - return decoded.right as T; - } else { - // eslint-disable-next-line no-console - console.warn( - `API ${apiUrl} is not returning expected response, ${formatErrors(decoded.left)}` - ); - } - } - return response; + return this.parseResponse(response, apiUrl, decodeType); } public async delete(apiUrl: string, params?: HttpFetchQuery) { diff --git a/x-pack/plugins/synthetics/server/routes/settings/add_param.ts b/x-pack/plugins/synthetics/server/routes/settings/add_param.ts index b27ddf27a88b3..875e4da8694e1 100644 --- a/x-pack/plugins/synthetics/server/routes/settings/add_param.ts +++ b/x-pack/plugins/synthetics/server/routes/settings/add_param.ts @@ -8,8 +8,13 @@ import { schema } from '@kbn/config-schema'; import { ALL_SPACES_ID } from '@kbn/security-plugin/common/constants'; import { DEFAULT_SPACE_ID } from '@kbn/spaces-plugin/common'; +import { IKibanaResponse } from '@kbn/core/server'; import { SyntheticsRestApiRouteFactory } from '../types'; -import { SyntheticsParamRequest, SyntheticsParamSO } from '../../../common/runtime_types'; +import { + SyntheticsParamRequest, + SyntheticsParams, + SyntheticsParamSOAttributes, +} from '../../../common/runtime_types'; import { syntheticsParamType } from '../../../common/types/saved_objects'; import { SYNTHETICS_API_URLS } from '../../../common/constants'; @@ -26,7 +31,12 @@ export const addSyntheticsParamsRoute: SyntheticsRestApiRouteFactory = () => ({ }), }, writeAccess: true, - handler: async ({ request, response, server, savedObjectsClient }): Promise => { + handler: async ({ + request, + response, + server, + savedObjectsClient, + }): Promise> => { try { const { id: spaceId } = (await server.spaces?.spacesService.getActiveSpace(request)) ?? { id: DEFAULT_SPACE_ID, @@ -34,14 +44,33 @@ export const addSyntheticsParamsRoute: SyntheticsRestApiRouteFactory = () => ({ const { share_across_spaces: shareAcrossSpaces, ...data } = request.body as SyntheticsParamRequest; - const result = await savedObjectsClient.create(syntheticsParamType, data, { - initialNamespaces: shareAcrossSpaces ? [ALL_SPACES_ID] : [spaceId], + const { + attributes: { key, tags, description }, + id, + namespaces, + } = await savedObjectsClient.create>( + syntheticsParamType, + data, + { + initialNamespaces: shareAcrossSpaces ? [ALL_SPACES_ID] : [spaceId], + } + ); + return response.ok({ + body: { + id, + description, + key, + namespaces, + tags, + value: data.value, + }, }); - 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 response.notFound({ + body: { message: `Kibana space '${spaceId}' does not exist` }, + }); } throw error; diff --git a/x-pack/plugins/synthetics/server/routes/settings/delete_param.ts b/x-pack/plugins/synthetics/server/routes/settings/delete_param.ts index 7dd839a321088..dc529902b730f 100644 --- a/x-pack/plugins/synthetics/server/routes/settings/delete_param.ts +++ b/x-pack/plugins/synthetics/server/routes/settings/delete_param.ts @@ -5,10 +5,12 @@ * 2.0. */ +import { IKibanaResponse } from '@kbn/core/server'; import { schema } from '@kbn/config-schema'; import { SyntheticsRestApiRouteFactory } from '../types'; import { syntheticsParamType } from '../../../common/types/saved_objects'; import { SYNTHETICS_API_URLS } from '../../../common/constants'; +import { DeleteParamsResponse } from '../../../common/runtime_types'; export const deleteSyntheticsParamsRoute: SyntheticsRestApiRouteFactory = () => ({ method: 'DELETE', @@ -19,7 +21,11 @@ export const deleteSyntheticsParamsRoute: SyntheticsRestApiRouteFactory = () => }), }, writeAccess: true, - handler: async ({ savedObjectsClient, request }): Promise => { + handler: async ({ + savedObjectsClient, + request, + response, + }): Promise> => { const { ids } = request.query as { ids: string }; const parsedIds = JSON.parse(ids) as string[]; @@ -27,7 +33,8 @@ export const deleteSyntheticsParamsRoute: SyntheticsRestApiRouteFactory = () => parsedIds.map((id) => ({ type: syntheticsParamType, id })), { force: true } ); - - return { data: result }; + return response.ok({ + body: result.statuses.map(({ id, success }) => ({ id, deleted: success })), + }); }, }); diff --git a/x-pack/plugins/synthetics/server/routes/settings/edit_param.ts b/x-pack/plugins/synthetics/server/routes/settings/edit_param.ts index 0201f350249c6..b235d0b323c8b 100644 --- a/x-pack/plugins/synthetics/server/routes/settings/edit_param.ts +++ b/x-pack/plugins/synthetics/server/routes/settings/edit_param.ts @@ -6,9 +6,10 @@ */ import { schema } from '@kbn/config-schema'; +import { IKibanaResponse, SavedObject } from '@kbn/core/server'; import { DEFAULT_SPACE_ID } from '@kbn/spaces-plugin/common'; import { SyntheticsRestApiRouteFactory } from '../types'; -import { SyntheticsParamRequest } from '../../../common/runtime_types'; +import { SyntheticsParamRequest, SyntheticsParams } from '../../../common/runtime_types'; import { syntheticsParamType } from '../../../common/types/saved_objects'; import { SYNTHETICS_API_URLS } from '../../../common/constants'; @@ -26,7 +27,12 @@ export const editSyntheticsParamsRoute: SyntheticsRestApiRouteFactory = () => ({ }), }, writeAccess: true, - handler: async ({ savedObjectsClient, request, response, server }): Promise => { + handler: async ({ + savedObjectsClient, + request, + response, + server, + }): Promise> => { try { const { id: _spaceId } = (await server.spaces?.spacesService.getActiveSpace(request)) ?? { id: DEFAULT_SPACE_ID, @@ -39,9 +45,18 @@ export const editSyntheticsParamsRoute: SyntheticsRestApiRouteFactory = () => ({ id: string; }; - const result = await savedObjectsClient.update(syntheticsParamType, id, data); + const { value } = data; + const { + id: responseId, + attributes: { key, tags, description }, + namespaces, + } = (await savedObjectsClient.update( + syntheticsParamType, + id, + data + )) as SavedObject; - return { data: result }; + return response.ok({ body: { id: responseId, key, tags, description, namespaces, value } }); } catch (error) { if (error.output?.statusCode === 404) { const spaceId = server.spaces?.spacesService.getSpaceId(request) ?? DEFAULT_SPACE_ID; diff --git a/x-pack/plugins/synthetics/server/routes/settings/params.ts b/x-pack/plugins/synthetics/server/routes/settings/params.ts index 5622438ab47c0..789761c529e84 100644 --- a/x-pack/plugins/synthetics/server/routes/settings/params.ts +++ b/x-pack/plugins/synthetics/server/routes/settings/params.ts @@ -5,52 +5,66 @@ * 2.0. */ +import { IKibanaResponse } from '@kbn/core/server'; import { SavedObjectsFindResult } from '@kbn/core-saved-objects-api-server'; -import { DEFAULT_SPACE_ID } from '@kbn/spaces-plugin/common'; import { SyntheticsRestApiRouteFactory } from '../types'; import { syntheticsParamType } from '../../../common/types/saved_objects'; import { SYNTHETICS_API_URLS } from '../../../common/constants'; +import { SyntheticsParams, SyntheticsParamsReadonly } from '../../../common/runtime_types'; -export const getSyntheticsParamsRoute: SyntheticsRestApiRouteFactory = () => ({ +type SyntheticsParamsResponse = + | IKibanaResponse + | IKibanaResponse; +export const getSyntheticsParamsRoute: SyntheticsRestApiRouteFactory< + SyntheticsParamsResponse +> = () => ({ method: 'GET', path: SYNTHETICS_API_URLS.PARAMS, validate: {}, - handler: async ({ savedObjectsClient, request, response, server }): Promise => { + handler: async ({ savedObjectsClient, request, response, server, spaceId }) => { try { const encryptedSavedObjectsClient = server.encryptedSavedObjects.getClient(); - const { id: spaceId } = (await server.spaces?.spacesService.getActiveSpace(request)) ?? { - id: DEFAULT_SPACE_ID, - }; - const canSave = (await server.coreStart?.capabilities.resolveCapabilities(request)).uptime.save ?? false; if (canSave) { const finder = - await encryptedSavedObjectsClient.createPointInTimeFinderDecryptedAsInternalUser({ - type: syntheticsParamType, - perPage: 1000, - namespaces: [spaceId], - }); + await encryptedSavedObjectsClient.createPointInTimeFinderDecryptedAsInternalUser( + { + type: syntheticsParamType, + perPage: 1000, + namespaces: [spaceId], + } + ); - const hits: SavedObjectsFindResult[] = []; + const hits: Array> = []; for await (const result of finder.find()) { hits.push(...result.saved_objects); } - return { data: hits }; + return response.ok({ + body: hits.map(({ id, attributes, namespaces }) => ({ + ...attributes, + id, + namespaces, + })), + }); } else { - const data = await savedObjectsClient.find({ + const data = await savedObjectsClient.find({ type: syntheticsParamType, perPage: 10000, }); - - return { data: data.saved_objects }; + return response.ok({ + body: data.saved_objects.map(({ id, attributes, namespaces }) => ({ + ...attributes, + namespaces, + id, + })), + }); } } 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` } }); } diff --git a/x-pack/plugins/synthetics/server/synthetics_service/synthetics_service.ts b/x-pack/plugins/synthetics/server/synthetics_service/synthetics_service.ts index a464e4ea0f971..ecfb10cc1632f 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/synthetics_service.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/synthetics_service.ts @@ -36,7 +36,7 @@ import { ServiceLocations, SyntheticsMonitorWithId, SyntheticsMonitorWithSecrets, - SyntheticsParamSO, + SyntheticsParams, ThrottlingOptions, } from '../../common/runtime_types'; import { getServiceLocations } from './get_service_locations'; @@ -599,7 +599,7 @@ export class SyntheticsService { const paramsBySpace: Record> = Object.create(null); const finder = - await encryptedClient.createPointInTimeFinderDecryptedAsInternalUser({ + await encryptedClient.createPointInTimeFinderDecryptedAsInternalUser({ type: syntheticsParamType, perPage: 1000, namespaces: spaceId ? [spaceId] : undefined, diff --git a/x-pack/test/api_integration/apis/synthetics/add_edit_params.ts b/x-pack/test/api_integration/apis/synthetics/add_edit_params.ts index b052a06e8bf52..f5d9256a13b4d 100644 --- a/x-pack/test/api_integration/apis/synthetics/add_edit_params.ts +++ b/x-pack/test/api_integration/apis/synthetics/add_edit_params.ts @@ -4,13 +4,19 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ + import { v4 as uuidv4 } from 'uuid'; +import { pick } from 'lodash'; 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'; import { PrivateLocationTestService } from './services/private_location_test_service'; +function assertHas(actual: unknown, expected: object) { + expect(pick(actual, Object.keys(expected))).eql(expected); +} + export default function ({ getService }: FtrProviderContext) { describe('AddEditParams', function () { this.tags('skipCloud'); @@ -40,7 +46,7 @@ export default function ({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'true') .expect(200); - expect(getResponse.body.data[0].attributes).eql(testParam); + assertHas(getResponse.body[0], testParam); }); it('handles tags and description', async () => { @@ -63,11 +69,11 @@ export default function ({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'true') .expect(200); - expect(getResponse.body.data[0].attributes).eql(testParam2); + assertHas(getResponse.body[0], testParam2); }); it('handles editing a param', async () => { - const updatedParam = { + const expectedUpdatedParam = { key: 'testUpdated', value: 'testUpdated', tags: ['a tag'], @@ -84,21 +90,21 @@ export default function ({ getService }: FtrProviderContext) { .get(SYNTHETICS_API_URLS.PARAMS) .set('kbn-xsrf', 'true') .expect(200); - const param = getResponse.body.data[0]; - expect(param.attributes).eql(testParam); + const param = getResponse.body[0]; + assertHas(param, testParam); await supertestAPI .put(SYNTHETICS_API_URLS.PARAMS) .set('kbn-xsrf', 'true') - .send({ ...updatedParam, id: param.id }) + .send({ ...expectedUpdatedParam, 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); + const actualUpdatedParam = updatedGetResponse.body[0]; + assertHas(actualUpdatedParam, expectedUpdatedParam); }); it('handles spaces', async () => { @@ -118,8 +124,8 @@ export default function ({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'true') .expect(200); - expect(getResponse.body.data[0].namespaces).eql([SPACE_ID]); - expect(getResponse.body.data[0].attributes).eql(testParam); + expect(getResponse.body[0].namespaces).eql([SPACE_ID]); + assertHas(getResponse.body[0], testParam); }); it('handles editing a param in spaces', async () => { @@ -128,7 +134,7 @@ export default function ({ getService }: FtrProviderContext) { await kServer.spaces.create({ id: SPACE_ID, name: SPACE_NAME }); - const updatedParam = { + const expectedUpdatedParam = { key: 'testUpdated', value: 'testUpdated', tags: ['a tag'], @@ -145,21 +151,21 @@ export default function ({ getService }: FtrProviderContext) { .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); + const param = getResponse.body[0]; + assertHas(param, testParam); await supertestAPI .put(`/s/${SPACE_ID}${SYNTHETICS_API_URLS.PARAMS}`) .set('kbn-xsrf', 'true') - .send({ ...updatedParam, id: param.id }) + .send({ ...expectedUpdatedParam, 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); + const actualUpdatedParam = updatedGetResponse.body[0]; + assertHas(actualUpdatedParam, expectedUpdatedParam); }); it('does not allow editing a param in created in one space in a different space', async () => { @@ -188,8 +194,8 @@ export default function ({ getService }: FtrProviderContext) { .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); + const param = getResponse.body[0]; + assertHas(param, testParam); // space does exist so get request should be 200 await supertestAPI @@ -207,8 +213,8 @@ export default function ({ getService }: FtrProviderContext) { .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); + const actualUpdatedParam = updatedGetResponse.body[0]; + assertHas(actualUpdatedParam, testParam); }); it('handles invalid spaces', async () => { @@ -241,8 +247,8 @@ export default function ({ getService }: FtrProviderContext) { .get(SYNTHETICS_API_URLS.PARAMS) .set('kbn-xsrf', 'true') .expect(200); - const param = getResponse.body.data[0]; - expect(param.attributes).eql(testParam); + const param = getResponse.body[0]; + assertHas(param, testParam); await supertestAPI .put(`/s/doesnotexist${SYNTHETICS_API_URLS.PARAMS}`) @@ -268,8 +274,8 @@ export default function ({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'true') .expect(200); - expect(getResponse.body.data[0].namespaces).eql(['*']); - expect(getResponse.body.data[0].attributes).eql(testParam); + expect(getResponse.body[0].namespaces).eql(['*']); + assertHas(getResponse.body[0], testParam); }); }); } diff --git a/x-pack/test/api_integration/apis/synthetics/sync_global_params.ts b/x-pack/test/api_integration/apis/synthetics/sync_global_params.ts index 2840f8f3935f6..e8182d97e0fee 100644 --- a/x-pack/test/api_integration/apis/synthetics/sync_global_params.ts +++ b/x-pack/test/api_integration/apis/synthetics/sync_global_params.ts @@ -7,7 +7,7 @@ import { ConfigKey, HTTPFields, - SyntheticsParamSO, + SyntheticsParams, } from '@kbn/synthetics-plugin/common/runtime_types'; import { SYNTHETICS_API_URLS } from '@kbn/synthetics-plugin/common/constants'; import { omit } from 'lodash'; @@ -15,7 +15,6 @@ import { secretKeys } from '@kbn/synthetics-plugin/common/constants/monitor_mana import { PackagePolicy } from '@kbn/fleet-plugin/common'; import expect from '@kbn/expect'; import { syntheticsParamType } from '@kbn/synthetics-plugin/common/types/saved_objects'; -import { SavedObject } from '@kbn/core-saved-objects-server'; import { FtrProviderContext } from '../../ftr_provider_context'; import { getFixtureJson } from './helper/get_fixture_json'; import { PrivateLocationTestService } from './services/private_location_test_service'; @@ -157,8 +156,8 @@ export default function ({ getService }: FtrProviderContext) { expect(apiResponse.status).eql(200); - apiResponse.body.data.forEach(({ attributes }: SavedObject) => { - params[attributes.key] = attributes.value; + apiResponse.body.forEach(({ key, value }: SyntheticsParams) => { + params[key] = value; }); }); @@ -257,23 +256,25 @@ export default function ({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'true') .expect(200); - expect(getResponse.body.data.length).eql(2); + expect(getResponse.body.length).eql(2); - const paramsResponse = getResponse.body.data || []; + const paramsResponse = getResponse.body || []; const ids = paramsResponse.map((param: any) => param.id); - await supertestAPI + const deleteResponse = await supertestAPI .delete(SYNTHETICS_API_URLS.PARAMS) .query({ ids: JSON.stringify(ids) }) .set('kbn-xsrf', 'true') .expect(200); + expect(deleteResponse.body).to.have.length(2); + const getResponseAfterDelete = await supertestAPI .get(SYNTHETICS_API_URLS.PARAMS) .set('kbn-xsrf', 'true') .expect(200); - expect(getResponseAfterDelete.body.data.length).eql(0); + expect(getResponseAfterDelete.body.length).eql(0); await supertestAPI .get(SYNTHETICS_API_URLS.SYNC_GLOBAL_PARAMS)