From b1a038ddc3e8bba9ad30791f06cb2574bf86d6cc Mon Sep 17 00:00:00 2001 From: Julia Bardi <90178898+juliaElastic@users.noreply.github.com> Date: Wed, 8 Dec 2021 13:04:04 +0100 Subject: [PATCH] [Fleet] Make API responses consistent (#119494) * make apis consistent * UI and test fixes * test fixes * fixed test * fix tests * fix test * removed deprecated shared_id from openapi spec * added back list prop as deprecated * renamed apis with hyphens * openapi update * fix checks * fix test * renamed epm api path and response * fix tests * fix ml * moved splitPkgKey * fixed edit package policy page * fixed storybook * fix prettier after conflict * fix tests * fix tests * fix tests * fix test * fix test * added back semver validation * fix test * pkgVersion optional * fix tests Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../plugins/fleet/common/constants/routes.ts | 31 +- .../plugins/fleet/common/openapi/bundled.json | 448 +++++++++++++++++- .../plugins/fleet/common/openapi/bundled.yaml | 281 ++++++++++- .../openapi/components/schemas/agent.yaml | 3 - .../fleet/common/openapi/entrypoint.yaml | 12 + .../fleet/common/openapi/paths/agents.yaml | 7 +- .../openapi/paths/enrollment_api_keys.yaml | 7 +- ...epm@packages@{pkg_name}@{pkg_version}.yaml | 118 +++++ x-pack/plugins/fleet/common/services/index.ts | 1 + .../plugins/fleet/common/services/routes.ts | 29 +- .../fleet/common/services/split_pkg_key.ts | 34 ++ .../fleet/common/types/rest_spec/agent.ts | 15 +- .../common/types/rest_spec/agent_policy.ts | 9 +- .../types/rest_spec/enrollment_api_key.ts | 18 +- .../fleet/common/types/rest_spec/epm.ts | 55 ++- .../fleet/common/types/rest_spec/output.ts | 9 +- .../common/types/rest_spec/package_policy.ts | 15 +- .../cypress/fixtures/integrations/apache.json | 2 +- .../cypress/integration/integrations.spec.ts | 2 +- .../fleet/cypress/tasks/integrations.ts | 2 +- x-pack/plugins/fleet/dev_docs/api/epm.md | 4 +- .../create_package_policy_page/index.tsx | 8 +- .../edit_package_policy_page/index.tsx | 9 +- .../sections/agents/agent_list_page/index.tsx | 2 +- .../components/fleet_server_upgrade_modal.tsx | 2 +- .../enrollment_token_list_page/index.tsx | 2 +- .../hooks/use_fleet_server_unhealthy.test.tsx | 4 +- .../integrations/hooks/use_links.tsx | 3 +- .../hooks/use_package_install.tsx | 6 +- .../epm/screens/detail/index.test.tsx | 6 +- .../sections/epm/screens/detail/index.tsx | 12 +- .../epm/screens/detail/settings/settings.tsx | 2 +- .../epm/screens/home/available_packages.tsx | 4 +- ...advanced_agent_authentication_settings.tsx | 4 +- .../public/hooks/use_package_icon_type.ts | 4 +- .../hooks/use_package_installations.tsx | 5 +- .../fleet/public/hooks/use_request/epm.ts | 24 +- .../fleet/public/search_provider.test.ts | 2 +- .../plugins/fleet/public/search_provider.ts | 2 +- .../fleet/server/routes/agent/handlers.ts | 3 +- .../fleet/server/routes/agent/index.ts | 9 + .../plugins/fleet/server/routes/app/index.ts | 9 + .../routes/enrollment_api_key/handler.ts | 8 +- .../server/routes/enrollment_api_key/index.ts | 40 ++ .../fleet/server/routes/epm/handlers.ts | 47 +- .../plugins/fleet/server/routes/epm/index.ts | 95 ++++ .../server/services/epm/packages/install.ts | 2 +- .../server/services/epm/packages/remove.ts | 8 +- .../server/services/epm/registry/index.ts | 39 +- .../fleet/server/types/rest_spec/epm.ts | 41 ++ .../storybook/context/fixtures/categories.ts | 2 +- .../context/fixtures/integration.nginx.ts | 2 +- .../context/fixtures/integration.okta.ts | 2 +- .../storybook/context/fixtures/packages.ts | 2 +- .../plugins/fleet/storybook/context/http.ts | 4 +- .../osquery/public/agents/use_agent_status.ts | 2 +- .../get_agent_status_for_agent_policy.ts | 2 +- .../data_loaders/index_endpoint_hosts.ts | 2 +- .../data_loaders/setup_fleet_for_endpoint.ts | 2 +- .../common/endpoint/generate_data.ts | 2 +- .../common/endpoint/index_data.ts | 4 +- .../store/mock_endpoint_result_list.ts | 6 +- .../management/pages/endpoint_hosts/types.ts | 2 +- .../management/pages/mocks/fleet_mocks.ts | 2 +- .../pages/policy/store/services/ingest.ts | 6 +- .../pages/policy/store/test_mock_utils.ts | 2 +- .../api_integration/apis/ml/modules/index.ts | 8 +- .../agent_policy_with_agents_setup.ts | 6 +- .../fleet_api_integration/apis/agents/list.ts | 6 +- .../apis/agents/reassign.ts | 2 +- .../apis/agents/status.ts | 6 +- .../apis/data_streams/list.ts | 13 +- .../apis/enrollment_api_keys/crud.ts | 61 ++- .../apis/epm/bulk_upgrade.ts | 44 +- .../apis/epm/data_stream.ts | 20 +- .../fleet_api_integration/apis/epm/delete.ts | 21 +- .../fleet_api_integration/apis/epm/file.ts | 2 +- .../apis/epm/final_pipeline.ts | 10 +- .../fleet_api_integration/apis/epm/get.ts | 44 +- .../apis/epm/install_by_upload.ts | 29 +- .../apis/epm/install_endpoint.ts | 6 +- .../apis/epm/install_error_rollback.ts | 29 +- .../apis/epm/install_overrides.ts | 13 +- .../apis/epm/install_prerelease.ts | 11 +- .../apis/epm/install_remove_assets.ts | 23 +- .../apis/epm/install_remove_multiple.ts | 34 +- .../apis/epm/install_update.ts | 26 +- .../fleet_api_integration/apis/epm/list.ts | 4 +- .../apis/epm/package_install_complete.ts | 10 +- .../fleet_api_integration/apis/epm/setup.ts | 20 +- .../apis/epm/update_assets.ts | 16 +- .../apis/package_policy/upgrade.ts | 4 +- .../apis/service_tokens.ts | 8 +- x-pack/test/fleet_cypress/agent.ts | 6 +- .../functional/services/ml/test_resources.ts | 11 +- .../services/uptime/synthetics_package.ts | 4 +- x-pack/test/osquery_cypress/agent.ts | 6 +- .../services/endpoint_policy.ts | 10 +- 98 files changed, 1596 insertions(+), 465 deletions(-) create mode 100644 x-pack/plugins/fleet/common/openapi/paths/epm@packages@{pkg_name}@{pkg_version}.yaml create mode 100644 x-pack/plugins/fleet/common/services/split_pkg_key.ts diff --git a/x-pack/plugins/fleet/common/constants/routes.ts b/x-pack/plugins/fleet/common/constants/routes.ts index 9fc20bbf38eb7d..69363f37d33e04 100644 --- a/x-pack/plugins/fleet/common/constants/routes.ts +++ b/x-pack/plugins/fleet/common/constants/routes.ts @@ -18,8 +18,8 @@ export const LIMITED_CONCURRENCY_ROUTE_TAG = 'ingest:limited-concurrency'; // EPM API routes const EPM_PACKAGES_MANY = `${EPM_API_ROOT}/packages`; const EPM_PACKAGES_BULK = `${EPM_PACKAGES_MANY}/_bulk`; -const EPM_PACKAGES_ONE = `${EPM_PACKAGES_MANY}/{pkgkey}`; -const EPM_PACKAGES_FILE = `${EPM_PACKAGES_MANY}/{pkgName}/{pkgVersion}`; +const EPM_PACKAGES_ONE_DEPRECATED = `${EPM_PACKAGES_MANY}/{pkgkey}`; +const EPM_PACKAGES_ONE = `${EPM_PACKAGES_MANY}/{pkgName}/{pkgVersion}`; export const EPM_API_ROUTES = { BULK_INSTALL_PATTERN: EPM_PACKAGES_BULK, LIST_PATTERN: EPM_PACKAGES_MANY, @@ -28,9 +28,13 @@ export const EPM_API_ROUTES = { INSTALL_FROM_REGISTRY_PATTERN: EPM_PACKAGES_ONE, INSTALL_BY_UPLOAD_PATTERN: EPM_PACKAGES_MANY, DELETE_PATTERN: EPM_PACKAGES_ONE, - FILEPATH_PATTERN: `${EPM_PACKAGES_FILE}/{filePath*}`, + FILEPATH_PATTERN: `${EPM_PACKAGES_ONE}/{filePath*}`, CATEGORIES_PATTERN: `${EPM_API_ROOT}/categories`, STATS_PATTERN: `${EPM_PACKAGES_MANY}/{pkgName}/stats`, + + INFO_PATTERN_DEPRECATED: EPM_PACKAGES_ONE_DEPRECATED, + INSTALL_FROM_REGISTRY_PATTERN_DEPRECATED: EPM_PACKAGES_ONE_DEPRECATED, + DELETE_PATTERN_DEPRECATED: EPM_PACKAGES_ONE_DEPRECATED, }; // Data stream API routes @@ -79,7 +83,9 @@ export const SETTINGS_API_ROUTES = { // App API routes export const APP_API_ROUTES = { CHECK_PERMISSIONS_PATTERN: `${API_ROOT}/check-permissions`, - GENERATE_SERVICE_TOKEN_PATTERN: `${API_ROOT}/service-tokens`, + GENERATE_SERVICE_TOKEN_PATTERN: `${API_ROOT}/service_tokens`, + // deprecated since 8.0 + GENERATE_SERVICE_TOKEN_PATTERN_DEPRECATED: `${API_ROOT}/service-tokens`, }; // Agent API routes @@ -95,16 +101,23 @@ export const AGENT_API_ROUTES = { BULK_UNENROLL_PATTERN: `${API_ROOT}/agents/bulk_unenroll`, REASSIGN_PATTERN: `${API_ROOT}/agents/{agentId}/reassign`, BULK_REASSIGN_PATTERN: `${API_ROOT}/agents/bulk_reassign`, - STATUS_PATTERN: `${API_ROOT}/agent-status`, + STATUS_PATTERN: `${API_ROOT}/agent_status`, + // deprecated since 8.0 + STATUS_PATTERN_DEPRECATED: `${API_ROOT}/agent-status`, UPGRADE_PATTERN: `${API_ROOT}/agents/{agentId}/upgrade`, BULK_UPGRADE_PATTERN: `${API_ROOT}/agents/bulk_upgrade`, }; export const ENROLLMENT_API_KEY_ROUTES = { - CREATE_PATTERN: `${API_ROOT}/enrollment-api-keys`, - LIST_PATTERN: `${API_ROOT}/enrollment-api-keys`, - INFO_PATTERN: `${API_ROOT}/enrollment-api-keys/{keyId}`, - DELETE_PATTERN: `${API_ROOT}/enrollment-api-keys/{keyId}`, + CREATE_PATTERN: `${API_ROOT}/enrollment_api_keys`, + LIST_PATTERN: `${API_ROOT}/enrollment_api_keys`, + INFO_PATTERN: `${API_ROOT}/enrollment_api_keys/{keyId}`, + DELETE_PATTERN: `${API_ROOT}/enrollment_api_keys/{keyId}`, + // deprecated since 8.0 + CREATE_PATTERN_DEPRECATED: `${API_ROOT}/enrollment-api-keys`, + LIST_PATTERN_DEPRECATED: `${API_ROOT}/enrollment-api-keys`, + INFO_PATTERN_DEPRECATED: `${API_ROOT}/enrollment-api-keys/{keyId}`, + DELETE_PATTERN_DEPRECATED: `${API_ROOT}/enrollment-api-keys/{keyId}`, }; // Agents setup API routes diff --git a/x-pack/plugins/fleet/common/openapi/bundled.json b/x-pack/plugins/fleet/common/openapi/bundled.json index f30369b5792b86..7423a4dc54bbed 100644 --- a/x-pack/plugins/fleet/common/openapi/bundled.json +++ b/x-pack/plugins/fleet/common/openapi/bundled.json @@ -157,6 +157,7 @@ "parameters": [] }, "/epm/packages/{pkgkey}": { + "deprecated": true, "get": { "summary": "Packages - Info", "tags": [], @@ -352,6 +353,210 @@ } } }, + "/epm/packages/{pkgName}/{pkgVersion}": { + "get": { + "summary": "Packages - Info", + "tags": [], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "allOf": [ + { + "properties": { + "item": { + "$ref": "#/components/schemas/package_info" + } + } + }, + { + "properties": { + "status": { + "type": "string", + "enum": [ + "installed", + "installing", + "install_failed", + "not_installed" + ] + }, + "savedObject": { + "type": "string" + } + }, + "required": [ + "status", + "savedObject" + ] + } + ] + } + } + } + } + }, + "operationId": "get-package", + "security": [ + { + "basicAuth": [] + } + ] + }, + "parameters": [ + { + "schema": { + "type": "string" + }, + "name": "pkgName", + "in": "path", + "required": true + }, + { + "schema": { + "type": "string" + }, + "name": "pkgVersion", + "in": "path", + "required": true + } + ], + "post": { + "summary": "Packages - Install", + "tags": [], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "oneOf": [ + { + "$ref": "#/components/schemas/kibana_saved_object_type" + }, + { + "$ref": "#/components/schemas/elasticsearch_asset_type" + } + ] + } + }, + "required": [ + "id", + "type" + ] + } + } + }, + "required": [ + "items" + ] + } + } + } + } + }, + "operationId": "install-package", + "description": "", + "parameters": [ + { + "$ref": "#/components/parameters/kbn_xsrf" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "force": { + "type": "boolean" + } + } + } + } + } + } + }, + "delete": { + "summary": "Packages - Delete", + "tags": [], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "oneOf": [ + { + "$ref": "#/components/schemas/kibana_saved_object_type" + }, + { + "$ref": "#/components/schemas/elasticsearch_asset_type" + } + ] + } + }, + "required": [ + "id", + "type" + ] + } + } + }, + "required": [ + "items" + ] + } + } + } + } + }, + "operationId": "delete-package", + "parameters": [ + { + "$ref": "#/components/parameters/kbn_xsrf" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "force": { + "type": "boolean" + } + } + } + } + } + } + } + }, "/agents/setup": { "get": { "summary": "Agents setup - Info", @@ -419,6 +624,72 @@ } }, "/agent-status": { + "deprecated": true, + "get": { + "summary": "Agents - Summary stats", + "tags": [], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "integer" + }, + "events": { + "type": "integer" + }, + "inactive": { + "type": "integer" + }, + "offline": { + "type": "integer" + }, + "online": { + "type": "integer" + }, + "other": { + "type": "integer" + }, + "total": { + "type": "integer" + }, + "updating": { + "type": "integer" + } + }, + "required": [ + "error", + "events", + "inactive", + "offline", + "online", + "other", + "total", + "updating" + ] + } + } + } + } + }, + "operationId": "get-agent-status", + "parameters": [ + { + "schema": { + "type": "string" + }, + "name": "policyId", + "in": "query", + "required": false + } + ] + } + }, + "/agent_status": { "get": { "summary": "Agents - Summary stats", "tags": [], @@ -496,6 +767,13 @@ "type": "object", "properties": { "list": { + "type": "array", + "items": { + "$ref": "#/components/schemas/agent" + }, + "deprecated": true + }, + "items": { "type": "array", "items": { "$ref": "#/components/schemas/agent" @@ -512,7 +790,7 @@ } }, "required": [ - "list", + "items", "total", "page", "perPage" @@ -1294,6 +1572,7 @@ "parameters": [] }, "/enrollment-api-keys": { + "deprecated": true, "get": { "summary": "Enrollment API Keys - List", "tags": [], @@ -1306,6 +1585,13 @@ "type": "object", "properties": { "list": { + "type": "array", + "items": { + "$ref": "#/components/schemas/enrollment_api_key" + }, + "deprecated": true + }, + "items": { "type": "array", "items": { "$ref": "#/components/schemas/enrollment_api_key" @@ -1322,7 +1608,7 @@ } }, "required": [ - "list", + "items", "page", "perPage", "total" @@ -1370,6 +1656,160 @@ } }, "/enrollment-api-keys/{keyId}": { + "deprecated": true, + "parameters": [ + { + "schema": { + "type": "string" + }, + "name": "keyId", + "in": "path", + "required": true + } + ], + "get": { + "summary": "Enrollment API Key - Info", + "tags": [], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "item": { + "$ref": "#/components/schemas/enrollment_api_key" + } + }, + "required": [ + "item" + ] + } + } + } + } + }, + "operationId": "get-enrollment-api-key" + }, + "delete": { + "summary": "Enrollment API Key - Delete", + "tags": [], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "action": { + "type": "string", + "enum": [ + "deleted" + ] + } + }, + "required": [ + "action" + ] + } + } + } + } + }, + "operationId": "delete-enrollment-api-key", + "parameters": [ + { + "$ref": "#/components/parameters/kbn_xsrf" + } + ] + } + }, + "/enrollment_api_keys": { + "get": { + "summary": "Enrollment API Keys - List", + "tags": [], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "list": { + "type": "array", + "items": { + "$ref": "#/components/schemas/enrollment_api_key" + }, + "deprecated": true + }, + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/enrollment_api_key" + } + }, + "page": { + "type": "number" + }, + "perPage": { + "type": "number" + }, + "total": { + "type": "number" + } + }, + "required": [ + "items", + "page", + "perPage", + "total" + ] + } + } + } + } + }, + "operationId": "get-enrollment-api-keys", + "parameters": [] + }, + "post": { + "summary": "Enrollment API Key - Create", + "tags": [], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "item": { + "$ref": "#/components/schemas/enrollment_api_key" + }, + "action": { + "type": "string", + "enum": [ + "created" + ] + } + } + } + } + } + } + }, + "operationId": "create-enrollment-api-keys", + "parameters": [ + { + "$ref": "#/components/parameters/kbn_xsrf" + } + ] + } + }, + "/enrollment_api_keys/{keyId}": { "parameters": [ { "schema": { @@ -2520,10 +2960,6 @@ "unenrollment_started_at": { "type": "string" }, - "shared_id": { - "type": "string", - "deprecated": true - }, "access_api_key_id": { "type": "string" }, diff --git a/x-pack/plugins/fleet/common/openapi/bundled.yaml b/x-pack/plugins/fleet/common/openapi/bundled.yaml index 44242423aa4205..13ffa77279c213 100644 --- a/x-pack/plugins/fleet/common/openapi/bundled.yaml +++ b/x-pack/plugins/fleet/common/openapi/bundled.yaml @@ -100,6 +100,7 @@ paths: operationId: list-all-packages parameters: [] /epm/packages/{pkgkey}: + deprecated: true get: summary: Packages - Info tags: [] @@ -213,6 +214,125 @@ paths: properties: force: type: boolean + /epm/packages/{pkgName}/{pkgVersion}: + get: + summary: Packages - Info + tags: [] + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + allOf: + - properties: + item: + $ref: '#/components/schemas/package_info' + - properties: + status: + type: string + enum: + - installed + - installing + - install_failed + - not_installed + savedObject: + type: string + required: + - status + - savedObject + operationId: get-package + security: + - basicAuth: [] + parameters: + - schema: + type: string + name: pkgName + in: path + required: true + - schema: + type: string + name: pkgVersion + in: path + required: true + post: + summary: Packages - Install + tags: [] + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + items: + type: array + items: + type: object + properties: + id: + type: string + type: + oneOf: + - $ref: '#/components/schemas/kibana_saved_object_type' + - $ref: '#/components/schemas/elasticsearch_asset_type' + required: + - id + - type + required: + - items + operationId: install-package + description: '' + parameters: + - $ref: '#/components/parameters/kbn_xsrf' + requestBody: + content: + application/json: + schema: + type: object + properties: + force: + type: boolean + delete: + summary: Packages - Delete + tags: [] + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + items: + type: array + items: + type: object + properties: + id: + type: string + type: + oneOf: + - $ref: '#/components/schemas/kibana_saved_object_type' + - $ref: '#/components/schemas/elasticsearch_asset_type' + required: + - id + - type + required: + - items + operationId: delete-package + parameters: + - $ref: '#/components/parameters/kbn_xsrf' + requestBody: + content: + application/json: + schema: + type: object + properties: + force: + type: boolean /agents/setup: get: summary: Agents setup - Info @@ -253,6 +373,51 @@ paths: parameters: - $ref: '#/components/parameters/kbn_xsrf' /agent-status: + deprecated: true + get: + summary: Agents - Summary stats + tags: [] + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + error: + type: integer + events: + type: integer + inactive: + type: integer + offline: + type: integer + online: + type: integer + other: + type: integer + total: + type: integer + updating: + type: integer + required: + - error + - events + - inactive + - offline + - online + - other + - total + - updating + operationId: get-agent-status + parameters: + - schema: + type: string + name: policyId + in: query + required: false + /agent_status: get: summary: Agents - Summary stats tags: [] @@ -312,6 +477,11 @@ paths: type: array items: $ref: '#/components/schemas/agent' + deprecated: true + items: + type: array + items: + $ref: '#/components/schemas/agent' total: type: number page: @@ -319,7 +489,7 @@ paths: perPage: type: number required: - - list + - items - total - page - perPage @@ -784,6 +954,7 @@ paths: - $ref: '#/components/parameters/kbn_xsrf' parameters: [] /enrollment-api-keys: + deprecated: true get: summary: Enrollment API Keys - List tags: [] @@ -799,6 +970,11 @@ paths: type: array items: $ref: '#/components/schemas/enrollment_api_key' + deprecated: true + items: + type: array + items: + $ref: '#/components/schemas/enrollment_api_key' page: type: number perPage: @@ -806,7 +982,7 @@ paths: total: type: number required: - - list + - items - page - perPage - total @@ -833,6 +1009,104 @@ paths: parameters: - $ref: '#/components/parameters/kbn_xsrf' /enrollment-api-keys/{keyId}: + deprecated: true + parameters: + - schema: + type: string + name: keyId + in: path + required: true + get: + summary: Enrollment API Key - Info + tags: [] + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + item: + $ref: '#/components/schemas/enrollment_api_key' + required: + - item + operationId: get-enrollment-api-key + delete: + summary: Enrollment API Key - Delete + tags: [] + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + action: + type: string + enum: + - deleted + required: + - action + operationId: delete-enrollment-api-key + parameters: + - $ref: '#/components/parameters/kbn_xsrf' + /enrollment_api_keys: + get: + summary: Enrollment API Keys - List + tags: [] + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + list: + type: array + items: + $ref: '#/components/schemas/enrollment_api_key' + deprecated: true + items: + type: array + items: + $ref: '#/components/schemas/enrollment_api_key' + page: + type: number + perPage: + type: number + total: + type: number + required: + - items + - page + - perPage + - total + operationId: get-enrollment-api-keys + parameters: [] + post: + summary: Enrollment API Key - Create + tags: [] + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + item: + $ref: '#/components/schemas/enrollment_api_key' + action: + type: string + enum: + - created + operationId: create-enrollment-api-keys + parameters: + - $ref: '#/components/parameters/kbn_xsrf' + /enrollment_api_keys/{keyId}: parameters: - schema: type: string @@ -1582,9 +1856,6 @@ components: type: string unenrollment_started_at: type: string - shared_id: - type: string - deprecated: true access_api_key_id: type: string default_api_key_id: diff --git a/x-pack/plugins/fleet/common/openapi/components/schemas/agent.yaml b/x-pack/plugins/fleet/common/openapi/components/schemas/agent.yaml index c21651ca7f8be5..72679dd1dab648 100644 --- a/x-pack/plugins/fleet/common/openapi/components/schemas/agent.yaml +++ b/x-pack/plugins/fleet/common/openapi/components/schemas/agent.yaml @@ -11,9 +11,6 @@ properties: type: string unenrollment_started_at: type: string - shared_id: - type: string - deprecated: true access_api_key_id: type: string default_api_key_id: diff --git a/x-pack/plugins/fleet/common/openapi/entrypoint.yaml b/x-pack/plugins/fleet/common/openapi/entrypoint.yaml index 5495f2b3ccacf8..8dbf54582299a1 100644 --- a/x-pack/plugins/fleet/common/openapi/entrypoint.yaml +++ b/x-pack/plugins/fleet/common/openapi/entrypoint.yaml @@ -25,11 +25,17 @@ paths: $ref: paths/epm@packages.yaml '/epm/packages/{pkgkey}': $ref: 'paths/epm@packages@{pkgkey}.yaml' + deprecated: true + '/epm/packages/{pkgName}/{pkgVersion}': + $ref: 'paths/epm@packages@{pkg_name}@{pkg_version}.yaml' # Agent-related endpoints /agents/setup: $ref: paths/agents@setup.yaml /agent-status: $ref: paths/agent_status.yaml + deprecated: true + /agent_status: + $ref: paths/agent_status.yaml /agents: $ref: paths/agents.yaml /agents/bulk_upgrade: @@ -56,7 +62,13 @@ paths: $ref: paths/agent_policies@delete.yaml /enrollment-api-keys: $ref: paths/enrollment_api_keys.yaml + deprecated: true '/enrollment-api-keys/{keyId}': + $ref: 'paths/enrollment_api_keys@{key_id}.yaml' + deprecated: true + /enrollment_api_keys: + $ref: paths/enrollment_api_keys.yaml + '/enrollment_api_keys/{keyId}': $ref: 'paths/enrollment_api_keys@{key_id}.yaml' /package_policies: $ref: paths/package_policies.yaml diff --git a/x-pack/plugins/fleet/common/openapi/paths/agents.yaml b/x-pack/plugins/fleet/common/openapi/paths/agents.yaml index 4a217eda5c5edc..19ea27956dac37 100644 --- a/x-pack/plugins/fleet/common/openapi/paths/agents.yaml +++ b/x-pack/plugins/fleet/common/openapi/paths/agents.yaml @@ -13,6 +13,11 @@ get: type: array items: $ref: ../components/schemas/agent.yaml + deprecated: true + items: + type: array + items: + $ref: ../components/schemas/agent.yaml total: type: number page: @@ -20,7 +25,7 @@ get: perPage: type: number required: - - list + - items - total - page - perPage diff --git a/x-pack/plugins/fleet/common/openapi/paths/enrollment_api_keys.yaml b/x-pack/plugins/fleet/common/openapi/paths/enrollment_api_keys.yaml index 6cfbede4a7eadf..9f6ac6de0ebd66 100644 --- a/x-pack/plugins/fleet/common/openapi/paths/enrollment_api_keys.yaml +++ b/x-pack/plugins/fleet/common/openapi/paths/enrollment_api_keys.yaml @@ -13,6 +13,11 @@ get: type: array items: $ref: ../components/schemas/enrollment_api_key.yaml + deprecated: true + items: + type: array + items: + $ref: ../components/schemas/enrollment_api_key.yaml page: type: number perPage: @@ -20,7 +25,7 @@ get: total: type: number required: - - list + - items - page - perPage - total diff --git a/x-pack/plugins/fleet/common/openapi/paths/epm@packages@{pkg_name}@{pkg_version}.yaml b/x-pack/plugins/fleet/common/openapi/paths/epm@packages@{pkg_name}@{pkg_version}.yaml new file mode 100644 index 00000000000000..1c3c92d99ab38b --- /dev/null +++ b/x-pack/plugins/fleet/common/openapi/paths/epm@packages@{pkg_name}@{pkg_version}.yaml @@ -0,0 +1,118 @@ +get: + summary: Packages - Info + tags: [] + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + allOf: + - properties: + item: + $ref: ../components/schemas/package_info.yaml + - properties: + status: + type: string + enum: + - installed + - installing + - install_failed + - not_installed + savedObject: + type: string + required: + - status + - savedObject + operationId: get-package + security: + - basicAuth: [] +parameters: + - schema: + type: string + name: pkgName + in: path + required: true + - schema: + type: string + name: pkgVersion + in: path + required: true +post: + summary: Packages - Install + tags: [] + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + items: + type: array + items: + type: object + properties: + id: + type: string + type: + oneOf: + - $ref: ../components/schemas/kibana_saved_object_type.yaml + - $ref: ../components/schemas/elasticsearch_asset_type.yaml + required: + - id + - type + required: + - items + operationId: install-package + description: '' + parameters: + - $ref: ../components/headers/kbn_xsrf.yaml + requestBody: + content: + application/json: + schema: + type: object + properties: + force: + type: boolean +delete: + summary: Packages - Delete + tags: [] + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + items: + type: array + items: + type: object + properties: + id: + type: string + type: + oneOf: + - $ref: ../components/schemas/kibana_saved_object_type.yaml + - $ref: ../components/schemas/elasticsearch_asset_type.yaml + required: + - id + - type + required: + - items + operationId: delete-package + parameters: + - $ref: ../components/headers/kbn_xsrf.yaml + requestBody: + content: + application/json: + schema: + type: object + properties: + force: + type: boolean diff --git a/x-pack/plugins/fleet/common/services/index.ts b/x-pack/plugins/fleet/common/services/index.ts index ba3fb447536433..7698308270fff3 100644 --- a/x-pack/plugins/fleet/common/services/index.ts +++ b/x-pack/plugins/fleet/common/services/index.ts @@ -34,3 +34,4 @@ export { } from './validate_package_policy'; export { normalizeHostsForAgents } from './hosts_utils'; +export { splitPkgKey } from './split_pkg_key'; diff --git a/x-pack/plugins/fleet/common/services/routes.ts b/x-pack/plugins/fleet/common/services/routes.ts index 8ab02c462cfa49..d7954aff70dd24 100644 --- a/x-pack/plugins/fleet/common/services/routes.ts +++ b/x-pack/plugins/fleet/common/services/routes.ts @@ -33,8 +33,11 @@ export const epmRouteService = { return EPM_API_ROUTES.LIMITED_LIST_PATTERN; }, - getInfoPath: (pkgkey: string) => { - return EPM_API_ROUTES.INFO_PATTERN.replace('{pkgkey}', pkgkey); + getInfoPath: (pkgName: string, pkgVersion: string) => { + return EPM_API_ROUTES.INFO_PATTERN.replace('{pkgName}', pkgName).replace( + '{pkgVersion}', + pkgVersion + ); }, getStatsPath: (pkgName: string) => { @@ -45,23 +48,27 @@ export const epmRouteService = { return `${EPM_API_ROOT}${filePath.replace('/package', '/packages')}`; }, - getInstallPath: (pkgkey: string) => { - return EPM_API_ROUTES.INSTALL_FROM_REGISTRY_PATTERN.replace('{pkgkey}', pkgkey).replace( - /\/$/, - '' - ); // trim trailing slash + getInstallPath: (pkgName: string, pkgVersion: string) => { + return EPM_API_ROUTES.INSTALL_FROM_REGISTRY_PATTERN.replace('{pkgName}', pkgName) + .replace('{pkgVersion}', pkgVersion) + .replace(/\/$/, ''); // trim trailing slash }, getBulkInstallPath: () => { return EPM_API_ROUTES.BULK_INSTALL_PATTERN; }, - getRemovePath: (pkgkey: string) => { - return EPM_API_ROUTES.DELETE_PATTERN.replace('{pkgkey}', pkgkey).replace(/\/$/, ''); // trim trailing slash + getRemovePath: (pkgName: string, pkgVersion: string) => { + return EPM_API_ROUTES.DELETE_PATTERN.replace('{pkgName}', pkgName) + .replace('{pkgVersion}', pkgVersion) + .replace(/\/$/, ''); // trim trailing slash }, - getUpdatePath: (pkgkey: string) => { - return EPM_API_ROUTES.INFO_PATTERN.replace('{pkgkey}', pkgkey); + getUpdatePath: (pkgName: string, pkgVersion: string) => { + return EPM_API_ROUTES.INFO_PATTERN.replace('{pkgName}', pkgName).replace( + '{pkgVersion}', + pkgVersion + ); }, }; diff --git a/x-pack/plugins/fleet/common/services/split_pkg_key.ts b/x-pack/plugins/fleet/common/services/split_pkg_key.ts new file mode 100644 index 00000000000000..8bbc5b37a2e41a --- /dev/null +++ b/x-pack/plugins/fleet/common/services/split_pkg_key.ts @@ -0,0 +1,34 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import semverValid from 'semver/functions/valid'; + +/** + * Extract the package name and package version from a string. + * + * @param pkgkey a string containing the package name delimited by the package version + */ +export function splitPkgKey(pkgkey: string): { pkgName: string; pkgVersion: string } { + // If no version is provided, use the provided package key as the + // package name and return an empty version value + if (!pkgkey.includes('-')) { + return { pkgName: pkgkey, pkgVersion: '' }; + } + + const pkgName = pkgkey.includes('-') ? pkgkey.substr(0, pkgkey.indexOf('-')) : pkgkey; + + if (pkgName === '') { + throw new Error('Package key parsing failed: package name was empty'); + } + + // this will return the entire string if `indexOf` return -1 + const pkgVersion = pkgkey.substr(pkgkey.indexOf('-') + 1); + if (!semverValid(pkgVersion)) { + throw new Error('Package key parsing failed: package version was not a valid semver'); + } + return { pkgName, pkgVersion }; +} diff --git a/x-pack/plugins/fleet/common/types/rest_spec/agent.ts b/x-pack/plugins/fleet/common/types/rest_spec/agent.ts index e6da9d4498ce25..5e091b9c543f2f 100644 --- a/x-pack/plugins/fleet/common/types/rest_spec/agent.ts +++ b/x-pack/plugins/fleet/common/types/rest_spec/agent.ts @@ -7,22 +7,19 @@ import type { Agent, AgentAction, NewAgentAction } from '../models'; +import type { ListResult, ListWithKuery } from './common'; + export interface GetAgentsRequest { - query: { - page: number; - perPage: number; - kuery?: string; + query: ListWithKuery & { showInactive: boolean; showUpgradeable?: boolean; }; } -export interface GetAgentsResponse { - list: Agent[]; - total: number; +export interface GetAgentsResponse extends ListResult { totalInactive: number; - page: number; - perPage: number; + // deprecated in 8.x + list?: Agent[]; } export interface GetOneAgentRequest { diff --git a/x-pack/plugins/fleet/common/types/rest_spec/agent_policy.ts b/x-pack/plugins/fleet/common/types/rest_spec/agent_policy.ts index 0975b1e28fb8bf..cbf3c9806d3882 100644 --- a/x-pack/plugins/fleet/common/types/rest_spec/agent_policy.ts +++ b/x-pack/plugins/fleet/common/types/rest_spec/agent_policy.ts @@ -7,7 +7,7 @@ import type { AgentPolicy, NewAgentPolicy, FullAgentPolicy } from '../models'; -import type { ListWithKuery } from './common'; +import type { ListResult, ListWithKuery } from './common'; export interface GetAgentPoliciesRequest { query: ListWithKuery & { @@ -17,12 +17,7 @@ export interface GetAgentPoliciesRequest { export type GetAgentPoliciesResponseItem = AgentPolicy & { agents?: number }; -export interface GetAgentPoliciesResponse { - items: GetAgentPoliciesResponseItem[]; - total: number; - page: number; - perPage: number; -} +export type GetAgentPoliciesResponse = ListResult; export interface GetOneAgentPolicyRequest { params: { diff --git a/x-pack/plugins/fleet/common/types/rest_spec/enrollment_api_key.ts b/x-pack/plugins/fleet/common/types/rest_spec/enrollment_api_key.ts index da870deb31d9c4..7fa724e5079c8e 100644 --- a/x-pack/plugins/fleet/common/types/rest_spec/enrollment_api_key.ts +++ b/x-pack/plugins/fleet/common/types/rest_spec/enrollment_api_key.ts @@ -7,20 +7,16 @@ import type { EnrollmentAPIKey } from '../models'; +import type { ListResult, ListWithKuery } from './common'; + export interface GetEnrollmentAPIKeysRequest { - query: { - page: number; - perPage: number; - kuery?: string; - }; + query: ListWithKuery; } -export interface GetEnrollmentAPIKeysResponse { - list: EnrollmentAPIKey[]; - total: number; - page: number; - perPage: number; -} +export type GetEnrollmentAPIKeysResponse = ListResult & { + // deprecated in 8.x + list?: EnrollmentAPIKey[]; +}; export interface GetOneEnrollmentAPIKeyRequest { params: { diff --git a/x-pack/plugins/fleet/common/types/rest_spec/epm.ts b/x-pack/plugins/fleet/common/types/rest_spec/epm.ts index cfe0b4abdcd3c5..6a72792e780ef5 100644 --- a/x-pack/plugins/fleet/common/types/rest_spec/epm.ts +++ b/x-pack/plugins/fleet/common/types/rest_spec/epm.ts @@ -22,7 +22,9 @@ export interface GetCategoriesRequest { } export interface GetCategoriesResponse { - response: CategorySummaryList; + items: CategorySummaryList; + // deprecated in 8.0 + response?: CategorySummaryList; } export interface GetPackagesRequest { @@ -33,33 +35,46 @@ export interface GetPackagesRequest { } export interface GetPackagesResponse { - response: PackageList; + items: PackageList; + // deprecated in 8.0 + response?: PackageList; } export interface GetLimitedPackagesResponse { - response: string[]; + items: string[]; + // deprecated in 8.0 + response?: string[]; } export interface GetFileRequest { params: { - pkgkey: string; + pkgName: string; + pkgVersion: string; filePath: string; }; } export interface GetInfoRequest { params: { - pkgkey: string; + // deprecated in 8.0 + pkgkey?: string; + pkgName: string; + pkgVersion: string; }; } export interface GetInfoResponse { - response: PackageInfo; + item: PackageInfo; + // deprecated in 8.0 + response?: PackageInfo; } export interface UpdatePackageRequest { params: { - pkgkey: string; + // deprecated in 8.0 + pkgkey?: string; + pkgName: string; + pkgVersion: string; }; body: { keepPoliciesUpToDate?: boolean; @@ -67,7 +82,9 @@ export interface UpdatePackageRequest { } export interface UpdatePackageResponse { - response: PackageInfo; + item: PackageInfo; + // deprecated in 8.0 + response?: PackageInfo; } export interface GetStatsRequest { @@ -82,12 +99,17 @@ export interface GetStatsResponse { export interface InstallPackageRequest { params: { - pkgkey: string; + // deprecated in 8.0 + pkgkey?: string; + pkgName: string; + pkgVersion: string; }; } export interface InstallPackageResponse { - response: AssetReference[]; + items: AssetReference[]; + // deprecated in 8.0 + response?: AssetReference[]; } export interface IBulkInstallPackageHTTPError { @@ -110,7 +132,9 @@ export interface BulkInstallPackageInfo { } export interface BulkInstallPackagesResponse { - response: Array; + items: Array; + // deprecated in 8.0 + response?: Array; } export interface BulkInstallPackagesRequest { @@ -125,10 +149,15 @@ export interface MessageResponse { export interface DeletePackageRequest { params: { - pkgkey: string; + // deprecated in 8.0 + pkgkey?: string; + pkgName: string; + pkgVersion: string; }; } export interface DeletePackageResponse { - response: AssetReference[]; + // deprecated in 8.0 + response?: AssetReference[]; + items: AssetReference[]; } diff --git a/x-pack/plugins/fleet/common/types/rest_spec/output.ts b/x-pack/plugins/fleet/common/types/rest_spec/output.ts index 4e380feeb83a81..98376b3ba52235 100644 --- a/x-pack/plugins/fleet/common/types/rest_spec/output.ts +++ b/x-pack/plugins/fleet/common/types/rest_spec/output.ts @@ -7,6 +7,8 @@ import type { Output } from '../models'; +import type { ListResult } from './common'; + export interface GetOneOutputResponse { item: Output; } @@ -53,9 +55,4 @@ export interface PutOutputResponse { item: Output; } -export interface GetOutputsResponse { - items: Output[]; - total: number; - page: number; - perPage: number; -} +export type GetOutputsResponse = ListResult; diff --git a/x-pack/plugins/fleet/common/types/rest_spec/package_policy.ts b/x-pack/plugins/fleet/common/types/rest_spec/package_policy.ts index b050a7c798a0bf..9eb20383d57bdf 100644 --- a/x-pack/plugins/fleet/common/types/rest_spec/package_policy.ts +++ b/x-pack/plugins/fleet/common/types/rest_spec/package_policy.ts @@ -13,20 +13,13 @@ import type { PackagePolicyPackage, } from '../models'; +import type { ListResult, ListWithKuery } from './common'; + export interface GetPackagePoliciesRequest { - query: { - page: number; - perPage: number; - kuery?: string; - }; + query: ListWithKuery; } -export interface GetPackagePoliciesResponse { - items: PackagePolicy[]; - total: number; - page: number; - perPage: number; -} +export type GetPackagePoliciesResponse = ListResult; export interface GetOnePackagePolicyRequest { params: { diff --git a/x-pack/plugins/fleet/cypress/fixtures/integrations/apache.json b/x-pack/plugins/fleet/cypress/fixtures/integrations/apache.json index 3b78048fdd83fc..397bc6d6534095 100644 --- a/x-pack/plugins/fleet/cypress/fixtures/integrations/apache.json +++ b/x-pack/plugins/fleet/cypress/fixtures/integrations/apache.json @@ -1,5 +1,5 @@ { - "response": { + "item": { "name": "apache", "title": "Apache", "version": "1.1.0", diff --git a/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts b/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts index 88769ece39f2f7..8b1a5e97279e89 100644 --- a/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/integrations.spec.ts @@ -88,7 +88,7 @@ describe('Add Integration', () => { fixture: 'integrations/agent_policy.json', }); // TODO fixture includes 1 package policy, should be empty initially - cy.intercept('GET', '/api/fleet/epm/packages/apache-1.1.0', { + cy.intercept('GET', '/api/fleet/epm/packages/apache/1.1.0', { fixture: 'integrations/apache.json', }); addAndVerifyIntegration(); diff --git a/x-pack/plugins/fleet/cypress/tasks/integrations.ts b/x-pack/plugins/fleet/cypress/tasks/integrations.ts index f1c891fa1186c0..e9e3f2613c3e8f 100644 --- a/x-pack/plugins/fleet/cypress/tasks/integrations.ts +++ b/x-pack/plugins/fleet/cypress/tasks/integrations.ts @@ -50,7 +50,7 @@ export const deleteIntegrations = async (integration: string) => { export const installPackageWithVersion = (integration: string, version: string) => { cy.request({ - url: `/api/fleet/epm/packages/${integration}-${version}`, + url: `/api/fleet/epm/packages/${integration}/${version}`, headers: { 'kbn-xsrf': 'cypress' }, body: '{ "force": true }', method: 'POST', diff --git a/x-pack/plugins/fleet/dev_docs/api/epm.md b/x-pack/plugins/fleet/dev_docs/api/epm.md index 90b636a5a92a10..1588e228c438b0 100644 --- a/x-pack/plugins/fleet/dev_docs/api/epm.md +++ b/x-pack/plugins/fleet/dev_docs/api/epm.md @@ -14,11 +14,11 @@ curl localhost:5601/api/fleet/epm/packages Install a package: ``` -curl -X POST localhost:5601/api/fleet/epm/packages/iptables-1.0.4 +curl -X POST localhost:5601/api/fleet/epm/packages/iptables/1.0.4 ``` Delete a package: ``` -curl -X DELETE localhost:5601/api/fleet/epm/packages/iptables-1.0.4 +curl -X DELETE localhost:5601/api/fleet/epm/packages/iptables/1.0.4 ``` diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx index 4f1211a83ebba2..c731936c775e56 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/index.tsx @@ -24,6 +24,7 @@ import { import type { EuiStepProps } from '@elastic/eui/src/components/steps/step'; import { safeLoad } from 'js-yaml'; +import { splitPkgKey } from '../../../../../../common'; import type { AgentPolicy, NewPackagePolicy, @@ -152,15 +153,16 @@ export const CreatePackagePolicyPage: React.FunctionComponent = () => { // Form state const [formState, setFormState] = useState('VALID'); + const { pkgName, pkgVersion } = splitPkgKey(params.pkgkey); // Fetch package info const { data: packageInfoData, error: packageInfoError, isLoading: isPackageInfoLoading, - } = useGetPackageInfoByKey(params.pkgkey); + } = useGetPackageInfoByKey(pkgName, pkgVersion); const packageInfo = useMemo(() => { - if (packageInfoData && packageInfoData.response) { - return packageInfoData.response; + if (packageInfoData && packageInfoData.item) { + return packageInfoData.item; } }, [packageInfoData]); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/index.tsx index a7dd682384748c..8d7ac07867605a 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/index.tsx @@ -213,15 +213,16 @@ export const EditPackagePolicyForm = memo<{ } const { data: packageData } = await sendGetPackageInfoByKey( - pkgKeyFromPackageInfo(_packageInfo!) + _packageInfo!.name, + _packageInfo!.version ); - if (packageData?.response) { - setPackageInfo(packageData.response); + if (packageData?.item) { + setPackageInfo(packageData.item); const newValidationResults = validatePackagePolicy( newPackagePolicy, - packageData.response, + packageData.item, safeLoad ); setValidationResults(newValidationResults); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx index 0dbe947369ad3c..c8c0ff7fbda207 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx @@ -308,7 +308,7 @@ export const AgentListPage: React.FunctionComponent<{}> = () => { inactive: agentsRequest.data.totalInactive, }); - setAgents(agentsRequest.data.list); + setAgents(agentsRequest.data.items); setTotalAgents(agentsRequest.data.total); setTotalInactiveAgents(agentsRequest.data.totalInactive); } catch (error) { diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/fleet_server_upgrade_modal.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/fleet_server_upgrade_modal.tsx index 2d963ea0ddf300..5902f73cae3bc9 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/fleet_server_upgrade_modal.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/fleet_server_upgrade_modal.tsx @@ -63,7 +63,7 @@ export const FleetServerUpgradeModal: React.FunctionComponent = ({ onClos throw res.error; } - for (const agent of res.data?.list ?? []) { + for (const agent of res.data?.items ?? []) { if (!agent.policy_id || agentPoliciesAlreadyChecked[agent.policy_id]) { continue; } diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/enrollment_token_list_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/enrollment_token_list_page/index.tsx index b8b66b42b533d3..72160fb4ae8973 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/enrollment_token_list_page/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/enrollment_token_list_page/index.tsx @@ -182,7 +182,7 @@ export const EnrollmentTokenListPage: React.FunctionComponent<{}> = () => { const total = enrollmentAPIKeysRequest?.data?.total ?? 0; const rowItems = - enrollmentAPIKeysRequest?.data?.list.filter((enrollmentKey) => { + enrollmentAPIKeysRequest?.data?.items.filter((enrollmentKey) => { if (!agentPolicies.length || !enrollmentKey.policy_id) return false; const agentPolicy = agentPoliciesById[enrollmentKey.policy_id]; return !agentPolicy?.is_managed; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/hooks/use_fleet_server_unhealthy.test.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/hooks/use_fleet_server_unhealthy.test.tsx index 87a269672ed9c5..a36b4fb25793fe 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/hooks/use_fleet_server_unhealthy.test.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/hooks/use_fleet_server_unhealthy.test.tsx @@ -37,7 +37,7 @@ const mockApiCallsWithHealthyFleetServer = (http: MockedFleetStartServices['http }; } - if (path === '/api/fleet/agent-status') { + if (path === '/api/fleet/agent_status') { return { data: { results: { online: 1, updating: 0, offline: 0 }, @@ -65,7 +65,7 @@ const mockApiCallsWithoutHealthyFleetServer = (http: MockedFleetStartServices['h }; } - if (path === '/api/fleet/agent-status') { + if (path === '/api/fleet/agent_status') { return { data: { results: { online: 0, updating: 0, offline: 1 }, diff --git a/x-pack/plugins/fleet/public/applications/integrations/hooks/use_links.tsx b/x-pack/plugins/fleet/public/applications/integrations/hooks/use_links.tsx index 032554a4ec439a..c39e4e0d097c53 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/hooks/use_links.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/hooks/use_links.tsx @@ -39,8 +39,7 @@ export function useLinks() { version: string; }) => { const imagePath = removeRelativePath(path); - const pkgkey = `${packageName}-${version}`; - const filePath = `${epmRouteService.getInfoPath(pkgkey)}/${imagePath}`; + const filePath = `${epmRouteService.getInfoPath(packageName, version)}/${imagePath}`; return http.basePath.prepend(filePath); }, }; diff --git a/x-pack/plugins/fleet/public/applications/integrations/hooks/use_package_install.tsx b/x-pack/plugins/fleet/public/applications/integrations/hooks/use_package_install.tsx index ad6f492bc5fce1..90a2231da40c61 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/hooks/use_package_install.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/hooks/use_package_install.tsx @@ -61,9 +61,8 @@ function usePackageInstall({ notifications }: { notifications: NotificationsStar const currStatus = getPackageInstallStatus(name); const newStatus = { ...currStatus, name, status: InstallStatus.installing }; setPackageInstallStatus(newStatus); - const pkgkey = `${name}-${version}`; - const res = await sendInstallPackage(pkgkey); + const res = await sendInstallPackage(name, version); if (res.error) { if (fromUpdate) { // if there is an error during update, set it back to the previous version @@ -126,9 +125,8 @@ function usePackageInstall({ notifications }: { notifications: NotificationsStar redirectToVersion, }: Pick & { redirectToVersion: string }) => { setPackageInstallStatus({ name, status: InstallStatus.uninstalling, version }); - const pkgkey = `${name}-${version}`; - const res = await sendRemovePackage(pkgkey); + const res = await sendRemovePackage(name, version); if (res.error) { setPackageInstallStatus({ name, status: InstallStatus.installed, version }); notifications.toasts.addWarning({ diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.test.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.test.tsx index d442f8a13e27e2..02874f12c6592c 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.test.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.test.tsx @@ -75,7 +75,7 @@ describe('when on integration detail', () => { describe('and the package is not installed', () => { beforeEach(() => { const unInstalledPackage = mockedApi.responseProvider.epmGetInfo(); - unInstalledPackage.response.status = 'not_installed'; + unInstalledPackage.item.status = 'not_installed'; mockedApi.responseProvider.epmGetInfo.mockReturnValue(unInstalledPackage); render(); }); @@ -283,7 +283,7 @@ const mockApiCalls = ( // @ts-ignore const epmPackageResponse: GetInfoResponse = { - response: { + item: { name: 'nginx', title: 'Nginx', version: '0.3.7', @@ -770,7 +770,7 @@ On Windows, the module was tested with Nginx installed from the Chocolatey repos http.get.mockImplementation(async (path: any) => { if (typeof path === 'string') { - if (path === epmRouteService.getInfoPath(`nginx-0.3.7`)) { + if (path === epmRouteService.getInfoPath(`nginx`, `0.3.7`)) { markApiCallAsHandled(); return mockedApiInterface.responseProvider.epmGetInfo(); } diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.tsx index 1a3a5c7eadd351..cdebc5f8b3ce11 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.tsx @@ -27,6 +27,7 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import semverLt from 'semver/functions/lt'; +import { splitPkgKey } from '../../../../../../../common'; import { useGetPackageInstallStatus, useSetPackageInstallStatus, @@ -132,26 +133,27 @@ export function Detail() { packageInfo.savedObject && semverLt(packageInfo.savedObject.attributes.version, packageInfo.latestVersion); + const { pkgName, pkgVersion } = splitPkgKey(pkgkey); // Fetch package info const { data: packageInfoData, error: packageInfoError, isLoading: packageInfoLoading, - } = useGetPackageInfoByKey(pkgkey); + } = useGetPackageInfoByKey(pkgName, pkgVersion); const isLoading = packageInfoLoading || permissionCheck.isLoading; const showCustomTab = - useUIExtension(packageInfoData?.response.name ?? '', 'package-detail-custom') !== undefined; + useUIExtension(packageInfoData?.item.name ?? '', 'package-detail-custom') !== undefined; // Track install status state useEffect(() => { - if (packageInfoData?.response) { - const packageInfoResponse = packageInfoData.response; + if (packageInfoData?.item) { + const packageInfoResponse = packageInfoData.item; setPackageInfo(packageInfoResponse); let installedVersion; - const { name } = packageInfoData.response; + const { name } = packageInfoData.item; if ('savedObject' in packageInfoResponse) { installedVersion = packageInfoResponse.savedObject.attributes.version; } diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/settings/settings.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/settings/settings.tsx index 73c762d34a2cf6..a28f63c3f91639 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/settings/settings.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/settings/settings.tsx @@ -122,7 +122,7 @@ export const SettingsPage: React.FC = memo(({ packageInfo }: Props) => { try { setKeepPoliciesUpToDateSwitchValue((prev) => !prev); - await sendUpdatePackage(`${packageInfo.name}-${packageInfo.version}`, { + await sendUpdatePackage(packageInfo.name, packageInfo.version, { keepPoliciesUpToDate: !keepPoliciesUpToDateSwitchValue, }); diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/available_packages.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/available_packages.tsx index 81d1701c4a9867..7547e062011711 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/available_packages.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/available_packages.tsx @@ -215,7 +215,7 @@ export const AvailablePackages: React.FC = memo(() => { category: '', }); const eprIntegrationList = useMemo( - () => packageListToIntegrationsList(eprPackages?.response || []), + () => packageListToIntegrationsList(eprPackages?.items || []), [eprPackages] ); @@ -256,7 +256,7 @@ export const AvailablePackages: React.FC = memo(() => { ? [] : mergeCategoriesAndCount( eprCategories - ? (eprCategories.response as Array<{ id: string; title: string; count: number }>) + ? (eprCategories.items as Array<{ id: string; title: string; count: number }>) : [], cards ); diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/advanced_agent_authentication_settings.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/advanced_agent_authentication_settings.tsx index 3d069c1d0336ba..52c4d09a58c564 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/advanced_agent_authentication_settings.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/advanced_agent_authentication_settings.tsx @@ -103,7 +103,7 @@ export const AdvancedAgentAuthenticationSettings: FunctionComponent = ({ onKeyChange, }) => { const { notifications } = useStartServices(); - const [enrollmentAPIKeys, setEnrollmentAPIKeys] = useState( + const [enrollmentAPIKeys, setEnrollmentAPIKeys] = useState( [] ); @@ -143,7 +143,7 @@ export const AdvancedAgentAuthenticationSettings: FunctionComponent = ({ throw new Error('No data while fetching enrollment API keys'); } - const enrollmentAPIKeysResponse = res.data.list.filter( + const enrollmentAPIKeysResponse = res.data.items.filter( (key) => key.policy_id === agentPolicyId && key.active === true ); diff --git a/x-pack/plugins/fleet/public/hooks/use_package_icon_type.ts b/x-pack/plugins/fleet/public/hooks/use_package_icon_type.ts index 1b21b7bfd78eb6..733aaef8b92676 100644 --- a/x-pack/plugins/fleet/public/hooks/use_package_icon_type.ts +++ b/x-pack/plugins/fleet/public/hooks/use_package_icon_type.ts @@ -66,11 +66,11 @@ export const usePackageIconType = ({ } if (tryApi && !paramIcons && !iconList) { - sendGetPackageInfoByKey(cacheKey) + sendGetPackageInfoByKey(packageName, version) .catch((error) => undefined) // Ignore API errors .then((res) => { CACHED_ICONS.delete(cacheKey); - setIconList(res?.data?.response?.icons); + setIconList(res?.data?.item?.icons); }); } diff --git a/x-pack/plugins/fleet/public/hooks/use_package_installations.tsx b/x-pack/plugins/fleet/public/hooks/use_package_installations.tsx index f4735e6f855464..4789770b7046f3 100644 --- a/x-pack/plugins/fleet/public/hooks/use_package_installations.tsx +++ b/x-pack/plugins/fleet/public/hooks/use_package_installations.tsx @@ -36,9 +36,8 @@ export const usePackageInstallations = () => { }); const allInstalledPackages = useMemo( - () => - (allPackages?.response || []).filter((pkg) => pkg.status === installationStatuses.Installed), - [allPackages?.response] + () => (allPackages?.items || []).filter((pkg) => pkg.status === installationStatuses.Installed), + [allPackages?.items] ); const updatablePackages = useMemo( diff --git a/x-pack/plugins/fleet/public/hooks/use_request/epm.ts b/x-pack/plugins/fleet/public/hooks/use_request/epm.ts index a7078dd3a3f913..c5e82316e5eb3d 100644 --- a/x-pack/plugins/fleet/public/hooks/use_request/epm.ts +++ b/x-pack/plugins/fleet/public/hooks/use_request/epm.ts @@ -67,9 +67,9 @@ export const useGetLimitedPackages = () => { }); }; -export const useGetPackageInfoByKey = (pkgkey: string) => { +export const useGetPackageInfoByKey = (pkgName: string, pkgVersion: string) => { return useRequest({ - path: epmRouteService.getInfoPath(pkgkey), + path: epmRouteService.getInfoPath(pkgName, pkgVersion), method: 'get', }); }; @@ -81,9 +81,9 @@ export const useGetPackageStats = (pkgName: string) => { }); }; -export const sendGetPackageInfoByKey = (pkgkey: string) => { +export const sendGetPackageInfoByKey = (pkgName: string, pkgVersion: string) => { return sendRequest({ - path: epmRouteService.getInfoPath(pkgkey), + path: epmRouteService.getInfoPath(pkgName, pkgVersion), method: 'get', }); }; @@ -102,23 +102,27 @@ export const sendGetFileByPath = (filePath: string) => { }); }; -export const sendInstallPackage = (pkgkey: string) => { +export const sendInstallPackage = (pkgName: string, pkgVersion: string) => { return sendRequest({ - path: epmRouteService.getInstallPath(pkgkey), + path: epmRouteService.getInstallPath(pkgName, pkgVersion), method: 'post', }); }; -export const sendRemovePackage = (pkgkey: string) => { +export const sendRemovePackage = (pkgName: string, pkgVersion: string) => { return sendRequest({ - path: epmRouteService.getRemovePath(pkgkey), + path: epmRouteService.getRemovePath(pkgName, pkgVersion), method: 'delete', }); }; -export const sendUpdatePackage = (pkgkey: string, body: UpdatePackageRequest['body']) => { +export const sendUpdatePackage = ( + pkgName: string, + pkgVersion: string, + body: UpdatePackageRequest['body'] +) => { return sendRequest({ - path: epmRouteService.getUpdatePath(pkgkey), + path: epmRouteService.getUpdatePath(pkgName, pkgVersion), method: 'put', body, }); diff --git a/x-pack/plugins/fleet/public/search_provider.test.ts b/x-pack/plugins/fleet/public/search_provider.test.ts index 97ed199c445020..43e6d93c8031cb 100644 --- a/x-pack/plugins/fleet/public/search_provider.test.ts +++ b/x-pack/plugins/fleet/public/search_provider.test.ts @@ -24,7 +24,7 @@ import { sendGetPackages } from './hooks'; const mockSendGetPackages = sendGetPackages as jest.Mock; -const testResponse: GetPackagesResponse['response'] = [ +const testResponse: GetPackagesResponse['items'] = [ { description: 'test', download: 'test', diff --git a/x-pack/plugins/fleet/public/search_provider.ts b/x-pack/plugins/fleet/public/search_provider.ts index d919462f38c28b..fe7cca92cf48d8 100644 --- a/x-pack/plugins/fleet/public/search_provider.ts +++ b/x-pack/plugins/fleet/public/search_provider.ts @@ -105,7 +105,7 @@ export const createPackageSearchProvider = (core: CoreSetup): GlobalSearchResult const toSearchResults = ( coreStart: CoreStart, - packagesResponse: GetPackagesResponse['response'] + packagesResponse: GetPackagesResponse['items'] ): GlobalSearchProviderResult[] => { return packagesResponse .flatMap( diff --git a/x-pack/plugins/fleet/server/routes/agent/handlers.ts b/x-pack/plugins/fleet/server/routes/agent/handlers.ts index dd77c216413f3a..578d4281cba3bd 100644 --- a/x-pack/plugins/fleet/server/routes/agent/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/agent/handlers.ts @@ -122,7 +122,8 @@ export const getAgentsHandler: RequestHandler< : 0; const body: GetAgentsResponse = { - list: agents, + list: agents, // deprecated + items: agents, total, totalInactive, page, diff --git a/x-pack/plugins/fleet/server/routes/agent/index.ts b/x-pack/plugins/fleet/server/routes/agent/index.ts index db5b01b319e008..7297252ff3230b 100644 --- a/x-pack/plugins/fleet/server/routes/agent/index.ts +++ b/x-pack/plugins/fleet/server/routes/agent/index.ts @@ -116,6 +116,15 @@ export const registerAPIRoutes = (router: IRouter, config: FleetConfigType) => { }, getAgentStatusForAgentPolicyHandler ); + router.get( + { + path: AGENT_API_ROUTES.STATUS_PATTERN_DEPRECATED, + validate: GetAgentStatusRequestSchema, + options: { tags: [`access:${PLUGIN_ID}-read`] }, + }, + getAgentStatusForAgentPolicyHandler + ); + // upgrade agent router.post( { diff --git a/x-pack/plugins/fleet/server/routes/app/index.ts b/x-pack/plugins/fleet/server/routes/app/index.ts index aa2d61732eed5c..cb2a01deecb4f1 100644 --- a/x-pack/plugins/fleet/server/routes/app/index.ts +++ b/x-pack/plugins/fleet/server/routes/app/index.ts @@ -90,4 +90,13 @@ export const registerRoutes = (router: IRouter) => { }, generateServiceTokenHandler ); + + router.post( + { + path: APP_API_ROUTES.GENERATE_SERVICE_TOKEN_PATTERN_DEPRECATED, + validate: {}, + options: { tags: [`access:${PLUGIN_ID}-all`] }, + }, + generateServiceTokenHandler + ); }; diff --git a/x-pack/plugins/fleet/server/routes/enrollment_api_key/handler.ts b/x-pack/plugins/fleet/server/routes/enrollment_api_key/handler.ts index 0465614c49432c..7fef583af50cd0 100644 --- a/x-pack/plugins/fleet/server/routes/enrollment_api_key/handler.ts +++ b/x-pack/plugins/fleet/server/routes/enrollment_api_key/handler.ts @@ -36,7 +36,13 @@ export const getEnrollmentApiKeysHandler: RequestHandler< perPage: request.query.perPage, kuery: request.query.kuery, }); - const body: GetEnrollmentAPIKeysResponse = { list: items, total, page, perPage }; + const body: GetEnrollmentAPIKeysResponse = { + list: items, // deprecated + items, + total, + page, + perPage, + }; return response.ok({ body }); } catch (error) { diff --git a/x-pack/plugins/fleet/server/routes/enrollment_api_key/index.ts b/x-pack/plugins/fleet/server/routes/enrollment_api_key/index.ts index 6429d4d29d5c94..39665f14484ba2 100644 --- a/x-pack/plugins/fleet/server/routes/enrollment_api_key/index.ts +++ b/x-pack/plugins/fleet/server/routes/enrollment_api_key/index.ts @@ -61,4 +61,44 @@ export const registerRoutes = (routers: { superuser: FleetRouter; fleetSetup: Fl }, postEnrollmentApiKeyHandler ); + + routers.fleetSetup.get( + { + path: ENROLLMENT_API_KEY_ROUTES.INFO_PATTERN_DEPRECATED, + validate: GetOneEnrollmentAPIKeyRequestSchema, + // Disable this tag and the automatic RBAC support until elastic/fleet-server access is removed in 8.0 + // Required to allow elastic/fleet-server to access this API. + // options: { tags: [`access:${PLUGIN_ID}-read`] }, + }, + getOneEnrollmentApiKeyHandler + ); + + routers.superuser.delete( + { + path: ENROLLMENT_API_KEY_ROUTES.DELETE_PATTERN_DEPRECATED, + validate: DeleteEnrollmentAPIKeyRequestSchema, + options: { tags: [`access:${PLUGIN_ID}-all`] }, + }, + deleteEnrollmentApiKeyHandler + ); + + routers.fleetSetup.get( + { + path: ENROLLMENT_API_KEY_ROUTES.LIST_PATTERN_DEPRECATED, + validate: GetEnrollmentAPIKeysRequestSchema, + // Disable this tag and the automatic RBAC support until elastic/fleet-server access is removed in 8.0 + // Required to allow elastic/fleet-server to access this API. + // options: { tags: [`access:${PLUGIN_ID}-read`] }, + }, + getEnrollmentApiKeysHandler + ); + + routers.superuser.post( + { + path: ENROLLMENT_API_KEY_ROUTES.CREATE_PATTERN_DEPRECATED, + validate: PostEnrollmentAPIKeyRequestSchema, + options: { tags: [`access:${PLUGIN_ID}-all`] }, + }, + postEnrollmentApiKeyHandler + ); }; diff --git a/x-pack/plugins/fleet/server/routes/epm/handlers.ts b/x-pack/plugins/fleet/server/routes/epm/handlers.ts index c98038427cafc4..4f3f969defd0c4 100644 --- a/x-pack/plugins/fleet/server/routes/epm/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/epm/handlers.ts @@ -9,6 +9,7 @@ import path from 'path'; import type { TypeOf } from '@kbn/config-schema'; import mime from 'mime-types'; +import semverValid from 'semver/functions/valid'; import type { ResponseHeaders, KnownHeaders } from 'src/core/server'; import type { @@ -50,8 +51,11 @@ import { getInstallation, } from '../../services/epm/packages'; import type { BulkInstallResponse } from '../../services/epm/packages'; -import { defaultIngestErrorHandler, ingestErrorToResponseOptions } from '../../errors'; -import { splitPkgKey } from '../../services/epm/registry'; +import { + defaultIngestErrorHandler, + ingestErrorToResponseOptions, + IngestManagerError, +} from '../../errors'; import { licenseService } from '../../services'; import { getArchiveEntry } from '../../services/epm/archive/cache'; import { getAsset } from '../../services/epm/archive/storage'; @@ -65,6 +69,7 @@ export const getCategoriesHandler: FleetRequestHandler< try { const res = await getCategories(request.query); const body: GetCategoriesResponse = { + items: res, response: res, }; return response.ok({ body }); @@ -84,6 +89,7 @@ export const getListHandler: FleetRequestHandler< ...request.query, }); const body: GetPackagesResponse = { + items: res, response: res, }; return response.ok({ @@ -99,6 +105,7 @@ export const getLimitedListHandler: FleetRequestHandler = async (context, reques const savedObjectsClient = context.fleet.epm.internalSoClient; const res = await getLimitedPackages({ savedObjectsClient }); const body: GetLimitedPackagesResponse = { + items: res, response: res, }; return response.ok({ @@ -186,13 +193,18 @@ export const getFileHandler: FleetRequestHandler> = async (context, request, response) => { try { - const { pkgkey } = request.params; const savedObjectsClient = context.fleet.epm.internalSoClient; - // TODO: change epm API to /packageName/version so we don't need to do this - const { pkgName, pkgVersion } = splitPkgKey(pkgkey); - const res = await getPackageInfo({ savedObjectsClient, pkgName, pkgVersion }); + const { pkgName, pkgVersion } = request.params; + if (pkgVersion && !semverValid(pkgVersion)) { + throw new IngestManagerError('Package version is not a valid semver'); + } + const res = await getPackageInfo({ + savedObjectsClient, + pkgName, + pkgVersion: pkgVersion || '', + }); const body: GetInfoResponse = { - response: res, + item: res, }; return response.ok({ body }); } catch (error) { @@ -206,14 +218,12 @@ export const updatePackageHandler: FleetRequestHandler< TypeOf > = async (context, request, response) => { try { - const { pkgkey } = request.params; const savedObjectsClient = context.fleet.epm.internalSoClient; - - const { pkgName } = splitPkgKey(pkgkey); + const { pkgName } = request.params; const res = await updatePackage({ savedObjectsClient, pkgName, ...request.body }); const body: UpdatePackageResponse = { - response: res, + item: res, }; return response.ok({ body }); @@ -243,18 +253,18 @@ export const installPackageFromRegistryHandler: FleetRequestHandler< > = async (context, request, response) => { const savedObjectsClient = context.fleet.epm.internalSoClient; const esClient = context.core.elasticsearch.client.asInternalUser; - const { pkgkey } = request.params; + const { pkgName, pkgVersion } = request.params; const res = await installPackage({ installSource: 'registry', savedObjectsClient, - pkgkey, + pkgkey: pkgVersion ? `${pkgName}-${pkgVersion}` : pkgName, esClient, force: request.body?.force, }); if (!res.error) { const body: InstallPackageResponse = { - response: res.assets || [], + items: res.assets || [], }; return response.ok({ body }); } else { @@ -291,6 +301,7 @@ export const bulkInstallPackagesFromRegistryHandler: FleetRequestHandler< }); const payload = bulkInstalledResponses.map(bulkInstallServiceResponseToHttpEntry); const body: BulkInstallPackagesResponse = { + items: payload, response: payload, }; return response.ok({ body }); @@ -321,6 +332,7 @@ export const installPackageByUploadHandler: FleetRequestHandler< }); if (!res.error) { const body: InstallPackageResponse = { + items: res.assets || [], response: res.assets || [], }; return response.ok({ body }); @@ -335,17 +347,18 @@ export const deletePackageHandler: FleetRequestHandler< TypeOf > = async (context, request, response) => { try { - const { pkgkey } = request.params; + const { pkgName, pkgVersion } = request.params; const savedObjectsClient = context.fleet.epm.internalSoClient; const esClient = context.core.elasticsearch.client.asInternalUser; const res = await removeInstallation({ savedObjectsClient, - pkgkey, + pkgName, + pkgVersion, esClient, force: request.body?.force, }); const body: DeletePackageResponse = { - response: res, + items: res, }; return response.ok({ body }); } catch (error) { diff --git a/x-pack/plugins/fleet/server/routes/epm/index.ts b/x-pack/plugins/fleet/server/routes/epm/index.ts index a2f2df4a00c55f..da2e2458276084 100644 --- a/x-pack/plugins/fleet/server/routes/epm/index.ts +++ b/x-pack/plugins/fleet/server/routes/epm/index.ts @@ -5,18 +5,32 @@ * 2.0. */ +import type { IKibanaResponse } from 'src/core/server'; + +import type { + DeletePackageResponse, + GetInfoResponse, + InstallPackageResponse, + UpdatePackageResponse, +} from '../../../common'; + import { PLUGIN_ID, EPM_API_ROUTES } from '../../constants'; +import { splitPkgKey } from '../../services/epm/registry'; import { GetCategoriesRequestSchema, GetPackagesRequestSchema, GetFileRequestSchema, GetInfoRequestSchema, + GetInfoRequestSchemaDeprecated, InstallPackageFromRegistryRequestSchema, + InstallPackageFromRegistryRequestSchemaDeprecated, InstallPackageByUploadRequestSchema, DeletePackageRequestSchema, + DeletePackageRequestSchemaDeprecated, BulkUpgradePackagesFromRegistryRequestSchema, GetStatsRequestSchema, UpdatePackageRequestSchema, + UpdatePackageRequestSchemaDeprecated, } from '../../types'; import type { FleetRouter } from '../../types/request_context'; @@ -142,4 +156,85 @@ export const registerRoutes = (routers: { rbac: FleetRouter; superuser: FleetRou }, deletePackageHandler ); + + // deprecated since 8.0 + routers.rbac.get( + { + path: EPM_API_ROUTES.INFO_PATTERN_DEPRECATED, + validate: GetInfoRequestSchemaDeprecated, + options: { tags: [`access:${PLUGIN_ID}-read`] }, + }, + async (context, request, response) => { + const newRequest = { ...request, params: splitPkgKey(request.params.pkgkey) } as any; + const resp: IKibanaResponse = await getInfoHandler( + context, + newRequest, + response + ); + if (resp.payload?.item) { + return response.ok({ body: { response: resp.payload.item } }); + } + return resp; + } + ); + + routers.superuser.put( + { + path: EPM_API_ROUTES.INFO_PATTERN_DEPRECATED, + validate: UpdatePackageRequestSchemaDeprecated, + options: { tags: [`access:${PLUGIN_ID}-all`] }, + }, + async (context, request, response) => { + const newRequest = { ...request, params: splitPkgKey(request.params.pkgkey) } as any; + const resp: IKibanaResponse = await updatePackageHandler( + context, + newRequest, + response + ); + if (resp.payload?.item) { + return response.ok({ body: { response: resp.payload.item } }); + } + return resp; + } + ); + + routers.superuser.post( + { + path: EPM_API_ROUTES.INSTALL_FROM_REGISTRY_PATTERN_DEPRECATED, + validate: InstallPackageFromRegistryRequestSchemaDeprecated, + options: { tags: [`access:${PLUGIN_ID}-all`] }, + }, + async (context, request, response) => { + const newRequest = { ...request, params: splitPkgKey(request.params.pkgkey) } as any; + const resp: IKibanaResponse = await installPackageFromRegistryHandler( + context, + newRequest, + response + ); + if (resp.payload?.items) { + return response.ok({ body: { response: resp.payload.items } }); + } + return resp; + } + ); + + routers.superuser.delete( + { + path: EPM_API_ROUTES.DELETE_PATTERN_DEPRECATED, + validate: DeletePackageRequestSchemaDeprecated, + options: { tags: [`access:${PLUGIN_ID}-all`] }, + }, + async (context, request, response) => { + const newRequest = { ...request, params: splitPkgKey(request.params.pkgkey) } as any; + const resp: IKibanaResponse = await deletePackageHandler( + context, + newRequest, + response + ); + if (resp.payload?.items) { + return response.ok({ body: { response: resp.payload.items } }); + } + return resp; + } + ); }; diff --git a/x-pack/plugins/fleet/server/services/epm/packages/install.ts b/x-pack/plugins/fleet/server/services/epm/packages/install.ts index a580248b437314..77fcc429b2084c 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/install.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/install.ts @@ -164,7 +164,7 @@ export async function handleInstallPackageFailure({ const installType = getInstallType({ pkgVersion, installedPkg }); if (installType === 'install' || installType === 'reinstall') { logger.error(`uninstalling ${pkgkey} after error installing: [${error.toString()}]`); - await removeInstallation({ savedObjectsClient, pkgkey, esClient }); + await removeInstallation({ savedObjectsClient, pkgName, pkgVersion, esClient }); } await updateInstallStatus({ savedObjectsClient, pkgName, status: 'install_failed' }); diff --git a/x-pack/plugins/fleet/server/services/epm/packages/remove.ts b/x-pack/plugins/fleet/server/services/epm/packages/remove.ts index 957dac8c1aacb1..848d17f78c9292 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/remove.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/remove.ts @@ -22,7 +22,6 @@ import { removeUnusedIndexPatterns } from '../kibana/index_pattern/install'; import { deleteTransforms } from '../elasticsearch/transform/remove'; import { deleteMlModel } from '../elasticsearch/ml_model'; import { packagePolicyService, appContextService } from '../..'; -import { splitPkgKey } from '../registry'; import { deletePackageCache } from '../archive'; import { deleteIlms } from '../elasticsearch/datastream_ilm/remove'; import { removeArchiveEntries } from '../archive/storage'; @@ -31,13 +30,12 @@ import { getInstallation, kibanaSavedObjectTypes } from './index'; export async function removeInstallation(options: { savedObjectsClient: SavedObjectsClientContract; - pkgkey: string; + pkgName: string; + pkgVersion: string; esClient: ElasticsearchClient; force?: boolean; }): Promise { - const { savedObjectsClient, pkgkey, esClient, force } = options; - // TODO: the epm api should change to /name/version so we don't need to do this - const { pkgName, pkgVersion } = splitPkgKey(pkgkey); + const { savedObjectsClient, pkgName, pkgVersion, esClient, force } = options; const installation = await getInstallation({ savedObjectsClient, pkgName }); if (!installation) throw Boom.badRequest(`${pkgName} is not installed`); if (installation.removable === false && !force) diff --git a/x-pack/plugins/fleet/server/services/epm/registry/index.ts b/x-pack/plugins/fleet/server/services/epm/registry/index.ts index 1b6e28a07f8e0b..8cfb2844159bca 100644 --- a/x-pack/plugins/fleet/server/services/epm/registry/index.ts +++ b/x-pack/plugins/fleet/server/services/epm/registry/index.ts @@ -8,9 +8,11 @@ import { URL } from 'url'; import mime from 'mime-types'; -import semverValid from 'semver/functions/valid'; + import type { Response } from 'node-fetch'; +import { splitPkgKey as split } from '../../../../common'; + import { KibanaAssetType } from '../../../types'; import type { AssetsGroupedByServiceByType, @@ -31,12 +33,7 @@ import { } from '../archive'; import { streamToBuffer } from '../streams'; import { appContextService } from '../..'; -import { - PackageKeyInvalidError, - PackageNotFoundError, - PackageCacheError, - RegistryResponseError, -} from '../../../errors'; +import { PackageNotFoundError, PackageCacheError, RegistryResponseError } from '../../../errors'; import { fetchUrl, getResponse, getResponseStream } from './requests'; import { getRegistryUrl } from './registry_url'; @@ -46,33 +43,7 @@ export interface SearchParams { experimental?: boolean; } -/** - * Extract the package name and package version from a string. - * - * @param pkgkey a string containing the package name delimited by the package version - */ -export function splitPkgKey(pkgkey: string): { pkgName: string; pkgVersion: string } { - // If no version is provided, use the provided package key as the - // package name and return an empty version value - if (!pkgkey.includes('-')) { - return { pkgName: pkgkey, pkgVersion: '' }; - } - - const pkgName = pkgkey.includes('-') ? pkgkey.substr(0, pkgkey.indexOf('-')) : pkgkey; - - if (pkgName === '') { - throw new PackageKeyInvalidError('Package key parsing failed: package name was empty'); - } - - // this will return the entire string if `indexOf` return -1 - const pkgVersion = pkgkey.substr(pkgkey.indexOf('-') + 1); - if (!semverValid(pkgVersion)) { - throw new PackageKeyInvalidError( - 'Package key parsing failed: package version was not a valid semver' - ); - } - return { pkgName, pkgVersion }; -} +export const splitPkgKey = split; export const pkgToPkgKey = ({ name, version }: { name: string; version: string }) => `${name}-${version}`; diff --git a/x-pack/plugins/fleet/server/types/rest_spec/epm.ts b/x-pack/plugins/fleet/server/types/rest_spec/epm.ts index 918def62a9d0e7..390d5dea792cb2 100644 --- a/x-pack/plugins/fleet/server/types/rest_spec/epm.ts +++ b/x-pack/plugins/fleet/server/types/rest_spec/epm.ts @@ -30,12 +30,29 @@ export const GetFileRequestSchema = { }; export const GetInfoRequestSchema = { + params: schema.object({ + pkgName: schema.string(), + pkgVersion: schema.maybe(schema.string()), + }), +}; + +export const GetInfoRequestSchemaDeprecated = { params: schema.object({ pkgkey: schema.string(), }), }; export const UpdatePackageRequestSchema = { + params: schema.object({ + pkgName: schema.string(), + pkgVersion: schema.maybe(schema.string()), + }), + body: schema.object({ + keepPoliciesUpToDate: schema.boolean(), + }), +}; + +export const UpdatePackageRequestSchemaDeprecated = { params: schema.object({ pkgkey: schema.string(), }), @@ -51,6 +68,18 @@ export const GetStatsRequestSchema = { }; export const InstallPackageFromRegistryRequestSchema = { + params: schema.object({ + pkgName: schema.string(), + pkgVersion: schema.maybe(schema.string()), + }), + body: schema.nullable( + schema.object({ + force: schema.boolean(), + }) + ), +}; + +export const InstallPackageFromRegistryRequestSchemaDeprecated = { params: schema.object({ pkgkey: schema.string(), }), @@ -72,6 +101,18 @@ export const InstallPackageByUploadRequestSchema = { }; export const DeletePackageRequestSchema = { + params: schema.object({ + pkgName: schema.string(), + pkgVersion: schema.string(), + }), + body: schema.nullable( + schema.object({ + force: schema.boolean(), + }) + ), +}; + +export const DeletePackageRequestSchemaDeprecated = { params: schema.object({ pkgkey: schema.string(), }), diff --git a/x-pack/plugins/fleet/storybook/context/fixtures/categories.ts b/x-pack/plugins/fleet/storybook/context/fixtures/categories.ts index 002748bd3d9677..1bb8d3300624e9 100644 --- a/x-pack/plugins/fleet/storybook/context/fixtures/categories.ts +++ b/x-pack/plugins/fleet/storybook/context/fixtures/categories.ts @@ -6,7 +6,7 @@ */ import type { GetCategoriesResponse } from '../../../public/types'; -export const response: GetCategoriesResponse['response'] = [ +export const items: GetCategoriesResponse['items'] = [ { id: 'aws', title: 'AWS', diff --git a/x-pack/plugins/fleet/storybook/context/fixtures/integration.nginx.ts b/x-pack/plugins/fleet/storybook/context/fixtures/integration.nginx.ts index de4fd228b5342b..6f48b15158f8d0 100644 --- a/x-pack/plugins/fleet/storybook/context/fixtures/integration.nginx.ts +++ b/x-pack/plugins/fleet/storybook/context/fixtures/integration.nginx.ts @@ -7,7 +7,7 @@ import type { GetInfoResponse } from '../../../public/types'; import { KibanaAssetType, ElasticsearchAssetType } from '../../../common/types'; -export const response: GetInfoResponse['response'] = { +export const item: GetInfoResponse['item'] = { name: 'nginx', title: 'Nginx', version: '0.7.0', diff --git a/x-pack/plugins/fleet/storybook/context/fixtures/integration.okta.ts b/x-pack/plugins/fleet/storybook/context/fixtures/integration.okta.ts index 360c340c9645f6..6b766c2d126dfc 100644 --- a/x-pack/plugins/fleet/storybook/context/fixtures/integration.okta.ts +++ b/x-pack/plugins/fleet/storybook/context/fixtures/integration.okta.ts @@ -7,7 +7,7 @@ import type { GetInfoResponse } from '../../../public/types'; import { KibanaAssetType, ElasticsearchAssetType } from '../../../common/types'; -export const response: GetInfoResponse['response'] = { +export const item: GetInfoResponse['item'] = { name: 'okta', title: 'Okta', version: '1.2.0', diff --git a/x-pack/plugins/fleet/storybook/context/fixtures/packages.ts b/x-pack/plugins/fleet/storybook/context/fixtures/packages.ts index dfe8e905be089a..4c13b6b6bf8cb2 100644 --- a/x-pack/plugins/fleet/storybook/context/fixtures/packages.ts +++ b/x-pack/plugins/fleet/storybook/context/fixtures/packages.ts @@ -7,7 +7,7 @@ import type { GetPackagesResponse } from '../../../public/types'; -export const response: GetPackagesResponse['response'] = [ +export const items: GetPackagesResponse['items'] = [ { name: 'ga_not_installed', title: 'a. GA, Not Installed', diff --git a/x-pack/plugins/fleet/storybook/context/http.ts b/x-pack/plugins/fleet/storybook/context/http.ts index 3e515c075a595e..491b62201e5321 100644 --- a/x-pack/plugins/fleet/storybook/context/http.ts +++ b/x-pack/plugins/fleet/storybook/context/http.ts @@ -55,7 +55,7 @@ export const getHttp = (basepath = BASE_PATH) => { // Ideally, this would be a markdown file instead of a ts file, but we don't have // markdown-loader in our package.json, so we'll make do with what we have. - if (path.startsWith('/api/fleet/epm/packages/nginx/')) { + if (path.match('/api/fleet/epm/packages/nginx/.*/.*/')) { const { readme } = await import('./fixtures/readme.nginx'); return readme; } @@ -66,7 +66,7 @@ export const getHttp = (basepath = BASE_PATH) => { // Ideally, this would be a markdown file instead of a ts file, but we don't have // markdown-loader in our package.json, so we'll make do with what we have. - if (path.startsWith('/api/fleet/epm/packages/okta/')) { + if (path.match('/api/fleet/epm/packages/okta/.*/.*/')) { const { readme } = await import('./fixtures/readme.okta'); return readme; } diff --git a/x-pack/plugins/osquery/public/agents/use_agent_status.ts b/x-pack/plugins/osquery/public/agents/use_agent_status.ts index ba2237dbe57ea6..a94bb5631343d9 100644 --- a/x-pack/plugins/osquery/public/agents/use_agent_status.ts +++ b/x-pack/plugins/osquery/public/agents/use_agent_status.ts @@ -25,7 +25,7 @@ export const useAgentStatus = ({ policyId, skip }: UseAgentStatus) => { ['agentStatus', policyId], () => http.get( - `/internal/osquery/fleet_wrapper/agent-status`, + `/internal/osquery/fleet_wrapper/agent_status`, policyId ? { query: { diff --git a/x-pack/plugins/osquery/server/routes/fleet_wrapper/get_agent_status_for_agent_policy.ts b/x-pack/plugins/osquery/server/routes/fleet_wrapper/get_agent_status_for_agent_policy.ts index 1f4f12648a25b1..18fc42d725c10d 100644 --- a/x-pack/plugins/osquery/server/routes/fleet_wrapper/get_agent_status_for_agent_policy.ts +++ b/x-pack/plugins/osquery/server/routes/fleet_wrapper/get_agent_status_for_agent_policy.ts @@ -17,7 +17,7 @@ export const getAgentStatusForAgentPolicyRoute = ( ) => { router.get( { - path: '/internal/osquery/fleet_wrapper/agent-status', + path: '/internal/osquery/fleet_wrapper/agent_status', validate: { query: schema.object({ policyId: schema.string(), diff --git a/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_endpoint_hosts.ts b/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_endpoint_hosts.ts index ed75823cd30d3e..be26f8496c5e99 100644 --- a/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_endpoint_hosts.ts +++ b/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_endpoint_hosts.ts @@ -97,7 +97,7 @@ export async function indexEndpointHostDocs({ client: Client; kbnClient: KbnClient; realPolicies: Record; - epmEndpointPackage: GetPackagesResponse['response'][0]; + epmEndpointPackage: GetPackagesResponse['items'][0]; metadataIndex: string; policyResponseIndex: string; enrollFleet: boolean; diff --git a/x-pack/plugins/security_solution/common/endpoint/data_loaders/setup_fleet_for_endpoint.ts b/x-pack/plugins/security_solution/common/endpoint/data_loaders/setup_fleet_for_endpoint.ts index 61f7123c368409..a236b56737e03b 100644 --- a/x-pack/plugins/security_solution/common/endpoint/data_loaders/setup_fleet_for_endpoint.ts +++ b/x-pack/plugins/security_solution/common/endpoint/data_loaders/setup_fleet_for_endpoint.ts @@ -101,7 +101,7 @@ export const installOrUpgradeEndpointFleetPackage = async ( }) .catch(wrapErrorAndRejectPromise)) as AxiosResponse; - const bulkResp = installEndpointPackageResp.data.response; + const bulkResp = installEndpointPackageResp.data.items; if (bulkResp.length <= 0) { throw new EndpointDataLoadingError( diff --git a/x-pack/plugins/security_solution/common/endpoint/generate_data.ts b/x-pack/plugins/security_solution/common/endpoint/generate_data.ts index 9cbe1e19530ca7..f9ecb2e018dff2 100644 --- a/x-pack/plugins/security_solution/common/endpoint/generate_data.ts +++ b/x-pack/plugins/security_solution/common/endpoint/generate_data.ts @@ -1600,7 +1600,7 @@ export class EndpointDocGenerator extends BaseDataGenerator { /** * Generate an EPM Package for Endpoint */ - public generateEpmPackage(): GetPackagesResponse['response'][0] { + public generateEpmPackage(): GetPackagesResponse['items'][0] { return { id: this.seededUUIDv4(), name: 'endpoint', diff --git a/x-pack/plugins/security_solution/common/endpoint/index_data.ts b/x-pack/plugins/security_solution/common/endpoint/index_data.ts index 5bb3bd3dbae52d..5c81196a3709cd 100644 --- a/x-pack/plugins/security_solution/common/endpoint/index_data.ts +++ b/x-pack/plugins/security_solution/common/endpoint/index_data.ts @@ -124,13 +124,13 @@ export async function indexHostsAndAlerts( const getEndpointPackageInfo = async ( kbnClient: KbnClient -): Promise => { +): Promise => { const endpointPackage = ( (await kbnClient.request({ path: `${EPM_API_ROUTES.LIST_PATTERN}?category=security`, method: 'GET', })) as AxiosResponse - ).data.response.find((epmPackage) => epmPackage.name === 'endpoint'); + ).data.items.find((epmPackage) => epmPackage.name === 'endpoint'); if (!endpointPackage) { throw new Error('EPM Endpoint package was not found!'); diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/mock_endpoint_result_list.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/mock_endpoint_result_list.ts index 1e8b55ef977e8e..6a18bf5e16759f 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/mock_endpoint_result_list.ts +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/mock_endpoint_result_list.ts @@ -92,7 +92,7 @@ const endpointListApiPathHandlerMocks = ({ }: { /** route handlers will be setup for each individual host in this array */ endpointsResults?: MetadataListResponse['data']; - epmPackages?: GetPackagesResponse['response']; + epmPackages?: GetPackagesResponse['items']; endpointPackagePolicies?: GetPolicyListResponse['items']; policyResponse?: HostPolicyResponse; agentPolicy?: GetAgentPoliciesResponseItem; @@ -103,7 +103,7 @@ const endpointListApiPathHandlerMocks = ({ // endpoint package info [INGEST_API_EPM_PACKAGES]: (): GetPackagesResponse => { return { - response: epmPackages, + items: epmPackages, }; }, @@ -150,7 +150,7 @@ const endpointListApiPathHandlerMocks = ({ [INGEST_API_FLEET_AGENTS]: (): GetAgentsResponse => { return { total: totalAgentsUsingEndpoint, - list: [], + items: [], totalInactive: 0, page: 1, perPage: 10, diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/types.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/types.ts index 0a5e1362edafe6..7757aa7f1329be 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/types.ts +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/types.ts @@ -78,7 +78,7 @@ export interface EndpointState { /** the selected policy ID in the onboarding flow */ selectedPolicyId?: string; /** Endpoint package info */ - endpointPackageInfo: AsyncResourceState; + endpointPackageInfo: AsyncResourceState; /** Tracks the list of policies IDs used in Host metadata that may no longer exist */ nonExistingPolicies: PolicyIds['packagePolicy']; /** List of Package Policy Ids mapped to an associated Fleet Parent Agent Policy Id*/ diff --git a/x-pack/plugins/security_solution/public/management/pages/mocks/fleet_mocks.ts b/x-pack/plugins/security_solution/public/management/pages/mocks/fleet_mocks.ts index f771a44e576397..f015943b994b5b 100644 --- a/x-pack/plugins/security_solution/public/management/pages/mocks/fleet_mocks.ts +++ b/x-pack/plugins/security_solution/public/management/pages/mocks/fleet_mocks.ts @@ -129,7 +129,7 @@ export const fleetGetPackageListHttpMock = const generator = new EndpointDocGenerator('seed'); return { - response: [generator.generateEpmPackage()], + items: [generator.generateEpmPackage()], }; }, }, diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/store/services/ingest.ts b/x-pack/plugins/security_solution/public/management/pages/policy/store/services/ingest.ts index 27b567c3bb38cc..651d5840116f0a 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/store/services/ingest.ts +++ b/x-pack/plugins/security_solution/public/management/pages/policy/store/services/ingest.ts @@ -21,7 +21,7 @@ import { NewPolicyData } from '../../../../../../common/endpoint/types'; const INGEST_API_ROOT = `/api/fleet`; export const INGEST_API_PACKAGE_POLICIES = `${INGEST_API_ROOT}/package_policies`; export const INGEST_API_AGENT_POLICIES = `${INGEST_API_ROOT}/agent_policies`; -const INGEST_API_FLEET_AGENT_STATUS = `${INGEST_API_ROOT}/agent-status`; +const INGEST_API_FLEET_AGENT_STATUS = `${INGEST_API_ROOT}/agent_status`; export const INGEST_API_FLEET_AGENTS = `${INGEST_API_ROOT}/agents`; export const INGEST_API_EPM_PACKAGES = `${INGEST_API_ROOT}/epm/packages`; const INGEST_API_DELETE_PACKAGE_POLICY = `${INGEST_API_PACKAGE_POLICIES}/delete`; @@ -135,10 +135,10 @@ export const sendGetFleetAgentsWithEndpoint = ( */ export const sendGetEndpointSecurityPackage = async ( http: HttpStart -): Promise => { +): Promise => { const options = { query: { category: 'security' } }; const securityPackages = await http.get(INGEST_API_EPM_PACKAGES, options); - const endpointPackageInfo = securityPackages.response.find( + const endpointPackageInfo = securityPackages.items.find( (epmPackage) => epmPackage.name === 'endpoint' ); if (!endpointPackageInfo) { diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/store/test_mock_utils.ts b/x-pack/plugins/security_solution/public/management/pages/policy/store/test_mock_utils.ts index 7ab46617dae3ec..785ba6f066ffbd 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/store/test_mock_utils.ts +++ b/x-pack/plugins/security_solution/public/management/pages/policy/store/test_mock_utils.ts @@ -57,7 +57,7 @@ export const policyListApiPathHandlers = (totalPolicies: number = 1) => { }, [INGEST_API_EPM_PACKAGES]: (): GetPackagesResponse => { return { - response: [generator.generateEpmPackage()], + items: [generator.generateEpmPackage()], }; }, }; diff --git a/x-pack/test/api_integration/apis/ml/modules/index.ts b/x-pack/test/api_integration/apis/ml/modules/index.ts index c842fdad81bef7..182de3e2648cba 100644 --- a/x-pack/test/api_integration/apis/ml/modules/index.ts +++ b/x-pack/test/api_integration/apis/ml/modules/index.ts @@ -12,7 +12,7 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { const ml = getService('ml'); const fleetPackages = ['apache', 'nginx']; - const installedPackages: string[] = []; + const installedPackages: Array<{ pkgName: string; version: string }> = []; describe('modules', function () { before(async () => { @@ -23,14 +23,14 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { await ml.testResources.setupFleet(); for (const fleetPackage of fleetPackages) { - const packageWithVersion = await ml.testResources.installFleetPackage(fleetPackage); - installedPackages.push(packageWithVersion); + const version = await ml.testResources.installFleetPackage(fleetPackage); + installedPackages.push({ pkgName: fleetPackage, version }); } }); after(async () => { for (const fleetPackage of installedPackages) { - await ml.testResources.removeFleetPackage(fleetPackage); + await ml.testResources.removeFleetPackage(fleetPackage.pkgName, fleetPackage.version); } await esArchiver.unload('x-pack/test/functional/es_archives/empty_kibana'); }); diff --git a/x-pack/test/fleet_api_integration/apis/agent_policy/agent_policy_with_agents_setup.ts b/x-pack/test/fleet_api_integration/apis/agent_policy/agent_policy_with_agents_setup.ts index 87bb8b7d1c913c..d5fe4b2463d4ca 100644 --- a/x-pack/test/fleet_api_integration/apis/agent_policy/agent_policy_with_agents_setup.ts +++ b/x-pack/test/fleet_api_integration/apis/agent_policy/agent_policy_with_agents_setup.ts @@ -21,15 +21,15 @@ export default function (providerContext: FtrProviderContext) { const esClient = getService('es'); async function getEnrollmentKeyForPolicyId(policyId: string) { - const listRes = await supertest.get(`/api/fleet/enrollment-api-keys`).expect(200); + const listRes = await supertest.get(`/api/fleet/enrollment_api_keys`).expect(200); - const key = listRes.body.list.find( + const key = listRes.body.items.find( (item: { policy_id: string; id: string }) => item.policy_id === policyId ); expect(key).not.empty(); - const res = await supertest.get(`/api/fleet/enrollment-api-keys/${key.id}`).expect(200); + const res = await supertest.get(`/api/fleet/enrollment_api_keys/${key.id}`).expect(200); return res.body.item; } diff --git a/x-pack/test/fleet_api_integration/apis/agents/list.ts b/x-pack/test/fleet_api_integration/apis/agents/list.ts index 3795734f60fe08..ef1efcf1a46565 100644 --- a/x-pack/test/fleet_api_integration/apis/agents/list.ts +++ b/x-pack/test/fleet_api_integration/apis/agents/list.ts @@ -39,12 +39,12 @@ export default function ({ getService }: FtrProviderContext) { it('should return the list of agents when requesting as a user with fleet write permissions', async () => { const { body: apiResponse } = await supertest.get(`/api/fleet/agents`).expect(200); - expect(apiResponse).to.have.keys('page', 'total', 'list'); + expect(apiResponse).to.have.keys('page', 'total', 'items', 'list'); expect(apiResponse.total).to.eql(4); }); it('should return the list of agents when requesting as a user with fleet read permissions', async () => { const { body: apiResponse } = await supertest.get(`/api/fleet/agents`).expect(200); - expect(apiResponse).to.have.keys('page', 'total', 'list'); + expect(apiResponse).to.have.keys('page', 'total', 'items', 'list'); expect(apiResponse.total).to.eql(4); }); @@ -66,7 +66,7 @@ export default function ({ getService }: FtrProviderContext) { .expect(200); expect(apiResponse.total).to.eql(1); - const agent = apiResponse.list[0]; + const agent = apiResponse.items[0]; expect(agent.access_api_key_id).to.eql('api-key-2'); }); }); diff --git a/x-pack/test/fleet_api_integration/apis/agents/reassign.ts b/x-pack/test/fleet_api_integration/apis/agents/reassign.ts index 6d2132577da97c..a2ef226eb3d852 100644 --- a/x-pack/test/fleet_api_integration/apis/agents/reassign.ts +++ b/x-pack/test/fleet_api_integration/apis/agents/reassign.ts @@ -190,7 +190,7 @@ export default function (providerContext: FtrProviderContext) { .expect(200); const { body } = await supertest.get(`/api/fleet/agents`).set('kbn-xsrf', 'xxx'); expect(body.total).to.eql(4); - body.list.forEach((agent: any) => { + body.items.forEach((agent: any) => { expect(agent.policy_id).to.eql('policy2'); }); }); diff --git a/x-pack/test/fleet_api_integration/apis/agents/status.ts b/x-pack/test/fleet_api_integration/apis/agents/status.ts index a20007cee1f6af..bbcdfb0f1c4c30 100644 --- a/x-pack/test/fleet_api_integration/apis/agents/status.ts +++ b/x-pack/test/fleet_api_integration/apis/agents/status.ts @@ -68,7 +68,7 @@ export default function ({ getService }: FtrProviderContext) { }); it('should return the status of agents', async () => { - const { body: apiResponse } = await supertest.get(`/api/fleet/agent-status`).expect(200); + const { body: apiResponse } = await supertest.get(`/api/fleet/agent_status`).expect(200); expect(apiResponse).to.eql({ results: { @@ -83,5 +83,9 @@ export default function ({ getService }: FtrProviderContext) { }, }); }); + + it('should work with deprecated api', async () => { + await supertest.get(`/api/fleet/agent-status`).expect(200); + }); }); } diff --git a/x-pack/test/fleet_api_integration/apis/data_streams/list.ts b/x-pack/test/fleet_api_integration/apis/data_streams/list.ts index 2b0098a76ac1f0..9a34b31bf421bc 100644 --- a/x-pack/test/fleet_api_integration/apis/data_streams/list.ts +++ b/x-pack/test/fleet_api_integration/apis/data_streams/list.ts @@ -21,17 +21,16 @@ export default function (providerContext: FtrProviderContext) { const retry = getService('retry'); const pkgName = 'datastreams'; const pkgVersion = '0.1.0'; - const pkgKey = `${pkgName}-${pkgVersion}`; const logsTemplateName = `logs-${pkgName}.test_logs`; const metricsTemplateName = `metrics-${pkgName}.test_metrics`; - const uninstallPackage = async (pkg: string) => { - await supertest.delete(`/api/fleet/epm/packages/${pkg}`).set('kbn-xsrf', 'xxxx'); + const uninstallPackage = async (name: string, version: string) => { + await supertest.delete(`/api/fleet/epm/packages/${name}/${version}`).set('kbn-xsrf', 'xxxx'); }; - const installPackage = async (pkg: string) => { + const installPackage = async (name: string, version: string) => { return await supertest - .post(`/api/fleet/epm/packages/${pkg}`) + .post(`/api/fleet/epm/packages/${name}/${version}`) .set('kbn-xsrf', 'xxxx') .send({ force: true }) .expect(200); @@ -91,11 +90,11 @@ export default function (providerContext: FtrProviderContext) { skipIfNoDockerRegistry(providerContext); beforeEach(async () => { - await installPackage(pkgKey); + await installPackage(pkgName, pkgVersion); }); afterEach(async () => { - await uninstallPackage(pkgKey); + await uninstallPackage(pkgName, pkgVersion); try { await es.transport.request({ method: 'DELETE', diff --git a/x-pack/test/fleet_api_integration/apis/enrollment_api_keys/crud.ts b/x-pack/test/fleet_api_integration/apis/enrollment_api_keys/crud.ts index d1d9ce70dcd25d..1c584315a1871a 100644 --- a/x-pack/test/fleet_api_integration/apis/enrollment_api_keys/crud.ts +++ b/x-pack/test/fleet_api_integration/apis/enrollment_api_keys/crud.ts @@ -31,33 +31,34 @@ export default function (providerContext: FtrProviderContext) { skipIfNoDockerRegistry(providerContext); setupFleetAndAgents(providerContext); - describe('GET /fleet/enrollment-api-keys', async () => { + describe('GET /fleet/enrollment_api_keys', async () => { it('should list existing api keys', async () => { const { body: apiResponse } = await supertest - .get(`/api/fleet/enrollment-api-keys`) + .get(`/api/fleet/enrollment_api_keys`) .expect(200); expect(apiResponse.total).to.be(3); - expect(apiResponse.list[0]).to.have.keys('id', 'api_key_id', 'name'); + expect(apiResponse.items[0]).to.have.keys('id', 'api_key_id', 'name'); + expect(apiResponse).to.have.keys('list'); }); }); - describe('GET /fleet/enrollment-api-keys/{id}', async () => { + describe('GET /fleet/enrollment_api_keys/{id}', async () => { it('should allow to retrieve existing api keys', async () => { const { body: apiResponse } = await supertest - .get(`/api/fleet/enrollment-api-keys/${ENROLLMENT_KEY_ID}`) + .get(`/api/fleet/enrollment_api_keys/${ENROLLMENT_KEY_ID}`) .expect(200); expect(apiResponse.item).to.have.keys('id', 'api_key_id', 'name'); }); }); - describe('DELETE /fleet/enrollment-api-keys/{id}', async () => { + describe('DELETE /fleet/enrollment_api_keys/{id}', async () => { let keyId: string; let esApiKeyId: string; before(async () => { const { body: apiResponse } = await supertest - .post(`/api/fleet/enrollment-api-keys`) + .post(`/api/fleet/enrollment_api_keys`) .set('kbn-xsrf', 'xxx') .send({ policy_id: 'policy1', @@ -69,7 +70,7 @@ export default function (providerContext: FtrProviderContext) { it('should invalide an existing api keys', async () => { await supertest - .delete(`/api/fleet/enrollment-api-keys/${keyId}`) + .delete(`/api/fleet/enrollment_api_keys/${keyId}`) .set('kbn-xsrf', 'xxx') .expect(200); @@ -80,10 +81,10 @@ export default function (providerContext: FtrProviderContext) { }); }); - describe('POST /fleet/enrollment-api-keys', () => { + describe('POST /fleet/enrollment_api_keys', () => { it('should not accept bad parameters', async () => { await supertest - .post(`/api/fleet/enrollment-api-keys`) + .post(`/api/fleet/enrollment_api_keys`) .set('kbn-xsrf', 'xxx') .send({ raoul: 'raoul', @@ -93,7 +94,7 @@ export default function (providerContext: FtrProviderContext) { it('should return a 400 if the fleet admin user is modifed outside of Fleet', async () => { await supertest - .post(`/api/fleet/enrollment-api-keys`) + .post(`/api/fleet/enrollment_api_keys`) .set('kbn-xsrf', 'xxx') .send({ raoul: 'raoul', @@ -103,7 +104,7 @@ export default function (providerContext: FtrProviderContext) { it('should allow to create an enrollment api key with only an agent policy', async () => { const { body: apiResponse } = await supertest - .post(`/api/fleet/enrollment-api-keys`) + .post(`/api/fleet/enrollment_api_keys`) .set('kbn-xsrf', 'xxx') .send({ policy_id: 'policy1', @@ -115,7 +116,7 @@ export default function (providerContext: FtrProviderContext) { it('should allow to create an enrollment api key with agent policy and unique name', async () => { const { body: noSpacesRes } = await supertest - .post(`/api/fleet/enrollment-api-keys`) + .post(`/api/fleet/enrollment_api_keys`) .set('kbn-xsrf', 'xxx') .send({ policy_id: 'policy1', @@ -124,7 +125,7 @@ export default function (providerContext: FtrProviderContext) { expect(noSpacesRes.item).to.have.keys('id', 'api_key', 'api_key_id', 'name', 'policy_id'); const { body: hasSpacesRes } = await supertest - .post(`/api/fleet/enrollment-api-keys`) + .post(`/api/fleet/enrollment_api_keys`) .set('kbn-xsrf', 'xxx') .send({ policy_id: 'policy1', @@ -133,7 +134,7 @@ export default function (providerContext: FtrProviderContext) { expect(hasSpacesRes.item).to.have.keys('id', 'api_key', 'api_key_id', 'name', 'policy_id'); const { body: noSpacesDupe } = await supertest - .post(`/api/fleet/enrollment-api-keys`) + .post(`/api/fleet/enrollment_api_keys`) .set('kbn-xsrf', 'xxx') .send({ policy_id: 'policy1', @@ -148,7 +149,7 @@ export default function (providerContext: FtrProviderContext) { }); const { body: hasSpacesDupe } = await supertest - .post(`/api/fleet/enrollment-api-keys`) + .post(`/api/fleet/enrollment_api_keys`) .set('kbn-xsrf', 'xxx') .send({ policy_id: 'policy1', @@ -164,7 +165,7 @@ export default function (providerContext: FtrProviderContext) { it('should create an ES ApiKey with metadata', async () => { const { body: apiResponse } = await supertest - .post(`/api/fleet/enrollment-api-keys`) + .post(`/api/fleet/enrollment_api_keys`) .set('kbn-xsrf', 'xxx') .send({ policy_id: 'policy1', @@ -185,7 +186,7 @@ export default function (providerContext: FtrProviderContext) { it('should create an ES ApiKey with limited privileges', async () => { const { body: apiResponse } = await supertest - .post(`/api/fleet/enrollment-api-keys`) + .post(`/api/fleet/enrollment_api_keys`) .set('kbn-xsrf', 'xxx') .send({ policy_id: 'policy1', @@ -234,5 +235,29 @@ export default function (providerContext: FtrProviderContext) { }); }); }); + + describe('deprecated API', () => { + let keyId: string; + before(async () => { + const { body: apiResponse } = await supertest + .post(`/api/fleet/enrollment-api-keys`) + .set('kbn-xsrf', 'xxx') + .send({ + policy_id: 'policy1', + }) + .expect(200); + keyId = apiResponse.item.id; + }); + + it('should get and delete with deprecated API', async () => { + await supertest.get(`/api/fleet/enrollment-api-keys`).expect(200); + await supertest.get(`/api/fleet/enrollment-api-keys/${ENROLLMENT_KEY_ID}`).expect(200); + + await supertest + .delete(`/api/fleet/enrollment-api-keys/${keyId}`) + .set('kbn-xsrf', 'xxx') + .expect(200); + }); + }); }); } diff --git a/x-pack/test/fleet_api_integration/apis/epm/bulk_upgrade.ts b/x-pack/test/fleet_api_integration/apis/epm/bulk_upgrade.ts index 3b3ccb03e56f32..a51ac1c9803be2 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/bulk_upgrade.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/bulk_upgrade.ts @@ -21,8 +21,8 @@ export default function (providerContext: FtrProviderContext) { const supertest = getService('supertest'); const supertestWithoutAuth = getService('supertestWithoutAuth'); - const deletePackage = async (pkgkey: string) => { - await supertest.delete(`/api/fleet/epm/packages/${pkgkey}`).set('kbn-xsrf', 'xxxx'); + const deletePackage = async (name: string, version: string) => { + await supertest.delete(`/api/fleet/epm/packages/${name}/${version}`).set('kbn-xsrf', 'xxxx'); }; describe('bulk package upgrade api', async () => { @@ -32,15 +32,15 @@ export default function (providerContext: FtrProviderContext) { describe('bulk package upgrade with a package already installed', async () => { beforeEach(async () => { await supertest - .post(`/api/fleet/epm/packages/multiple_versions-0.1.0`) + .post(`/api/fleet/epm/packages/multiple_versions/0.1.0`) .set('kbn-xsrf', 'xxxx') .send({ force: true }) .expect(200); }); afterEach(async () => { - await deletePackage('multiple_versions-0.1.0'); - await deletePackage('multiple_versions-0.3.0'); - await deletePackage('overrides-0.1.0'); + await deletePackage('multiple_versions', '0.1.0'); + await deletePackage('multiple_versions', '0.3.0'); + await deletePackage('overrides', '0.1.0'); }); it('should return 400 if no packages are requested for upgrade', async function () { @@ -59,9 +59,9 @@ export default function (providerContext: FtrProviderContext) { .set('kbn-xsrf', 'xxxx') .send({ packages: ['multiple_versions'] }) .expect(200); - expect(body.response.length).equal(1); - expect(body.response[0].name).equal('multiple_versions'); - const entry = body.response[0] as BulkInstallPackageInfo; + expect(body.items.length).equal(1); + expect(body.items[0].name).equal('multiple_versions'); + const entry = body.items[0] as BulkInstallPackageInfo; expect(entry.version).equal('0.3.0'); }); it('should return an error for packages that do not exist', async function () { @@ -70,14 +70,14 @@ export default function (providerContext: FtrProviderContext) { .set('kbn-xsrf', 'xxxx') .send({ packages: ['multiple_versions', 'blahblah'] }) .expect(200); - expect(body.response.length).equal(2); - expect(body.response[0].name).equal('multiple_versions'); - const entry = body.response[0] as BulkInstallPackageInfo; + expect(body.items.length).equal(2); + expect(body.items[0].name).equal('multiple_versions'); + const entry = body.items[0] as BulkInstallPackageInfo; expect(entry.version).equal('0.3.0'); - const err = body.response[1] as IBulkInstallPackageHTTPError; + const err = body.items[1] as IBulkInstallPackageHTTPError; expect(err.statusCode).equal(404); - expect(body.response[1].name).equal('blahblah'); + expect(body.items[1].name).equal('blahblah'); }); it('should upgrade multiple packages', async function () { const { body }: { body: BulkInstallPackagesResponse } = await supertest @@ -85,12 +85,12 @@ export default function (providerContext: FtrProviderContext) { .set('kbn-xsrf', 'xxxx') .send({ packages: ['multiple_versions', 'overrides'] }) .expect(200); - expect(body.response.length).equal(2); - expect(body.response[0].name).equal('multiple_versions'); - let entry = body.response[0] as BulkInstallPackageInfo; + expect(body.items.length).equal(2); + expect(body.items[0].name).equal('multiple_versions'); + let entry = body.items[0] as BulkInstallPackageInfo; expect(entry.version).equal('0.3.0'); - entry = body.response[1] as BulkInstallPackageInfo; + entry = body.items[1] as BulkInstallPackageInfo; expect(entry.version).equal('0.1.0'); expect(entry.name).equal('overrides'); }); @@ -98,7 +98,7 @@ export default function (providerContext: FtrProviderContext) { describe('bulk upgrade without package already installed', async () => { afterEach(async () => { - await deletePackage('multiple_versions-0.3.0'); + await deletePackage('multiple_versions', '0.3.0'); }); it('should return 200 and an array for upgrading a package', async function () { @@ -107,9 +107,9 @@ export default function (providerContext: FtrProviderContext) { .set('kbn-xsrf', 'xxxx') .send({ packages: ['multiple_versions'] }) .expect(200); - expect(body.response.length).equal(1); - expect(body.response[0].name).equal('multiple_versions'); - const entry = body.response[0] as BulkInstallPackageInfo; + expect(body.items.length).equal(1); + expect(body.items[0].name).equal('multiple_versions'); + const entry = body.items[0] as BulkInstallPackageInfo; expect(entry.version).equal('0.3.0'); }); }); diff --git a/x-pack/test/fleet_api_integration/apis/epm/data_stream.ts b/x-pack/test/fleet_api_integration/apis/epm/data_stream.ts index 9cdc21943a312f..466f150ec1e058 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/data_stream.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/data_stream.ts @@ -18,18 +18,16 @@ export default function (providerContext: FtrProviderContext) { const pkgName = 'datastreams'; const pkgVersion = '0.1.0'; const pkgUpdateVersion = '0.2.0'; - const pkgKey = `${pkgName}-${pkgVersion}`; - const pkgUpdateKey = `${pkgName}-${pkgUpdateVersion}`; const logsTemplateName = `logs-${pkgName}.test_logs`; const metricsTemplateName = `metrics-${pkgName}.test_metrics`; const namespaces = ['default', 'foo', 'bar']; - const uninstallPackage = async (pkg: string) => { - await supertest.delete(`/api/fleet/epm/packages/${pkg}`).set('kbn-xsrf', 'xxxx'); + const uninstallPackage = async (name: string, version: string) => { + await supertest.delete(`/api/fleet/epm/packages/${name}/${version}`).set('kbn-xsrf', 'xxxx'); }; - const installPackage = async (pkg: string) => { + const installPackage = async (name: string, version: string) => { return await supertest - .post(`/api/fleet/epm/packages/${pkg}`) + .post(`/api/fleet/epm/packages/${name}/${version}`) .set('kbn-xsrf', 'xxxx') .send({ force: true }) .expect(200); @@ -40,7 +38,7 @@ export default function (providerContext: FtrProviderContext) { setupFleetAndAgents(providerContext); beforeEach(async () => { - await installPackage(pkgKey); + await installPackage(pkgName, pkgVersion); await Promise.all( namespaces.map(async (namespace) => { const createLogsRequest = es.transport.request( @@ -100,8 +98,8 @@ export default function (providerContext: FtrProviderContext) { return Promise.all([deleteLogsRequest, deleteMetricsRequest]); }) ); - await uninstallPackage(pkgKey); - await uninstallPackage(pkgUpdateKey); + await uninstallPackage(pkgName, pkgVersion); + await uninstallPackage(pkgName, pkgUpdateVersion); }); it('should list the logs and metrics datastream', async function () { @@ -128,7 +126,7 @@ export default function (providerContext: FtrProviderContext) { }); it('after update, it should have rolled over logs datastream because mappings are not compatible and not metrics', async function () { - await installPackage(pkgUpdateKey); + await installPackage(pkgName, pkgUpdateVersion); await asyncForEach(namespaces, async (namespace) => { const resLogsDatastream = await es.transport.request( { @@ -167,7 +165,7 @@ export default function (providerContext: FtrProviderContext) { ); expect(resLogsDatastream.body.data_streams[0].indices.length).equal(2); }); - await installPackage(pkgUpdateKey); + await installPackage(pkgName, pkgUpdateVersion); }); }); } diff --git a/x-pack/test/fleet_api_integration/apis/epm/delete.ts b/x-pack/test/fleet_api_integration/apis/epm/delete.ts index 9980d85ac171ef..5e839e51113c4c 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/delete.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/delete.ts @@ -14,18 +14,19 @@ export default function (providerContext: FtrProviderContext) { const { getService } = providerContext; const supertest = getService('supertest'); const supertestWithoutAuth = getService('supertestWithoutAuth'); - const requiredPackage = 'elastic_agent-0.0.7'; + const requiredPackage = 'elastic_agent'; + const pkgVersion = '0.0.7'; - const installPackage = async (pkgkey: string) => { + const installPackage = async (name: string, version: string) => { await supertest - .post(`/api/fleet/epm/packages/${pkgkey}`) + .post(`/api/fleet/epm/packages/${name}/${version}`) .set('kbn-xsrf', 'xxxx') .send({ force: true }); }; - const deletePackage = async (pkgkey: string) => { + const deletePackage = async (name: string, version: string) => { await supertest - .delete(`/api/fleet/epm/packages/${pkgkey}`) + .delete(`/api/fleet/epm/packages/${name}/${version}`) .set('kbn-xsrf', 'xxxx') .send({ force: true }); }; @@ -34,22 +35,22 @@ export default function (providerContext: FtrProviderContext) { skipIfNoDockerRegistry(providerContext); setupFleetAndAgents(providerContext); before(async () => { - await installPackage(requiredPackage); + await installPackage(requiredPackage, pkgVersion); }); after(async () => { - await deletePackage(requiredPackage); + await deletePackage(requiredPackage, pkgVersion); }); it('should return 400 if trying to uninstall a required package', async function () { await supertest - .delete(`/api/fleet/epm/packages/${requiredPackage}`) + .delete(`/api/fleet/epm/packages/${requiredPackage}/${pkgVersion}`) .set('kbn-xsrf', 'xxxx') .expect(400); }); it('should return 200 if trying to force uninstall a required package', async function () { await supertest - .delete(`/api/fleet/epm/packages/${requiredPackage}`) + .delete(`/api/fleet/epm/packages/${requiredPackage}/${pkgVersion}`) .set('kbn-xsrf', 'xxxx') .send({ force: true }) .expect(200); @@ -57,7 +58,7 @@ export default function (providerContext: FtrProviderContext) { it('should return 403 for read-only users', async () => { await supertestWithoutAuth - .delete(`/api/fleet/epm/packages/${requiredPackage}`) + .delete(`/api/fleet/epm/packages/${requiredPackage}/${pkgVersion}`) .auth(testUsers.fleet_read_only.username, testUsers.fleet_read_only.password) .set('kbn-xsrf', 'xxxx') .expect(403); diff --git a/x-pack/test/fleet_api_integration/apis/epm/file.ts b/x-pack/test/fleet_api_integration/apis/epm/file.ts index aade350ecacf9f..7dec9456bf5f16 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/file.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/file.ts @@ -103,7 +103,7 @@ export default function ({ getService }: FtrProviderContext) { }); after(async () => { if (!server.enabled) return; - await supertest.delete(`/api/fleet/epm/packages/apache-0.1.4`).set('kbn-xsrf', 'xxxx'); + await supertest.delete(`/api/fleet/epm/packages/apache/0.1.4`).set('kbn-xsrf', 'xxxx'); }); it('fetches a .png screenshot image', async function () { if (server.enabled) { diff --git a/x-pack/test/fleet_api_integration/apis/epm/final_pipeline.ts b/x-pack/test/fleet_api_integration/apis/epm/final_pipeline.ts index 3d413a280b521f..8d606d2afc2c10 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/final_pipeline.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/final_pipeline.ts @@ -16,7 +16,7 @@ const FINAL_PIPELINE_ID = '.fleet_final_pipeline-1'; const FINAL_PIPELINE_VERSION = 1; -let pkgKey: string; +let pkgVersion: string; export default function (providerContext: FtrProviderContext) { const { getService } = providerContext; @@ -45,22 +45,22 @@ export default function (providerContext: FtrProviderContext) { const { body: getPackagesRes } = await supertest.get( `/api/fleet/epm/packages?experimental=true` ); - const logPackage = getPackagesRes.response.find((p: any) => p.name === 'log'); + const logPackage = getPackagesRes.items.find((p: any) => p.name === 'log'); if (!logPackage) { throw new Error('No log package'); } - pkgKey = `log-${logPackage.version}`; + pkgVersion = logPackage.version; await supertest - .post(`/api/fleet/epm/packages/${pkgKey}`) + .post(`/api/fleet/epm/packages/log/${pkgVersion}`) .set('kbn-xsrf', 'xxxx') .send({ force: true }) .expect(200); }); after(async () => { await supertest - .delete(`/api/fleet/epm/packages/${pkgKey}`) + .delete(`/api/fleet/epm/packages/log/${pkgVersion}`) .set('kbn-xsrf', 'xxxx') .send({ force: true }) .expect(200); diff --git a/x-pack/test/fleet_api_integration/apis/epm/get.ts b/x-pack/test/fleet_api_integration/apis/epm/get.ts index 13533a9a82af00..71a359c10c2a58 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/get.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/get.ts @@ -19,14 +19,15 @@ export default function (providerContext: FtrProviderContext) { const supertest = getService('supertest'); const supertestWithoutAuth = getService('supertestWithoutAuth'); - const testPkgKey = 'apache-0.1.4'; + const testPkgName = 'apache'; + const testPkgVersion = '0.1.4'; - const uninstallPackage = async (pkg: string) => { - await supertest.delete(`/api/fleet/epm/packages/${pkg}`).set('kbn-xsrf', 'xxxx'); + const uninstallPackage = async (name: string, version: string) => { + await supertest.delete(`/api/fleet/epm/packages/${name}/${version}`).set('kbn-xsrf', 'xxxx'); }; - const installPackage = async (pkg: string) => { + const installPackage = async (name: string, version: string) => { await supertest - .post(`/api/fleet/epm/packages/${pkg}`) + .post(`/api/fleet/epm/packages/${name}/${version}`) .set('kbn-xsrf', 'xxxx') .send({ force: true }); }; @@ -41,14 +42,16 @@ export default function (providerContext: FtrProviderContext) { setupFleetAndAgents(providerContext); it('returns package info from the registry if it was installed from the registry', async function () { // this will install through the registry by default - await installPackage(testPkgKey); - const res = await supertest.get(`/api/fleet/epm/packages/${testPkgKey}`).expect(200); - const packageInfo = res.body.response; + await installPackage(testPkgName, testPkgVersion); + const res = await supertest + .get(`/api/fleet/epm/packages/${testPkgName}/${testPkgVersion}`) + .expect(200); + const packageInfo = res.body.item; // the uploaded version will have this description expect(packageInfo.description).to.not.equal('Apache Uploaded Test Integration'); // download property should exist expect(packageInfo.download).to.not.equal(undefined); - await uninstallPackage(testPkgKey); + await uninstallPackage(testPkgName, testPkgVersion); }); it('returns correct package info if it was installed by upload', async function () { const buf = fs.readFileSync(testPkgArchiveZip); @@ -59,13 +62,15 @@ export default function (providerContext: FtrProviderContext) { .send(buf) .expect(200); - const res = await supertest.get(`/api/fleet/epm/packages/${testPkgKey}`).expect(200); - const packageInfo = res.body.response; + const res = await supertest + .get(`/api/fleet/epm/packages/${testPkgName}/${testPkgVersion}`) + .expect(200); + const packageInfo = res.body.item; // the uploaded version will have this description expect(packageInfo.description).to.equal('Apache Uploaded Test Integration'); // download property should not exist on uploaded packages expect(packageInfo.download).to.equal(undefined); - await uninstallPackage(testPkgKey); + await uninstallPackage(testPkgName, testPkgVersion); }); it('returns correct package info from registry if a different version is installed by upload', async function () { const buf = fs.readFileSync(testPkgArchiveZip); @@ -76,27 +81,24 @@ export default function (providerContext: FtrProviderContext) { .send(buf) .expect(200); - const res = await supertest.get(`/api/fleet/epm/packages/apache-0.1.3`).expect(200); - const packageInfo = res.body.response; + const res = await supertest.get(`/api/fleet/epm/packages/apache/0.1.3`).expect(200); + const packageInfo = res.body.item; expect(packageInfo.description).to.equal('Apache Integration'); expect(packageInfo.download).to.not.equal(undefined); - await uninstallPackage(testPkgKey); - }); - it('returns a 400 for a package key without a proper name', async function () { - await supertest.get('/api/fleet/epm/packages/-0.1.0').expect(400); + await uninstallPackage(testPkgName, testPkgVersion); }); it('returns a 404 for a package that do not exists', async function () { - await supertest.get('/api/fleet/epm/packages/notexists-99.99.99').expect(404); + await supertest.get('/api/fleet/epm/packages/notexists/99.99.99').expect(404); }); it('returns a 400 for a package key without a proper semver version', async function () { - await supertest.get('/api/fleet/epm/packages/endpoint-0.1.0.1.2.3').expect(400); + await supertest.get('/api/fleet/epm/packages/endpoint/0.1.0.1.2.3').expect(400); }); it('allows user with only read permission to access', async () => { await supertestWithoutAuth - .get(`/api/fleet/epm/packages/${testPkgKey}`) + .get(`/api/fleet/epm/packages/${testPkgName}/${testPkgVersion}`) .auth(testUsers.fleet_read_only.username, testUsers.fleet_read_only.password) .expect(200); }); diff --git a/x-pack/test/fleet_api_integration/apis/epm/install_by_upload.ts b/x-pack/test/fleet_api_integration/apis/epm/install_by_upload.ts index 85f4cb6193d60d..1ac5f2750fc98f 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/install_by_upload.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/install_by_upload.ts @@ -49,11 +49,12 @@ export default function (providerContext: FtrProviderContext) { '../fixtures/direct_upload_packages/apache_invalid_toplevel_mismatch_0.1.4.zip' ); - const testPkgKey = 'apache-0.1.4'; + const testPkgName = 'apache'; + const testPkgVersion = '0.1.4'; const server = dockerServers.get('registry'); - const deletePackage = async (pkgkey: string) => { - await supertest.delete(`/api/fleet/epm/packages/${pkgkey}`).set('kbn-xsrf', 'xxxx'); + const deletePackage = async (name: string, version: string) => { + await supertest.delete(`/api/fleet/epm/packages/${name}/${version}`).set('kbn-xsrf', 'xxxx'); }; describe('installs packages from direct upload', async () => { @@ -62,7 +63,7 @@ export default function (providerContext: FtrProviderContext) { afterEach(async () => { if (server) { // remove the packages just in case it being installed will affect other tests - await deletePackage(testPkgKey); + await deletePackage(testPkgName, testPkgVersion); } }); @@ -74,7 +75,7 @@ export default function (providerContext: FtrProviderContext) { .type('application/gzip') .send(buf) .expect(200); - expect(res.body.response.length).to.be(27); + expect(res.body.items.length).to.be(27); }); it('should install a zip archive correctly and package info should return correctly after validation', async function () { @@ -85,21 +86,21 @@ export default function (providerContext: FtrProviderContext) { .type('application/zip') .send(buf) .expect(200); - expect(res.body.response.length).to.be(27); + expect(res.body.items.length).to.be(27); const packageInfoRes = await supertest - .get(`/api/fleet/epm/packages/${testPkgKey}`) + .get(`/api/fleet/epm/packages/${testPkgName}/${testPkgVersion}`) .set('kbn-xsrf', 'xxxx') .expect(200); - delete packageInfoRes.body.response.latestVersion; - delete packageInfoRes.body.response.savedObject.attributes.install_started_at; - delete packageInfoRes.body.response.savedObject.version; - delete packageInfoRes.body.response.savedObject.updated_at; - delete packageInfoRes.body.response.savedObject.coreMigrationVersion; - delete packageInfoRes.body.response.savedObject.migrationVersion; + delete packageInfoRes.body.item.latestVersion; + delete packageInfoRes.body.item.savedObject.attributes.install_started_at; + delete packageInfoRes.body.item.savedObject.version; + delete packageInfoRes.body.item.savedObject.updated_at; + delete packageInfoRes.body.item.savedObject.coreMigrationVersion; + delete packageInfoRes.body.item.savedObject.migrationVersion; - expectSnapshot(packageInfoRes.body.response).toMatch(); + expectSnapshot(packageInfoRes.body.item).toMatch(); }); it('should throw an error if the archive is zip but content type is gzip', async function () { diff --git a/x-pack/test/fleet_api_integration/apis/epm/install_endpoint.ts b/x-pack/test/fleet_api_integration/apis/epm/install_endpoint.ts index e3e0fda58e2305..2ba688dfb8bf53 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/install_endpoint.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/install_endpoint.ts @@ -72,13 +72,13 @@ export default function (providerContext: FtrProviderContext) { }); }); - const uninstallPackage = async (pkg: string) => - supertest.delete(`/api/fleet/epm/packages/${pkg}`).set('kbn-xsrf', 'xxxx'); + const uninstallPackage = async (pkg: string, version: string) => + supertest.delete(`/api/fleet/epm/packages/${pkg}/${version}`).set('kbn-xsrf', 'xxxx'); // Endpoint doesn't currently support uninstalls describe.skip('uninstall', () => { before(async () => { - await uninstallPackage(`${pkgName}-${pkgVersion}`); + await uninstallPackage(pkgName, pkgVersion); }); transforms.forEach((transform) => { diff --git a/x-pack/test/fleet_api_integration/apis/epm/install_error_rollback.ts b/x-pack/test/fleet_api_integration/apis/epm/install_error_rollback.ts index f518b8a4035ca5..9a49958d31d34c 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/install_error_rollback.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/install_error_rollback.ts @@ -14,18 +14,19 @@ export default function (providerContext: FtrProviderContext) { const { getService } = providerContext; const supertest = getService('supertest'); const esArchiver = getService('esArchiver'); - const goodPackage = 'error_handling-0.1.0'; - const badPackage = 'error_handling-0.2.0'; + const pkgName = 'error_handling'; + const goodPackageVersion = '0.1.0'; + const badPackageVersion = '0.2.0'; - const installPackage = async (pkgkey: string) => { + const installPackage = async (pkg: string, version: string) => { await supertest - .post(`/api/fleet/epm/packages/${pkgkey}`) + .post(`/api/fleet/epm/packages/${pkg}/${version}`) .set('kbn-xsrf', 'xxxx') .send({ force: true }); }; - const getPackageInfo = async (pkgkey: string) => { - return await supertest.get(`/api/fleet/epm/packages/${pkgkey}`).set('kbn-xsrf', 'xxxx'); + const getPackageInfo = async (pkg: string, version: string) => { + return await supertest.get(`/api/fleet/epm/packages/${pkg}/${version}`).set('kbn-xsrf', 'xxxx'); }; describe('package installation error handling and rollback', async () => { @@ -40,24 +41,24 @@ export default function (providerContext: FtrProviderContext) { it('on a fresh install, it should uninstall a broken package during rollback', async function () { await supertest - .post(`/api/fleet/epm/packages/${badPackage}`) + .post(`/api/fleet/epm/packages/${pkgName}/${badPackageVersion}`) .set('kbn-xsrf', 'xxxx') .expect(422); // the broken package contains a broken visualization triggering a 422 from Kibana - const pkgInfoResponse = await getPackageInfo(badPackage); - expect(JSON.parse(pkgInfoResponse.text).response.status).to.be('not_installed'); + const pkgInfoResponse = await getPackageInfo(pkgName, badPackageVersion); + expect(JSON.parse(pkgInfoResponse.text).item.status).to.be('not_installed'); }); it('on an upgrade, it should fall back to the previous good version during rollback', async function () { - await installPackage(goodPackage); + await installPackage(pkgName, goodPackageVersion); await supertest - .post(`/api/fleet/epm/packages/${badPackage}`) + .post(`/api/fleet/epm/packages/${pkgName}/${badPackageVersion}`) .set('kbn-xsrf', 'xxxx') .expect(422); // the broken package contains a broken visualization triggering a 422 from Kibana - const goodPkgInfoResponse = await getPackageInfo(goodPackage); - expect(JSON.parse(goodPkgInfoResponse.text).response.status).to.be('installed'); - expect(JSON.parse(goodPkgInfoResponse.text).response.version).to.be('0.1.0'); + const goodPkgInfoResponse = await getPackageInfo(pkgName, goodPackageVersion); + expect(JSON.parse(goodPkgInfoResponse.text).item.status).to.be('installed'); + expect(JSON.parse(goodPkgInfoResponse.text).item.version).to.be('0.1.0'); }); }); } diff --git a/x-pack/test/fleet_api_integration/apis/epm/install_overrides.ts b/x-pack/test/fleet_api_integration/apis/epm/install_overrides.ts index 9e8bab3854b547..04477d9f089351 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/install_overrides.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/install_overrides.ts @@ -16,11 +16,12 @@ export default function (providerContext: FtrProviderContext) { const es = getService('es'); const dockerServers = getService('dockerServers'); - const mappingsPackage = 'overrides-0.1.0'; + const mappingsPackage = 'overrides'; + const mappingsPackageVersion = '0.1.0'; const server = dockerServers.get('registry'); - const deletePackage = async (pkgkey: string) => - supertest.delete(`/api/fleet/epm/packages/${pkgkey}`).set('kbn-xsrf', 'xxxx'); + const deletePackage = async (pkg: string, version: string) => + supertest.delete(`/api/fleet/epm/packages/${pkg}/${version}`).set('kbn-xsrf', 'xxxx'); describe('installs packages that include settings and mappings overrides', async () => { skipIfNoDockerRegistry(providerContext); @@ -28,17 +29,17 @@ export default function (providerContext: FtrProviderContext) { after(async () => { if (server.enabled) { // remove the package just in case it being installed will affect other tests - await deletePackage(mappingsPackage); + await deletePackage(mappingsPackage, mappingsPackageVersion); } }); it('should install the overrides package correctly', async function () { let { body } = await supertest - .post(`/api/fleet/epm/packages/${mappingsPackage}`) + .post(`/api/fleet/epm/packages/${mappingsPackage}/${mappingsPackageVersion}`) .set('kbn-xsrf', 'xxxx') .expect(200); - const templateName = body.response[0].id; + const templateName = body.items[0].id; const { body: indexTemplateResponse } = await es.transport.request( { diff --git a/x-pack/test/fleet_api_integration/apis/epm/install_prerelease.ts b/x-pack/test/fleet_api_integration/apis/epm/install_prerelease.ts index 6095fc7b387656..f375c9902317f0 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/install_prerelease.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/install_prerelease.ts @@ -14,11 +14,12 @@ export default function (providerContext: FtrProviderContext) { const supertest = getService('supertest'); const dockerServers = getService('dockerServers'); - const testPackage = 'prerelease-0.1.0-dev.0+abc'; + const testPackage = 'prerelease'; + const testPackageVersion = '0.1.0-dev.0+abc'; const server = dockerServers.get('registry'); - const deletePackage = async (pkgkey: string) => { - await supertest.delete(`/api/fleet/epm/packages/${pkgkey}`).set('kbn-xsrf', 'xxxx'); + const deletePackage = async (pkg: string, version: string) => { + await supertest.delete(`/api/fleet/epm/packages/${pkg}/${version}`).set('kbn-xsrf', 'xxxx'); }; describe('installs package that has a prerelease version', async () => { @@ -27,13 +28,13 @@ export default function (providerContext: FtrProviderContext) { after(async () => { if (server.enabled) { // remove the package just in case it being installed will affect other tests - await deletePackage(testPackage); + await deletePackage(testPackage, testPackageVersion); } }); it('should install the package correctly', async function () { await supertest - .post(`/api/fleet/epm/packages/${testPackage}`) + .post(`/api/fleet/epm/packages/${testPackage}/${testPackageVersion}`) .set('kbn-xsrf', 'xxxx') .expect(200); }); diff --git a/x-pack/test/fleet_api_integration/apis/epm/install_remove_assets.ts b/x-pack/test/fleet_api_integration/apis/epm/install_remove_assets.ts index e553ee35a6eb69..4c6976c4632170 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/install_remove_assets.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/install_remove_assets.ts @@ -21,16 +21,15 @@ export default function (providerContext: FtrProviderContext) { const es: Client = getService('es'); const pkgName = 'all_assets'; const pkgVersion = '0.1.0'; - const pkgKey = `${pkgName}-${pkgVersion}`; const logsTemplateName = `logs-${pkgName}.test_logs`; const metricsTemplateName = `metrics-${pkgName}.test_metrics`; - const uninstallPackage = async (pkg: string) => { - await supertest.delete(`/api/fleet/epm/packages/${pkg}`).set('kbn-xsrf', 'xxxx'); + const uninstallPackage = async (pkg: string, version: string) => { + await supertest.delete(`/api/fleet/epm/packages/${pkg}/${version}`).set('kbn-xsrf', 'xxxx'); }; - const installPackage = async (pkg: string) => { + const installPackage = async (pkg: string, version: string) => { await supertest - .post(`/api/fleet/epm/packages/${pkg}`) + .post(`/api/fleet/epm/packages/${pkg}/${version}`) .set('kbn-xsrf', 'xxxx') .send({ force: true }); }; @@ -42,11 +41,11 @@ export default function (providerContext: FtrProviderContext) { describe('installs all assets when installing a package for the first time', async () => { before(async () => { if (!server.enabled) return; - await installPackage(pkgKey); + await installPackage(pkgName, pkgVersion); }); after(async () => { if (!server.enabled) return; - await uninstallPackage(pkgKey); + await uninstallPackage(pkgName, pkgVersion); }); expectAssetsInstalled({ logsTemplateName, @@ -63,8 +62,8 @@ export default function (providerContext: FtrProviderContext) { if (!server.enabled) return; // these tests ensure that uninstall works properly so make sure that the package gets installed and uninstalled // and then we'll test that not artifacts are left behind. - await installPackage(pkgKey); - await uninstallPackage(pkgKey); + await installPackage(pkgName, pkgVersion); + await uninstallPackage(pkgName, pkgVersion); }); it('should have uninstalled the index templates', async function () { const resLogsTemplate = await es.transport.request( @@ -272,13 +271,13 @@ export default function (providerContext: FtrProviderContext) { describe('reinstalls all assets', async () => { before(async () => { if (!server.enabled) return; - await installPackage(pkgKey); + await installPackage(pkgName, pkgVersion); // reinstall - await installPackage(pkgKey); + await installPackage(pkgName, pkgVersion); }); after(async () => { if (!server.enabled) return; - await uninstallPackage(pkgKey); + await uninstallPackage(pkgName, pkgVersion); }); expectAssetsInstalled({ logsTemplateName, diff --git a/x-pack/test/fleet_api_integration/apis/epm/install_remove_multiple.ts b/x-pack/test/fleet_api_integration/apis/epm/install_remove_multiple.ts index b3c70539579c5a..ed8c16e79b0a0a 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/install_remove_multiple.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/install_remove_multiple.ts @@ -20,13 +20,10 @@ export default function (providerContext: FtrProviderContext) { const server = dockerServers.get('registry'); const pkgName = 'all_assets'; const pkgVersion = '0.1.0'; - const pkgKey = `${pkgName}-${pkgVersion}`; const experimentalPkgName = 'experimental'; - const experimentalPkgKey = `${experimentalPkgName}-${pkgVersion}`; const experimental2PkgName = 'experimental2'; - const experimental2PkgKey = `${experimental2PkgName}-${pkgVersion}`; - const uploadPkgKey = 'apache-0.1.4'; + const uploadPkgName = 'apache'; const installUploadPackage = async (pkg: string) => { const buf = fs.readFileSync(testPkgArchiveZip); @@ -43,22 +40,22 @@ export default function (providerContext: FtrProviderContext) { '../fixtures/direct_upload_packages/apache_0.1.4.zip' ); - const uninstallPackage = async (pkg: string) => { - await supertest.delete(`/api/fleet/epm/packages/${pkg}`).set('kbn-xsrf', 'xxxx'); + const uninstallPackage = async (pkg: string, version: string) => { + await supertest.delete(`/api/fleet/epm/packages/${pkg}/${version}`).set('kbn-xsrf', 'xxxx'); }; - const installPackage = async (pkg: string) => { + const installPackage = async (pkg: string, version: string) => { await supertest - .post(`/api/fleet/epm/packages/${pkg}`) + .post(`/api/fleet/epm/packages/${pkg}/${version}`) .set('kbn-xsrf', 'xxxx') .send({ force: true }); }; - const installPackages = async (pkgs: string[]) => { - const installingPackagesPromise = pkgs.map((pkg) => installPackage(pkg)); + const installPackages = async (pkgs: Array<{ name: string; version: string }>) => { + const installingPackagesPromise = pkgs.map((pkg) => installPackage(pkg.name, pkg.version)); return Promise.all(installingPackagesPromise); }; - const uninstallPackages = async (pkgs: string[]) => { - const uninstallingPackagesPromise = pkgs.map((pkg) => uninstallPackage(pkg)); + const uninstallPackages = async (pkgs: Array<{ name: string; version: string }>) => { + const uninstallingPackagesPromise = pkgs.map((pkg) => uninstallPackage(pkg.name, pkg.version)); return Promise.all(uninstallingPackagesPromise); }; @@ -67,12 +64,19 @@ export default function (providerContext: FtrProviderContext) { setupFleetAndAgents(providerContext); before(async () => { if (!server.enabled) return; - await installPackages([pkgKey, experimentalPkgKey, experimental2PkgKey]); - await installUploadPackage(uploadPkgKey); + await installPackages([ + { name: pkgName, version: pkgVersion }, + { name: experimentalPkgName, version: pkgVersion }, + { name: experimental2PkgName, version: pkgVersion }, + ]); + await installUploadPackage(uploadPkgName); }); after(async () => { if (!server.enabled) return; - await uninstallPackages([pkgKey, experimentalPkgKey]); + await uninstallPackages([ + { name: pkgName, version: pkgVersion }, + { name: experimentalPkgName, version: pkgVersion }, + ]); }); it('should create index patterns (without fields)', async () => { const resIndexPatternLogs = await kibanaServer.savedObjects.get({ diff --git a/x-pack/test/fleet_api_integration/apis/epm/install_update.ts b/x-pack/test/fleet_api_integration/apis/epm/install_update.ts index 74305d88df32a6..4774d9e2d844d9 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/install_update.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/install_update.ts @@ -19,20 +19,20 @@ export default function (providerContext: FtrProviderContext) { const kibanaServer = getService('kibanaServer'); const supertest = getService('supertest'); - const deletePackage = async (pkgkey: string) => { - await supertest.delete(`/api/fleet/epm/packages/${pkgkey}`).set('kbn-xsrf', 'xxxx'); + const deletePackage = async (name: string, version: string) => { + await supertest.delete(`/api/fleet/epm/packages/${name}/${version}`).set('kbn-xsrf', 'xxxx'); }; describe('installing and updating scenarios', async () => { skipIfNoDockerRegistry(providerContext); setupFleetAndAgents(providerContext); after(async () => { - await deletePackage('multiple_versions-0.3.0'); + await deletePackage('multiple_versions', '0.3.0'); }); it('should return 404 if package does not exist', async function () { await supertest - .post(`/api/fleet/epm/packages/nonexistent-0.1.0`) + .post(`/api/fleet/epm/packages/nonexistent/0.1.0`) .set('kbn-xsrf', 'xxxx') .expect(404); let res; @@ -48,7 +48,7 @@ export default function (providerContext: FtrProviderContext) { }); it('should return 400 if trying to install an out-of-date package', async function () { await supertest - .post(`/api/fleet/epm/packages/multiple_versions-0.1.0`) + .post(`/api/fleet/epm/packages/multiple_versions/0.1.0`) .set('kbn-xsrf', 'xxxx') .expect(400); let res; @@ -64,26 +64,26 @@ export default function (providerContext: FtrProviderContext) { }); it('should return 200 if trying to force install an out-of-date package', async function () { await supertest - .post(`/api/fleet/epm/packages/multiple_versions-0.1.0`) + .post(`/api/fleet/epm/packages/multiple_versions/0.1.0`) .set('kbn-xsrf', 'xxxx') .send({ force: true }) .expect(200); }); it('should return 200 if trying to reinstall an out-of-date package', async function () { await supertest - .post(`/api/fleet/epm/packages/multiple_versions-0.1.0`) + .post(`/api/fleet/epm/packages/multiple_versions/0.1.0`) .set('kbn-xsrf', 'xxxx') .expect(200); }); it('should return 400 if trying to update to an out-of-date package', async function () { await supertest - .post(`/api/fleet/epm/packages/multiple_versions-0.2.0`) + .post(`/api/fleet/epm/packages/multiple_versions/0.2.0`) .set('kbn-xsrf', 'xxxx') .expect(400); }); it('should return 200 if trying to force update to an out-of-date package', async function () { await supertest - .post(`/api/fleet/epm/packages/multiple_versions-0.2.0`) + .post(`/api/fleet/epm/packages/multiple_versions/0.2.0`) .set('kbn-xsrf', 'xxxx') .send({ force: true }) .expect(200); @@ -102,20 +102,20 @@ export default function (providerContext: FtrProviderContext) { }, }); await supertest - .post(`/api/fleet/epm/packages/multiple_versions-0.2.0`) + .post(`/api/fleet/epm/packages/multiple_versions/0.2.0`) .set('kbn-xsrf', 'xxxx') .expect(200); }); it('should return 200 if trying to update to the latest package', async function () { await supertest - .post(`/api/fleet/epm/packages/multiple_versions-0.3.0`) + .post(`/api/fleet/epm/packages/multiple_versions/0.3.0`) .set('kbn-xsrf', 'xxxx') .expect(200); - await deletePackage('multiple_versions-0.3.0'); + await deletePackage('multiple_versions', '0.3.0'); }); it('should return 200 if trying to install the latest package', async function () { await supertest - .post(`/api/fleet/epm/packages/multiple_versions-0.3.0`) + .post(`/api/fleet/epm/packages/multiple_versions/0.3.0`) .set('kbn-xsrf', 'xxxx') .expect(200); }); diff --git a/x-pack/test/fleet_api_integration/apis/epm/list.ts b/x-pack/test/fleet_api_integration/apis/epm/list.ts index 56f3e6ca1f2fa7..64adf094927b64 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/list.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/list.ts @@ -41,7 +41,7 @@ export default function (providerContext: FtrProviderContext) { return response.body; }; const listResponse = await fetchPackageList(); - expect(listResponse.response.length).not.to.be(0); + expect(listResponse.items.length).not.to.be(0); }); it('lists all limited packages from the registry', async function () { @@ -54,7 +54,7 @@ export default function (providerContext: FtrProviderContext) { }; const listResponse = await fetchLimitedPackageList(); - expect(listResponse.response).to.eql(['endpoint']); + expect(listResponse.items).to.eql(['endpoint']); }); it('allows user with only read permission to access', async () => { diff --git a/x-pack/test/fleet_api_integration/apis/epm/package_install_complete.ts b/x-pack/test/fleet_api_integration/apis/epm/package_install_complete.ts index 91db5bccf45631..42ac48a4bd281d 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/package_install_complete.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/package_install_complete.ts @@ -30,7 +30,7 @@ export default function (providerContext: FtrProviderContext) { before(async () => { if (!server.enabled) return; await supertest - .post(`/api/fleet/epm/packages/${pkgName}-0.1.0`) + .post(`/api/fleet/epm/packages/${pkgName}/0.1.0`) .set('kbn-xsrf', 'xxxx') .send({ force: true }) .expect(200); @@ -92,7 +92,7 @@ export default function (providerContext: FtrProviderContext) { after(async () => { if (!server.enabled) return; await supertest - .delete(`/api/fleet/epm/packages/multiple_versions-0.1.0`) + .delete(`/api/fleet/epm/packages/multiple_versions/0.1.0`) .set('kbn-xsrf', 'xxxx') .expect(200); }); @@ -101,12 +101,12 @@ export default function (providerContext: FtrProviderContext) { before(async () => { if (!server.enabled) return; await supertest - .post(`/api/fleet/epm/packages/${pkgName}-0.1.0`) + .post(`/api/fleet/epm/packages/${pkgName}/0.1.0`) .set('kbn-xsrf', 'xxxx') .send({ force: true }) .expect(200); await supertest - .post(`/api/fleet/epm/packages/${pkgName}-0.2.0`) + .post(`/api/fleet/epm/packages/${pkgName}/0.2.0`) .set('kbn-xsrf', 'xxxx') .send({ force: true }) .expect(200); @@ -174,7 +174,7 @@ export default function (providerContext: FtrProviderContext) { after(async () => { if (!server.enabled) return; await supertest - .delete(`/api/fleet/epm/packages/multiple_versions-0.1.0`) + .delete(`/api/fleet/epm/packages/multiple_versions/0.1.0`) .set('kbn-xsrf', 'xxxx') .expect(200); }); diff --git a/x-pack/test/fleet_api_integration/apis/epm/setup.ts b/x-pack/test/fleet_api_integration/apis/epm/setup.ts index 0b669c96bb0ea0..b4812b39f74ef1 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/setup.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/setup.ts @@ -34,19 +34,19 @@ export default function (providerContext: FtrProviderContext) { }); it('upgrades the endpoint package from 0.13.0 to the latest version available', async function () { let { body }: { body: GetInfoResponse } = await supertest - .get(`/api/fleet/epm/packages/endpoint-${oldEndpointVersion}`) + .get(`/api/fleet/epm/packages/endpoint/${oldEndpointVersion}`) .expect(200); - const latestEndpointVersion = body.response.latestVersion; + const latestEndpointVersion = body.item.latestVersion; log.info(`Endpoint package latest version: ${latestEndpointVersion}`); // make sure we're actually doing an upgrade expect(latestEndpointVersion).not.eql(oldEndpointVersion); await supertest.post(`/api/fleet/setup`).set('kbn-xsrf', 'xxxx').expect(200); ({ body } = await supertest - .get(`/api/fleet/epm/packages/endpoint-${latestEndpointVersion}`) + .get(`/api/fleet/epm/packages/endpoint/${latestEndpointVersion}`) .expect(200)); - expect(body.response).to.have.property('savedObject'); - expect((body.response as Installed).savedObject.attributes.install_version).to.eql( + expect(body.item).to.have.property('savedObject'); + expect((body.item as Installed).savedObject.attributes.install_version).to.eql( latestEndpointVersion ); }); @@ -65,8 +65,8 @@ export default function (providerContext: FtrProviderContext) { // POST /api/fleet/setup // POST /api/fleet/agents/setup // GET /api/fleet/agent_policies - // GET /api/fleet/enrollment-api-keys - // GET /api/fleet/enrollment-api-keys/ + // GET /api/fleet/enrollment_api_keys + // GET /api/fleet/enrollment_api_keys/ await supertestWithoutAuth .post('/api/fleet/setup') .set('Authorization', `Bearer ${token.value}`) @@ -83,13 +83,13 @@ export default function (providerContext: FtrProviderContext) { .set('kbn-xsrf', 'xxx') .expect(200); const response = await supertestWithoutAuth - .get('/api/fleet/enrollment-api-keys') + .get('/api/fleet/enrollment_api_keys') .set('Authorization', `Bearer ${token.value}`) .set('kbn-xsrf', 'xxx') .expect(200); - const enrollmentApiKeyId = response.body.list[0].id; + const enrollmentApiKeyId = response.body.items[0].id; await supertestWithoutAuth - .get(`/api/fleet/enrollment-api-keys/${enrollmentApiKeyId}`) + .get(`/api/fleet/enrollment_api_keys/${enrollmentApiKeyId}`) .set('Authorization', `Bearer ${token.value}`) .set('kbn-xsrf', 'xxx') .expect(200); diff --git a/x-pack/test/fleet_api_integration/apis/epm/update_assets.ts b/x-pack/test/fleet_api_integration/apis/epm/update_assets.ts index b46c932373cdf3..faa95f3b65e602 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/update_assets.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/update_assets.ts @@ -18,18 +18,16 @@ export default function (providerContext: FtrProviderContext) { const pkgName = 'all_assets'; const pkgVersion = '0.1.0'; const pkgUpdateVersion = '0.2.0'; - const pkgKey = `${pkgName}-${pkgVersion}`; - const pkgUpdateKey = `${pkgName}-${pkgUpdateVersion}`; const logsTemplateName = `logs-${pkgName}.test_logs`; const logsTemplateName2 = `logs-${pkgName}.test_logs2`; const metricsTemplateName = `metrics-${pkgName}.test_metrics`; - const uninstallPackage = async (pkg: string) => { - await supertest.delete(`/api/fleet/epm/packages/${pkg}`).set('kbn-xsrf', 'xxxx'); + const uninstallPackage = async (pkg: string, version: string) => { + await supertest.delete(`/api/fleet/epm/packages/${pkg}/${version}`).set('kbn-xsrf', 'xxxx'); }; - const installPackage = async (pkg: string) => { + const installPackage = async (pkg: string, version: string) => { await supertest - .post(`/api/fleet/epm/packages/${pkg}`) + .post(`/api/fleet/epm/packages/${pkg}/${version}`) .set('kbn-xsrf', 'xxxx') .send({ force: true }); }; @@ -39,11 +37,11 @@ export default function (providerContext: FtrProviderContext) { setupFleetAndAgents(providerContext); before(async () => { - await installPackage(pkgKey); - await installPackage(pkgUpdateKey); + await installPackage(pkgName, pkgVersion); + await installPackage(pkgName, pkgUpdateVersion); }); after(async () => { - await uninstallPackage(pkgUpdateKey); + await uninstallPackage(pkgName, pkgUpdateVersion); }); it('should have updated the ILM policy', async function () { const resPolicy = await es.ilm.getLifecycle( diff --git a/x-pack/test/fleet_api_integration/apis/package_policy/upgrade.ts b/x-pack/test/fleet_api_integration/apis/package_policy/upgrade.ts index 0747a452c58644..cc37e799f32e22 100644 --- a/x-pack/test/fleet_api_integration/apis/package_policy/upgrade.ts +++ b/x-pack/test/fleet_api_integration/apis/package_policy/upgrade.ts @@ -22,7 +22,7 @@ export default function (providerContext: FtrProviderContext) { function withTestPackageVersion(version: string) { before(async function () { await supertest - .post(`/api/fleet/epm/packages/package_policy_upgrade-${version}`) + .post(`/api/fleet/epm/packages/package_policy_upgrade/${version}`) .set('kbn-xsrf', 'xxxx') .send({ force: true }) .expect(200); @@ -30,7 +30,7 @@ export default function (providerContext: FtrProviderContext) { after(async function () { await supertest - .delete(`/api/fleet/epm/packages/package_policy_upgrade-${version}`) + .delete(`/api/fleet/epm/packages/package_policy_upgrade/${version}`) .set('kbn-xsrf', 'xxxx') .send({ force: true }) .expect(200); diff --git a/x-pack/test/fleet_api_integration/apis/service_tokens.ts b/x-pack/test/fleet_api_integration/apis/service_tokens.ts index 4d5487841782c8..e668caab8e98f2 100644 --- a/x-pack/test/fleet_api_integration/apis/service_tokens.ts +++ b/x-pack/test/fleet_api_integration/apis/service_tokens.ts @@ -23,10 +23,10 @@ export default function (providerContext: FtrProviderContext) { await esArchiver.unload('x-pack/test/functional/es_archives/empty_kibana'); }); - describe('POST /api/fleet/service-tokens', () => { + describe('POST /api/fleet/service_tokens', () => { it('should create a valid service account token', async () => { const { body: apiResponse } = await supertest - .post(`/api/fleet/service-tokens`) + .post(`/api/fleet/service_tokens`) .set('kbn-xsrf', 'xxxx') .expect(200); @@ -44,5 +44,9 @@ export default function (providerContext: FtrProviderContext) { expect(tokensResponse.tokens).have.property(apiResponse.name); }); }); + + it('should work with deprecated api', async () => { + await supertest.post(`/api/fleet/service-tokens`).set('kbn-xsrf', 'xxxx').expect(200); + }); }); } diff --git a/x-pack/test/fleet_cypress/agent.ts b/x-pack/test/fleet_cypress/agent.ts index e05a21c6a63e33..1838d9df8b3e28 100644 --- a/x-pack/test/fleet_cypress/agent.ts +++ b/x-pack/test/fleet_cypress/agent.ts @@ -50,10 +50,10 @@ export class AgentManager extends Manager { public async startAgent() { this.log.info('Getting agent enrollment key'); const { data: apiKeys } = await axios.get( - this.params.kibanaUrl + '/api/fleet/enrollment-api-keys', + this.params.kibanaUrl + '/api/fleet/enrollment_api_keys', this.requestOptions ); - const policy = apiKeys.list[1]; + const policy = apiKeys.items[1]; this.log.info('Running the agent'); @@ -87,7 +87,7 @@ export class AgentManager extends Manager { `${this.params.kibanaUrl}/api/fleet/agents`, this.requestOptions ); - done = agents.list[0]?.status === 'online'; + done = agents.items[0]?.status === 'online'; if (++retries > 12) { this.log.error('Giving up on enrolling the agent after a minute'); throw new Error('Agent timed out while coming online'); diff --git a/x-pack/test/functional/services/ml/test_resources.ts b/x-pack/test/functional/services/ml/test_resources.ts index fa6a53a80b2878..b9e80c3ebf5e90 100644 --- a/x-pack/test/functional/services/ml/test_resources.ts +++ b/x-pack/test/functional/services/ml/test_resources.ts @@ -474,25 +474,24 @@ export function MachineLearningTestResourcesProvider({ getService }: FtrProvider log.debug(`Installing Fleet package '${packageName}'`); const version = await this.getFleetPackageVersion(packageName); - const packageWithVersion = `${packageName}-${version}`; await retry.tryForTime(30 * 1000, async () => { await supertest - .post(`/api/fleet/epm/packages/${packageWithVersion}`) + .post(`/api/fleet/epm/packages/${packageName}/${version}`) .set(COMMON_REQUEST_HEADERS) .expect(200); }); log.debug(` > Installed`); - return packageWithVersion; + return version; }, - async removeFleetPackage(packageWithVersion: string) { - log.debug(`Removing Fleet package '${packageWithVersion}'`); + async removeFleetPackage(packageName: string, version: string) { + log.debug(`Removing Fleet package '${packageName}-${version}'`); await retry.tryForTime(30 * 1000, async () => { await supertest - .delete(`/api/fleet/epm/packages/${packageWithVersion}`) + .delete(`/api/fleet/epm/packages/${packageName}/${version}`) .set(COMMON_REQUEST_HEADERS) .expect(200); }); diff --git a/x-pack/test/functional/services/uptime/synthetics_package.ts b/x-pack/test/functional/services/uptime/synthetics_package.ts index b939ee453545e2..b0d935c408e4d9 100644 --- a/x-pack/test/functional/services/uptime/synthetics_package.ts +++ b/x-pack/test/functional/services/uptime/synthetics_package.ts @@ -38,7 +38,7 @@ export function SyntheticsPackageProvider({ getService }: FtrProviderContext) { // Retrieve information about the Synthetics package // EPM does not currently have an API to get the "lastest" information for a page given its name, // so we'll retrieve a list of packages and then find the package info in the list. - let apiRequest: Promise; + let apiRequest: Promise; return () => { if (!apiRequest) { @@ -57,7 +57,7 @@ export function SyntheticsPackageProvider({ getService }: FtrProviderContext) { }) .then((response: { body: GetPackagesResponse }) => { const { body } = response; - const syntheticsPackageInfo = body.response.find( + const syntheticsPackageInfo = body.items.find( (epmPackage) => epmPackage.name === 'synthetics' ); if (!syntheticsPackageInfo) { diff --git a/x-pack/test/osquery_cypress/agent.ts b/x-pack/test/osquery_cypress/agent.ts index e05a21c6a63e33..1838d9df8b3e28 100644 --- a/x-pack/test/osquery_cypress/agent.ts +++ b/x-pack/test/osquery_cypress/agent.ts @@ -50,10 +50,10 @@ export class AgentManager extends Manager { public async startAgent() { this.log.info('Getting agent enrollment key'); const { data: apiKeys } = await axios.get( - this.params.kibanaUrl + '/api/fleet/enrollment-api-keys', + this.params.kibanaUrl + '/api/fleet/enrollment_api_keys', this.requestOptions ); - const policy = apiKeys.list[1]; + const policy = apiKeys.items[1]; this.log.info('Running the agent'); @@ -87,7 +87,7 @@ export class AgentManager extends Manager { `${this.params.kibanaUrl}/api/fleet/agents`, this.requestOptions ); - done = agents.list[0]?.status === 'online'; + done = agents.items[0]?.status === 'online'; if (++retries > 12) { this.log.error('Giving up on enrolling the agent after a minute'); throw new Error('Agent timed out while coming online'); diff --git a/x-pack/test/security_solution_endpoint/services/endpoint_policy.ts b/x-pack/test/security_solution_endpoint/services/endpoint_policy.ts index 7383ef80d49c2b..6232f821815099 100644 --- a/x-pack/test/security_solution_endpoint/services/endpoint_policy.ts +++ b/x-pack/test/security_solution_endpoint/services/endpoint_policy.ts @@ -48,7 +48,7 @@ export interface PolicyTestResourceInfo { /** * Information about the endpoint package */ - packageInfo: Immutable; + packageInfo: Immutable; /** will clean up (delete) the objects created (Agent Policy + Package Policy) */ cleanup: () => Promise; } @@ -72,7 +72,7 @@ export function EndpointPolicyTestResourcesProvider({ getService }: FtrProviderC // so we'll retrieve a list of packages for a category of Security, and will then find the // endpoint package info. in the list. The request is kicked off here, but handled below after // Agent Policy creation so that they can be executed concurrently - let apiRequest: Promise; + let apiRequest: Promise; return () => { if (!apiRequest) { @@ -94,7 +94,7 @@ export function EndpointPolicyTestResourcesProvider({ getService }: FtrProviderC }) .then((response: { body: GetPackagesResponse }) => { const { body: secPackages } = response; - const endpointPackageInfo = secPackages.response.find( + const endpointPackageInfo = secPackages.items.find( (epmPackage) => epmPackage.name === 'endpoint' ); if (!endpointPackageInfo) { @@ -124,11 +124,11 @@ export function EndpointPolicyTestResourcesProvider({ getService }: FtrProviderC /** * Retrieves the currently installed endpoint package */ - async getEndpointPackage(): Promise> { + async getEndpointPackage(): Promise> { const endpointPackage = await retrieveEndpointPackageInfo(); if (!endpointPackage) { - throw new EndpointError(`endpoint package not instealled`); + throw new EndpointError(`endpoint package not installed`); } return endpointPackage;