From c55ba6ceff34c2cbb7e172d43f5848dab210e49c Mon Sep 17 00:00:00 2001 From: Nick Clark Date: Fri, 14 Jul 2023 11:17:25 +1000 Subject: [PATCH 1/9] Add makefile to SLO openapi generation --- .../observability/docs/openapi/slo/Makefile | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 x-pack/plugins/observability/docs/openapi/slo/Makefile diff --git a/x-pack/plugins/observability/docs/openapi/slo/Makefile b/x-pack/plugins/observability/docs/openapi/slo/Makefile new file mode 100644 index 0000000000000..23a1cb7404947 --- /dev/null +++ b/x-pack/plugins/observability/docs/openapi/slo/Makefile @@ -0,0 +1,16 @@ +.DEFAULT_GOAL := help + +.PHONY: validate +validate: ## validate tree + @ npx swagger-cli validate entrypoint.yaml + +.PHONY: bundle +bundle: validate ## generate bundled.yaml and bundled.json + @ npx @redocly/cli bundle entrypoint.yaml --output bundled.yaml --ext yaml + @ npx @redocly/cli bundle entrypoint.yaml --output bundled.json --ext json + @ npx @redocly/cli lint bundled.json + +.PHONY: help +help: ## you're looking at it + @ awk 'BEGIN {FS = ":.*##"; printf "Usage: make \033[36m\033[0m\n\nTargets:\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-10s\033[0m\t%s\n", $$1, $$2 }' $(MAKEFILE_LIST) | column -s$$'\t' -t + From f3006ed8bc34f0b76f12e3d91169490669fc7c41 Mon Sep 17 00:00:00 2001 From: Nick Clark Date: Fri, 14 Jul 2023 11:20:19 +1000 Subject: [PATCH 2/9] Remove oneOf in instances where there is only one type --- .../slo/components/schemas/base_composite_slo_response.yaml | 3 +-- .../openapi/slo/components/schemas/composite_slo_response.yaml | 3 +-- .../slo/components/schemas/create_composite_slo_request.yaml | 3 +-- .../slo/components/schemas/update_composite_slo_request.yaml | 3 +-- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/base_composite_slo_response.yaml b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/base_composite_slo_response.yaml index 8fce7e38f46de..07dd47d1707fd 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/base_composite_slo_response.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/base_composite_slo_response.yaml @@ -18,8 +18,7 @@ properties: objective: $ref: "objective.yaml" sources: - oneOf: - - $ref: "weighted_composite_sources.yaml" + - $ref: "weighted_composite_sources.yaml" createdAt: description: The creation date type: string diff --git a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/composite_slo_response.yaml b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/composite_slo_response.yaml index e4c66379ef554..00a9c3426756e 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/composite_slo_response.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/composite_slo_response.yaml @@ -18,8 +18,7 @@ properties: objective: $ref: "objective.yaml" sources: - oneOf: - - $ref: "weighted_composite_sources.yaml" + - $ref: "weighted_composite_sources.yaml" summary: $ref: "summary.yaml" createdAt: diff --git a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/create_composite_slo_request.yaml b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/create_composite_slo_request.yaml index 46a801c75bba2..97536626c1287 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/create_composite_slo_request.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/create_composite_slo_request.yaml @@ -26,5 +26,4 @@ properties: objective: $ref: "objective.yaml" sources: - oneOf: - - $ref: "weighted_composite_sources.yaml" + - $ref: "weighted_composite_sources.yaml" diff --git a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/update_composite_slo_request.yaml b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/update_composite_slo_request.yaml index 6368b62badf6e..c93578f4404c0 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/update_composite_slo_request.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/update_composite_slo_request.yaml @@ -19,5 +19,4 @@ properties: objective: $ref: "objective.yaml" sources: - oneOf: - - $ref: "weighted_composite_sources.yaml" + - $ref: "weighted_composite_sources.yaml" From a5537510451ada428caeef0771a1f6558f0ffde9 Mon Sep 17 00:00:00 2001 From: Nick Clark Date: Fri, 14 Jul 2023 11:20:36 +1000 Subject: [PATCH 3/9] Add generated bundles --- .../docs/openapi/slo/bundled.json | 1688 ++++++----------- .../docs/openapi/slo/bundled.yaml | 142 +- 2 files changed, 636 insertions(+), 1194 deletions(-) diff --git a/x-pack/plugins/observability/docs/openapi/slo/bundled.json b/x-pack/plugins/observability/docs/openapi/slo/bundled.json index 09295ed296678..05437b3e89028 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/bundled.json +++ b/x-pack/plugins/observability/docs/openapi/slo/bundled.json @@ -37,13 +37,13 @@ } ], "paths": { - "/s/{spaceId}/api/observability/composite_slos": { + "/s/{spaceId}/api/observability/slos": { "post": { - "summary": "Creates a Composite SLO", - "operationId": "createCompositeSlo", + "summary": "Creates an SLO.", + "operationId": "createSloOp", "description": "You must have `all` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", "tags": [ - "composite slo" + "slo" ], "parameters": [ { @@ -58,7 +58,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/create_composite_slo_request" + "$ref": "#/components/schemas/create_slo_request" } } } @@ -69,7 +69,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/create_composite_slo_response" + "$ref": "#/components/schemas/create_slo_response" } } } @@ -105,7 +105,7 @@ } }, "409": { - "description": "Conflict - The Composite SLO id already exists", + "description": "Conflict - The SLO id already exists", "content": { "application/json": { "schema": { @@ -114,14 +114,19 @@ } } } - } + }, + "servers": [ + { + "url": "https://localhost:5601" + } + ] }, "get": { - "summary": "Retrieves a paginated list of composite SLOs with summary", - "operationId": "findCompositeSlo", + "summary": "Retrieves a paginated list of SLOs", + "operationId": "findSlosOp", "description": "You must have the `read` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", "tags": [ - "composite slo" + "slo" ], "parameters": [ { @@ -130,6 +135,29 @@ { "$ref": "#/components/parameters/space_id" }, + { + "name": "name", + "in": "query", + "description": "Filter by name", + "schema": { + "type": "string" + }, + "example": "awesome-service" + }, + { + "name": "indicatorTypes", + "in": "query", + "description": "Filter by indicator type", + "schema": { + "type": "array", + "items": { + "type": "string" + } + }, + "example": [ + "sli.kql.custom" + ] + }, { "name": "page", "in": "query", @@ -157,7 +185,8 @@ "schema": { "type": "string", "enum": [ - "creationTime" + "creationTime", + "indicatorType" ], "default": "creationTime" }, @@ -184,7 +213,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/find_composite_slo_response" + "$ref": "#/components/schemas/find_slo_response" } } } @@ -232,13 +261,13 @@ } } }, - "/s/{spaceId}/api/observability/composite_slos/{compositeSloId}": { + "/s/{spaceId}/api/observability/slos/{sloId}": { "get": { - "summary": "Retrieves a composite SLO", - "operationId": "getCompositeSlo", + "summary": "Retrieves a SLO", + "operationId": "getSloOp", "description": "You must have the `read` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", "tags": [ - "composite slo" + "slo" ], "parameters": [ { @@ -248,7 +277,7 @@ "$ref": "#/components/parameters/space_id" }, { - "$ref": "#/components/parameters/composite_slo_id" + "$ref": "#/components/parameters/slo_id" } ], "responses": { @@ -257,7 +286,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/composite_slo_response" + "$ref": "#/components/schemas/slo_response" } } } @@ -305,11 +334,11 @@ } }, "put": { - "summary": "Updates a composite SLO", - "operationId": "updateCompositeSlo", + "summary": "Updates an SLO", + "operationId": "updateSloOp", "description": "You must have the `write` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", "tags": [ - "composite slo" + "slo" ], "parameters": [ { @@ -319,7 +348,7 @@ "$ref": "#/components/parameters/space_id" }, { - "$ref": "#/components/parameters/composite_slo_id" + "$ref": "#/components/parameters/slo_id" } ], "requestBody": { @@ -327,7 +356,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/update_composite_slo_request" + "$ref": "#/components/schemas/update_slo_request" } } } @@ -338,7 +367,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/base_composite_slo_response" + "$ref": "#/components/schemas/slo_response" } } } @@ -386,11 +415,11 @@ } }, "delete": { - "summary": "Deletes a composite SLO", - "operationId": "deleteCompositeSlo", + "summary": "Deletes an SLO", + "operationId": "deleteSloOp", "description": "You must have the `write` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", "tags": [ - "composite slo" + "slo" ], "parameters": [ { @@ -400,7 +429,7 @@ "$ref": "#/components/parameters/space_id" }, { - "$ref": "#/components/parameters/composite_slo_id" + "$ref": "#/components/parameters/slo_id" } ], "responses": { @@ -450,11 +479,11 @@ } } }, - "/s/{spaceId}/api/observability/slos": { + "/s/{spaceId}/api/observability/slos/{sloId}/enable": { "post": { - "summary": "Creates an SLO.", - "operationId": "createSlo", - "description": "You must have `all` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", + "summary": "Enables an SLO", + "operationId": "enableSloOp", + "description": "You must have the `write` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", "tags": [ "slo" ], @@ -464,28 +493,14 @@ }, { "$ref": "#/components/parameters/space_id" + }, + { + "$ref": "#/components/parameters/slo_id" } ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/create_slo_request" - } - } - } - }, "responses": { - "200": { - "description": "Successful request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/create_slo_response" - } - } - } + "204": { + "description": "Successful request" }, "400": { "description": "Bad request", @@ -517,27 +532,24 @@ } } }, - "409": { - "description": "Conflict - The SLO id already exists", + "404": { + "description": "Not found response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/409_response" + "$ref": "#/components/schemas/404_response" } } } } - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "get": { - "summary": "Retrieves a paginated list of SLOs", - "operationId": "findSlos", - "description": "You must have the `read` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", + } + } + }, + "/s/{spaceId}/api/observability/slos/{sloId}/disable": { + "post": { + "summary": "Disables an SLO", + "operationId": "disableSloOp", + "description": "You must have the `write` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", "tags": [ "slo" ], @@ -549,87 +561,12 @@ "$ref": "#/components/parameters/space_id" }, { - "name": "name", - "in": "query", - "description": "Filter by name", - "schema": { - "type": "string" - }, - "example": "awesome-service" - }, - { - "name": "indicatorTypes", - "in": "query", - "description": "Filter by indicator type", - "schema": { - "type": "array", - "items": { - "type": "string" - } - }, - "example": [ - "sli.kql.custom" - ] - }, - { - "name": "page", - "in": "query", - "description": "The page number to return", - "schema": { - "type": "integer", - "default": 1 - }, - "example": 1 - }, - { - "name": "perPage", - "in": "query", - "description": "The number of SLOs to return per page", - "schema": { - "type": "integer", - "default": 25 - }, - "example": 20 - }, - { - "name": "sortBy", - "in": "query", - "description": "Sort by field", - "schema": { - "type": "string", - "enum": [ - "creationTime", - "indicatorType" - ], - "default": "creationTime" - }, - "example": "creationTime" - }, - { - "name": "sortDirection", - "in": "query", - "description": "Sort order", - "schema": { - "type": "string", - "enum": [ - "asc", - "desc" - ], - "default": "asc" - }, - "example": "asc" + "$ref": "#/components/parameters/slo_id" } ], "responses": { "200": { - "description": "Successful request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/find_slo_response" - } - } - } + "description": "Successful request" }, "400": { "description": "Bad request", @@ -674,10 +611,10 @@ } } }, - "/s/{spaceId}/api/observability/slos/{sloId}": { - "get": { - "summary": "Retrieves a SLO", - "operationId": "getSlo", + "/s/{spaceId}/internal/observability/slos/_historical_summary": { + "post": { + "summary": "Retrieves the historical summary for a list of SLOs", + "operationId": "historicalSummaryOp", "description": "You must have the `read` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", "tags": [ "slo" @@ -688,18 +625,25 @@ }, { "$ref": "#/components/parameters/space_id" - }, - { - "$ref": "#/components/parameters/slo_id" } ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/historical_summary_request" + } + } + } + }, "responses": { "200": { "description": "Successful request", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/slo_response" + "$ref": "#/components/schemas/historical_summary_response" } } } @@ -733,898 +677,62 @@ } } } - }, - "404": { - "description": "Not found response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/404_response" - } - } - } } } + } + } + }, + "components": { + "securitySchemes": { + "basicAuth": { + "type": "http", + "scheme": "basic" }, - "put": { - "summary": "Updates an SLO", - "operationId": "updateSlo", - "description": "You must have the `write` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", - "tags": [ - "slo" - ], - "parameters": [ - { - "$ref": "#/components/parameters/kbn_xsrf" - }, - { - "$ref": "#/components/parameters/space_id" - }, - { - "$ref": "#/components/parameters/slo_id" - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/update_slo_request" - } - } - } - }, - "responses": { - "200": { - "description": "Successful request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/slo_response" - } - } - } - }, - "400": { - "description": "Bad request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/400_response" - } - } - } - }, - "401": { - "description": "Unauthorized response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/401_response" - } - } - } - }, - "403": { - "description": "Unauthorized response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/403_response" - } - } - } - }, - "404": { - "description": "Not found response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/404_response" - } - } - } - } - } - }, - "delete": { - "summary": "Deletes an SLO", - "operationId": "deleteSlo", - "description": "You must have the `write` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", - "tags": [ - "slo" - ], - "parameters": [ - { - "$ref": "#/components/parameters/kbn_xsrf" - }, - { - "$ref": "#/components/parameters/space_id" - }, - { - "$ref": "#/components/parameters/slo_id" - } - ], - "responses": { - "204": { - "description": "Successful request" - }, - "400": { - "description": "Bad request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/400_response" - } - } - } - }, - "401": { - "description": "Unauthorized response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/401_response" - } - } - } - }, - "403": { - "description": "Unauthorized response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/403_response" - } - } - } - }, - "404": { - "description": "Not found response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/404_response" - } - } - } - } - } - } - }, - "/s/{spaceId}/api/observability/slos/{sloId}/enable": { - "post": { - "summary": "Enables an SLO", - "operationId": "enableSlo", - "description": "You must have the `write` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", - "tags": [ - "slo" - ], - "parameters": [ - { - "$ref": "#/components/parameters/kbn_xsrf" - }, - { - "$ref": "#/components/parameters/space_id" - }, - { - "$ref": "#/components/parameters/slo_id" - } - ], - "responses": { - "204": { - "description": "Successful request" - }, - "400": { - "description": "Bad request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/400_response" - } - } - } - }, - "401": { - "description": "Unauthorized response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/401_response" - } - } - } - }, - "403": { - "description": "Unauthorized response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/403_response" - } - } - } - }, - "404": { - "description": "Not found response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/404_response" - } - } - } - } - } - } - }, - "/s/{spaceId}/api/observability/slos/{sloId}/disable": { - "post": { - "summary": "Disables an SLO", - "operationId": "disableSlo", - "description": "You must have the `write` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", - "tags": [ - "slo" - ], - "parameters": [ - { - "$ref": "#/components/parameters/kbn_xsrf" - }, - { - "$ref": "#/components/parameters/space_id" - }, - { - "$ref": "#/components/parameters/slo_id" - } - ], - "responses": { - "200": { - "description": "Successful request" - }, - "400": { - "description": "Bad request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/400_response" - } - } - } - }, - "401": { - "description": "Unauthorized response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/401_response" - } - } - } - }, - "403": { - "description": "Unauthorized response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/403_response" - } - } - } - }, - "404": { - "description": "Not found response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/404_response" - } - } - } - } - } - } - }, - "/s/{spaceId}/internal/observability/slos/_historical_summary": { - "post": { - "summary": "Retrieves the historical summary for a list of SLOs", - "operationId": "historicalSummary", - "description": "You must have the `read` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", - "tags": [ - "slo" - ], - "parameters": [ - { - "$ref": "#/components/parameters/kbn_xsrf" - }, - { - "$ref": "#/components/parameters/space_id" - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/historical_summary_request" - } - } - } - }, - "responses": { - "200": { - "description": "Successful request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/historical_summary_response" - } - } - } - }, - "400": { - "description": "Bad request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/400_response" - } - } - } - }, - "401": { - "description": "Unauthorized response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/401_response" - } - } - } - }, - "403": { - "description": "Unauthorized response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/403_response" - } - } - } - } - } - } - } - }, - "components": { - "securitySchemes": { - "basicAuth": { - "type": "http", - "scheme": "basic" - }, - "apiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "ApiKey" - } - }, - "parameters": { - "kbn_xsrf": { - "schema": { - "type": "string" - }, - "in": "header", - "name": "kbn-xsrf", - "description": "Cross-site request forgery protection", - "required": true - }, - "space_id": { - "in": "path", - "name": "spaceId", - "description": "An identifier for the space. If `/s/` and the identifier are omitted from the path, the default space is used.", - "required": true, - "schema": { - "type": "string", - "example": "default" - } - }, - "composite_slo_id": { - "in": "path", - "name": "compositeSloId", - "description": "An identifier for the composite slo.", - "required": true, - "schema": { - "type": "string", - "example": "9c235211-6834-11ea-a78c-6feb38a34414" - } - }, - "slo_id": { - "in": "path", - "name": "sloId", - "description": "An identifier for the slo.", - "required": true, - "schema": { - "type": "string", - "example": "9c235211-6834-11ea-a78c-6feb38a34414" - } - } - }, - "schemas": { - "time_window_rolling": { - "title": "Rolling", - "required": [ - "duration", - "isRolling" - ], - "description": "Defines properties for rolling time window", - "type": "object", - "properties": { - "duration": { - "description": "the duration formatted as {duration}{unit}", - "type": "string", - "example": "28d" - }, - "isRolling": { - "description": "Indicates a rolling time window", - "type": "boolean", - "example": true - } - } - }, - "budgeting_method": { - "title": "Budgeting method", - "type": "string", - "description": "The budgeting method to use when computing the rollup data.", - "enum": [ - "occurrences", - "timeslices" - ], - "example": "occurrences" - }, - "composite_method": { - "title": "Composite method", - "type": "string", - "description": "The composite method to use for the composite SLO.", - "enum": [ - "weightedAverage" - ], - "example": "weightedAverage" - }, - "objective": { - "title": "Objective", - "required": [ - "target" - ], - "description": "Defines properties for the SLO objective", - "type": "object", - "properties": { - "target": { - "description": "the target objective between 0 and 1 excluded", - "type": "number", - "example": 0.99 - }, - "timeslicesTarget": { - "description": "the target objective for each slice when using a timeslices budgeting method", - "type": "number", - "example": 0.995 - }, - "timeslicesWindow": { - "description": "the duration of each slice when using a timeslices budgeting method, as {duraton}{unit}", - "type": "string", - "example": "5m" - } - } - }, - "weighted_composite_sources": { - "title": "Weighted sources", - "description": "An array of source SLO to use for the weighted average composite.", - "type": "array", - "items": { - "type": "object", - "required": [ - "id", - "revision", - "weight" - ], - "properties": { - "id": { - "description": "The id of the SLO.", - "type": "string", - "example": "8853df00-ae2e-11ed-90af-09bb6422b258" - }, - "revision": { - "description": "The revision number of the SLO.", - "type": "number", - "example": 2 - }, - "weight": { - "description": "The weight to apply to this SLO.", - "type": "number", - "example": 3 - } - } - } - }, - "error_budget": { - "title": "Error budget", - "type": "object", - "properties": { - "initial": { - "type": "number", - "description": "The initial error budget, as 1 - objective", - "example": 0.02 - }, - "consumed": { - "type": "number", - "description": "The error budget consummed, as a percentage of the initial value.", - "example": 0.8 - }, - "remaining": { - "type": "number", - "description": "The error budget remaining, as a percentage of the initial value.", - "example": 0.2 - }, - "isEstimated": { - "type": "boolean", - "description": "Only for SLO defined with occurrences budgeting method and calendar aligned time window.", - "example": true - } - } - }, - "summary": { - "title": "Summary", - "type": "object", - "description": "The SLO computed data", - "properties": { - "status": { - "type": "string", - "enum": [ - "NO_DATA", - "HEALTHY", - "DEGRADING", - "VIOLATED" - ], - "example": "HEALTHY" - }, - "sliValue": { - "type": "number", - "example": 0.9836 - }, - "errorBudget": { - "$ref": "#/components/schemas/error_budget" - } - } - }, - "composite_slo_response": { - "title": "Composite SLO with summary response", - "type": "object", - "properties": { - "id": { - "description": "The identifier of the composite SLO.", - "type": "string", - "example": "8853df00-ae2e-11ed-90af-09bb6422b258" - }, - "name": { - "description": "The name of the composite SLO.", - "type": "string", - "example": "My Service SLO" - }, - "timeWindow": { - "$ref": "#/components/schemas/time_window_rolling" - }, - "budgetingMethod": { - "$ref": "#/components/schemas/budgeting_method" - }, - "compositeMethod": { - "$ref": "#/components/schemas/composite_method" - }, - "objective": { - "$ref": "#/components/schemas/objective" - }, - "sources": { - "oneOf": [ - { - "$ref": "#/components/schemas/weighted_composite_sources" - } - ] - }, - "summary": { - "$ref": "#/components/schemas/summary" - }, - "createdAt": { - "description": "The creation date", - "type": "string", - "example": "2023-01-12T10:03:19.000Z" - }, - "updatedAt": { - "description": "The last update date", - "type": "string", - "example": "2023-01-12T10:03:19.000Z" - } - } - }, - "find_composite_slo_response": { - "title": "Find composite SLO response", - "description": "A paginated response of composite SLOs matching the query.", - "type": "object", - "properties": { - "page": { - "type": "number", - "example": 1 - }, - "perPage": { - "type": "number", - "example": 25 - }, - "total": { - "type": "number", - "example": 34 - }, - "results": { - "type": "array", - "items": { - "$ref": "#/components/schemas/composite_slo_response" - } - } - } - }, - "400_response": { - "title": "Bad request", - "type": "object", - "required": [ - "statusCode", - "error", - "message" - ], - "properties": { - "statusCode": { - "type": "number", - "example": 400 - }, - "error": { - "type": "string", - "example": "Bad Request" - }, - "message": { - "type": "string", - "example": "Invalid value 'foo' supplied to: [...]" - } - } - }, - "401_response": { - "title": "Unauthorized", - "type": "object", - "required": [ - "statusCode", - "error", - "message" - ], - "properties": { - "statusCode": { - "type": "number", - "example": 401 - }, - "error": { - "type": "string", - "example": "Unauthorized" - }, - "message": { - "type": "string", - "example": "[security_exception\n\tRoot causes:\n\t\tsecurity_exception: unable to authenticate user [elastics] for REST request [/_security/_authenticate]]: unable to authenticate user [elastics] for REST request [/_security/_authenticate]" - } - } - }, - "403_response": { - "title": "Unauthorized", - "type": "object", - "required": [ - "statusCode", - "error", - "message" - ], - "properties": { - "statusCode": { - "type": "number", - "example": 403 - }, - "error": { - "type": "string", - "example": "Unauthorized" - }, - "message": { - "type": "string", - "example": "[security_exception\n\tRoot causes:\n\t\tsecurity_exception: unable to authenticate user [elastics] for REST request [/_security/_authenticate]]: unable to authenticate user [elastics] for REST request [/_security/_authenticate]" - } - } - }, - "404_response": { - "title": "Not found", - "type": "object", - "required": [ - "statusCode", - "error", - "message" - ], - "properties": { - "statusCode": { - "type": "number", - "example": 404 - }, - "error": { - "type": "string", - "example": "Not Found" - }, - "message": { - "type": "string", - "example": "SLO [3749f390-03a3-11ee-8139-c7ff60a1692d] not found" - } - } - }, - "create_composite_slo_request": { - "title": "Create composite SLO request", - "description": "The create Composite SLO API request body. The provided source SLOs must exists and their budgeting method and time window must match the one from the composite SLO.\n", - "type": "object", - "required": [ - "name", - "timeWindow", - "budgetingMethod", - "compositeMethod", - "objective", - "sources" - ], - "properties": { - "id": { - "description": "A unique identifier for the composite SLO. Must be between 8 and 36 chars", - "type": "string", - "example": "my-super-composite-slo-id" - }, - "name": { - "description": "A name for the composite SLO.", - "type": "string" - }, - "timeWindow": { - "$ref": "#/components/schemas/time_window_rolling" - }, - "budgetingMethod": { - "$ref": "#/components/schemas/budgeting_method" - }, - "compositeMethod": { - "$ref": "#/components/schemas/composite_method" - }, - "objective": { - "$ref": "#/components/schemas/objective" - }, - "sources": { - "oneOf": [ - { - "$ref": "#/components/schemas/weighted_composite_sources" - } - ] - } - } - }, - "create_composite_slo_response": { - "title": "Create composite SLO response", - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "type": "string", - "example": "8853df00-ae2e-11ed-90af-09bb6422b258" - } - } - }, - "409_response": { - "title": "Conflict", - "type": "object", - "required": [ - "statusCode", - "error", - "message" - ], - "properties": { - "statusCode": { - "type": "number", - "example": 409 - }, - "error": { - "type": "string", - "example": "Conflict" - }, - "message": { - "type": "string", - "example": "SLO [d077e940-1515-11ee-9c50-9d096392f520] already exists" - } - } + "apiKeyAuth": { + "type": "apiKey", + "in": "header", + "name": "ApiKey" + } + }, + "parameters": { + "kbn_xsrf": { + "schema": { + "type": "string" + }, + "in": "header", + "name": "kbn-xsrf", + "description": "Cross-site request forgery protection", + "required": true }, - "update_composite_slo_request": { - "title": "Update composite SLO request", - "description": "The update composite SLO API request body. The provided source SLOs must exists and their budgeting method and time window must match the one from the composite SLO.\n", - "type": "object", - "properties": { - "id": { - "description": "A unique identifier for the composite SLO. Must be between 8 and 36 chars", - "type": "string", - "example": "my-super-composite-slo-id" - }, - "name": { - "description": "A name for the composite SLO.", - "type": "string" - }, - "timeWindow": { - "$ref": "#/components/schemas/time_window_rolling" - }, - "budgetingMethod": { - "$ref": "#/components/schemas/budgeting_method" - }, - "compositeMethod": { - "$ref": "#/components/schemas/composite_method" - }, - "objective": { - "$ref": "#/components/schemas/objective" - }, - "sources": { - "oneOf": [ - { - "$ref": "#/components/schemas/weighted_composite_sources" - } - ] - } + "space_id": { + "in": "path", + "name": "spaceId", + "description": "An identifier for the space. If `/s/` and the identifier are omitted from the path, the default space is used.", + "required": true, + "schema": { + "type": "string", + "example": "default" } }, - "base_composite_slo_response": { - "title": "Composite SLO response", - "type": "object", - "properties": { - "id": { - "description": "The identifier of the composite SLO.", - "type": "string", - "example": "8853df00-ae2e-11ed-90af-09bb6422b258" - }, - "name": { - "description": "The name of the composite SLO.", - "type": "string", - "example": "My Service SLO" - }, - "timeWindow": { - "$ref": "#/components/schemas/time_window_rolling" - }, - "budgetingMethod": { - "$ref": "#/components/schemas/budgeting_method" - }, - "compositeMethod": { - "$ref": "#/components/schemas/composite_method" - }, - "objective": { - "$ref": "#/components/schemas/objective" - }, - "sources": { - "oneOf": [ - { - "$ref": "#/components/schemas/weighted_composite_sources" - } - ] - }, - "createdAt": { - "description": "The creation date", - "type": "string", - "example": "2023-01-12T10:03:19.000Z" - }, - "updatedAt": { - "description": "The last update date", - "type": "string", - "example": "2023-01-12T10:03:19.000Z" - } + "slo_id": { + "in": "path", + "name": "sloId", + "description": "An identifier for the slo.", + "required": true, + "schema": { + "type": "string", + "example": "9c235211-6834-11ea-a78c-6feb38a34414" } - }, - "indicator_properties_custom_kql": { - "title": "Custom KQL", + } + }, + "schemas": { + "indicator_properties_apm_availability": { + "title": "APM availability", "required": [ "type", "params" ], - "description": "Defines properties for a custom KQL indicator type", + "description": "Defines properties for the APM availability indicator type", "type": "object", "properties": { "params": { @@ -1632,51 +740,59 @@ "type": "object", "nullable": false, "required": [ - "index", - "timestampField" + "service", + "environment", + "transactionType", + "transactionName", + "index" ], "properties": { - "index": { - "description": "The index or index pattern to use", + "service": { + "description": "The APM service name", "type": "string", - "example": "my-service-*" + "example": "o11y-app" }, - "filter": { - "description": "the KQL query to filter the documents with.", + "environment": { + "description": "The APM service environment or \"*\"", "type": "string", - "example": "field.environment : \"production\" and service.name : \"my-service\"" + "example": "production" }, - "good": { - "description": "the KQL query used to define the good events.", + "transactionType": { + "description": "The APM transaction type or \"*\"", "type": "string", - "example": "request.latency <= 150 and request.status_code : \"2xx\"" + "example": "request" }, - "total": { - "description": "the KQL query used to define all events.", + "transactionName": { + "description": "The APM transaction name or \"*\"", "type": "string", - "example": "" + "example": "GET /my/api" }, - "timestampField": { - "description": "The timestamp field used in the source indice.\n", + "filter": { + "description": "KQL query used for filtering the data", "type": "string", - "example": "timestamp" + "example": "service.foo : \"bar\"" + }, + "index": { + "description": "The index used by APM metrics", + "type": "string", + "example": "metrics-apm*,apm*" } } }, "type": { "description": "The type of indicator.", "type": "string", - "example": "sli.kql.custom" + "example": "sli.apm.transactionDuration" } } }, - "indicator_properties_apm_availability": { - "title": "APM availability", + "indicator_properties_custom_kql": { + "title": "Custom KQL", "required": [ "type", "params" ], - "description": "Defines properties for the APM availability indicator type", + "description": "Defines properties for a custom KQL indicator type", "type": "object", "properties": { "params": { @@ -1684,49 +800,41 @@ "type": "object", "nullable": false, "required": [ - "service", - "environment", - "transactionType", - "transactionName", - "index" + "index", + "timestampField" ], "properties": { - "service": { - "description": "The APM service name", - "type": "string", - "example": "o11y-app" - }, - "environment": { - "description": "The APM service environment or \"*\"", + "index": { + "description": "The index or index pattern to use", "type": "string", - "example": "production" + "example": "my-service-*" }, - "transactionType": { - "description": "The APM transaction type or \"*\"", + "filter": { + "description": "the KQL query to filter the documents with.", "type": "string", - "example": "request" + "example": "field.environment : \"production\" and service.name : \"my-service\"" }, - "transactionName": { - "description": "The APM transaction name or \"*\"", + "good": { + "description": "the KQL query used to define the good events.", "type": "string", - "example": "GET /my/api" + "example": "request.latency <= 150 and request.status_code : \"2xx\"" }, - "filter": { - "description": "KQL query used for filtering the data", + "total": { + "description": "the KQL query used to define all events.", "type": "string", - "example": "service.foo : \"bar\"" + "example": "" }, - "index": { - "description": "The index used by APM metrics", + "timestampField": { + "description": "The timestamp field used in the source indice.\n", "type": "string", - "example": "metrics-apm*,apm*" + "example": "timestamp" } } }, "type": { "description": "The type of indicator.", "type": "string", - "example": "sli.apm.transactionDuration" + "example": "sli.kql.custom" } } }, @@ -1868,6 +976,11 @@ "description": "The field of the metric.", "type": "string", "example": "processor.processed" + }, + "filter": { + "description": "The filter to apply to the metric.", + "type": "string", + "example": "processor.outcome: \"success\"" } } } @@ -1916,14 +1029,141 @@ "description": "The field of the metric.", "type": "string", "example": "processor.processed" + }, + "filter": { + "description": "The filter to apply to the metric.", + "type": "string", + "example": "processor.outcome: *" } } } }, - "equation": { - "description": "The equation to calculate the \"total\" metric.", + "equation": { + "description": "The equation to calculate the \"total\" metric.", + "type": "string", + "example": "A" + } + } + } + } + }, + "type": { + "description": "The type of indicator.", + "type": "string", + "example": "sli.metric.custom" + } + } + }, + "indicator_properties_histogram": { + "title": "Histogram indicator", + "required": [ + "type", + "params" + ], + "description": "Defines properties for a histogram indicator type", + "type": "object", + "properties": { + "params": { + "description": "An object containing the indicator parameters.", + "type": "object", + "nullable": false, + "required": [ + "index", + "timestampField", + "good", + "total" + ], + "properties": { + "index": { + "description": "The index or index pattern to use", + "type": "string", + "example": "my-service-*" + }, + "filter": { + "description": "the KQL query to filter the documents with.", + "type": "string", + "example": "field.environment : \"production\" and service.name : \"my-service\"" + }, + "timestampField": { + "description": "The timestamp field used in the source indice.\n", + "type": "string", + "example": "timestamp" + }, + "good": { + "description": "An object defining the \"good\" events\n", + "type": "object", + "required": [ + "aggregation", + "field" + ], + "properties": { + "field": { + "description": "The field use to aggregate the good events.", + "type": "string", + "example": "processor.latency" + }, + "aggregation": { + "description": "The type of aggregation to use.", "type": "string", - "example": "A" + "example": "value_count", + "enum": [ + "value_count", + "range" + ] + }, + "filter": { + "description": "The filter for good events.", + "type": "string", + "example": "processor.outcome: \"success\"" + }, + "from": { + "description": "The starting value of the range. Only required for \"range\" aggregations.", + "type": "number", + "example": 0 + }, + "to": { + "description": "The ending value of the range. Only required for \"range\" aggregations.", + "type": "number", + "example": 100 + } + } + }, + "total": { + "description": "An object defining the \"total\" events\n", + "type": "object", + "required": [ + "aggregation", + "field" + ], + "properties": { + "field": { + "description": "The field use to aggregate the good events.", + "type": "string", + "example": "processor.latency" + }, + "aggregation": { + "description": "The type of aggregation to use.", + "type": "string", + "example": "value_count", + "enum": [ + "value_count", + "range" + ] + }, + "filter": { + "description": "The filter for total events.", + "type": "string", + "example": "processor.outcome : *" + }, + "from": { + "description": "The starting value of the range. Only required for \"range\" aggregations.", + "type": "number", + "example": 0 + }, + "to": { + "description": "The ending value of the range. Only required for \"range\" aggregations.", + "type": "number", + "example": 100 } } } @@ -1932,28 +1172,67 @@ "type": { "description": "The type of indicator.", "type": "string", - "example": "sli.metric.custom" + "example": "sli.histogram.custom" } } }, - "time_window_calendar_aligned": { - "title": "Calendar aligned", + "time_window": { + "title": "Time window", "required": [ "duration", - "isCalendar" + "type" ], - "description": "Defines properties for calendar aligned time window", + "description": "Defines properties for the SLO time window", "type": "object", "properties": { "duration": { - "description": "the duration formatted as {duration}{unit}, accept '1w' (weekly calendar) or '1M' (monthly calendar) only", + "description": "the duration formatted as {duration}{unit}. Accepted values for rolling: 7d, 30d, 90d. Accepted values for calendar aligned: 1w (weekly) or 1M (monthly)", "type": "string", - "example": "1M" + "example": "30d" }, - "isCalendar": { - "description": "Indicates a calendar aligned time window", - "type": "boolean", - "example": true + "type": { + "description": "Indicates weither the time window is a rolling or a calendar aligned time window.", + "type": "string", + "example": "rolling", + "enum": [ + "rolling", + "calendarAligned" + ] + } + } + }, + "budgeting_method": { + "title": "Budgeting method", + "type": "string", + "description": "The budgeting method to use when computing the rollup data.", + "enum": [ + "occurrences", + "timeslices" + ], + "example": "occurrences" + }, + "objective": { + "title": "Objective", + "required": [ + "target" + ], + "description": "Defines properties for the SLO objective", + "type": "object", + "properties": { + "target": { + "description": "the target objective between 0 and 1 excluded", + "type": "number", + "example": 0.99 + }, + "timesliceTarget": { + "description": "the target objective for each slice when using a timeslices budgeting method", + "type": "number", + "example": 0.995 + }, + "timesliceWindow": { + "description": "the duration of each slice when using a timeslices budgeting method, as {duraton}{unit}", + "type": "string", + "example": "5m" } } }, @@ -1974,6 +1253,60 @@ } } }, + "summary_status": { + "title": "summary status", + "type": "string", + "enum": [ + "NO_DATA", + "HEALTHY", + "DEGRADING", + "VIOLATED" + ], + "example": "HEALTHY" + }, + "error_budget": { + "title": "Error budget", + "type": "object", + "properties": { + "initial": { + "type": "number", + "description": "The initial error budget, as 1 - objective", + "example": 0.02 + }, + "consumed": { + "type": "number", + "description": "The error budget consummed, as a percentage of the initial value.", + "example": 0.8 + }, + "remaining": { + "type": "number", + "description": "The error budget remaining, as a percentage of the initial value.", + "example": 0.2 + }, + "isEstimated": { + "type": "boolean", + "description": "Only for SLO defined with occurrences budgeting method and calendar aligned time window.", + "example": true + } + } + }, + "summary": { + "title": "Summary", + "type": "object", + "description": "The SLO computed data", + "properties": { + "status": { + "$ref": "#/components/schemas/summary_status" + }, + "sliValue": { + "type": "number", + "example": 0.9836 + }, + "errorBudget": { + "$ref": "#/components/schemas/error_budget" + } + } + }, "slo_response": { "title": "SLO response", "type": "object", @@ -1994,6 +1327,15 @@ "example": "My SLO description" }, "indicator": { + "discriminator": { + "propertyName": "type", + "mapping": { + "sli.apm.transactionErrorRate": "#/components/schemas/indicator_properties_apm_availability", + "sli.kql.custom": "#/components/schemas/indicator_properties_custom_kql", + "sli.apm.transactionDuration": "#/components/schemas/indicator_properties_apm_latency", + "sli.apm.sli.metric.custom": "#/components/schemas/indicator_properties_custom_metric" + } + }, "oneOf": [ { "$ref": "#/components/schemas/indicator_properties_custom_kql" @@ -2006,19 +1348,15 @@ }, { "$ref": "#/components/schemas/indicator_properties_custom_metric" - } - ] - }, - "timeWindow": { - "oneOf": [ - { - "$ref": "#/components/schemas/time_window_rolling" }, { - "$ref": "#/components/schemas/time_window_calendar_aligned" + "$ref": "#/components/schemas/indicator_properties_histogram" } ] }, + "timeWindow": { + "$ref": "#/components/schemas/time_window" + }, "budgetingMethod": { "$ref": "#/components/schemas/budgeting_method" }, @@ -2078,6 +1416,98 @@ } } }, + "400_response": { + "title": "Bad request", + "type": "object", + "required": [ + "statusCode", + "error", + "message" + ], + "properties": { + "statusCode": { + "type": "number", + "example": 400 + }, + "error": { + "type": "string", + "example": "Bad Request" + }, + "message": { + "type": "string", + "example": "Invalid value 'foo' supplied to: [...]" + } + } + }, + "401_response": { + "title": "Unauthorized", + "type": "object", + "required": [ + "statusCode", + "error", + "message" + ], + "properties": { + "statusCode": { + "type": "number", + "example": 401 + }, + "error": { + "type": "string", + "example": "Unauthorized" + }, + "message": { + "type": "string", + "example": "[security_exception\n\tRoot causes:\n\t\tsecurity_exception: unable to authenticate user [elastics] for REST request [/_security/_authenticate]]: unable to authenticate user [elastics] for REST request [/_security/_authenticate]" + } + } + }, + "403_response": { + "title": "Unauthorized", + "type": "object", + "required": [ + "statusCode", + "error", + "message" + ], + "properties": { + "statusCode": { + "type": "number", + "example": 403 + }, + "error": { + "type": "string", + "example": "Unauthorized" + }, + "message": { + "type": "string", + "example": "[security_exception\n\tRoot causes:\n\t\tsecurity_exception: unable to authenticate user [elastics] for REST request [/_security/_authenticate]]: unable to authenticate user [elastics] for REST request [/_security/_authenticate]" + } + } + }, + "404_response": { + "title": "Not found", + "type": "object", + "required": [ + "statusCode", + "error", + "message" + ], + "properties": { + "statusCode": { + "type": "number", + "example": 404 + }, + "error": { + "type": "string", + "example": "Not Found" + }, + "message": { + "type": "string", + "example": "SLO [3749f390-03a3-11ee-8139-c7ff60a1692d] not found" + } + } + }, "create_slo_request": { "title": "Create SLO request", "description": "The create SLO API request body varies depending on the type of indicator, time window and budgeting method.\n", @@ -2117,19 +1547,15 @@ }, { "$ref": "#/components/schemas/indicator_properties_custom_metric" - } - ] - }, - "timeWindow": { - "oneOf": [ - { - "$ref": "#/components/schemas/time_window_rolling" }, { - "$ref": "#/components/schemas/time_window_calendar_aligned" + "$ref": "#/components/schemas/indicator_properties_histogram" } ] }, + "timeWindow": { + "$ref": "#/components/schemas/time_window" + }, "budgetingMethod": { "$ref": "#/components/schemas/budgeting_method" }, @@ -2154,6 +1580,29 @@ } } }, + "409_response": { + "title": "Conflict", + "type": "object", + "required": [ + "statusCode", + "error", + "message" + ], + "properties": { + "statusCode": { + "type": "number", + "example": 409 + }, + "error": { + "type": "string", + "example": "Conflict" + }, + "message": { + "type": "string", + "example": "SLO [d077e940-1515-11ee-9c50-9d096392f520] already exists" + } + } + }, "update_slo_request": { "title": "Update SLO request", "description": "The update SLO API request body varies depending on the type of indicator, time window and budgeting method. Partial update is handled.\n", @@ -2180,19 +1629,15 @@ }, { "$ref": "#/components/schemas/indicator_properties_custom_metric" - } - ] - }, - "timeWindow": { - "oneOf": [ - { - "$ref": "#/components/schemas/time_window_rolling" }, { - "$ref": "#/components/schemas/time_window_calendar_aligned" + "$ref": "#/components/schemas/indicator_properties_histogram" } ] }, + "timeWindow": { + "$ref": "#/components/schemas/time_window" + }, "budgetingMethod": { "$ref": "#/components/schemas/budgeting_method" }, @@ -2234,14 +1679,7 @@ "example": "2022-01-01T00:00:00.000Z" }, "status": { - "type": "string", - "enum": [ - "NO_DATA", - "HEALTHY", - "DEGRADING", - "VIOLATED" - ], - "example": "HEALTHY" + "$ref": "#/components/schemas/summary_status" }, "sliValue": { "type": "number", diff --git a/x-pack/plugins/observability/docs/openapi/slo/bundled.yaml b/x-pack/plugins/observability/docs/openapi/slo/bundled.yaml index d1a2d233328c6..624c641aca5d3 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/bundled.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/bundled.yaml @@ -8,19 +8,22 @@ info: license: name: Elastic License 2.0 url: https://www.elastic.co/licensing/elastic-license +servers: + - url: http://localhost:5601 + description: local +security: + - basicAuth: [] + - apiKeyAuth: [] tags: - name: slo description: SLO APIs enable you to define, manage and track service-level objectives - name: composite slo description: Composite SLO APIs enable you to define, manage and track a group of SLOs. -servers: - - url: http://localhost:5601 - description: local paths: /s/{spaceId}/api/observability/slos: post: summary: Creates an SLO. - operationId: createSlo + operationId: createSloOp description: | You must have `all` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges. tags: @@ -69,7 +72,7 @@ paths: - url: https://localhost:5601 get: summary: Retrieves a paginated list of SLOs - operationId: findSlos + operationId: findSlosOp description: | You must have the `read` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges. tags: @@ -160,7 +163,7 @@ paths: /s/{spaceId}/api/observability/slos/{sloId}: get: summary: Retrieves a SLO - operationId: getSlo + operationId: getSloOp description: | You must have the `read` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges. tags: @@ -202,7 +205,7 @@ paths: $ref: '#/components/schemas/404_response' put: summary: Updates an SLO - operationId: updateSlo + operationId: updateSloOp description: | You must have the `write` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges. tags: @@ -250,7 +253,7 @@ paths: $ref: '#/components/schemas/404_response' delete: summary: Deletes an SLO - operationId: deleteSlo + operationId: deleteSloOp description: | You must have the `write` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges. tags: @@ -289,7 +292,7 @@ paths: /s/{spaceId}/api/observability/slos/{sloId}/enable: post: summary: Enables an SLO - operationId: enableSlo + operationId: enableSloOp description: | You must have the `write` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges. tags: @@ -328,7 +331,7 @@ paths: /s/{spaceId}/api/observability/slos/{sloId}/disable: post: summary: Disables an SLO - operationId: disableSlo + operationId: disableSloOp description: | You must have the `write` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges. tags: @@ -367,7 +370,7 @@ paths: /s/{spaceId}/internal/observability/slos/_historical_summary: post: summary: Retrieves the historical summary for a list of SLOs - operationId: historicalSummary + operationId: historicalSummaryOp description: | You must have the `read` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges. tags: @@ -440,47 +443,6 @@ components: type: string example: 9c235211-6834-11ea-a78c-6feb38a34414 schemas: - indicator_properties_custom_kql: - title: Custom KQL - required: - - type - - params - description: Defines properties for a custom KQL indicator type - type: object - properties: - params: - description: An object containing the indicator parameters. - type: object - nullable: false - required: - - index - - timestampField - properties: - index: - description: The index or index pattern to use - type: string - example: my-service-* - filter: - description: the KQL query to filter the documents with. - type: string - example: 'field.environment : "production" and service.name : "my-service"' - good: - description: the KQL query used to define the good events. - type: string - example: 'request.latency <= 150 and request.status_code : "2xx"' - total: - description: the KQL query used to define all events. - type: string - example: '' - timestampField: - description: | - The timestamp field used in the source indice. - type: string - example: timestamp - type: - description: The type of indicator. - type: string - example: sli.kql.custom indicator_properties_apm_availability: title: APM availability required: @@ -528,6 +490,47 @@ components: description: The type of indicator. type: string example: sli.apm.transactionDuration + indicator_properties_custom_kql: + title: Custom KQL + required: + - type + - params + description: Defines properties for a custom KQL indicator type + type: object + properties: + params: + description: An object containing the indicator parameters. + type: object + nullable: false + required: + - index + - timestampField + properties: + index: + description: The index or index pattern to use + type: string + example: my-service-* + filter: + description: the KQL query to filter the documents with. + type: string + example: 'field.environment : "production" and service.name : "my-service"' + good: + description: the KQL query used to define the good events. + type: string + example: 'request.latency <= 150 and request.status_code : "2xx"' + total: + description: the KQL query used to define all events. + type: string + example: '' + timestampField: + description: | + The timestamp field used in the source indice. + type: string + example: timestamp + type: + description: The type of indicator. + type: string + example: sli.kql.custom indicator_properties_apm_latency: title: APM latency required: @@ -853,6 +856,15 @@ components: description: Configure how often the transform runs, default 1m type: string example: 5m + summary_status: + title: summary status + type: string + enum: + - NO_DATA + - HEALTHY + - DEGRADING + - VIOLATED + example: HEALTHY error_budget: title: Error budget type: object @@ -879,13 +891,7 @@ components: description: The SLO computed data properties: status: - type: string - enum: - - NO_DATA - - HEALTHY - - DEGRADING - - VIOLATED - example: HEALTHY + $ref: '#/components/schemas/summary_status' sliValue: type: number example: 0.9836 @@ -908,6 +914,13 @@ components: type: string example: My SLO description indicator: + discriminator: + propertyName: type + mapping: + sli.apm.transactionErrorRate: '#/components/schemas/indicator_properties_apm_availability' + sli.kql.custom: '#/components/schemas/indicator_properties_custom_kql' + sli.apm.transactionDuration: '#/components/schemas/indicator_properties_apm_latency' + sli.apm.sli.metric.custom: '#/components/schemas/indicator_properties_custom_metric' oneOf: - $ref: '#/components/schemas/indicator_properties_custom_kql' - $ref: '#/components/schemas/indicator_properties_apm_availability' @@ -1142,18 +1155,9 @@ components: type: string example: '2022-01-01T00:00:00.000Z' status: - type: string - enum: - - NO_DATA - - HEALTHY - - DEGRADING - - VIOLATED - example: HEALTHY + $ref: '#/components/schemas/summary_status' sliValue: type: number example: 0.9836 errorBudget: $ref: '#/components/schemas/error_budget' -security: - - basicAuth: [] - - apiKeyAuth: [] From 0cc68fa371949803e69dcb620e0387035a3f574c Mon Sep 17 00:00:00 2001 From: Nick Clark Date: Fri, 14 Jul 2023 11:21:00 +1000 Subject: [PATCH 4/9] Break out reusable summary status schema --- .../components/schemas/historical_summary_response.yaml | 8 +------- .../docs/openapi/slo/components/schemas/summary.yaml | 8 +------- .../openapi/slo/components/schemas/summary_status.yaml | 8 ++++++++ 3 files changed, 10 insertions(+), 14 deletions(-) create mode 100644 x-pack/plugins/observability/docs/openapi/slo/components/schemas/summary_status.yaml diff --git a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/historical_summary_response.yaml b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/historical_summary_response.yaml index 923d6acbeaa93..9824b8cb9efe1 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/historical_summary_response.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/historical_summary_response.yaml @@ -9,13 +9,7 @@ additionalProperties: type: string example: "2022-01-01T00:00:00.000Z" status: - type: string - enum: - - NO_DATA - - HEALTHY - - DEGRADING - - VIOLATED - example: "HEALTHY" + $ref: './summary_status.yaml' sliValue: type: number example: 0.9836 diff --git a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/summary.yaml b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/summary.yaml index bc8c14e5e8bb1..a7b1be7d053b1 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/summary.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/summary.yaml @@ -3,13 +3,7 @@ type: object description: The SLO computed data properties: status: - type: string - enum: - - NO_DATA - - HEALTHY - - DEGRADING - - VIOLATED - example: "HEALTHY" + $ref: './summary_status.yaml' sliValue: type: number example: 0.9836 diff --git a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/summary_status.yaml b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/summary_status.yaml new file mode 100644 index 0000000000000..1dc19a83fe430 --- /dev/null +++ b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/summary_status.yaml @@ -0,0 +1,8 @@ +title: summary status +type: string +enum: + - NO_DATA + - HEALTHY + - DEGRADING + - VIOLATED +example: HEALTHY \ No newline at end of file From 7a2afb38ae77bb20f0e2cb623a5cc52106423916 Mon Sep 17 00:00:00 2001 From: Nick Clark Date: Fri, 14 Jul 2023 11:21:13 +1000 Subject: [PATCH 5/9] Add type discriminator to slo response --- .../docs/openapi/slo/components/schemas/slo_response.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/slo_response.yaml b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/slo_response.yaml index 112191e55654b..b77d5c49cf827 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/slo_response.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/slo_response.yaml @@ -14,6 +14,13 @@ properties: type: string example: My SLO description indicator: + discriminator: + propertyName: type + mapping: + sli.apm.transactionErrorRate: './indicator_properties_apm_availability.yaml' + sli.kql.custom: './indicator_properties_custom_kql.yaml' + sli.apm.transactionDuration: './indicator_properties_apm_latency.yaml' + sli.apm.sli.metric.custom: './indicator_properties_custom_metric.yaml' oneOf: - $ref: "indicator_properties_custom_kql.yaml" - $ref: "indicator_properties_apm_availability.yaml" From 24ea758c34234dab8b2ae6870637e02df0bfb7c5 Mon Sep 17 00:00:00 2001 From: Nick Clark Date: Fri, 14 Jul 2023 11:21:57 +1000 Subject: [PATCH 6/9] Append 'Op' to all operationIDs to prevent conflicts --- .../openapi/slo/paths/s@{spaceid}@api@composite_slos.yaml | 4 ++-- .../s@{spaceid}@api@composite_slos@{compositesloid}.yaml | 6 +++--- .../docs/openapi/slo/paths/s@{spaceid}@api@slos.yaml | 4 ++-- .../slo/paths/s@{spaceid}@api@slos@_historical_summary.yaml | 2 +- .../openapi/slo/paths/s@{spaceid}@api@slos@{sloid}.yaml | 6 +++--- .../slo/paths/s@{spaceid}@api@slos@{sloid}@{disable}.yaml | 2 +- .../slo/paths/s@{spaceid}@api@slos@{sloid}@{enable}.yaml | 2 +- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@composite_slos.yaml b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@composite_slos.yaml index d77431452136a..94230cde86002 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@composite_slos.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@composite_slos.yaml @@ -1,6 +1,6 @@ post: summary: Creates a Composite SLO - operationId: createCompositeSlo + operationId: createCompositeSloOp description: > You must have `all` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges. @@ -49,7 +49,7 @@ post: get: summary: Retrieves a paginated list of composite SLOs with summary - operationId: findCompositeSlo + operationId: findCompositeSloOp description: > You must have the `read` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges. diff --git a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@composite_slos@{compositesloid}.yaml b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@composite_slos@{compositesloid}.yaml index bca3976b80fcd..826ed87a27cd8 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@composite_slos@{compositesloid}.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@composite_slos@{compositesloid}.yaml @@ -1,6 +1,6 @@ get: summary: Retrieves a composite SLO - operationId: getCompositeSlo + operationId: getCompositeSloOp description: > You must have the `read` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges. @@ -44,7 +44,7 @@ get: put: summary: Updates a composite SLO - operationId: updateCompositeSlo + operationId: updateCompositeSloOp description: > You must have the `write` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges. @@ -94,7 +94,7 @@ put: delete: summary: Deletes a composite SLO - operationId: deleteCompositeSlo + operationId: deleteCompositeSloOp description: > You must have the `write` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges. diff --git a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos.yaml b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos.yaml index 68c0c602448dc..36ac4cb27e3b7 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos.yaml @@ -1,6 +1,6 @@ post: summary: Creates an SLO. - operationId: createSlo + operationId: createSloOp description: > You must have `all` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges. @@ -51,7 +51,7 @@ post: get: summary: Retrieves a paginated list of SLOs - operationId: findSlos + operationId: findSlosOp description: > You must have the `read` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges. diff --git a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@_historical_summary.yaml b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@_historical_summary.yaml index 6ce99505894cf..a1394e1f28379 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@_historical_summary.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@_historical_summary.yaml @@ -1,6 +1,6 @@ post: summary: Retrieves the historical summary for a list of SLOs - operationId: historicalSummary + operationId: historicalSummaryOp description: > You must have the `read` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges. diff --git a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@{sloid}.yaml b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@{sloid}.yaml index 66a5ddd7825a8..d081ba31b83f2 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@{sloid}.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@{sloid}.yaml @@ -1,6 +1,6 @@ get: summary: Retrieves a SLO - operationId: getSlo + operationId: getSloOp description: > You must have the `read` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges. @@ -44,7 +44,7 @@ get: put: summary: Updates an SLO - operationId: updateSlo + operationId: updateSloOp description: > You must have the `write` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges. @@ -94,7 +94,7 @@ put: delete: summary: Deletes an SLO - operationId: deleteSlo + operationId: deleteSloOp description: > You must have the `write` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges. diff --git a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@{sloid}@{disable}.yaml b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@{sloid}@{disable}.yaml index 4932e9cf78c36..2e756641b428c 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@{sloid}@{disable}.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@{sloid}@{disable}.yaml @@ -1,6 +1,6 @@ post: summary: Disables an SLO - operationId: disableSlo + operationId: disableSloOp description: > You must have the `write` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges. diff --git a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@{sloid}@{enable}.yaml b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@{sloid}@{enable}.yaml index 4ddda2bc94b60..2ff3b9de58388 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@{sloid}@{enable}.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@{sloid}@{enable}.yaml @@ -1,6 +1,6 @@ post: summary: Enables an SLO - operationId: enableSlo + operationId: enableSloOp description: > You must have the `write` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges. From 861df99b0eeec758de5c6a42433247d70af991b3 Mon Sep 17 00:00:00 2001 From: Nick Clark Date: Fri, 14 Jul 2023 11:31:11 +1000 Subject: [PATCH 7/9] Add lint target and update README --- .../observability/docs/openapi/slo/Makefile | 14 +++++++++----- .../observability/docs/openapi/slo/README.md | 13 ++++++------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/x-pack/plugins/observability/docs/openapi/slo/Makefile b/x-pack/plugins/observability/docs/openapi/slo/Makefile index 23a1cb7404947..60599ba378c57 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/Makefile +++ b/x-pack/plugins/observability/docs/openapi/slo/Makefile @@ -2,15 +2,19 @@ .PHONY: validate validate: ## validate tree - @ npx swagger-cli validate entrypoint.yaml + @npx swagger-cli validate entrypoint.yaml .PHONY: bundle bundle: validate ## generate bundled.yaml and bundled.json - @ npx @redocly/cli bundle entrypoint.yaml --output bundled.yaml --ext yaml - @ npx @redocly/cli bundle entrypoint.yaml --output bundled.json --ext json - @ npx @redocly/cli lint bundled.json + @npx @redocly/cli bundle entrypoint.yaml --output bundled.yaml --ext yaml + @npx @redocly/cli bundle entrypoint.yaml --output bundled.json --ext json + @$(MAKE) lint + +.PHONY: lint +lint: ## lint bundled.json + @npx @redocly/cli lint bundled.json .PHONY: help help: ## you're looking at it - @ awk 'BEGIN {FS = ":.*##"; printf "Usage: make \033[36m\033[0m\n\nTargets:\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-10s\033[0m\t%s\n", $$1, $$2 }' $(MAKEFILE_LIST) | column -s$$'\t' -t + @awk 'BEGIN {FS = ":.*##"; printf "Usage: make \033[36m\033[0m\n\nTargets:\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-10s\033[0m\t%s\n", $$1, $$2 }' $(MAKEFILE_LIST) | column -s$$'\t' -t diff --git a/x-pack/plugins/observability/docs/openapi/slo/README.md b/x-pack/plugins/observability/docs/openapi/slo/README.md index 440e560bf62f1..d7bd91627a5ef 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/README.md +++ b/x-pack/plugins/observability/docs/openapi/slo/README.md @@ -13,22 +13,21 @@ A guide about the OpenApi specification can be found at [https://swagger.io/docs ## Tools -It is possible to validate the docs before bundling them with the following +It is possible to manually validate the docs before bundling them with the following command in the `x-pack/plugins/observability/docs/openapi/slo` folder: ```bash - npx swagger-cli validate entrypoint.yaml +make validate ``` -Then you can generate the `bundled` files by running the following commands: +Then you can generate the `bundled` files by running the following command- this target will automatically validate inputs and lint the result: ```bash - npx @redocly/cli bundle entrypoint.yaml --output bundled.yaml --ext yaml - npx @redocly/cli bundle entrypoint.yaml --output bundled.json --ext json +make bundle ``` -After generating the json bundle ensure that it is also valid by running the following command: +To lint the generated bundle manually, run: ```bash - npx @redocly/cli lint bundled.json +make lint ``` From 954bf0c4eb529099a217468a1c6aa5f42b7f8a97 Mon Sep 17 00:00:00 2001 From: Nick Clark Date: Sat, 15 Jul 2023 07:35:02 +1000 Subject: [PATCH 8/9] Update x-pack/plugins/observability/docs/openapi/slo/components/schemas/slo_response.yaml Co-authored-by: Kevin Delemme --- .../docs/openapi/slo/components/schemas/slo_response.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/slo_response.yaml b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/slo_response.yaml index b77d5c49cf827..c8a4788c8a3de 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/slo_response.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/slo_response.yaml @@ -20,7 +20,8 @@ properties: sli.apm.transactionErrorRate: './indicator_properties_apm_availability.yaml' sli.kql.custom: './indicator_properties_custom_kql.yaml' sli.apm.transactionDuration: './indicator_properties_apm_latency.yaml' - sli.apm.sli.metric.custom: './indicator_properties_custom_metric.yaml' + sli.metric.custom: 'indicator_properties_custom_metric.yaml' + sli.histogram.custom: 'indicator_properties_histogram.yaml' oneOf: - $ref: "indicator_properties_custom_kql.yaml" - $ref: "indicator_properties_apm_availability.yaml" From 54278aad314903f0c8b9974757f69d1b8572fa1d Mon Sep 17 00:00:00 2001 From: Nick Clark Date: Sat, 15 Jul 2023 21:51:06 +1000 Subject: [PATCH 9/9] rename Makefile to makefile --- .../plugins/observability/docs/openapi/slo/{Makefile => makefile} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename x-pack/plugins/observability/docs/openapi/slo/{Makefile => makefile} (100%) diff --git a/x-pack/plugins/observability/docs/openapi/slo/Makefile b/x-pack/plugins/observability/docs/openapi/slo/makefile similarity index 100% rename from x-pack/plugins/observability/docs/openapi/slo/Makefile rename to x-pack/plugins/observability/docs/openapi/slo/makefile