diff --git a/.buildkite/pipelines/on_merge_unsupported_ftrs.yml b/.buildkite/pipelines/on_merge_unsupported_ftrs.yml index 8d67cbf37d8a0..ceef6e06ef96f 100644 --- a/.buildkite/pipelines/on_merge_unsupported_ftrs.yml +++ b/.buildkite/pipelines/on_merge_unsupported_ftrs.yml @@ -88,7 +88,7 @@ steps: - command: .buildkite/scripts/steps/functional/defend_workflows.sh label: 'Defend Workflows Cypress Tests' agents: - queue: n2-4-spot + queue: n2-4-virt depends_on: build timeout_in_minutes: 120 parallelism: 6 diff --git a/.buildkite/pipelines/pull_request/defend_workflows.yml b/.buildkite/pipelines/pull_request/defend_workflows.yml index c60030497b623..da79114cbebfb 100644 --- a/.buildkite/pipelines/pull_request/defend_workflows.yml +++ b/.buildkite/pipelines/pull_request/defend_workflows.yml @@ -14,7 +14,7 @@ steps: - command: .buildkite/scripts/steps/functional/defend_workflows_serverless.sh label: 'Defend Workflows Cypress Tests on Serverless' agents: - queue: n2-4-spot + queue: n2-4-virt depends_on: build timeout_in_minutes: 120 parallelism: 2 diff --git a/packages/kbn-dev-utils/src/dev_service_account.ts b/packages/kbn-dev-utils/src/dev_service_account.ts index efcd51b3f1559..32a50f5fcecd2 100644 --- a/packages/kbn-dev-utils/src/dev_service_account.ts +++ b/packages/kbn-dev-utils/src/dev_service_account.ts @@ -10,7 +10,7 @@ const env = process.env; /** * `kibana-dev` service account token for connecting to ESS - * See packages/kbn-es/src/ess_resources/README.md + * See packages/kbn-es/src/serverless_resources/README.md */ export const kibanaDevServiceAccount = { token: diff --git a/packages/kbn-es/src/cli_commands/serverless.ts b/packages/kbn-es/src/cli_commands/serverless.ts index db2a70bb7b715..7ee4f08fb94fe 100644 --- a/packages/kbn-es/src/cli_commands/serverless.ts +++ b/packages/kbn-es/src/cli_commands/serverless.ts @@ -28,19 +28,19 @@ export const serverless: Command = { return dedent` Options: - --tag Image tag of ESS to run from ${SERVERLESS_REPO} [default: ${SERVERLESS_TAG}] - --image Full path of ESS image to run, has precedence over tag. [default: ${SERVERLESS_IMG}] + --tag Image tag of ES serverless to run from ${SERVERLESS_REPO} [default: ${SERVERLESS_TAG}] + --image Full path of ES serverless image to run, has precedence over tag. [default: ${SERVERLESS_IMG}] - --background Start ESS without attaching to the first node's logs + --background Start ES serverless without attaching to the first node's logs --basePath Path to the directory where the ES cluster will store data --clean Remove existing file system object store before running - --kill Kill running ESS nodes if detected on startup + --kill Kill running ES serverless nodes if detected on startup --port The port to bind to on 127.0.0.1 [default: ${DEFAULT_PORT}] - --ssl Enable HTTP SSL on Elasticsearch + --ssl Enable HTTP SSL on the ES cluster --skipTeardown If this process exits, leave the ES cluster running in the background --waitForReady Wait for the ES cluster to be ready to serve requests - -E Additional key=value settings to pass to Elasticsearch + -E Additional key=value settings to pass to ES -F Absolute paths for files to mount into containers Examples: diff --git a/packages/kbn-es/src/paths.ts b/packages/kbn-es/src/paths.ts index 823b8d6b59361..d9b4be41aa15b 100644 --- a/packages/kbn-es/src/paths.ts +++ b/packages/kbn-es/src/paths.ts @@ -24,31 +24,43 @@ export const ES_CONFIG = 'config/elasticsearch.yml'; export const ES_KEYSTORE_BIN = maybeUseBat('./bin/elasticsearch-keystore'); -export const ESS_OPERATOR_USERS_PATH = resolve(__dirname, './ess_resources/operator_users.yml'); -export const ESS_SERVICE_TOKENS_PATH = resolve(__dirname, './ess_resources/service_tokens'); +export const SERVERLESS_OPERATOR_USERS_PATH = resolve( + __dirname, + './serverless_resources/operator_users.yml' +); +export const SERVERLESS_SERVICE_TOKENS_PATH = resolve( + __dirname, + './serverless_resources/service_tokens' +); -export const ESS_USERS_PATH = resolve(__dirname, './ess_resources/users'); -export const ESS_USERS_ROLES_PATH = resolve(__dirname, './ess_resources/users_roles'); +export const SERVERLESS_USERS_PATH = resolve(__dirname, './serverless_resources/users'); +export const SERVERLESS_USERS_ROLES_PATH = resolve(__dirname, './serverless_resources/users_roles'); -export const ESS_ROLES_PATH = resolve(__dirname, './ess_resources/roles.yml'); -export const ESS_ROLE_MAPPING_PATH = resolve(__dirname, './ess_resources/role_mapping.yml'); +export const SERVERLESS_ROLES_PATH = resolve(__dirname, './serverless_resources/roles.yml'); +export const SERVERLESS_ROLE_MAPPING_PATH = resolve( + __dirname, + './serverless_resources/role_mapping.yml' +); -export const ESS_SECRETS_PATH = resolve(__dirname, './ess_resources/secrets.json'); +export const SERVERLESS_SECRETS_PATH = resolve(__dirname, './serverless_resources/secrets.json'); -export const ESS_SECRETS_SSL_PATH = resolve(__dirname, './ess_resources/secrets_ssl.json'); +export const SERVERLESS_SECRETS_SSL_PATH = resolve( + __dirname, + './serverless_resources/secrets_ssl.json' +); -export const ESS_JWKS_PATH = resolve(__dirname, './ess_resources/jwks.json'); +export const SERVERLESS_JWKS_PATH = resolve(__dirname, './serverless_resources/jwks.json'); -export const ESS_RESOURCES_PATHS = [ - ESS_OPERATOR_USERS_PATH, - ESS_ROLE_MAPPING_PATH, - ESS_ROLES_PATH, - ESS_SERVICE_TOKENS_PATH, - ESS_USERS_PATH, - ESS_USERS_ROLES_PATH, +export const SERVERLESS_RESOURCES_PATHS = [ + SERVERLESS_OPERATOR_USERS_PATH, + SERVERLESS_ROLE_MAPPING_PATH, + SERVERLESS_ROLES_PATH, + SERVERLESS_SERVICE_TOKENS_PATH, + SERVERLESS_USERS_PATH, + SERVERLESS_USERS_ROLES_PATH, ]; -export const ESS_CONFIG_PATH = '/usr/share/elasticsearch/config/'; +export const SERVERLESS_CONFIG_PATH = '/usr/share/elasticsearch/config/'; // Files need to be inside config for permissions reasons inside the container -export const ESS_FILES_PATH = `${ESS_CONFIG_PATH}files/`; +export const SERVERLESS_FILES_PATH = `${SERVERLESS_CONFIG_PATH}files/`; diff --git a/packages/kbn-es/src/ess_resources/README.md b/packages/kbn-es/src/serverless_resources/README.md similarity index 78% rename from packages/kbn-es/src/ess_resources/README.md rename to packages/kbn-es/src/serverless_resources/README.md index a7af386bcff1f..d1ae204117075 100644 --- a/packages/kbn-es/src/ess_resources/README.md +++ b/packages/kbn-es/src/serverless_resources/README.md @@ -1,5 +1,5 @@ # Elasticsearch Serverless Resources -The resources in this directory are used for seeding Elasticsearch Serverless (ESS) images with users, roles and tokens for SSL and authentication. ESS requires file realm authentication, so we will bind mount them into the containers at `/usr/share/elasticsearch/config/`. +The resources in this directory are used for seeding Elasticsearch Serverless images with users, roles and tokens for SSL and authentication. Serverless requires file realm authentication, so we will bind mount them into the containers at `/usr/share/elasticsearch/config/`. ## Users @@ -21,7 +21,7 @@ password: changeme ## Service Account and Tokens -This section for Service Accounts was originally from the [ESS repository](https://github.com/elastic/elasticsearch-serverless/blob/main/serverless-build-tools/src/main/resources/README.service_tokens.md). +This section for Service Accounts was originally from the [ES Serverless repository](https://github.com/elastic/elasticsearch-serverless/blob/main/serverless-build-tools/src/main/resources/README.service_tokens.md). The "service_tokens" file contains this line: ``` @@ -46,4 +46,4 @@ If a node is configured to use this `service_tokens` file, then you can authenti curl -H "Authorization: Bearer AAEAAWVsYXN0aWMva2liYW5hL2tpYmFuYS1kZXY6VVVVVVVVTEstKiBaNA" http://localhost:9200/_security/_authenticate ``` -The name of the token (`kibana-dev`) is important because the `operator_users.yml` file designates that token as an operator and allows us to seed an ESS cluster with this token. \ No newline at end of file +The name of the token (`kibana-dev`) is important because the `operator_users.yml` file designates that token as an operator and allows us to seed a serverless cluster with this token. \ No newline at end of file diff --git a/packages/kbn-es/src/ess_resources/jwks.json b/packages/kbn-es/src/serverless_resources/jwks.json similarity index 100% rename from packages/kbn-es/src/ess_resources/jwks.json rename to packages/kbn-es/src/serverless_resources/jwks.json diff --git a/packages/kbn-es/src/ess_resources/operator_users.yml b/packages/kbn-es/src/serverless_resources/operator_users.yml similarity index 100% rename from packages/kbn-es/src/ess_resources/operator_users.yml rename to packages/kbn-es/src/serverless_resources/operator_users.yml diff --git a/packages/kbn-es/src/ess_resources/role_mapping.yml b/packages/kbn-es/src/serverless_resources/role_mapping.yml similarity index 100% rename from packages/kbn-es/src/ess_resources/role_mapping.yml rename to packages/kbn-es/src/serverless_resources/role_mapping.yml diff --git a/packages/kbn-es/src/ess_resources/roles.yml b/packages/kbn-es/src/serverless_resources/roles.yml similarity index 100% rename from packages/kbn-es/src/ess_resources/roles.yml rename to packages/kbn-es/src/serverless_resources/roles.yml diff --git a/packages/kbn-es/src/ess_resources/secrets.json b/packages/kbn-es/src/serverless_resources/secrets.json similarity index 100% rename from packages/kbn-es/src/ess_resources/secrets.json rename to packages/kbn-es/src/serverless_resources/secrets.json diff --git a/packages/kbn-es/src/ess_resources/secrets_ssl.json b/packages/kbn-es/src/serverless_resources/secrets_ssl.json similarity index 100% rename from packages/kbn-es/src/ess_resources/secrets_ssl.json rename to packages/kbn-es/src/serverless_resources/secrets_ssl.json diff --git a/packages/kbn-es/src/ess_resources/service_tokens b/packages/kbn-es/src/serverless_resources/service_tokens similarity index 100% rename from packages/kbn-es/src/ess_resources/service_tokens rename to packages/kbn-es/src/serverless_resources/service_tokens diff --git a/packages/kbn-es/src/ess_resources/users b/packages/kbn-es/src/serverless_resources/users similarity index 100% rename from packages/kbn-es/src/ess_resources/users rename to packages/kbn-es/src/serverless_resources/users diff --git a/packages/kbn-es/src/ess_resources/users_roles b/packages/kbn-es/src/serverless_resources/users_roles similarity index 100% rename from packages/kbn-es/src/ess_resources/users_roles rename to packages/kbn-es/src/serverless_resources/users_roles diff --git a/packages/kbn-es/src/utils/docker.test.ts b/packages/kbn-es/src/utils/docker.test.ts index 1d4f1a71468af..d48cddd6fdb6d 100644 --- a/packages/kbn-es/src/utils/docker.test.ts +++ b/packages/kbn-es/src/utils/docker.test.ts @@ -32,7 +32,12 @@ import { } from './docker'; import { ToolingLog, ToolingLogCollectingWriter } from '@kbn/tooling-log'; import { ES_P12_PATH } from '@kbn/dev-utils'; -import { ESS_CONFIG_PATH, ESS_RESOURCES_PATHS, ESS_SECRETS_PATH, ESS_JWKS_PATH } from '../paths'; +import { + SERVERLESS_CONFIG_PATH, + SERVERLESS_RESOURCES_PATHS, + SERVERLESS_SECRETS_PATH, + SERVERLESS_JWKS_PATH, +} from '../paths'; import * as waitClusterUtil from './wait_until_cluster_ready'; jest.mock('execa'); @@ -77,8 +82,8 @@ afterEach(() => { jest.clearAllMocks(); }); -const essResources = ESS_RESOURCES_PATHS.reduce((acc, path) => { - acc.push(`${path}:${ESS_CONFIG_PATH}${basename(path)}`); +const serverlessResources = SERVERLESS_RESOURCES_PATHS.reduce((acc, path) => { + acc.push(`${path}:${SERVERLESS_CONFIG_PATH}${basename(path)}`); return acc; }, []); @@ -88,10 +93,10 @@ const volumeCmdTest = async (volumeCmd: string[]) => { expect(volumeCmd).toEqual( expect.arrayContaining([ ...getESp12Volume(), - ...essResources, + ...serverlessResources, `${baseEsPath}:/objectstore:z`, - `${ESS_SECRETS_PATH}:${ESS_CONFIG_PATH}secrets/secrets.json:z`, - `${ESS_JWKS_PATH}:${ESS_CONFIG_PATH}secrets/jwks.json:z`, + `${SERVERLESS_SECRETS_PATH}:${SERVERLESS_CONFIG_PATH}secrets/secrets.json:z`, + `${SERVERLESS_JWKS_PATH}:${SERVERLESS_CONFIG_PATH}secrets/jwks.json:z`, ]) ); @@ -428,7 +433,11 @@ describe('setupServerlessVolumes()', () => { const volumeCmd = await setupServerlessVolumes(log, { basePath: baseEsPath, ssl: true }); - const requiredPaths = [`${baseEsPath}:/objectstore:z`, ES_P12_PATH, ...ESS_RESOURCES_PATHS]; + const requiredPaths = [ + `${baseEsPath}:/objectstore:z`, + ES_P12_PATH, + ...SERVERLESS_RESOURCES_PATHS, + ]; const pathsNotIncludedInCmd = requiredPaths.filter( (path) => !volumeCmd.some((cmd) => cmd.includes(path)) ); diff --git a/packages/kbn-es/src/utils/docker.ts b/packages/kbn-es/src/utils/docker.ts index 307ff796ae5e5..00a1d7ce9dc54 100644 --- a/packages/kbn-es/src/utils/docker.ts +++ b/packages/kbn-es/src/utils/docker.ts @@ -24,17 +24,17 @@ import { import { createCliError } from '../errors'; import { EsClusterExecOptions } from '../cluster_exec_options'; import { - ESS_RESOURCES_PATHS, - ESS_SECRETS_PATH, - ESS_JWKS_PATH, - ESS_CONFIG_PATH, - ESS_FILES_PATH, - ESS_SECRETS_SSL_PATH, + SERVERLESS_RESOURCES_PATHS, + SERVERLESS_SECRETS_PATH, + SERVERLESS_JWKS_PATH, + SERVERLESS_CONFIG_PATH, + SERVERLESS_FILES_PATH, + SERVERLESS_SECRETS_SSL_PATH, } from '../paths'; import { ELASTIC_SERVERLESS_SUPERUSER, ELASTIC_SERVERLESS_SUPERUSER_PASSWORD, -} from './ess_file_realm'; +} from './serverless_file_realm'; import { SYSTEM_INDICES_SUPERUSER } from './native_realm'; import { waitUntilClusterReady } from './wait_until_cluster_ready'; @@ -167,13 +167,19 @@ const DEFAULT_SERVERLESS_ESARGS: Array<[string, string]> = [ ['xpack.security.authc.realms.jwt.jwt1.order', '-98'], - ['xpack.security.authc.realms.jwt.jwt1.pkc_jwkset_path', `${ESS_CONFIG_PATH}secrets/jwks.json`], + [ + 'xpack.security.authc.realms.jwt.jwt1.pkc_jwkset_path', + `${SERVERLESS_CONFIG_PATH}secrets/jwks.json`, + ], ['xpack.security.operator_privileges.enabled', 'true'], ['xpack.security.transport.ssl.enabled', 'true'], - ['xpack.security.transport.ssl.keystore.path', `${ESS_CONFIG_PATH}certs/elasticsearch.p12`], + [ + 'xpack.security.transport.ssl.keystore.path', + `${SERVERLESS_CONFIG_PATH}certs/elasticsearch.p12`, + ], ['xpack.security.transport.ssl.verification_mode', 'certificate'], ]; @@ -181,7 +187,7 @@ const DEFAULT_SERVERLESS_ESARGS: Array<[string, string]> = [ const DEFAULT_SSL_ESARGS: Array<[string, string]> = [ ['xpack.security.http.ssl.enabled', 'true'], - ['xpack.security.http.ssl.keystore.path', `${ESS_CONFIG_PATH}certs/elasticsearch.p12`], + ['xpack.security.http.ssl.keystore.path', `${SERVERLESS_CONFIG_PATH}certs/elasticsearch.p12`], ['xpack.security.http.ssl.verification_mode', 'certificate'], ]; @@ -193,7 +199,10 @@ const DOCKER_SSL_ESARGS: Array<[string, string]> = [ ['xpack.security.transport.ssl.enabled', 'true'], - ['xpack.security.transport.ssl.keystore.path', `${ESS_CONFIG_PATH}certs/elasticsearch.p12`], + [ + 'xpack.security.transport.ssl.keystore.path', + `${SERVERLESS_CONFIG_PATH}certs/elasticsearch.p12`, + ], ['xpack.security.transport.ssl.verification_mode', 'certificate'], @@ -436,16 +445,16 @@ export function resolveEsArgs( } export function getESp12Volume() { - return ['--volume', `${ES_P12_PATH}:${ESS_CONFIG_PATH}certs/elasticsearch.p12`]; + return ['--volume', `${ES_P12_PATH}:${SERVERLESS_CONFIG_PATH}certs/elasticsearch.p12`]; } /** * Removes REPO_ROOT from hostPath. Keep the rest to avoid filename collisions. - * Returns the path where a file will be mounted inside the ES or ESS container. + * Returns the path where a file will be mounted inside the ES or ES serverless container. * /root/kibana/package/foo/bar.json => /usr/share/elasticsearch/files/package/foo/bar.json */ export function getDockerFileMountPath(hostPath: string) { - return join(ESS_FILES_PATH, hostPath.replace(REPO_ROOT, '')); + return join(SERVERLESS_FILES_PATH, hostPath.replace(REPO_ROOT, '')); } /** @@ -491,21 +500,23 @@ export async function setupServerlessVolumes(log: ToolingLog, options: Serverles volumeCmds.push(...fileCmds); } - const essResources = ESS_RESOURCES_PATHS.reduce((acc, path) => { - acc.push('--volume', `${path}:${ESS_CONFIG_PATH}${basename(path)}`); + const serverlessResources = SERVERLESS_RESOURCES_PATHS.reduce((acc, path) => { + acc.push('--volume', `${path}:${SERVERLESS_CONFIG_PATH}${basename(path)}`); return acc; }, []); volumeCmds.push( ...getESp12Volume(), - ...essResources, + ...serverlessResources, '--volume', - `${ssl ? ESS_SECRETS_SSL_PATH : ESS_SECRETS_PATH}:${ESS_CONFIG_PATH}secrets/secrets.json:z`, + `${ + ssl ? SERVERLESS_SECRETS_SSL_PATH : SERVERLESS_SECRETS_PATH + }:${SERVERLESS_CONFIG_PATH}secrets/secrets.json:z`, '--volume', - `${ESS_JWKS_PATH}:${ESS_CONFIG_PATH}secrets/jwks.json:z` + `${SERVERLESS_JWKS_PATH}:${SERVERLESS_CONFIG_PATH}secrets/jwks.json:z` ); return volumeCmds; @@ -592,7 +603,7 @@ export async function runServerlessCluster(log: ToolingLog, options: ServerlessO if (options.ssl) { log.warning(`SSL has been enabled for ES. Kibana should be started with the SSL flag so that it can authenticate with ES. - See packages/kbn-es/src/ess_resources/README.md for additional information on authentication. + See packages/kbn-es/src/serverless_resources/README.md for additional information on authentication. `); } @@ -631,7 +642,7 @@ export async function runServerlessCluster(log: ToolingLog, options: ServerlessO } if (!options.background) { - // The ESS cluster has to be started detached, so we attach a logger afterwards for output + // The serverless cluster has to be started detached, so we attach a logger afterwards for output await execa('docker', ['logs', '-f', SERVERLESS_NODES[0].name], { // inherit is required to show Docker output and Java console output for pw, enrollment token, etc stdio: ['ignore', 'inherit', 'inherit'], diff --git a/packages/kbn-es/src/utils/index.ts b/packages/kbn-es/src/utils/index.ts index cc46d0bf28271..3110b82033be2 100644 --- a/packages/kbn-es/src/utils/index.ts +++ b/packages/kbn-es/src/utils/index.ts @@ -17,4 +17,4 @@ export { buildSnapshot } from './build_snapshot'; export { archiveForPlatform } from './build_snapshot'; export * from './parse_timeout_to_ms'; export * from './docker'; -export * from './ess_file_realm'; +export * from './serverless_file_realm'; diff --git a/packages/kbn-es/src/utils/ess_file_realm.ts b/packages/kbn-es/src/utils/serverless_file_realm.ts similarity index 100% rename from packages/kbn-es/src/utils/ess_file_realm.ts rename to packages/kbn-es/src/utils/serverless_file_realm.ts diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/archive/index.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/archive/index.ts new file mode 100644 index 0000000000000..c8b190b59b795 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/archive/index.ts @@ -0,0 +1,23 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { archiveBodySchema, archiveParamsSchema } from './schemas/latest'; +export type { + ArchiveMaintenanceWindowRequestBody, + ArchiveMaintenanceWindowRequestParams, + ArchiveMaintenanceWindowResponse, +} from './types/latest'; + +export { + archiveBodySchema as archiveBodySchemaV1, + archiveParamsSchema as archiveParamsSchemaV1, +} from './schemas/v1'; +export type { + ArchiveMaintenanceWindowRequestBody as ArchiveMaintenanceWindowRequestBodyV1, + ArchiveMaintenanceWindowRequestParams as ArchiveMaintenanceWindowRequestParamsV1, + ArchiveMaintenanceWindowResponse as ArchiveMaintenanceWindowResponseV1, +} from './types/latest'; diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/archive/schemas/latest.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/archive/schemas/latest.ts new file mode 100644 index 0000000000000..f3db50c4e784d --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/archive/schemas/latest.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { archiveBodySchema, archiveParamsSchema } from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/archive/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/archive/schemas/v1.ts new file mode 100644 index 0000000000000..41e66b8257268 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/archive/schemas/v1.ts @@ -0,0 +1,16 @@ +/* + * 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 { schema } from '@kbn/config-schema'; + +export const archiveParamsSchema = schema.object({ + id: schema.string(), +}); + +export const archiveBodySchema = schema.object({ + archive: schema.boolean(), +}); diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/archive/types/latest.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/archive/types/latest.ts new file mode 100644 index 0000000000000..010d0ef883020 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/archive/types/latest.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type { + ArchiveMaintenanceWindowRequestBody, + ArchiveMaintenanceWindowRequestParams, + ArchiveMaintenanceWindowResponse, +} from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/archive/types/v1.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/archive/types/v1.ts new file mode 100644 index 0000000000000..37ce349e23a1e --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/archive/types/v1.ts @@ -0,0 +1,17 @@ +/* + * 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 type { TypeOf } from '@kbn/config-schema'; +import { MaintenanceWindowResponseV1 } from '../../../response'; +import { archiveBodySchemaV1, archiveParamsSchemaV1 } from '..'; + +export type ArchiveMaintenanceWindowRequestBody = TypeOf; +export type ArchiveMaintenanceWindowRequestParams = TypeOf; + +export interface ArchiveMaintenanceWindowResponse { + body: MaintenanceWindowResponseV1; +} diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/bulk_get/index.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/bulk_get/index.ts new file mode 100644 index 0000000000000..e5cbf04054ac6 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/bulk_get/index.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { bulkGetBodySchema } from './schemas/latest'; +export type { + BulkGetMaintenanceWindowsRequestBody, + BulkGetMaintenanceWindowsResponse, + BulkGetMaintenanceWindowsResponseBody, +} from './types/latest'; + +export { bulkGetBodySchema as bulkGetBodySchemaV1 } from './schemas/v1'; +export type { + BulkGetMaintenanceWindowsRequestBody as BulkGetMaintenanceWindowsRequestBodyV1, + BulkGetMaintenanceWindowsResponse as BulkGetMaintenanceWindowsResponseV1, + BulkGetMaintenanceWindowsResponseBody as BulkGetMaintenanceWindowsResponseBodyV1, +} from './types/v1'; diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/bulk_get/schemas/latest.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/bulk_get/schemas/latest.ts new file mode 100644 index 0000000000000..46433ae2d3b56 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/bulk_get/schemas/latest.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { bulkGetBodySchema } from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/bulk_get/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/bulk_get/schemas/v1.ts new file mode 100644 index 0000000000000..394802e32f44e --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/bulk_get/schemas/v1.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { schema } from '@kbn/config-schema'; + +export const bulkGetBodySchema = schema.object({ + ids: schema.arrayOf(schema.string()), +}); diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/bulk_get/types/latest.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/bulk_get/types/latest.ts new file mode 100644 index 0000000000000..b4834afe6d07d --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/bulk_get/types/latest.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type { + BulkGetMaintenanceWindowsRequestBody, + BulkGetMaintenanceWindowsResponse, + BulkGetMaintenanceWindowsResponseBody, +} from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/bulk_get/types/v1.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/bulk_get/types/v1.ts new file mode 100644 index 0000000000000..153df0010293a --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/bulk_get/types/v1.ts @@ -0,0 +1,26 @@ +/* + * 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 type { TypeOf } from '@kbn/config-schema'; +import { MaintenanceWindowResponseV1 } from '../../../response'; +import { bulkGetBodySchemaV1 } from '..'; + +export type BulkGetMaintenanceWindowsRequestBody = TypeOf; + +export interface BulkGetMaintenanceWindowsResponseBody { + maintenance_windows: MaintenanceWindowResponseV1[]; + errors: Array<{ + id: string; + error: string; + message: string; + status_code: number; + }>; +} + +export interface BulkGetMaintenanceWindowsResponse { + body: BulkGetMaintenanceWindowsResponseBody; +} diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/create/index.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/create/index.ts new file mode 100644 index 0000000000000..1013fcb0b7f56 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/create/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { createBodySchema } from './schemas/latest'; +export type { + CreateMaintenanceWindowRequestBody, + CreateMaintenanceWindowResponse, +} from './types/latest'; + +export { createBodySchema as createBodySchemaV1 } from './schemas/v1'; +export type { + CreateMaintenanceWindowRequestBody as CreateMaintenanceWindowRequestBodyV1, + CreateMaintenanceWindowResponse as CreateMaintenanceWindowResponseV1, +} from './types/v1'; diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/create/schemas/latest.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/create/schemas/latest.ts new file mode 100644 index 0000000000000..e7a9ece5cecaf --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/create/schemas/latest.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { createBodySchema } from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/create/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/create/schemas/v1.ts new file mode 100644 index 0000000000000..6199bee1b2bfc --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/create/schemas/v1.ts @@ -0,0 +1,15 @@ +/* + * 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 { schema } from '@kbn/config-schema'; +import { rRuleRequestSchemaV1 } from '../../../../r_rule'; + +export const createBodySchema = schema.object({ + title: schema.string(), + duration: schema.number(), + r_rule: rRuleRequestSchemaV1, +}); diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/create/types/latest.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/create/types/latest.ts new file mode 100644 index 0000000000000..08b5432ba042d --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/create/types/latest.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type { CreateMaintenanceWindowRequestBody, CreateMaintenanceWindowResponse } from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/create/types/v1.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/create/types/v1.ts new file mode 100644 index 0000000000000..269206c977687 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/create/types/v1.ts @@ -0,0 +1,16 @@ +/* + * 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 type { TypeOf } from '@kbn/config-schema'; +import { MaintenanceWindowResponseV1 } from '../../../response'; +import { createBodySchemaV1 } from '..'; + +export type CreateMaintenanceWindowRequestBody = TypeOf; + +export interface CreateMaintenanceWindowResponse { + body: MaintenanceWindowResponseV1; +} diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/delete/index.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/delete/index.ts new file mode 100644 index 0000000000000..56dd23821f457 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/delete/index.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { deleteParamsSchema } from './schemas/latest'; +export type { DeleteMaintenanceWindowRequestParams } from './types/latest'; + +export { deleteParamsSchema as deleteParamsSchemaV1 } from './schemas/v1'; +export type { DeleteMaintenanceWindowRequestParams as DeleteMaintenanceWindowRequestParamsV1 } from './types/v1'; diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/delete/schemas/latest.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/delete/schemas/latest.ts new file mode 100644 index 0000000000000..c2c12cb127bf1 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/delete/schemas/latest.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { deleteParamsSchema } from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/delete/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/delete/schemas/v1.ts new file mode 100644 index 0000000000000..609e3f172c5fb --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/delete/schemas/v1.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { schema } from '@kbn/config-schema'; + +export const deleteParamsSchema = schema.object({ + id: schema.string(), +}); diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/delete/types/latest.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/delete/types/latest.ts new file mode 100644 index 0000000000000..26d0f97c9cfcc --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/delete/types/latest.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type { DeleteMaintenanceWindowRequestParams } from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/delete/types/v1.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/delete/types/v1.ts new file mode 100644 index 0000000000000..64c02f23b703c --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/delete/types/v1.ts @@ -0,0 +1,11 @@ +/* + * 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 type { TypeOf } from '@kbn/config-schema'; +import { deleteParamsSchemaV1 } from '..'; + +export type DeleteMaintenanceWindowRequestParams = TypeOf; diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/find/index.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/find/index.ts new file mode 100644 index 0000000000000..c3e30072e7348 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/find/index.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type { FindMaintenanceWindowsResponse } from './types/latest'; + +export type { FindMaintenanceWindowsResponse as FindMaintenanceWindowsResponseV1 } from './types/v1'; diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/find/types/latest.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/find/types/latest.ts new file mode 100644 index 0000000000000..4741df5c6c6c1 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/find/types/latest.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type { FindMaintenanceWindowsResponse } from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/find/types/v1.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/find/types/v1.ts new file mode 100644 index 0000000000000..0bdff90d3419f --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/find/types/v1.ts @@ -0,0 +1,15 @@ +/* + * 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 { MaintenanceWindowResponseV1 } from '../../../response'; + +export interface FindMaintenanceWindowsResponse { + body: { + data: MaintenanceWindowResponseV1[]; + total: number; + }; +} diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/finish/index.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/finish/index.ts new file mode 100644 index 0000000000000..034a95df34954 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/finish/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { finishParamsSchema } from './schemas/latest'; +export type { + FinishMaintenanceWindowRequestParams, + FinishMaintenanceWindowResponse, +} from './types/latest'; + +export { finishParamsSchema as finishParamsSchemaV1 } from './schemas/v1'; +export type { + FinishMaintenanceWindowRequestParams as FinishMaintenanceWindowRequestParamsV1, + FinishMaintenanceWindowResponse as FinishMaintenanceWindowResponseV1, +} from './types/latest'; diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/finish/schemas/latest.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/finish/schemas/latest.ts new file mode 100644 index 0000000000000..2033541a56287 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/finish/schemas/latest.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { finishParamsSchema } from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/finish/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/finish/schemas/v1.ts new file mode 100644 index 0000000000000..0c29cd6b2643a --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/finish/schemas/v1.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { schema } from '@kbn/config-schema'; + +export const finishParamsSchema = schema.object({ + id: schema.string(), +}); diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/finish/types/latest.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/finish/types/latest.ts new file mode 100644 index 0000000000000..b368726333754 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/finish/types/latest.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type { FinishMaintenanceWindowRequestParams, FinishMaintenanceWindowResponse } from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/finish/types/v1.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/finish/types/v1.ts new file mode 100644 index 0000000000000..aff9df5ba9c45 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/finish/types/v1.ts @@ -0,0 +1,16 @@ +/* + * 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 type { TypeOf } from '@kbn/config-schema'; +import { MaintenanceWindowResponseV1 } from '../../../response'; +import { finishParamsSchemaV1 } from '..'; + +export type FinishMaintenanceWindowRequestParams = TypeOf; + +export interface FinishMaintenanceWindowResponse { + body: MaintenanceWindowResponseV1; +} diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/get/index.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/get/index.ts new file mode 100644 index 0000000000000..d537b4a5cc6b4 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/get/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { getParamsSchema } from './schemas/latest'; +export type { + GetMaintenanceWindowRequestParams, + GetMaintenanceWindowResponse, +} from './types/latest'; + +export { getParamsSchema as getParamsSchemaV1 } from './schemas/v1'; +export type { + GetMaintenanceWindowRequestParams as GetMaintenanceWindowRequestParamsV1, + GetMaintenanceWindowResponse as GetMaintenanceWindowResponseV1, +} from './types/v1'; diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/get/schemas/latest.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/get/schemas/latest.ts new file mode 100644 index 0000000000000..46439e0d42301 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/get/schemas/latest.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { getParamsSchema } from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/get/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/get/schemas/v1.ts new file mode 100644 index 0000000000000..e20a50a4d80b0 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/get/schemas/v1.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { schema } from '@kbn/config-schema'; + +export const getParamsSchema = schema.object({ + id: schema.string(), +}); diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/get/types/latest.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/get/types/latest.ts new file mode 100644 index 0000000000000..327741ce963bf --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/get/types/latest.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type { GetMaintenanceWindowRequestParams, GetMaintenanceWindowResponse } from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/get/types/v1.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/get/types/v1.ts new file mode 100644 index 0000000000000..c264150229540 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/get/types/v1.ts @@ -0,0 +1,16 @@ +/* + * 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 type { TypeOf } from '@kbn/config-schema'; +import { MaintenanceWindowResponseV1 } from '../../../response'; +import { getParamsSchemaV1 } from '..'; + +export type GetMaintenanceWindowRequestParams = TypeOf; + +export interface GetMaintenanceWindowResponse { + body: MaintenanceWindowResponseV1; +} diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/get_active/index.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/get_active/index.ts new file mode 100644 index 0000000000000..9bedc681d2c4c --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/get_active/index.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type { GetActiveMaintenanceWindowsResponse } from './types/latest'; + +export type { GetActiveMaintenanceWindowsResponse as GetActiveMaintenanceWindowsResponseV1 } from './types/v1'; diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/get_active/types/latest.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/get_active/types/latest.ts new file mode 100644 index 0000000000000..cf7f23c05f794 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/get_active/types/latest.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type { GetActiveMaintenanceWindowsResponse } from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/get_active/types/v1.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/get_active/types/v1.ts new file mode 100644 index 0000000000000..3e6ed18dc18c2 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/get_active/types/v1.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { MaintenanceWindowResponseV1 } from '../../../response'; + +export interface GetActiveMaintenanceWindowsResponse { + body: MaintenanceWindowResponseV1[]; +} diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/update/index.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/update/index.ts new file mode 100644 index 0000000000000..df3d632736827 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/update/index.ts @@ -0,0 +1,23 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { updateParamsSchema, updateBodySchema } from './schemas/latest'; +export type { + UpdateMaintenanceWindowRequestParams, + UpdateMaintenanceWindowRequestBody, + UpdateMaintenanceWindowResponse, +} from './types/latest'; + +export { + updateParamsSchema as updateParamsSchemaV1, + updateBodySchema as updateBodySchemaV1, +} from './schemas/v1'; +export type { + UpdateMaintenanceWindowRequestParams as UpdateMaintenanceWindowRequestParamsV1, + UpdateMaintenanceWindowRequestBody as UpdateMaintenanceWindowRequestBodyV1, + UpdateMaintenanceWindowResponse as UpdateMaintenanceWindowResponseV1, +} from './types/v1'; diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/update/schemas/latest.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/update/schemas/latest.ts new file mode 100644 index 0000000000000..785163b7e1bc5 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/update/schemas/latest.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { updateParamsSchema, updateBodySchema } from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/update/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/update/schemas/v1.ts new file mode 100644 index 0000000000000..4322627c61e04 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/update/schemas/v1.ts @@ -0,0 +1,20 @@ +/* + * 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 { schema } from '@kbn/config-schema'; +import { rRuleRequestSchemaV1 } from '../../../../r_rule'; + +export const updateParamsSchema = schema.object({ + id: schema.string(), +}); + +export const updateBodySchema = schema.object({ + title: schema.maybe(schema.string()), + enabled: schema.maybe(schema.boolean()), + duration: schema.maybe(schema.number()), + r_rule: schema.maybe(rRuleRequestSchemaV1), +}); diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/update/types/latest.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/update/types/latest.ts new file mode 100644 index 0000000000000..0f42d4715be00 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/update/types/latest.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type { + UpdateMaintenanceWindowRequestParams, + UpdateMaintenanceWindowRequestBody, + UpdateMaintenanceWindowResponse, +} from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/update/types/v1.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/update/types/v1.ts new file mode 100644 index 0000000000000..d56107619687a --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/update/types/v1.ts @@ -0,0 +1,17 @@ +/* + * 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 type { TypeOf } from '@kbn/config-schema'; +import { MaintenanceWindowResponseV1 } from '../../../response'; +import { updateParamsSchemaV1, updateBodySchemaV1 } from '..'; + +export type UpdateMaintenanceWindowRequestParams = TypeOf; +export type UpdateMaintenanceWindowRequestBody = TypeOf; + +export interface UpdateMaintenanceWindowResponse { + body: MaintenanceWindowResponseV1; +} diff --git a/x-pack/plugins/alerting/common/routes/r_rule/schemas/latest.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/response/constants/latest.ts similarity index 100% rename from x-pack/plugins/alerting/common/routes/r_rule/schemas/latest.ts rename to x-pack/plugins/alerting/common/routes/maintenance_window/response/constants/latest.ts diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/response/constants/v1.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/response/constants/v1.ts new file mode 100644 index 0000000000000..faacb70c3cd56 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/response/constants/v1.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const maintenanceWindowStatus = { + RUNNING: 'running', + UPCOMING: 'upcoming', + FINISHED: 'finished', + ARCHIVED: 'archived', +} as const; + +export type MaintenanceWindowStatus = + typeof maintenanceWindowStatus[keyof typeof maintenanceWindowStatus]; diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/response/index.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/response/index.ts new file mode 100644 index 0000000000000..6701762f02f6c --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/response/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { maintenanceWindowResponseSchema } from './schemas/latest'; +export { maintenanceWindowStatus } from './constants/latest'; +export type { MaintenanceWindowStatus } from './constants/latest'; +export type { MaintenanceWindowResponse } from './types/latest'; + +export { maintenanceWindowResponseSchema as maintenanceWindowResponseSchemaV1 } from './schemas/v1'; +export { maintenanceWindowStatus as maintenanceWindowStatusV1 } from './constants/v1'; +export type { MaintenanceWindowStatus as MaintenanceWindowStatusV1 } from './constants/v1'; +export type { MaintenanceWindowResponse as MaintenanceWindowResponseV1 } from './types/v1'; diff --git a/x-pack/plugins/alerting/common/routes/r_rule/types/latest.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/response/schemas/latest.ts similarity index 100% rename from x-pack/plugins/alerting/common/routes/r_rule/types/latest.ts rename to x-pack/plugins/alerting/common/routes/maintenance_window/response/schemas/latest.ts diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/response/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/response/schemas/v1.ts new file mode 100644 index 0000000000000..5ddfdf502789f --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/response/schemas/v1.ts @@ -0,0 +1,37 @@ +/* + * 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 { schema } from '@kbn/config-schema'; +import { maintenanceWindowStatusV1 } from '..'; +import { rRuleResponseSchemaV1 } from '../../../r_rule'; + +export const maintenanceWindowEventSchema = schema.object({ + gte: schema.string(), + lte: schema.string(), +}); + +export const maintenanceWindowResponseSchema = schema.object({ + id: schema.string(), + title: schema.string(), + enabled: schema.boolean(), + duration: schema.number(), + expiration_date: schema.string(), + events: schema.arrayOf(maintenanceWindowEventSchema), + r_rule: rRuleResponseSchemaV1, + created_by: schema.nullable(schema.string()), + updated_by: schema.nullable(schema.string()), + created_at: schema.string(), + updated_at: schema.string(), + event_start_time: schema.nullable(schema.string()), + event_end_time: schema.nullable(schema.string()), + status: schema.oneOf([ + schema.literal(maintenanceWindowStatusV1.RUNNING), + schema.literal(maintenanceWindowStatusV1.UPCOMING), + schema.literal(maintenanceWindowStatusV1.FINISHED), + schema.literal(maintenanceWindowStatusV1.ARCHIVED), + ]), +}); diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/response/types/latest.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/response/types/latest.ts new file mode 100644 index 0000000000000..25300c97a6d2e --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/response/types/latest.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/response/types/v1.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/response/types/v1.ts new file mode 100644 index 0000000000000..91fdcbc16674b --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/response/types/v1.ts @@ -0,0 +1,11 @@ +/* + * 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 type { TypeOf } from '@kbn/config-schema'; +import { maintenanceWindowResponseSchemaV1 } from '..'; + +export type MaintenanceWindowResponse = TypeOf; diff --git a/x-pack/plugins/alerting/common/routes/r_rule/index.ts b/x-pack/plugins/alerting/common/routes/r_rule/index.ts index 43de19735a40c..6062cbd1fac59 100644 --- a/x-pack/plugins/alerting/common/routes/r_rule/index.ts +++ b/x-pack/plugins/alerting/common/routes/r_rule/index.ts @@ -5,8 +5,12 @@ * 2.0. */ -export { rRuleSchema } from './schemas/latest'; -export type { RRule } from './types/latest'; +export { rRuleRequestSchema } from './request/schemas/latest'; +export { rRuleResponseSchema } from './response/schemas/latest'; +export type { RRuleRequest } from './request/types/latest'; +export type { RRuleResponse } from './response/types/latest'; -export { rRuleSchema as rRuleSchemaV1 } from './schemas/v1'; -export type { RRule as RRuleV1 } from './types/latest'; +export { rRuleRequestSchema as rRuleRequestSchemaV1 } from './request/schemas/v1'; +export { rRuleResponseSchema as rRuleResponseSchemaV1 } from './response/schemas/v1'; +export type { RRuleRequest as RRuleRequestV1 } from './request/types/v1'; +export type { RRuleResponse as RRuleResponseV1 } from './response/types/v1'; diff --git a/x-pack/plugins/alerting/common/routes/r_rule/request/schemas/latest.ts b/x-pack/plugins/alerting/common/routes/r_rule/request/schemas/latest.ts new file mode 100644 index 0000000000000..25300c97a6d2e --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/r_rule/request/schemas/latest.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/r_rule/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/r_rule/request/schemas/v1.ts similarity index 94% rename from x-pack/plugins/alerting/common/routes/r_rule/schemas/v1.ts rename to x-pack/plugins/alerting/common/routes/r_rule/request/schemas/v1.ts index 5e10629e4f7ee..43528f7c0f722 100644 --- a/x-pack/plugins/alerting/common/routes/r_rule/schemas/v1.ts +++ b/x-pack/plugins/alerting/common/routes/r_rule/request/schemas/v1.ts @@ -10,9 +10,9 @@ import { validateStartDateV1, validateEndDateV1, createValidateRecurrenceByV1, -} from '../validation'; +} from '../../validation'; -export const rRuleSchema = schema.object({ +export const rRuleRequestSchema = schema.object({ dtstart: schema.string({ validate: validateStartDateV1 }), tzid: schema.string(), freq: schema.maybe( diff --git a/x-pack/plugins/alerting/common/routes/r_rule/request/types/latest.ts b/x-pack/plugins/alerting/common/routes/r_rule/request/types/latest.ts new file mode 100644 index 0000000000000..25300c97a6d2e --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/r_rule/request/types/latest.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/r_rule/types/v1.ts b/x-pack/plugins/alerting/common/routes/r_rule/request/types/v1.ts similarity index 73% rename from x-pack/plugins/alerting/common/routes/r_rule/types/v1.ts rename to x-pack/plugins/alerting/common/routes/r_rule/request/types/v1.ts index a8a2cf0f65e04..8a5605b6f9152 100644 --- a/x-pack/plugins/alerting/common/routes/r_rule/types/v1.ts +++ b/x-pack/plugins/alerting/common/routes/r_rule/request/types/v1.ts @@ -5,6 +5,6 @@ * 2.0. */ import type { TypeOf } from '@kbn/config-schema'; -import { rRuleSchemaV1 } from '..'; +import { rRuleRequestSchemaV1 } from '../..'; -export type RRule = TypeOf; +export type RRuleRequest = TypeOf; diff --git a/x-pack/plugins/alerting/common/routes/r_rule/response/schemas/latest.ts b/x-pack/plugins/alerting/common/routes/r_rule/response/schemas/latest.ts new file mode 100644 index 0000000000000..25300c97a6d2e --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/r_rule/response/schemas/latest.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/r_rule/response/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/r_rule/response/schemas/v1.ts new file mode 100644 index 0000000000000..0b32b61746ec9 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/r_rule/response/schemas/v1.ts @@ -0,0 +1,47 @@ +/* + * 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 { schema } from '@kbn/config-schema'; + +export const rRuleResponseSchema = schema.object({ + dtstart: schema.string(), + tzid: schema.string(), + freq: schema.maybe( + schema.oneOf([ + schema.literal(0), + schema.literal(1), + schema.literal(2), + schema.literal(3), + schema.literal(4), + schema.literal(5), + schema.literal(6), + ]) + ), + until: schema.maybe(schema.string()), + count: schema.maybe(schema.number()), + interval: schema.maybe(schema.number()), + wkst: schema.maybe( + schema.oneOf([ + schema.literal('MO'), + schema.literal('TU'), + schema.literal('WE'), + schema.literal('TH'), + schema.literal('FR'), + schema.literal('SA'), + schema.literal('SU'), + ]) + ), + byweekday: schema.maybe(schema.arrayOf(schema.oneOf([schema.string(), schema.number()]))), + bymonth: schema.maybe(schema.arrayOf(schema.number())), + bysetpos: schema.maybe(schema.arrayOf(schema.number())), + bymonthday: schema.arrayOf(schema.number()), + byyearday: schema.arrayOf(schema.number()), + byweekno: schema.arrayOf(schema.number()), + byhour: schema.arrayOf(schema.number()), + byminute: schema.arrayOf(schema.number()), + bysecond: schema.arrayOf(schema.number()), +}); diff --git a/x-pack/plugins/alerting/common/routes/r_rule/response/types/latest.ts b/x-pack/plugins/alerting/common/routes/r_rule/response/types/latest.ts new file mode 100644 index 0000000000000..25300c97a6d2e --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/r_rule/response/types/latest.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/r_rule/response/types/v1.ts b/x-pack/plugins/alerting/common/routes/r_rule/response/types/v1.ts new file mode 100644 index 0000000000000..1a35454a87655 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/r_rule/response/types/v1.ts @@ -0,0 +1,10 @@ +/* + * 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 type { TypeOf } from '@kbn/config-schema'; +import { rRuleResponseSchemaV1 } from '../..'; + +export type RRuleResponse = TypeOf; diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/schemas/v1.ts index adbebc679c218..54e70cde689ac 100644 --- a/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/schemas/v1.ts +++ b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/schemas/v1.ts @@ -8,7 +8,7 @@ import { schema } from '@kbn/config-schema'; import { validateDurationV1, validateNotifyWhenV1 } from '../../../validation'; import { validateSnoozeScheduleV1 } from '../validation'; -import { rRuleSchemaV1 } from '../../../../r_rule'; +import { rRuleRequestSchemaV1 } from '../../../../r_rule'; import { ruleNotifyWhenV1 } from '../../../response'; const notifyWhenSchema = schema.oneOf( @@ -25,14 +25,14 @@ export const scheduleIdsSchema = schema.maybe(schema.arrayOf(schema.string())); export const ruleSnoozeScheduleSchema = schema.object({ id: schema.maybe(schema.string()), duration: schema.number(), - rRule: rRuleSchemaV1, + rRule: rRuleRequestSchemaV1, }); const ruleSnoozeScheduleSchemaWithValidation = schema.object( { id: schema.maybe(schema.string()), duration: schema.number(), - rRule: rRuleSchemaV1, + rRule: rRuleRequestSchemaV1, }, { validate: validateSnoozeScheduleV1 } ); diff --git a/x-pack/plugins/alerting/common/routes/rule/response/index.ts b/x-pack/plugins/alerting/common/routes/rule/response/index.ts index 4be81ae30c79f..cdf693c7867eb 100644 --- a/x-pack/plugins/alerting/common/routes/rule/response/index.ts +++ b/x-pack/plugins/alerting/common/routes/rule/response/index.ts @@ -12,7 +12,6 @@ export { ruleExecutionStatusSchema, ruleLastRunSchema, monitoringSchema, - rRuleSchema, ruleResponseSchema, ruleSnoozeScheduleSchema, } from './schemas/latest'; @@ -48,7 +47,6 @@ export { ruleExecutionStatusSchema as ruleExecutionStatusSchemaV1, ruleLastRunSchema as ruleLastRunSchemaV1, monitoringSchema as monitoringSchemaV1, - rRuleSchema as rRuleSchemaV1, ruleResponseSchema as ruleResponseSchemaV1, ruleSnoozeScheduleSchema as ruleSnoozeScheduleSchemaV1, } from './schemas/v1'; diff --git a/x-pack/plugins/alerting/common/routes/rule/response/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/rule/response/schemas/v1.ts index 2fb82c3558cb7..1c093314f7a47 100644 --- a/x-pack/plugins/alerting/common/routes/rule/response/schemas/v1.ts +++ b/x-pack/plugins/alerting/common/routes/rule/response/schemas/v1.ts @@ -6,6 +6,7 @@ */ import { schema } from '@kbn/config-schema'; +import { rRuleResponseSchemaV1 } from '../../../r_rule'; import { ruleNotifyWhen as ruleNotifyWhenV1, ruleExecutionStatusValues as ruleExecutionStatusValuesV1, @@ -180,48 +181,9 @@ export const monitoringSchema = schema.object({ }), }); -export const rRuleSchema = schema.object({ - dtstart: schema.string(), - tzid: schema.string(), - freq: schema.maybe( - schema.oneOf([ - schema.literal(0), - schema.literal(1), - schema.literal(2), - schema.literal(3), - schema.literal(4), - schema.literal(5), - schema.literal(6), - ]) - ), - until: schema.maybe(schema.string()), - count: schema.maybe(schema.number()), - interval: schema.maybe(schema.number()), - wkst: schema.maybe( - schema.oneOf([ - schema.literal('MO'), - schema.literal('TU'), - schema.literal('WE'), - schema.literal('TH'), - schema.literal('FR'), - schema.literal('SA'), - schema.literal('SU'), - ]) - ), - byweekday: schema.maybe(schema.arrayOf(schema.oneOf([schema.string(), schema.number()]))), - bymonth: schema.maybe(schema.arrayOf(schema.number())), - bysetpos: schema.maybe(schema.arrayOf(schema.number())), - bymonthday: schema.arrayOf(schema.number()), - byyearday: schema.arrayOf(schema.number()), - byweekno: schema.arrayOf(schema.number()), - byhour: schema.arrayOf(schema.number()), - byminute: schema.arrayOf(schema.number()), - bysecond: schema.arrayOf(schema.number()), -}); - export const ruleSnoozeScheduleSchema = schema.object({ duration: schema.number(), - rRule: rRuleSchema, + rRule: rRuleResponseSchemaV1, id: schema.maybe(schema.string()), skipRecurrences: schema.maybe(schema.arrayOf(schema.string())), }); diff --git a/x-pack/plugins/alerting/server/alerts_client/alerts_client.ts b/x-pack/plugins/alerting/server/alerts_client/alerts_client.ts index 03500c8b94575..ae28dc818957f 100644 --- a/x-pack/plugins/alerting/server/alerts_client/alerts_client.ts +++ b/x-pack/plugins/alerting/server/alerts_client/alerts_client.ts @@ -369,7 +369,7 @@ export class AlertsClient< }) ); } else { - this.options.logger.warn( + this.options.logger.debug( `Could not find alert document to update for recovered alert with id ${id} and uuid ${recoveredAlerts[ id ].getUuid()}` diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/constants.ts b/x-pack/plugins/alerting/server/application/maintenance_window/constants.ts new file mode 100644 index 0000000000000..2844030ad79cc --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/constants.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const maintenanceWindowStatus = { + RUNNING: 'running', + UPCOMING: 'upcoming', + FINISHED: 'finished', + ARCHIVED: 'archived', +} as const; diff --git a/x-pack/plugins/alerting/server/maintenance_window_client/generate_maintenance_window_events.test.ts b/x-pack/plugins/alerting/server/application/maintenance_window/lib/generate_maintenance_window_events.test.ts similarity index 100% rename from x-pack/plugins/alerting/server/maintenance_window_client/generate_maintenance_window_events.test.ts rename to x-pack/plugins/alerting/server/application/maintenance_window/lib/generate_maintenance_window_events.test.ts diff --git a/x-pack/plugins/alerting/server/maintenance_window_client/generate_maintenance_window_events.ts b/x-pack/plugins/alerting/server/application/maintenance_window/lib/generate_maintenance_window_events.ts similarity index 99% rename from x-pack/plugins/alerting/server/maintenance_window_client/generate_maintenance_window_events.ts rename to x-pack/plugins/alerting/server/application/maintenance_window/lib/generate_maintenance_window_events.ts index 92ad3ad0fda4d..99f8e99f3f5e3 100644 --- a/x-pack/plugins/alerting/server/maintenance_window_client/generate_maintenance_window_events.ts +++ b/x-pack/plugins/alerting/server/application/maintenance_window/lib/generate_maintenance_window_events.ts @@ -8,7 +8,7 @@ import _ from 'lodash'; import moment from 'moment-timezone'; import { RRule, Weekday } from '@kbn/rrule'; -import { RRuleParams, MaintenanceWindowSOAttributes, DateRange } from '../../common'; +import { RRuleParams, MaintenanceWindowSOAttributes, DateRange } from '../../../../common'; export interface GenerateMaintenanceWindowEventsParams { rRule: RRuleParams; diff --git a/x-pack/plugins/alerting/server/maintenance_window_client/get_maintenance_window_date_and_status.test.ts b/x-pack/plugins/alerting/server/application/maintenance_window/lib/get_maintenance_window_date_and_status.test.ts similarity index 99% rename from x-pack/plugins/alerting/server/maintenance_window_client/get_maintenance_window_date_and_status.test.ts rename to x-pack/plugins/alerting/server/application/maintenance_window/lib/get_maintenance_window_date_and_status.test.ts index c0a61f7097f80..2ee4e2d8ea20b 100644 --- a/x-pack/plugins/alerting/server/maintenance_window_client/get_maintenance_window_date_and_status.test.ts +++ b/x-pack/plugins/alerting/server/application/maintenance_window/lib/get_maintenance_window_date_and_status.test.ts @@ -10,7 +10,7 @@ import { getMaintenanceWindowDateAndStatus, findRecentEventWithStatus, } from './get_maintenance_window_date_and_status'; -import { DateRange, MaintenanceWindowStatus } from '../../common'; +import { DateRange, MaintenanceWindowStatus } from '../../../../common'; const events: DateRange[] = [ { diff --git a/x-pack/plugins/alerting/server/maintenance_window_client/get_maintenance_window_date_and_status.ts b/x-pack/plugins/alerting/server/application/maintenance_window/lib/get_maintenance_window_date_and_status.ts similarity index 98% rename from x-pack/plugins/alerting/server/maintenance_window_client/get_maintenance_window_date_and_status.ts rename to x-pack/plugins/alerting/server/application/maintenance_window/lib/get_maintenance_window_date_and_status.ts index 4cd1e3322134b..877f6f2fe32eb 100644 --- a/x-pack/plugins/alerting/server/maintenance_window_client/get_maintenance_window_date_and_status.ts +++ b/x-pack/plugins/alerting/server/application/maintenance_window/lib/get_maintenance_window_date_and_status.ts @@ -5,7 +5,7 @@ * 2.0. */ import moment from 'moment'; -import { DateRange, MaintenanceWindowStatus } from '../../common'; +import { DateRange, MaintenanceWindowStatus } from '../../../../common'; export interface DateSearchResult { event: DateRange; diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/lib/index.ts b/x-pack/plugins/alerting/server/application/maintenance_window/lib/index.ts new file mode 100644 index 0000000000000..473de1f777d88 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/lib/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { + generateMaintenanceWindowEvents, + shouldRegenerateEvents, + mergeEvents, +} from './generate_maintenance_window_events'; + +export { + getMaintenanceWindowDateAndStatus, + findRecentEventWithStatus, +} from './get_maintenance_window_date_and_status'; diff --git a/x-pack/plugins/alerting/server/maintenance_window_client/methods/archive.test.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/archive/archive_maintenance_window.test.ts similarity index 91% rename from x-pack/plugins/alerting/server/maintenance_window_client/methods/archive.test.ts rename to x-pack/plugins/alerting/server/application/maintenance_window/methods/archive/archive_maintenance_window.test.ts index c3da9c5948206..0a4f25d87fbbf 100644 --- a/x-pack/plugins/alerting/server/maintenance_window_client/methods/archive.test.ts +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/archive/archive_maintenance_window.test.ts @@ -7,14 +7,15 @@ import moment from 'moment-timezone'; import { Frequency } from '@kbn/rrule'; -import { archive } from './archive'; +import { archiveMaintenanceWindow } from './archive_maintenance_window'; import { savedObjectsClientMock, loggingSystemMock } from '@kbn/core/server/mocks'; import { SavedObjectsUpdateResponse, SavedObject } from '@kbn/core/server'; import { MaintenanceWindowClientContext, MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, -} from '../../../common'; -import { getMockMaintenanceWindow } from './test_helpers'; +} from '../../../../../common'; +import { getMockMaintenanceWindow } from '../../../../data/maintenance_window/test_helpers'; +import type { MaintenanceWindow } from '../../types'; const savedObjectsClient = savedObjectsClientMock.create(); @@ -68,7 +69,7 @@ describe('MaintenanceWindowClient - archive', () => { // Move to some time in the future jest.useFakeTimers().setSystemTime(new Date(secondTimestamp)); - await archive(mockContext, { id: 'test-id', archive: true }); + await archiveMaintenanceWindow(mockContext, { id: 'test-id', archive: true }); expect(savedObjectsClient.get).toHaveBeenLastCalledWith( MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, @@ -116,7 +117,7 @@ describe('MaintenanceWindowClient - archive', () => { // Move to some time in the future jest.useFakeTimers().setSystemTime(new Date(secondTimestamp)); - await archive(mockContext, { id: 'test-id', archive: false }); + await archiveMaintenanceWindow(mockContext, { id: 'test-id', archive: false }); expect(savedObjectsClient.get).toHaveBeenLastCalledWith( MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, @@ -155,7 +156,7 @@ describe('MaintenanceWindowClient - archive', () => { dtstart: '2023-03-26T00:00:00.000Z', freq: Frequency.WEEKLY, count: 5, - }, + } as MaintenanceWindow['rRule'], events: modifiedEvents, expirationDate: moment(new Date(firstTimestamp)).tz('UTC').add(2, 'week').toISOString(), }); @@ -175,7 +176,7 @@ describe('MaintenanceWindowClient - archive', () => { } as unknown as SavedObjectsUpdateResponse); jest.useFakeTimers().setSystemTime(new Date('2023-04-16T00:00:00.000Z')); - await archive(mockContext, { id: 'test-id', archive: true }); + await archiveMaintenanceWindow(mockContext, { id: 'test-id', archive: true }); expect(savedObjectsClient.update).toHaveBeenLastCalledWith( MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, diff --git a/x-pack/plugins/alerting/server/maintenance_window_client/methods/archive.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/archive/archive_maintenance_window.ts similarity index 57% rename from x-pack/plugins/alerting/server/maintenance_window_client/methods/archive.ts rename to x-pack/plugins/alerting/server/application/maintenance_window/methods/archive/archive_maintenance_window.ts index 948f3c0e3e06e..461f88288ced3 100644 --- a/x-pack/plugins/alerting/server/maintenance_window_client/methods/archive.ts +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/archive/archive_maintenance_window.ts @@ -7,23 +7,23 @@ import moment from 'moment'; import Boom from '@hapi/boom'; +import type { MaintenanceWindowClientContext } from '../../../../../common'; +import type { MaintenanceWindow } from '../../types'; +import type { ArchiveMaintenanceWindowParams } from './types'; +import { archiveMaintenanceWindowParamsSchema } from './schemas'; import { generateMaintenanceWindowEvents, mergeEvents, -} from '../generate_maintenance_window_events'; -import { getMaintenanceWindowFromRaw } from '../get_maintenance_window_from_raw'; +} from '../../lib/generate_maintenance_window_events'; +import { retryIfConflicts } from '../../../../lib/retry_if_conflicts'; import { - MaintenanceWindowSOAttributes, - MaintenanceWindow, - MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, - MaintenanceWindowClientContext, -} from '../../../common'; -import { retryIfConflicts } from '../../lib/retry_if_conflicts'; - -export interface ArchiveParams { - id: string; - archive: boolean; -} + transformMaintenanceWindowAttributesToMaintenanceWindow, + transformMaintenanceWindowToMaintenanceWindowAttributes, +} from '../../transforms'; +import { + getMaintenanceWindowSo, + updateMaintenanceWindowSo, +} from '../../../../data/maintenance_window'; const getArchivedExpirationDate = (shouldArchive: boolean) => { if (shouldArchive) { @@ -32,9 +32,9 @@ const getArchivedExpirationDate = (shouldArchive: boolean) => { return moment.utc().add(1, 'year').toISOString(); }; -export async function archive( +export async function archiveMaintenanceWindow( context: MaintenanceWindowClientContext, - params: ArchiveParams + params: ArchiveMaintenanceWindowParams ): Promise { return await retryIfConflicts( context.logger, @@ -47,8 +47,14 @@ export async function archive( async function archiveWithOCC( context: MaintenanceWindowClientContext, - params: ArchiveParams + params: ArchiveMaintenanceWindowParams ): Promise { + try { + archiveMaintenanceWindowParamsSchema.validate(params); + } catch (error) { + throw Boom.badRequest(`Error validating archive params - ${error.message}`); + } + const { savedObjectsClient, getModificationMetadata, logger } = context; const { id, archive: shouldArchive } = params; @@ -56,10 +62,10 @@ async function archiveWithOCC( const expirationDate = getArchivedExpirationDate(shouldArchive); try { - const { attributes, version } = await savedObjectsClient.get( - MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, - id - ); + const { attributes, version } = await getMaintenanceWindowSo({ + id, + savedObjectsClient, + }); const events = mergeEvents({ newEvents: generateMaintenanceWindowEvents({ @@ -70,27 +76,30 @@ async function archiveWithOCC( oldEvents: attributes.events, }); - const result = await savedObjectsClient.update( - MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, - id, - { + const updatedMaintenanceWindowAttributes = + transformMaintenanceWindowToMaintenanceWindowAttributes({ ...attributes, events, expirationDate, updatedAt: modificationMetadata.updatedAt, updatedBy: modificationMetadata.updatedBy, - }, - { + }); + + const result = await updateMaintenanceWindowSo({ + id, + savedObjectsClient, + updateMaintenanceWindowAttributes: updatedMaintenanceWindowAttributes, + savedObjectsUpdateOptions: { version, - } - ); + }, + }); - return getMaintenanceWindowFromRaw({ + return transformMaintenanceWindowAttributesToMaintenanceWindow({ attributes: { ...attributes, ...result.attributes, }, - id, + id: result.id, }); } catch (e) { const errorMessage = `Failed to archive maintenance window by id: ${id}, Error: ${e}`; diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/archive/schemas/archive_maintenance_window_params_schema.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/archive/schemas/archive_maintenance_window_params_schema.ts new file mode 100644 index 0000000000000..6dd806c856f27 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/archive/schemas/archive_maintenance_window_params_schema.ts @@ -0,0 +1,13 @@ +/* + * 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 { schema } from '@kbn/config-schema'; + +export const archiveMaintenanceWindowParamsSchema = schema.object({ + id: schema.string(), + archive: schema.boolean(), +}); diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/archive/schemas/index.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/archive/schemas/index.ts new file mode 100644 index 0000000000000..1e85f6049a4ef --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/archive/schemas/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { archiveMaintenanceWindowParamsSchema } from './archive_maintenance_window_params_schema'; diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/archive/types/archive_maintenance_window_params.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/archive/types/archive_maintenance_window_params.ts new file mode 100644 index 0000000000000..81ad31de9c6a9 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/archive/types/archive_maintenance_window_params.ts @@ -0,0 +1,11 @@ +/* + * 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 type { TypeOf } from '@kbn/config-schema'; +import { archiveMaintenanceWindowParamsSchema } from '../schemas'; + +export type ArchiveMaintenanceWindowParams = TypeOf; diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/archive/types/index.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/archive/types/index.ts new file mode 100644 index 0000000000000..388f69056d9e2 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/archive/types/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type { ArchiveMaintenanceWindowParams } from './archive_maintenance_window_params'; diff --git a/x-pack/plugins/alerting/server/maintenance_window_client/methods/bulk_get.test.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/bulk_get/bulk_get_maintenance_windows.test.ts similarity index 87% rename from x-pack/plugins/alerting/server/maintenance_window_client/methods/bulk_get.test.ts rename to x-pack/plugins/alerting/server/application/maintenance_window/methods/bulk_get/bulk_get_maintenance_windows.test.ts index c0d12169ac909..488eb14f7df27 100644 --- a/x-pack/plugins/alerting/server/maintenance_window_client/methods/bulk_get.test.ts +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/bulk_get/bulk_get_maintenance_windows.test.ts @@ -5,14 +5,14 @@ * 2.0. */ -import { bulkGet } from './bulk_get'; +import { bulkGetMaintenanceWindows } from './bulk_get_maintenance_windows'; import { savedObjectsClientMock, loggingSystemMock } from '@kbn/core/server/mocks'; import { SavedObject } from '@kbn/core/server'; import { MaintenanceWindowClientContext, MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, -} from '../../../common'; -import { getMockMaintenanceWindow } from './test_helpers'; +} from '../../../../../common'; +import { getMockMaintenanceWindow } from '../../../../data/maintenance_window/test_helpers'; const savedObjectsClient = savedObjectsClientMock.create(); @@ -55,7 +55,7 @@ describe('MaintenanceWindowClient - get', () => { ], }); - const result = await bulkGet(mockContext, { ids: ['id-1', 'id-2'] }); + const result = await bulkGetMaintenanceWindows(mockContext, { ids: ['id-1', 'id-2'] }); expect(savedObjectsClient.bulkGet).toHaveBeenLastCalledWith([ { diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/bulk_get/bulk_get_maintenance_windows.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/bulk_get/bulk_get_maintenance_windows.ts new file mode 100644 index 0000000000000..ed9d403f3fa5c --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/bulk_get/bulk_get_maintenance_windows.ts @@ -0,0 +1,71 @@ +/* + * 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 Boom from '@hapi/boom'; +import type { + BulkGetMaintenanceWindowsParams, + BulkGetMaintenanceWindowsError, + BulkGetMaintenanceWindowsResult, +} from './types'; +import type { MaintenanceWindow } from '../../types'; +import { bulkGetMaintenanceWindowsParamsSchema } from './schemas'; +import type { MaintenanceWindowClientContext } from '../../../../../common'; +import { transformMaintenanceWindowAttributesToMaintenanceWindow } from '../../transforms'; +import { bulkGetMaintenanceWindowSo } from '../../../../data/maintenance_window'; + +export async function bulkGetMaintenanceWindows( + context: MaintenanceWindowClientContext, + params: BulkGetMaintenanceWindowsParams +): Promise { + const { savedObjectsClient, logger } = context; + const { ids } = params; + + try { + bulkGetMaintenanceWindowsParamsSchema.validate(params); + } catch (error) { + throw Boom.badRequest(`Error validating bulk get maintenance window data - ${error.message}`); + } + + const bulkGetObjects = ids.map((id) => ({ id })); + + try { + const { saved_objects: savedObjects } = await bulkGetMaintenanceWindowSo({ + objects: bulkGetObjects, + savedObjectsClient, + }); + + const maintenanceWindows: MaintenanceWindow[] = []; + const errors: BulkGetMaintenanceWindowsError[] = []; + + savedObjects.forEach((so) => { + if (so.error) { + errors.push({ + id: so.id, + error: so.error.error, + message: so.error.message, + statusCode: so.error.statusCode, + }); + } else { + maintenanceWindows.push( + transformMaintenanceWindowAttributesToMaintenanceWindow({ + id: so.id, + attributes: so.attributes, + }) + ); + } + }); + + return { + maintenanceWindows, + errors, + }; + } catch (e) { + const errorMessage = `Failed to bulk get maintenance window for ids: ${ids}, Error: ${e}`; + logger.error(errorMessage); + throw Boom.boomify(e, { message: errorMessage }); + } +} diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/bulk_get/schemas/bulk_get_maintenance_windows_params_schema.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/bulk_get/schemas/bulk_get_maintenance_windows_params_schema.ts new file mode 100644 index 0000000000000..80e7cb776c911 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/bulk_get/schemas/bulk_get_maintenance_windows_params_schema.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { schema } from '@kbn/config-schema'; + +export const bulkGetMaintenanceWindowsParamsSchema = schema.object({ + ids: schema.arrayOf(schema.string()), +}); diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/bulk_get/schemas/bulk_get_maintenance_windows_result_schema.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/bulk_get/schemas/bulk_get_maintenance_windows_result_schema.ts new file mode 100644 index 0000000000000..214c9553a2e5d --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/bulk_get/schemas/bulk_get_maintenance_windows_result_schema.ts @@ -0,0 +1,21 @@ +/* + * 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 { schema } from '@kbn/config-schema'; +import { maintenanceWindowSchema } from '../../../schemas'; + +export const bulkGetMaintenanceWindowsErrorSchema = schema.object({ + id: schema.string(), + error: schema.string(), + message: schema.string(), + statusCode: schema.number(), +}); + +export const bulkGetMaintenanceWindowsResultSchema = schema.object({ + maintenanceWindows: schema.arrayOf(maintenanceWindowSchema), + errors: schema.arrayOf(bulkGetMaintenanceWindowsErrorSchema), +}); diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/bulk_get/schemas/index.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/bulk_get/schemas/index.ts new file mode 100644 index 0000000000000..f59497cf06d9e --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/bulk_get/schemas/index.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { + bulkGetMaintenanceWindowsErrorSchema, + bulkGetMaintenanceWindowsResultSchema, +} from './bulk_get_maintenance_windows_result_schema'; + +export { bulkGetMaintenanceWindowsParamsSchema } from './bulk_get_maintenance_windows_params_schema'; diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/bulk_get/types/bulk_get_maintenance_window_params.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/bulk_get/types/bulk_get_maintenance_window_params.ts new file mode 100644 index 0000000000000..7b0a155880926 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/bulk_get/types/bulk_get_maintenance_window_params.ts @@ -0,0 +1,11 @@ +/* + * 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 { TypeOf } from '@kbn/config-schema'; +import { bulkGetMaintenanceWindowsParamsSchema } from '../schemas'; + +export type BulkGetMaintenanceWindowsParams = TypeOf; diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/bulk_get/types/bulk_get_maintenance_window_result.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/bulk_get/types/bulk_get_maintenance_window_result.ts new file mode 100644 index 0000000000000..7f640342bf651 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/bulk_get/types/bulk_get_maintenance_window_result.ts @@ -0,0 +1,15 @@ +/* + * 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 { TypeOf } from '@kbn/config-schema'; +import { + bulkGetMaintenanceWindowsErrorSchema, + bulkGetMaintenanceWindowsResultSchema, +} from '../schemas'; + +export type BulkGetMaintenanceWindowsError = TypeOf; +export type BulkGetMaintenanceWindowsResult = TypeOf; diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/bulk_get/types/index.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/bulk_get/types/index.ts new file mode 100644 index 0000000000000..ecd869b8f1064 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/bulk_get/types/index.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type { + BulkGetMaintenanceWindowsError, + BulkGetMaintenanceWindowsResult, +} from './bulk_get_maintenance_window_result'; + +export type { BulkGetMaintenanceWindowsParams } from './bulk_get_maintenance_window_params'; diff --git a/x-pack/plugins/alerting/server/maintenance_window_client/methods/create.test.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/create/create_maintenance_window.test.ts similarity index 81% rename from x-pack/plugins/alerting/server/maintenance_window_client/methods/create.test.ts rename to x-pack/plugins/alerting/server/application/maintenance_window/methods/create/create_maintenance_window.test.ts index 656a090788079..452c3fe5c999c 100644 --- a/x-pack/plugins/alerting/server/maintenance_window_client/methods/create.test.ts +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/create/create_maintenance_window.test.ts @@ -6,14 +6,15 @@ */ import moment from 'moment-timezone'; -import { create } from './create'; +import { createMaintenanceWindow } from './create_maintenance_window'; +import { CreateMaintenanceWindowParams } from './types'; import { savedObjectsClientMock, loggingSystemMock } from '@kbn/core/server/mocks'; import { SavedObject } from '@kbn/core/server'; import { MaintenanceWindowClientContext, MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, -} from '../../../common'; -import { getMockMaintenanceWindow } from './test_helpers'; +} from '../../../../../common'; +import { getMockMaintenanceWindow } from '../../../../data/maintenance_window/test_helpers'; const savedObjectsClient = savedObjectsClientMock.create(); @@ -56,10 +57,12 @@ describe('MaintenanceWindowClient - create', () => { id: 'test-id', } as unknown as SavedObject); - const result = await create(mockContext, { - title: mockMaintenanceWindow.title, - duration: mockMaintenanceWindow.duration, - rRule: mockMaintenanceWindow.rRule, + const result = await createMaintenanceWindow(mockContext, { + data: { + title: mockMaintenanceWindow.title, + duration: mockMaintenanceWindow.duration, + rRule: mockMaintenanceWindow.rRule as CreateMaintenanceWindowParams['data']['rRule'], + }, }); expect(savedObjectsClient.create).toHaveBeenLastCalledWith( diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/create/create_maintenance_window.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/create/create_maintenance_window.ts new file mode 100644 index 0000000000000..4f02b9038197f --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/create/create_maintenance_window.ts @@ -0,0 +1,69 @@ +/* + * 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 moment from 'moment'; +import Boom from '@hapi/boom'; +import { SavedObjectsUtils } from '@kbn/core/server'; +import { generateMaintenanceWindowEvents } from '../../lib/generate_maintenance_window_events'; +import type { MaintenanceWindowClientContext } from '../../../../../common'; +import type { MaintenanceWindow } from '../../types'; +import type { CreateMaintenanceWindowParams } from './types'; +import { + transformMaintenanceWindowAttributesToMaintenanceWindow, + transformMaintenanceWindowToMaintenanceWindowAttributes, +} from '../../transforms'; +import { createMaintenanceWindowSo } from '../../../../data/maintenance_window'; +import { createMaintenanceWindowParamsSchema } from './schemas'; + +export async function createMaintenanceWindow( + context: MaintenanceWindowClientContext, + params: CreateMaintenanceWindowParams +): Promise { + const { data } = params; + const { savedObjectsClient, getModificationMetadata, logger } = context; + const { title, duration, rRule } = data; + + try { + createMaintenanceWindowParamsSchema.validate(params); + } catch (error) { + throw Boom.badRequest(`Error validating create maintenance window data - ${error.message}`); + } + + const id = SavedObjectsUtils.generateId(); + const expirationDate = moment().utc().add(1, 'year').toISOString(); + const modificationMetadata = await getModificationMetadata(); + + const events = generateMaintenanceWindowEvents({ rRule, expirationDate, duration }); + const maintenanceWindowAttributes = transformMaintenanceWindowToMaintenanceWindowAttributes({ + title, + enabled: true, + expirationDate, + rRule: rRule as MaintenanceWindow['rRule'], + duration, + events, + ...modificationMetadata, + }); + + try { + const result = await createMaintenanceWindowSo({ + savedObjectsClient, + maintenanceWindowAttributes, + savedObjectsCreateOptions: { + id, + }, + }); + + return transformMaintenanceWindowAttributesToMaintenanceWindow({ + attributes: result.attributes, + id: result.id, + }); + } catch (e) { + const errorMessage = `Failed to create maintenance window, Error: ${e}`; + logger.error(errorMessage); + throw Boom.boomify(e, { message: errorMessage }); + } +} diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/create/schemas/create_maintenance_window_params_schema.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/create/schemas/create_maintenance_window_params_schema.ts new file mode 100644 index 0000000000000..306b9bd8c259a --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/create/schemas/create_maintenance_window_params_schema.ts @@ -0,0 +1,17 @@ +/* + * 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 { schema } from '@kbn/config-schema'; +import { rRuleRequestSchema } from '../../../../r_rule/schemas'; + +export const createMaintenanceWindowParamsSchema = schema.object({ + data: schema.object({ + title: schema.string(), + duration: schema.number(), + rRule: rRuleRequestSchema, + }), +}); diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/create/schemas/index.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/create/schemas/index.ts new file mode 100644 index 0000000000000..0cea0dce3efe2 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/create/schemas/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { createMaintenanceWindowParamsSchema } from './create_maintenance_window_params_schema'; diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/create/types/create_maintenance_window_params.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/create/types/create_maintenance_window_params.ts new file mode 100644 index 0000000000000..66f9070f24277 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/create/types/create_maintenance_window_params.ts @@ -0,0 +1,11 @@ +/* + * 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 { TypeOf } from '@kbn/config-schema'; +import { createMaintenanceWindowParamsSchema } from '../schemas'; + +export type CreateMaintenanceWindowParams = TypeOf; diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/create/types/index.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/create/types/index.ts new file mode 100644 index 0000000000000..2f43ca0850e89 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/create/types/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type { CreateMaintenanceWindowParams } from './create_maintenance_window_params'; diff --git a/x-pack/plugins/alerting/server/maintenance_window_client/methods/delete.test.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/delete/delete_maintenance_window.test.ts similarity index 92% rename from x-pack/plugins/alerting/server/maintenance_window_client/methods/delete.test.ts rename to x-pack/plugins/alerting/server/application/maintenance_window/methods/delete/delete_maintenance_window.test.ts index 866382eee81bc..0fd75c49f91d5 100644 --- a/x-pack/plugins/alerting/server/maintenance_window_client/methods/delete.test.ts +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/delete/delete_maintenance_window.test.ts @@ -5,12 +5,12 @@ * 2.0. */ -import { deleteMaintenanceWindow } from './delete'; +import { deleteMaintenanceWindow } from './delete_maintenance_window'; import { savedObjectsClientMock, loggingSystemMock } from '@kbn/core/server/mocks'; import { MaintenanceWindowClientContext, MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, -} from '../../../common'; +} from '../../../../../common'; const savedObjectsClient = savedObjectsClientMock.create(); @@ -36,7 +36,8 @@ describe('MaintenanceWindowClient - delete', () => { expect(savedObjectsClient.delete).toHaveBeenLastCalledWith( MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, - 'test-id' + 'test-id', + undefined ); expect(result).toEqual({}); diff --git a/x-pack/plugins/alerting/server/maintenance_window_client/methods/delete.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/delete/delete_maintenance_window.ts similarity index 57% rename from x-pack/plugins/alerting/server/maintenance_window_client/methods/delete.ts rename to x-pack/plugins/alerting/server/application/maintenance_window/methods/delete/delete_maintenance_window.ts index 8b72742cc94b6..44bcdd9f55049 100644 --- a/x-pack/plugins/alerting/server/maintenance_window_client/methods/delete.ts +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/delete/delete_maintenance_window.ts @@ -6,19 +6,15 @@ */ import Boom from '@hapi/boom'; -import { - MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, - MaintenanceWindowClientContext, -} from '../../../common'; -import { retryIfConflicts } from '../../lib/retry_if_conflicts'; - -export interface DeleteParams { - id: string; -} +import type { MaintenanceWindowClientContext } from '../../../../../common'; +import type { DeleteMaintenanceWindowParams } from './types'; +import { deleteMaintenanceWindowParamsSchema } from './schemas'; +import { retryIfConflicts } from '../../../../lib/retry_if_conflicts'; +import { deleteMaintenanceWindowSo } from '../../../../data/maintenance_window'; export async function deleteMaintenanceWindow( context: MaintenanceWindowClientContext, - params: DeleteParams + params: DeleteMaintenanceWindowParams ): Promise<{}> { return await retryIfConflicts( context.logger, @@ -29,12 +25,19 @@ export async function deleteMaintenanceWindow( async function deleteWithOCC( context: MaintenanceWindowClientContext, - params: DeleteParams + params: DeleteMaintenanceWindowParams ): Promise<{}> { const { savedObjectsClient, logger } = context; const { id } = params; + + try { + deleteMaintenanceWindowParamsSchema.validate(params); + } catch (error) { + throw Boom.badRequest(`Error validating delete maintenance window data - ${error.message}`); + } + try { - return await savedObjectsClient.delete(MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, id); + return await deleteMaintenanceWindowSo({ id, savedObjectsClient }); } catch (e) { const errorMessage = `Failed to delete maintenance window by id: ${id}, Error: ${e}`; logger.error(errorMessage); diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/delete/schemas/delete_maintenance_window_params_schema.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/delete/schemas/delete_maintenance_window_params_schema.ts new file mode 100644 index 0000000000000..189494a30c826 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/delete/schemas/delete_maintenance_window_params_schema.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { schema } from '@kbn/config-schema'; + +export const deleteMaintenanceWindowParamsSchema = schema.object({ + id: schema.string(), +}); diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/delete/schemas/index.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/delete/schemas/index.ts new file mode 100644 index 0000000000000..9310193b7c6d0 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/delete/schemas/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { deleteMaintenanceWindowParamsSchema } from './delete_maintenance_window_params_schema'; diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/delete/types/delete_maintenance_window_params.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/delete/types/delete_maintenance_window_params.ts new file mode 100644 index 0000000000000..e241528ec2011 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/delete/types/delete_maintenance_window_params.ts @@ -0,0 +1,11 @@ +/* + * 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 { TypeOf } from '@kbn/config-schema'; +import { deleteMaintenanceWindowParamsSchema } from '../schemas'; + +export type DeleteMaintenanceWindowParams = TypeOf; diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/delete/types/index.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/delete/types/index.ts new file mode 100644 index 0000000000000..67afa872c9387 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/delete/types/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type { DeleteMaintenanceWindowParams } from './delete_maintenance_window_params'; diff --git a/x-pack/plugins/alerting/server/maintenance_window_client/methods/find.test.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/find/find_maintenance_windows.test.ts similarity index 86% rename from x-pack/plugins/alerting/server/maintenance_window_client/methods/find.test.ts rename to x-pack/plugins/alerting/server/application/maintenance_window/methods/find/find_maintenance_windows.test.ts index f29e6576e6f78..8645012406e2c 100644 --- a/x-pack/plugins/alerting/server/maintenance_window_client/methods/find.test.ts +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/find/find_maintenance_windows.test.ts @@ -5,14 +5,14 @@ * 2.0. */ -import { find } from './find'; +import { findMaintenanceWindows } from './find_maintenance_windows'; import { savedObjectsClientMock, loggingSystemMock } from '@kbn/core/server/mocks'; import { SavedObjectsFindResponse } from '@kbn/core/server'; import { MaintenanceWindowClientContext, MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, -} from '../../../common'; -import { getMockMaintenanceWindow } from './test_helpers'; +} from '../../../../../common'; +import { getMockMaintenanceWindow } from '../../../../data/maintenance_window/test_helpers'; const savedObjectsClient = savedObjectsClientMock.create(); @@ -47,7 +47,7 @@ describe('MaintenanceWindowClient - find', () => { ], } as unknown as SavedObjectsFindResponse); - const result = await find(mockContext); + const result = await findMaintenanceWindows(mockContext); expect(savedObjectsClient.find).toHaveBeenLastCalledWith({ type: MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, diff --git a/x-pack/plugins/alerting/server/maintenance_window_client/methods/find.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/find/find_maintenance_windows.ts similarity index 53% rename from x-pack/plugins/alerting/server/maintenance_window_client/methods/find.ts rename to x-pack/plugins/alerting/server/application/maintenance_window/methods/find/find_maintenance_windows.ts index f28761b4a2b66..fe0f279ea4073 100644 --- a/x-pack/plugins/alerting/server/maintenance_window_client/methods/find.ts +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/find/find_maintenance_windows.ts @@ -6,29 +6,22 @@ */ import Boom from '@hapi/boom'; -import { getMaintenanceWindowFromRaw } from '../get_maintenance_window_from_raw'; -import { - MaintenanceWindowSOAttributes, - MaintenanceWindow, - MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, - MaintenanceWindowClientContext, -} from '../../../common'; +import { MaintenanceWindowClientContext } from '../../../../../common'; +import { transformMaintenanceWindowAttributesToMaintenanceWindow } from '../../transforms'; +import { findMaintenanceWindowSo } from '../../../../data/maintenance_window'; +import type { FindMaintenanceWindowsResult } from './types'; -export interface FindResult { - data: MaintenanceWindow[]; -} - -export async function find(context: MaintenanceWindowClientContext): Promise { +export async function findMaintenanceWindows( + context: MaintenanceWindowClientContext +): Promise { const { savedObjectsClient, logger } = context; try { - const result = await savedObjectsClient.find({ - type: MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, - }); + const result = await findMaintenanceWindowSo({ savedObjectsClient }); return { data: result.saved_objects.map((so) => - getMaintenanceWindowFromRaw({ + transformMaintenanceWindowAttributesToMaintenanceWindow({ attributes: so.attributes, id: so.id, }) diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/find/schemas/find_maintenance_windows_result_schema.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/find/schemas/find_maintenance_windows_result_schema.ts new file mode 100644 index 0000000000000..1bdc2f00219ae --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/find/schemas/find_maintenance_windows_result_schema.ts @@ -0,0 +1,13 @@ +/* + * 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 { schema } from '@kbn/config-schema'; +import { maintenanceWindowSchema } from '../../../schemas'; + +export const findMaintenanceWindowsResultSchema = schema.object({ + data: schema.arrayOf(maintenanceWindowSchema), +}); diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/find/schemas/index.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/find/schemas/index.ts new file mode 100644 index 0000000000000..4b2f087c95505 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/find/schemas/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { findMaintenanceWindowsResultSchema } from './find_maintenance_windows_result_schema'; diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/find/types/find_maintenance_window_result.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/find/types/find_maintenance_window_result.ts new file mode 100644 index 0000000000000..6a16366cd8f29 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/find/types/find_maintenance_window_result.ts @@ -0,0 +1,11 @@ +/* + * 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 { TypeOf } from '@kbn/config-schema'; +import { findMaintenanceWindowsResultSchema } from '../schemas'; + +export type FindMaintenanceWindowsResult = TypeOf; diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/find/types/index.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/find/types/index.ts new file mode 100644 index 0000000000000..a5f00973bb82e --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/find/types/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type { FindMaintenanceWindowsResult } from './find_maintenance_window_result'; diff --git a/x-pack/plugins/alerting/server/maintenance_window_client/methods/finish.test.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/finish/finish_maintenance_window.test.ts similarity index 90% rename from x-pack/plugins/alerting/server/maintenance_window_client/methods/finish.test.ts rename to x-pack/plugins/alerting/server/application/maintenance_window/methods/finish/finish_maintenance_window.test.ts index 8a37f228892b6..0d32342355706 100644 --- a/x-pack/plugins/alerting/server/maintenance_window_client/methods/finish.test.ts +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/finish/finish_maintenance_window.test.ts @@ -7,14 +7,15 @@ import moment from 'moment-timezone'; import { Frequency } from '@kbn/rrule'; -import { finish } from './finish'; +import { finishMaintenanceWindow } from './finish_maintenance_window'; import { savedObjectsClientMock, loggingSystemMock } from '@kbn/core/server/mocks'; import { SavedObjectsUpdateResponse, SavedObject } from '@kbn/core/server'; import { MaintenanceWindowClientContext, MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, -} from '../../../common'; -import { getMockMaintenanceWindow } from './test_helpers'; +} from '../../../../../common'; +import { getMockMaintenanceWindow } from '../../../../data/maintenance_window/test_helpers'; +import type { MaintenanceWindow } from '../../types'; const savedObjectsClient = savedObjectsClientMock.create(); @@ -56,7 +57,7 @@ describe('MaintenanceWindowClient - finish', () => { dtstart: moment().utc().toISOString(), freq: Frequency.WEEKLY, count: 2, - }, + } as MaintenanceWindow['rRule'], }); savedObjectsClient.get.mockResolvedValueOnce({ @@ -80,7 +81,7 @@ describe('MaintenanceWindowClient - finish', () => { // Move 30 mins into the future jest.useFakeTimers().setSystemTime(moment.utc(firstTimestamp).add(30, 'minute').toDate()); - const result = await finish(mockContext, { id: 'test-id' }); + const result = await finishMaintenanceWindow(mockContext, { id: 'test-id' }); expect(savedObjectsClient.update).toHaveBeenLastCalledWith( MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, @@ -112,7 +113,7 @@ describe('MaintenanceWindowClient - finish', () => { dtstart: '2023-03-26T00:00:00.000Z', freq: Frequency.WEEKLY, count: 5, - }, + } as MaintenanceWindow['rRule'], events: modifiedEvents, expirationDate: moment(new Date(firstTimestamp)).tz('UTC').add(2, 'week').toISOString(), }); @@ -133,7 +134,7 @@ describe('MaintenanceWindowClient - finish', () => { jest.useFakeTimers().setSystemTime(new Date('2023-04-15T23:30:00.000Z')); - await finish(mockContext, { id: 'test-id' }); + await finishMaintenanceWindow(mockContext, { id: 'test-id' }); expect(savedObjectsClient.update).toHaveBeenLastCalledWith( MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, @@ -160,7 +161,7 @@ describe('MaintenanceWindowClient - finish', () => { dtstart: moment().utc().toISOString(), freq: Frequency.WEEKLY, count: 2, - }, + } as MaintenanceWindow['rRule'], }); savedObjectsClient.get.mockResolvedValueOnce({ @@ -173,7 +174,7 @@ describe('MaintenanceWindowClient - finish', () => { jest.useFakeTimers().setSystemTime(moment.utc(firstTimestamp).add(2, 'hours').toDate()); await expect(async () => { - await finish(mockContext, { id: 'test-id' }); + await finishMaintenanceWindow(mockContext, { id: 'test-id' }); }).rejects.toThrowError(); expect(mockContext.logger.error).toHaveBeenLastCalledWith( diff --git a/x-pack/plugins/alerting/server/maintenance_window_client/methods/finish.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/finish/finish_maintenance_window.ts similarity index 61% rename from x-pack/plugins/alerting/server/maintenance_window_client/methods/finish.ts rename to x-pack/plugins/alerting/server/application/maintenance_window/methods/finish/finish_maintenance_window.ts index 1853a2e49f94e..e318971993542 100644 --- a/x-pack/plugins/alerting/server/maintenance_window_client/methods/finish.ts +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/finish/finish_maintenance_window.ts @@ -10,26 +10,29 @@ import Boom from '@hapi/boom'; import { generateMaintenanceWindowEvents, mergeEvents, -} from '../generate_maintenance_window_events'; -import { getMaintenanceWindowDateAndStatus } from '../get_maintenance_window_date_and_status'; -import { getMaintenanceWindowFromRaw } from '../get_maintenance_window_from_raw'; +} from '../../lib/generate_maintenance_window_events'; +import { getMaintenanceWindowDateAndStatus } from '../../lib/get_maintenance_window_date_and_status'; import { - MaintenanceWindowSOAttributes, - MaintenanceWindow, DateRange, - MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, MaintenanceWindowClientContext, MaintenanceWindowStatus, -} from '../../../common'; -import { retryIfConflicts } from '../../lib/retry_if_conflicts'; - -export interface FinishParams { - id: string; -} +} from '../../../../../common'; +import { retryIfConflicts } from '../../../../lib/retry_if_conflicts'; +import { + getMaintenanceWindowSo, + updateMaintenanceWindowSo, +} from '../../../../data/maintenance_window'; +import type { MaintenanceWindow } from '../../types'; +import { + transformMaintenanceWindowAttributesToMaintenanceWindow, + transformMaintenanceWindowToMaintenanceWindowAttributes, +} from '../../transforms'; +import type { FinishMaintenanceWindowParams } from './types'; +import { finishMaintenanceWindowParamsSchema } from './schemas'; -export async function finish( +export async function finishMaintenanceWindow( context: MaintenanceWindowClientContext, - params: FinishParams + params: FinishMaintenanceWindowParams ): Promise { return await retryIfConflicts( context.logger, @@ -42,11 +45,17 @@ export async function finish( async function finishWithOCC( context: MaintenanceWindowClientContext, - params: FinishParams + params: FinishMaintenanceWindowParams ): Promise { const { savedObjectsClient, getModificationMetadata, logger } = context; const { id } = params; + try { + finishMaintenanceWindowParamsSchema.validate(params); + } catch (error) { + throw Boom.badRequest(`Error validating finish maintenance window data - ${error.message}`); + } + const modificationMetadata = await getModificationMetadata(); const now = new Date(); const expirationDate = moment.utc(now).add(1, 'year').toDate(); @@ -56,22 +65,24 @@ async function finishWithOCC( attributes, version, id: fetchedId, - } = await savedObjectsClient.get( - MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, - id - ); + } = await getMaintenanceWindowSo({ id, savedObjectsClient }); + + const maintenanceWindow = transformMaintenanceWindowAttributesToMaintenanceWindow({ + attributes, + id: fetchedId, + }); // Generate new events with new expiration date const newEvents = generateMaintenanceWindowEvents({ - rRule: attributes.rRule, - duration: attributes.duration, + rRule: maintenanceWindow.rRule, + duration: maintenanceWindow.duration, expirationDate: expirationDate.toISOString(), }); // Merge it with the old events const events = mergeEvents({ newEvents, - oldEvents: attributes.events, + oldEvents: maintenanceWindow.events, }); // Find the current event and status of the maintenance window @@ -99,21 +110,25 @@ async function finishWithOCC( const eventsWithFinishedEvent = [...events]; eventsWithFinishedEvent[index] = eventToFinish; - const result = await savedObjectsClient.update( - MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, - fetchedId, - { + const updateMaintenanceWindowAttributes = + transformMaintenanceWindowToMaintenanceWindowAttributes({ + ...maintenanceWindow, events: eventsWithFinishedEvent, expirationDate: expirationDate.toISOString(), updatedAt: modificationMetadata.updatedAt, updatedBy: modificationMetadata.updatedBy, - }, - { + }); + + const result = await updateMaintenanceWindowSo({ + id: fetchedId, + savedObjectsClient, + updateMaintenanceWindowAttributes, + savedObjectsUpdateOptions: { version, - } - ); + }, + }); - return getMaintenanceWindowFromRaw({ + return transformMaintenanceWindowAttributesToMaintenanceWindow({ attributes: { ...attributes, ...result.attributes, diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/finish/schemas/finish_maintenance_window_params_schema.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/finish/schemas/finish_maintenance_window_params_schema.ts new file mode 100644 index 0000000000000..efb7733da9abb --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/finish/schemas/finish_maintenance_window_params_schema.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { schema } from '@kbn/config-schema'; + +export const finishMaintenanceWindowParamsSchema = schema.object({ + id: schema.string(), +}); diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/finish/schemas/index.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/finish/schemas/index.ts new file mode 100644 index 0000000000000..482631258caa9 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/finish/schemas/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { finishMaintenanceWindowParamsSchema } from './finish_maintenance_window_params_schema'; diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/finish/types/finish_maintenance_window_params.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/finish/types/finish_maintenance_window_params.ts new file mode 100644 index 0000000000000..7356042f758fa --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/finish/types/finish_maintenance_window_params.ts @@ -0,0 +1,11 @@ +/* + * 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 { TypeOf } from '@kbn/config-schema'; +import { finishMaintenanceWindowParamsSchema } from '../schemas'; + +export type FinishMaintenanceWindowParams = TypeOf; diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/finish/types/index.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/finish/types/index.ts new file mode 100644 index 0000000000000..d5a180637ff2e --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/finish/types/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type { FinishMaintenanceWindowParams } from './finish_maintenance_window_params'; diff --git a/x-pack/plugins/alerting/server/maintenance_window_client/methods/get.test.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/get/get_maintenance_window.test.ts similarity index 84% rename from x-pack/plugins/alerting/server/maintenance_window_client/methods/get.test.ts rename to x-pack/plugins/alerting/server/application/maintenance_window/methods/get/get_maintenance_window.test.ts index 09ba15d0289d1..fa24bb42e57d8 100644 --- a/x-pack/plugins/alerting/server/maintenance_window_client/methods/get.test.ts +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/get/get_maintenance_window.test.ts @@ -5,14 +5,14 @@ * 2.0. */ -import { get } from './get'; +import { getMaintenanceWindow } from './get_maintenance_window'; import { savedObjectsClientMock, loggingSystemMock } from '@kbn/core/server/mocks'; import { SavedObject } from '@kbn/core/server'; import { MaintenanceWindowClientContext, MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, -} from '../../../common'; -import { getMockMaintenanceWindow } from './test_helpers'; +} from '../../../../../common'; +import { getMockMaintenanceWindow } from '../../../../data/maintenance_window/test_helpers'; const savedObjectsClient = savedObjectsClientMock.create(); @@ -42,7 +42,7 @@ describe('MaintenanceWindowClient - get', () => { id: 'test-id', } as unknown as SavedObject); - const result = await get(mockContext, { id: 'test-id' }); + const result = await getMaintenanceWindow(mockContext, { id: 'test-id' }); expect(savedObjectsClient.get).toHaveBeenLastCalledWith( MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/get/get_maintenance_window.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/get/get_maintenance_window.ts new file mode 100644 index 0000000000000..1b4aefa831094 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/get/get_maintenance_window.ts @@ -0,0 +1,44 @@ +/* + * 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 Boom from '@hapi/boom'; +import type { MaintenanceWindowClientContext } from '../../../../../common'; +import type { MaintenanceWindow } from '../../types'; +import type { GetMaintenanceWindowParams } from './types'; +import { transformMaintenanceWindowAttributesToMaintenanceWindow } from '../../transforms'; +import { getMaintenanceWindowParamsSchema } from './schemas'; +import { getMaintenanceWindowSo } from '../../../../data/maintenance_window'; + +export async function getMaintenanceWindow( + context: MaintenanceWindowClientContext, + params: GetMaintenanceWindowParams +): Promise { + const { savedObjectsClient, logger } = context; + const { id } = params; + + try { + getMaintenanceWindowParamsSchema.validate(params); + } catch (error) { + throw Boom.badRequest(`Error validating get maintenance window data - ${error.message}`); + } + + try { + const result = await getMaintenanceWindowSo({ + id, + savedObjectsClient, + }); + + return transformMaintenanceWindowAttributesToMaintenanceWindow({ + attributes: result.attributes, + id: result.id, + }); + } catch (e) { + const errorMessage = `Failed to get maintenance window by id: ${id}, Error: ${e}`; + logger.error(errorMessage); + throw Boom.boomify(e, { message: errorMessage }); + } +} diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/get/schemas/get_maintenance_window_params_schema.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/get/schemas/get_maintenance_window_params_schema.ts new file mode 100644 index 0000000000000..9eaffadc90cc2 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/get/schemas/get_maintenance_window_params_schema.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { schema } from '@kbn/config-schema'; + +export const getMaintenanceWindowParamsSchema = schema.object({ + id: schema.string(), +}); diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/get/schemas/index.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/get/schemas/index.ts new file mode 100644 index 0000000000000..92b3a8024c787 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/get/schemas/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { getMaintenanceWindowParamsSchema } from './get_maintenance_window_params_schema'; diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/get/types/get_maintenance_window_params.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/get/types/get_maintenance_window_params.ts new file mode 100644 index 0000000000000..e9bf4c7f3d1c4 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/get/types/get_maintenance_window_params.ts @@ -0,0 +1,11 @@ +/* + * 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 { TypeOf } from '@kbn/config-schema'; +import { getMaintenanceWindowParamsSchema } from '../schemas'; + +export type GetMaintenanceWindowParams = TypeOf; diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/get/types/index.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/get/types/index.ts new file mode 100644 index 0000000000000..c38bba1cf250c --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/get/types/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type { GetMaintenanceWindowParams } from './get_maintenance_window_params'; diff --git a/x-pack/plugins/alerting/server/maintenance_window_client/methods/get_active_maintenance_windows.test.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/get_active/get_active_maintenance_windows.test.ts similarity index 97% rename from x-pack/plugins/alerting/server/maintenance_window_client/methods/get_active_maintenance_windows.test.ts rename to x-pack/plugins/alerting/server/application/maintenance_window/methods/get_active/get_active_maintenance_windows.test.ts index 2351a687728c8..b9a9f958b4e6a 100644 --- a/x-pack/plugins/alerting/server/maintenance_window_client/methods/get_active_maintenance_windows.test.ts +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/get_active/get_active_maintenance_windows.test.ts @@ -12,8 +12,8 @@ import { SavedObjectsFindResponse } from '@kbn/core/server'; import { MaintenanceWindowClientContext, MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, -} from '../../../common'; -import { getMockMaintenanceWindow } from './test_helpers'; +} from '../../../../../common'; +import { getMockMaintenanceWindow } from '../../../../data/maintenance_window/test_helpers'; const savedObjectsClient = savedObjectsClientMock.create(); diff --git a/x-pack/plugins/alerting/server/maintenance_window_client/methods/get_active_maintenance_windows.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/get_active/get_active_maintenance_windows.ts similarity index 64% rename from x-pack/plugins/alerting/server/maintenance_window_client/methods/get_active_maintenance_windows.ts rename to x-pack/plugins/alerting/server/application/maintenance_window/methods/get_active/get_active_maintenance_windows.ts index ececf6618b0a5..9fc834c607548 100644 --- a/x-pack/plugins/alerting/server/maintenance_window_client/methods/get_active_maintenance_windows.ts +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/get_active/get_active_maintenance_windows.ts @@ -7,13 +7,10 @@ import Boom from '@hapi/boom'; import { nodeBuilder } from '@kbn/es-query'; -import { getMaintenanceWindowFromRaw } from '../get_maintenance_window_from_raw'; -import { - MaintenanceWindow, - MaintenanceWindowSOAttributes, - MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, - MaintenanceWindowClientContext, -} from '../../../common'; +import type { MaintenanceWindowClientContext } from '../../../../../common'; +import type { MaintenanceWindow } from '../../types'; +import { transformMaintenanceWindowAttributesToMaintenanceWindow } from '../../transforms'; +import { findMaintenanceWindowSo } from '../../../../data/maintenance_window'; export interface MaintenanceWindowAggregationResult { maintenanceWindow: { @@ -39,17 +36,17 @@ export async function getActiveMaintenanceWindows( ]); try { - const result = await savedObjectsClient.find({ - type: MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, - filter, + const { saved_objects: savedObjects } = await findMaintenanceWindowSo({ + savedObjectsClient, + savedObjectsFindOptions: { filter }, }); - return result.saved_objects.map((so) => - getMaintenanceWindowFromRaw({ - attributes: so.attributes, - id: so.id, - }) - ); + return savedObjects.map((savedObject) => { + return transformMaintenanceWindowAttributesToMaintenanceWindow({ + attributes: savedObject.attributes, + id: savedObject.id, + }); + }); } catch (e) { const errorMessage = `Failed to find active maintenance window by interval, Error: ${e}`; logger.error(errorMessage); diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/update/schemas/index.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/update/schemas/index.ts new file mode 100644 index 0000000000000..5d410841841c5 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/update/schemas/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { updateMaintenanceWindowParamsSchema } from './update_maintenance_window_params_schema'; diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/update/schemas/update_maintenance_window_params_schema.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/update/schemas/update_maintenance_window_params_schema.ts new file mode 100644 index 0000000000000..1171855ca2819 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/update/schemas/update_maintenance_window_params_schema.ts @@ -0,0 +1,19 @@ +/* + * 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 { schema } from '@kbn/config-schema'; +import { rRuleRequestSchema } from '../../../../r_rule/schemas'; + +export const updateMaintenanceWindowParamsSchema = schema.object({ + id: schema.string(), + data: schema.object({ + title: schema.maybe(schema.string()), + enabled: schema.maybe(schema.boolean()), + duration: schema.maybe(schema.number()), + rRule: schema.maybe(rRuleRequestSchema), + }), +}); diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/update/types/index.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/update/types/index.ts new file mode 100644 index 0000000000000..af979060d6222 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/update/types/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type { UpdateMaintenanceWindowParams } from './update_maintenance_window_params'; diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/update/types/update_maintenance_window_params.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/update/types/update_maintenance_window_params.ts new file mode 100644 index 0000000000000..a8497347a52b7 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/update/types/update_maintenance_window_params.ts @@ -0,0 +1,11 @@ +/* + * 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 { TypeOf } from '@kbn/config-schema'; +import { updateMaintenanceWindowParamsSchema } from '../schemas'; + +export type UpdateMaintenanceWindowParams = TypeOf; diff --git a/x-pack/plugins/alerting/server/maintenance_window_client/methods/update.test.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/update/update_maintenance_window.test.ts similarity index 85% rename from x-pack/plugins/alerting/server/maintenance_window_client/methods/update.test.ts rename to x-pack/plugins/alerting/server/application/maintenance_window/methods/update/update_maintenance_window.test.ts index ea2cb33341b0d..27798cc4e3c57 100644 --- a/x-pack/plugins/alerting/server/maintenance_window_client/methods/update.test.ts +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/update/update_maintenance_window.test.ts @@ -7,14 +7,16 @@ import moment from 'moment-timezone'; import { Frequency } from '@kbn/rrule'; -import { update } from './update'; +import { updateMaintenanceWindow } from './update_maintenance_window'; +import { UpdateMaintenanceWindowParams } from './types'; import { savedObjectsClientMock, loggingSystemMock } from '@kbn/core/server/mocks'; import { SavedObject } from '@kbn/core/server'; import { MaintenanceWindowClientContext, MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, -} from '../../../common'; -import { getMockMaintenanceWindow } from './test_helpers'; +} from '../../../../../common'; +import { getMockMaintenanceWindow } from '../../../../data/maintenance_window/test_helpers'; +import type { MaintenanceWindow } from '../../types'; const savedObjectsClient = savedObjectsClientMock.create(); @@ -83,9 +85,12 @@ describe('MaintenanceWindowClient - update', () => { jest.useFakeTimers().setSystemTime(new Date(secondTimestamp)); - const result = await update(mockContext, { + const result = await updateMaintenanceWindow(mockContext, { id: 'test-id', - ...updatedAttributes, + data: { + ...updatedAttributes, + rRule: updatedAttributes.rRule as UpdateMaintenanceWindowParams['data']['rRule'], + }, }); expect(savedObjectsClient.get).toHaveBeenLastCalledWith( @@ -136,7 +141,7 @@ describe('MaintenanceWindowClient - update', () => { dtstart: '2023-03-26T00:00:00.000Z', freq: Frequency.WEEKLY, count: 5, - }, + } as MaintenanceWindow['rRule'], events: modifiedEvents, expirationDate: moment(new Date(firstTimestamp)).tz('UTC').add(2, 'week').toISOString(), }); @@ -157,7 +162,7 @@ describe('MaintenanceWindowClient - update', () => { } as unknown as SavedObject); // Update without changing duration or rrule - await update(mockContext, { id: 'test-id' }); + await updateMaintenanceWindow(mockContext, { id: 'test-id', data: {} }); // Events keep the previous modified events, but adds on the new events expect(savedObjectsClient.create).toHaveBeenLastCalledWith( MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, @@ -172,13 +177,15 @@ describe('MaintenanceWindowClient - update', () => { ); // Update with changing rrule - await update(mockContext, { + await updateMaintenanceWindow(mockContext, { id: 'test-id', - rRule: { - tzid: 'CET', - dtstart: '2023-03-26T00:00:00.000Z', - freq: Frequency.WEEKLY, - count: 2, + data: { + rRule: { + tzid: 'CET', + dtstart: '2023-03-26T00:00:00.000Z', + freq: Frequency.WEEKLY, + count: 2, + }, }, }); // All events are regenerated @@ -211,7 +218,17 @@ describe('MaintenanceWindowClient - update', () => { } as unknown as SavedObject); await expect(async () => { - await update(mockContext, { id: 'test-id', ...updatedAttributes }); + await updateMaintenanceWindow(mockContext, { + id: 'test-id', + data: { + rRule: { + tzid: 'CET', + dtstart: '2023-03-26T00:00:00.000Z', + freq: Frequency.WEEKLY, + count: 2, + }, + }, + }); }).rejects.toThrowError(); expect(mockContext.logger.error).toHaveBeenLastCalledWith( diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/update/update_maintenance_window.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/update/update_maintenance_window.ts new file mode 100644 index 0000000000000..19b145a489431 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/update/update_maintenance_window.ts @@ -0,0 +1,120 @@ +/* + * 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 moment from 'moment'; +import Boom from '@hapi/boom'; +import type { MaintenanceWindowClientContext } from '../../../../../common'; +import type { MaintenanceWindow } from '../../types'; +import { + generateMaintenanceWindowEvents, + shouldRegenerateEvents, + mergeEvents, +} from '../../lib/generate_maintenance_window_events'; +import { retryIfConflicts } from '../../../../lib/retry_if_conflicts'; +import { + transformMaintenanceWindowAttributesToMaintenanceWindow, + transformMaintenanceWindowToMaintenanceWindowAttributes, +} from '../../transforms'; +import { + getMaintenanceWindowSo, + createMaintenanceWindowSo, +} from '../../../../data/maintenance_window'; +import { UpdateMaintenanceWindowParams } from './types'; +import { updateMaintenanceWindowParamsSchema } from './schemas'; + +export async function updateMaintenanceWindow( + context: MaintenanceWindowClientContext, + params: UpdateMaintenanceWindowParams +): Promise { + return await retryIfConflicts( + context.logger, + `maintenanceWindowClient.update('${params.id})`, + async () => { + return await updateWithOCC(context, params); + } + ); +} + +async function updateWithOCC( + context: MaintenanceWindowClientContext, + params: UpdateMaintenanceWindowParams +): Promise { + const { savedObjectsClient, getModificationMetadata, logger } = context; + const { id, data } = params; + const { title, enabled, duration, rRule } = data; + + try { + updateMaintenanceWindowParamsSchema.validate(params); + } catch (error) { + throw Boom.badRequest(`Error validating update maintenance window data - ${error.message}`); + } + + try { + const { + attributes, + id: fetchedId, + version, + } = await getMaintenanceWindowSo({ id, savedObjectsClient }); + + const maintenanceWindow = transformMaintenanceWindowAttributesToMaintenanceWindow({ + attributes, + id: fetchedId, + }); + + if (moment.utc(maintenanceWindow.expirationDate).isBefore(new Date())) { + throw Boom.badRequest('Cannot edit archived maintenance windows'); + } + + const expirationDate = moment.utc().add(1, 'year').toISOString(); + const modificationMetadata = await getModificationMetadata(); + + let events = generateMaintenanceWindowEvents({ + rRule: rRule || maintenanceWindow.rRule, + duration: typeof duration === 'number' ? duration : maintenanceWindow.duration, + expirationDate, + }); + + if (!shouldRegenerateEvents({ maintenanceWindow, rRule, duration })) { + events = mergeEvents({ oldEvents: maintenanceWindow.events, newEvents: events }); + } + + const updateMaintenanceWindowAttributes = + transformMaintenanceWindowToMaintenanceWindowAttributes({ + ...maintenanceWindow, + ...(title ? { title } : {}), + ...(rRule ? { rRule: rRule as MaintenanceWindow['rRule'] } : {}), + ...(typeof duration === 'number' ? { duration } : {}), + ...(typeof enabled === 'boolean' ? { enabled } : {}), + expirationDate, + events, + updatedBy: modificationMetadata.updatedBy, + updatedAt: modificationMetadata.updatedAt, + }); + + // We are deleting and then creating rather than updating because SO.update + // performs a partial update on the rRule, we would need to null out all of the fields + // that are removed from a new rRule if that were the case. + const result = await createMaintenanceWindowSo({ + savedObjectsClient, + maintenanceWindowAttributes: updateMaintenanceWindowAttributes, + savedObjectsCreateOptions: { + id: fetchedId, + version, + overwrite: true, + }, + }); + + return transformMaintenanceWindowAttributesToMaintenanceWindow({ + attributes: result.attributes, + id: result.id, + }); + } catch (e) { + const errorMessage = `Failed to update maintenance window by id: ${id}, Error: ${e}`; + logger.error(errorMessage); + throw Boom.boomify(e, { message: errorMessage }); + } +} diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/schemas/index.ts b/x-pack/plugins/alerting/server/application/maintenance_window/schemas/index.ts new file mode 100644 index 0000000000000..6cfbebc677b33 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/schemas/index.ts @@ -0,0 +1,11 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { + maintenanceWindowEventSchema, + maintenanceWindowSchema, +} from './maintenance_window_schemas'; diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/schemas/maintenance_window_schemas.ts b/x-pack/plugins/alerting/server/application/maintenance_window/schemas/maintenance_window_schemas.ts new file mode 100644 index 0000000000000..bb70e4ee82abe --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/schemas/maintenance_window_schemas.ts @@ -0,0 +1,37 @@ +/* + * 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 { schema } from '@kbn/config-schema'; +import { maintenanceWindowStatus } from '../constants'; +import { rRuleSchema } from '../../r_rule/schemas'; + +export const maintenanceWindowEventSchema = schema.object({ + gte: schema.string(), + lte: schema.string(), +}); + +export const maintenanceWindowSchema = schema.object({ + id: schema.string(), + title: schema.string(), + enabled: schema.boolean(), + duration: schema.number(), + expirationDate: schema.string(), + events: schema.arrayOf(maintenanceWindowEventSchema), + rRule: rRuleSchema, + createdBy: schema.nullable(schema.string()), + updatedBy: schema.nullable(schema.string()), + createdAt: schema.string(), + updatedAt: schema.string(), + eventStartTime: schema.nullable(schema.string()), + eventEndTime: schema.nullable(schema.string()), + status: schema.oneOf([ + schema.literal(maintenanceWindowStatus.RUNNING), + schema.literal(maintenanceWindowStatus.UPCOMING), + schema.literal(maintenanceWindowStatus.FINISHED), + schema.literal(maintenanceWindowStatus.ARCHIVED), + ]), +}); diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/transforms/index.ts b/x-pack/plugins/alerting/server/application/maintenance_window/transforms/index.ts new file mode 100644 index 0000000000000..a9b5323c94a68 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/transforms/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { transformMaintenanceWindowAttributesToMaintenanceWindow } from './transform_maintenance_window_attributes_to_maintenance_window'; +export { transformMaintenanceWindowToMaintenanceWindowAttributes } from './transform_maintenance_window_to_maintenance_window_attributes'; diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/transforms/transform_maintenance_window_attributes_to_maintenance_window.ts b/x-pack/plugins/alerting/server/application/maintenance_window/transforms/transform_maintenance_window_attributes_to_maintenance_window.ts new file mode 100644 index 0000000000000..a03dbe9e4b3a8 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/transforms/transform_maintenance_window_attributes_to_maintenance_window.ts @@ -0,0 +1,43 @@ +/* + * 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 { MaintenanceWindow } from '../types'; +import { MaintenanceWindowAttributes } from '../../../data/maintenance_window/types'; +import { getMaintenanceWindowDateAndStatus } from '../lib'; + +export interface TransformMaintenanceWindowAttributesMaintenanceWindowParams { + attributes: MaintenanceWindowAttributes; + id: string; +} + +export const transformMaintenanceWindowAttributesToMaintenanceWindow = ( + params: TransformMaintenanceWindowAttributesMaintenanceWindowParams +): MaintenanceWindow => { + const { id, attributes } = params; + const { events, expirationDate } = attributes; + const { eventStartTime, eventEndTime, status } = getMaintenanceWindowDateAndStatus({ + events, + expirationDate: new Date(expirationDate), + dateToCompare: new Date(), + }); + + return { + id, + title: attributes.title, + enabled: attributes.enabled, + duration: attributes.duration, + expirationDate: attributes.expirationDate, + events: attributes.events, + rRule: attributes.rRule, + createdBy: attributes.createdBy, + updatedBy: attributes.updatedBy, + createdAt: attributes.createdAt, + updatedAt: attributes.updatedAt, + eventStartTime, + eventEndTime, + status, + }; +}; diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/transforms/transform_maintenance_window_to_maintenance_window_attributes.ts b/x-pack/plugins/alerting/server/application/maintenance_window/transforms/transform_maintenance_window_to_maintenance_window_attributes.ts new file mode 100644 index 0000000000000..98b2f9fe93bce --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/transforms/transform_maintenance_window_to_maintenance_window_attributes.ts @@ -0,0 +1,26 @@ +/* + * 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 { MaintenanceWindowWithoutComputedProperties } from '../types'; +import { MaintenanceWindowAttributes } from '../../../data/maintenance_window/types'; + +export const transformMaintenanceWindowToMaintenanceWindowAttributes = ( + maintenanceWindow: MaintenanceWindowWithoutComputedProperties +): MaintenanceWindowAttributes => { + return { + title: maintenanceWindow.title, + enabled: maintenanceWindow.enabled, + duration: maintenanceWindow.duration, + expirationDate: maintenanceWindow.expirationDate, + events: maintenanceWindow.events, + rRule: maintenanceWindow.rRule, + createdBy: maintenanceWindow.createdBy, + updatedBy: maintenanceWindow.updatedBy, + createdAt: maintenanceWindow.createdAt, + updatedAt: maintenanceWindow.updatedAt, + }; +}; diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/types/index.ts b/x-pack/plugins/alerting/server/application/maintenance_window/types/index.ts new file mode 100644 index 0000000000000..30a56f4e53083 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/types/index.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type { + MaintenanceWindow, + MaintenanceWindowStatus, + MaintenanceWindowWithoutComputedProperties, +} from './maintenance_window'; diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/types/maintenance_window.ts b/x-pack/plugins/alerting/server/application/maintenance_window/types/maintenance_window.ts new file mode 100644 index 0000000000000..15dd6b8ca2a1b --- /dev/null +++ b/x-pack/plugins/alerting/server/application/maintenance_window/types/maintenance_window.ts @@ -0,0 +1,19 @@ +/* + * 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 { TypeOf } from '@kbn/config-schema'; +import { maintenanceWindowStatus } from '../constants'; +import { maintenanceWindowSchema } from '../schemas'; + +export type MaintenanceWindow = TypeOf; +export type MaintenanceWindowStatus = + typeof maintenanceWindowStatus[keyof typeof maintenanceWindowStatus]; + +export type MaintenanceWindowWithoutComputedProperties = Omit< + MaintenanceWindow, + 'id' | 'eventStartTime' | 'eventEndTime' | 'status' +>; diff --git a/x-pack/plugins/alerting/server/data/maintenance_window/index.ts b/x-pack/plugins/alerting/server/data/maintenance_window/index.ts new file mode 100644 index 0000000000000..a2b43b507797d --- /dev/null +++ b/x-pack/plugins/alerting/server/data/maintenance_window/index.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { bulkGetMaintenanceWindowSo } from './methods/bulk_get_maintenance_window_so'; +export { createMaintenanceWindowSo } from './methods/create_maintenance_window_so'; +export { deleteMaintenanceWindowSo } from './methods/delete_maintenance_window_so'; +export { findMaintenanceWindowSo } from './methods/find_maintenance_window_so'; +export { getMaintenanceWindowSo } from './methods/get_maintenance_window_so'; +export { updateMaintenanceWindowSo } from './methods/update_maintenance_window_so'; + +export type { BulkGetMaintenanceWindowSoParams } from './methods/bulk_get_maintenance_window_so'; +export type { CreateMaintenanceWindowSoParams } from './methods/create_maintenance_window_so'; +export type { DeleteMaintenanceWindowSoParams } from './methods/delete_maintenance_window_so'; +export type { FindMaintenanceWindowSoParams } from './methods/find_maintenance_window_so'; +export type { GetMaintenanceWindowSoParams } from './methods/get_maintenance_window_so'; +export type { UpdateMaintenanceWindowSoParams } from './methods/update_maintenance_window_so'; diff --git a/x-pack/plugins/alerting/server/data/maintenance_window/methods/bulk_get_maintenance_window_so.ts b/x-pack/plugins/alerting/server/data/maintenance_window/methods/bulk_get_maintenance_window_so.ts new file mode 100644 index 0000000000000..4023948caf7ad --- /dev/null +++ b/x-pack/plugins/alerting/server/data/maintenance_window/methods/bulk_get_maintenance_window_so.ts @@ -0,0 +1,32 @@ +/* + * 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 { SavedObjectsClientContract, SavedObjectsBulkResponse } from '@kbn/core/server'; +import { MaintenanceWindowAttributes } from '../types'; +import { MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE } from '../../../../common'; + +export interface BulkGetMaintenanceWindowObject { + id: string; +} + +export interface BulkGetMaintenanceWindowSoParams { + objects: BulkGetMaintenanceWindowObject[]; + savedObjectsClient: SavedObjectsClientContract; +} + +export const bulkGetMaintenanceWindowSo = ( + params: BulkGetMaintenanceWindowSoParams +): Promise> => { + const { objects, savedObjectsClient } = params; + + return savedObjectsClient.bulkGet( + objects.map((object) => ({ + id: object.id, + type: MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, + })) + ); +}; diff --git a/x-pack/plugins/alerting/server/data/maintenance_window/methods/create_maintenance_window_so.ts b/x-pack/plugins/alerting/server/data/maintenance_window/methods/create_maintenance_window_so.ts new file mode 100644 index 0000000000000..6beee4db0d9e8 --- /dev/null +++ b/x-pack/plugins/alerting/server/data/maintenance_window/methods/create_maintenance_window_so.ts @@ -0,0 +1,32 @@ +/* + * 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 { + SavedObjectsClientContract, + SavedObjectsCreateOptions, + SavedObject, +} from '@kbn/core/server'; +import { MaintenanceWindowAttributes } from '../types'; +import { MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE } from '../../../../common'; + +export interface CreateMaintenanceWindowSoParams { + savedObjectsClient: SavedObjectsClientContract; + maintenanceWindowAttributes: MaintenanceWindowAttributes; + savedObjectsCreateOptions?: SavedObjectsCreateOptions; +} + +export const createMaintenanceWindowSo = ( + params: CreateMaintenanceWindowSoParams +): Promise> => { + const { savedObjectsClient, maintenanceWindowAttributes, savedObjectsCreateOptions } = params; + + return savedObjectsClient.create( + MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, + maintenanceWindowAttributes, + savedObjectsCreateOptions + ); +}; diff --git a/x-pack/plugins/alerting/server/data/maintenance_window/methods/delete_maintenance_window_so.ts b/x-pack/plugins/alerting/server/data/maintenance_window/methods/delete_maintenance_window_so.ts new file mode 100644 index 0000000000000..18725da8dbd5a --- /dev/null +++ b/x-pack/plugins/alerting/server/data/maintenance_window/methods/delete_maintenance_window_so.ts @@ -0,0 +1,25 @@ +/* + * 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 { SavedObjectsClientContract, SavedObjectsDeleteOptions } from '@kbn/core/server'; +import { MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE } from '../../../../common'; + +export interface DeleteMaintenanceWindowSoParams { + id: string; + savedObjectsClient: SavedObjectsClientContract; + savedObjectsDeleteOptions?: SavedObjectsDeleteOptions; +} + +export const deleteMaintenanceWindowSo = (params: DeleteMaintenanceWindowSoParams): Promise<{}> => { + const { id, savedObjectsClient, savedObjectsDeleteOptions } = params; + + return savedObjectsClient.delete( + MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, + id, + savedObjectsDeleteOptions + ); +}; diff --git a/x-pack/plugins/alerting/server/data/maintenance_window/methods/find_maintenance_window_so.ts b/x-pack/plugins/alerting/server/data/maintenance_window/methods/find_maintenance_window_so.ts new file mode 100644 index 0000000000000..baaed546c88cb --- /dev/null +++ b/x-pack/plugins/alerting/server/data/maintenance_window/methods/find_maintenance_window_so.ts @@ -0,0 +1,30 @@ +/* + * 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 { + SavedObjectsClientContract, + SavedObjectsFindOptions, + SavedObjectsFindResponse, +} from '@kbn/core/server'; +import { MaintenanceWindowAttributes } from '../types'; +import { MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE } from '../../../../common'; + +export interface FindMaintenanceWindowSoParams { + savedObjectsClient: SavedObjectsClientContract; + savedObjectsFindOptions?: Omit; +} + +export const findMaintenanceWindowSo = >( + params: FindMaintenanceWindowSoParams +): Promise> => { + const { savedObjectsClient, savedObjectsFindOptions } = params; + + return savedObjectsClient.find({ + ...savedObjectsFindOptions, + type: MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, + }); +}; diff --git a/x-pack/plugins/alerting/server/data/maintenance_window/methods/get_maintenance_window_so.ts b/x-pack/plugins/alerting/server/data/maintenance_window/methods/get_maintenance_window_so.ts new file mode 100644 index 0000000000000..9dfb11ee7ee0b --- /dev/null +++ b/x-pack/plugins/alerting/server/data/maintenance_window/methods/get_maintenance_window_so.ts @@ -0,0 +1,26 @@ +/* + * 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 { SavedObjectsClientContract, SavedObject } from '@kbn/core/server'; +import { MaintenanceWindowAttributes } from '../types'; +import { MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE } from '../../../../common'; + +export interface GetMaintenanceWindowSoParams { + id: string; + savedObjectsClient: SavedObjectsClientContract; +} + +export const getMaintenanceWindowSo = ( + params: GetMaintenanceWindowSoParams +): Promise> => { + const { id, savedObjectsClient } = params; + + return savedObjectsClient.get( + MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, + id + ); +}; diff --git a/x-pack/plugins/alerting/server/data/maintenance_window/methods/update_maintenance_window_so.ts b/x-pack/plugins/alerting/server/data/maintenance_window/methods/update_maintenance_window_so.ts new file mode 100644 index 0000000000000..b65516da3c726 --- /dev/null +++ b/x-pack/plugins/alerting/server/data/maintenance_window/methods/update_maintenance_window_so.ts @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + SavedObjectsClientContract, + SavedObjectsUpdateOptions, + SavedObjectsUpdateResponse, +} from '@kbn/core/server'; +import { MaintenanceWindowAttributes } from '../types'; +import { MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE } from '../../../../common'; + +export interface UpdateMaintenanceWindowSoParams { + id: string; + savedObjectsClient: SavedObjectsClientContract; + updateMaintenanceWindowAttributes: Partial; + savedObjectsUpdateOptions?: SavedObjectsUpdateOptions; +} + +export const updateMaintenanceWindowSo = ( + params: UpdateMaintenanceWindowSoParams +): Promise> => { + const { id, savedObjectsClient, updateMaintenanceWindowAttributes, savedObjectsUpdateOptions } = + params; + + return savedObjectsClient.update( + MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, + id, + updateMaintenanceWindowAttributes, + savedObjectsUpdateOptions + ); +}; diff --git a/x-pack/plugins/alerting/server/maintenance_window_client/methods/test_helpers.ts b/x-pack/plugins/alerting/server/data/maintenance_window/test_helpers.ts similarity index 83% rename from x-pack/plugins/alerting/server/maintenance_window_client/methods/test_helpers.ts rename to x-pack/plugins/alerting/server/data/maintenance_window/test_helpers.ts index 54745c61b73e9..2d18b736fdc14 100644 --- a/x-pack/plugins/alerting/server/maintenance_window_client/methods/test_helpers.ts +++ b/x-pack/plugins/alerting/server/data/maintenance_window/test_helpers.ts @@ -6,11 +6,11 @@ */ import { Frequency } from '@kbn/rrule'; -import { MaintenanceWindowSOAttributes } from '../../../common'; +import { MaintenanceWindowAttributes } from './types'; export const getMockMaintenanceWindow = ( - overwrites?: Partial -): MaintenanceWindowSOAttributes => { + overwrites?: Partial +): MaintenanceWindowAttributes => { return { title: 'test-title', duration: 60 * 60 * 1000, @@ -20,7 +20,7 @@ export const getMockMaintenanceWindow = ( dtstart: '2023-02-26T00:00:00.000Z', freq: Frequency.WEEKLY, count: 2, - }, + } as MaintenanceWindowAttributes['rRule'], events: [ { gte: '2023-02-26T00:00:00.000Z', diff --git a/x-pack/plugins/alerting/server/data/maintenance_window/types/index.ts b/x-pack/plugins/alerting/server/data/maintenance_window/types/index.ts new file mode 100644 index 0000000000000..a3d230d15e6e3 --- /dev/null +++ b/x-pack/plugins/alerting/server/data/maintenance_window/types/index.ts @@ -0,0 +1,11 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type { + MaintenanceWindowAttributes, + MaintenanceWindowEventAttributes, +} from './maintenance_window_attributes'; diff --git a/x-pack/plugins/alerting/server/data/maintenance_window/types/maintenance_window_attributes.ts b/x-pack/plugins/alerting/server/data/maintenance_window/types/maintenance_window_attributes.ts new file mode 100644 index 0000000000000..6167d94a722db --- /dev/null +++ b/x-pack/plugins/alerting/server/data/maintenance_window/types/maintenance_window_attributes.ts @@ -0,0 +1,26 @@ +/* + * 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 { RRuleAttributes } from '../../r_rule/types'; + +export interface MaintenanceWindowEventAttributes { + gte: string; + lte: string; +} + +export interface MaintenanceWindowAttributes { + title: string; + enabled: boolean; + duration: number; + expirationDate: string; + events: MaintenanceWindowEventAttributes[]; + rRule: RRuleAttributes; + createdBy: string | null; + updatedBy: string | null; + createdAt: string; + updatedAt: string; +} diff --git a/x-pack/plugins/alerting/server/data/r_rule/types/index.ts b/x-pack/plugins/alerting/server/data/r_rule/types/index.ts new file mode 100644 index 0000000000000..282fd9238c73b --- /dev/null +++ b/x-pack/plugins/alerting/server/data/r_rule/types/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type { RRuleAttributes } from './r_rule_attributes'; diff --git a/x-pack/plugins/alerting/server/data/r_rule/types/r_rule_attributes.ts b/x-pack/plugins/alerting/server/data/r_rule/types/r_rule_attributes.ts new file mode 100644 index 0000000000000..e29bc5c7ab7e2 --- /dev/null +++ b/x-pack/plugins/alerting/server/data/r_rule/types/r_rule_attributes.ts @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { WeekdayStr } from '@kbn/rrule'; + +type RRuleFreq = 0 | 1 | 2 | 3 | 4 | 5 | 6; + +export interface RRuleAttributes { + dtstart: string; + tzid: string; + freq?: RRuleFreq; + until?: string; + count?: number; + interval?: number; + wkst?: WeekdayStr; + byweekday?: Array; + bymonth?: number[]; + bysetpos?: number[]; + bymonthday: number[]; + byyearday: number[]; + byweekno: number[]; + byhour: number[]; + byminute: number[]; + bysecond: number[]; +} diff --git a/x-pack/plugins/alerting/server/data/rule/types/index.ts b/x-pack/plugins/alerting/server/data/rule/types/index.ts index d0eef33f65547..a742c1b28224b 100644 --- a/x-pack/plugins/alerting/server/data/rule/types/index.ts +++ b/x-pack/plugins/alerting/server/data/rule/types/index.ts @@ -12,7 +12,6 @@ export type { RuleExecutionStatusValuesAttributes, RuleExecutionStatusErrorReasonAttributes, RuleExecutionStatusWarningReasonAttributes, - RRuleAttributes, RuleSnoozeScheduleAttributes, RuleExecutionStatusAttributes, RuleLastRunAttributes, diff --git a/x-pack/plugins/alerting/server/data/rule/types/rule_attributes.ts b/x-pack/plugins/alerting/server/data/rule/types/rule_attributes.ts index 03ccf7c8a6b0d..aa8adda873cde 100644 --- a/x-pack/plugins/alerting/server/data/rule/types/rule_attributes.ts +++ b/x-pack/plugins/alerting/server/data/rule/types/rule_attributes.ts @@ -7,7 +7,6 @@ import type { SavedObjectAttributes } from '@kbn/core/server'; import { Filter } from '@kbn/es-query'; -import type { WeekdayStr } from '@kbn/rrule'; import { IsoWeekday } from '../../../../common'; import { ruleNotifyWhenAttributes, @@ -16,6 +15,7 @@ import { ruleExecutionStatusErrorReasonAttributes, ruleExecutionStatusWarningReasonAttributes, } from '../constants'; +import { RRuleAttributes } from '../../r_rule/types'; export type RuleNotifyWhenAttributes = typeof ruleNotifyWhenAttributes[keyof typeof ruleNotifyWhenAttributes]; @@ -28,27 +28,6 @@ export type RuleExecutionStatusErrorReasonAttributes = export type RuleExecutionStatusWarningReasonAttributes = typeof ruleExecutionStatusWarningReasonAttributes[keyof typeof ruleExecutionStatusWarningReasonAttributes]; -type RRuleFreq = 0 | 1 | 2 | 3 | 4 | 5 | 6; - -export interface RRuleAttributes { - dtstart: string; - tzid: string; - freq?: RRuleFreq; - until?: string; - count?: number; - interval?: number; - wkst?: WeekdayStr; - byweekday?: Array; - bymonth?: number[]; - bysetpos?: number[]; - bymonthday: number[]; - byyearday: number[]; - byweekno: number[]; - byhour: number[]; - byminute: number[]; - bysecond: number[]; -} - export interface RuleSnoozeScheduleAttributes { duration: number; rRule: RRuleAttributes; diff --git a/x-pack/plugins/alerting/server/maintenance_window_client/get_maintenance_window_from_raw.ts b/x-pack/plugins/alerting/server/maintenance_window_client/get_maintenance_window_from_raw.ts deleted file mode 100644 index 6f97bfbe7577a..0000000000000 --- a/x-pack/plugins/alerting/server/maintenance_window_client/get_maintenance_window_from_raw.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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 { MaintenanceWindowSOAttributes } from '../../common'; -import { getMaintenanceWindowDateAndStatus } from './get_maintenance_window_date_and_status'; - -export interface GetMaintenanceWindowFromRawParams { - id: string; - attributes: MaintenanceWindowSOAttributes; -} - -export const getMaintenanceWindowFromRaw = ({ - id, - attributes, -}: GetMaintenanceWindowFromRawParams) => { - const { events, expirationDate } = attributes; - const { eventStartTime, eventEndTime, status } = getMaintenanceWindowDateAndStatus({ - events, - expirationDate: new Date(expirationDate), - dateToCompare: new Date(), - }); - - return { - ...attributes, - id, - eventStartTime, - eventEndTime, - status, - }; -}; diff --git a/x-pack/plugins/alerting/server/maintenance_window_client/index.ts b/x-pack/plugins/alerting/server/maintenance_window_client/index.ts index 13f9f00d6e4da..0ff7fcf47be6b 100644 --- a/x-pack/plugins/alerting/server/maintenance_window_client/index.ts +++ b/x-pack/plugins/alerting/server/maintenance_window_client/index.ts @@ -6,4 +6,4 @@ */ export * from './maintenance_window_client'; -export * from './generate_maintenance_window_events'; +export * from '../application/maintenance_window/lib/generate_maintenance_window_events'; diff --git a/x-pack/plugins/alerting/server/maintenance_window_client/maintenance_window_client.ts b/x-pack/plugins/alerting/server/maintenance_window_client/maintenance_window_client.ts index 19b7fe8d862fc..2bbbacad73a9e 100644 --- a/x-pack/plugins/alerting/server/maintenance_window_client/maintenance_window_client.ts +++ b/x-pack/plugins/alerting/server/maintenance_window_client/maintenance_window_client.ts @@ -6,21 +6,31 @@ */ import { Logger, SavedObjectsClientContract } from '@kbn/core/server'; -import { create, CreateParams } from './methods/create'; -import { get, GetParams } from './methods/get'; -import { update, UpdateParams } from './methods/update'; -import { find, FindResult } from './methods/find'; -import { deleteMaintenanceWindow, DeleteParams } from './methods/delete'; -import { archive, ArchiveParams } from './methods/archive'; -import { getActiveMaintenanceWindows } from './methods/get_active_maintenance_windows'; -import { finish, FinishParams } from './methods/finish'; -import { bulkGet, BulkGetParams, BulkGetResult } from './methods/bulk_get'; - +import { createMaintenanceWindow } from '../application/maintenance_window/methods/create/create_maintenance_window'; +import type { CreateMaintenanceWindowParams } from '../application/maintenance_window/methods/create/types'; +import { getMaintenanceWindow } from '../application/maintenance_window/methods/get/get_maintenance_window'; +import type { GetMaintenanceWindowParams } from '../application/maintenance_window/methods/get/types'; +import { updateMaintenanceWindow } from '../application/maintenance_window/methods/update/update_maintenance_window'; +import type { UpdateMaintenanceWindowParams } from '../application/maintenance_window/methods/update/types'; +import { findMaintenanceWindows } from '../application/maintenance_window/methods/find/find_maintenance_windows'; +import type { FindMaintenanceWindowsResult } from '../application/maintenance_window/methods/find/types'; +import { deleteMaintenanceWindow } from '../application/maintenance_window/methods/delete/delete_maintenance_window'; +import type { DeleteMaintenanceWindowParams } from '../application/maintenance_window/methods/delete/types'; +import { archiveMaintenanceWindow } from '../application/maintenance_window/methods/archive/archive_maintenance_window'; +import type { ArchiveMaintenanceWindowParams } from '../application/maintenance_window/methods/archive/types'; +import { getActiveMaintenanceWindows } from '../application/maintenance_window/methods/get_active/get_active_maintenance_windows'; +import { finishMaintenanceWindow } from '../application/maintenance_window/methods/finish/finish_maintenance_window'; +import type { FinishMaintenanceWindowParams } from '../application/maintenance_window/methods/finish/types'; +import { bulkGetMaintenanceWindows } from '../application/maintenance_window/methods/bulk_get/bulk_get_maintenance_windows'; +import type { + BulkGetMaintenanceWindowsParams, + BulkGetMaintenanceWindowsResult, +} from '../application/maintenance_window/methods/bulk_get/types'; import { - MaintenanceWindow, MaintenanceWindowModificationMetadata, MaintenanceWindowClientContext, } from '../../common'; +import type { MaintenanceWindow } from '../application/maintenance_window/types'; export interface MaintenanceWindowClientConstructorOptions { readonly logger: Logger; @@ -57,19 +67,22 @@ export class MaintenanceWindowClient { }; } - public create = (params: CreateParams): Promise => - create(this.context, params); - public get = (params: GetParams): Promise => get(this.context, params); - public update = (params: UpdateParams): Promise => - update(this.context, params); - public find = (): Promise => find(this.context); - public delete = (params: DeleteParams): Promise<{}> => + public create = (params: CreateMaintenanceWindowParams): Promise => + createMaintenanceWindow(this.context, params); + public get = (params: GetMaintenanceWindowParams): Promise => + getMaintenanceWindow(this.context, params); + public update = (params: UpdateMaintenanceWindowParams): Promise => + updateMaintenanceWindow(this.context, params); + public find = (): Promise => findMaintenanceWindows(this.context); + public delete = (params: DeleteMaintenanceWindowParams): Promise<{}> => deleteMaintenanceWindow(this.context, params); - public archive = (params: ArchiveParams): Promise => - archive(this.context, params); - public finish = (params: FinishParams): Promise => - finish(this.context, params); - public bulkGet = (params: BulkGetParams): Promise => bulkGet(this.context, params); + public archive = (params: ArchiveMaintenanceWindowParams): Promise => + archiveMaintenanceWindow(this.context, params); + public finish = (params: FinishMaintenanceWindowParams): Promise => + finishMaintenanceWindow(this.context, params); + public bulkGet = ( + params: BulkGetMaintenanceWindowsParams + ): Promise => bulkGetMaintenanceWindows(this.context, params); public getActiveMaintenanceWindows = (): Promise => getActiveMaintenanceWindows(this.context); } diff --git a/x-pack/plugins/alerting/server/maintenance_window_client/methods/bulk_get.ts b/x-pack/plugins/alerting/server/maintenance_window_client/methods/bulk_get.ts deleted file mode 100644 index c87a62257827c..0000000000000 --- a/x-pack/plugins/alerting/server/maintenance_window_client/methods/bulk_get.ts +++ /dev/null @@ -1,76 +0,0 @@ -/* - * 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 Boom from '@hapi/boom'; -import { getMaintenanceWindowFromRaw } from '../get_maintenance_window_from_raw'; -import { - MaintenanceWindowSOAttributes, - MaintenanceWindow, - MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, - MaintenanceWindowClientContext, -} from '../../../common'; - -export interface BulkGetParams { - ids: string[]; -} - -export interface BulkGetMaintenanceWindowError { - id: string; - error: string; - message: string; - statusCode: number; -} - -export interface BulkGetResult { - maintenanceWindows: MaintenanceWindow[]; - errors: BulkGetMaintenanceWindowError[]; -} - -export async function bulkGet( - context: MaintenanceWindowClientContext, - params: BulkGetParams -): Promise { - const { savedObjectsClient, logger } = context; - const { ids } = params; - - const bulkGetObjects = ids.map((id) => ({ id, type: MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE })); - - try { - const { saved_objects: savedObjects } = - await savedObjectsClient.bulkGet(bulkGetObjects); - - const maintenanceWindows: MaintenanceWindow[] = []; - const errors: BulkGetMaintenanceWindowError[] = []; - - savedObjects.forEach((so) => { - if (so.error) { - errors.push({ - id: so.id, - error: so.error.error, - message: so.error.message, - statusCode: so.error.statusCode, - }); - } else { - maintenanceWindows.push( - getMaintenanceWindowFromRaw({ - id: so.id, - attributes: so.attributes, - }) - ); - } - }); - - return { - maintenanceWindows, - errors, - }; - } catch (e) { - const errorMessage = `Failed to bulk get maintenance window for ids: ${ids}, Error: ${e}`; - logger.error(errorMessage); - throw Boom.boomify(e, { message: errorMessage }); - } -} diff --git a/x-pack/plugins/alerting/server/maintenance_window_client/methods/create.ts b/x-pack/plugins/alerting/server/maintenance_window_client/methods/create.ts deleted file mode 100644 index 5586103ac9d2d..0000000000000 --- a/x-pack/plugins/alerting/server/maintenance_window_client/methods/create.ts +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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 moment from 'moment'; -import Boom from '@hapi/boom'; -import { SavedObjectsUtils } from '@kbn/core/server'; -import { getMaintenanceWindowFromRaw } from '../get_maintenance_window_from_raw'; -import { generateMaintenanceWindowEvents } from '../generate_maintenance_window_events'; -import { - MaintenanceWindowSOAttributes, - MaintenanceWindow, - MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, - RRuleParams, - MaintenanceWindowClientContext, -} from '../../../common'; - -export interface CreateParams { - title: string; - duration: number; - rRule: RRuleParams; -} - -export async function create( - context: MaintenanceWindowClientContext, - params: CreateParams -): Promise { - const { savedObjectsClient, getModificationMetadata, logger } = context; - const { title, duration, rRule } = params; - - const id = SavedObjectsUtils.generateId(); - const expirationDate = moment().utc().add(1, 'year').toISOString(); - const modificationMetadata = await getModificationMetadata(); - - try { - const events = generateMaintenanceWindowEvents({ rRule, expirationDate, duration }); - const result = await savedObjectsClient.create( - MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, - { - title, - enabled: true, - expirationDate, - rRule, - duration, - events, - ...modificationMetadata, - }, - { - id, - } - ); - return getMaintenanceWindowFromRaw({ - attributes: result.attributes, - id: result.id, - }); - } catch (e) { - const errorMessage = `Failed to create maintenance window, Error: ${e}`; - logger.error(errorMessage); - throw Boom.boomify(e, { message: errorMessage }); - } -} diff --git a/x-pack/plugins/alerting/server/maintenance_window_client/methods/get.ts b/x-pack/plugins/alerting/server/maintenance_window_client/methods/get.ts deleted file mode 100644 index 91bbd0a35ab6f..0000000000000 --- a/x-pack/plugins/alerting/server/maintenance_window_client/methods/get.ts +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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 Boom from '@hapi/boom'; -import { getMaintenanceWindowFromRaw } from '../get_maintenance_window_from_raw'; -import { - MaintenanceWindowSOAttributes, - MaintenanceWindow, - MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, - MaintenanceWindowClientContext, -} from '../../../common'; - -export interface GetParams { - id: string; -} - -export async function get( - context: MaintenanceWindowClientContext, - params: GetParams -): Promise { - const { savedObjectsClient, logger } = context; - const { id } = params; - try { - const result = await savedObjectsClient.get( - MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, - id - ); - - return getMaintenanceWindowFromRaw({ - attributes: result.attributes, - id: result.id, - }); - } catch (e) { - const errorMessage = `Failed to get maintenance window by id: ${id}, Error: ${e}`; - logger.error(errorMessage); - throw Boom.boomify(e, { message: errorMessage }); - } -} diff --git a/x-pack/plugins/alerting/server/maintenance_window_client/methods/update.ts b/x-pack/plugins/alerting/server/maintenance_window_client/methods/update.ts deleted file mode 100644 index e42ca980f1148..0000000000000 --- a/x-pack/plugins/alerting/server/maintenance_window_client/methods/update.ts +++ /dev/null @@ -1,114 +0,0 @@ -/* - * 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 moment from 'moment'; -import Boom from '@hapi/boom'; -import { getMaintenanceWindowFromRaw } from '../get_maintenance_window_from_raw'; -import { - generateMaintenanceWindowEvents, - shouldRegenerateEvents, - mergeEvents, -} from '../generate_maintenance_window_events'; -import { - MaintenanceWindow, - MaintenanceWindowSOAttributes, - MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, - RRuleParams, - MaintenanceWindowClientContext, -} from '../../../common'; -import { retryIfConflicts } from '../../lib/retry_if_conflicts'; - -export interface UpdateParams { - id: string; - title?: string; - enabled?: boolean; - duration?: number; - rRule?: RRuleParams; -} - -export async function update( - context: MaintenanceWindowClientContext, - params: UpdateParams -): Promise { - return await retryIfConflicts( - context.logger, - `maintenanceWindowClient.update('${params.id})`, - async () => { - return await updateWithOCC(context, params); - } - ); -} - -async function updateWithOCC( - context: MaintenanceWindowClientContext, - params: UpdateParams -): Promise { - const { savedObjectsClient, getModificationMetadata, logger } = context; - const { id, title, enabled, duration, rRule } = params; - - try { - const { - attributes, - id: fetchedId, - version, - } = await savedObjectsClient.get( - MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, - id - ); - - if (moment.utc(attributes.expirationDate).isBefore(new Date())) { - throw Boom.badRequest('Cannot edit archived maintenance windows'); - } - - const expirationDate = moment.utc().add(1, 'year').toISOString(); - const modificationMetadata = await getModificationMetadata(); - - let events = generateMaintenanceWindowEvents({ - rRule: rRule || attributes.rRule, - duration: typeof duration === 'number' ? duration : attributes.duration, - expirationDate, - }); - - if (!shouldRegenerateEvents({ maintenanceWindow: attributes, rRule, duration })) { - events = mergeEvents({ oldEvents: attributes.events, newEvents: events }); - } - - const updatedAttributes = { - ...attributes, - ...(title ? { title } : {}), - ...(rRule ? { rRule } : {}), - ...(typeof duration === 'number' ? { duration } : {}), - ...(typeof enabled === 'boolean' ? { enabled } : {}), - expirationDate, - events, - updatedBy: modificationMetadata.updatedBy, - updatedAt: modificationMetadata.updatedAt, - }; - - // We are deleting and then creating rather than updating because SO.update - // performs a partial update on the rRule, we would need to null out all of the fields - // that are removed from a new rRule if that were the case. - const result = await savedObjectsClient.create( - MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, - updatedAttributes, - { - id: fetchedId, - version, - overwrite: true, - } - ); - - return getMaintenanceWindowFromRaw({ - attributes: result.attributes, - id: result.id, - }); - } catch (e) { - const errorMessage = `Failed to update maintenance window by id: ${id}, Error: ${e}`; - logger.error(errorMessage); - throw Boom.boomify(e, { message: errorMessage }); - } -} diff --git a/x-pack/plugins/alerting/server/routes/index.ts b/x-pack/plugins/alerting/server/routes/index.ts index 1bffc87e7b60a..fe82abe56c4af 100644 --- a/x-pack/plugins/alerting/server/routes/index.ts +++ b/x-pack/plugins/alerting/server/routes/index.ts @@ -49,17 +49,17 @@ import { updateFlappingSettingsRoute } from './update_flapping_settings'; import { getRuleTagsRoute } from './get_rule_tags'; import { getScheduleFrequencyRoute } from './rule/apis/get_schedule_frequency'; -import { createMaintenanceWindowRoute } from './maintenance_window/create_maintenance_window'; -import { getMaintenanceWindowRoute } from './maintenance_window/get_maintenance_window'; -import { updateMaintenanceWindowRoute } from './maintenance_window/update_maintenance_window'; -import { deleteMaintenanceWindowRoute } from './maintenance_window/delete_maintenance_window'; -import { findMaintenanceWindowsRoute } from './maintenance_window/find_maintenance_windows'; -import { archiveMaintenanceWindowRoute } from './maintenance_window/archive_maintenance_window'; -import { finishMaintenanceWindowRoute } from './maintenance_window/finish_maintenance_window'; -import { activeMaintenanceWindowsRoute } from './maintenance_window/active_maintenance_windows'; +import { createMaintenanceWindowRoute } from './maintenance_window/apis/create/create_maintenance_window_route'; +import { getMaintenanceWindowRoute } from './maintenance_window/apis/get/get_maintenance_window_route'; +import { updateMaintenanceWindowRoute } from './maintenance_window/apis/update/update_maintenance_window_route'; +import { deleteMaintenanceWindowRoute } from './maintenance_window/apis/delete/delete_maintenance_window_route'; +import { findMaintenanceWindowsRoute } from './maintenance_window/apis/find/find_maintenance_windows_route'; +import { archiveMaintenanceWindowRoute } from './maintenance_window/apis/archive/archive_maintenance_window_route'; +import { finishMaintenanceWindowRoute } from './maintenance_window/apis/finish/finish_maintenance_window_route'; +import { getActiveMaintenanceWindowsRoute } from './maintenance_window/apis/get_active/get_active_maintenance_windows_route'; import { registerRulesValueSuggestionsRoute } from './suggestions/values_suggestion_rules'; import { registerFieldsRoute } from './suggestions/fields_rules'; -import { bulkGetMaintenanceWindowRoute } from './maintenance_window/bulk_get_maintenance_windows'; +import { bulkGetMaintenanceWindowRoute } from './maintenance_window/apis/bulk_get/bulk_get_maintenance_windows_route'; import { registerAlertsValueSuggestionsRoute } from './suggestions/values_suggestion_alerts'; export interface RouteOptions { @@ -125,7 +125,7 @@ export function defineRoutes(opts: RouteOptions) { findMaintenanceWindowsRoute(router, licenseState); archiveMaintenanceWindowRoute(router, licenseState); finishMaintenanceWindowRoute(router, licenseState); - activeMaintenanceWindowsRoute(router, licenseState); + getActiveMaintenanceWindowsRoute(router, licenseState); registerAlertsValueSuggestionsRoute(router, licenseState, config$!, getAlertIndicesAlias); registerRulesValueSuggestionsRoute(router, licenseState, config$!); registerFieldsRoute(router, licenseState); diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/archive_maintenance_window.test.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/archive/archive_maintenance_window_route.test.ts similarity index 86% rename from x-pack/plugins/alerting/server/routes/maintenance_window/archive_maintenance_window.test.ts rename to x-pack/plugins/alerting/server/routes/maintenance_window/apis/archive/archive_maintenance_window_route.test.ts index 0c3ec076167dd..040ba6e8ea9ab 100644 --- a/x-pack/plugins/alerting/server/routes/maintenance_window/archive_maintenance_window.test.ts +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/archive/archive_maintenance_window_route.test.ts @@ -6,18 +6,18 @@ */ import { httpServiceMock } from '@kbn/core/server/mocks'; -import { licenseStateMock } from '../../lib/license_state.mock'; -import { verifyApiAccess } from '../../lib/license_api_access'; -import { mockHandlerArguments } from '../_mock_handler_arguments'; -import { maintenanceWindowClientMock } from '../../maintenance_window_client.mock'; -import { archiveMaintenanceWindowRoute } from './archive_maintenance_window'; -import { getMockMaintenanceWindow } from '../../maintenance_window_client/methods/test_helpers'; -import { MaintenanceWindowStatus } from '../../../common'; -import { rewritePartialMaintenanceBodyRes } from '../lib'; +import { licenseStateMock } from '../../../../lib/license_state.mock'; +import { verifyApiAccess } from '../../../../lib/license_api_access'; +import { mockHandlerArguments } from '../../../_mock_handler_arguments'; +import { maintenanceWindowClientMock } from '../../../../maintenance_window_client.mock'; +import { archiveMaintenanceWindowRoute } from './archive_maintenance_window_route'; +import { getMockMaintenanceWindow } from '../../../../data/maintenance_window/test_helpers'; +import { MaintenanceWindowStatus } from '../../../../../common'; +import { rewritePartialMaintenanceBodyRes } from '../../../lib'; const maintenanceWindowClient = maintenanceWindowClientMock.create(); -jest.mock('../../lib/license_api_access', () => ({ +jest.mock('../../../../lib/license_api_access', () => ({ verifyApiAccess: jest.fn(), })); diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/apis/archive/archive_maintenance_window_route.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/archive/archive_maintenance_window_route.ts new file mode 100644 index 0000000000000..9f218220e6a92 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/archive/archive_maintenance_window_route.ts @@ -0,0 +1,63 @@ +/* + * 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 { IRouter } from '@kbn/core/server'; +import { ILicenseState } from '../../../../lib'; +import { verifyAccessAndContext } from '../../../lib'; +import { + AlertingRequestHandlerContext, + INTERNAL_ALERTING_API_MAINTENANCE_WINDOW_PATH, +} from '../../../../types'; +import { MAINTENANCE_WINDOW_API_PRIVILEGES } from '../../../../../common'; +import { MaintenanceWindow } from '../../../../application/maintenance_window/types'; +import { + archiveBodySchemaV1, + archiveParamsSchemaV1, + ArchiveMaintenanceWindowRequestBodyV1, + ArchiveMaintenanceWindowRequestParamsV1, + ArchiveMaintenanceWindowResponseV1, +} from '../../../../../common/routes/maintenance_window/apis/archive'; +import { transformMaintenanceWindowToResponseV1 } from '../../transforms'; + +export const archiveMaintenanceWindowRoute = ( + router: IRouter, + licenseState: ILicenseState +) => { + router.post( + { + path: `${INTERNAL_ALERTING_API_MAINTENANCE_WINDOW_PATH}/{id}/_archive`, + validate: { + params: archiveParamsSchemaV1, + body: archiveBodySchemaV1, + }, + options: { + tags: [`access:${MAINTENANCE_WINDOW_API_PRIVILEGES.WRITE_MAINTENANCE_WINDOW}`], + }, + }, + router.handleLegacyErrors( + verifyAccessAndContext(licenseState, async function (context, req, res) { + licenseState.ensureLicenseForMaintenanceWindow(); + + const params: ArchiveMaintenanceWindowRequestParamsV1 = req.params; + const body: ArchiveMaintenanceWindowRequestBodyV1 = req.body; + + const maintenanceWindowClient = (await context.alerting).getMaintenanceWindowClient(); + + const maintenanceWindow: MaintenanceWindow = await maintenanceWindowClient.archive({ + id: params.id, + archive: body.archive, + }); + + const response: ArchiveMaintenanceWindowResponseV1 = { + body: transformMaintenanceWindowToResponseV1(maintenanceWindow), + }; + + return res.ok(response); + }) + ) + ); +}; diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/bulk_get_maintenance_windows.test.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/bulk_get/bulk_get_maintenance_windows_route.test.ts similarity index 84% rename from x-pack/plugins/alerting/server/routes/maintenance_window/bulk_get_maintenance_windows.test.ts rename to x-pack/plugins/alerting/server/routes/maintenance_window/apis/bulk_get/bulk_get_maintenance_windows_route.test.ts index 50422e581aebd..c39fe061b69e5 100644 --- a/x-pack/plugins/alerting/server/routes/maintenance_window/bulk_get_maintenance_windows.test.ts +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/bulk_get/bulk_get_maintenance_windows_route.test.ts @@ -6,17 +6,18 @@ */ import { httpServiceMock } from '@kbn/core/server/mocks'; -import { licenseStateMock } from '../../lib/license_state.mock'; -import { verifyApiAccess } from '../../lib/license_api_access'; -import { mockHandlerArguments } from '../_mock_handler_arguments'; -import { maintenanceWindowClientMock } from '../../maintenance_window_client.mock'; -import { bulkGetMaintenanceWindowRoute, rewriteBodyResponse } from './bulk_get_maintenance_windows'; -import { getMockMaintenanceWindow } from '../../maintenance_window_client/methods/test_helpers'; -import { MaintenanceWindowStatus } from '../../../common'; +import { licenseStateMock } from '../../../../lib/license_state.mock'; +import { verifyApiAccess } from '../../../../lib/license_api_access'; +import { mockHandlerArguments } from '../../../_mock_handler_arguments'; +import { maintenanceWindowClientMock } from '../../../../maintenance_window_client.mock'; +import { bulkGetMaintenanceWindowRoute } from './bulk_get_maintenance_windows_route'; +import { getMockMaintenanceWindow } from '../../../../data/maintenance_window/test_helpers'; +import { MaintenanceWindowStatus } from '../../../../../common'; +import { transformBulkGetResultToResponseV1 } from './transforms'; const maintenanceWindowClient = maintenanceWindowClientMock.create(); -jest.mock('../../lib/license_api_access', () => ({ +jest.mock('../../../../lib/license_api_access', () => ({ verifyApiAccess: jest.fn(), })); @@ -75,7 +76,7 @@ describe('bulkGetMaintenanceWindowRoute', () => { ids: ['test-id-1', 'test-id-2', 'test-id-3'], }); expect(res.ok).toHaveBeenLastCalledWith({ - body: rewriteBodyResponse(mockBulkGetResponse), + body: transformBulkGetResultToResponseV1(mockBulkGetResponse), }); }); diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/bulk_get_maintenance_windows.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/bulk_get/bulk_get_maintenance_windows_route.ts similarity index 51% rename from x-pack/plugins/alerting/server/routes/maintenance_window/bulk_get_maintenance_windows.ts rename to x-pack/plugins/alerting/server/routes/maintenance_window/apis/bulk_get/bulk_get_maintenance_windows_route.ts index 77916fb4d44f3..fd77b52e0c04f 100644 --- a/x-pack/plugins/alerting/server/routes/maintenance_window/bulk_get_maintenance_windows.ts +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/bulk_get/bulk_get_maintenance_windows_route.ts @@ -6,29 +6,20 @@ */ import { IRouter } from '@kbn/core/server'; -import { schema } from '@kbn/config-schema'; -import { ILicenseState } from '../../lib'; -import { verifyAccessAndContext, rewriteMaintenanceWindowRes, RewriteResponseCase } from '../lib'; +import { ILicenseState } from '../../../../lib'; +import { verifyAccessAndContext } from '../../../lib'; import { AlertingRequestHandlerContext, INTERNAL_ALERTING_API_MAINTENANCE_WINDOW_PATH, -} from '../../types'; -import { MAINTENANCE_WINDOW_API_PRIVILEGES } from '../../../common'; -import { BulkGetResult } from '../../maintenance_window_client/methods/bulk_get'; - -const bodySchema = schema.object({ - ids: schema.arrayOf(schema.string()), -}); - -export const rewriteBodyResponse: RewriteResponseCase = (result: BulkGetResult) => ({ - maintenance_windows: result.maintenanceWindows.map((mw) => rewriteMaintenanceWindowRes(mw)), - errors: result.errors.map((error) => ({ - id: error.id, - error: error.error, - message: error.message, - status_code: error.statusCode, - })), -}); +} from '../../../../types'; +import { MAINTENANCE_WINDOW_API_PRIVILEGES } from '../../../../../common'; +import { BulkGetMaintenanceWindowsResult } from '../../../../application/maintenance_window/methods/bulk_get/types'; +import { + bulkGetBodySchemaV1, + BulkGetMaintenanceWindowsRequestBodyV1, + BulkGetMaintenanceWindowsResponseV1, +} from '../../../../../common/routes/maintenance_window/apis/bulk_get'; +import { transformBulkGetResultToResponseV1 } from './transforms'; export const bulkGetMaintenanceWindowRoute = ( router: IRouter, @@ -38,7 +29,7 @@ export const bulkGetMaintenanceWindowRoute = ( { path: `${INTERNAL_ALERTING_API_MAINTENANCE_WINDOW_PATH}/_bulk_get`, validate: { - body: bodySchema, + body: bulkGetBodySchemaV1, }, options: { tags: [`access:${MAINTENANCE_WINDOW_API_PRIVILEGES.READ_MAINTENANCE_WINDOW}`], @@ -48,13 +39,19 @@ export const bulkGetMaintenanceWindowRoute = ( verifyAccessAndContext(licenseState, async function (context, req, res) { licenseState.ensureLicenseForMaintenanceWindow(); + const body: BulkGetMaintenanceWindowsRequestBodyV1 = req.body; + const maintenanceWindowClient = (await context.alerting).getMaintenanceWindowClient(); - const { ids } = req.body; - const result = await maintenanceWindowClient.bulkGet({ ids }); - return res.ok({ - body: rewriteBodyResponse(result), + const result: BulkGetMaintenanceWindowsResult = await maintenanceWindowClient.bulkGet({ + ids: body.ids, }); + + const response: BulkGetMaintenanceWindowsResponseV1 = { + body: transformBulkGetResultToResponseV1(result), + }; + + return res.ok(response); }) ) ); diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/apis/bulk_get/transforms/index.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/bulk_get/transforms/index.ts new file mode 100644 index 0000000000000..430c2f6b93f83 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/bulk_get/transforms/index.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { transformBulkGetResultToResponse } from './transform_bulk_get_response/latest'; + +export { transformBulkGetResultToResponse as transformBulkGetResultToResponseV1 } from './transform_bulk_get_response/v1'; diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/apis/bulk_get/transforms/transform_bulk_get_response/latest.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/bulk_get/transforms/transform_bulk_get_response/latest.ts new file mode 100644 index 0000000000000..46b64fd03d6e2 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/bulk_get/transforms/transform_bulk_get_response/latest.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { transformBulkGetResultToResponse } from './v1'; diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/apis/bulk_get/transforms/transform_bulk_get_response/v1.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/bulk_get/transforms/transform_bulk_get_response/v1.ts new file mode 100644 index 0000000000000..5e791e0d917e9 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/bulk_get/transforms/transform_bulk_get_response/v1.ts @@ -0,0 +1,28 @@ +/* + * 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 { BulkGetMaintenanceWindowsResponseBodyV1 } from '../../../../../../../common/routes/maintenance_window/apis/bulk_get'; +import { BulkGetMaintenanceWindowsResult } from '../../../../../../application/maintenance_window/methods/bulk_get/types'; +import { transformMaintenanceWindowToResponseV1 } from '../../../../transforms'; + +export const transformBulkGetResultToResponse = ( + result: BulkGetMaintenanceWindowsResult +): BulkGetMaintenanceWindowsResponseBodyV1 => { + return { + maintenance_windows: result.maintenanceWindows.map((mw) => { + return transformMaintenanceWindowToResponseV1(mw); + }), + errors: result.errors.map((error) => { + return { + id: error.id, + error: error.error, + message: error.message, + status_code: error.statusCode, + }; + }), + }; +}; diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/create_maintenance_window.test.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/create/create_maintenance_window_route.test.ts similarity index 75% rename from x-pack/plugins/alerting/server/routes/maintenance_window/create_maintenance_window.test.ts rename to x-pack/plugins/alerting/server/routes/maintenance_window/apis/create/create_maintenance_window_route.test.ts index adf365f409d9b..f019f8a04b76e 100644 --- a/x-pack/plugins/alerting/server/routes/maintenance_window/create_maintenance_window.test.ts +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/create/create_maintenance_window_route.test.ts @@ -6,18 +6,22 @@ */ import { httpServiceMock } from '@kbn/core/server/mocks'; -import { licenseStateMock } from '../../lib/license_state.mock'; -import { verifyApiAccess } from '../../lib/license_api_access'; -import { mockHandlerArguments } from '../_mock_handler_arguments'; -import { maintenanceWindowClientMock } from '../../maintenance_window_client.mock'; -import { createMaintenanceWindowRoute, rewriteQueryReq } from './create_maintenance_window'; -import { getMockMaintenanceWindow } from '../../maintenance_window_client/methods/test_helpers'; -import { MaintenanceWindowStatus } from '../../../common'; -import { rewritePartialMaintenanceBodyRes } from '../lib'; +import { licenseStateMock } from '../../../../lib/license_state.mock'; +import { verifyApiAccess } from '../../../../lib/license_api_access'; +import { mockHandlerArguments } from '../../../_mock_handler_arguments'; +import { maintenanceWindowClientMock } from '../../../../maintenance_window_client.mock'; +import { createMaintenanceWindowRoute } from './create_maintenance_window_route'; +import { getMockMaintenanceWindow } from '../../../../data/maintenance_window/test_helpers'; +import { MaintenanceWindowStatus } from '../../../../../common'; + +import { MaintenanceWindow } from '../../../../application/maintenance_window/types'; +import { CreateMaintenanceWindowRequestBody } from '../../../../../common/routes/maintenance_window/apis/create'; +import { transformCreateBody } from './transforms'; +import { transformMaintenanceWindowToResponse } from '../../transforms'; const maintenanceWindowClient = maintenanceWindowClientMock.create(); -jest.mock('../../lib/license_api_access', () => ({ +jest.mock('../../../../lib/license_api_access', () => ({ verifyApiAccess: jest.fn(), })); @@ -27,13 +31,13 @@ const mockMaintenanceWindow = { eventEndTime: new Date().toISOString(), status: MaintenanceWindowStatus.Running, id: 'test-id', -}; +} as MaintenanceWindow; const createParams = { title: 'test-title', duration: 1000, r_rule: mockMaintenanceWindow.rRule, -}; +} as CreateMaintenanceWindowRequestBody; describe('createMaintenanceWindowRoute', () => { beforeEach(() => { @@ -58,9 +62,11 @@ describe('createMaintenanceWindowRoute', () => { await handler(context, req, res); - expect(maintenanceWindowClient.create).toHaveBeenLastCalledWith(rewriteQueryReq(createParams)); + expect(maintenanceWindowClient.create).toHaveBeenLastCalledWith({ + data: transformCreateBody(createParams), + }); expect(res.ok).toHaveBeenLastCalledWith({ - body: rewritePartialMaintenanceBodyRes(mockMaintenanceWindow), + body: transformMaintenanceWindowToResponse(mockMaintenanceWindow), }); }); diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/create_maintenance_window.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/create/create_maintenance_window_route.ts similarity index 51% rename from x-pack/plugins/alerting/server/routes/maintenance_window/create_maintenance_window.ts rename to x-pack/plugins/alerting/server/routes/maintenance_window/apis/create/create_maintenance_window_route.ts index 311383e7957f7..1bbc6e311068c 100644 --- a/x-pack/plugins/alerting/server/routes/maintenance_window/create_maintenance_window.ts +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/create/create_maintenance_window_route.ts @@ -6,33 +6,21 @@ */ import { IRouter } from '@kbn/core/server'; -import { schema } from '@kbn/config-schema'; -import { ILicenseState } from '../../lib'; -import { - verifyAccessAndContext, - rRuleSchema, - RewriteRequestCase, - rewriteMaintenanceWindowRes, -} from '../lib'; +import { ILicenseState } from '../../../../lib'; +import { verifyAccessAndContext } from '../../../lib'; import { AlertingRequestHandlerContext, INTERNAL_ALERTING_API_MAINTENANCE_WINDOW_PATH, -} from '../../types'; -import { MaintenanceWindowCreateBody, MAINTENANCE_WINDOW_API_PRIVILEGES } from '../../../common'; - -const bodySchema = schema.object({ - title: schema.string(), - duration: schema.number(), - r_rule: rRuleSchema, -}); - -export const rewriteQueryReq: RewriteRequestCase = ({ - r_rule: rRule, - ...rest -}) => ({ - ...rest, - rRule, -}); +} from '../../../../types'; +import { MAINTENANCE_WINDOW_API_PRIVILEGES } from '../../../../../common'; +import { MaintenanceWindow } from '../../../../application/maintenance_window/types'; +import { + createBodySchemaV1, + CreateMaintenanceWindowRequestBodyV1, + CreateMaintenanceWindowResponseV1, +} from '../../../../../common/routes/maintenance_window/apis/create'; +import { transformCreateBodyV1 } from './transforms'; +import { transformMaintenanceWindowToResponseV1 } from '../../transforms'; export const createMaintenanceWindowRoute = ( router: IRouter, @@ -42,7 +30,7 @@ export const createMaintenanceWindowRoute = ( { path: INTERNAL_ALERTING_API_MAINTENANCE_WINDOW_PATH, validate: { - body: bodySchema, + body: createBodySchemaV1, }, options: { tags: [`access:${MAINTENANCE_WINDOW_API_PRIVILEGES.WRITE_MAINTENANCE_WINDOW}`], @@ -52,11 +40,19 @@ export const createMaintenanceWindowRoute = ( verifyAccessAndContext(licenseState, async function (context, req, res) { licenseState.ensureLicenseForMaintenanceWindow(); + const body: CreateMaintenanceWindowRequestBodyV1 = req.body; + const maintenanceWindowClient = (await context.alerting).getMaintenanceWindowClient(); - const maintenanceWindow = await maintenanceWindowClient.create(rewriteQueryReq(req.body)); - return res.ok({ - body: rewriteMaintenanceWindowRes(maintenanceWindow), + + const maintenanceWindow: MaintenanceWindow = await maintenanceWindowClient.create({ + data: transformCreateBodyV1(body), }); + + const response: CreateMaintenanceWindowResponseV1 = { + body: transformMaintenanceWindowToResponseV1(maintenanceWindow), + }; + + return res.ok(response); }) ) ); diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/apis/create/transforms/index.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/create/transforms/index.ts new file mode 100644 index 0000000000000..acd4b6fde493c --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/create/transforms/index.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { transformCreateBody } from './transform_create_body/latest'; + +export { transformCreateBody as transformCreateBodyV1 } from './transform_create_body/v1'; diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/apis/create/transforms/transform_create_body/latest.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/create/transforms/transform_create_body/latest.ts new file mode 100644 index 0000000000000..84b3dac9e7737 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/create/transforms/transform_create_body/latest.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { transformCreateBody } from './v1'; diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/apis/create/transforms/transform_create_body/v1.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/create/transforms/transform_create_body/v1.ts new file mode 100644 index 0000000000000..290f29d90849f --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/create/transforms/transform_create_body/v1.ts @@ -0,0 +1,19 @@ +/* + * 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 { CreateMaintenanceWindowRequestBodyV1 } from '../../../../../../../common/routes/maintenance_window/apis/create'; +import { CreateMaintenanceWindowParams } from '../../../../../../application/maintenance_window/methods/create/types'; + +export const transformCreateBody = ( + createBody: CreateMaintenanceWindowRequestBodyV1 +): CreateMaintenanceWindowParams['data'] => { + return { + title: createBody.title, + duration: createBody.duration, + rRule: createBody.r_rule, + }; +}; diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/delete_maintenance_window.test.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/delete/delete_maintenance_window_route.test.ts similarity index 86% rename from x-pack/plugins/alerting/server/routes/maintenance_window/delete_maintenance_window.test.ts rename to x-pack/plugins/alerting/server/routes/maintenance_window/apis/delete/delete_maintenance_window_route.test.ts index 2c356c65d65ec..7ac0db328cf9d 100644 --- a/x-pack/plugins/alerting/server/routes/maintenance_window/delete_maintenance_window.test.ts +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/delete/delete_maintenance_window_route.test.ts @@ -6,17 +6,17 @@ */ import { httpServiceMock } from '@kbn/core/server/mocks'; -import { licenseStateMock } from '../../lib/license_state.mock'; -import { verifyApiAccess } from '../../lib/license_api_access'; -import { mockHandlerArguments } from '../_mock_handler_arguments'; -import { maintenanceWindowClientMock } from '../../maintenance_window_client.mock'; -import { deleteMaintenanceWindowRoute } from './delete_maintenance_window'; -import { getMockMaintenanceWindow } from '../../maintenance_window_client/methods/test_helpers'; -import { MaintenanceWindowStatus } from '../../../common'; +import { licenseStateMock } from '../../../../lib/license_state.mock'; +import { verifyApiAccess } from '../../../../lib/license_api_access'; +import { mockHandlerArguments } from '../../../_mock_handler_arguments'; +import { maintenanceWindowClientMock } from '../../../../maintenance_window_client.mock'; +import { deleteMaintenanceWindowRoute } from './delete_maintenance_window_route'; +import { getMockMaintenanceWindow } from '../../../../data/maintenance_window/test_helpers'; +import { MaintenanceWindowStatus } from '../../../../../common'; const maintenanceWindowClient = maintenanceWindowClientMock.create(); -jest.mock('../../lib/license_api_access', () => ({ +jest.mock('../../../../lib/license_api_access', () => ({ verifyApiAccess: jest.fn(), })); diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/delete_maintenance_window.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/delete/delete_maintenance_window_route.ts similarity index 67% rename from x-pack/plugins/alerting/server/routes/maintenance_window/delete_maintenance_window.ts rename to x-pack/plugins/alerting/server/routes/maintenance_window/apis/delete/delete_maintenance_window_route.ts index ca2a166f1ab57..9abc9872b9b37 100644 --- a/x-pack/plugins/alerting/server/routes/maintenance_window/delete_maintenance_window.ts +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/delete/delete_maintenance_window_route.ts @@ -6,18 +6,18 @@ */ import { IRouter } from '@kbn/core/server'; -import { schema } from '@kbn/config-schema'; -import { ILicenseState } from '../../lib'; -import { verifyAccessAndContext } from '../lib'; +import { ILicenseState } from '../../../../lib'; +import { verifyAccessAndContext } from '../../../lib'; import { AlertingRequestHandlerContext, INTERNAL_ALERTING_API_MAINTENANCE_WINDOW_PATH, -} from '../../types'; -import { MAINTENANCE_WINDOW_API_PRIVILEGES } from '../../../common'; +} from '../../../../types'; +import { MAINTENANCE_WINDOW_API_PRIVILEGES } from '../../../../../common'; -const paramSchema = schema.object({ - id: schema.string(), -}); +import { + deleteParamsSchemaV1, + DeleteMaintenanceWindowRequestParamsV1, +} from '../../../../../common/routes/maintenance_window/apis/delete'; export const deleteMaintenanceWindowRoute = ( router: IRouter, @@ -27,7 +27,7 @@ export const deleteMaintenanceWindowRoute = ( { path: `${INTERNAL_ALERTING_API_MAINTENANCE_WINDOW_PATH}/{id}`, validate: { - params: paramSchema, + params: deleteParamsSchemaV1, }, options: { tags: [`access:${MAINTENANCE_WINDOW_API_PRIVILEGES.WRITE_MAINTENANCE_WINDOW}`], @@ -37,9 +37,12 @@ export const deleteMaintenanceWindowRoute = ( verifyAccessAndContext(licenseState, async function (context, req, res) { licenseState.ensureLicenseForMaintenanceWindow(); + const params: DeleteMaintenanceWindowRequestParamsV1 = req.params; + const maintenanceWindowClient = (await context.alerting).getMaintenanceWindowClient(); - const { id } = req.params; - await maintenanceWindowClient.delete({ id }); + + await maintenanceWindowClient.delete({ id: params.id }); + return res.noContent(); }) ) diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/find_maintenance_windows.test.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/find/find_maintenance_windows_route.test.ts similarity index 86% rename from x-pack/plugins/alerting/server/routes/maintenance_window/find_maintenance_windows.test.ts rename to x-pack/plugins/alerting/server/routes/maintenance_window/apis/find/find_maintenance_windows_route.test.ts index ed1562ce726df..a9a7d22e20751 100644 --- a/x-pack/plugins/alerting/server/routes/maintenance_window/find_maintenance_windows.test.ts +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/find/find_maintenance_windows_route.test.ts @@ -6,18 +6,18 @@ */ import { httpServiceMock } from '@kbn/core/server/mocks'; -import { licenseStateMock } from '../../lib/license_state.mock'; -import { verifyApiAccess } from '../../lib/license_api_access'; -import { mockHandlerArguments } from '../_mock_handler_arguments'; -import { maintenanceWindowClientMock } from '../../maintenance_window_client.mock'; -import { findMaintenanceWindowsRoute } from './find_maintenance_windows'; -import { getMockMaintenanceWindow } from '../../maintenance_window_client/methods/test_helpers'; -import { MaintenanceWindowStatus } from '../../../common'; -import { rewriteMaintenanceWindowRes } from '../lib'; +import { licenseStateMock } from '../../../../lib/license_state.mock'; +import { verifyApiAccess } from '../../../../lib/license_api_access'; +import { mockHandlerArguments } from '../../../_mock_handler_arguments'; +import { maintenanceWindowClientMock } from '../../../../maintenance_window_client.mock'; +import { findMaintenanceWindowsRoute } from './find_maintenance_windows_route'; +import { getMockMaintenanceWindow } from '../../../../data/maintenance_window/test_helpers'; +import { MaintenanceWindowStatus } from '../../../../../common'; +import { rewriteMaintenanceWindowRes } from '../../../lib'; const maintenanceWindowClient = maintenanceWindowClientMock.create(); -jest.mock('../../lib/license_api_access', () => ({ +jest.mock('../../../../lib/license_api_access', () => ({ verifyApiAccess: jest.fn(), })); diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/find_maintenance_windows.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/find/find_maintenance_windows_route.ts similarity index 60% rename from x-pack/plugins/alerting/server/routes/maintenance_window/find_maintenance_windows.ts rename to x-pack/plugins/alerting/server/routes/maintenance_window/apis/find/find_maintenance_windows_route.ts index 0e1b615e939c0..4baf6032e4222 100644 --- a/x-pack/plugins/alerting/server/routes/maintenance_window/find_maintenance_windows.ts +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/find/find_maintenance_windows_route.ts @@ -6,13 +6,16 @@ */ import { IRouter } from '@kbn/core/server'; -import { ILicenseState } from '../../lib'; -import { verifyAccessAndContext, rewriteMaintenanceWindowRes } from '../lib'; +import { ILicenseState } from '../../../../lib'; +import { verifyAccessAndContext } from '../../../lib'; import { AlertingRequestHandlerContext, INTERNAL_ALERTING_API_MAINTENANCE_WINDOW_PATH, -} from '../../types'; -import { MAINTENANCE_WINDOW_API_PRIVILEGES } from '../../../common'; +} from '../../../../types'; +import { MAINTENANCE_WINDOW_API_PRIVILEGES } from '../../../../../common'; +import type { FindMaintenanceWindowsResult } from '../../../../application/maintenance_window/methods/find/types'; +import type { FindMaintenanceWindowsResponseV1 } from '../../../../../common/routes/maintenance_window/apis/find'; +import { transformMaintenanceWindowToResponseV1 } from '../../transforms'; export const findMaintenanceWindowsRoute = ( router: IRouter, @@ -31,16 +34,19 @@ export const findMaintenanceWindowsRoute = ( licenseState.ensureLicenseForMaintenanceWindow(); const maintenanceWindowClient = (await context.alerting).getMaintenanceWindowClient(); - const result = await maintenanceWindowClient.find(); - return res.ok({ + const result: FindMaintenanceWindowsResult = await maintenanceWindowClient.find(); + + const response: FindMaintenanceWindowsResponseV1 = { body: { data: result.data.map((maintenanceWindow) => - rewriteMaintenanceWindowRes(maintenanceWindow) + transformMaintenanceWindowToResponseV1(maintenanceWindow) ), total: result.data.length, }, - }); + }; + + return res.ok(response); }) ) ); diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/finish_maintenance_window.test.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/finish/finish_maintenance_window_route.test.ts similarity index 85% rename from x-pack/plugins/alerting/server/routes/maintenance_window/finish_maintenance_window.test.ts rename to x-pack/plugins/alerting/server/routes/maintenance_window/apis/finish/finish_maintenance_window_route.test.ts index a115e7d47d628..e7ec470839fe9 100644 --- a/x-pack/plugins/alerting/server/routes/maintenance_window/finish_maintenance_window.test.ts +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/finish/finish_maintenance_window_route.test.ts @@ -6,18 +6,18 @@ */ import { httpServiceMock } from '@kbn/core/server/mocks'; -import { licenseStateMock } from '../../lib/license_state.mock'; -import { verifyApiAccess } from '../../lib/license_api_access'; -import { mockHandlerArguments } from '../_mock_handler_arguments'; -import { maintenanceWindowClientMock } from '../../maintenance_window_client.mock'; -import { finishMaintenanceWindowRoute } from './finish_maintenance_window'; -import { getMockMaintenanceWindow } from '../../maintenance_window_client/methods/test_helpers'; -import { MaintenanceWindowStatus } from '../../../common'; -import { rewritePartialMaintenanceBodyRes } from '../lib'; +import { licenseStateMock } from '../../../../lib/license_state.mock'; +import { verifyApiAccess } from '../../../../lib/license_api_access'; +import { mockHandlerArguments } from '../../../_mock_handler_arguments'; +import { maintenanceWindowClientMock } from '../../../../maintenance_window_client.mock'; +import { finishMaintenanceWindowRoute } from './finish_maintenance_window_route'; +import { getMockMaintenanceWindow } from '../../../../data/maintenance_window/test_helpers'; +import { MaintenanceWindowStatus } from '../../../../../common'; +import { rewritePartialMaintenanceBodyRes } from '../../../lib'; const maintenanceWindowClient = maintenanceWindowClientMock.create(); -jest.mock('../../lib/license_api_access', () => ({ +jest.mock('../../../../lib/license_api_access', () => ({ verifyApiAccess: jest.fn(), })); diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/finish_maintenance_window.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/finish/finish_maintenance_window_route.ts similarity index 52% rename from x-pack/plugins/alerting/server/routes/maintenance_window/finish_maintenance_window.ts rename to x-pack/plugins/alerting/server/routes/maintenance_window/apis/finish/finish_maintenance_window_route.ts index 0c9cd8e058ec9..fe1310734d424 100644 --- a/x-pack/plugins/alerting/server/routes/maintenance_window/finish_maintenance_window.ts +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/finish/finish_maintenance_window_route.ts @@ -6,18 +6,20 @@ */ import { IRouter } from '@kbn/core/server'; -import { schema } from '@kbn/config-schema'; -import { ILicenseState } from '../../lib'; -import { verifyAccessAndContext, rewritePartialMaintenanceBodyRes } from '../lib'; +import { ILicenseState } from '../../../../lib'; +import { verifyAccessAndContext } from '../../../lib'; import { AlertingRequestHandlerContext, INTERNAL_ALERTING_API_MAINTENANCE_WINDOW_PATH, -} from '../../types'; -import { MAINTENANCE_WINDOW_API_PRIVILEGES } from '../../../common'; - -const paramSchema = schema.object({ - id: schema.string(), -}); +} from '../../../../types'; +import { MaintenanceWindow } from '../../../../application/maintenance_window/types'; +import { + finishParamsSchemaV1, + FinishMaintenanceWindowRequestParamsV1, + FinishMaintenanceWindowResponseV1, +} from '../../../../../common/routes/maintenance_window/apis/finish'; +import { MAINTENANCE_WINDOW_API_PRIVILEGES } from '../../../../../common'; +import { transformMaintenanceWindowToResponseV1 } from '../../transforms'; export const finishMaintenanceWindowRoute = ( router: IRouter, @@ -27,7 +29,7 @@ export const finishMaintenanceWindowRoute = ( { path: `${INTERNAL_ALERTING_API_MAINTENANCE_WINDOW_PATH}/{id}/_finish`, validate: { - params: paramSchema, + params: finishParamsSchemaV1, }, options: { tags: [`access:${MAINTENANCE_WINDOW_API_PRIVILEGES.WRITE_MAINTENANCE_WINDOW}`], @@ -37,11 +39,19 @@ export const finishMaintenanceWindowRoute = ( verifyAccessAndContext(licenseState, async function (context, req, res) { licenseState.ensureLicenseForMaintenanceWindow(); + const params: FinishMaintenanceWindowRequestParamsV1 = req.params; + const maintenanceWindowClient = (await context.alerting).getMaintenanceWindowClient(); - const maintenanceWindow = await maintenanceWindowClient.finish(req.params); - return res.ok({ - body: rewritePartialMaintenanceBodyRes(maintenanceWindow), + + const maintenanceWindow: MaintenanceWindow = await maintenanceWindowClient.finish({ + id: params.id, }); + + const response: FinishMaintenanceWindowResponseV1 = { + body: transformMaintenanceWindowToResponseV1(maintenanceWindow), + }; + + return res.ok(response); }) ) ); diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/get_maintenance_window.test.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/get/get_maintenance_window_route.test.ts similarity index 85% rename from x-pack/plugins/alerting/server/routes/maintenance_window/get_maintenance_window.test.ts rename to x-pack/plugins/alerting/server/routes/maintenance_window/apis/get/get_maintenance_window_route.test.ts index a2691939d00e5..9e17aed88eaf0 100644 --- a/x-pack/plugins/alerting/server/routes/maintenance_window/get_maintenance_window.test.ts +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/get/get_maintenance_window_route.test.ts @@ -6,18 +6,18 @@ */ import { httpServiceMock } from '@kbn/core/server/mocks'; -import { licenseStateMock } from '../../lib/license_state.mock'; -import { verifyApiAccess } from '../../lib/license_api_access'; -import { mockHandlerArguments } from '../_mock_handler_arguments'; -import { maintenanceWindowClientMock } from '../../maintenance_window_client.mock'; -import { getMaintenanceWindowRoute } from './get_maintenance_window'; -import { getMockMaintenanceWindow } from '../../maintenance_window_client/methods/test_helpers'; -import { MaintenanceWindowStatus } from '../../../common'; -import { rewritePartialMaintenanceBodyRes } from '../lib'; +import { licenseStateMock } from '../../../../lib/license_state.mock'; +import { verifyApiAccess } from '../../../../lib/license_api_access'; +import { mockHandlerArguments } from '../../../_mock_handler_arguments'; +import { maintenanceWindowClientMock } from '../../../../maintenance_window_client.mock'; +import { getMaintenanceWindowRoute } from './get_maintenance_window_route'; +import { getMockMaintenanceWindow } from '../../../../data/maintenance_window/test_helpers'; +import { MaintenanceWindowStatus } from '../../../../../common'; +import { rewritePartialMaintenanceBodyRes } from '../../../lib'; const maintenanceWindowClient = maintenanceWindowClientMock.create(); -jest.mock('../../lib/license_api_access', () => ({ +jest.mock('../../../../lib/license_api_access', () => ({ verifyApiAccess: jest.fn(), })); diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/get_maintenance_window.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/get/get_maintenance_window_route.ts similarity index 52% rename from x-pack/plugins/alerting/server/routes/maintenance_window/get_maintenance_window.ts rename to x-pack/plugins/alerting/server/routes/maintenance_window/apis/get/get_maintenance_window_route.ts index 9dfe599855f62..2b842f3ad0449 100644 --- a/x-pack/plugins/alerting/server/routes/maintenance_window/get_maintenance_window.ts +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/get/get_maintenance_window_route.ts @@ -6,18 +6,20 @@ */ import { IRouter } from '@kbn/core/server'; -import { schema } from '@kbn/config-schema'; -import { ILicenseState } from '../../lib'; -import { verifyAccessAndContext, rewriteMaintenanceWindowRes } from '../lib'; +import { ILicenseState } from '../../../../lib'; +import { verifyAccessAndContext } from '../../../lib'; import { AlertingRequestHandlerContext, INTERNAL_ALERTING_API_MAINTENANCE_WINDOW_PATH, -} from '../../types'; -import { MAINTENANCE_WINDOW_API_PRIVILEGES } from '../../../common'; - -const paramSchema = schema.object({ - id: schema.string(), -}); +} from '../../../../types'; +import { MAINTENANCE_WINDOW_API_PRIVILEGES } from '../../../../../common'; +import { MaintenanceWindow } from '../../../../application/maintenance_window/types'; +import { + getParamsSchemaV1, + GetMaintenanceWindowRequestParamsV1, + GetMaintenanceWindowResponseV1, +} from '../../../../../common/routes/maintenance_window/apis/get'; +import { transformMaintenanceWindowToResponseV1 } from '../../transforms'; export const getMaintenanceWindowRoute = ( router: IRouter, @@ -27,7 +29,7 @@ export const getMaintenanceWindowRoute = ( { path: `${INTERNAL_ALERTING_API_MAINTENANCE_WINDOW_PATH}/{id}`, validate: { - params: paramSchema, + params: getParamsSchemaV1, }, options: { tags: [`access:${MAINTENANCE_WINDOW_API_PRIVILEGES.READ_MAINTENANCE_WINDOW}`], @@ -38,11 +40,17 @@ export const getMaintenanceWindowRoute = ( licenseState.ensureLicenseForMaintenanceWindow(); const maintenanceWindowClient = (await context.alerting).getMaintenanceWindowClient(); - const { id } = req.params; - const maintenanceWindow = await maintenanceWindowClient.get({ id }); - return res.ok({ - body: rewriteMaintenanceWindowRes(maintenanceWindow), + + const params: GetMaintenanceWindowRequestParamsV1 = req.params; + + const maintenanceWindow: MaintenanceWindow = await maintenanceWindowClient.get({ + id: params.id, }); + + const response: GetMaintenanceWindowResponseV1 = { + body: transformMaintenanceWindowToResponseV1(maintenanceWindow), + }; + return res.ok(response); }) ) ); diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/active_maintenance_windows.test.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/get_active/get_active_maintenance_windows_route.test.ts similarity index 78% rename from x-pack/plugins/alerting/server/routes/maintenance_window/active_maintenance_windows.test.ts rename to x-pack/plugins/alerting/server/routes/maintenance_window/apis/get_active/get_active_maintenance_windows_route.test.ts index 868f1542561e4..c9f9fa2841374 100644 --- a/x-pack/plugins/alerting/server/routes/maintenance_window/active_maintenance_windows.test.ts +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/get_active/get_active_maintenance_windows_route.test.ts @@ -6,18 +6,18 @@ */ import { httpServiceMock } from '@kbn/core/server/mocks'; -import { licenseStateMock } from '../../lib/license_state.mock'; -import { verifyApiAccess } from '../../lib/license_api_access'; -import { mockHandlerArguments } from '../_mock_handler_arguments'; -import { maintenanceWindowClientMock } from '../../maintenance_window_client.mock'; -import { activeMaintenanceWindowsRoute } from './active_maintenance_windows'; -import { getMockMaintenanceWindow } from '../../maintenance_window_client/methods/test_helpers'; -import { MaintenanceWindowStatus } from '../../../common'; -import { rewriteMaintenanceWindowRes } from '../lib'; +import { licenseStateMock } from '../../../../lib/license_state.mock'; +import { verifyApiAccess } from '../../../../lib/license_api_access'; +import { mockHandlerArguments } from '../../../_mock_handler_arguments'; +import { maintenanceWindowClientMock } from '../../../../maintenance_window_client.mock'; +import { getActiveMaintenanceWindowsRoute } from './get_active_maintenance_windows_route'; +import { getMockMaintenanceWindow } from '../../../../data/maintenance_window/test_helpers'; +import { MaintenanceWindowStatus } from '../../../../../common'; +import { rewriteMaintenanceWindowRes } from '../../../lib'; const maintenanceWindowClient = maintenanceWindowClientMock.create(); -jest.mock('../../lib/license_api_access', () => ({ +jest.mock('../../../../lib/license_api_access', () => ({ verifyApiAccess: jest.fn(), })); @@ -38,7 +38,7 @@ const mockMaintenanceWindows = [ }, ]; -describe('activeMaintenanceWindowsRoute', () => { +describe('getActiveMaintenanceWindowsRoute', () => { beforeEach(() => { jest.resetAllMocks(); }); @@ -47,7 +47,7 @@ describe('activeMaintenanceWindowsRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - activeMaintenanceWindowsRoute(router, licenseState); + getActiveMaintenanceWindowsRoute(router, licenseState); maintenanceWindowClient.getActiveMaintenanceWindows.mockResolvedValueOnce( mockMaintenanceWindows @@ -70,7 +70,7 @@ describe('activeMaintenanceWindowsRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - activeMaintenanceWindowsRoute(router, licenseState); + getActiveMaintenanceWindowsRoute(router, licenseState); maintenanceWindowClient.getActiveMaintenanceWindows.mockResolvedValueOnce( mockMaintenanceWindows @@ -85,7 +85,7 @@ describe('activeMaintenanceWindowsRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - activeMaintenanceWindowsRoute(router, licenseState); + getActiveMaintenanceWindowsRoute(router, licenseState); (verifyApiAccess as jest.Mock).mockImplementation(() => { throw new Error('Failure'); @@ -99,7 +99,7 @@ describe('activeMaintenanceWindowsRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - activeMaintenanceWindowsRoute(router, licenseState); + getActiveMaintenanceWindowsRoute(router, licenseState); (licenseState.ensureLicenseForMaintenanceWindow as jest.Mock).mockImplementation(() => { throw new Error('Failure'); diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/active_maintenance_windows.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/get_active/get_active_maintenance_windows_route.ts similarity index 58% rename from x-pack/plugins/alerting/server/routes/maintenance_window/active_maintenance_windows.ts rename to x-pack/plugins/alerting/server/routes/maintenance_window/apis/get_active/get_active_maintenance_windows_route.ts index c2a8d6c761d63..e7c70d23a5132 100644 --- a/x-pack/plugins/alerting/server/routes/maintenance_window/active_maintenance_windows.ts +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/get_active/get_active_maintenance_windows_route.ts @@ -6,15 +6,19 @@ */ import { IRouter } from '@kbn/core/server'; -import { ILicenseState } from '../../lib'; -import { verifyAccessAndContext, rewriteMaintenanceWindowRes } from '../lib'; +import { ILicenseState } from '../../../../lib'; +import { verifyAccessAndContext } from '../../../lib'; import { AlertingRequestHandlerContext, INTERNAL_ALERTING_API_GET_ACTIVE_MAINTENANCE_WINDOWS_PATH, -} from '../../types'; -import { MAINTENANCE_WINDOW_API_PRIVILEGES } from '../../../common'; +} from '../../../../types'; +import { MAINTENANCE_WINDOW_API_PRIVILEGES } from '../../../../../common'; -export const activeMaintenanceWindowsRoute = ( +import { MaintenanceWindow } from '../../../../application/maintenance_window/types'; +import { GetActiveMaintenanceWindowsResponseV1 } from '../../../../../common/routes/maintenance_window/apis/get_active'; +import { transformMaintenanceWindowToResponseV1 } from '../../transforms'; + +export const getActiveMaintenanceWindowsRoute = ( router: IRouter, licenseState: ILicenseState ) => { @@ -39,11 +43,16 @@ export const activeMaintenanceWindowsRoute = ( }); } const maintenanceWindowClient = (await context.alerting).getMaintenanceWindowClient(); - const result = await maintenanceWindowClient.getActiveMaintenanceWindows(); + const maintenanceWindows: MaintenanceWindow[] = + await maintenanceWindowClient.getActiveMaintenanceWindows(); + + const response: GetActiveMaintenanceWindowsResponseV1 = { + body: maintenanceWindows.map((maintenanceWindow) => + transformMaintenanceWindowToResponseV1(maintenanceWindow) + ), + }; - return res.ok({ - body: result.map((maintenanceWindow) => rewriteMaintenanceWindowRes(maintenanceWindow)), - }); + return res.ok(response); }) ) ); diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/apis/update/transforms/index.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/update/transforms/index.ts new file mode 100644 index 0000000000000..975b9236bd5b6 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/update/transforms/index.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { transformUpdateBody } from './transform_update_body/latest'; + +export { transformUpdateBody as transformUpdateBodyV1 } from './transform_update_body/v1'; diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/apis/update/transforms/transform_update_body/latest.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/update/transforms/transform_update_body/latest.ts new file mode 100644 index 0000000000000..880fa5f920551 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/update/transforms/transform_update_body/latest.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { transformUpdateBody } from './v1'; diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/apis/update/transforms/transform_update_body/v1.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/update/transforms/transform_update_body/v1.ts new file mode 100644 index 0000000000000..5e6ac58bb16f3 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/update/transforms/transform_update_body/v1.ts @@ -0,0 +1,21 @@ +/* + * 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 { UpdateMaintenanceWindowRequestBodyV1 } from '../../../../../../../common/routes/maintenance_window/apis/update'; +import { UpdateMaintenanceWindowParams } from '../../../../../../application/maintenance_window/methods/update/types'; + +export const transformUpdateBody = ( + updateBody: UpdateMaintenanceWindowRequestBodyV1 +): UpdateMaintenanceWindowParams['data'] => { + const { title, enabled, duration, r_rule: rRule } = updateBody; + return { + ...(title !== undefined ? { title } : {}), + ...(enabled !== undefined ? { enabled } : {}), + ...(duration !== undefined ? { duration } : {}), + ...(rRule !== undefined ? { rRule } : {}), + }; +}; diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/update_maintenance_window.test.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/update/update_maintenance_window_route.test.ts similarity index 83% rename from x-pack/plugins/alerting/server/routes/maintenance_window/update_maintenance_window.test.ts rename to x-pack/plugins/alerting/server/routes/maintenance_window/apis/update/update_maintenance_window_route.test.ts index a7793c4995890..40c6da84c551c 100644 --- a/x-pack/plugins/alerting/server/routes/maintenance_window/update_maintenance_window.test.ts +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/update/update_maintenance_window_route.test.ts @@ -4,20 +4,20 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { Frequency } from '@kbn/rrule'; import { httpServiceMock } from '@kbn/core/server/mocks'; -import { licenseStateMock } from '../../lib/license_state.mock'; -import { verifyApiAccess } from '../../lib/license_api_access'; -import { mockHandlerArguments } from '../_mock_handler_arguments'; -import { maintenanceWindowClientMock } from '../../maintenance_window_client.mock'; -import { updateMaintenanceWindowRoute, rewriteQueryReq } from './update_maintenance_window'; -import { getMockMaintenanceWindow } from '../../maintenance_window_client/methods/test_helpers'; -import { MaintenanceWindowStatus } from '../../../common'; -import { rewritePartialMaintenanceBodyRes } from '../lib'; +import { licenseStateMock } from '../../../../lib/license_state.mock'; +import { verifyApiAccess } from '../../../../lib/license_api_access'; +import { mockHandlerArguments } from '../../../_mock_handler_arguments'; +import { maintenanceWindowClientMock } from '../../../../maintenance_window_client.mock'; +import { updateMaintenanceWindowRoute } from './update_maintenance_window_route'; +import { getMockMaintenanceWindow } from '../../../../data/maintenance_window/test_helpers'; +import { MaintenanceWindowStatus } from '../../../../../common'; +import { transformUpdateBody } from './transforms'; +import { rewritePartialMaintenanceBodyRes } from '../../../lib'; const maintenanceWindowClient = maintenanceWindowClientMock.create(); -jest.mock('../../lib/license_api_access', () => ({ +jest.mock('../../../../lib/license_api_access', () => ({ verifyApiAccess: jest.fn(), })); @@ -36,7 +36,7 @@ const updateParams = { r_rule: { tzid: 'CET', dtstart: '2023-03-26T00:00:00.000Z', - freq: Frequency.WEEKLY, + freq: 2 as const, count: 10, }, }; @@ -69,7 +69,7 @@ describe('updateMaintenanceWindowRoute', () => { expect(maintenanceWindowClient.update).toHaveBeenLastCalledWith({ id: 'test-id', - ...rewriteQueryReq(updateParams), + data: transformUpdateBody(updateParams), }); expect(res.ok).toHaveBeenLastCalledWith({ diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/apis/update/update_maintenance_window_route.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/update/update_maintenance_window_route.ts new file mode 100644 index 0000000000000..82f116e3ab8d7 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/update/update_maintenance_window_route.ts @@ -0,0 +1,65 @@ +/* + * 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 { IRouter } from '@kbn/core/server'; +import { ILicenseState } from '../../../../lib'; +import { verifyAccessAndContext } from '../../../lib'; +import { + AlertingRequestHandlerContext, + INTERNAL_ALERTING_API_MAINTENANCE_WINDOW_PATH, +} from '../../../../types'; +import { MAINTENANCE_WINDOW_API_PRIVILEGES } from '../../../../../common'; +import { MaintenanceWindow } from '../../../../application/maintenance_window/types'; +import { + updateBodySchemaV1, + updateParamsSchemaV1, + UpdateMaintenanceWindowRequestBodyV1, + UpdateMaintenanceWindowRequestParamsV1, + UpdateMaintenanceWindowResponseV1, +} from '../../../../../common/routes/maintenance_window/apis/update'; +import { transformUpdateBodyV1 } from './transforms'; +import { transformMaintenanceWindowToResponseV1 } from '../../transforms'; + +export const updateMaintenanceWindowRoute = ( + router: IRouter, + licenseState: ILicenseState +) => { + router.post( + { + path: `${INTERNAL_ALERTING_API_MAINTENANCE_WINDOW_PATH}/{id}`, + validate: { + body: updateBodySchemaV1, + params: updateParamsSchemaV1, + }, + options: { + tags: [`access:${MAINTENANCE_WINDOW_API_PRIVILEGES.WRITE_MAINTENANCE_WINDOW}`], + }, + }, + router.handleLegacyErrors( + verifyAccessAndContext(licenseState, async function (context, req, res) { + licenseState.ensureLicenseForMaintenanceWindow(); + + const body: UpdateMaintenanceWindowRequestBodyV1 = req.body; + + const params: UpdateMaintenanceWindowRequestParamsV1 = req.params; + + const maintenanceWindowClient = (await context.alerting).getMaintenanceWindowClient(); + + const maintenanceWindow: MaintenanceWindow = await maintenanceWindowClient.update({ + id: params.id, + data: transformUpdateBodyV1(body), + }); + + const response: UpdateMaintenanceWindowResponseV1 = { + body: transformMaintenanceWindowToResponseV1(maintenanceWindow), + }; + + return res.ok(response); + }) + ) + ); +}; diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/archive_maintenance_window.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/archive_maintenance_window.ts deleted file mode 100644 index 5aafa10862688..0000000000000 --- a/x-pack/plugins/alerting/server/routes/maintenance_window/archive_maintenance_window.ts +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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 { IRouter } from '@kbn/core/server'; -import { schema } from '@kbn/config-schema'; -import { ILicenseState } from '../../lib'; -import { verifyAccessAndContext, rewritePartialMaintenanceBodyRes } from '../lib'; -import { - AlertingRequestHandlerContext, - INTERNAL_ALERTING_API_MAINTENANCE_WINDOW_PATH, -} from '../../types'; -import { MAINTENANCE_WINDOW_API_PRIVILEGES } from '../../../common'; - -const paramSchema = schema.object({ - id: schema.string(), -}); - -const bodySchema = schema.object({ - archive: schema.boolean(), -}); - -export const archiveMaintenanceWindowRoute = ( - router: IRouter, - licenseState: ILicenseState -) => { - router.post( - { - path: `${INTERNAL_ALERTING_API_MAINTENANCE_WINDOW_PATH}/{id}/_archive`, - validate: { - params: paramSchema, - body: bodySchema, - }, - options: { - tags: [`access:${MAINTENANCE_WINDOW_API_PRIVILEGES.WRITE_MAINTENANCE_WINDOW}`], - }, - }, - router.handleLegacyErrors( - verifyAccessAndContext(licenseState, async function (context, req, res) { - licenseState.ensureLicenseForMaintenanceWindow(); - - const maintenanceWindowClient = (await context.alerting).getMaintenanceWindowClient(); - const { id } = req.params; - const { archive } = req.body; - const maintenanceWindow = await maintenanceWindowClient.archive({ - id, - archive, - }); - return res.ok({ - body: rewritePartialMaintenanceBodyRes(maintenanceWindow), - }); - }) - ) - ); -}; diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/transforms/index.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/transforms/index.ts new file mode 100644 index 0000000000000..040c4daabcd84 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/transforms/index.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { transformMaintenanceWindowToResponse } from './transform_maintenance_window_to_response/latest'; + +export { transformMaintenanceWindowToResponse as transformMaintenanceWindowToResponseV1 } from './transform_maintenance_window_to_response/v1'; diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/transforms/transform_maintenance_window_to_response/latest.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/transforms/transform_maintenance_window_to_response/latest.ts new file mode 100644 index 0000000000000..3308f4fb4751d --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/transforms/transform_maintenance_window_to_response/latest.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { transformMaintenanceWindowToResponse } from './v1'; diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/transforms/transform_maintenance_window_to_response/v1.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/transforms/transform_maintenance_window_to_response/v1.ts new file mode 100644 index 0000000000000..cfa091a25dda1 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/transforms/transform_maintenance_window_to_response/v1.ts @@ -0,0 +1,30 @@ +/* + * 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 { MaintenanceWindowResponseV1 } from '../../../../../common/routes/maintenance_window/response'; +import { MaintenanceWindow } from '../../../../application/maintenance_window/types'; + +export const transformMaintenanceWindowToResponse = ( + maintenanceWindow: MaintenanceWindow +): MaintenanceWindowResponseV1 => { + return { + id: maintenanceWindow.id, + title: maintenanceWindow.title, + enabled: maintenanceWindow.enabled, + duration: maintenanceWindow.duration, + expiration_date: maintenanceWindow.expirationDate, + events: maintenanceWindow.events, + r_rule: maintenanceWindow.rRule, + created_by: maintenanceWindow.createdBy, + updated_by: maintenanceWindow.updatedBy, + created_at: maintenanceWindow.createdAt, + updated_at: maintenanceWindow.updatedAt, + event_start_time: maintenanceWindow.eventStartTime, + event_end_time: maintenanceWindow.eventEndTime, + status: maintenanceWindow.status, + }; +}; diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/update_maintenance_window.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/update_maintenance_window.ts deleted file mode 100644 index 46d9c70cc9ab3..0000000000000 --- a/x-pack/plugins/alerting/server/routes/maintenance_window/update_maintenance_window.ts +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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 { IRouter } from '@kbn/core/server'; -import { schema } from '@kbn/config-schema'; -import { ILicenseState } from '../../lib'; -import { - verifyAccessAndContext, - rRuleSchema, - RewriteRequestCase, - rewritePartialMaintenanceBodyRes, -} from '../lib'; -import { - AlertingRequestHandlerContext, - INTERNAL_ALERTING_API_MAINTENANCE_WINDOW_PATH, -} from '../../types'; -import { MaintenanceWindowSOProperties, MAINTENANCE_WINDOW_API_PRIVILEGES } from '../../../common'; - -const paramSchema = schema.object({ - id: schema.string(), -}); - -const bodySchema = schema.object({ - title: schema.maybe(schema.string()), - enabled: schema.maybe(schema.boolean()), - duration: schema.maybe(schema.number()), - r_rule: schema.maybe(rRuleSchema), -}); - -interface MaintenanceWindowUpdateBody { - title?: MaintenanceWindowSOProperties['title']; - enabled?: MaintenanceWindowSOProperties['enabled']; - duration?: MaintenanceWindowSOProperties['duration']; - rRule?: MaintenanceWindowSOProperties['rRule']; -} - -export const rewriteQueryReq: RewriteRequestCase = ({ - r_rule: rRule, - ...rest -}) => ({ - ...rest, - ...(rRule ? { rRule } : {}), -}); - -export const updateMaintenanceWindowRoute = ( - router: IRouter, - licenseState: ILicenseState -) => { - router.post( - { - path: `${INTERNAL_ALERTING_API_MAINTENANCE_WINDOW_PATH}/{id}`, - validate: { - body: bodySchema, - params: paramSchema, - }, - options: { - tags: [`access:${MAINTENANCE_WINDOW_API_PRIVILEGES.WRITE_MAINTENANCE_WINDOW}`], - }, - }, - router.handleLegacyErrors( - verifyAccessAndContext(licenseState, async function (context, req, res) { - licenseState.ensureLicenseForMaintenanceWindow(); - - const maintenanceWindowClient = (await context.alerting).getMaintenanceWindowClient(); - const maintenanceWindow = await maintenanceWindowClient.update({ - id: req.params.id, - ...rewriteQueryReq(req.body), - }); - return res.ok({ - body: rewritePartialMaintenanceBodyRes(maintenanceWindow), - }); - }) - ) - ); -}; diff --git a/x-pack/plugins/alerting/server/task_runner/task_runner.test.ts b/x-pack/plugins/alerting/server/task_runner/task_runner.test.ts index c0d8a1434aa3d..382e0f3e608c7 100644 --- a/x-pack/plugins/alerting/server/task_runner/task_runner.test.ts +++ b/x-pack/plugins/alerting/server/task_runner/task_runner.test.ts @@ -16,7 +16,6 @@ import { RuleExecutionStatusWarningReasons, Rule, RuleAction, - MaintenanceWindow, RuleAlertData, } from '../types'; import { ConcreteTaskInstance, isUnrecoverableError } from '@kbn/task-manager-plugin/server'; @@ -80,8 +79,9 @@ import { DataViewsServerPluginStart } from '@kbn/data-views-plugin/server'; import { rulesSettingsClientMock } from '../rules_settings_client.mock'; import { maintenanceWindowClientMock } from '../maintenance_window_client.mock'; import { alertsServiceMock } from '../alerts_service/alerts_service.mock'; -import { getMockMaintenanceWindow } from '../maintenance_window_client/methods/test_helpers'; +import { getMockMaintenanceWindow } from '../data/maintenance_window/test_helpers'; import { alertsClientMock } from '../alerts_client/alerts_client.mock'; +import { MaintenanceWindow } from '../application/maintenance_window/types'; jest.mock('uuid', () => ({ v4: () => '5f6aa57d-3e22-484e-bae8-cbed868f4d28', diff --git a/x-pack/plugins/alerting/server/task_runner/task_runner.ts b/x-pack/plugins/alerting/server/task_runner/task_runner.ts index 6d3be52cf2e62..cc019b46cec51 100644 --- a/x-pack/plugins/alerting/server/task_runner/task_runner.ts +++ b/x-pack/plugins/alerting/server/task_runner/task_runner.ts @@ -47,7 +47,6 @@ import { parseDuration, RawAlertInstance, RuleLastRunOutcomeOrderMap, - MaintenanceWindow, RuleAlertData, SanitizedRule, RuleNotifyWhen, @@ -80,6 +79,7 @@ import { RunningHandler } from './running_handler'; import { RuleResultService } from '../monitoring/rule_result_service'; import { LegacyAlertsClient } from '../alerts_client'; import { IAlertsClient } from '../alerts_client/types'; +import { MaintenanceWindow } from '../application/maintenance_window/types'; const FALLBACK_RETRY_INTERVAL = '5m'; const CONNECTIVITY_RETRY_INTERVAL = '5m'; diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/extend_index_management.test.tsx b/x-pack/plugins/index_lifecycle_management/__jest__/extend_index_management.test.tsx index 565a994e4e186..be64e1a4674aa 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/extend_index_management.test.tsx +++ b/x-pack/plugins/index_lifecycle_management/__jest__/extend_index_management.test.tsx @@ -17,10 +17,11 @@ import { addLifecyclePolicyActionExtension, ilmBannerExtension, ilmFilterExtension, - ilmSummaryExtension, } from '../public/extend_index_management'; import { init as initHttp } from '../public/application/services/http'; import { init as initUiMetric } from '../public/application/services/ui_metric'; +import { IndexLifecycleSummary } from '../public/extend_index_management/components/index_lifecycle_summary'; +import React from 'react'; const { httpSetup } = init(); @@ -243,20 +244,26 @@ describe('extend index management', () => { describe('ilm summary extension', () => { test('should render null when index has no index lifecycle policy', () => { - const extension = ilmSummaryExtension(indexWithoutLifecyclePolicy, getUrlForApp); + const extension = ( + + ); const rendered = mountWithIntl(extension); expect(rendered.isEmptyRender()).toBeTruthy(); }); test('should return extension when index has lifecycle policy', () => { - const extension = ilmSummaryExtension(indexWithLifecyclePolicy, getUrlForApp); + const extension = ( + + ); expect(extension).toBeDefined(); const rendered = mountWithIntl(extension); expect(rendered.render()).toMatchSnapshot(); }); test('should return extension when index has lifecycle error', () => { - const extension = ilmSummaryExtension(indexWithLifecycleError, getUrlForApp); + const extension = ( + + ); expect(extension).toBeDefined(); const rendered = mountWithIntl(extension); expect(rendered.render()).toMatchSnapshot(); diff --git a/x-pack/plugins/index_lifecycle_management/public/extend_index_management/components/index_lifecycle_summary.tsx b/x-pack/plugins/index_lifecycle_management/public/extend_index_management/components/index_lifecycle_summary.tsx index 91b9203bea1aa..f1468117dc53c 100644 --- a/x-pack/plugins/index_lifecycle_management/public/extend_index_management/components/index_lifecycle_summary.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/extend_index_management/components/index_lifecycle_summary.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { Component, Fragment } from 'react'; +import React, { FunctionComponent, Fragment, useState } from 'react'; import moment from 'moment-timezone'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -82,34 +82,20 @@ interface Props { index: Index; getUrlForApp: ApplicationStart['getUrlForApp']; } -interface State { - showStackPopover: boolean; - showPhaseExecutionPopover: boolean; -} -export class IndexLifecycleSummary extends Component { - constructor(props: Props) { - super(props); - this.state = { - showStackPopover: false, - showPhaseExecutionPopover: false, - }; - } - toggleStackPopover = () => { - this.setState({ showStackPopover: !this.state.showStackPopover }); - }; - closeStackPopover = () => { - this.setState({ showStackPopover: false }); - }; - togglePhaseExecutionPopover = () => { - this.setState({ showPhaseExecutionPopover: !this.state.showPhaseExecutionPopover }); +export const IndexLifecycleSummary: FunctionComponent = ({ index, getUrlForApp }) => { + const [showPhaseExecutionPopover, setShowPhaseExecutionPopover] = useState(false); + const { ilm } = index; + + const togglePhaseExecutionPopover = () => { + setShowPhaseExecutionPopover(!showPhaseExecutionPopover); }; - closePhaseExecutionPopover = () => { - this.setState({ showPhaseExecutionPopover: false }); + const closePhaseExecutionPopover = () => { + setShowPhaseExecutionPopover(false); }; - renderPhaseExecutionPopoverButton(ilm: IndexLifecyclePolicy) { + const renderPhaseExecutionPopoverButton = () => { const button = ( - + { key="phaseExecutionPopover" id="phaseExecutionPopover" button={button} - isOpen={this.state.showPhaseExecutionPopover} - closePopover={this.closePhaseExecutionPopover} + isOpen={showPhaseExecutionPopover} + closePopover={closePhaseExecutionPopover} > { ); - } - buildRows() { - const { - index: { ilm }, - } = this.props; + }; + const buildRows = () => { const headers = getHeaders(); const rows: { left: JSX.Element[]; @@ -168,7 +151,7 @@ export class IndexLifecycleSummary extends Component { } else if (fieldName === 'policy') { content = ( @@ -196,72 +179,67 @@ export class IndexLifecycleSummary extends Component { } }); if (ilm.phase_execution) { - rows.right.push(this.renderPhaseExecutionPopoverButton(ilm)); + rows.right.push(renderPhaseExecutionPopoverButton()); } return rows; - } + }; - render() { - const { - index: { ilm }, - } = this.props; - if (!ilm.managed) { - return null; - } - const { left, right } = this.buildRows(); - return ( - <> - -

- -

-
- {ilm.step_info && ilm.step_info.type ? ( - <> - - - } - iconType="cross" - > - {ilm.step_info.type}: {ilm.step_info.reason} - - - ) : null} - {ilm.step_info && ilm.step_info!.message ? ( - <> - - - } - > - {ilm.step_info!.message} - - - ) : null} - - - - {left} - - - {right} - - - - ); + if (!ilm.managed) { + return null; } -} + const { left, right } = buildRows(); + return ( + <> + +

+ +

+
+ {ilm.step_info && ilm.step_info.type ? ( + <> + + + } + iconType="cross" + > + {ilm.step_info.type}: {ilm.step_info.reason} + + + ) : null} + {ilm.step_info && ilm.step_info!.message ? ( + <> + + + } + > + {ilm.step_info!.message} + + + ) : null} + + + + {left} + + + {right} + + + + ); +}; diff --git a/x-pack/plugins/index_lifecycle_management/public/extend_index_management/index.tsx b/x-pack/plugins/index_lifecycle_management/public/extend_index_management/index.tsx index 57434c71f1045..9d3d14f11e685 100644 --- a/x-pack/plugins/index_lifecycle_management/public/extend_index_management/index.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/extend_index_management/index.tsx @@ -144,13 +144,6 @@ export const ilmBannerExtension = (indices: Index[]) => { }; }; -export const ilmSummaryExtension = ( - index: Index, - getUrlForApp: ApplicationStart['getUrlForApp'] -) => { - return ; -}; - export const ilmFilterExtension = (indices: Index[]) => { const hasIlm = some(indices, (index) => index.ilm && index.ilm.managed); if (!hasIlm) { @@ -231,6 +224,6 @@ export const addAllExtensions = ( extensionsService.addAction(addLifecyclePolicyActionExtension); extensionsService.addBanner(ilmBannerExtension); - extensionsService.addSummary(ilmSummaryExtension); + extensionsService.addSummary(IndexLifecycleSummary); extensionsService.addFilter(ilmFilterExtension); }; diff --git a/x-pack/plugins/index_management/__jest__/client_integration/index_details_page/index_details_page.helpers.ts b/x-pack/plugins/index_management/__jest__/client_integration/index_details_page/index_details_page.helpers.ts index 24cf015e3918d..9c7e3e1efbe4a 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/index_details_page/index_details_page.helpers.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/index_details_page/index_details_page.helpers.ts @@ -80,6 +80,7 @@ export interface IndexDetailsPageTestBed extends TestBed { indexStatsContentExists: () => boolean; indexDetailsContentExists: () => boolean; addDocCodeBlockExists: () => boolean; + extensionSummaryExists: (index: number) => boolean; }; }; } @@ -131,6 +132,9 @@ export const setup = async ( addDocCodeBlockExists: () => { return exists('codeBlockControlsPanel'); }, + extensionSummaryExists: (index: number) => { + return exists(`extensionsSummary-${index}`); + }, }; const mappings = { diff --git a/x-pack/plugins/index_management/__jest__/client_integration/index_details_page/index_details_page.test.tsx b/x-pack/plugins/index_management/__jest__/client_integration/index_details_page/index_details_page.test.tsx index 31680f9f860b9..99ec128d9cc67 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/index_details_page/index_details_page.test.tsx +++ b/x-pack/plugins/index_management/__jest__/client_integration/index_details_page/index_details_page.test.tsx @@ -222,6 +222,51 @@ describe('', () => { expect(testBed.actions.overview.indexDetailsContentExists()).toBe(true); expect(testBed.actions.overview.indexStatsContentExists()).toBe(false); }); + + describe('extension service summary', () => { + it('renders all summaries added to the extension service', async () => { + await act(async () => { + testBed = await setup(httpSetup, { + services: { + extensionsService: { + summaries: [() => test, () => test2], + }, + }, + }); + }); + testBed.component.update(); + expect(testBed.actions.overview.extensionSummaryExists(0)).toBe(true); + expect(testBed.actions.overview.extensionSummaryExists(1)).toBe(true); + }); + + it(`doesn't render empty panels if the summary renders null`, async () => { + await act(async () => { + testBed = await setup(httpSetup, { + services: { + extensionsService: { + summaries: [() => null], + }, + }, + }); + }); + testBed.component.update(); + expect(testBed.actions.overview.extensionSummaryExists(0)).toBe(false); + }); + + it(`doesn't render anything when no summaries added to the extension service`, async () => { + await act(async () => { + testBed = await setup(httpSetup, { + services: { + extensionsService: { + summaries: [], + }, + }, + }); + }); + testBed.component.update(); + expect(testBed.actions.overview.extensionSummaryExists(0)).toBe(false); + }); + }); }); it('documents tab', async () => { diff --git a/x-pack/plugins/index_management/public/application/sections/home/index_list/detail_panel/summary/summary.js b/x-pack/plugins/index_management/public/application/sections/home/index_list/detail_panel/summary/summary.js index e41769daacbd5..7e680bbfe5bde 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/index_list/detail_panel/summary/summary.js +++ b/x-pack/plugins/index_management/public/application/sections/home/index_list/detail_panel/summary/summary.js @@ -65,10 +65,11 @@ export class Summary extends React.PureComponent { const { index } = this.props; const extensions = extensionsService.summaries; return extensions.map((summaryExtension, i) => { + const ExtensionSummaryComponent = summaryExtension; return ( - {summaryExtension(index, getUrlForApp)} + ); }); diff --git a/x-pack/plugins/index_management/public/application/sections/home/index_list/details_page/details_page_overview/details_page_overview.tsx b/x-pack/plugins/index_management/public/application/sections/home/index_list/details_page/details_page_overview/details_page_overview.tsx index 712d6d9f19b7e..0ed7bc8e4ab9c 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/index_list/details_page/details_page_overview/details_page_overview.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/index_list/details_page/details_page_overview/details_page_overview.tsx @@ -28,6 +28,7 @@ import type { Index } from '../../../../../../../common'; import { useAppContext } from '../../../../../app_context'; import { breadcrumbService, IndexManagementBreadcrumb } from '../../../../../services/breadcrumbs'; import { languageDefinitions, curlDefinition } from './languages'; +import { ExtensionsSummary } from './extensions_summary'; interface Props { indexDetails: Index; @@ -157,6 +158,8 @@ export const DetailsPageOverview: React.FunctionComponent = ({ indexDetai + + diff --git a/x-pack/plugins/index_management/public/application/sections/home/index_list/details_page/details_page_overview/extensions_summary.tsx b/x-pack/plugins/index_management/public/application/sections/home/index_list/details_page/details_page_overview/extensions_summary.tsx new file mode 100644 index 0000000000000..3788988ec72aa --- /dev/null +++ b/x-pack/plugins/index_management/public/application/sections/home/index_list/details_page/details_page_overview/extensions_summary.tsx @@ -0,0 +1,32 @@ +/* + * 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 React, { Fragment, FunctionComponent } from 'react'; +import { EuiPanel, EuiSpacer } from '@elastic/eui'; +import { Index } from '../../../../../../../common'; +import { useAppContext } from '../../../../../app_context'; + +export const ExtensionsSummary: FunctionComponent<{ index: Index }> = ({ index }) => { + const { + services: { extensionsService }, + core: { getUrlForApp }, + } = useAppContext(); + const summaries = extensionsService.summaries.map((summaryExtension, i) => { + const summary = summaryExtension({ index, getUrlForApp }); + + if (!summary) { + return null; + } + return ( + + {summary} + + + ); + }); + return <>{summaries}; +}; diff --git a/x-pack/plugins/ml/public/application/model_management/test_models/models/index_input.tsx b/x-pack/plugins/ml/public/application/model_management/test_models/models/index_input.tsx index c80a84c5e1f4a..03466cd87a16b 100644 --- a/x-pack/plugins/ml/public/application/model_management/test_models/models/index_input.tsx +++ b/x-pack/plugins/ml/public/application/model_management/test_models/models/index_input.tsx @@ -111,15 +111,34 @@ export function useIndexInput({ inferrer }: { inferrer: InferrerType }) { ); useEffect( function loadDataViewListItems() { - dataViews.getIdsWithTitle().then((items) => { + async function getFilteredDataViewListItems() { + const dataViewIds = await dataViews.getIdsWithTitle(); + const supportedFieldTypes = inferrer.getSupportedFieldTypes(); + + const hasTextField = async ({ id }: { id: string }) => { + const dataView = await dataViews.get(id); + + return dataView.fields + .getAll() + .some((dvField) => + supportedFieldTypes.some((esType) => dvField.esTypes?.includes(esType)) + ); + }; + + const allPromises = dataViewIds.map(hasTextField); + const resolvedPromises = await Promise.all(allPromises); + const filteredDataViews = dataViewIds.filter((value, index) => resolvedPromises[index]); + setDataViewListItems( - items + filteredDataViews .sort((a, b) => a.title.localeCompare(b.title)) .map(({ id, title }) => ({ text: title, value: id })) ); - }); + } + + getFilteredDataViewListItems(); }, - [dataViews] + [dataViews, inferrer] ); useEffect( diff --git a/x-pack/plugins/ml/public/application/model_management/test_models/models/inference_base.ts b/x-pack/plugins/ml/public/application/model_management/test_models/models/inference_base.ts index 5954ed710c5f2..8dc0bf6b88815 100644 --- a/x-pack/plugins/ml/public/application/model_management/test_models/models/inference_base.ts +++ b/x-pack/plugins/ml/public/application/model_management/test_models/models/inference_base.ts @@ -11,6 +11,7 @@ import { i18n } from '@kbn/i18n'; import { map } from 'rxjs/operators'; import { SupportedPytorchTasksType } from '@kbn/ml-trained-models-utils'; +import { ES_FIELD_TYPES } from '@kbn/field-types'; import type { MLHttpFetchError } from '@kbn/ml-error-utils'; import { trainedModelsApiProvider } from '../../../services/ml_api_service/trained_models'; import { getInferenceInfoComponent } from './inference_info'; @@ -70,6 +71,7 @@ export abstract class InferenceBase { private runningState$ = new BehaviorSubject(RUNNING_STATE.STOPPED); private isValid$ = new BehaviorSubject(false); private pipeline$ = new BehaviorSubject({}); + private supportedFieldTypes: ES_FIELD_TYPES[] = [ES_FIELD_TYPES.TEXT]; protected readonly info: string[] = []; @@ -241,6 +243,10 @@ export abstract class InferenceBase { return this.pipeline$.getValue(); } + public getSupportedFieldTypes(): ES_FIELD_TYPES[] { + return this.supportedFieldTypes; + } + protected getBasicProcessors( inferenceConfigOverrides?: InferenceOptions ): estypes.IngestProcessorContainer[] { diff --git a/x-pack/plugins/observability/public/pages/slos/components/slo_list.tsx b/x-pack/plugins/observability/public/pages/slos/components/slo_list.tsx index 9e1db8c019381..651a97d364439 100644 --- a/x-pack/plugins/observability/public/pages/slos/components/slo_list.tsx +++ b/x-pack/plugins/observability/public/pages/slos/components/slo_list.tsx @@ -21,7 +21,7 @@ export function SloList({ autoRefresh }: Props) { const [query, setQuery] = useState(''); const [sort, setSort] = useState('status'); - const { isInitialLoading, isLoading, isRefetching, isError, sloList, refetch } = useFetchSloList({ + const { isLoading, isRefetching, isError, sloList } = useFetchSloList({ page: activePage + 1, kqlQuery: query, sortBy: sort, @@ -38,34 +38,23 @@ export function SloList({ autoRefresh }: Props) { const handlePageClick = (pageNumber: number) => { setActivePage(pageNumber); - refetch(); }; const handleChangeQuery = (newQuery: string) => { setActivePage(0); setQuery(newQuery); - refetch(); }; const handleChangeSort = (newSort: SortField | undefined) => { setActivePage(0); setSort(newSort); - refetch(); }; return ( diff --git a/x-pack/plugins/observability/public/pages/slos/components/slo_list_search_filter_sort_bar.tsx b/x-pack/plugins/observability/public/pages/slos/components/slo_list_search_filter_sort_bar.tsx index 8a9b22c6b5c7f..c1d9c6b3c3a07 100644 --- a/x-pack/plugins/observability/public/pages/slos/components/slo_list_search_filter_sort_bar.tsx +++ b/x-pack/plugins/observability/public/pages/slos/components/slo_list_search_filter_sort_bar.tsx @@ -16,6 +16,7 @@ import { EuiSelectableOption, } from '@elastic/eui'; import { EuiSelectableOptionCheckedType } from '@elastic/eui/src/components/selectable/selectable_option'; +import { Query } from '@kbn/es-query'; import { i18n } from '@kbn/i18n'; import { QueryStringInput } from '@kbn/unified-search-plugin/public'; import React, { useState } from 'react'; @@ -103,9 +104,13 @@ export function SloListSearchFilterSortBar({ unifiedSearch, }} disableAutoFocus - onSubmit={() => onChangeQuery(query)} + onSubmit={(value: Query) => { + setQuery(String(value.query)); + onChangeQuery(String(value.query)); + }} disableLanguageSwitcher isDisabled={loading} + autoSubmit indexPatterns={dataView ? [dataView] : []} placeholder={i18n.translate('xpack.observability.slo.list.search', { defaultMessage: 'Search your SLOs...', diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/eql/build_alert_group_from_sequence.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/eql/build_alert_group_from_sequence.test.ts index b3cf8f3ed1675..84349e9142e22 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/eql/build_alert_group_from_sequence.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/eql/build_alert_group_from_sequence.test.ts @@ -34,10 +34,6 @@ describe('buildAlert', () => { jest.clearAllMocks(); }); - test('it builds an alert composed of a sequence', () => { - expect(true).toEqual(true); - }); - test('it builds an alert as expected without original_event if event does not exist', () => { const completeRule = getCompleteRuleMock(getQueryRuleParams()); const eqlSequence = { @@ -146,6 +142,64 @@ describe('buildAlert', () => { }); describe('recursive intersection between objects', () => { + describe('objectPairIntersection', () => { + test('returns the intersection of fields with identically-valued arrays', () => { + const a = { + field1: [1], + }; + const b = { + field1: [1], + }; + const intersection = objectPairIntersection(a, b); + const expected = { + field1: [1], + }; + expect(intersection).toEqual(expected); + }); + + test('returns the intersection of arrays with differing lengths', () => { + const a = { + field1: 1, + }; + const b = { + field1: [1, 2, 3], + }; + const intersection = objectPairIntersection(a, b); + const expected = { + field1: [1], + }; + expect(intersection).toEqual(expected); + }); + + test('should work with arrays with same lengths but only one intersecting element', () => { + const a = { + field1: [3, 4, 5], + }; + const b = { + field1: [1, 2, 3], + }; + const intersection = objectPairIntersection(a, b); + const expected = { + field1: [3], + }; + expect(intersection).toEqual(expected); + }); + + test('should work with arrays with differing lengths and two intersecting elements', () => { + const a = { + field1: [3, 4, 5], + }; + const b = { + field1: [1, 2, 3, 4], + }; + const intersection = objectPairIntersection(a, b); + const expected = { + field1: [3, 4], + }; + expect(intersection).toEqual(expected); + }); + }); + test('should treat numbers and strings as unequal', () => { const a = { field1: 1, @@ -217,7 +271,7 @@ describe('buildAlert', () => { expect(intersection).toEqual(expected); }); - test('should strip arrays out regardless of whether they are equal', () => { + test('returns the intersection of values for fields containing arrays', () => { const a = { array_field1: [1, 2], array_field2: [1, 2], @@ -227,7 +281,7 @@ describe('buildAlert', () => { array_field2: [3, 4], }; const intersection = objectPairIntersection(a, b); - const expected = undefined; + const expected = { array_field1: [1, 2], array_field2: [] }; expect(intersection).toEqual(expected); }); @@ -287,6 +341,7 @@ describe('buildAlert', () => { const intersection = objectPairIntersection(a, b); const expected = { container_field: { + array_field: [1, 2], field1: 1, field6: null, nested_container_field: { @@ -332,6 +387,7 @@ describe('buildAlert', () => { }; const intersection = objectPairIntersection(a, b); const expected = { + array_field: [1, 2], field1: 1, field6: null, container_field: { @@ -419,6 +475,7 @@ describe('buildAlert', () => { }; const intersection = objectArrayIntersection([a, b]); const expected = { + array_field: [1, 2], field1: 1, field6: null, container_field: { @@ -427,7 +484,6 @@ describe('buildAlert', () => { }; expect(intersection).toEqual(expected); }); - test('should work with 3 or more objects', () => { const a = { field1: 1, @@ -477,6 +533,7 @@ describe('buildAlert', () => { }; const intersection = objectArrayIntersection([a, b, c]); const expected = { + array_field: [1, 2], field1: 1, }; expect(intersection).toEqual(expected); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/eql/build_alert_group_from_sequence.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/eql/build_alert_group_from_sequence.ts index 8db01c11d4de5..2675c3996e865 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/eql/build_alert_group_from_sequence.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/eql/build_alert_group_from_sequence.ts @@ -6,6 +6,7 @@ */ import { ALERT_URL, ALERT_UUID } from '@kbn/rule-data-utils'; +import { intersection as lodashIntersection, isArray } from 'lodash'; import { getAlertDetailsUrl } from '../../../../../common/utils/alert_detail_path'; import { DEFAULT_ALERTS_INDEX } from '../../../../../common/constants'; @@ -180,6 +181,11 @@ export const buildAlertRoot = ( }; }; +/** + * Merges array of alert sources with the first item in the array + * @param objects array of alert _source objects + * @returns singular object + */ export const objectArrayIntersection = (objects: object[]) => { if (objects.length === 0) { return undefined; @@ -195,6 +201,16 @@ export const objectArrayIntersection = (objects: object[]) => { } }; +/** + * Finds the intersection of two objects by recursively + * finding the "intersection" of each of of their common keys' + * values. If an intersection cannot be found between a key's + * values, the value will be undefined in the returned object. + * + * @param a object + * @param b object + * @returns intersection of the two objects + */ export const objectPairIntersection = (a: object | undefined, b: object | undefined) => { if (a === undefined || b === undefined) { return undefined; @@ -214,6 +230,12 @@ export const objectPairIntersection = (a: object | undefined, b: object | undefi intersection[key] = objectPairIntersection(aVal, bVal); } else if (aVal === bVal) { intersection[key] = aVal; + } else if (isArray(aVal) && isArray(bVal)) { + intersection[key] = lodashIntersection(aVal, bVal); + } else if (isArray(aVal) && !isArray(bVal)) { + intersection[key] = lodashIntersection(aVal, [bVal]); + } else if (!isArray(aVal) && isArray(bVal)) { + intersection[key] = lodashIntersection([aVal], bVal); } } }); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/max_queued_actions_circuit_breaker.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/max_queued_actions_circuit_breaker.ts index 62523561c3823..02231a58a83c3 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/max_queued_actions_circuit_breaker.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/max_queued_actions_circuit_breaker.ts @@ -6,20 +6,29 @@ */ import expect from '@kbn/expect'; -import { ES_TEST_INDEX_NAME } from '@kbn/alerting-api-integration-helpers'; -import { getEventLog, getTestRuleData, ObjectRemover } from '../../../common/lib'; +import { ESTestIndexTool, ES_TEST_INDEX_NAME } from '@kbn/alerting-api-integration-helpers'; +import { getEventLog, ObjectRemover } from '../../../common/lib'; import { FtrProviderContext } from '../../../common/ftr_provider_context'; // eslint-disable-next-line import/no-default-export export default function createActionTests({ getService }: FtrProviderContext) { const supertest = getService('supertest'); - // Failing ES Promotion: See https://github.com/elastic/kibana/issues/166770 - describe.skip('max queued actions circuit breaker', () => { + describe('max queued actions circuit breaker', () => { const objectRemover = new ObjectRemover(supertest); const retry = getService('retry'); + const es = getService('es'); + const esTestIndexTool = new ESTestIndexTool(es, retry); - after(() => objectRemover.removeAll()); + beforeEach(async () => { + await esTestIndexTool.destroy(); + await esTestIndexTool.setup(); + }); + + afterEach(async () => { + objectRemover.removeAll(); + await esTestIndexTool.destroy(); + }); it('completes execution and reports back whether it reached the limit', async () => { const response = await supertest @@ -44,7 +53,7 @@ export default function createActionTests({ getService }: FtrProviderContext) { for (let i = 0; i < 510; i++) { actions.push({ id: actionId, - group: 'default', + group: 'query matched', params: { index: ES_TEST_INDEX_NAME, reference: 'test', @@ -61,19 +70,25 @@ export default function createActionTests({ getService }: FtrProviderContext) { const resp = await supertest .post('/api/alerting/rule') .set('kbn-xsrf', 'foo') - .send( - getTestRuleData({ - rule_type_id: 'test.always-firing-alert-as-data', - schedule: { interval: '1h' }, - throttle: undefined, - notify_when: undefined, - params: { - index: ES_TEST_INDEX_NAME, - reference: 'test', - }, - actions, - }) - ); + .send({ + name: 'abc', + consumer: 'alertsFixture', + enabled: true, + rule_type_id: '.es-query', + schedule: { interval: '1h' }, + actions, + notify_when: undefined, + params: { + size: 100, + timeWindowSize: 20, + timeWindowUnit: 's', + thresholdComparator: '>', + threshold: [-1], + esQuery: `{\n \"query\":{\n \"match_all\" : {}\n }\n}`, + timeField: 'date', + index: [ES_TEST_INDEX_NAME], + }, + }); expect(resp.status).to.eql(200); const ruleId = resp.body.id; diff --git a/x-pack/test/functional/apps/dashboard/group1/preserve_url.ts b/x-pack/test/functional/apps/dashboard/group1/preserve_url.ts index baab3bbeb52f7..db9912be25625 100644 --- a/x-pack/test/functional/apps/dashboard/group1/preserve_url.ts +++ b/x-pack/test/functional/apps/dashboard/group1/preserve_url.ts @@ -15,7 +15,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const kibanaServer = getService('kibanaServer'); const spacesService = getService('spaces'); - describe('preserve url', function () { + // Failing: See https://github.com/elastic/kibana/issues/166900 + describe.skip('preserve url', function () { const anotherSpace = 'another-space'; before(async () => {