[RAM] update api key to become public (#164883)

## Summary

[Summarize your PR. If it involves visual changes include a screenshot
or gif.](https://github.com/elastic/enhancements/issues/17998)


### Checklist

- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios

---------

Co-authored-by: lcawl <lcawley@elastic.co>
This commit is contained in:
Xavier Mouligneau 2023-08-28 13:25:48 -04:00 committed by GitHub
parent 68a6a56eb2
commit cb9797500a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 262 additions and 43 deletions

View file

@ -45,6 +45,7 @@ Any modifications made to this file will be overwritten.
<li><a href="#unmuteAlert"><code><span class="http-method">post</span> /s/{spaceId}/api/alerting/rule/{ruleId}/alert/{alertId}/_unmute</code></a></li>
<li><a href="#unmuteAllAlerts"><code><span class="http-method">post</span> /s/{spaceId}/api/alerting/rule/{ruleId}/_unmute_all</code></a></li>
<li><a href="#updateRule"><code><span class="http-method">put</span> /s/{spaceId}/api/alerting/rule/{ruleId}</code></a></li>
<li><a href="#updateRuleAPIKey"><code><span class="http-method">post</span> /s/{spaceId}/api/alerting/rule/{ruleId}/_update_api_key</code></a></li>
</ul>
<h1><a name="Alerting">Alerting</a></h1>
@ -2827,12 +2828,61 @@ Any modifications made to this file will be overwritten.
<a href="#404_response">404_response</a>
</div> <!-- method -->
<hr/>
<div class="method"><a name="updateRuleAPIKey"/>
<div class="method-path">
<a class="up" href="#__Methods">Up</a>
<pre class="post"><code class="huge"><span class="http-method">post</span> /s/{spaceId}/api/alerting/rule/{ruleId}/_update_api_key</code></pre></div>
<div class="method-summary">Updates the API key for a rule. (<span class="nickname">updateRuleAPIKey</span>)</div>
<div class="method-notes">The new API key has the credentials of the user that submits the request.</div>
<h3 class="field-label">Path parameters</h3>
<div class="field-items">
<div class="param">ruleId (required)</div>
<div class="param-desc"><span class="param-type">Path Parameter</span> &mdash; An identifier for the rule. default: null </div><div class="param">spaceId (required)</div>
<div class="param-desc"><span class="param-type">Path Parameter</span> &mdash; An identifier for the space. If <code>/s/</code> and the identifier are omitted from the path, the default space is used. default: null </div>
</div> <!-- field-items -->
<h3 class="field-label">Request headers</h3>
<div class="field-items">
<div class="param">kbn-xsrf (required)</div>
<div class="param-desc"><span class="param-type">Header Parameter</span> &mdash; Cross-site request forgery protection default: null </div>
</div> <!-- field-items -->
<!--Todo: process Response Object and its headers, schema, examples -->
<h3 class="field-label">Produces</h3>
This API call produces the following media types according to the <span class="header">Accept</span> request header;
the media type will be conveyed by the <span class="header">Content-Type</span> response header.
<ul>
<li><code>application/json</code></li>
</ul>
<h3 class="field-label">Responses</h3>
<h4 class="field-label">200</h4>
Indicates a successful call.
<a href="#"></a>
<h4 class="field-label">400</h4>
Bad request
<a href="#400_response">400_response</a>
</div> <!-- method -->
<hr/>
<h2><a name="__Models">Models</a></h2>
[ Jump to <a href="#__Methods">Methods</a> ]
<h3>Table of Contents</h3>
<ol>
<li><a href="#400_response"><code>400_response</code> - Bad request</a></li>
<li><a href="#401_response"><code>401_response</code> - Unsuccessful rule API response</a></li>
<li><a href="#404_response"><code>404_response</code> - </a></li>
<li><a href="#Count"><code>Count</code> - Count</a></li>
@ -2969,6 +3019,19 @@ Any modifications made to this file will be overwritten.
<li><a href="#update_rule_request"><code>update_rule_request</code> - Update rule request</a></li>
</ol>
<div class="model">
<h3><a name="400_response"><code>400_response</code> - Bad request</a> <a class="up" href="#__Models">Up</a></h3>
<div class='model-description'></div>
<div class="field-items">
<div class="param">error </div><div class="param-desc"><span class="param-type"><a href="#string">String</a></span> </div>
<div class="param-enum-header">Enum:</div>
<div class="param-enum">Bad Request</div>
<div class="param">message </div><div class="param-desc"><span class="param-type"><a href="#string">String</a></span> </div>
<div class="param">statusCode </div><div class="param-desc"><span class="param-type"><a href="#integer">Integer</a></span> </div>
<div class="param-enum-header">Enum:</div>
<div class="param-enum">400</div>
</div> <!-- field-items -->
</div>
<div class="model">
<h3><a name="401_response"><code>401_response</code> - Unsuccessful rule API response</a> <a class="up" href="#__Models">Up</a></h3>
<div class='model-description'></div>

View file

@ -30,7 +30,7 @@ Table of Contents
- [Internal HTTP APIs](#internal-http-apis)
- [`GET /internal/alerting/rule/{id}/state`: Get rule state](#get-internalalertingruleidstate-get-rule-state)
- [`GET /internal/alerting/rule/{id}/_alert_summary`: Get rule alert summary](#get-internalalertingruleidalertsummary-get-rule-alert-summary)
- [`POST /internal/alerting/rule/{id}/_update_api_key`: Update rule API key](#post-internalalertingruleidupdateapikey-update-rule-api-key)
- [`POST /api/alerting/rule/{id}/_update_api_key`: Update rule API key](#post-internalalertingruleidupdateapikey-update-rule-api-key)
- [Alert Factory](#alert-factory)
- [Templating Actions](#templating-actions)
- [Examples](#examples)
@ -306,7 +306,7 @@ interface MyRuleTypeAlertContext extends AlertInstanceContext {
}
type MyRuleTypeActionGroups = 'default' | 'warning';
const myRuleType: RuleType<
MyRuleTypeParams,
MyRuleTypeExtractedParams,
@ -380,9 +380,9 @@ const myRuleType: RuleType<
// Only execute if CPU usage is greater than threshold
if (currentCpuUsage > threshold) {
// The first argument is a unique identifier for the alert. In this
// scenario the provided server will be used. Also, this ID will be
// used to make `getState()` return previous state, if any, on
// The first argument is a unique identifier for the alert. In this
// scenario the provided server will be used. Also, this ID will be
// used to make `getState()` return previous state, if any, on
// matching identifiers.
const alert = services.alertFactory.create(server);
@ -395,7 +395,7 @@ const myRuleType: RuleType<
cpuUsage: currentCpuUsage,
});
// 'default' refers to the id of a group of actions to be scheduled
// 'default' refers to the id of a group of actions to be scheduled
// for execution, see 'actions' in create rule section
alert.scheduleActions('default', {
server,
@ -406,8 +406,8 @@ const myRuleType: RuleType<
// Returning updated rule type level state, this will become available
// within the `state` function parameter at the next execution
return {
// This is an example attribute you could set, it makes more sense
// to use this state when the rule type executes multiple
// This is an example attribute you could set, it makes more sense
// to use this state when the rule type executes multiple
// alerts but wants a single place to track certain values.
lastChecked: new Date(),
};
@ -497,7 +497,7 @@ features.registerKibanaFeature({
// grant `read` over our own type
'my-application-id.my-alert-type',
// grant `read` over the built-in IndexThreshold
'.index-threshold',
'.index-threshold',
// grant `read` over Uptime's TLS RuleType
'xpack.uptime.alerts.actionGroups.tls'
],
@ -507,7 +507,7 @@ features.registerKibanaFeature({
// grant `read` over our own type
'my-application-id.my-alert-type',
// grant `read` over the built-in IndexThreshold
'.index-threshold',
'.index-threshold',
// grant `read` over Uptime's TLS RuleType
'xpack.uptime.alerts.actionGroups.tls'
],
@ -555,7 +555,7 @@ features.registerKibanaFeature({
read: [
'my-application-id.my-restricted-rule-type'
],
},
},
alert: {
all: [
'my-application-id.my-rule-type'
@ -563,7 +563,7 @@ features.registerKibanaFeature({
read: [
'my-application-id.my-restricted-rule-type'
],
},
},
},
savedObject: {
all: [],
@ -798,7 +798,7 @@ Query:
|---|---|---|
|dateStart|The date to start looking for alert events in the event log. Either an ISO date string, or a duration string indicating time since now.|string|
### `POST /internal/alerting/rule/{id}/_update_api_key`: Update rule API key
### `POST /api/alerting/rule/{id}/_update_api_key`: Update rule API key
|Property|Description|Type|
|---|---|---|

View file

@ -12,18 +12,26 @@
"url": "https://www.elastic.co/licensing/elastic-license"
}
},
"tags": [
{
"name": "alerting",
"description": "Alerting APIs enable you to create and manage rules and alerts."
}
],
"servers": [
{
"url": "http://localhost:5601",
"description": "local"
}
],
"security": [
{
"basicAuth": []
},
{
"apiKeyAuth": []
}
],
"tags": [
{
"name": "alerting",
"description": "Alerting APIs enable you to create and manage rules and alerts."
}
],
"paths": {
"/s/{spaceId}/api/alerting/rule": {
"post": {
@ -1188,6 +1196,52 @@
}
]
},
"/s/{spaceId}/api/alerting/rule/{ruleId}/_update_api_key": {
"post": {
"summary": "Updates the API key for a rule.",
"operationId": "updateRuleAPIKey",
"description": "The new API key has the credentials of the user that submits the request.",
"tags": [
"alerting"
],
"parameters": [
{
"$ref": "#/components/parameters/kbn_xsrf"
},
{
"$ref": "#/components/parameters/rule_id"
},
{
"$ref": "#/components/parameters/space_id"
}
],
"responses": {
"200": {
"description": "Indicates a successful call."
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/400_response"
}
}
}
}
},
"servers": [
{
"url": "https://localhost:5601"
}
]
},
"servers": [
{
"url": "https://localhost:5601"
}
]
},
"/s/{spaceId}/api/alerting/rule/{ruleId}/alert/{alertId}/_mute": {
"post": {
"summary": "Mutes an alert.",
@ -6595,6 +6649,32 @@
}
}
},
"400_response": {
"title": "Bad request",
"type": "object",
"required": [
"error",
"message",
"statusCode"
],
"properties": {
"error": {
"type": "string",
"enum": [
"Bad Request"
]
},
"message": {
"type": "string"
},
"statusCode": {
"type": "integer",
"enum": [
400
]
}
}
},
"alert_response_properties": {
"title": "Legacy alert response properties",
"type": "object",
@ -7504,13 +7584,5 @@
]
}
}
},
"security": [
{
"basicAuth": []
},
{
"apiKeyAuth": []
}
]
}
}

View file

@ -8,12 +8,15 @@ info:
license:
name: Elastic License 2.0
url: https://www.elastic.co/licensing/elastic-license
tags:
- name: alerting
description: Alerting APIs enable you to create and manage rules and alerts.
servers:
- url: http://localhost:5601
description: local
security:
- basicAuth: []
- apiKeyAuth: []
tags:
- name: alerting
description: Alerting APIs enable you to create and manage rules and alerts.
paths:
/s/{spaceId}/api/alerting/rule:
post:
@ -732,6 +735,30 @@ paths:
- url: https://localhost:5601
servers:
- url: https://localhost:5601
/s/{spaceId}/api/alerting/rule/{ruleId}/_update_api_key:
post:
summary: Updates the API key for a rule.
operationId: updateRuleAPIKey
description: The new API key has the credentials of the user that submits the request.
tags:
- alerting
parameters:
- $ref: '#/components/parameters/kbn_xsrf'
- $ref: '#/components/parameters/rule_id'
- $ref: '#/components/parameters/space_id'
responses:
'200':
description: Indicates a successful call.
'400':
description: Bad request
content:
application/json:
schema:
$ref: '#/components/schemas/400_response'
servers:
- url: https://localhost:5601
servers:
- url: https://localhost:5601
/s/{spaceId}/api/alerting/rule/{ruleId}/alert/{alertId}/_mute:
post:
summary: Mutes an alert.
@ -4503,6 +4530,24 @@ components:
$ref: '#/components/schemas/tags'
throttle:
$ref: '#/components/schemas/throttle'
400_response:
title: Bad request
type: object
required:
- error
- message
- statusCode
properties:
error:
type: string
enum:
- Bad Request
message:
type: string
statusCode:
type: integer
enum:
- 400
alert_response_properties:
title: Legacy alert response properties
type: object
@ -5217,6 +5262,3 @@ components:
id: recovered
name: Recovered
rule_task_timeout: 5m
security:
- basicAuth: []
- apiKeyAuth: []

View file

@ -0,0 +1,17 @@
title: Bad request
type: object
required:
- error
- message
- statusCode
properties:
error:
type: string
enum:
- Bad Request
message:
type: string
statusCode:
type: integer
enum:
- 400

View file

@ -33,6 +33,8 @@ paths:
$ref: 'paths/s@{spaceid}@api@alerting@rule@{ruleid}@_mute_all.yaml'
'/s/{spaceId}/api/alerting/rule/{ruleId}/_unmute_all':
$ref: 'paths/s@{spaceid}@api@alerting@rule@{ruleid}@_unmute_all.yaml'
'/s/{spaceId}/api/alerting/rule/{ruleId}/_update_api_key':
$ref: 'paths/s@{spaceid}@api@alerting@rule@{ruleid}@_update_api_key.yaml'
'/s/{spaceId}/api/alerting/rule/{ruleId}/alert/{alertId}/_mute':
$ref: 'paths/s@{spaceid}@api@alerting@rule@{ruleid}@alert@{alertid}@_mute.yaml'
'/s/{spaceId}/api/alerting/rule/{ruleId}/alert/{alertId}/_unmute':

View file

@ -0,0 +1,23 @@
post:
summary: Updates the API key for a rule.
operationId: updateRuleAPIKey
description: The new API key has the credentials of the user that submits the request.
tags:
- alerting
parameters:
- $ref: ../components/headers/kbn_xsrf.yaml
- $ref: '../components/parameters/rule_id.yaml'
- $ref: '../components/parameters/space_id.yaml'
responses:
'200':
description: Indicates a successful call.
'400':
description: Bad request
content:
application/json:
schema:
$ref: '../components/schemas/400_response.yaml'
servers:
- url: https://localhost:5601
servers:
- url: https://localhost:5601

View file

@ -30,7 +30,7 @@ describe('updateRuleApiKeyRoute', () => {
const [config, handler] = router.post.mock.calls[0];
expect(config.path).toMatchInlineSnapshot(`"/internal/alerting/rule/{id}/_update_api_key"`);
expect(config.path).toMatchInlineSnapshot(`"/api/alerting/rule/{id}/_update_api_key"`);
rulesClient.updateApiKey.mockResolvedValueOnce();

View file

@ -9,7 +9,7 @@ import { IRouter } from '@kbn/core/server';
import { schema } from '@kbn/config-schema';
import { ILicenseState, RuleTypeDisabledError } from '../lib';
import { verifyAccessAndContext } from './lib';
import { AlertingRequestHandlerContext, INTERNAL_BASE_ALERTING_API_PATH } from '../types';
import { AlertingRequestHandlerContext, BASE_ALERTING_API_PATH } from '../types';
const paramSchema = schema.object({
id: schema.string(),
@ -21,7 +21,7 @@ export const updateRuleApiKeyRoute = (
) => {
router.post(
{
path: `${INTERNAL_BASE_ALERTING_API_PATH}/rule/{id}/_update_api_key`,
path: `${BASE_ALERTING_API_PATH}/rule/{id}/_update_api_key`,
validate: {
params: paramSchema,
},

View file

@ -18,7 +18,7 @@ describe('updateAPIKey', () => {
expect(http.post.mock.calls).toMatchInlineSnapshot(`
Array [
Array [
"/internal/alerting/rule/1%2F/_update_api_key",
"/api/alerting/rule/1%2F/_update_api_key",
],
]
`);

View file

@ -6,12 +6,12 @@
*/
import { HttpSetup } from '@kbn/core/public';
import { KueryNode } from '@kbn/es-query';
import { INTERNAL_BASE_ALERTING_API_PATH } from '../../constants';
import { BASE_ALERTING_API_PATH, INTERNAL_BASE_ALERTING_API_PATH } from '../../constants';
import { BulkEditResponse } from '../../../types';
export async function updateAPIKey({ id, http }: { id: string; http: HttpSetup }): Promise<string> {
return http.post<string>(
`${INTERNAL_BASE_ALERTING_API_PATH}/rule/${encodeURIComponent(id)}/_update_api_key`
`${BASE_ALERTING_API_PATH}/rule/${encodeURIComponent(id)}/_update_api_key`
);
}

View file

@ -167,7 +167,7 @@ export class AlertUtils {
public getUpdateApiKeyRequest(alertId: string) {
const request = this.supertestWithoutAuth
.post(`${getUrlPrefix(this.space.id)}/internal/alerting/rule/${alertId}/_update_api_key`)
.post(`${getUrlPrefix(this.space.id)}/api/alerting/rule/${alertId}/_update_api_key`)
.set('kbn-xsrf', 'foo');
if (this.user) {
return request.auth(this.user.username, this.user.password);

View file

@ -397,7 +397,7 @@ export default function userManagedApiKeyTest({ getService }: FtrProviderContext
.post(
`${getUrlPrefix(
SuperuserAtSpace1.space.id
)}/internal/alerting/rule/${ruleId}/_update_api_key`
)}/api/alerting/rule/${ruleId}/_update_api_key`
)
.set('kbn-xsrf', 'foo')
.set('Authorization', `ApiKey ${apiKey}`);
@ -422,7 +422,7 @@ export default function userManagedApiKeyTest({ getService }: FtrProviderContext
.post(
`${getUrlPrefix(
SuperuserAtSpace1.space.id
)}/internal/alerting/rule/${ruleId}/_update_api_key`
)}/api/alerting/rule/${ruleId}/_update_api_key`
)
.set('kbn-xsrf', 'foo');
expect(response.status).to.eql(204);