Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@
"@kbn/alerting-example-plugin": "link:x-pack/examples/alerting_example",
"@kbn/alerting-fixture-plugin": "link:x-pack/platform/test/functional_with_es_ssl/plugins/alerts",
"@kbn/alerting-plugin": "link:x-pack/platform/plugins/shared/alerting",
"@kbn/alerting-rule-schemas": "link:x-pack/platform/packages/shared/kbn-alerting-rule-schemas",
"@kbn/alerting-rule-utils": "link:x-pack/platform/packages/shared/alerting-rule-utils",
"@kbn/alerting-state-types": "link:x-pack/platform/packages/private/kbn-alerting-state-types",
"@kbn/alerting-types": "link:src/platform/packages/shared/kbn-alerting-types",
Expand Down
2 changes: 2 additions & 0 deletions tsconfig.base.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@
"@kbn/alerting-fixture-plugin/*": ["x-pack/platform/test/functional_with_es_ssl/plugins/alerts/*"],
"@kbn/alerting-plugin": ["x-pack/platform/plugins/shared/alerting"],
"@kbn/alerting-plugin/*": ["x-pack/platform/plugins/shared/alerting/*"],
"@kbn/alerting-rule-schemas": ["x-pack/platform/packages/shared/kbn-alerting-rule-schemas"],
"@kbn/alerting-rule-schemas/*": ["x-pack/platform/packages/shared/kbn-alerting-rule-schemas/*"],
"@kbn/alerting-rule-utils": ["x-pack/platform/packages/shared/alerting-rule-utils"],
"@kbn/alerting-rule-utils/*": ["x-pack/platform/packages/shared/alerting-rule-utils/*"],
"@kbn/alerting-state-types": ["x-pack/platform/packages/private/kbn-alerting-state-types"],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# @kbn/alerting-rule-schemas

Zod schemas and shared types for alerting rule data requests.
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,4 @@
* 2.0.
*/

export { createRuleDataSchema } from './create_rule_data_schema';
export { updateRuleDataSchema } from './update_rule_data_schema';
export * from './src';
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,8 @@
* 2.0.
*/

import { Parser } from '@kbn/esql-language';

export const validateEsqlQuery = (query: string): string | void => {
const errors = Parser.parseErrors(query);
if (errors.length > 0) {
return `Invalid ES|QL query: ${errors[0].message}`;
}
module.exports = {
preset: '@kbn/test/jest_node',
rootDir: '../../../../..',
roots: ['<rootDir>/x-pack/platform/packages/shared/kbn-alerting-rule-schemas'],
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "shared-common",
"id": "@kbn/alerting-rule-schemas",
"owner": "@elastic/response-ops",
"group": "platform",
"visibility": "shared"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "@kbn/alerting-rule-schemas",
"description": "Alerting rule request Zod schemas and shared types.",
"private": true,
"version": "1.0.0",
"license": "Elastic License 2.0 OR AGPL-3.0-only OR SSPL-1.0",
"sideEffects": false
}
Original file line number Diff line number Diff line change
@@ -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 './rule_data_schema';
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* 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 { Parser } from '@kbn/esql-language';
import { z } from '@kbn/zod';

const DURATION_RE = /^(\d+)(ms|s|m|h|d|w)$/;

const durationSchema = z.string().superRefine((value, ctx) => {
if (!DURATION_RE.test(value)) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: `Invalid duration "${value}". Expected format like "5m", "1h", "30s", "250ms"`,
});
}
});

const withEsqlValidation = (schema: z.ZodString) =>
schema.superRefine((query, ctx) => {
const errors = Parser.parseErrors(query);
if (errors.length > 0) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: `Invalid ES|QL query: ${errors[0].message}`,
});
}
});

const scheduleSchema = z
.object({
custom: durationSchema,
})
.strict();

export const createRuleDataSchema = z
.object({
name: z.string().min(1).max(64),
tags: z.array(z.string().max(64)).max(100).default([]),
schedule: scheduleSchema,
enabled: z.boolean().default(true),
query: withEsqlValidation(z.string().min(1).max(10000)),
timeField: z.string().min(1).max(128).default('@timestamp'),
lookbackWindow: durationSchema,
groupingKey: z.array(z.string()).max(16).default([]),
})
.strip();

export type CreateRuleData = z.infer<typeof createRuleDataSchema>;

export const updateRuleDataSchema = z
.object({
name: z.string().min(1).optional(),
tags: z.array(z.string()).optional(),
schedule: scheduleSchema.optional(),
enabled: z.boolean().optional(),
query: withEsqlValidation(z.string().min(1)).optional(),
timeField: z.string().min(1).optional(),
lookbackWindow: durationSchema.optional(),
groupingKey: z.array(z.string()).optional(),
})
.strip();

