-
Notifications
You must be signed in to change notification settings - Fork 8.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Fleet] Automate the generation of Fleet's OpenAPI spec through @kbn/config-schema
#184685
Comments
Pinging @elastic/fleet (Team:Fleet) |
New fleet API docs: https://www.elastic.co/docs/api/doc/kibana/operation/operation-get-enrollment-api-keys Currently this reads from the existing When we move all APIs to use kibana/oas_docs/scripts/merge_ess_oas.js Line 23 in f15e825
|
It seems not supported yet to add examples yet, there is an open issue for it: #188926 |
## Summary Part of #184685 First set of changes, I'm planning to do more prs for the remaining endpoints. Will also look at making sure these schema definitions are included in the final kibana `bundle.json`, related doc: https://elasticco.atlassian.net/wiki/spaces/DOC/pages/450494532/API+reference+docs When all schema definitions are moved to code, the fleet/openapi folder can be deleted. To check the result, add to `kibana.dev.yml`: `server.oas.enabled: true` And then in kibana console, query: ``` GET kbn:/api/oas?pathStartsWith=/api/fleet/setup GET kbn:/api/oas?pathStartsWith=/api/fleet/agents/setup GET kbn:/api/oas?pathStartsWith=/api/fleet/package_policies GET kbn:/api/oas?pathStartsWith=/api/fleet/package_policies/delete GET kbn:/api/oas?pathStartsWith=/api/fleet/settings GET kbn:/api/oas?pathStartsWith=/internal/fleet/settings/enrollment ``` To generate the bundle from code, run: ``` node scripts/capture_oas_snapshot --include-path /api/fleet --no-serverless --update # writes to oas_docs/bundle.json ``` Response: ``` { "openapi": "3.0.0", "info": { "title": "Kibana HTTP APIs", "version": "0.0.0" }, "servers": [ { "url": "http://localhost:5603/julia" } ], "paths": { "/api/fleet/setup": { "post": { "summary": "", "tags": [], "description": "Initiate Fleet setup", "responses": { "200": { "content": { "application/json; Elastic-Api-Version=2023-10-31": { "schema": { "type": "object", "description": "A summary of the result of Fleet's `setup` lifecycle. If `isInitialized` is true, Fleet is ready to accept agent enrollment. `nonFatalErrors` may include useful insight into non-blocking issues with Fleet setup.", "properties": { "isInitialized": { "type": "boolean" }, "nonFatalErrors": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string" }, "message": { "type": "string" } }, "additionalProperties": false, "required": [ "name", "message" ] } } }, "additionalProperties": false, "required": [ "isInitialized", "nonFatalErrors" ] } } } }, "400": { "content": { "application/json; Elastic-Api-Version=2023-10-31": { "schema": { "type": "object", "description": "Generic Error", "properties": { "statusCode": { "type": "number" }, "error": { "type": "string" }, "message": { "type": "string" } }, "additionalProperties": false, "required": [ "statusCode", "error", "message" ] } } } }, "500": { "content": { "application/json; Elastic-Api-Version=2023-10-31": { "schema": { "type": "object", "description": "Internal Server Error", "properties": { "message": { "type": "string" } }, "additionalProperties": false, "required": [ "message" ] } } } } }, "parameters": [ { "in": "header", "name": "elastic-api-version", "description": "The version of the API to use", "schema": { "type": "string", "enum": [ "2023-10-31" ], "default": "2023-10-31" } }, { "description": "A required header to protect against CSRF attacks", "in": "header", "name": "kbn-xsrf", "required": true, "schema": { "example": "true", "type": "string" } } ], "operationId": "%2Fapi%2Ffleet%2Fsetup#0" } } }, "components": { "schemas": {}, "securitySchemes": { "basicAuth": { "type": "http", "scheme": "basic" }, "apiKeyAuth": { "type": "apiKey", "in": "header", "name": "Authorization" } } }, "security": [ { "basicAuth": [] } ], "tags": [] } ```
…" (#192840) This reverts commit 1116ac6. Related to #184685 There were a few issues reported by the security team (like #192832) It seems we have gaps in the test coverage, and adding the response schemas to the code is impacting the API as it adds validation on the response objects. I'll reopen the pr with adding more test coverage to prevent other errors.
## Summary Part of elastic#184685 First set of changes, I'm planning to do more prs for the remaining endpoints. Will also look at making sure these schema definitions are included in the final kibana `bundle.json`, related doc: https://elasticco.atlassian.net/wiki/spaces/DOC/pages/450494532/API+reference+docs When all schema definitions are moved to code, the fleet/openapi folder can be deleted. To check the result, add to `kibana.dev.yml`: `server.oas.enabled: true` And then in kibana console, query: ``` GET kbn:/api/oas?pathStartsWith=/api/fleet/setup GET kbn:/api/oas?pathStartsWith=/api/fleet/agents/setup GET kbn:/api/oas?pathStartsWith=/api/fleet/package_policies GET kbn:/api/oas?pathStartsWith=/api/fleet/package_policies/delete GET kbn:/api/oas?pathStartsWith=/api/fleet/settings GET kbn:/api/oas?pathStartsWith=/internal/fleet/settings/enrollment ``` To generate the bundle from code, run: ``` node scripts/capture_oas_snapshot --include-path /api/fleet --no-serverless --update # writes to oas_docs/bundle.json ``` Response: ``` { "openapi": "3.0.0", "info": { "title": "Kibana HTTP APIs", "version": "0.0.0" }, "servers": [ { "url": "http://localhost:5603/julia" } ], "paths": { "/api/fleet/setup": { "post": { "summary": "", "tags": [], "description": "Initiate Fleet setup", "responses": { "200": { "content": { "application/json; Elastic-Api-Version=2023-10-31": { "schema": { "type": "object", "description": "A summary of the result of Fleet's `setup` lifecycle. If `isInitialized` is true, Fleet is ready to accept agent enrollment. `nonFatalErrors` may include useful insight into non-blocking issues with Fleet setup.", "properties": { "isInitialized": { "type": "boolean" }, "nonFatalErrors": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string" }, "message": { "type": "string" } }, "additionalProperties": false, "required": [ "name", "message" ] } } }, "additionalProperties": false, "required": [ "isInitialized", "nonFatalErrors" ] } } } }, "400": { "content": { "application/json; Elastic-Api-Version=2023-10-31": { "schema": { "type": "object", "description": "Generic Error", "properties": { "statusCode": { "type": "number" }, "error": { "type": "string" }, "message": { "type": "string" } }, "additionalProperties": false, "required": [ "statusCode", "error", "message" ] } } } }, "500": { "content": { "application/json; Elastic-Api-Version=2023-10-31": { "schema": { "type": "object", "description": "Internal Server Error", "properties": { "message": { "type": "string" } }, "additionalProperties": false, "required": [ "message" ] } } } } }, "parameters": [ { "in": "header", "name": "elastic-api-version", "description": "The version of the API to use", "schema": { "type": "string", "enum": [ "2023-10-31" ], "default": "2023-10-31" } }, { "description": "A required header to protect against CSRF attacks", "in": "header", "name": "kbn-xsrf", "required": true, "schema": { "example": "true", "type": "string" } } ], "operationId": "%2Fapi%2Ffleet%2Fsetup#0" } } }, "components": { "schemas": {}, "securitySchemes": { "basicAuth": { "type": "http", "scheme": "basic" }, "apiKeyAuth": { "type": "apiKey", "in": "header", "name": "Authorization" } } }, "security": [ { "basicAuth": [] } ], "tags": [] } ```
## Summary Relates #184685 Readd #192447 with fixes and tests to validate that the response schemas are correct. ### 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
## Summary Relates elastic#184685 Readd elastic#192447 with fixes and tests to validate that the response schemas are correct. ### 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 (cherry picked from commit 406f073)
…193296) # Backport This will backport the following commits from `main` to `8.x`: - [[Fleet] use @kbn/config-schema in Fleet API (Part 1) (#192883)](#192883) <!--- Backport version: 9.4.3 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Julia Bardi","email":"[email protected]"},"sourceCommit":{"committedDate":"2024-09-18T13:13:21Z","message":"[Fleet] use @kbn/config-schema in Fleet API (Part 1) (#192883)\n\n## Summary\r\n\r\nRelates https://github.com/elastic/kibana/issues/184685\r\n\r\nReadd #192447 with fixes and tests\r\nto validate that the response schemas are correct.\r\n\r\n### Checklist\r\n\r\n- [x] [Unit or functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere updated or added to match the most common scenarios","sha":"406f07386ca6b35f375e8f22e682e44c101b1182","branchLabelMapping":{"^v9.0.0$":"main","^v8.16.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","Team:Fleet","v9.0.0","backport:prev-minor","v8.16.0"],"title":"[Fleet] use @kbn/config-schema in Fleet API (Part 1)","number":192883,"url":"https://github.com/elastic/kibana/pull/192883","mergeCommit":{"message":"[Fleet] use @kbn/config-schema in Fleet API (Part 1) (#192883)\n\n## Summary\r\n\r\nRelates https://github.com/elastic/kibana/issues/184685\r\n\r\nReadd #192447 with fixes and tests\r\nto validate that the response schemas are correct.\r\n\r\n### Checklist\r\n\r\n- [x] [Unit or functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere updated or added to match the most common scenarios","sha":"406f07386ca6b35f375e8f22e682e44c101b1182"}},"sourceBranch":"main","suggestedTargetBranches":["8.x"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/192883","number":192883,"mergeCommit":{"message":"[Fleet] use @kbn/config-schema in Fleet API (Part 1) (#192883)\n\n## Summary\r\n\r\nRelates https://github.com/elastic/kibana/issues/184685\r\n\r\nReadd #192447 with fixes and tests\r\nto validate that the response schemas are correct.\r\n\r\n### Checklist\r\n\r\n- [x] [Unit or functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere updated or added to match the most common scenarios","sha":"406f07386ca6b35f375e8f22e682e44c101b1182"}},{"branch":"8.x","label":"v8.16.0","branchLabelMappingKey":"^v8.16.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT--> Co-authored-by: Julia Bardi <[email protected]>
As discussed we are targeting 9.x with this change. |
… schema (#193604) Relates #184685 Make statusCode and error optional in genericErrorResponse, sometimes it seems to be missing. Saw this screenshot in another issue: ![image](https://github.com/user-attachments/assets/f2cdf0a4-9067-4c36-a98f-65dc302a4e55)
…3326) ## Summary Relates #184685 Added tests to verify response schemas. To verify, go to Fleet settings and try create/update different output types, fleet server hosts, outputs. ``` GET kbn:/api/oas?pathStartsWith=/api/fleet/outputs GET kbn:/api/oas?pathStartsWith=/api/fleet/health_check GET kbn:/api/oas?pathStartsWith=/api/fleet/message_signing_service/rotate_key_pair GET kbn:/api/oas?pathStartsWith=/api/fleet/fleet_server_hosts GET kbn:/api/oas?pathStartsWith=/api/fleet/data_streams # test APIs POST kbn:/api/fleet/health_check { "id": "default-fleet-server" } POST kbn:/api/fleet/message_signing_service/rotate_key_pair GET kbn:/api/fleet/data_streams GET kbn:/api/fleet/check-permissions POST kbn:/api/fleet/service_tokens ``` --------- Co-authored-by: kibanamachine <[email protected]>
Opened #193698 as the last chunk of APIs to define schema, still working on the last |
## Summary Relates #184685 Added response schemas to remaining APIs: - agent_policies - agents, actions - download_source - enrollment_api_key - epm when this is merged, the fleet/openapi folder can be deleted (which includes the previous version of bundled.yaml) ### 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
## Summary Closes #184685 **Release notes**: These schema changes shouldn't be breaking, but there were some incorrect/missing response schemas in the old openapi spec. For example the API `POST /api/fleet/agents/{agentId}/actions` response was incorrectly documented: https://petstore.swagger.io/?url=https://raw.githubusercontent.com/elastic/kibana/main/x-pack/plugins/fleet/common/openapi/bundled.json#/Elastic%20Agent%20actions/new-agent-action ``` { "body": [ 0 ], "statusCode": 0, "headers": "string" } ``` Fixed here: https://petstore.swagger.io/?url=https://raw.githubusercontent.com/elastic/kibana/31f8cfd6efc5e79255fec0dfbc1f735592736dad/oas_docs/bundle.json#/Elastic%20Agent%20actions/%252Fapi%252Ffleet%252Fagents%252F%257BagentId%257D%252Factions%230 ``` { "item": { "ack_data": "string", "agents": [ "string" ], "created_at": "string", "data": "string", "expiration": "string", "id": "string", "minimum_execution_duration": 0, "namespaces": [ "string" ], "rollout_duration_seconds": 0, "sent_at": "string", "source_uri": "string", "start_time": "string", "total": 0, "type": "string" } } ``` The new spec should match the implementation accurately, and responses are being verified when returned. Tests were added to make sure the response schemas are correct. If there are any bugs in the current schema, it will result in a HTTP 500 error with an error message on where the schema validation failed. Example of an error where a field is missing: ``` { "statusCode": 500, "error": "Internal Server Error", "message": "Failed output validation: [request body.items.0.name]: definition for this key is missing" } ``` Example of an error where a field is mandatory in the schema, but not provided in the response (missing `schema.maybe`) ``` { "statusCode": 500, "error": "Internal Server Error", "message": "Failed output validation: [request body.items.0.internal]: expected value of type [boolean] but got [undefined]" } ``` There are a few places where the validation allows unknown fields. Used it where some fields were not included in TS types or fields are more dynamic, e.g. fields coming from packages or elasticsearch settings. https://github.com/search?q=repo%3Aelastic%2Fkibana+extendsDeep+path%3A%2F%5Ex-pack%5C%2Fplugins%5C%2Ffleet%5C%2Fserver%5C%2Ftypes%5C%2F%2F&type=code ``` .extendsDeep({ unknowns: 'allow', }) ``` Changes in this pr: Remove using old `bundled.yaml` to generate oas, fixed tags. Removed old openapi files, updated readme. Here is the new bundle in Swagger UI: [stateful](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/elastic/kibana/31f8cfd6efc5e79255fec0dfbc1f735592736dad/oas_docs/bundle.json) [serverless](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/elastic/kibana/da72ee0093c5a1e164b4a24c5f94333c2376e7cc/oas_docs/bundle.serverless.json) Updated serverless scripts too. Updated Fleet readme: https://github.com/elastic/kibana/blob/da72ee0093c5a1e164b4a24c5f94333c2376e7cc/x-pack/plugins/fleet/common/openapi/README.md Generated the new bundle by running this script locally: ``` node scripts/capture_oas_snapshot --include-path /api/fleet --update ``` --------- Co-authored-by: kibanamachine <[email protected]>
## Summary Relates elastic#184685 Added response schemas to remaining APIs: - agent_policies - agents, actions - download_source - enrollment_api_key - epm when this is merged, the fleet/openapi folder can be deleted (which includes the previous version of bundled.yaml) ### 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
## Summary Closes elastic#184685 **Release notes**: These schema changes shouldn't be breaking, but there were some incorrect/missing response schemas in the old openapi spec. For example the API `POST /api/fleet/agents/{agentId}/actions` response was incorrectly documented: https://petstore.swagger.io/?url=https://raw.githubusercontent.com/elastic/kibana/main/x-pack/plugins/fleet/common/openapi/bundled.json#/Elastic%20Agent%20actions/new-agent-action ``` { "body": [ 0 ], "statusCode": 0, "headers": "string" } ``` Fixed here: https://petstore.swagger.io/?url=https://raw.githubusercontent.com/elastic/kibana/31f8cfd6efc5e79255fec0dfbc1f735592736dad/oas_docs/bundle.json#/Elastic%20Agent%20actions/%252Fapi%252Ffleet%252Fagents%252F%257BagentId%257D%252Factions%230 ``` { "item": { "ack_data": "string", "agents": [ "string" ], "created_at": "string", "data": "string", "expiration": "string", "id": "string", "minimum_execution_duration": 0, "namespaces": [ "string" ], "rollout_duration_seconds": 0, "sent_at": "string", "source_uri": "string", "start_time": "string", "total": 0, "type": "string" } } ``` The new spec should match the implementation accurately, and responses are being verified when returned. Tests were added to make sure the response schemas are correct. If there are any bugs in the current schema, it will result in a HTTP 500 error with an error message on where the schema validation failed. Example of an error where a field is missing: ``` { "statusCode": 500, "error": "Internal Server Error", "message": "Failed output validation: [request body.items.0.name]: definition for this key is missing" } ``` Example of an error where a field is mandatory in the schema, but not provided in the response (missing `schema.maybe`) ``` { "statusCode": 500, "error": "Internal Server Error", "message": "Failed output validation: [request body.items.0.internal]: expected value of type [boolean] but got [undefined]" } ``` There are a few places where the validation allows unknown fields. Used it where some fields were not included in TS types or fields are more dynamic, e.g. fields coming from packages or elasticsearch settings. https://github.com/search?q=repo%3Aelastic%2Fkibana+extendsDeep+path%3A%2F%5Ex-pack%5C%2Fplugins%5C%2Ffleet%5C%2Fserver%5C%2Ftypes%5C%2F%2F&type=code ``` .extendsDeep({ unknowns: 'allow', }) ``` Changes in this pr: Remove using old `bundled.yaml` to generate oas, fixed tags. Removed old openapi files, updated readme. Here is the new bundle in Swagger UI: [stateful](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/elastic/kibana/31f8cfd6efc5e79255fec0dfbc1f735592736dad/oas_docs/bundle.json) [serverless](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/elastic/kibana/da72ee0093c5a1e164b4a24c5f94333c2376e7cc/oas_docs/bundle.serverless.json) Updated serverless scripts too. Updated Fleet readme: https://github.com/elastic/kibana/blob/da72ee0093c5a1e164b4a24c5f94333c2376e7cc/x-pack/plugins/fleet/common/openapi/README.md Generated the new bundle by running this script locally: ``` node scripts/capture_oas_snapshot --include-path /api/fleet --update ``` --------- Co-authored-by: kibanamachine <[email protected]>
Today, Fleet's OpenAPI spec file is generated and maintained through a manual process documented in the README file in
x-pack/fleet/plugins/fleet/common/openapi/
.Kibana as a whole is moving towards support for fully-automated OpenAPI specs for plugin APIs, as tracked here: #180056. Fleet's manual process should be replaced by a fully automated one in which the OAS spec is inferred from metadata on our server-side routes and request/response contracts defined via
@kbn/config-schema
.We had previously done some investigation into whether
@kbn/openapi-generator
was ready to meet Fleet's needs and the answer at the time was "no". However, with a few months of progress since then, we should start the process of moving towards automating our schema generation. Manually generating and maintaining our OpenAPI spec is labor intensive and error prone, so shedding this friction will speed up our development process on the team.Here is an example of the
/api/status
Kibana API's schema written with@kbn/config-schema
that results in an OpenAPI spec here:kibana/oas_docs/bundle.json
Lines 451 to 525 in 3efa595
What we'll actually need to do to accomplish this is to replace each entry we have today in Fleet's OpenAPI spec files with a more advanced set of types created with
@kbn/config-schema
alongside each route we register.An example of this for the
/api/fleet/setup
API might look like this:Each documented status code, response body, query parameter, etc can be documented directly alongside the route definition. We'd need to take what we have today in the various OpenAPI spec files and translate them to this approach for every Fleet API endpoint. This will be no small undertaking, but it will greatly improve our ability to create or iterate on API endpoints It will also greatly empower our docs team to generate better API documentation.
The text was updated successfully, but these errors were encountered: