mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[eem] allow definition to be only installed and not started (#190339)
When creating a definition we automatically start the transforms when all the components are installed. This change introduces `installOnly: boolean` query string that can be passed to routes that create definitions (`POST /internal/entities/definition` and `PUT /internal/entities/managed/enablement`) in order to only install the components ### Testing - `PUT kbn:/internal/entities/managed/enablement?installOnly=true` - `GET kbn:/internal/entities/definition` returns builtin definitions with `{ state: { installed: true, running: false } }` - check the installed transforms are not started
This commit is contained in:
parent
fe592d4f3b
commit
5290b35e5b
10 changed files with 95 additions and 17 deletions
|
@ -9,6 +9,7 @@ export * from './src/schema/entity_definition';
|
|||
export * from './src/schema/entity';
|
||||
export * from './src/schema/common';
|
||||
export * from './src/schema/patterns';
|
||||
export * from './src/rest_spec/create';
|
||||
export * from './src/rest_spec/delete';
|
||||
export * from './src/rest_spec/reset';
|
||||
export * from './src/rest_spec/get';
|
||||
|
|
14
x-pack/packages/kbn-entities-schema/src/rest_spec/create.ts
Normal file
14
x-pack/packages/kbn-entities-schema/src/rest_spec/create.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { z } from 'zod';
|
||||
|
||||
export const createEntityDefinitionQuerySchema = z.object({
|
||||
installOnly: z.optional(z.coerce.boolean()).default(false),
|
||||
});
|
||||
|
||||
export type CreateEntityDefinitionQuery = z.infer<typeof createEntityDefinitionQuerySchema>;
|
|
@ -14,3 +14,5 @@ export const deleteEntityDefinitionParamsSchema = z.object({
|
|||
export const deleteEntityDefinitionQuerySchema = z.object({
|
||||
deleteData: z.optional(z.coerce.boolean().default(false)),
|
||||
});
|
||||
|
||||
export type DeleteEntityDefinitionQuery = z.infer<typeof deleteEntityDefinitionQuerySchema>;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
import { HttpStart } from '@kbn/core/public';
|
||||
import { CreateEntityDefinitionQuery, DeleteEntityDefinitionQuery } from '@kbn/entities-schema';
|
||||
import { EntityManagerUnauthorizedError } from './errors';
|
||||
import { IEntityClient } from '../types';
|
||||
import {
|
||||
|
@ -21,9 +22,13 @@ export class EntityClient implements IEntityClient {
|
|||
return await this.http.get('/internal/entities/managed/enablement');
|
||||
}
|
||||
|
||||
async enableManagedEntityDiscovery(): Promise<EnableManagedEntityResponse> {
|
||||
async enableManagedEntityDiscovery(
|
||||
query?: CreateEntityDefinitionQuery
|
||||
): Promise<EnableManagedEntityResponse> {
|
||||
try {
|
||||
return await this.http.put('/internal/entities/managed/enablement');
|
||||
return await this.http.put('/internal/entities/managed/enablement', {
|
||||
query,
|
||||
});
|
||||
} catch (err) {
|
||||
if (err.body?.statusCode === 403) {
|
||||
throw new EntityManagerUnauthorizedError(err.body.message);
|
||||
|
@ -32,9 +37,11 @@ export class EntityClient implements IEntityClient {
|
|||
}
|
||||
}
|
||||
|
||||
async disableManagedEntityDiscovery(): Promise<DisableManagedEntityResponse> {
|
||||
async disableManagedEntityDiscovery(
|
||||
query?: DeleteEntityDefinitionQuery
|
||||
): Promise<DisableManagedEntityResponse> {
|
||||
try {
|
||||
return await this.http.delete('/internal/entities/managed/enablement');
|
||||
return await this.http.delete('/internal/entities/managed/enablement', { query });
|
||||
} catch (err) {
|
||||
if (err.body?.statusCode === 403) {
|
||||
throw new EntityManagerUnauthorizedError(err.body.message);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
import type { Plugin as PluginClass } from '@kbn/core/public';
|
||||
import { CreateEntityDefinitionQuery } from '@kbn/entities-schema';
|
||||
import {
|
||||
DisableManagedEntityResponse,
|
||||
EnableManagedEntityResponse,
|
||||
|
@ -26,6 +27,8 @@ export type EntityManagerPluginClass = PluginClass<
|
|||
|
||||
export interface IEntityClient {
|
||||
isManagedEntityDiscoveryEnabled: () => Promise<ManagedEntityEnabledResponse>;
|
||||
enableManagedEntityDiscovery: () => Promise<EnableManagedEntityResponse>;
|
||||
enableManagedEntityDiscovery: (
|
||||
query?: CreateEntityDefinitionQuery
|
||||
) => Promise<EnableManagedEntityResponse>;
|
||||
disableManagedEntityDiscovery: () => Promise<DisableManagedEntityResponse>;
|
||||
}
|
||||
|
|
|
@ -160,8 +160,10 @@ export async function installBuiltInEntityDefinitions({
|
|||
soClient,
|
||||
logger,
|
||||
builtInDefinitions,
|
||||
installOnly,
|
||||
}: Omit<InstallDefinitionParams, 'definition'> & {
|
||||
builtInDefinitions: EntityDefinition[];
|
||||
installOnly?: boolean;
|
||||
}): Promise<EntityDefinition[]> {
|
||||
if (builtInDefinitions.length === 0) return [];
|
||||
|
||||
|
@ -179,6 +181,7 @@ export async function installBuiltInEntityDefinitions({
|
|||
esClient,
|
||||
soClient,
|
||||
logger,
|
||||
installOnly,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -192,6 +195,7 @@ export async function installBuiltInEntityDefinitions({
|
|||
esClient,
|
||||
soClient,
|
||||
logger,
|
||||
installOnly,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -205,8 +209,12 @@ export async function installBuiltInEntityDefinitions({
|
|||
return await Promise.all(installPromises);
|
||||
}
|
||||
|
||||
async function installAndStartDefinition(params: InstallDefinitionParams) {
|
||||
async function installAndStartDefinition(
|
||||
params: InstallDefinitionParams & { installOnly?: boolean }
|
||||
) {
|
||||
const definition = await installEntityDefinition(params);
|
||||
await startTransform(params.esClient, definition, params.logger);
|
||||
if (!params.installOnly) {
|
||||
await startTransform(params.esClient, definition, params.logger);
|
||||
}
|
||||
return definition;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,11 @@
|
|||
*/
|
||||
|
||||
import { RequestHandlerContext } from '@kbn/core/server';
|
||||
import {
|
||||
CreateEntityDefinitionQuery,
|
||||
createEntityDefinitionQuerySchema,
|
||||
} from '@kbn/entities-schema';
|
||||
import { buildRouteValidationWithZod } from '@kbn/zod-helpers';
|
||||
import { SetupRouteOptions } from '../types';
|
||||
import {
|
||||
canEnableEntityDiscovery,
|
||||
|
@ -26,10 +31,12 @@ export function enableEntityDiscoveryRoute<T extends RequestHandlerContext>({
|
|||
server,
|
||||
logger,
|
||||
}: SetupRouteOptions<T>) {
|
||||
router.put<unknown, unknown, unknown>(
|
||||
router.put<unknown, CreateEntityDefinitionQuery, unknown>(
|
||||
{
|
||||
path: '/internal/entities/managed/enablement',
|
||||
validate: false,
|
||||
validate: {
|
||||
query: buildRouteValidationWithZod(createEntityDefinitionQuerySchema),
|
||||
},
|
||||
},
|
||||
async (context, req, res) => {
|
||||
try {
|
||||
|
@ -87,6 +94,7 @@ export function enableEntityDiscoveryRoute<T extends RequestHandlerContext>({
|
|||
builtInDefinitions,
|
||||
esClient,
|
||||
soClient,
|
||||
installOnly: req.query.installOnly,
|
||||
});
|
||||
|
||||
return res.ok({ body: { success: true } });
|
||||
|
|
|
@ -6,7 +6,12 @@
|
|||
*/
|
||||
|
||||
import { RequestHandlerContext } from '@kbn/core/server';
|
||||
import { EntityDefinition, entityDefinitionSchema } from '@kbn/entities-schema';
|
||||
import {
|
||||
EntityDefinition,
|
||||
entityDefinitionSchema,
|
||||
createEntityDefinitionQuerySchema,
|
||||
CreateEntityDefinitionQuery,
|
||||
} from '@kbn/entities-schema';
|
||||
import { buildRouteValidationWithZod } from '@kbn/zod-helpers';
|
||||
import { SetupRouteOptions } from '../types';
|
||||
import { EntityIdConflict } from '../../lib/entities/errors/entity_id_conflict_error';
|
||||
|
@ -19,11 +24,12 @@ export function createEntityDefinitionRoute<T extends RequestHandlerContext>({
|
|||
router,
|
||||
server,
|
||||
}: SetupRouteOptions<T>) {
|
||||
router.post<unknown, unknown, EntityDefinition>(
|
||||
router.post<unknown, CreateEntityDefinitionQuery, EntityDefinition>(
|
||||
{
|
||||
path: '/internal/entities/definition',
|
||||
validate: {
|
||||
body: buildRouteValidationWithZod(entityDefinitionSchema.strict()),
|
||||
query: buildRouteValidationWithZod(createEntityDefinitionQuerySchema),
|
||||
},
|
||||
},
|
||||
async (context, req, res) => {
|
||||
|
@ -39,7 +45,9 @@ export function createEntityDefinitionRoute<T extends RequestHandlerContext>({
|
|||
definition: req.body,
|
||||
});
|
||||
|
||||
await startTransform(esClient, definition, logger);
|
||||
if (!req.query.installOnly) {
|
||||
await startTransform(esClient, definition, logger);
|
||||
}
|
||||
|
||||
return res.ok({ body: definition });
|
||||
} catch (e) {
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
|
||||
import expect from '@kbn/expect';
|
||||
import { EntityDefinition } from '@kbn/entities-schema';
|
||||
import {
|
||||
entityDefinition as mockDefinition,
|
||||
entityDefinitionWithBackfill as mockBackfillDefinition,
|
||||
|
@ -26,17 +25,36 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
const { definitions } = await getInstalledDefinitions(supertest);
|
||||
expect(definitions.length).to.eql(2);
|
||||
expect(
|
||||
definitions.find((definition: EntityDefinition) => definition.id === mockDefinition.id)
|
||||
definitions.find(
|
||||
(definition) =>
|
||||
definition.id === mockDefinition.id &&
|
||||
definition.state.installed === true &&
|
||||
definition.state.running === true
|
||||
)
|
||||
);
|
||||
expect(
|
||||
definitions.find(
|
||||
(definition: EntityDefinition) => definition.id === mockBackfillDefinition.id
|
||||
(definition) =>
|
||||
definition.id === mockBackfillDefinition.id &&
|
||||
definition.state.installed === true &&
|
||||
definition.state.running === true
|
||||
)
|
||||
);
|
||||
|
||||
await uninstallDefinition(supertest, mockDefinition.id);
|
||||
await uninstallDefinition(supertest, mockBackfillDefinition.id);
|
||||
});
|
||||
|
||||
it('does not start transforms when specified', async () => {
|
||||
await installDefinition(supertest, mockDefinition, { installOnly: true });
|
||||
|
||||
const { definitions } = await getInstalledDefinitions(supertest);
|
||||
expect(definitions.length).to.eql(1);
|
||||
expect(definitions[0].state.installed).to.eql(true);
|
||||
expect(definitions[0].state.running).to.eql(false);
|
||||
|
||||
await uninstallDefinition(supertest, mockDefinition.id);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -7,13 +7,17 @@
|
|||
|
||||
import { Agent } from 'supertest';
|
||||
import { EntityDefinition } from '@kbn/entities-schema';
|
||||
import { EntityDefinitionWithState } from '@kbn/entityManager-plugin/server/lib/entities/types';
|
||||
|
||||
export interface Auth {
|
||||
username: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
export const getInstalledDefinitions = async (supertest: Agent, auth?: Auth) => {
|
||||
export const getInstalledDefinitions = async (
|
||||
supertest: Agent,
|
||||
auth?: Auth
|
||||
): Promise<{ definitions: EntityDefinitionWithState[] }> => {
|
||||
let req = supertest.get('/internal/entities/definition').set('kbn-xsrf', 'xxx');
|
||||
if (auth) {
|
||||
req = req.auth(auth.username, auth.password);
|
||||
|
@ -22,9 +26,14 @@ export const getInstalledDefinitions = async (supertest: Agent, auth?: Auth) =>
|
|||
return response.body;
|
||||
};
|
||||
|
||||
export const installDefinition = async (supertest: Agent, definition: EntityDefinition) => {
|
||||
export const installDefinition = async (
|
||||
supertest: Agent,
|
||||
definition: EntityDefinition,
|
||||
query: Record<string, any> = {}
|
||||
) => {
|
||||
return supertest
|
||||
.post('/internal/entities/definition')
|
||||
.query(query)
|
||||
.set('kbn-xsrf', 'xxx')
|
||||
.send(definition)
|
||||
.expect(200);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue