elastic / kibana

Your window into the Elastic Stack
https://www.elastic.co/products/kibana
Other
19.69k stars 8.12k forks source link

[Security Solution] Improve OpenAPI bundler/merger's shared components conflict resolution #188817

Closed maximpn closed 1 month ago

maximpn commented 1 month ago

Epic: https://github.com/elastic/security-team/issues/9401 (internal) Relates to: https://github.com/elastic/security-team/issues/7981 (internal)

Summary

Processing OpenAPI specs may have references name conflicts. We need functionality to process such conflicts automatically.

Details

While working with various OpenAPI specs it may happen that different specs use exactly the same name for some shared components but different definitions. It must be avoided inside one API domain but it's a usual situation when merging OpenAPI specs of different API domains. For example domains may define a shared Id or 404Response schemas where Id is a string in one domain and a number in another.

OpenAPI merger implemented in https://github.com/elastic/kibana/pull/188110 and OpenAPI bundler implemented in https://github.com/elastic/kibana/pull/171526 do not solve shared components related conflicts automatically. It works perfectly for a single API domain forcing engineers choosing shared schema names carefully.

To generalize OpenAPI merger and bundler we need to add functionality for automatic conflict resolution. The simplest approach would be prefixing shared component names with some domain specific information.

Example

Consider two following OpenAPI specs each defining local MySchema

spec1.schema.yaml

openapi: 3.0.3
info:
  title: My endpoint
  version: '2023-10-31'
paths:
  /api/some_api:
    get:
      operationId: MyEndpointGet
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MySchema'

components:
  schemas:
    MySchema:
      type: string
      enum:
        - value1

spec2.schema.yaml

openapi: 3.0.3
info:
  title: My another endpoint
  version: '2023-10-31'
paths:
  /api/another_api:
    get:
      operationId: MyAnotherEndpointGet
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MySchema'

components:
  schemas:
    MySchema:
      type: number

When processed via OpenAPI bundler or merger it will lead to an error

Error: ❌  Unable to merge documents due to conflicts in referenced schemas. Component
/components/schemas/MySchema is defined in .../spec2.schema.yaml and in .../spec1.schema.yaml
but definitions DO NOT match.
elasticmachine commented 1 month ago

Pinging @elastic/security-detections-response (Team:Detections and Resp)

elasticmachine commented 1 month ago

Pinging @elastic/security-solution (Team: SecuritySolution)

elasticmachine commented 1 month ago

Pinging @elastic/security-detection-rule-management (Team:Detection Rule Management)

maximpn commented 1 month ago

Shared components conflict resolution functionality was implemented in https://github.com/elastic/kibana/pull/188812.

maximpn commented 1 month ago

Reopening to add OpenAPI mapping conflict resolution.

maximpn commented 1 month ago

Closing after adding functionality to add a namespace prefix to OpenAPI discriminator mapping in https://github.com/elastic/kibana/pull/189472.