[ResponseOps][Rules] Add OAS schema for handled 4xx errors on rule apis (#192616)

## Summary

Closes #188514 

Adds OAS schemas for the `403 Forbidden` errors that public rule apis
can return if a license is invalid, `400 Bad Request` for unregistered
rule types, and `404 Not Found` for missing saved objects.

### Checklist

- [x] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)
- [x]
[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)
was added for features that require explanation or tutorials

### Testing

1. Start ES
2. Add `server.oas.enabled: true` to `kibana.dev.yml`
3. Start Kibana `yarn start --no-base-path`
4. `curl -s -uelastic:changeme
http://localhost:5601/api/oas\?pathStartsWith\=/api/alerting/rule/ | jq`
(If you have `jq` installed, otherwise pipe to `pbcopy` and paste the
result into a JSON prettifier)
5. Search the output for the word `Forbidden` to ensure this schema has
been added to `create`, `update`, `enable`, `disable`, `mute`, `unmute`,
and `update_rule_api_key`

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
Zacqary Adam Xeper 2024-09-19 11:52:17 -05:00 committed by GitHub
parent 0c222addbb
commit 18afcae609
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 306 additions and 28 deletions

View file

@ -1493,6 +1493,15 @@
"responses": {
"204": {
"description": "Indicates a successful call."
},
"400": {
"description": "Indicates an invalid schema or parameters."
},
"403": {
"description": "Indicates that this call is forbidden."
},
"404": {
"description": "Indicates a rule with the given ID does not exist."
}
},
"summary": "Delete a rule",
@ -2399,6 +2408,15 @@
}
},
"description": "Indicates a successful call."
},
"400": {
"description": "Indicates an invalid schema or parameters."
},
"403": {
"description": "Indicates that this call is forbidden."
},
"404": {
"description": "Indicates a rule with the given ID does not exist."
}
},
"summary": "Get rule details",
@ -3586,6 +3604,15 @@
}
},
"description": "Indicates a successful call."
},
"400": {
"description": "Indicates an invalid schema or parameters."
},
"403": {
"description": "Indicates that this call is forbidden."
},
"409": {
"description": "Indicates that the rule id is already in use."
}
},
"summary": "Create a rule",
@ -4756,6 +4783,18 @@
}
},
"description": "Indicates a successful call."
},
"400": {
"description": "Indicates an invalid schema or parameters."
},
"403": {
"description": "Indicates that this call is forbidden."
},
"404": {
"description": "Indicates a rule with the given ID does not exist."
},
"409": {
"description": "Indicates that the rule has already been updated by another user."
}
},
"summary": "Update a rule",
@ -4821,6 +4860,15 @@
"responses": {
"204": {
"description": "Indicates a successful call."
},
"400": {
"description": "Indicates an invalid schema."
},
"403": {
"description": "Indicates that this call is forbidden."
},
"404": {
"description": "Indicates a rule with the given ID does not exist."
}
},
"summary": "Disable a rule",
@ -4868,6 +4916,15 @@
"responses": {
"204": {
"description": "Indicates a successful call."
},
"400": {
"description": "Indicates an invalid schema or parameters."
},
"403": {
"description": "Indicates that this call is forbidden."
},
"404": {
"description": "Indicates a rule with the given ID does not exist."
}
},
"summary": "Enable a rule",
@ -5009,6 +5066,18 @@
"responses": {
"204": {
"description": "Indicates a successful call."
},
"400": {
"description": "Indicates an invalid schema or parameters."
},
"403": {
"description": "Indicates that this call is forbidden."
},
"404": {
"description": "Indicates a rule with the given ID does not exist."
},
"409": {
"description": "Indicates that the rule has already been updated by another user."
}
},
"summary": "Update the API key for a rule",
@ -5065,6 +5134,15 @@
"responses": {
"204": {
"description": "Indicates a successful call."
},
"400": {
"description": "Indicates an invalid schema or parameters."
},
"403": {
"description": "Indicates that this call is forbidden."
},
"404": {
"description": "Indicates a rule or alert with the given ID does not exist."
}
},
"summary": "Mute an alert",
@ -5121,6 +5199,15 @@
"responses": {
"204": {
"description": "Indicates a successful call."
},
"400": {
"description": "Indicates an invalid schema or parameters."
},
"403": {
"description": "Indicates that this call is forbidden."
},
"404": {
"description": "Indicates a rule or alert with the given ID does not exist."
}
},
"summary": "Unmute an alert",
@ -6162,6 +6249,12 @@
}
},
"description": "Indicates a successful call."
},
"400": {
"description": "Indicates an invalid schema or parameters."
},
"403": {
"description": "Indicates that this call is forbidden."
}
},
"summary": "Get information about rules",

View file

@ -1493,6 +1493,15 @@
"responses": {
"204": {
"description": "Indicates a successful call."
},
"400": {
"description": "Indicates an invalid schema or parameters."
},
"403": {
"description": "Indicates that this call is forbidden."
},
"404": {
"description": "Indicates a rule with the given ID does not exist."
}
},
"summary": "Delete a rule",
@ -2399,6 +2408,15 @@
}
},
"description": "Indicates a successful call."
},
"400": {
"description": "Indicates an invalid schema or parameters."
},
"403": {
"description": "Indicates that this call is forbidden."
},
"404": {
"description": "Indicates a rule with the given ID does not exist."
}
},
"summary": "Get rule details",
@ -3586,6 +3604,15 @@
}
},
"description": "Indicates a successful call."
},
"400": {
"description": "Indicates an invalid schema or parameters."
},
"403": {
"description": "Indicates that this call is forbidden."
},
"409": {
"description": "Indicates that the rule id is already in use."
}
},
"summary": "Create a rule",
@ -4756,6 +4783,18 @@
}
},
"description": "Indicates a successful call."
},
"400": {
"description": "Indicates an invalid schema or parameters."
},
"403": {
"description": "Indicates that this call is forbidden."
},
"404": {
"description": "Indicates a rule with the given ID does not exist."
},
"409": {
"description": "Indicates that the rule has already been updated by another user."
}
},
"summary": "Update a rule",
@ -4821,6 +4860,15 @@
"responses": {
"204": {
"description": "Indicates a successful call."
},
"400": {
"description": "Indicates an invalid schema."
},
"403": {
"description": "Indicates that this call is forbidden."
},
"404": {
"description": "Indicates a rule with the given ID does not exist."
}
},
"summary": "Disable a rule",
@ -4868,6 +4916,15 @@
"responses": {
"204": {
"description": "Indicates a successful call."
},
"400": {
"description": "Indicates an invalid schema or parameters."
},
"403": {
"description": "Indicates that this call is forbidden."
},
"404": {
"description": "Indicates a rule with the given ID does not exist."
}
},
"summary": "Enable a rule",
@ -5009,6 +5066,18 @@
"responses": {
"204": {
"description": "Indicates a successful call."
},
"400": {
"description": "Indicates an invalid schema or parameters."
},
"403": {
"description": "Indicates that this call is forbidden."
},
"404": {
"description": "Indicates a rule with the given ID does not exist."
},
"409": {
"description": "Indicates that the rule has already been updated by another user."
}
},
"summary": "Update the API key for a rule",
@ -5065,6 +5134,15 @@
"responses": {
"204": {
"description": "Indicates a successful call."
},
"400": {
"description": "Indicates an invalid schema or parameters."
},
"403": {
"description": "Indicates that this call is forbidden."
},
"404": {
"description": "Indicates a rule or alert with the given ID does not exist."
}
},
"summary": "Mute an alert",
@ -5121,6 +5199,15 @@
"responses": {
"204": {
"description": "Indicates a successful call."
},
"400": {
"description": "Indicates an invalid schema or parameters."
},
"403": {
"description": "Indicates that this call is forbidden."
},
"404": {
"description": "Indicates a rule or alert with the given ID does not exist."
}
},
"summary": "Unmute an alert",
@ -6162,6 +6249,12 @@
}
},
"description": "Indicates a successful call."
},
"400": {
"description": "Indicates an invalid schema or parameters."
},
"403": {
"description": "Indicates that this call is forbidden."
}
},
"summary": "Get information about rules",

View file

@ -6,9 +6,9 @@
*/
import { IRouter } from '@kbn/core/server';
import { verifyAccessAndContext, handleDisabledApiKeysError } from '../../../lib';
import { ILicenseState, RuleTypeDisabledError } from '../../../../lib';
import { AlertingRequestHandlerContext, INTERNAL_BASE_ALERTING_API_PATH } from '../../../../types';
import { handleDisabledApiKeysError, verifyAccessAndContext } from '../../../lib';
import {
bulkDisableRulesRequestBodySchemaV1,
@ -16,8 +16,8 @@ import {
BulkDisableRulesResponseV1,
} from '../../../../../common/routes/rule/apis/bulk_disable';
import type { RuleParamsV1 } from '../../../../../common/routes/rule/response';
import { transformRuleToRuleResponseV1 } from '../../transforms';
import { Rule } from '../../../../application/rule/types';
import { transformRuleToRuleResponseV1 } from '../../transforms';
export const bulkDisableRulesRoute = ({
router,

View file

@ -8,20 +8,20 @@
import { IRouter } from '@kbn/core/server';
import { ILicenseState, RuleTypeDisabledError } from '../../../../lib';
import { verifyAccessAndContext, handleDisabledApiKeysError } from '../../../lib';
import { AlertingRequestHandlerContext, INTERNAL_BASE_ALERTING_API_PATH } from '../../../../types';
import { handleDisabledApiKeysError, verifyAccessAndContext } from '../../../lib';
import {
bulkEditRulesRequestBodySchemaV1,
BulkEditRulesRequestBodyV1,
BulkEditRulesResponseV1,
} from '../../../../../common/routes/rule/apis/bulk_edit';
import { Rule } from '../../../../application/rule/types';
import type { RuleParamsV1 } from '../../../../../common/routes/rule/response';
import { Rule } from '../../../../application/rule/types';
import { transformRuleToRuleResponseV1 } from '../../transforms';
import { transformOperationsV1 } from './transforms';
import { validateRequiredGroupInDefaultActionsV1 } from '../../validation';
import { transformOperationsV1 } from './transforms';
interface BuildBulkEditRulesRouteParams {
licenseState: ILicenseState;

View file

@ -5,13 +5,6 @@
* 2.0.
*/
import { RuleTypeDisabledError } from '../../../../lib';
import {
handleDisabledApiKeysError,
verifyAccessAndContext,
countUsageOfPredefinedIds,
} from '../../../lib';
import { BASE_ALERTING_API_PATH } from '../../../../types';
import { RouteOptions } from '../../..';
import type {
CreateRuleRequestBodyV1,
@ -24,9 +17,16 @@ import {
} from '../../../../../common/routes/rule/apis/create';
import { RuleParamsV1, ruleResponseSchemaV1 } from '../../../../../common/routes/rule/response';
import { Rule } from '../../../../application/rule/types';
import { transformCreateBodyV1 } from './transforms';
import { RuleTypeDisabledError } from '../../../../lib';
import { BASE_ALERTING_API_PATH } from '../../../../types';
import {
countUsageOfPredefinedIds,
handleDisabledApiKeysError,
verifyAccessAndContext,
} from '../../../lib';
import { transformRuleToRuleResponseV1 } from '../../transforms';
import { validateRequiredGroupInDefaultActionsV1 } from '../../validation';
import { transformCreateBodyV1 } from './transforms';
export const createRuleRoute = ({ router, licenseState, usageCounter }: RouteOptions) => {
router.post(
@ -47,6 +47,15 @@ export const createRuleRoute = ({ router, licenseState, usageCounter }: RouteOpt
body: () => ruleResponseSchemaV1,
description: 'Indicates a successful call.',
},
400: {
description: 'Indicates an invalid schema or parameters.',
},
403: {
description: 'Indicates that this call is forbidden.',
},
409: {
description: 'Indicates that the rule id is already in use.',
},
},
},
},

View file

@ -34,6 +34,15 @@ export const deleteRuleRoute = (
204: {
description: 'Indicates a successful call.',
},
400: {
description: 'Indicates an invalid schema or parameters.',
},
403: {
description: 'Indicates that this call is forbidden.',
},
404: {
description: 'Indicates a rule with the given ID does not exist.',
},
},
},
},

View file

@ -7,14 +7,14 @@
import { IRouter } from '@kbn/core/server';
import {
disableRuleRequestParamsSchemaV1,
disableRuleRequestBodySchemaV1,
DisableRuleRequestParamsV1,
DisableRuleRequestBodyV1,
DisableRuleRequestParamsV1,
disableRuleRequestBodySchemaV1,
disableRuleRequestParamsSchemaV1,
} from '../../../../../common/routes/rule/apis/disable';
import { ILicenseState, RuleTypeDisabledError } from '../../../../lib';
import { verifyAccessAndContext } from '../../../lib';
import { AlertingRequestHandlerContext, BASE_ALERTING_API_PATH } from '../../../../types';
import { verifyAccessAndContext } from '../../../lib';
export const disableRuleRoute = (
router: IRouter<AlertingRequestHandlerContext>,
@ -37,6 +37,15 @@ export const disableRuleRoute = (
204: {
description: 'Indicates a successful call.',
},
400: {
description: 'Indicates an invalid schema.',
},
403: {
description: 'Indicates that this call is forbidden.',
},
404: {
description: 'Indicates a rule with the given ID does not exist.',
},
},
},
},

View file

@ -7,14 +7,13 @@
import { IRouter } from '@kbn/core/server';
import { ILicenseState, RuleTypeDisabledError } from '../../../../lib';
import { verifyAccessAndContext } from '../../../lib';
import { AlertingRequestHandlerContext, BASE_ALERTING_API_PATH } from '../../../../types';
import { verifyAccessAndContext } from '../../../lib';
import {
EnableRuleRequestParamsV1,
enableRuleRequestParamsSchemaV1,
} from '../../../../../common/routes/rule/apis/enable';
export const enableRuleRoute = (
router: IRouter<AlertingRequestHandlerContext>,
licenseState: ILicenseState
@ -35,6 +34,15 @@ export const enableRuleRoute = (
204: {
description: 'Indicates a successful call.',
},
400: {
description: 'Indicates an invalid schema or parameters.',
},
403: {
description: 'Indicates that this call is forbidden.',
},
404: {
description: 'Indicates a rule with the given ID does not exist.',
},
},
},
},

