Commit graph

4 commits

Author SHA1 Message Date
Maxim Palenov
a4fc565333
[Security Solution] Align operationId and file names in OpenAPI specs (#189703)
**Relates to:** https://github.com/elastic/kibana/issues/183661 (internal)
**Relates to:** https://github.com/elastic/kibana/issues/183821 (internal)
**Relates to:** https://github.com/elastic/kibana/issues/183837 (internal)

## Summary

It addresses a discussion Rule Management team had on a tech time meeting whose outcome was usage of consistent  operationId, files and folder naming related to OpenAPI specs. For example use `Read` instead of `Get` since it gives better readability and matches with already used approach.

This PR aligns the naming and performs necessary renaming.
2024-08-05 18:11:54 +02:00
Maxim Palenov
845dd1fabb
[Security Solution] Add tags by OpenAPI bundler (#189621)
**Resolves:** https://github.com/elastic/kibana/issues/183375

## Summary

This PR implements functionality assigning a provided tag to OpenAPI `Operation object`s in the result bundle. Specified tag is also added as the only root level OpenAPI tag. This approach allows to produce domain bundles having a single tag assigned. At the next step domain bundles are merged together into single Kibana bundle where tags will allow to properly display grouping at Bump.sh (API reference documentation platform).

## Details

Bump.sh (our new API reference documentation platform) uses OpenAPI tags for grouping API endpoints. It supports only one tag per endpoint.

This PR facilitates preparation of Kibana OpenAPI bundle to be uploaded to Bump.sh by implementing functionality assigning a provided tag to OpenAPI `Operation object`s in the result domain bundles. It's implemented by providing an optional configuration option `assignTag` whose format is OpenAPI Tag Object. When `assignTag` isn't specified the bundler merges existing tags.

## Example

Consider the following bundling configuration

```js
const { bundle } = require('@kbn/openapi-bundler');

bundle({
  // ...
  options: {
    assignTag: {
      name: 'Some Domain API tag name',
      description: 'Some Domain API description',
      externalDocs: {
        url: 'https://some-external-documentation-url',
        description: 'External documentation description',
    }
  },
});
```

and source OpenAPI specs

**spec1.schema.yaml**
```yaml
openapi: 3.0.3
info:
  title: Spec1
  version: '2023-10-31'
paths:
  /api/some_api:
    get:
      tags: ['Some local tag']
      responses:
        200:
          content:
            'application/json':
              schema:
                type: string
```

**spec2.schema.yaml**
```yaml
openapi: 3.0.3
info:
  title: Spec2
  version: '2023-10-31'
paths:
  /api/some_api:
    post:
      tags: ['Some global tag']
      responses:
        200:
          content:
            'application/json':
              schema:
                type: string
tags:
  - name: Some global tag
```

**spec2.schema.yaml**
```yaml
openapi: 3.0.3
info:
  title: Spec3
  version: '2023-10-31'
paths:
  /api/another_api:
    get:
      responses:
        200:
          content:
            'application/json':
              schema:
                type: string
```

After bundling above OpenAPI specs with the provided bundling script we'll get the following

**domain-bundle.schema.yaml**
```yaml
openapi: 3.0.3
info:
  title: Bundled document
  version: '2023-10-31'
paths:
  /api/some_api:
    get:
      tags: ['Some Domain API tag name']
      responses:
        200:
          content:
            'application/json':
              schema:
                type: string
    post:
      tags: ['Some Domain API tag name']
      responses:
        200:
          content:
            'application/json':
              schema:
                type: string
  /api/another_api:
    get:
      tags: ['Some Domain API tag name']
      responses:
        200:
          content:
            'application/json':
              schema:
                type: string
tags:
  - name: Some Domain API tag name
    description: Some Domain API description
    externalDocs:
      url: 'https://some-external-documentation-url'
      description: External documentation description
```
2024-08-02 16:41:49 +02:00
Maxim Palenov
3732d88680
[Security Solution] Implement shared components conflict resolution functionality (#188812)
**Resolves:** https://github.com/elastic/kibana/issues/188817

## Summary

This PR adds automatic shared components conflict resolution functionality for OpenAPI merger. It boils down to a similar result as `npx @redocly/cli join --prefix-components-with-info-prop title` produces by prefixing shared components with document's title in each source.

OpenAPI bundler intentionally won't solve conflicts automatically since it's focused on bundling domain APIs where conflicts are usually indicators of upstream problems.

## 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. 

This PR adds automatic shared components conflict resolution for OpenAPI merger. It prefixes shared component names with a normalized document's title.

OpenAPI bundler intentionally won't solve conflicts automatically since it's focused on bundling domain APIs where conflicts are usually indicators of upstream problems.

## Example

Consider two following OpenAPI specs each defining local `MySchema`

**spec1.schema.yaml**
```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**
```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
```

and a script to merge them

```js
require('../../src/setup_node_env');
const { resolve } = require('path');
const { merge } = require('@kbn/openapi-bundler');
const { REPO_ROOT } = require('@kbn/repo-info');

(async () => {
  await merge({
    sourceGlobs: [
      `${REPO_ROOT}/oas_docs/spec1.schema.yaml`,
      `${REPO_ROOT}/oas_docs/spec2.schema.yaml`,
    ],
    outputFilePath: resolve(`${REPO_ROOT}/oas_docs/merged.yaml`),
    options: {
      mergedSpecInfo: {
        title: 'Merge result',
        version: 'my version',
      },
    },
  });
})();
```

will be merged successfully to

**merged.yaml**
```yaml
openapi: 3.0.3
info:
  title: Merge result
  version: 'my version' 
paths:
  /api/another_api:
    get:
      operationId: MyAnotherEndpointGet
      responses:
        '200':
          content:
            application/json; Elastic-Api-Version=2023-10-31:
              schema:
                $ref: '#/components/schemas/My_another_endpoint_MySchema'
  /api/some_api:
    get:
      operationId: MyEndpointGet
      responses:
        '200':
          content:
            application/json; Elastic-Api-Version=2023-10-31:
              schema:
                $ref: '#/components/schemas/My_endpoint_MySchema'
components:
  schemas:
    My_another_endpoint_MySchema:
      type: number
    My_endpoint_MySchema:
      enum:
        - value1
      type: string
```
2024-07-25 12:33:17 -05:00
Maxim Palenov
c76f68e55c
[Security Solution] Auto-bundle Lists API OpenAPI specs (#188407)
**Addresses**: https://github.com/elastic/kibana/issues/184428

## Summary

This PR adds scripts for automatic bundling of Lists API OpenAPI specs as a part of PR pipeline. Corresponding resulting bundles are automatically committed in the Lists common package `kbn-securitysolution-lists-common` in the `docs/openapi/ess/` and `docs/openapi/serverless` folders (similar to https://github.com/elastic/kibana/pull/186384).
2024-07-18 13:33:53 +02:00