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

[Console] Use ES specification for autocomplete definitions #159241

Merged
merged 19 commits into from
Jun 23, 2023
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
2cc1e5f
[Console] Create a new package to generate autocomplete definitions
yuliacech Jun 7, 2023
bd76003
[Console] Add Kibana a script command and implementation basics for d…
yuliacech Jun 7, 2023
9b58966
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Jun 7, 2023
fdcddb6
[CI] Auto-commit changed files from 'node scripts/generate codeowners'
kibanamachine Jun 7, 2023
e6754ee
[Console] Remove the new folder
yuliacech Jun 13, 2023
52051aa
[Console] Add options for source and dest folders
yuliacech Jun 13, 2023
e0b3c18
[Console] Export a constant for autocomplete definitions folder and u…
yuliacech Jun 14, 2023
1b63e1e
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Jun 14, 2023
751ac76
[Console] Add functionality to create the definitions folder if doesn…
yuliacech Jun 15, 2023
2340672
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Jun 15, 2023
a237de0
Merge branch 'main' into console/new_definitions
yuliacech Jun 15, 2023
7804ccf
[Console] Add description and usage to the command
yuliacech Jun 15, 2023
5b66edd
Update packages/kbn-generate-console-definitions/src/cli.ts
yuliacech Jun 21, 2023
ad59531
Update packages/kbn-generate-console-definitions/src/cli.ts
yuliacech Jun 21, 2023
70045a0
Update packages/kbn-generate-console-definitions/src/cli.ts
yuliacech Jun 21, 2023
ddc250f
Merge branch 'main' into console/new_definitions
yuliacech Jun 21, 2023
a90111b
[Console] Add back a new line at the end of the definitions files
yuliacech Jun 21, 2023
aa781d5
Merge branch 'main' into console/new_definitions
yuliacech Jun 23, 2023
927cb73
[Console] Fix the new line
yuliacech Jun 23, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,7 @@ packages/kbn-ftr-common-functional-services @elastic/kibana-operations @elastic/
packages/kbn-ftr-screenshot-filename @elastic/kibana-operations @elastic/appex-qa
x-pack/test/functional_with_es_ssl/plugins/cases @elastic/response-ops
packages/kbn-generate @elastic/kibana-operations
packages/kbn-generate-console-definitions @elastic/platform-deployment-management
packages/kbn-generate-csv @elastic/appex-sharedux
packages/kbn-generate-csv-types @elastic/appex-sharedux
packages/kbn-get-repo-files @elastic/kibana-operations
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,7 @@
"@kbn/foo-plugin": "link:x-pack/test/ui_capabilities/common/plugins/foo_plugin",
"@kbn/ftr-apis-plugin": "link:src/plugins/ftr_apis",
"@kbn/functional-with-es-ssl-cases-test-plugin": "link:x-pack/test/functional_with_es_ssl/plugins/cases",
"@kbn/generate-console-definitions": "link:packages/kbn-generate-console-definitions",
"@kbn/generate-csv": "link:packages/kbn-generate-csv",
"@kbn/generate-csv-types": "link:packages/kbn-generate-csv-types",
"@kbn/global-search-bar-plugin": "link:x-pack/plugins/global_search_bar",
Expand Down
3 changes: 3 additions & 0 deletions packages/kbn-generate-console-definitions/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# @kbn/generate-console-definitions

Empty package generated by @kbn/generate
9 changes: 9 additions & 0 deletions packages/kbn-generate-console-definitions/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

export * from './src/cli';
13 changes: 13 additions & 0 deletions packages/kbn-generate-console-definitions/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

module.exports = {
preset: '@kbn/test/jest_node',
rootDir: '../..',
roots: ['<rootDir>/packages/kbn-generate-console-definitions'],
};
5 changes: 5 additions & 0 deletions packages/kbn-generate-console-definitions/kibana.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"type": "shared-common",
"id": "@kbn/generate-console-definitions",
"owner": "@elastic/platform-deployment-management"
}
6 changes: 6 additions & 0 deletions packages/kbn-generate-console-definitions/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "@kbn/generate-console-definitions",
"private": true,
"version": "1.0.0",
"license": "SSPL-1.0 OR Elastic License 2.0"
}
76 changes: 76 additions & 0 deletions packages/kbn-generate-console-definitions/src/cli.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import Path from 'path';
import fs from 'fs';
import { run } from '@kbn/dev-cli-runner';
import { createFlagError } from '@kbn/dev-cli-errors';
import { REPO_ROOT } from '@kbn/repo-info';
import { AUTOCOMPLETE_DEFINITIONS_FOLDER } from '@kbn/console-plugin/common/constants';
import { generateConsoleDefinitions } from './generate_console_definitions';

