diff --git a/src/plugins/console/README.md b/src/plugins/console/README.md index ac4cc8f76dd38..f03c7d9defe0d 100644 --- a/src/plugins/console/README.md +++ b/src/plugins/console/README.md @@ -54,7 +54,14 @@ Autocomplete definitions are all created in the form of javascript objects loade ### Creating definitions The [`generated`](https://github.com/elastic/kibana/blob/main/src/plugins/console/server/lib/spec_definitions/json/generated) folder contains definitions created automatically from Elasticsearch REST API specifications. See this [README](https://github.com/elastic/kibana/blob/main/packages/kbn-spec-to-console/README.md) file for more information on the `spec-to-console` script. -Manually created override files in the [`overrides`](https://github.com/elastic/kibana/blob/main/src/plugins/console/server/lib/spec_definitions/json/overrides) folder contain fixes for generated files and additions for request body parameters. +Manually created override files in the [`overrides`](https://github.com/elastic/kibana/blob/main/src/plugins/console/server/lib/spec_definitions/json/overrides) folder contain additions for request body parameters since those +are not created by the script. Any other fixes such as documentation links, request methods and patterns and url parameters +should be addressed at the source. That means this should be fixed in Elasticsearch REST API specifications and then +autocomplete definitions can be re-generated with the script. + +If there are any endpoints missing completely from the `generated` folder, this should also be addressed at the source, i.e. +Elasticsearch REST API specifications. If for some reason, that is not possible, then additional definitions files +can be placed in the folder [`manual`]((https://github.com/elastic/kibana/blob/main/src/plugins/console/server/lib/spec_definitions/json/manual)). ### Top level keys Use following top level keys in the definitions objects. diff --git a/src/plugins/console/common/constants/autocomplete_definitions.ts b/src/plugins/console/common/constants/autocomplete_definitions.ts index 9e106e1641d10..bc236a12fe1e3 100644 --- a/src/plugins/console/common/constants/autocomplete_definitions.ts +++ b/src/plugins/console/common/constants/autocomplete_definitions.ts @@ -12,3 +12,7 @@ export const AUTOCOMPLETE_DEFINITIONS_FOLDER = resolve( __dirname, '../../server/lib/spec_definitions/json' ); + +export const GENERATED_SUBFOLDER = 'generated'; +export const OVERRIDES_SUBFOLDER = 'overrides'; +export const MANUAL_SUBFOLDER = 'manual'; diff --git a/src/plugins/console/common/constants/index.ts b/src/plugins/console/common/constants/index.ts index d8a259c4c450d..a3ecf18113aeb 100644 --- a/src/plugins/console/common/constants/index.ts +++ b/src/plugins/console/common/constants/index.ts @@ -9,4 +9,9 @@ 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'; +export { + AUTOCOMPLETE_DEFINITIONS_FOLDER, + GENERATED_SUBFOLDER, + OVERRIDES_SUBFOLDER, + MANUAL_SUBFOLDER, +} from './autocomplete_definitions'; diff --git a/src/plugins/console/common/types/autocomplete_definitions.ts b/src/plugins/console/common/types/autocomplete_definitions.ts new file mode 100644 index 0000000000000..a7bb4cdf9a1f1 --- /dev/null +++ b/src/plugins/console/common/types/autocomplete_definitions.ts @@ -0,0 +1,23 @@ +/* + * 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 type EndpointsAvailability = 'stack' | 'serverless'; + +export interface EndpointDescription { + methods?: string[]; + patterns?: string | string[]; + url_params?: Record; + data_autocomplete_rules?: Record; + url_components?: Record; + priority?: number; + availability?: Record; +} + +export interface EndpointDefinition { + [endpointName: string]: EndpointDescription; +} diff --git a/src/plugins/console/common/types/index.ts b/src/plugins/console/common/types/index.ts index a2dcde016a6b7..18b5299f9353b 100644 --- a/src/plugins/console/common/types/index.ts +++ b/src/plugins/console/common/types/index.ts @@ -8,3 +8,4 @@ export * from './models'; export * from './plugin_config'; +export * from './autocomplete_definitions'; diff --git a/src/plugins/console/server/config.ts b/src/plugins/console/server/config.ts index 99bf06e5a06f8..281d18895ceec 100644 --- a/src/plugins/console/server/config.ts +++ b/src/plugins/console/server/config.ts @@ -26,8 +26,9 @@ const schemaLatest = schema.object( }), autocompleteDefinitions: schema.object({ // Only displays the endpoints that are available in the specified environment - // Current supported values are 'stack' and 'serverless' - endpointsAvailability: schema.string({ defaultValue: 'stack' }), + endpointsAvailability: schema.oneOf([schema.literal('stack'), schema.literal('serverless')], { + defaultValue: 'stack', + }), }), }, { defaultValue: undefined } diff --git a/src/plugins/console/server/lib/spec_definitions/json/README.md b/src/plugins/console/server/lib/spec_definitions/json/README.md new file mode 100644 index 0000000000000..9e9dc9fbec716 --- /dev/null +++ b/src/plugins/console/server/lib/spec_definitions/json/README.md @@ -0,0 +1 @@ +Please refer to this [README](https://github.com/elastic/kibana/blob/main/src/plugins/console/README.md#creating-definitions) file before adding/editing definitions files in this folder. \ No newline at end of file diff --git a/src/plugins/console/server/lib/spec_definitions/json/generated/autoscaling.get_autoscaling_decision.json b/src/plugins/console/server/lib/spec_definitions/json/generated/autoscaling.get_autoscaling_decision.json deleted file mode 100644 index 241075f4ca538..0000000000000 --- a/src/plugins/console/server/lib/spec_definitions/json/generated/autoscaling.get_autoscaling_decision.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "autoscaling.get_autoscaling_decision": { - "methods": [ - "GET" - ], - "patterns": [ - "_autoscaling/decision" - ], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/autoscaling-get-autoscaling-decision.html" - } -} diff --git a/src/plugins/console/server/lib/spec_definitions/json/generated/data_frame_transform_deprecated.delete_transform.json b/src/plugins/console/server/lib/spec_definitions/json/generated/data_frame_transform_deprecated.delete_transform.json deleted file mode 100644 index 6dfd81ded7bc5..0000000000000 --- a/src/plugins/console/server/lib/spec_definitions/json/generated/data_frame_transform_deprecated.delete_transform.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "data_frame_transform_deprecated.delete_transform": { - "url_params": { - "force": "__flag__" - }, - "methods": [], - "patterns": [], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/delete-transform.html" - } -} diff --git a/src/plugins/console/server/lib/spec_definitions/json/generated/data_frame_transform_deprecated.get_transform.json b/src/plugins/console/server/lib/spec_definitions/json/generated/data_frame_transform_deprecated.get_transform.json deleted file mode 100644 index be3716ba3da6e..0000000000000 --- a/src/plugins/console/server/lib/spec_definitions/json/generated/data_frame_transform_deprecated.get_transform.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "data_frame_transform_deprecated.get_transform": { - "url_params": { - "from": 0, - "size": 0, - "allow_no_match": "__flag__", - "exclude_generated": "__flag__" - }, - "methods": [], - "patterns": [], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/get-transform.html" - } -} diff --git a/src/plugins/console/server/lib/spec_definitions/json/generated/data_frame_transform_deprecated.get_transform_stats.json b/src/plugins/console/server/lib/spec_definitions/json/generated/data_frame_transform_deprecated.get_transform_stats.json deleted file mode 100644 index 440eed6a1f2a4..0000000000000 --- a/src/plugins/console/server/lib/spec_definitions/json/generated/data_frame_transform_deprecated.get_transform_stats.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "data_frame_transform_deprecated.get_transform_stats": { - "url_params": { - "from": "", - "size": "", - "allow_no_match": "__flag__" - }, - "methods": [], - "patterns": [], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/get-transform-stats.html" - } -} diff --git a/src/plugins/console/server/lib/spec_definitions/json/generated/data_frame_transform_deprecated.preview_transform.json b/src/plugins/console/server/lib/spec_definitions/json/generated/data_frame_transform_deprecated.preview_transform.json deleted file mode 100644 index f095847ed0d9a..0000000000000 --- a/src/plugins/console/server/lib/spec_definitions/json/generated/data_frame_transform_deprecated.preview_transform.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "data_frame_transform_deprecated.preview_transform": { - "methods": [], - "patterns": [], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/preview-transform.html" - } -} diff --git a/src/plugins/console/server/lib/spec_definitions/json/generated/data_frame_transform_deprecated.put_transform.json b/src/plugins/console/server/lib/spec_definitions/json/generated/data_frame_transform_deprecated.put_transform.json deleted file mode 100644 index e7555ce4bad29..0000000000000 --- a/src/plugins/console/server/lib/spec_definitions/json/generated/data_frame_transform_deprecated.put_transform.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "data_frame_transform_deprecated.put_transform": { - "url_params": { - "defer_validation": "__flag__" - }, - "methods": [], - "patterns": [], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/put-transform.html" - } -} diff --git a/src/plugins/console/server/lib/spec_definitions/json/generated/data_frame_transform_deprecated.start_transform.json b/src/plugins/console/server/lib/spec_definitions/json/generated/data_frame_transform_deprecated.start_transform.json deleted file mode 100644 index d50346ff328c6..0000000000000 --- a/src/plugins/console/server/lib/spec_definitions/json/generated/data_frame_transform_deprecated.start_transform.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "data_frame_transform_deprecated.start_transform": { - "url_params": { - "timeout": "" - }, - "methods": [], - "patterns": [], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/start-transform.html" - } -} diff --git a/src/plugins/console/server/lib/spec_definitions/json/generated/data_frame_transform_deprecated.stop_transform.json b/src/plugins/console/server/lib/spec_definitions/json/generated/data_frame_transform_deprecated.stop_transform.json deleted file mode 100644 index 2618446916c76..0000000000000 --- a/src/plugins/console/server/lib/spec_definitions/json/generated/data_frame_transform_deprecated.stop_transform.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "data_frame_transform_deprecated.stop_transform": { - "url_params": { - "wait_for_completion": "__flag__", - "timeout": "", - "allow_no_match": "__flag__" - }, - "methods": [], - "patterns": [], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/stop-transform.html" - } -} diff --git a/src/plugins/console/server/lib/spec_definitions/json/generated/data_frame_transform_deprecated.update_transform.json b/src/plugins/console/server/lib/spec_definitions/json/generated/data_frame_transform_deprecated.update_transform.json deleted file mode 100644 index 60f71474e865a..0000000000000 --- a/src/plugins/console/server/lib/spec_definitions/json/generated/data_frame_transform_deprecated.update_transform.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "data_frame_transform_deprecated.update_transform": { - "url_params": { - "defer_validation": "__flag__" - }, - "methods": [], - "patterns": [], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/update-transform.html" - } -} diff --git a/src/plugins/console/server/lib/spec_definitions/json/generated/ilm.set_policy.json b/src/plugins/console/server/lib/spec_definitions/json/generated/ilm.set_policy.json deleted file mode 100644 index 6c57973eaabae..0000000000000 --- a/src/plugins/console/server/lib/spec_definitions/json/generated/ilm.set_policy.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "ilm.set_policy": { - "methods": [ - "PUT" - ], - "patterns": [ - "{indices}/_ilm/{new_policy}" - ], - "documentation": "http://www.elastic.co/guide/en/index_lifecycle/current/index_lifecycle.html" - } -} diff --git a/src/plugins/console/server/lib/spec_definitions/json/generated/indices.exists_type.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.exists_type.json deleted file mode 100644 index 0b11356155b50..0000000000000 --- a/src/plugins/console/server/lib/spec_definitions/json/generated/indices.exists_type.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "indices.exists_type": { - "url_params": { - "ignore_unavailable": "__flag__", - "allow_no_indices": "__flag__", - "expand_wildcards": [ - "open", - "closed", - "hidden", - "none", - "all" - ], - "local": "__flag__" - }, - "methods": [ - "HEAD" - ], - "patterns": [ - "{indices}/_mapping/{type}" - ], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-types-exists.html" - } -} diff --git a/src/plugins/console/server/lib/spec_definitions/json/generated/indices.flush_synced.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.flush_synced.json deleted file mode 100644 index 4531401105122..0000000000000 --- a/src/plugins/console/server/lib/spec_definitions/json/generated/indices.flush_synced.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "indices.flush_synced": { - "url_params": { - "ignore_unavailable": "__flag__", - "allow_no_indices": "__flag__", - "expand_wildcards": [ - "open", - "closed", - "none", - "all" - ] - }, - "methods": [ - "POST", - "GET" - ], - "patterns": [ - "_flush/synced", - "{indices}/_flush/synced" - ], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-synced-flush-api.html" - } -} diff --git a/src/plugins/console/server/lib/spec_definitions/json/generated/indices.freeze.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.freeze.json deleted file mode 100644 index 77c765b90bcdc..0000000000000 --- a/src/plugins/console/server/lib/spec_definitions/json/generated/indices.freeze.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "indices.freeze": { - "url_params": { - "timeout": "", - "master_timeout": "", - "ignore_unavailable": "__flag__", - "allow_no_indices": "__flag__", - "expand_wildcards": [ - "open", - "closed", - "hidden", - "none", - "all" - ], - "wait_for_active_shards": "" - }, - "methods": [], - "patterns": [], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/freeze-index-api.html" - } -} diff --git a/src/plugins/console/server/lib/spec_definitions/json/generated/indices.get_upgrade.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.get_upgrade.json deleted file mode 100644 index 99ac958523084..0000000000000 --- a/src/plugins/console/server/lib/spec_definitions/json/generated/indices.get_upgrade.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "indices.get_upgrade": { - "url_params": { - "ignore_unavailable": "__flag__", - "allow_no_indices": "__flag__", - "expand_wildcards": [ - "open", - "closed", - "hidden", - "none", - "all" - ] - }, - "methods": [ - "GET" - ], - "patterns": [ - "_upgrade", - "{indices}/_upgrade" - ], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-upgrade.html" - } -} diff --git a/src/plugins/console/server/lib/spec_definitions/json/generated/indices.upgrade.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.upgrade.json deleted file mode 100644 index 484115bb9b260..0000000000000 --- a/src/plugins/console/server/lib/spec_definitions/json/generated/indices.upgrade.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "indices.upgrade": { - "url_params": { - "allow_no_indices": "__flag__", - "expand_wildcards": [ - "open", - "closed", - "hidden", - "none", - "all" - ], - "ignore_unavailable": "__flag__", - "wait_for_completion": "__flag__", - "only_ancient_segments": "__flag__" - }, - "methods": [ - "POST" - ], - "patterns": [ - "_upgrade", - "{indices}/_upgrade" - ], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-upgrade.html" - } -} diff --git a/src/plugins/console/server/lib/spec_definitions/json/generated/migration.get_assistance.json b/src/plugins/console/server/lib/spec_definitions/json/generated/migration.get_assistance.json deleted file mode 100644 index 4cc068ce2e460..0000000000000 --- a/src/plugins/console/server/lib/spec_definitions/json/generated/migration.get_assistance.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "xpack.migration.get_assistance": { - "url_params": { - "allow_no_indices": "__flag__", - "expand_wildcards": [ - "open", - "closed", - "none", - "all" - ], - "ignore_unavailable": "__flag__" - }, - "methods": [ - "GET" - ], - "patterns": [ - "_migration/assistance", - "_migration/assistance/{indices}" - ], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/migration-api-assistance.html" - } -} diff --git a/src/plugins/console/server/lib/spec_definitions/json/generated/migration.upgrade.json b/src/plugins/console/server/lib/spec_definitions/json/generated/migration.upgrade.json deleted file mode 100644 index 93186f31a0876..0000000000000 --- a/src/plugins/console/server/lib/spec_definitions/json/generated/migration.upgrade.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "xpack.migration.upgrade": { - "url_params": { - "wait_for_completion": "__flag__" - }, - "methods": [ - "POST" - ], - "patterns": [ - "_migration/upgrade/{indices}" - ], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/migration-api-upgrade.html" - } -} diff --git a/src/plugins/console/server/lib/spec_definitions/json/generated/ml.find_file_structure.json b/src/plugins/console/server/lib/spec_definitions/json/generated/ml.find_file_structure.json deleted file mode 100644 index 9ede28306e313..0000000000000 --- a/src/plugins/console/server/lib/spec_definitions/json/generated/ml.find_file_structure.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "ml.find_file_structure": { - "url_params": { - "lines_to_sample": 0, - "line_merge_size_limit": 0, - "timeout": "", - "charset": "", - "format": [ - "ndjson", - "xml", - "delimited", - "semi_structured_text" - ], - "has_header_row": "__flag__", - "column_names": [], - "delimiter": "", - "quote": "", - "should_trim_fields": "__flag__", - "grok_pattern": "", - "timestamp_field": "", - "timestamp_format": "", - "explain": "__flag__" - }, - "methods": [ - "POST" - ], - "patterns": [ - "_text_structure/find_structure" - ], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/find-structure.html" - } -} diff --git a/src/plugins/console/server/lib/spec_definitions/json/generated/ml.upgrade.json b/src/plugins/console/server/lib/spec_definitions/json/generated/ml.upgrade.json deleted file mode 100644 index 4603b7d5a5e4d..0000000000000 --- a/src/plugins/console/server/lib/spec_definitions/json/generated/ml.upgrade.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "ml.upgrade": { - "url_params": { - "wait_for_completion": "__flag__" - }, - "methods": [ - "POST" - ], - "patterns": [ - "_ml/_upgrade" - ], - "documentation": "TODO" - } -} diff --git a/src/plugins/console/server/lib/spec_definitions/json/generated/rollup.rollup.json b/src/plugins/console/server/lib/spec_definitions/json/generated/rollup.rollup.json deleted file mode 100644 index c3cc629abac80..0000000000000 --- a/src/plugins/console/server/lib/spec_definitions/json/generated/rollup.rollup.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "rollup.rollup": { - "methods": [ - "POST" - ], - "patterns": [ - "{indices}/_rollup/{rollup_index}" - ], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/xpack-rollup.html" - } -} diff --git a/src/plugins/console/server/lib/spec_definitions/json/generated/transform.cat_transform.json b/src/plugins/console/server/lib/spec_definitions/json/generated/transform.cat_transform.json deleted file mode 100644 index 6fe19a6e53d28..0000000000000 --- a/src/plugins/console/server/lib/spec_definitions/json/generated/transform.cat_transform.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "transform.cat_transform": { - "url_params": { - "from": 0, - "size": 0, - "allow_no_match": "__flag__", - "format": "", - "h": [], - "help": "__flag__", - "s": [], - "time": [ - "d", - "h", - "m", - "s", - "ms", - "micros", - "nanos" - ], - "v": "__flag__" - }, - "methods": [ - "GET" - ], - "patterns": [ - "_cat/transforms", - "_cat/transforms/{transform_id}" - ], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/cat-transforms.html" - } -} diff --git a/src/plugins/console/server/lib/spec_definitions/json/generated/xpack.ssl.certificates.json b/src/plugins/console/server/lib/spec_definitions/json/generated/xpack.ssl.certificates.json deleted file mode 100644 index 0a4b60b6766e4..0000000000000 --- a/src/plugins/console/server/lib/spec_definitions/json/generated/xpack.ssl.certificates.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "xpack.ssl.certificates": { - "methods": [ - "GET" - ], - "patterns": [ - "_xpack/ssl/certificates" - ], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-ssl.html" - } -} diff --git a/src/plugins/console/server/lib/spec_definitions/json/manual/.empty b/src/plugins/console/server/lib/spec_definitions/json/manual/.empty new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/src/plugins/console/server/lib/spec_definitions/json/overrides/xpack.graph.explore.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/graph.explore.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/json/overrides/xpack.graph.explore.json rename to src/plugins/console/server/lib/spec_definitions/json/overrides/graph.explore.json diff --git a/src/plugins/console/server/lib/spec_definitions/json/overrides/indices.analyze.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/indices.analyze.json deleted file mode 100644 index 4ab4fc3930437..0000000000000 --- a/src/plugins/console/server/lib/spec_definitions/json/overrides/indices.analyze.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "indices.analyze": { - "data_autocomplete_rules": { - "text": [], - "field": "{field}", - "analyzer": "", - "tokenizer": "", - "char_filter": [], - "filter": [], - "explain": { "__one_of": [false, true] }, - "attributes": [] - } - } -} diff --git a/src/plugins/console/server/lib/spec_definitions/json/overrides/xpack.license.post.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/license.post.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/json/overrides/xpack.license.post.json rename to src/plugins/console/server/lib/spec_definitions/json/overrides/license.post.json diff --git a/src/plugins/console/server/lib/spec_definitions/json/overrides/xpack.rollup.delete_job.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/rollup.delete_job.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/json/overrides/xpack.rollup.delete_job.json rename to src/plugins/console/server/lib/spec_definitions/json/overrides/rollup.delete_job.json diff --git a/src/plugins/console/server/lib/spec_definitions/json/overrides/xpack.rollup.put_job.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/rollup.put_job.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/json/overrides/xpack.rollup.put_job.json rename to src/plugins/console/server/lib/spec_definitions/json/overrides/rollup.put_job.json diff --git a/src/plugins/console/server/lib/spec_definitions/json/overrides/xpack.rollup.rollup_search.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/rollup.rollup_search.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/json/overrides/xpack.rollup.rollup_search.json rename to src/plugins/console/server/lib/spec_definitions/json/overrides/rollup.rollup_search.json diff --git a/src/plugins/console/server/lib/spec_definitions/json/overrides/xpack.watcher.execute_watch.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/watcher.execute_watch.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/json/overrides/xpack.watcher.execute_watch.json rename to src/plugins/console/server/lib/spec_definitions/json/overrides/watcher.execute_watch.json diff --git a/src/plugins/console/server/lib/spec_definitions/json/overrides/xpack.watcher.put_watch.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/watcher.put_watch.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/json/overrides/xpack.watcher.put_watch.json rename to src/plugins/console/server/lib/spec_definitions/json/overrides/watcher.put_watch.json diff --git a/src/plugins/console/server/lib/spec_definitions/json/overrides/xpack.security.authenticate.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/xpack.security.authenticate.json deleted file mode 100644 index dbf769e777121..0000000000000 --- a/src/plugins/console/server/lib/spec_definitions/json/overrides/xpack.security.authenticate.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "xpack.security.authenticate": { - "data_autocomplete_rules": { - "password": "" - } - } -} diff --git a/src/plugins/console/server/lib/spec_definitions/json/overrides/xpack.security.change_password.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/xpack.security.change_password.json deleted file mode 100644 index afc37f4fbbf1f..0000000000000 --- a/src/plugins/console/server/lib/spec_definitions/json/overrides/xpack.security.change_password.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "xpack.security.change_password": { - "data_autocomplete_rules": { - "password": "" - } - } -} diff --git a/src/plugins/console/server/lib/spec_definitions/json/overrides/xpack.security.get_token.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/xpack.security.get_token.json deleted file mode 100644 index b7eb93656cdff..0000000000000 --- a/src/plugins/console/server/lib/spec_definitions/json/overrides/xpack.security.get_token.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "xpack.security.get_token": { - "data_autocomplete_rules": { - "grant_type": "", - "password": "", - "scope": "", - "username": "" - } - } -} diff --git a/src/plugins/console/server/lib/spec_definitions/json/overrides/xpack.security.invalidate_token.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/xpack.security.invalidate_token.json deleted file mode 100644 index 5607fdc7cf418..0000000000000 --- a/src/plugins/console/server/lib/spec_definitions/json/overrides/xpack.security.invalidate_token.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "xpack.security.invalidate_token": { - "data_autocomplete_rules": { - "token": "" - } - } -} diff --git a/src/plugins/console/server/lib/spec_definitions/json/overrides/xpack.security.put_role.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/xpack.security.put_role.json deleted file mode 100644 index 6c40d0afe9b96..0000000000000 --- a/src/plugins/console/server/lib/spec_definitions/json/overrides/xpack.security.put_role.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "xpack.security.put_role": { - "data_autocomplete_rules": { - "cluster": [], - "indices": [ - { - "field_security": {}, - "names": [], - "privileges": [], - "query": "" - } - ], - "run_as": [], - "metadata": {} - } - } -} diff --git a/src/plugins/console/server/lib/spec_definitions/json/overrides/xpack.security.put_role_mapping.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/xpack.security.put_role_mapping.json deleted file mode 100644 index 58124509ab271..0000000000000 --- a/src/plugins/console/server/lib/spec_definitions/json/overrides/xpack.security.put_role_mapping.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "xpack.security.put_role_mapping": { - "data_autocomplete_rules": { - "enabled": true, - "metadata": {}, - "roles": [], - "rules": {} - } - } -} diff --git a/src/plugins/console/server/lib/spec_definitions/json/overrides/xpack.security.put_user.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/xpack.security.put_user.json deleted file mode 100644 index 3660da48b875b..0000000000000 --- a/src/plugins/console/server/lib/spec_definitions/json/overrides/xpack.security.put_user.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "xpack.security.put_user": { - "data_autocomplete_rules": { - "metadata": {}, - "password": "", - "full_name": "", - "roles": [] - }, - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-put-user.html" - } -} diff --git a/src/plugins/console/server/services/spec_definitions_service.test.ts b/src/plugins/console/server/services/spec_definitions_service.test.ts new file mode 100644 index 0000000000000..8580c51bb844a --- /dev/null +++ b/src/plugins/console/server/services/spec_definitions_service.test.ts @@ -0,0 +1,366 @@ +/* + * 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 globby from 'globby'; +import fs from 'fs'; +import { SpecDefinitionsService } from '.'; +import { EndpointDefinition, EndpointsAvailability } from '../../common/types'; + +const mockReadFilySync = jest.spyOn(fs, 'readFileSync'); +const mockGlobbySync = jest.spyOn(globby, 'sync'); +const mockJsLoadersGetter = jest.fn(); + +jest.mock('../lib', () => { + return { + ...jest.requireActual('../lib'), + get jsSpecLoaders() { + return mockJsLoadersGetter(); + }, + }; +}); + +const getMockEndpoint = ({ + endpointName, + methods, + patterns, + // eslint-disable-next-line @typescript-eslint/naming-convention + data_autocomplete_rules, + availability, +}: { + endpointName: string; + methods?: string[]; + patterns?: string[]; + data_autocomplete_rules?: Record; + availability?: Record; +}): EndpointDefinition => ({ + [endpointName]: { + methods: methods ?? ['GET'], + patterns: patterns ?? ['/endpoint'], + data_autocomplete_rules: data_autocomplete_rules ?? undefined, + availability: availability ?? undefined, + }, +}); + +describe('SpecDefinitionsService', () => { + beforeAll(() => { + jest.useFakeTimers().setSystemTime(new Date(1577836800000)); + }); + afterAll(() => { + jest.useRealTimers(); + }); + beforeEach(() => { + // mock the function that lists files in the definitions folders + mockGlobbySync.mockImplementation(() => []); + // mock the function that reads files + mockReadFilySync.mockImplementation(() => ''); + // mock the function that returns the list of js definitions loaders + mockJsLoadersGetter.mockImplementation(() => []); + }); + afterEach(() => { + jest.resetAllMocks(); + }); + + it('initializes with empty definitions when folders and global rules are empty', () => { + const specDefinitionsService = new SpecDefinitionsService(); + specDefinitionsService.start({ + endpointsAvailability: 'stack', + }); + const definitions = specDefinitionsService.asJson(); + expect(definitions).toEqual({ + endpoints: {}, + globals: {}, + name: 'es', + }); + }); + + it('loads globals rules', () => { + const loadMockAliasRule = (service: SpecDefinitionsService) => { + service.addGlobalAutocompleteRules('alias', { + param1: 1, + param2: 'test', + }); + }; + const loadMockIndicesRule = (service: SpecDefinitionsService) => { + service.addGlobalAutocompleteRules('indices', { + test1: 'param1', + test2: 'param2', + }); + }; + mockJsLoadersGetter.mockImplementation(() => [loadMockAliasRule, loadMockIndicesRule]); + const specDefinitionsService = new SpecDefinitionsService(); + specDefinitionsService.start({ + endpointsAvailability: 'stack', + }); + const globals = specDefinitionsService.asJson().globals; + expect(globals).toEqual({ + alias: { + param1: 1, + param2: 'test', + }, + indices: { + test1: 'param1', + test2: 'param2', + }, + }); + }); + + it('loads generated endpoints definition', () => { + mockGlobbySync.mockImplementation((pattern) => { + if (pattern.includes('generated')) { + return ['/generated/endpoint1.json', '/generated/endpoint2.json']; + } + return []; + }); + + mockReadFilySync.mockImplementation((path) => { + if (path.toString() === '/generated/endpoint1.json') { + return JSON.stringify(getMockEndpoint({ endpointName: 'endpoint1' })); + } + if (path.toString() === '/generated/endpoint2.json') { + return JSON.stringify( + getMockEndpoint({ + endpointName: 'endpoint2', + methods: ['POST'], + patterns: ['/endpoint2'], + }) + ); + } + return ''; + }); + const specDefinitionsService = new SpecDefinitionsService(); + specDefinitionsService.start({ + endpointsAvailability: 'stack', + }); + const endpoints = specDefinitionsService.asJson().endpoints; + expect(endpoints).toEqual({ + endpoint1: { + id: 'endpoint1', + methods: ['GET'], + patterns: ['/endpoint'], + }, + endpoint2: { + id: 'endpoint2', + methods: ['POST'], + patterns: ['/endpoint2'], + }, + }); + }); + + it('overrides an endpoint if override file is present', () => { + mockGlobbySync.mockImplementation((pattern) => { + if (pattern.includes('generated')) { + return ['/generated/endpoint1.json', '/generated/endpoint2.json']; + } + if (pattern.includes('overrides')) { + return ['/overrides/endpoint1.json']; + } + return []; + }); + + mockReadFilySync.mockImplementation((path) => { + if (path.toString() === '/generated/endpoint1.json') { + return JSON.stringify(getMockEndpoint({ endpointName: 'endpoint1' })); + } + if (path.toString() === '/generated/endpoint2.json') { + return JSON.stringify( + getMockEndpoint({ + endpointName: 'endpoint2', + methods: ['POST'], + patterns: ['/endpoint2'], + }) + ); + } + if (path.toString() === '/overrides/endpoint1.json') { + return JSON.stringify( + getMockEndpoint({ + endpointName: 'endpoint1', + data_autocomplete_rules: { + param1: 'test', + param2: 2, + }, + }) + ); + } + return ''; + }); + const specDefinitionsService = new SpecDefinitionsService(); + specDefinitionsService.start({ + endpointsAvailability: 'stack', + }); + const endpoints = specDefinitionsService.asJson().endpoints; + expect(endpoints).toEqual({ + endpoint1: { + data_autocomplete_rules: { + param1: 'test', + param2: 2, + }, + id: 'endpoint1', + methods: ['GET'], + patterns: ['/endpoint'], + }, + endpoint2: { + id: 'endpoint2', + methods: ['POST'], + patterns: ['/endpoint2'], + }, + }); + }); + + it('loads manual definitions if any', () => { + mockGlobbySync.mockImplementation((pattern) => { + if (pattern.includes('manual')) { + return ['manual_endpoint.json']; + } + return []; + }); + + mockReadFilySync.mockImplementation((path) => { + if (path.toString() === 'manual_endpoint.json') { + return JSON.stringify(getMockEndpoint({ endpointName: 'manual_endpoint' })); + } + return ''; + }); + const specDefinitionsService = new SpecDefinitionsService(); + specDefinitionsService.start({ + endpointsAvailability: 'stack', + }); + const endpoints = specDefinitionsService.asJson().endpoints; + expect(endpoints).toEqual({ + manual_endpoint: { + id: 'manual_endpoint', + methods: ['GET'], + patterns: ['/endpoint'], + }, + }); + }); + + it("manual definitions don't override generated files even when the same endpoint name is used", () => { + mockGlobbySync.mockImplementation((pattern) => { + if (pattern.includes('generated')) { + return ['generated_endpoint.json']; + } + if (pattern.includes('manual')) { + return ['manual_endpoint.json']; + } + return []; + }); + + mockReadFilySync.mockImplementation((path) => { + if (path.toString() === 'generated_endpoint.json') { + return JSON.stringify(getMockEndpoint({ endpointName: 'test', methods: ['GET'] })); + } + if (path.toString() === 'manual_endpoint.json') { + return JSON.stringify( + getMockEndpoint({ endpointName: 'test', methods: ['POST'], patterns: ['/manual_test'] }) + ); + } + return ''; + }); + const specDefinitionsService = new SpecDefinitionsService(); + specDefinitionsService.start({ + endpointsAvailability: 'stack', + }); + const endpoints = specDefinitionsService.asJson().endpoints; + expect(endpoints).toEqual({ + test: { + id: 'test', + methods: ['GET'], + patterns: ['/endpoint'], + }, + test1577836800000: { + id: 'test1577836800000', + methods: ['POST'], + patterns: ['/manual_test'], + }, + }); + }); + + it('filters out endpoints not available in stack', () => { + mockGlobbySync.mockImplementation((pattern) => { + if (pattern.includes('generated')) { + return ['/generated/endpoint1.json', '/generated/endpoint2.json']; + } + return []; + }); + + mockReadFilySync.mockImplementation((path) => { + if (path.toString() === '/generated/endpoint1.json') { + return JSON.stringify( + getMockEndpoint({ + endpointName: 'endpoint1', + availability: { stack: false, serverless: true }, + }) + ); + } + if (path.toString() === '/generated/endpoint2.json') { + return JSON.stringify( + getMockEndpoint({ + endpointName: 'endpoint2', + methods: ['POST'], + patterns: ['/endpoint2'], + }) + ); + } + return ''; + }); + const specDefinitionsService = new SpecDefinitionsService(); + specDefinitionsService.start({ + endpointsAvailability: 'stack', + }); + const endpoints = specDefinitionsService.asJson().endpoints; + expect(endpoints).toEqual({ + endpoint2: { + id: 'endpoint2', + methods: ['POST'], + patterns: ['/endpoint2'], + }, + }); + }); + + it('filters out endpoints not available in serverless', () => { + mockGlobbySync.mockImplementation((pattern) => { + if (pattern.includes('generated')) { + return ['/generated/endpoint1.json', '/generated/endpoint2.json']; + } + return []; + }); + + mockReadFilySync.mockImplementation((path) => { + if (path.toString() === '/generated/endpoint1.json') { + return JSON.stringify( + getMockEndpoint({ + endpointName: 'endpoint1', + availability: { stack: true, serverless: false }, + }) + ); + } + if (path.toString() === '/generated/endpoint2.json') { + return JSON.stringify( + getMockEndpoint({ + endpointName: 'endpoint2', + methods: ['POST'], + patterns: ['/endpoint2'], + }) + ); + } + return ''; + }); + const specDefinitionsService = new SpecDefinitionsService(); + specDefinitionsService.start({ + endpointsAvailability: 'serverless', + }); + const endpoints = specDefinitionsService.asJson().endpoints; + expect(endpoints).toEqual({ + endpoint2: { + id: 'endpoint2', + methods: ['POST'], + patterns: ['/endpoint2'], + }, + }); + }); +}); diff --git a/src/plugins/console/server/services/spec_definitions_service.ts b/src/plugins/console/server/services/spec_definitions_service.ts index 73ae5ec95a4bf..7ce647152d643 100644 --- a/src/plugins/console/server/services/spec_definitions_service.ts +++ b/src/plugins/console/server/services/spec_definitions_service.ts @@ -12,37 +12,37 @@ import { basename, join } from 'path'; import normalizePath from 'normalize-path'; import { readFileSync } from 'fs'; -import { AUTOCOMPLETE_DEFINITIONS_FOLDER } from '../../common/constants'; +import { + AUTOCOMPLETE_DEFINITIONS_FOLDER, + GENERATED_SUBFOLDER, + MANUAL_SUBFOLDER, + OVERRIDES_SUBFOLDER, +} from '../../common/constants'; import { jsSpecLoaders } from '../lib'; - -interface EndpointDescription { - methods?: string[]; - patterns?: string | string[]; - url_params?: Record; - data_autocomplete_rules?: Record; - url_components?: Record; - priority?: number; - availability?: Record; -} +import type { + EndpointsAvailability, + EndpointDescription, + EndpointDefinition, +} from '../../common/types'; export interface SpecDefinitionsDependencies { - endpointsAvailability: string; + endpointsAvailability: EndpointsAvailability; } export class SpecDefinitionsService { private readonly name = 'es'; private readonly globalRules: Record = {}; - private readonly endpoints: Record = {}; + private readonly endpoints: Record = {}; - private hasLoadedSpec = false; + private hasLoadedDefinitions = false; public addGlobalAutocompleteRules(parentNode: string, rules: unknown) { this.globalRules[parentNode] = rules; } public addEndpointDescription(endpoint: string, description: EndpointDescription = {}) { - let copiedDescription: { patterns?: string; url_params?: Record } = {}; + let copiedDescription: EndpointDescription = {}; if (this.endpoints[endpoint]) { copiedDescription = { ...this.endpoints[endpoint] }; } @@ -87,42 +87,70 @@ export class SpecDefinitionsService { } public start({ endpointsAvailability }: SpecDefinitionsDependencies) { - if (!this.hasLoadedSpec) { - this.loadJsonSpec(endpointsAvailability); - this.loadJSSpec(); - this.hasLoadedSpec = true; + if (!this.hasLoadedDefinitions) { + this.loadJsonDefinitions(endpointsAvailability); + this.loadJSDefinitions(); + this.hasLoadedDefinitions = true; } else { throw new Error('Service has already started!'); } } - private loadJSONSpecInDir(dirname: string) { + private loadJSONDefinitionsFiles() { // we need to normalize paths otherwise they don't work on windows, see https://github.com/elastic/kibana/issues/151032 - const generatedFiles = globby.sync(normalizePath(join(dirname, 'generated', '*.json'))); - const overrideFiles = globby.sync(normalizePath(join(dirname, 'overrides', '*.json'))); - - return generatedFiles.reduce((acc, file) => { + const generatedFiles = globby.sync( + normalizePath(join(AUTOCOMPLETE_DEFINITIONS_FOLDER, GENERATED_SUBFOLDER, '*.json')) + ); + const overrideFiles = globby.sync( + normalizePath(join(AUTOCOMPLETE_DEFINITIONS_FOLDER, OVERRIDES_SUBFOLDER, '*.json')) + ); + const manualFiles = globby.sync( + normalizePath(join(AUTOCOMPLETE_DEFINITIONS_FOLDER, MANUAL_SUBFOLDER, '*.json')) + ); + + // definitions files contain only 1 definition per endpoint name { "endpointName": { endpointDescription }} + // all endpoints need to be merged into 1 object with endpoint names as keys and endpoint definitions as values + const jsonDefinitions = {} as Record; + generatedFiles.forEach((file) => { const overrideFile = overrideFiles.find((f) => basename(f) === basename(file)); - const loadedSpec: Record = JSON.parse( - readFileSync(file, 'utf8') - ); + const loadedDefinition: EndpointDefinition = JSON.parse(readFileSync(file, 'utf8')); if (overrideFile) { - merge(loadedSpec, JSON.parse(readFileSync(overrideFile, 'utf8'))); + merge(loadedDefinition, JSON.parse(readFileSync(overrideFile, 'utf8'))); } - Object.entries(loadedSpec).forEach(([key, value]) => { - if (acc[key]) { - // add time to remove key collision - acc[`${key}${Date.now()}`] = value; - } else { - acc[key] = value; - } - }); - return acc; - }, {} as Record); + this.addToJsonDefinitions({ loadedDefinition, jsonDefinitions }); + }); + + // add manual definitions + manualFiles.forEach((file) => { + const loadedDefinition: EndpointDefinition = JSON.parse(readFileSync(file, 'utf8')); + this.addToJsonDefinitions({ loadedDefinition, jsonDefinitions }); + }); + return jsonDefinitions; + } + + private addToJsonDefinitions({ + loadedDefinition, + jsonDefinitions, + }: { + loadedDefinition: EndpointDefinition; + jsonDefinitions: Record; + }) { + // iterate over EndpointDefinition for a safe and easy access to the only property in this object + Object.entries(loadedDefinition).forEach(([endpointName, endpointDescription]) => { + // endpoints should all have unique names, but in case that happens unintentionally + // don't silently overwrite the definition but create a new unique endpoint name + if (jsonDefinitions[endpointName]) { + // add time to create a unique key + jsonDefinitions[`${endpointName}${Date.now()}`] = endpointDescription; + } else { + jsonDefinitions[endpointName] = endpointDescription; + } + }); + return jsonDefinitions; } - private loadJsonSpec(endpointsAvailability: string) { - const result = this.loadJSONSpecInDir(AUTOCOMPLETE_DEFINITIONS_FOLDER); + private loadJsonDefinitions(endpointsAvailability: string) { + const result = this.loadJSONDefinitionsFiles(); Object.keys(result).forEach((endpoint) => { const description = result[endpoint]; @@ -137,7 +165,7 @@ export class SpecDefinitionsService { }); } - private loadJSSpec() { + private loadJSDefinitions() { jsSpecLoaders.forEach((addJsSpec) => addJsSpec(this)); } } diff --git a/test/plugin_functional/test_suites/core_plugins/rendering.ts b/test/plugin_functional/test_suites/core_plugins/rendering.ts index 633ecea1bb6f8..d150ef4e70612 100644 --- a/test/plugin_functional/test_suites/core_plugins/rendering.ts +++ b/test/plugin_functional/test_suites/core_plugins/rendering.ts @@ -83,7 +83,7 @@ export default function ({ getService }: PluginFunctionalProviderContext) { // what types of config settings can be exposed to the browser. // When plugin owners make a change that exposes additional config values, the changes will be reflected in this test assertion. // Ensure that your change does not unintentionally expose any sensitive values! - 'console.autocompleteDefinitions.endpointsAvailability (string)', + 'console.autocompleteDefinitions.endpointsAvailability (alternatives)', 'console.ui.enabled (boolean)', 'dashboard.allowByValueEmbeddables (boolean)', 'unifiedSearch.autocomplete.querySuggestions.enabled (boolean)',