export type UpdateRuleData = z.infer<typeof updateRuleDataSchema>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"extends": "@kbn/tsconfig-base/tsconfig.json",
"compilerOptions": {
"outDir": "target/types",
},
"include": [
"**/*.ts",
],
"exclude": [
"target/**/*"
],
"kbn_references": [
"@kbn/esql-language",
"@kbn/zod"
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
* 2.0.
*/

export { createRuleDataSchema, updateRuleDataSchema } from '@kbn/alerting-rule-schemas';
export { RulesClient } from './rules_client';
export { createRuleDataSchema, updateRuleDataSchema } from './schemas';
export type {
CreateRuleData,
CreateRuleParams,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@ import type { SecurityPluginStart } from '@kbn/security-plugin/server';
import { inject, injectable } from 'inversify';
import { PluginStart } from '@kbn/core-di';
import { CoreStart, Request } from '@kbn/core-di-server';
import { stringifyZodError } from '@kbn/zod-helpers';
import { createRuleDataSchema, updateRuleDataSchema } from '@kbn/alerting-rule-schemas';

import { type RuleSavedObjectAttributes } from '../../saved_objects';
import { ensureRuleExecutorTaskScheduled, getRuleExecutorTaskId } from '../rule_executor/schedule';
import type { RulesSavedObjectServiceContract } from '../services/rules_saved_object_service/rules_saved_object_service';
import { RulesSavedObjectService } from '../services/rules_saved_object_service/rules_saved_object_service';
import { createRuleDataSchema, updateRuleDataSchema } from './schemas';
import type {
CreateRuleParams,
FindRulesParams,
Expand Down Expand Up @@ -54,10 +55,11 @@ export class RulesClient {
public async createRule(params: CreateRuleParams): Promise<RuleResponse> {
const { spaceId } = this.getSpaceContext();

try {
createRuleDataSchema.validate(params.data);
} catch (error) {
throw Boom.badRequest(`Error validating create rule data - ${(error as Error).message}`);
const createValidationResult = createRuleDataSchema.safeParse(params.data);
if (!createValidationResult.success) {
throw Boom.badRequest(
`Error validating create rule data - ${stringifyZodError(createValidationResult.error)}`
);
}

const username = await this.getUserName();
Expand Down Expand Up @@ -122,10 +124,11 @@ export class RulesClient {
}): Promise<RuleResponse> {
const { spaceId } = this.getSpaceContext();

try {
updateRuleDataSchema.validate(data);
} catch (error) {
throw Boom.badRequest(`Error validating update rule data - ${(error as Error).message}`);
const updateValidationResult = updateRuleDataSchema.safeParse(data);
if (!updateValidationResult.success) {
throw Boom.badRequest(
`Error validating update rule data - ${stringifyZodError(updateValidationResult.error)}`
);
}

const username = await this.getUserName();
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@
* 2.0.
*/

import type { TypeOf } from '@kbn/config-schema';
import type { createRuleDataSchema, updateRuleDataSchema } from './schemas';

export type CreateRuleData = TypeOf<typeof createRuleDataSchema>;
import type { CreateRuleData, UpdateRuleData } from '@kbn/alerting-rule-schemas';

export interface CreateRuleParams {
data: CreateRuleData;
Expand All @@ -23,7 +20,7 @@ export interface RuleResponse extends CreateRuleData {
updatedAt: string;
}

export type UpdateRuleData = TypeOf<typeof updateRuleDataSchema>;
export type { CreateRuleData, UpdateRuleData };

export interface FindRulesParams {
page?: number;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import type { RouteHandler } from '@kbn/core-di-server';
import { Request, Response } from '@kbn/core-di-server';
import type { TypeOf } from '@kbn/config-schema';
import type { RouteSecurity } from '@kbn/core-http-server';
import { buildRouteValidationWithZod } from '@kbn/zod-helpers';
import { createRuleDataSchema, type CreateRuleData } from '../lib/rules_client';
import { RulesClient } from '../lib/rules_client';
import { ALERTING_V2_API_PRIVILEGES } from '../lib/security/privileges';
Expand All @@ -36,7 +37,7 @@ export class CreateRuleRoute implements RouteHandler {
static options = { access: 'internal' } as const;
static validate = {
request: {
body: createRuleDataSchema,
body: buildRouteValidationWithZod(createRuleDataSchema),
params: createRuleParamsSchema,
},
} as const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { inject, injectable } from 'inversify';
import { Request, Response } from '@kbn/core-di-server';
import type { TypeOf } from '@kbn/config-schema';
import type { RouteSecurity } from '@kbn/core-http-server';
import { buildRouteValidationWithZod } from '@kbn/zod-helpers';

import { updateRuleDataSchema, type UpdateRuleData } from '../lib/rules_client';
import { RulesClient } from '../lib/rules_client/rules_client';
Expand All @@ -34,7 +35,7 @@ export class UpdateRuleRoute {
static options = { access: 'internal' } as const;
static validate = {
request: {
body: updateRuleDataSchema,
body: buildRouteValidationWithZod(updateRuleDataSchema),
params: updateRuleParamsSchema,
},
} as const;
Expand Down
2 changes: 2 additions & 0 deletions x-pack/platform/plugins/shared/alerting_v2/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@
"@kbn/logging-mocks",
"@kbn/core-elasticsearch-client-server-mocks",
"@kbn/es-errors",
"@kbn/alerting-rule-schemas",
"@kbn/zod",
"@kbn/zod-helpers",
"@kbn/core-di-internal"
],
"exclude": [
Expand Down