Skip to content
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

[Security Solution] Implement OpenAPI specs merger utility #188110

Merged
merged 8 commits into from
Jul 16, 2024

Conversation

maximpn
Copy link
Contributor

@maximpn maximpn commented Jul 11, 2024

Addresses: #186356

Summary

This PR adds OpenAPI spec files merger utility (programmatic API). It provides a similar functionality as npx @redocly/cli join does and takes into account discussion results

  • provides a simple way to produce a single Kibana OpenAPI bundle
  • extends requestBody and responses MIME types with a version parameters Elastic-Api-Version=<version> to avoid different API endpoint versions conflicts
  • has flexibility to adjust Kibana needs

The utility is exposed from kbn-openapi-bundler package.

Details

OpenAPI merger is a tool for merging multiple OpenAPI specification files. It's useful to merge already processed specification files to produce a result bundle. OpenAPI bundler uses the merger under the hood to merge bundled OpenAPI specification files. Exposed externally merger is a wrapper of the bundler's merger but extended with an ability to parse JSON files and forced to produce a single result file.

It is able to read OpenAPI spec files defined in JSON and YAML formats. The result file is always written in YAML format where every requestBody and response in responses extended with document's info.version value added as a MIME type parameter Elastic-Api-Version=<version>.

Currently package supports only programmatic API. As the next step you need to create a JavaScript script file like below

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}/my/path/to/spec1.json`,
      `${REPO_ROOT}/my/path/to/spec2.yml`,
      `${REPO_ROOT}/my/path/to/spec3.yaml`,
    ],
    outputFilePath: `${REPO_ROOT}/oas_docs/bundle.yaml`,
    mergedSpecInfo: {
      title: 'My merged OpenAPI specs',
      version: '1.0.0',
    },
  });
})();

Finally you should be able to run OpenAPI merger via

node ./path/to/the/script.js

or it could be added to package.json and run via yarn.

After running the script it will log different information and write a merged OpenAPI specification to a the provided path.

Caveats

Items below don't look critical at the moment and can be addressed later on.

  • It doesn't support merging of specs having different OpenAPI versions (Kibana's OpenAPI specs use version 3.0.x but we should keep an eye on that)
  • It doesn't support top level $ref for
    • Path item
    • Request body
    • Responses

@maximpn maximpn added release_note:skip Skip the PR/issue when compiling release notes docs Team:Detections and Resp Security Detection Response Team Team: SecuritySolution Security Solutions Team working on SIEM, Endpoint, Timeline, Resolver, etc. Team:Detection Rule Management Security Detection Rule Management Team Project:Serverless Work as part of the Serverless project for its initial release v8.16.0 labels Jul 11, 2024
@maximpn maximpn self-assigned this Jul 11, 2024
@maximpn maximpn force-pushed the oas-merger branch 3 times, most recently from 7c39e7d to c6df87d Compare July 12, 2024 11:29
@maximpn maximpn changed the title [Security Solution] Add OpenAPI specs merger utility [Security Solution] Implement OpenAPI specs merger utility Jul 12, 2024
@maximpn maximpn force-pushed the oas-merger branch 2 times, most recently from 8854c7d to 57cd594 Compare July 15, 2024 10:59
@maximpn maximpn requested a review from xcrzx July 15, 2024 11:22
@maximpn maximpn marked this pull request as ready for review July 15, 2024 11:25
@maximpn maximpn requested a review from a team as a code owner July 15, 2024 11:25
@elasticmachine
Copy link
Contributor

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

@elasticmachine
Copy link
Contributor

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

@elasticmachine
Copy link
Contributor

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

Copy link
Contributor

@xcrzx xcrzx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @maximpn! The changes look good to me. Leaving just a couple of minor comments

continue;
}

merged.push(item);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's avoid mutating function arguments. That often leads to many kinds of subtle bugs. Instead, a new array can be easily created and returned here.


export function mergeArrays(source: unknown[], merged: unknown[]): void {
for (const item of source) {
const existing = merged.find((x) => deepEqual(x, item));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: merged.find is a bit more semantically suitable in this case, as we don't need to access the found element, but only need to check if there's an element in the array that satisfies our predicate.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean merged.some()?

I changed it to merged.some().

Comment on lines 89 to 107
try {
return extractByJsonPointer(resolvedDocument.document, sourcePointer);
} catch {
return;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we at least log the errors here? Silently ignoring them will make the code hard to debug.

Copy link
Contributor Author

@maximpn maximpn Jul 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not all sourcePointers may exist. For example path item's requestBodies field is optional. I added debug logging here to have traces for possible debugging.

const componentToAdd = object[name];
const existingComponent = merged[name];

if (existingComponent && !deepEqual(componentToAdd, existingComponent)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the case for checking if there are two components defined in different schemas but they are the same? Shouldn't we just throw an error in that case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It turned out that sometimes it's convenient to have duplicated schema. For example ExceptionListType is defined in Detections API OpenAPI specs and in Exceptions API OpenAPI specs. Referencing a file locating quite far could lead to long relative paths. It can be mitigated by using packages for OpenAPI specs which was discussed in #184859.

I added logging a warning when duplicated components are encountered.

@maximpn maximpn enabled auto-merge (squash) July 16, 2024 21:07
@maximpn maximpn merged commit f02a41c into elastic:main Jul 16, 2024
19 checks passed
@kibanamachine kibanamachine added the backport:skip This commit does not require backporting label Jul 16, 2024
@elasticmachine
Copy link
Contributor

💚 Build Succeeded

Metrics [docs]

Public APIs missing comments

Total count of every public API that lacks a comment. Target amount is 0. Run node scripts/build_api_docs --plugin [yourplugin] --stats comments for more detailed information.

id before after diff
@kbn/openapi-bundler 6 12 +6
Unknown metric groups

API count

id before after diff
@kbn/openapi-bundler 6 12 +6

History

  • 💔 Build #221825 failed 274f9376b44f165d3384e708f1f83938593f69df
  • 💛 Build #221433 was flaky 4db41b9e39267289c49f20f65c56c086a3e50005
  • 💔 Build #221398 failed 57cd5941e6a570c820bb47eb37705093059289e3
  • 💔 Build #221135 failed 8854c7d2d420e1716ec8ad01a311206d16b16dbf

cc @maximpn

@maximpn maximpn deleted the oas-merger branch July 17, 2024 06:46
maximpn added a commit that referenced this pull request Jul 25, 2024
…unctionality (#188812)

**Resolves:** #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 #188110 and OpenAPI bundler implemented in #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
```
maximpn added a commit that referenced this pull request Aug 13, 2024
**Addresses:** #186356
**Relates to:** #184428

## Summary

This PR adds a merging JS script based on the utility implemented in #186356. Resulted OpenAPI bundle as committed in `oas_docs/output/kibana.serverless.bundled.yaml`.

## Details

#188110 implements and exposes `merge` utility design to merge source OpenAPI specs without processing. It's has only a programmatic API. To merge OpenAPI specs it's required to add a JS script like below

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

(async () => {
  await merge({
   sourceGlobs: [/* a list of source globs goes here */],
   outputFilePath: 'path/to/the/output/file.yaml',
  });
})();
```

The JS script added in this PR includes source OpenAPI specs presented in `oas_docs/makefile` plus Security Solution OpenAPI specs based on #184428.

**To run** the script use the following command from Kibana root folder

```bash
node ./oas_docs/scripts/merge_serverless_oas.js 
```

## Known linting issues with Security Solution OpenAPI specs

Running Spectral OpenAPI linter on the result bundle shows a number of errors caused by `no-$ref-siblings` rule. This caused by the current code generator implementation which requires `default` property to be set next to `$ref` though it's not correct for OpenAPI `3.0.3` while it's allowed in `3.1`. It seems that Bump.sh handles such cases properly though by properly showing a default value.

We need to analyze the problem and decide if/when we should fix it.

The rest of warnings look fixable and will be addressed in the next stage after setting up linter rules.

## Next steps

Since `@kbn/openapi-bundler` package is tailored specifically for Kibana it should replace Redocly currently used to merge OpenAPI specs. It also means `oas_docs/makefile` should be superseded by JS script(s) using `merge` utility form `@kbn/openapi-bundler` package.

`@kbn/openapi-bundler` SHOULD NOT replace OpenAPI linters since it doesn't perform thorough linting. It's good if we continue adopting `spectral-cli` for linting purposes.
bryce-b pushed a commit to bryce-b/kibana that referenced this pull request Aug 13, 2024
…c#189262)

**Addresses:** elastic#186356
**Relates to:** elastic#184428

## Summary

This PR adds a merging JS script based on the utility implemented in elastic#186356. Resulted OpenAPI bundle as committed in `oas_docs/output/kibana.serverless.bundled.yaml`.

## Details

elastic#188110 implements and exposes `merge` utility design to merge source OpenAPI specs without processing. It's has only a programmatic API. To merge OpenAPI specs it's required to add a JS script like below

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

(async () => {
  await merge({
   sourceGlobs: [/* a list of source globs goes here */],
   outputFilePath: 'path/to/the/output/file.yaml',
  });
})();
```