export function runGenerateConsoleDefinitionsCli() {
run(
(context) => {
const { log, flags } = context;
log.info('starting console definitions generation');
const { source, dest, emptyDest } = flags;
if (!source) {
throw createFlagError(`Missing --source argument`);
}
let definitionsFolder = Path.resolve(REPO_ROOT, `${dest}`);
if (!dest) {
definitionsFolder = Path.resolve(AUTOCOMPLETE_DEFINITIONS_FOLDER, 'generated');
}
log.info(`autocomplete definitions folder ${definitionsFolder}`);
if (!fs.existsSync(definitionsFolder)) {
log.warning(`folder ${definitionsFolder} doesn't exist, creating a new folder`);
fs.mkdirSync(definitionsFolder, { recursive: true });
log.warning(`created a new folder ${definitionsFolder}`);
}
const files = fs.readdirSync(definitionsFolder);
if (files.length > 0) {
if (!emptyDest) {
throw createFlagError(
`Definitions folder already contain files, use --emptyDest to clean the folder before generation`
);
}
log.warning(`folder ${definitionsFolder} already contains files, emptying the folder`);
for (const file of files) {
fs.unlinkSync(Path.resolve(definitionsFolder, file));
}
log.warning(`folder ${definitionsFolder} has been emptied`);
}

const specsRepo = Path.resolve(`${source}`);
if (!fs.existsSync(specsRepo)) {
throw createFlagError(`ES specification folder ${specsRepo} doesn't exist`);
}
log.info(`ES specification repo folder ${source}`);
generateConsoleDefinitions({ specsRepo, definitionsFolder, log });
log.info('completed console definitions generation');
},
{
description: `Generate Console autocomplete definitions from the ES specification repo`,
usage: `
node scripts/generate_console_definitions.js --help
node scripts/generate_console_definitions.js --source <ES_SPECIFICATION_REPO>
node scripts/generate_console_definitions.js --source <ES_SPECIFICATION_REPO> [--dest <DEFINITIONS_FOLDER] [--emptyDest]
`,
flags: {
string: ['source', 'dest'],
boolean: ['emptyDest'],
help: `
--source Folder containing the root of the Elasticsearch specification repo
--dest Folder where console autocomplete definitions will be generated (relative to the Kibana repo root)
--emptyDest Flag to empty definitions folder if it already contains any files
`,
},
}
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import fs from 'fs';
import Path, { join } from 'path';
import { ToolingLog } from '@kbn/tooling-log';

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This file is mostly WIP and probably will change a lot in follow up PRs. But still feel free to review as usual

interface EndpointRequest {
name: string;
namespace: string;
}

interface Endpoint {
name: string;
urls: Array<{
methods: string[];
path: string;
}>;
docUrl: string;
request: null | EndpointRequest;
}

interface SchemaType {
name: {
name: string;
namespace: string;
};
}

interface Schema {
endpoints: Endpoint[];
types: SchemaType[];
}

interface UrlParams {
[key: string]: number | string;
}

interface BodyParams {
[key: string]: number | string;
}

interface Definition {
documentation?: string;
methods: string[];
patterns: string[];
url_params?: UrlParams;
data_autocomplete_rules?: BodyParams;
}

const generateMethods = (endpoint: Endpoint): string[] => {
// this array consists of arrays of strings
const methodsArray = endpoint.urls.map((url) => url.methods);
// flatten to return array of strings
const flattenMethodsArray = ([] as string[]).concat(...methodsArray);
// use set to remove duplication
return [...new Set(flattenMethodsArray)];
};

const generatePatterns = (endpoint: Endpoint): string[] => {
return endpoint.urls.map(({ path }) => {
let pattern = path;
// remove leading / if present
if (path.startsWith('/')) {
pattern = path.substring(1);
}
return pattern;
});
};

const generateDocumentation = (endpoint: Endpoint): string => {
return endpoint.docUrl;
};

const generateParams = (
endpoint: Endpoint,
schema: Schema
): { urlParams: UrlParams; bodyParams: BodyParams } | undefined => {
const { request } = endpoint;
if (!request) {
return;
}
const requestType = schema.types.find(
({ name: { name, namespace } }) => name === request.name && namespace === request.namespace
);
if (!requestType) {
return;
}

const urlParams = generateUrlParams(requestType);
const bodyParams = generateBodyParams(requestType);
return { urlParams, bodyParams };
};

const generateUrlParams = (requestType: SchemaType): UrlParams => {
return {};
};

const generateBodyParams = (requestType: SchemaType): BodyParams => {
return {};
};

const addParams = (
definition: Definition,
params: { urlParams: UrlParams; bodyParams: BodyParams }
): Definition => {
const { urlParams, bodyParams } = params;
if (urlParams && Object.keys(urlParams).length > 0) {
definition.url_params = urlParams;
}
if (bodyParams && Object.keys(bodyParams).length > 0) {
definition.data_autocomplete_rules = bodyParams;
}
return definition;
};

const generateDefinition = (endpoint: Endpoint, schema: Schema): Definition => {
const methods = generateMethods(endpoint);
const patterns = generatePatterns(endpoint);
const documentation = generateDocumentation(endpoint);
let definition: Definition = { methods, patterns, documentation };
const params = generateParams(endpoint, schema);
if (params) {
definition = addParams(definition, params);
}

return definition;
};

export function generateConsoleDefinitions({
specsRepo,
definitionsFolder,
log,
}: {
specsRepo: string;
definitionsFolder: string;
log: ToolingLog;
}) {
const pathToSchemaFile = Path.resolve(specsRepo, 'output/schema/schema.json');
log.info('loading the ES specification schema file');
const schema = JSON.parse(fs.readFileSync(pathToSchemaFile, 'utf8')) as Schema;

const { endpoints } = schema;
log.info(`iterating over endpoints array: ${endpoints.length} endpoints`);
endpoints.forEach((endpoint) => {
const { name } = endpoint;
log.info(name);
const definition = generateDefinition(endpoint, schema);
const fileContent: { [name: string]: Definition } = {
[name]: definition,
};
fs.writeFileSync(
join(definitionsFolder, `${name}.json`),
JSON.stringify(fileContent + '\n', null, 2),
'utf8'
);
});
}
23 changes: 23 additions & 0 deletions packages/kbn-generate-console-definitions/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "target/types",
"types": [
"jest",
"node"
]
},
"include": [
"**/*.ts",
],
"exclude": [
"target/**/*"
],
"kbn_references": [
"@kbn/dev-cli-runner",
"@kbn/dev-cli-errors",
"@kbn/repo-info",
"@kbn/console-plugin",
"@kbn/tooling-log",
]
}
10 changes: 10 additions & 0 deletions scripts/generate_console_definitions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

require('../src/setup_node_env');
require('@kbn/generate-console-definitions').runGenerateConsoleDefinitionsCli();
14 changes: 14 additions & 0 deletions src/plugins/console/common/constants/autocomplete_definitions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { resolve } from 'path';

export const AUTOCOMPLETE_DEFINITIONS_FOLDER = resolve(
__dirname,
'../../server/lib/spec_definitions/json'
);
1 change: 1 addition & 0 deletions src/plugins/console/common/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@
export { MAJOR_VERSION } from './plugin';
export { API_BASE_PATH, KIBANA_API_PREFIX } from './api';
export { DEFAULT_VARIABLES } from './variables';
export { AUTOCOMPLETE_DEFINITIONS_FOLDER } from './autocomplete_definitions';
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ export function getDocumentation(
if (endpoint && endpoint.documentation && endpoint.documentation.indexOf('http') !== -1) {
return endpoint.documentation
.replace('/master/', `/${docLinkVersion}/`)
.replace('/current/', `/${docLinkVersion}/`);
.replace('/current/', `/${docLinkVersion}/`)
.replace('/{branch}/', `/${docLinkVersion}/`);
} else {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,13 @@

import _, { merge } from 'lodash';
import globby from 'globby';
import { basename, join, resolve } from 'path';
import { basename, join } from 'path';
import normalizePath from 'normalize-path';
import { readFileSync } from 'fs';

import { AUTOCOMPLETE_DEFINITIONS_FOLDER } from '../../common/constants';
import { jsSpecLoaders } from '../lib';

const PATH_TO_OSS_JSON_SPEC = resolve(__dirname, '../lib/spec_definitions/json');

interface EndpointDescription {
methods?: string[];
patterns?: string | string[];
Expand Down Expand Up @@ -129,7 +128,7 @@ export class SpecDefinitionsService {
}

private loadJsonSpec() {
const result = this.loadJSONSpecInDir(PATH_TO_OSS_JSON_SPEC);
const result = this.loadJSONSpecInDir(AUTOCOMPLETE_DEFINITIONS_FOLDER);
this.extensionSpecFilePaths.forEach((extensionSpecFilePath) => {
merge(result, this.loadJSONSpecInDir(extensionSpecFilePath));
});
Expand Down
2 changes: 2 additions & 0 deletions tsconfig.base.json
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,8 @@
"@kbn/functional-with-es-ssl-cases-test-plugin/*": ["x-pack/test/functional_with_es_ssl/plugins/cases/*"],
"@kbn/generate": ["packages/kbn-generate"],
"@kbn/generate/*": ["packages/kbn-generate/*"],
"@kbn/generate-console-definitions": ["packages/kbn-generate-console-definitions"],
"@kbn/generate-console-definitions/*": ["packages/kbn-generate-console-definitions/*"],
"@kbn/generate-csv": ["packages/kbn-generate-csv"],
"@kbn/generate-csv/*": ["packages/kbn-generate-csv/*"],
"@kbn/generate-csv-types": ["packages/kbn-generate-csv-types"],
Expand Down
Loading