View file

@ -55,6 +55,12 @@ const buildFindRulesRoute = ({
body: () => ruleResponseSchemaV1,
description: 'Indicates a successful call.',
},
400: {
description: 'Indicates an invalid schema or parameters.',
},
403: {
description: 'Indicates that this call is forbidden.',
},
},
},
},

View file

@ -50,6 +50,15 @@ const buildGetRuleRoute = ({
body: () => ruleResponseSchemaV1,
description: 'Indicates a successful call.',
},
400: {
description: 'Indicates an invalid schema or parameters.',
},
403: {
description: 'Indicates that this call is forbidden.',
},
404: {
description: 'Indicates a rule with the given ID does not exist.',
},
},
},
},

View file

@ -34,6 +34,15 @@ export const muteAlertRoute = (
204: {
description: 'Indicates a successful call.',
},
400: {
description: 'Indicates an invalid schema or parameters.',
},
403: {
description: 'Indicates that this call is forbidden.',
},
404: {
description: 'Indicates a rule or alert with the given ID does not exist.',
},
},
},
},

View file

@ -6,13 +6,13 @@
*/
import { IRouter } from '@kbn/core/server';
import { ILicenseState, RuleTypeDisabledError } from '../../../../lib';
import { verifyAccessAndContext } from '../../../lib';
import { AlertingRequestHandlerContext, BASE_ALERTING_API_PATH } from '../../../../types';
import {
unmuteAlertParamsSchemaV1,
UnmuteAlertRequestParamsV1,
unmuteAlertParamsSchemaV1,
} from '../../../../../common/routes/rule/apis/unmute_alert';
import { ILicenseState, RuleTypeDisabledError } from '../../../../lib';
import { AlertingRequestHandlerContext, BASE_ALERTING_API_PATH } from '../../../../types';
import { verifyAccessAndContext } from '../../../lib';
import { transformRequestParamsToApplicationV1 } from './transforms';
export const unmuteAlertRoute = (
@ -35,6 +35,15 @@ export const unmuteAlertRoute = (
204: {
description: 'Indicates a successful call.',
},
400: {
description: 'Indicates an invalid schema or parameters.',
},
403: {
description: 'Indicates that this call is forbidden.',
},
404: {
description: 'Indicates a rule or alert with the given ID does not exist.',
},
},
},
},

View file

@ -6,8 +6,6 @@
*/
import { IRouter } from '@kbn/core/server';
import { ILicenseState, RuleTypeDisabledError } from '../../../../lib';
import { verifyAccessAndContext, handleDisabledApiKeysError } from '../../../lib';
import type {
UpdateRuleRequestBodyV1,
UpdateRuleRequestParamsV1,
@ -18,11 +16,13 @@ import {
updateParamsSchemaV1,
} from '../../../../../common/routes/rule/apis/update';
import { RuleParamsV1, ruleResponseSchemaV1 } from '../../../../../common/routes/rule/response';
import { AlertingRequestHandlerContext, BASE_ALERTING_API_PATH } from '../../../../types';
import { Rule } from '../../../../application/rule/types';
import { transformUpdateBodyV1 } from './transforms';
import { ILicenseState, RuleTypeDisabledError } from '../../../../lib';
import { AlertingRequestHandlerContext, BASE_ALERTING_API_PATH } from '../../../../types';
import { handleDisabledApiKeysError, verifyAccessAndContext } from '../../../lib';
import { transformRuleToRuleResponseV1 } from '../../transforms';
import { validateRequiredGroupInDefaultActionsV1 } from '../../validation';
import { transformUpdateBodyV1 } from './transforms';
export const updateRuleRoute = (
router: IRouter<AlertingRequestHandlerContext>,
@ -46,6 +46,18 @@ export const updateRuleRoute = (
body: () => ruleResponseSchemaV1,
description: 'Indicates a successful call.',
},
400: {
description: 'Indicates an invalid schema or parameters.',
},
403: {
description: 'Indicates that this call is forbidden.',
},
404: {
description: 'Indicates a rule with the given ID does not exist.',
},
409: {
description: 'Indicates that the rule has already been updated by another user.',
},
},
},
},

View file

@ -11,8 +11,8 @@ import {
updateApiKeyParamsSchemaV1,
} from '../../../../../common/routes/rule/apis/update_api_key';
import { ILicenseState, RuleTypeDisabledError } from '../../../../lib';
import { verifyAccessAndContext } from '../../../lib';
import { AlertingRequestHandlerContext, BASE_ALERTING_API_PATH } from '../../../../types';
import { verifyAccessAndContext } from '../../../lib';
export const updateRuleApiKeyRoute = (
router: IRouter<AlertingRequestHandlerContext>,
@ -34,6 +34,18 @@ export const updateRuleApiKeyRoute = (
204: {
description: 'Indicates a successful call.',
},
400: {
description: 'Indicates an invalid schema or parameters.',
},
403: {
description: 'Indicates that this call is forbidden.',
},
404: {
description: 'Indicates a rule with the given ID does not exist.',
},
409: {
description: 'Indicates that the rule has already been updated by another user.',
},
},
},
},