The JS script added in this PR includes source OpenAPI specs presented in `oas_docs/makefile` plus Security Solution OpenAPI specs based on elastic#184428.

**To run** the script use the following command from Kibana root folder

```bash
node ./oas_docs/scripts/merge_serverless_oas.js 
```

## Known linting issues with Security Solution OpenAPI specs

Running Spectral OpenAPI linter on the result bundle shows a number of errors caused by `no-$ref-siblings` rule. This caused by the current code generator implementation which requires `default` property to be set next to `$ref` though it's not correct for OpenAPI `3.0.3` while it's allowed in `3.1`. It seems that Bump.sh handles such cases properly though by properly showing a default value.

We need to analyze the problem and decide if/when we should fix it.

The rest of warnings look fixable and will be addressed in the next stage after setting up linter rules.

## Next steps

Since `@kbn/openapi-bundler` package is tailored specifically for Kibana it should replace Redocly currently used to merge OpenAPI specs. It also means `oas_docs/makefile` should be superseded by JS script(s) using `merge` utility form `@kbn/openapi-bundler` package.

`@kbn/openapi-bundler` SHOULD NOT replace OpenAPI linters since it doesn't perform thorough linting. It's good if we continue adopting `spectral-cli` for linting purposes.
lcawl pushed a commit to lcawl/kibana that referenced this pull request Aug 20, 2024
…88110)

**Addresses:** elastic#186356

## Summary

This PR adds OpenAPI spec files merger utility (programmatic API). It provides a similar functionality as `npx @redocly/cli join` does and takes into account [discussion results](elastic#183019 (comment))

- provides a simple way to produce a single Kibana OpenAPI bundle
- extends `requestBody` and `responses` MIME types with a version parameters `Elastic-Api-Version=<version>` to avoid different API endpoint versions conflicts
- has flexibility to adjust Kibana needs

The utility is exposed from `kbn-openapi-bundler` package.

## Details

**OpenAPI merger** is a tool for merging multiple OpenAPI specification files. It's useful to merge already processed specification files to produce a result bundle. **OpenAPI bundler** uses the merger under the hood to merge bundled OpenAPI specification files. Exposed externally merger is a wrapper of the bundler's merger but extended with an ability to parse JSON files and forced to produce a single result file.

It is able to read OpenAPI spec files defined in JSON and YAML formats. The result file is always written in YAML format where every `requestBody` and response in `responses` extended with document's `info.version` value added as a MIME type parameter `Elastic-Api-Version=<version>`.

Currently package supports only programmatic API. As the next step you need to create a JavaScript script file like below

```ts
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}/my/path/to/spec1.json`,
      `${REPO_ROOT}/my/path/to/spec2.yml`,
      `${REPO_ROOT}/my/path/to/spec3.yaml`,
    ],
    outputFilePath: `${REPO_ROOT}/oas_docs/bundle.yaml`,
    mergedSpecInfo: {
      title: 'My merged OpenAPI specs',
      version: '1.0.0',
    },
  });
})();
```

Finally you should be able to run OpenAPI merger via

```bash
node ./path/to/the/script.js
```

or it could be added to `package.json` and run via `yarn`.

After running the script it will log different information and write a merged OpenAPI specification to a the provided path.

## Caveats

Items below don't look critical at the moment and can be addressed later on.

- It doesn't support merging of specs having different OpenAPI versions (Kibana's OpenAPI specs use version `3.0.x` but we should keep an eye on that)
- It doesn't support top level `$ref` for
  - Path item
  - Request body
  - Responses
lcawl pushed a commit to lcawl/kibana that referenced this pull request Aug 20, 2024
…unctionality (elastic#188812)

**Resolves:** elastic#188817

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.

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 elastic#188110 and OpenAPI bundler implemented in elastic#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.

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
```
lcawl pushed a commit to lcawl/kibana that referenced this pull request Aug 20, 2024
…c#189262)

**Addresses:** elastic#186356
**Relates to:** elastic#184428

This PR adds a merging JS script based on the utility implemented in elastic#186356. Resulted OpenAPI bundle as committed in `oas_docs/output/kibana.serverless.bundled.yaml`.

elastic#188110 implements and exposes `merge` utility design to merge source OpenAPI specs without processing. It's has only a programmatic API. To merge OpenAPI specs it's required to add a JS script like below

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

(async () => {
  await merge({
   sourceGlobs: [/* a list of source globs goes here */],
   outputFilePath: 'path/to/the/output/file.yaml',
  });
})();
```

The JS script added in this PR includes source OpenAPI specs presented in `oas_docs/makefile` plus Security Solution OpenAPI specs based on elastic#184428.

**To run** the script use the following command from Kibana root folder

```bash
node ./oas_docs/scripts/merge_serverless_oas.js
```

Running Spectral OpenAPI linter on the result bundle shows a number of errors caused by `no-$ref-siblings` rule. This caused by the current code generator implementation which requires `default` property to be set next to `$ref` though it's not correct for OpenAPI `3.0.3` while it's allowed in `3.1`. It seems that Bump.sh handles such cases properly though by properly showing a default value.

We need to analyze the problem and decide if/when we should fix it.

The rest of warnings look fixable and will be addressed in the next stage after setting up linter rules.

Since `@kbn/openapi-bundler` package is tailored specifically for Kibana it should replace Redocly currently used to merge OpenAPI specs. It also means `oas_docs/makefile` should be superseded by JS script(s) using `merge` utility form `@kbn/openapi-bundler` package.

`@kbn/openapi-bundler` SHOULD NOT replace OpenAPI linters since it doesn't perform thorough linting. It's good if we continue adopting `spectral-cli` for linting purposes.
lcawl added a commit that referenced this pull request Aug 20, 2024
…189262) (#190541)

# Backport

This will backport the bundler aspects of the following commits from
`main` to `8.15`:
- [[HTTP/OAS] Merge OpenAPI specs by using `kbn-openapi-bundler`
(#189262)](#189262)
 - #189621
 - #189482
 - #189348
 - #189472
 - #188110
 - #188812

<!--- Backport version: 8.9.8 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Maxim
Palenov","email":"[email protected]"},"sourceCommit":{"committedDate":"2024-08-13T10:45:35Z","message":"[HTTP/OAS]
Merge OpenAPI specs by using `kbn-openapi-bundler`
(#189262)\n\n**Addresses:**
https://github.com/elastic/kibana/issues/186356\r\n**Relates to:**
https://github.com/elastic/kibana/issues/184428\r\n\r\n##
Summary\r\n\r\nThis PR adds a merging JS script based on the utility
implemented in #186356. Resulted
OpenAPI bundle as committed in
`oas_docs/output/kibana.serverless.bundled.yaml`.\r\n\r\n##
Details\r\n\r\nhttps://github.com//pull/188110 implements
and exposes `merge` utility design to merge source OpenAPI specs without
processing. It's has only a programmatic API. To merge OpenAPI specs
it's required to add a JS script like below\r\n\r\n```js\r\nconst {
merge } = require('@kbn/openapi-bundler');\r\n\r\n(async () => {\r\n
await merge({\r\n sourceGlobs: [/* a list of source globs goes here
*/],\r\n outputFilePath: 'path/to/the/output/file.yaml',\r\n
});\r\n})();\r\n```\r\n\r\nThe JS script added in this PR includes
source OpenAPI specs presented in `oas_docs/makefile` plus Security
Solution OpenAPI specs based on
https://github.com/elastic/kibana/issues/184428.\r\n\r\n**To run** the
script use the following command from Kibana root
folder\r\n\r\n```bash\r\nnode ./oas_docs/scripts/merge_serverless_oas.js
\r\n```\r\n\r\n## Known linting issues with Security Solution OpenAPI
specs\r\n\r\nRunning Spectral OpenAPI linter on the result bundle shows
a number of errors caused by `no-$ref-siblings` rule. This caused by the
current code generator implementation which requires `default` property
to be set next to `$ref` though it's not correct for OpenAPI `3.0.3`
while it's allowed in `3.1`. It seems that Bump.sh handles such cases
properly though by properly showing a default value.\r\n\r\nWe need to
analyze the problem and decide if/when we should fix it.\r\n\r\nThe rest
of warnings look fixable and will be addressed in the next stage after
setting up linter rules.\r\n\r\n## Next steps\r\n\r\nSince
`@kbn/openapi-bundler` package is tailored specifically for Kibana it
should replace Redocly currently used to merge OpenAPI specs. It also
means `oas_docs/makefile` should be superseded by JS script(s) using
`merge` utility form `@kbn/openapi-bundler`
package.\r\n\r\n`@kbn/openapi-bundler` SHOULD NOT replace OpenAPI
linters since it doesn't perform thorough linting. It's good if we
continue adopting `spectral-cli` for linting
purposes.","sha":"7a2e7bef9644eaf04fd820d16b8ee137b3c00f2b","branchLabelMapping":{"^v8.16.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["Team:Core","release_note:skip","backport:skip","docs","Team:
SecuritySolution","Feature:OAS","v8.16.0"],"number":189262,"url":"https://github.com/elastic/kibana/pull/189262","mergeCommit":{"message":"[HTTP/OAS]
Merge OpenAPI specs by using `kbn-openapi-bundler`
(#189262)\n\n**Addresses:**
https://github.com/elastic/kibana/issues/186356\r\n**Relates to:**
https://github.com/elastic/kibana/issues/184428\r\n\r\n##
Summary\r\n\r\nThis PR adds a merging JS script based on the utility
implemented in #186356. Resulted
OpenAPI bundle as committed in
`oas_docs/output/kibana.serverless.bundled.yaml`.\r\n\r\n##
Details\r\n\r\nhttps://github.com//pull/188110 implements
and exposes `merge` utility design to merge source OpenAPI specs without
processing. It's has only a programmatic API. To merge OpenAPI specs
it's required to add a JS script like below\r\n\r\n```js\r\nconst {
merge } = require('@kbn/openapi-bundler');\r\n\r\n(async () => {\r\n
await merge({\r\n sourceGlobs: [/* a list of source globs goes here
*/],\r\n outputFilePath: 'path/to/the/output/file.yaml',\r\n
});\r\n})();\r\n```\r\n\r\nThe JS script added in this PR includes
source OpenAPI specs presented in `oas_docs/makefile` plus Security
Solution OpenAPI specs based on
https://github.com/elastic/kibana/issues/184428.\r\n\r\n**To run** the
script use the following command from Kibana root
folder\r\n\r\n```bash\r\nnode ./oas_docs/scripts/merge_serverless_oas.js
\r\n```\r\n\r\n## Known linting issues with Security Solution OpenAPI
specs\r\n\r\nRunning Spectral OpenAPI linter on the result bundle shows
a number of errors caused by `no-$ref-siblings` rule. This caused by the
current code generator implementation which requires `default` property
to be set next to `$ref` though it's not correct for OpenAPI `3.0.3`
while it's allowed in `3.1`. It seems that Bump.sh handles such cases
properly though by properly showing a default value.\r\n\r\nWe need to
analyze the problem and decide if/when we should fix it.\r\n\r\nThe rest
of warnings look fixable and will be addressed in the next stage after
setting up linter rules.\r\n\r\n## Next steps\r\n\r\nSince
`@kbn/openapi-bundler` package is tailored specifically for Kibana it
should replace Redocly currently used to merge OpenAPI specs. It also
means `oas_docs/makefile` should be superseded by JS script(s) using
`merge` utility form `@kbn/openapi-bundler`
package.\r\n\r\n`@kbn/openapi-bundler` SHOULD NOT replace OpenAPI
linters since it doesn't perform thorough linting. It's good if we
continue adopting `spectral-cli` for linting
purposes.","sha":"7a2e7bef9644eaf04fd820d16b8ee137b3c00f2b"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v8.16.0","labelRegex":"^v8.16.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/189262","number":189262,"mergeCommit":{"message":"[HTTP/OAS]
Merge OpenAPI specs by using `kbn-openapi-bundler`
(#189262)\n\n**Addresses:**
https://github.com/elastic/kibana/issues/186356\r\n**Relates to:**
https://github.com/elastic/kibana/issues/184428\r\n\r\n##
Summary\r\n\r\nThis PR adds a merging JS script based on the utility
implemented in #186356. Resulted
OpenAPI bundle as committed in
`oas_docs/output/kibana.serverless.bundled.yaml`.\r\n\r\n##
Details\r\n\r\nhttps://github.com//pull/188110 implements
and exposes `merge` utility design to merge source OpenAPI specs without
processing. It's has only a programmatic API. To merge OpenAPI specs
it's required to add a JS script like below\r\n\r\n```js\r\nconst {
merge } = require('@kbn/openapi-bundler');\r\n\r\n(async () => {\r\n
await merge({\r\n sourceGlobs: [/* a list of source globs goes here
*/],\r\n outputFilePath: 'path/to/the/output/file.yaml',\r\n
});\r\n})();\r\n```\r\n\r\nThe JS script added in this PR includes
source OpenAPI specs presented in `oas_docs/makefile` plus Security
Solution OpenAPI specs based on
https://github.com/elastic/kibana/issues/184428.\r\n\r\n**To run** the
script use the following command from Kibana root
folder\r\n\r\n```bash\r\nnode ./oas_docs/scripts/merge_serverless_oas.js
\r\n```\r\n\r\n## Known linting issues with Security Solution OpenAPI
specs\r\n\r\nRunning Spectral OpenAPI linter on the result bundle shows
a number of errors caused by `no-$ref-siblings` rule. This caused by the
current code generator implementation which requires `default` property
to be set next to `$ref` though it's not correct for OpenAPI `3.0.3`
while it's allowed in `3.1`. It seems that Bump.sh handles such cases
properly though by properly showing a default value.\r\n\r\nWe need to
analyze the problem and decide if/when we should fix it.\r\n\r\nThe rest
of warnings look fixable and will be addressed in the next stage after
setting up linter rules.\r\n\r\n## Next steps\r\n\r\nSince
`@kbn/openapi-bundler` package is tailored specifically for Kibana it
should replace Redocly currently used to merge OpenAPI specs. It also
means `oas_docs/makefile` should be superseded by JS script(s) using
`merge` utility form `@kbn/openapi-bundler`
package.\r\n\r\n`@kbn/openapi-bundler` SHOULD NOT replace OpenAPI
linters since it doesn't perform thorough linting. It's good if we
continue adopting `spectral-cli` for linting
purposes.","sha":"7a2e7bef9644eaf04fd820d16b8ee137b3c00f2b"}}]}]
BACKPORT-->

---------

Co-authored-by: Maxim Palenov <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport:skip This commit does not require backporting docs Project:Serverless Work as part of the Serverless project for its initial release release_note:skip Skip the PR/issue when compiling release notes Team:Detection Rule Management Security Detection Rule Management Team Team:Detections and Resp Security Detection Response Team Team: SecuritySolution Security Solutions Team working on SIEM, Endpoint, Timeline, Resolver, etc. v8.16.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants