[Ingest Manager] Rename agent/package config(s) to agent/package policy(ies) (#74914)

* Initial pass at updating client routes, variables names, code comments, and UI copy

* Adjust server routes and param names, more var names and i18n fixes

* Fix test

* More var renaming

* Rest of server-side var renaming

* Rest of client side var renaming

* Rename agent SO attributes and add migrations

* Remove agent prefix from policy fields

* Rename agent policy SO attributes and add migrations

* Rename enrollment api key SO attributes and add migrations

* Rename package policy SO attributes and add migrations

* Rename agent event SO attributes and add migrations

* Rename subtype CONFIG to POLICY (I don't think this string is ever sent by agent, though)

* Update snapshot

* Remove unnecessary cloning in migrations

* Fix migration typos

* Update naming in tests and es archiver data

* Rename file names in /common

* Rename /server files

* Rename /public files

* Rename test file names

* Rename missed files

* Revert "Rename subtype CONFIG to POLICY (I don't think this string is ever sent by agent, though)"

This reverts commit 3c91e01ed9.

* Add migration version to updated es archiver data to fix tests
This commit is contained in:
Jen Huang 2020-08-19 13:52:06 -07:00 committed by GitHub
parent 9111d50965
commit ad5c0f58fe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
249 changed files with 4845 additions and 4720 deletions

View file

@ -3,7 +3,7 @@
## Plugin
- The plugin is enabled by default. See the TypeScript type for the [the available plugin configuration options](https://github.com/elastic/kibana/blob/master/x-pack/plugins/ingest_manager/common/types/index.ts#L9-L27)
- Adding `xpack.ingestManager.enabled=false` will disable the plugin including the EPM and Fleet features. It will also remove the `PACKAGE_CONFIG_API_ROUTES` and `AGENT_CONFIG_API_ROUTES` values in [`common/constants/routes.ts`](./common/constants/routes.ts)
- Adding `xpack.ingestManager.enabled=false` will disable the plugin including the EPM and Fleet features. It will also remove the `PACKAGE_POLICY_API_ROUTES` and `AGENT_POLICY_API_ROUTES` values in [`common/constants/routes.ts`](./common/constants/routes.ts)
- Adding `--xpack.ingestManager.fleet.enabled=false` will disable the Fleet API & UI
- [code for adding the routes](https://github.com/elastic/kibana/blob/1f27d349533b1c2865c10c45b2cf705d7416fb36/x-pack/plugins/ingest_manager/server/plugin.ts#L115-L133)
- [Integration tests](server/integration_tests/router.test.ts)

View file

@ -17,5 +17,5 @@ export const AGENT_POLLING_INTERVAL = 1000;
export const AGENT_UPDATE_LAST_CHECKIN_INTERVAL_MS = 30000;
export const AGENT_UPDATE_ACTIONS_INTERVAL_MS = 5000;
export const AGENT_CONFIG_ROLLOUT_RATE_LIMIT_INTERVAL_MS = 5000;
export const AGENT_CONFIG_ROLLOUT_RATE_LIMIT_REQUEST_PER_INTERVAL = 25;
export const AGENT_POLICY_ROLLOUT_RATE_LIMIT_INTERVAL_MS = 5000;
export const AGENT_POLICY_ROLLOUT_RATE_LIMIT_REQUEST_PER_INTERVAL = 25;

View file

@ -1,20 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { AgentConfigStatus, DefaultPackages } from '../types';
export const AGENT_CONFIG_SAVED_OBJECT_TYPE = 'ingest-agent-policies';
export const DEFAULT_AGENT_CONFIG = {
name: 'Default config',
namespace: 'default',
description: 'Default agent configuration created by Kibana',
status: AgentConfigStatus.Active,
package_configs: [],
is_default: true,
monitoring_enabled: ['logs', 'metrics'] as Array<'logs' | 'metrics'>,
};
export const DEFAULT_AGENT_CONFIGS_PACKAGES = [DefaultPackages.system];

View file

@ -0,0 +1,20 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { AgentPolicyStatus, DefaultPackages } from '../types';
export const AGENT_POLICY_SAVED_OBJECT_TYPE = 'ingest-agent-policies';
export const DEFAULT_AGENT_POLICY = {
name: 'Default policy',
namespace: 'default',
description: 'Default agent policy created by Kibana',
status: AgentPolicyStatus.Active,
package_policies: [],
is_default: true,
monitoring_enabled: ['logs', 'metrics'] as Array<'logs' | 'metrics'>,
};
export const DEFAULT_AGENT_POLICIES_PACKAGES = [DefaultPackages.system];

View file

@ -7,8 +7,8 @@ export * from './plugin';
export * from './routes';
export * from './agent';
export * from './agent_config';
export * from './package_config';
export * from './agent_policy';
export * from './package_policy';
export * from './epm';
export * from './output';
export * from './enrollment_api_key';

View file

@ -4,4 +4,4 @@
* you may not use this file except in compliance with the Elastic License.
*/
export const PACKAGE_CONFIG_SAVED_OBJECT_TYPE = 'ingest-package-policies';
export const PACKAGE_POLICY_SAVED_OBJECT_TYPE = 'ingest-package-policies';

View file

@ -7,8 +7,8 @@
export const API_ROOT = `/api/ingest_manager`;
export const EPM_API_ROOT = `${API_ROOT}/epm`;
export const DATA_STREAM_API_ROOT = `${API_ROOT}/data_streams`;
export const PACKAGE_CONFIG_API_ROOT = `${API_ROOT}/package_configs`;
export const AGENT_CONFIG_API_ROOT = `${API_ROOT}/agent_configs`;
export const PACKAGE_POLICY_API_ROOT = `${API_ROOT}/package_policies`;
export const AGENT_POLICY_API_ROOT = `${API_ROOT}/agent_policies`;
export const FLEET_API_ROOT = `${API_ROOT}/fleet`;
export const LIMITED_CONCURRENCY_ROUTE_TAG = 'ingest:limited-concurrency';
@ -32,25 +32,25 @@ export const DATA_STREAM_API_ROUTES = {
LIST_PATTERN: `${DATA_STREAM_API_ROOT}`,
};
// Package config API routes
export const PACKAGE_CONFIG_API_ROUTES = {
LIST_PATTERN: `${PACKAGE_CONFIG_API_ROOT}`,
INFO_PATTERN: `${PACKAGE_CONFIG_API_ROOT}/{packageConfigId}`,
CREATE_PATTERN: `${PACKAGE_CONFIG_API_ROOT}`,
UPDATE_PATTERN: `${PACKAGE_CONFIG_API_ROOT}/{packageConfigId}`,
DELETE_PATTERN: `${PACKAGE_CONFIG_API_ROOT}/delete`,
// Package policy API routes
export const PACKAGE_POLICY_API_ROUTES = {
LIST_PATTERN: `${PACKAGE_POLICY_API_ROOT}`,
INFO_PATTERN: `${PACKAGE_POLICY_API_ROOT}/{packagePolicyId}`,
CREATE_PATTERN: `${PACKAGE_POLICY_API_ROOT}`,
UPDATE_PATTERN: `${PACKAGE_POLICY_API_ROOT}/{packagePolicyId}`,
DELETE_PATTERN: `${PACKAGE_POLICY_API_ROOT}/delete`,
};
// Agent config API routes
export const AGENT_CONFIG_API_ROUTES = {
LIST_PATTERN: `${AGENT_CONFIG_API_ROOT}`,
INFO_PATTERN: `${AGENT_CONFIG_API_ROOT}/{agentConfigId}`,
CREATE_PATTERN: `${AGENT_CONFIG_API_ROOT}`,
UPDATE_PATTERN: `${AGENT_CONFIG_API_ROOT}/{agentConfigId}`,
COPY_PATTERN: `${AGENT_CONFIG_API_ROOT}/{agentConfigId}/copy`,
DELETE_PATTERN: `${AGENT_CONFIG_API_ROOT}/delete`,
FULL_INFO_PATTERN: `${AGENT_CONFIG_API_ROOT}/{agentConfigId}/full`,
FULL_INFO_DOWNLOAD_PATTERN: `${AGENT_CONFIG_API_ROOT}/{agentConfigId}/download`,
// Agent policy API routes
export const AGENT_POLICY_API_ROUTES = {
LIST_PATTERN: `${AGENT_POLICY_API_ROOT}`,
INFO_PATTERN: `${AGENT_POLICY_API_ROOT}/{agentPolicyId}`,
CREATE_PATTERN: `${AGENT_POLICY_API_ROOT}`,
UPDATE_PATTERN: `${AGENT_POLICY_API_ROOT}/{agentPolicyId}`,
COPY_PATTERN: `${AGENT_POLICY_API_ROOT}/{agentPolicyId}/copy`,
DELETE_PATTERN: `${AGENT_POLICY_API_ROOT}/delete`,
FULL_INFO_PATTERN: `${AGENT_POLICY_API_ROOT}/{agentPolicyId}/full`,
FULL_INFO_DOWNLOAD_PATTERN: `${AGENT_POLICY_API_ROOT}/{agentPolicyId}/download`,
};
// Output API routes

View file

@ -4,15 +4,15 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { NewPackageConfig, PackageConfig } from './types/models/package_config';
import { NewPackagePolicy, PackagePolicy } from './types';
export const createNewPackageConfigMock = (): NewPackageConfig => {
export const createNewPackagePolicyMock = (): NewPackagePolicy => {
return {
name: 'endpoint-1',
description: '',
namespace: 'default',
enabled: true,
config_id: '93c46720-c217-11ea-9906-b5b8a21b268e',
policy_id: '93c46720-c217-11ea-9906-b5b8a21b268e',
output_id: '',
package: {
name: 'endpoint',
@ -23,10 +23,10 @@ export const createNewPackageConfigMock = (): NewPackageConfig => {
};
};
export const createPackageConfigMock = (): PackageConfig => {
const newPackageConfig = createNewPackageConfigMock();
export const createPackagePolicyMock = (): PackagePolicy => {
const newPackagePolicy = createNewPackagePolicyMock();
return {
...newPackageConfig,
...newPackagePolicy,
id: 'c6d16e42-c32d-4dce-8a88-113cfe276ad1',
version: 'abcd',
revision: 1,

View file

@ -17,9 +17,9 @@
}
],
"paths": {
"/agent_configs": {
"/agent_policies": {
"get": {
"summary": "Agent Config - List",
"summary": "Agent policy - List",
"tags": [],
"responses": {
"200": {
@ -32,7 +32,7 @@
"items": {
"type": "array",
"items": {
"$ref": "#/components/schemas/AgentConfig"
"$ref": "#/components/schemas/AgentPolicy"
}
},
"total": {
@ -56,11 +56,11 @@
"items": [
{
"id": "82da1fc0-8fbf-11ea-b2ce-01c4a6127154",
"name": "Default config",
"name": "Default policy",
"namespace": "default",
"description": "Default agent configuration created by Kibana",
"description": "Default agent policy created by Kibana",
"status": "active",
"packageConfigs": ["8a5679b0-8fbf-11ea-b2ce-01c4a6127154"],
"packagePolicies": ["8a5679b0-8fbf-11ea-b2ce-01c4a6127154"],
"is_default": true,
"monitoring_enabled": ["logs", "metrics"],
"revision": 2,
@ -80,7 +80,7 @@
}
}
},
"operationId": "agent-config-list",
"operationId": "agent-policy-list",
"parameters": [
{
"$ref": "#/components/parameters/pageSizeParam"
@ -95,7 +95,7 @@
"description": ""
},
"post": {
"summary": "Agent Config - Create",
"summary": "Agent policy - Create",
"tags": [],
"responses": {
"200": {
@ -106,7 +106,7 @@
"type": "object",
"properties": {
"item": {
"$ref": "#/components/schemas/AgentConfig"
"$ref": "#/components/schemas/AgentPolicy"
},
"success": {
"type": "boolean"
@ -117,12 +117,12 @@
}
}
},
"operationId": "post-agent_configs",
"operationId": "post-agent-policy",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/NewAgentConfig"
"$ref": "#/components/schemas/NewAgentPolicy"
}
}
}
@ -135,19 +135,19 @@
]
}
},
"/agent_configs/{agentConfigId}": {
"/agent_policies/{agentPolicyId}": {
"parameters": [
{
"schema": {
"type": "string"
},
"name": "agentConfigId",
"name": "agentPolicyId",
"in": "path",
"required": true
}
],
"get": {
"summary": "Agent Config - Info",
"summary": "Agent policy - Info",
"tags": [],
"responses": {
"200": {
@ -158,7 +158,7 @@
"type": "object",
"properties": {
"item": {
"$ref": "#/components/schemas/AgentConfig"
"$ref": "#/components/schemas/AgentPolicy"
},
"success": {
"type": "boolean"
@ -171,11 +171,11 @@
"value": {
"item": {
"id": "82da1fc0-8fbf-11ea-b2ce-01c4a6127154",
"name": "Default config",
"name": "Default policy",
"namespace": "default",
"description": "Default agent configuration created by Kibana",
"description": "Default agent policy created by Kibana",
"status": "active",
"packageConfigs": [
"packagePolicies": [
{
"id": "8a5679b0-8fbf-11ea-b2ce-01c4a6127154",
"name": "system-1",
@ -186,7 +186,7 @@
"version": "0.0.3"
},
"enabled": true,
"config_id": "82da1fc0-8fbf-11ea-b2ce-01c4a6127154",
"policy_id": "82da1fc0-8fbf-11ea-b2ce-01c4a6127154",
"output_id": "08adc51c-69f3-4294-80e2-24527c6ff73d",
"inputs": [
{
@ -716,12 +716,12 @@
}
}
},
"operationId": "agent-config-info",
"description": "Get one agent config",
"operationId": "agent-policy-info",
"description": "Get one agent policy",
"parameters": []
},
"put": {
"summary": "Agent Config - Update",
"summary": "Agent policy - Update",
"tags": [],
"responses": {
"200": {
@ -732,7 +732,7 @@
"type": "object",
"properties": {
"item": {
"$ref": "#/components/schemas/AgentConfig"
"$ref": "#/components/schemas/AgentPolicy"
},
"success": {
"type": "boolean"
@ -750,7 +750,7 @@
"namespace": "UPDATED namespace",
"updated_on": "Fri Feb 28 2020 16:22:31 GMT-0500 (Eastern Standard Time)",
"updated_by": "elastic",
"packageConfigs": []
"packagePolicies": []
},
"success": true
}
@ -760,12 +760,12 @@
}
}
},
"operationId": "put-agent_configs-agentConfigId",
"operationId": "put-agent-policy-agentPolicyId",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/NewAgentConfig"
"$ref": "#/components/schemas/NewAgentPolicy"
},
"examples": {
"example-1": {
@ -786,20 +786,20 @@
]
}
},
"/agent_configs/{agentConfigId}/copy": {
"/agent_policies/{agentPolicyId}/copy": {
"parameters": [
{
"schema": {
"type": "string"
},
"name": "agentConfigId",
"name": "agentPolicyId",
"in": "path",
"required": true
}
],
"post": {
"summary": "Agent config - copy one config",
"operationId": "agent-config-copy",
"summary": "Agent policy - copy one policy",
"operationId": "agent-policy-copy",
"responses": {
"200": {
"description": "OK",
@ -809,7 +809,7 @@
"type": "object",
"properties": {
"item": {
"$ref": "#/components/schemas/AgentConfig"
"$ref": "#/components/schemas/AgentPolicy"
},
"success": {
"type": "boolean"
@ -841,13 +841,13 @@
},
"description": ""
},
"description": "Copies one agent config"
"description": "Copies one agent policy"
}
},
"/agent_configs/delete": {
"/agent_policies/delete": {
"post": {
"summary": "Agent Config - Delete",
"operationId": "post-agent_config-delete",
"summary": "Agent policy - Delete",
"operationId": "post-agent-policy-delete",
"responses": {
"200": {
"description": "OK",
@ -896,7 +896,7 @@
"schema": {
"type": "object",
"properties": {
"agentConfigIds": {
"agentPolicyIds": {
"type": "array",
"items": {
"type": "string"
@ -907,7 +907,7 @@
"examples": {
"example-1": {
"value": {
"agentConfigIds": ["df7d2540-5a47-11ea-80da-89b5a66da347"]
"agentPolicyIds": ["df7d2540-5a47-11ea-80da-89b5a66da347"]
}
}
}
@ -922,9 +922,9 @@
},
"parameters": []
},
"/package_configs": {
"/package_policies": {
"get": {
"summary": "PackageConfigs - List",
"summary": "PackagePolicies - List",
"tags": [],
"responses": {
"200": {
@ -937,7 +937,7 @@
"items": {
"type": "array",
"items": {
"$ref": "#/components/schemas/PackageConfig"
"$ref": "#/components/schemas/PackagePolicy"
}
},
"total": {
@ -1166,14 +1166,14 @@
}
}
},
"operationId": "get-packageConfigs",
"operationId": "get-packagePolicies",
"security": [],
"parameters": []
},
"parameters": [],
"post": {
"summary": "PackageConfigs - Create",
"operationId": "post-packageConfigs",
"summary": "PackagePolicies - Create",
"operationId": "post-packagePolicies",
"responses": {
"200": {
"description": "OK"
@ -1183,7 +1183,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/NewPackageConfig"
"$ref": "#/components/schemas/NewPackagePolicy"
},
"examples": {
"example-1": {
@ -1237,9 +1237,9 @@
]
}
},
"/package_configs/{packageConfigId}": {
"/package_policies/{packagePolicyId}": {
"get": {
"summary": "PackageConfigs - Info",
"summary": "PackagePolicies - Info",
"tags": [],
"responses": {
"200": {
@ -1250,7 +1250,7 @@
"type": "object",
"properties": {
"item": {
"$ref": "#/components/schemas/PackageConfig"
"$ref": "#/components/schemas/PackagePolicy"
},
"success": {
"type": "boolean"
@ -1262,21 +1262,21 @@
}
}
},
"operationId": "get-packageConfigs-packageConfigId"
"operationId": "get-packagePolicies-packagePolicyId"
},
"parameters": [
{
"schema": {
"type": "string"
},
"name": "packageConfigId",
"name": "packagePolicyId",
"in": "path",
"required": true
}
],
"put": {
"summary": "PackageConfigs - Update",
"operationId": "put-packageConfigs-packageConfigId",
"summary": "PackagePolicies - Update",
"operationId": "put-packagePolicies-packagePolicyId",
"responses": {
"200": {
"description": "OK",
@ -1286,7 +1286,7 @@
"type": "object",
"properties": {
"item": {
"$ref": "#/components/schemas/PackageConfig"
"$ref": "#/components/schemas/PackagePolicy"
},
"sucess": {
"type": "boolean"
@ -1824,10 +1824,10 @@
"path": "telemetry"
}
],
"packageConfigs": [
"packagePolicies": [
{
"name": "endpoint",
"title": "Endpoint package config",
"title": "Endpoint package policy",
"description": "Interact with the endpoint.",
"inputs": null,
"multiple": false
@ -2119,7 +2119,7 @@
}
},
{
"description": "The log package should be used to create package configs for all type of logs for which an package doesn't exist yet.\n",
"description": "The log package should be used to create package policies for all type of logs for which an package doesn't exist yet.\n",
"download": "/epr/log/log-0.9.0.tar.gz",
"icons": [
{
@ -2765,7 +2765,7 @@
{
"id": "205661d0-5e53-11ea-ad31-4f31c06bd9a4",
"active": true,
"config_id": "ae556400-5e39-11ea-8b49-f9747e466f7b",
"policy_id": "ae556400-5e39-11ea-8b49-f9747e466f7b",
"type": "PERMANENT",
"enrolled_at": "2020-03-04T20:02:50.605Z",
"user_provided_metadata": {
@ -2780,7 +2780,7 @@
},
"actions": [
{
"data": "{\"config\":{\"id\":\"ae556400-5e39-11ea-8b49-f9747e466f7b\",\"outputs\":{\"default\":{\"type\":\"elasticsearch\",\"hosts\":[\"http://localhost:9200\"],\"api_key\":\"\",\"api_token\":\"6ckkp3ABz7e_XRqr3LM8:gQuDfUNSRgmY0iziYqP9Hw\"}},\"packageConfigs\":[]}}",
"data": "{\"config\":{\"id\":\"ae556400-5e39-11ea-8b49-f9747e466f7b\",\"outputs\":{\"default\":{\"type\":\"elasticsearch\",\"hosts\":[\"http://localhost:9200\"],\"api_key\":\"\",\"api_token\":\"6ckkp3ABz7e_XRqr3LM8:gQuDfUNSRgmY0iziYqP9Hw\"}},\"packagePolicies\":[]}}",
"created_at": "2020-03-04T20:02:56.149Z",
"id": "6a95c00a-d76d-4931-97c3-0bf935272d7d",
"type": "CONFIG_CHANGE"
@ -2965,7 +2965,7 @@
"api_key": "Z-XkgHIBvwtjzIKtSCTh:AejRqdKpQx6z-6dqSI1LHg"
}
},
"packageConfigs": [
"packagePolicies": [
{
"id": "33d6bd70-a5e0-11ea-a587-5f886c8a849f",
"name": "system-1",
@ -3433,7 +3433,7 @@
"item": {
"id": "8086fb1a-72ca-4a67-8533-09300c1639fa",
"active": true,
"config_id": "2fe89350-a5e0-11ea-a587-5f886c8a849f",
"policy_id": "2fe89350-a5e0-11ea-a587-5f886c8a849f",
"type": "PERMANENT",
"enrolled_at": "2020-06-04T13:03:57.856Z",
"user_provided_metadata": {
@ -3562,22 +3562,22 @@
}
}
},
"/fleet/config/{configId}/agent-status": {
"parameters": [
{
"schema": {
"type": "string"
},
"name": "configId",
"in": "path",
"required": true
}
],
"/fleet/agent-status": {
"get": {
"summary": "Fleet - Agent - Status for config",
"summary": "Fleet - Agent - Status for policy",
"tags": [],
"responses": {},
"operationId": "get-fleet-config-configId-agent-status"
"operationId": "get-fleet-agent-status",
"parameters": [
{
"schema": {
"type": "string"
},
"name": "policyId",
"in": "query",
"required": false
}
]
}
},
"/fleet/enrollment-api-keys": {
@ -3702,10 +3702,10 @@
},
"components": {
"schemas": {
"AgentConfig": {
"AgentPolicy": {
"allOf": [
{
"$ref": "#/components/schemas/NewAgentConfig"
"$ref": "#/components/schemas/NewAgentPolicy"
},
{
"type": "object",
@ -3717,7 +3717,7 @@
"type": "string",
"enum": ["active", "inactive"]
},
"packageConfigs": {
"packagePolicies": {
"oneOf": [
{
"items": {
@ -3726,7 +3726,7 @@
},
{
"items": {
"$ref": "#/components/schemas/PackageConfig"
"$ref": "#/components/schemas/PackagePolicy"
}
}
],
@ -3750,8 +3750,8 @@
}
]
},
"PackageConfig": {
"title": "PackageConfig",
"PackagePolicy": {
"title": "PackagePolicy",
"allOf": [
{
"type": "object",
@ -3770,15 +3770,15 @@
"required": ["id", "revision"]
},
{
"$ref": "#/components/schemas/NewPackageConfig"
"$ref": "#/components/schemas/NewPackagePolicy"
}
],
"x-examples": {
"example-1": {}
}
},
"NewAgentConfig": {
"title": "NewAgentConfig",
"NewAgentPolicy": {
"title": "NewAgentPolicy",
"type": "object",
"properties": {
"name": {
@ -3792,8 +3792,8 @@
}
}
},
"NewPackageConfig": {
"title": "NewPackageConfig",
"NewPackagePolicy": {
"title": "NewPackagePolicy",
"type": "object",
"x-examples": {
"example-1": {
@ -3892,7 +3892,7 @@
"required": ["type", "enabled", "streams"]
}
},
"config_id": {
"policy_id": {
"type": "string"
},
"name": {
@ -3902,7 +3902,7 @@
"type": "string"
}
},
"required": ["output_id", "inputs", "config_id", "name"]
"required": ["output_id", "inputs", "policy_id", "name"]
},
"PackageInfo": {
"title": "PackageInfo",
@ -4140,10 +4140,10 @@
"default_api_key_id": {
"type": "string"
},
"config_id": {
"policy_id": {
"type": "string"
},
"config_revision": {
"policy_revision": {
"type": ["number", "null"]
},
"last_checkin": {
@ -4221,7 +4221,7 @@
"agent_id": {
"type": "string"
},
"config_id": {
"policy_id": {
"type": "string"
},
"stream_id": {

View file

@ -4,9 +4,9 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { safeDump } from 'js-yaml';
import { FullAgentConfig } from '../types';
import { FullAgentPolicy } from '../types';
const CONFIG_KEYS_ORDER = [
const POLICY_KEYS_ORDER = [
'id',
'name',
'revision',
@ -21,12 +21,12 @@ const CONFIG_KEYS_ORDER = [
'input',
];
export const configToYaml = (config: FullAgentConfig): string => {
return safeDump(config, {
export const fullAgentPolicyToYaml = (policy: FullAgentPolicy): string => {
return safeDump(policy, {
skipInvalid: true,
sortKeys: (keyA: string, keyB: string) => {
const indexA = CONFIG_KEYS_ORDER.indexOf(keyA);
const indexB = CONFIG_KEYS_ORDER.indexOf(keyB);
const indexA = POLICY_KEYS_ORDER.indexOf(keyA);
const indexB = POLICY_KEYS_ORDER.indexOf(keyB);
if (indexA >= 0 && indexB < 0) {
return -1;
}

View file

@ -5,8 +5,8 @@
*/
export * from './routes';
export * as AgentStatusKueryHelper from './agent_status';
export { packageToPackageConfigInputs, packageToPackageConfig } from './package_to_config';
export { storedPackageConfigsToAgentInputs } from './package_configs_to_agent_inputs';
export { configToYaml } from './config_to_yaml';
export { isPackageLimited, doesAgentConfigAlreadyIncludePackage } from './limited_package';
export { packageToPackagePolicyInputs, packageToPackagePolicy } from './package_to_package_policy';
export { storedPackagePoliciesToAgentInputs } from './package_policies_to_agent_inputs';
export { fullAgentPolicyToYaml } from './full_agent_policy_to_yaml';
export { isPackageLimited, doesAgentPolicyAlreadyIncludePackage } from './limited_package';
export { decodeCloudId } from './decode_cloud_id';

View file

@ -3,21 +3,21 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { PackageInfo, AgentConfig, PackageConfig } from '../types';
import { PackageInfo, AgentPolicy, PackagePolicy } from '../types';
// Assume packages only ever include 1 config template for now
export const isPackageLimited = (packageInfo: PackageInfo): boolean => {
return packageInfo.config_templates?.[0]?.multiple === false;
};
export const doesAgentConfigAlreadyIncludePackage = (
agentConfig: AgentConfig,
export const doesAgentPolicyAlreadyIncludePackage = (
agentPolicy: AgentPolicy,
packageName: string
): boolean => {
if (agentConfig.package_configs.length && typeof agentConfig.package_configs[0] === 'string') {
throw new Error('Unable to read full package config information');
if (agentPolicy.package_policies.length && typeof agentPolicy.package_policies[0] === 'string') {
throw new Error('Unable to read full package policy information');
}
return (agentConfig.package_configs as PackageConfig[])
.map((packageConfig) => packageConfig.package?.name || '')
return (agentPolicy.package_policies as PackagePolicy[])
.map((packagePolicy) => packagePolicy.package?.name || '')
.includes(packageName);
};

View file

@ -3,19 +3,19 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { PackageConfig, PackageConfigInput } from '../types';
import { storedPackageConfigsToAgentInputs } from './package_configs_to_agent_inputs';
import { PackagePolicy, PackagePolicyInput } from '../types';
import { storedPackagePoliciesToAgentInputs } from './package_policies_to_agent_inputs';
describe('Ingest Manager - storedPackageConfigsToAgentInputs', () => {
const mockPackageConfig: PackageConfig = {
describe('Ingest Manager - storedPackagePoliciesToAgentInputs', () => {
const mockPackagePolicy: PackagePolicy = {
id: 'some-uuid',
name: 'mock-package-config',
name: 'mock-package-policy',
description: '',
created_at: '',
created_by: '',
updated_at: '',
updated_by: '',
config_id: '',
policy_id: '',
enabled: true,
output_id: '',
namespace: 'default',
@ -23,7 +23,7 @@ describe('Ingest Manager - storedPackageConfigsToAgentInputs', () => {
revision: 1,
};
const mockInput: PackageConfigInput = {
const mockInput: PackagePolicyInput = {
type: 'test-logs',
enabled: true,
vars: {
@ -74,13 +74,13 @@ describe('Ingest Manager - storedPackageConfigsToAgentInputs', () => {
],
};
it('returns no inputs for package config with no inputs, or only disabled inputs', () => {
expect(storedPackageConfigsToAgentInputs([mockPackageConfig])).toEqual([]);
it('returns no inputs for package policy with no inputs, or only disabled inputs', () => {
expect(storedPackagePoliciesToAgentInputs([mockPackagePolicy])).toEqual([]);
expect(
storedPackageConfigsToAgentInputs([
storedPackagePoliciesToAgentInputs([
{
...mockPackageConfig,
...mockPackagePolicy,
package: {
name: 'mock-package',
title: 'Mock package',
@ -91,9 +91,9 @@ describe('Ingest Manager - storedPackageConfigsToAgentInputs', () => {
).toEqual([]);
expect(
storedPackageConfigsToAgentInputs([
storedPackagePoliciesToAgentInputs([
{
...mockPackageConfig,
...mockPackagePolicy,
inputs: [{ ...mockInput, enabled: false }],
},
])
@ -102,9 +102,9 @@ describe('Ingest Manager - storedPackageConfigsToAgentInputs', () => {
it('returns agent inputs', () => {
expect(
storedPackageConfigsToAgentInputs([
storedPackagePoliciesToAgentInputs([
{
...mockPackageConfig,
...mockPackagePolicy,
package: {
name: 'mock-package',
title: 'Mock package',
@ -116,7 +116,7 @@ describe('Ingest Manager - storedPackageConfigsToAgentInputs', () => {
).toEqual([
{
id: 'some-uuid',
name: 'mock-package-config',
name: 'mock-package-policy',
type: 'test-logs',
data_stream: { namespace: 'default' },
use_output: 'default',
@ -144,9 +144,9 @@ describe('Ingest Manager - storedPackageConfigsToAgentInputs', () => {
it('returns agent inputs without disabled streams', () => {
expect(
storedPackageConfigsToAgentInputs([
storedPackagePoliciesToAgentInputs([
{
...mockPackageConfig,
...mockPackagePolicy,
inputs: [
{
...mockInput,
@ -158,7 +158,7 @@ describe('Ingest Manager - storedPackageConfigsToAgentInputs', () => {
).toEqual([
{
id: 'some-uuid',
name: 'mock-package-config',
name: 'mock-package-policy',
type: 'test-logs',
data_stream: { namespace: 'default' },
use_output: 'default',

View file

@ -3,29 +3,29 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { PackageConfig, FullAgentConfigInput, FullAgentConfigInputStream } from '../types';
import { PackagePolicy, FullAgentPolicyInput, FullAgentPolicyInputStream } from '../types';
import { DEFAULT_OUTPUT } from '../constants';
export const storedPackageConfigsToAgentInputs = (
packageConfigs: PackageConfig[]
): FullAgentConfigInput[] => {
const fullInputs: FullAgentConfigInput[] = [];
export const storedPackagePoliciesToAgentInputs = (
packagePolicies: PackagePolicy[]
): FullAgentPolicyInput[] => {
const fullInputs: FullAgentPolicyInput[] = [];
packageConfigs.forEach((packageConfig) => {
if (!packageConfig.enabled || !packageConfig.inputs || !packageConfig.inputs.length) {
packagePolicies.forEach((packagePolicy) => {
if (!packagePolicy.enabled || !packagePolicy.inputs || !packagePolicy.inputs.length) {
return;
}
packageConfig.inputs.forEach((input) => {
packagePolicy.inputs.forEach((input) => {
if (!input.enabled) {
return;
}
const fullInput: FullAgentConfigInput = {
id: packageConfig.id || packageConfig.name,
name: packageConfig.name,
const fullInput: FullAgentPolicyInput = {
id: packagePolicy.id || packagePolicy.name,
name: packagePolicy.name,
type: input.type,
data_stream: {
namespace: packageConfig.namespace || 'default',
namespace: packagePolicy.namespace || 'default',
},
use_output: DEFAULT_OUTPUT.name,
...Object.entries(input.config || {}).reduce((acc, [key, { value }]) => {
@ -35,7 +35,7 @@ export const storedPackageConfigsToAgentInputs = (
streams: input.streams
.filter((stream) => stream.enabled)
.map((stream) => {
const fullStream: FullAgentConfigInputStream = {
const fullStream: FullAgentPolicyInputStream = {
id: stream.id,
data_stream: stream.data_stream,
...stream.compiled_stream,
@ -48,11 +48,11 @@ export const storedPackageConfigsToAgentInputs = (
}),
};
if (packageConfig.package) {
if (packagePolicy.package) {
fullInput.meta = {
package: {
name: packageConfig.package.name,
version: packageConfig.package.version,
name: packagePolicy.package.name,
version: packagePolicy.package.version,
},
};
}

View file

@ -4,9 +4,9 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { PackageInfo, InstallationStatus } from '../types';
import { packageToPackageConfig, packageToPackageConfigInputs } from './package_to_config';
import { packageToPackagePolicy, packageToPackagePolicyInputs } from './package_to_package_policy';
describe('Ingest Manager - packageToConfig', () => {
describe('Ingest Manager - packageToPackagePolicy', () => {
const mockPackage: PackageInfo = {
name: 'mock-package',
title: 'Mock package',
@ -31,15 +31,15 @@ describe('Ingest Manager - packageToConfig', () => {
status: InstallationStatus.notInstalled,
};
describe('packageToPackageConfigInputs', () => {
describe('packageToPackagePolicyInputs', () => {
it('returns empty array for packages with no config templates', () => {
expect(packageToPackageConfigInputs(mockPackage)).toEqual([]);
expect(packageToPackageConfigInputs({ ...mockPackage, config_templates: [] })).toEqual([]);
expect(packageToPackagePolicyInputs(mockPackage)).toEqual([]);
expect(packageToPackagePolicyInputs({ ...mockPackage, config_templates: [] })).toEqual([]);
});
it('returns empty array for packages with a config template but no inputs', () => {
expect(
packageToPackageConfigInputs(({
packageToPackagePolicyInputs(({
...mockPackage,
config_templates: [{ inputs: [] }],
} as unknown) as PackageInfo)
@ -48,13 +48,13 @@ describe('Ingest Manager - packageToConfig', () => {
it('returns inputs with no streams for packages with no streams', () => {
expect(
packageToPackageConfigInputs(({
packageToPackagePolicyInputs(({
...mockPackage,
config_templates: [{ inputs: [{ type: 'foo' }] }],
} as unknown) as PackageInfo)
).toEqual([{ type: 'foo', enabled: true, streams: [] }]);
expect(
packageToPackageConfigInputs(({
packageToPackagePolicyInputs(({
...mockPackage,
config_templates: [{ inputs: [{ type: 'foo' }, { type: 'bar' }] }],
} as unknown) as PackageInfo)
@ -66,7 +66,7 @@ describe('Ingest Manager - packageToConfig', () => {
it('returns inputs with streams for packages with streams', () => {
expect(
packageToPackageConfigInputs(({
packageToPackagePolicyInputs(({
...mockPackage,
datasets: [
{ type: 'logs', name: 'foo', streams: [{ input: 'foo' }] },
@ -100,7 +100,7 @@ describe('Ingest Manager - packageToConfig', () => {
it('returns inputs with streams configurations for packages with stream vars', () => {
expect(
packageToPackageConfigInputs(({
packageToPackagePolicyInputs(({
...mockPackage,
datasets: [
{
@ -171,7 +171,7 @@ describe('Ingest Manager - packageToConfig', () => {
it('returns inputs with streams configurations for packages with stream and input vars', () => {
expect(
packageToPackageConfigInputs(({
packageToPackagePolicyInputs(({
...mockPackage,
datasets: [
{
@ -315,10 +315,10 @@ describe('Ingest Manager - packageToConfig', () => {
});
});
describe('packageToPackageConfig', () => {
it('returns package config with default name', () => {
expect(packageToPackageConfig(mockPackage, '1', '2')).toEqual({
config_id: '1',
describe('packageToPackagePolicy', () => {
it('returns package policy with default name', () => {
expect(packageToPackagePolicy(mockPackage, '1', '2')).toEqual({
policy_id: '1',
namespace: '',
enabled: true,
inputs: [],
@ -331,13 +331,13 @@ describe('Ingest Manager - packageToConfig', () => {
},
});
});
it('returns package config with custom name', () => {
expect(packageToPackageConfig(mockPackage, '1', '2', 'default', 'pkgConfig-1')).toEqual({
config_id: '1',
it('returns package policy with custom name', () => {
expect(packageToPackagePolicy(mockPackage, '1', '2', 'default', 'pkgPolicy-1')).toEqual({
policy_id: '1',
namespace: 'default',
enabled: true,
inputs: [],
name: 'pkgConfig-1',
name: 'pkgPolicy-1',
output_id: '2',
package: {
name: 'mock-package',
@ -346,21 +346,21 @@ describe('Ingest Manager - packageToConfig', () => {
},
});
});
it('returns package config with namespace and description', () => {
it('returns package policy with namespace and description', () => {
expect(
packageToPackageConfig(
packageToPackagePolicy(
mockPackage,
'1',
'2',
'mock-namespace',
'pkgConfig-1',
'pkgPolicy-1',
'Test description'
)
).toEqual({
config_id: '1',
policy_id: '1',
enabled: true,
inputs: [],
name: 'pkgConfig-1',
name: 'pkgPolicy-1',
namespace: 'mock-namespace',
description: 'Test description',
output_id: '2',
@ -371,20 +371,20 @@ describe('Ingest Manager - packageToConfig', () => {
},
});
});
it('returns package config with inputs', () => {
it('returns package policy with inputs', () => {
const mockPackageWithConfigTemplates = ({
...mockPackage,
config_templates: [{ inputs: [{ type: 'foo' }] }],
} as unknown) as PackageInfo;
expect(
packageToPackageConfig(mockPackageWithConfigTemplates, '1', '2', 'default', 'pkgConfig-1')
packageToPackagePolicy(mockPackageWithConfigTemplates, '1', '2', 'default', 'pkgPolicy-1')
).toEqual({
config_id: '1',
policy_id: '1',
namespace: 'default',
enabled: true,
inputs: [{ type: 'foo', enabled: true, streams: [] }],
name: 'pkgConfig-1',
name: 'pkgPolicy-1',
output_id: '2',
package: {
name: 'mock-package',

View file

@ -8,12 +8,12 @@ import {
RegistryConfigTemplate,
RegistryVarsEntry,
RegistryStream,
PackageConfig,
PackageConfigConfigRecord,
PackageConfigConfigRecordEntry,
PackageConfigInput,
PackageConfigInputStream,
NewPackageConfig,
PackagePolicy,
PackagePolicyConfigRecord,
PackagePolicyConfigRecordEntry,
PackagePolicyInput,
PackagePolicyInputStream,
NewPackagePolicy,
} from '../types';
const getStreamsForInputType = (
@ -40,27 +40,27 @@ const getStreamsForInputType = (
};
/*
* This service creates a package config inputs definition from defaults provided in package info
* This service creates a package policy inputs definition from defaults provided in package info
*/
export const packageToPackageConfigInputs = (packageInfo: PackageInfo): PackageConfig['inputs'] => {
const inputs: PackageConfig['inputs'] = [];
export const packageToPackagePolicyInputs = (packageInfo: PackageInfo): PackagePolicy['inputs'] => {
const inputs: PackagePolicy['inputs'] = [];
// Assume package will only ever ship one package config template for now
const packageConfigTemplate: RegistryConfigTemplate | null =
// Assume package will only ever ship one package policy template for now
const packagePolicyTemplate: RegistryConfigTemplate | null =
packageInfo.config_templates && packageInfo.config_templates[0]
? packageInfo.config_templates[0]
: null;
// Create package config input property
if (packageConfigTemplate?.inputs?.length) {
// Map each package package config input to agent config package config input
packageConfigTemplate.inputs.forEach((packageInput) => {
// Create package policy input property
if (packagePolicyTemplate?.inputs?.length) {
// Map each package package policy input to agent policy package policy input
packagePolicyTemplate.inputs.forEach((packageInput) => {
// Reduces registry var def into config object entry
const varsReducer = (
configObject: PackageConfigConfigRecord,
configObject: PackagePolicyConfigRecord,
registryVar: RegistryVarsEntry
): PackageConfigConfigRecord => {
const configEntry: PackageConfigConfigRecordEntry = {
): PackagePolicyConfigRecord => {
const configEntry: PackagePolicyConfigRecordEntry = {
value: !registryVar.default && registryVar.multi ? [] : registryVar.default,
};
if (registryVar.type) {
@ -70,12 +70,12 @@ export const packageToPackageConfigInputs = (packageInfo: PackageInfo): PackageC
return configObject;
};
// Map each package input stream into package config input stream
const streams: PackageConfigInputStream[] = getStreamsForInputType(
// Map each package input stream into package policy input stream
const streams: PackagePolicyInputStream[] = getStreamsForInputType(
packageInput.type,
packageInfo
).map((packageStream) => {
const stream: PackageConfigInputStream = {
const stream: PackagePolicyInputStream = {
id: `${packageInput.type}-${packageStream.data_stream.dataset}`,
enabled: packageStream.enabled === false ? false : true,
data_stream: packageStream.data_stream,
@ -86,7 +86,7 @@ export const packageToPackageConfigInputs = (packageInfo: PackageInfo): PackageC
return stream;
});
const input: PackageConfigInput = {
const input: PackagePolicyInput = {
type: packageInput.type,
enabled: streams.length ? !!streams.find((stream) => stream.enabled) : true,
streams,
@ -104,23 +104,23 @@ export const packageToPackageConfigInputs = (packageInfo: PackageInfo): PackageC
};
/**
* Builds a `NewPackageConfig` structure based on a package
* Builds a `NewPackagePolicy` structure based on a package
*
* @param packageInfo
* @param configId
* @param agentPolicyId
* @param outputId
* @param packageConfigName
* @param packagePolicyName
*/
export const packageToPackageConfig = (
export const packageToPackagePolicy = (
packageInfo: PackageInfo,
configId: string,
agentPolicyId: string,
outputId: string,
namespace: string = '',
packageConfigName?: string,
packagePolicyName?: string,
description?: string
): NewPackageConfig => {
): NewPackagePolicy => {
return {
name: packageConfigName || `${packageInfo.name}-1`,
name: packagePolicyName || `${packageInfo.name}-1`,
namespace,
description,
package: {
@ -129,8 +129,8 @@ export const packageToPackageConfig = (
version: packageInfo.version,
},
enabled: true,
config_id: configId,
policy_id: agentPolicyId,
output_id: outputId,
inputs: packageToPackageConfigInputs(packageInfo),
inputs: packageToPackagePolicyInputs(packageInfo),
};
};

View file

@ -6,8 +6,8 @@
import {
EPM_API_ROOT,
EPM_API_ROUTES,
PACKAGE_CONFIG_API_ROUTES,
AGENT_CONFIG_API_ROUTES,
PACKAGE_POLICY_API_ROUTES,
AGENT_POLICY_API_ROUTES,
DATA_STREAM_API_ROUTES,
FLEET_SETUP_API_ROUTES,
AGENT_API_ROUTES,
@ -48,61 +48,61 @@ export const epmRouteService = {
},
};
export const packageConfigRouteService = {
export const packagePolicyRouteService = {
getListPath: () => {
return PACKAGE_CONFIG_API_ROUTES.LIST_PATTERN;
return PACKAGE_POLICY_API_ROUTES.LIST_PATTERN;
},
getInfoPath: (packageConfigId: string) => {
return PACKAGE_CONFIG_API_ROUTES.INFO_PATTERN.replace('{packageConfigId}', packageConfigId);
getInfoPath: (packagePolicyId: string) => {
return PACKAGE_POLICY_API_ROUTES.INFO_PATTERN.replace('{packagePolicyId}', packagePolicyId);
},
getCreatePath: () => {
return PACKAGE_CONFIG_API_ROUTES.CREATE_PATTERN;
return PACKAGE_POLICY_API_ROUTES.CREATE_PATTERN;
},
getUpdatePath: (packageConfigId: string) => {
return PACKAGE_CONFIG_API_ROUTES.UPDATE_PATTERN.replace('{packageConfigId}', packageConfigId);
getUpdatePath: (packagePolicyId: string) => {
return PACKAGE_POLICY_API_ROUTES.UPDATE_PATTERN.replace('{packagePolicyId}', packagePolicyId);
},
getDeletePath: () => {
return PACKAGE_CONFIG_API_ROUTES.DELETE_PATTERN;
return PACKAGE_POLICY_API_ROUTES.DELETE_PATTERN;
},
};
export const agentConfigRouteService = {
export const agentPolicyRouteService = {
getListPath: () => {
return AGENT_CONFIG_API_ROUTES.LIST_PATTERN;
return AGENT_POLICY_API_ROUTES.LIST_PATTERN;
},
getInfoPath: (agentConfigId: string) => {
return AGENT_CONFIG_API_ROUTES.INFO_PATTERN.replace('{agentConfigId}', agentConfigId);
getInfoPath: (agentPolicyId: string) => {
return AGENT_POLICY_API_ROUTES.INFO_PATTERN.replace('{agentPolicyId}', agentPolicyId);
},
getCreatePath: () => {
return AGENT_CONFIG_API_ROUTES.CREATE_PATTERN;
return AGENT_POLICY_API_ROUTES.CREATE_PATTERN;
},
getUpdatePath: (agentConfigId: string) => {
return AGENT_CONFIG_API_ROUTES.UPDATE_PATTERN.replace('{agentConfigId}', agentConfigId);
getUpdatePath: (agentPolicyId: string) => {
return AGENT_POLICY_API_ROUTES.UPDATE_PATTERN.replace('{agentPolicyId}', agentPolicyId);
},
getCopyPath: (agentConfigId: string) => {
return AGENT_CONFIG_API_ROUTES.COPY_PATTERN.replace('{agentConfigId}', agentConfigId);
getCopyPath: (agentPolicyId: string) => {
return AGENT_POLICY_API_ROUTES.COPY_PATTERN.replace('{agentPolicyId}', agentPolicyId);
},
getDeletePath: () => {
return AGENT_CONFIG_API_ROUTES.DELETE_PATTERN;
return AGENT_POLICY_API_ROUTES.DELETE_PATTERN;
},
getInfoFullPath: (agentConfigId: string) => {
return AGENT_CONFIG_API_ROUTES.FULL_INFO_PATTERN.replace('{agentConfigId}', agentConfigId);
getInfoFullPath: (agentPolicyId: string) => {
return AGENT_POLICY_API_ROUTES.FULL_INFO_PATTERN.replace('{agentPolicyId}', agentPolicyId);
},
getInfoFullDownloadPath: (agentConfigId: string) => {
return AGENT_CONFIG_API_ROUTES.FULL_INFO_DOWNLOAD_PATTERN.replace(
'{agentConfigId}',
agentConfigId
getInfoFullDownloadPath: (agentPolicyId: string) => {
return AGENT_POLICY_API_ROUTES.FULL_INFO_DOWNLOAD_PATTERN.replace(
'{agentPolicyId}',
agentPolicyId
);
},
};

View file

@ -22,8 +22,8 @@ export interface IngestManagerConfigType {
host?: string;
ca_sha256?: string;
};
agentConfigRolloutRateLimitIntervalMs: number;
agentConfigRolloutRateLimitRequestPerInterval: number;
agentPolicyRolloutRateLimitIntervalMs: number;
agentPolicyRolloutRateLimitRequestPerInterval: number;
};
}

View file

@ -64,7 +64,7 @@ export interface NewAgentEvent {
payload?: any;
agent_id: string;
action_id?: string;
config_id?: string;
policy_id?: string;
stream_id?: string;
}
@ -89,8 +89,8 @@ interface AgentBase {
access_api_key_id?: string;
default_api_key?: string;
default_api_key_id?: string;
config_id?: string;
config_revision?: number | null;
policy_id?: string;
policy_revision?: number | null;
last_checkin?: string;
last_checkin_status?: 'error' | 'online' | 'degraded';
user_provided_metadata: AgentMetadata;

View file

@ -3,15 +3,15 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { PackageConfig, PackageConfigPackage } from './package_config';
import { PackagePolicy, PackagePolicyPackage } from './package_policy';
import { Output } from './output';
export enum AgentConfigStatus {
export enum AgentPolicyStatus {
Active = 'active',
Inactive = 'inactive',
}
export interface NewAgentConfig {
export interface NewAgentPolicy {
name: string;
namespace: string;
description?: string;
@ -19,18 +19,18 @@ export interface NewAgentConfig {
monitoring_enabled?: Array<'logs' | 'metrics'>;
}
export interface AgentConfig extends NewAgentConfig {
export interface AgentPolicy extends NewAgentPolicy {
id: string;
status: AgentConfigStatus;
package_configs: string[] | PackageConfig[];
status: AgentPolicyStatus;
package_policies: string[] | PackagePolicy[];
updated_at: string;
updated_by: string;
revision: number;
}
export type AgentConfigSOAttributes = Omit<AgentConfig, 'id'>;
export type AgentPolicySOAttributes = Omit<AgentPolicy, 'id'>;
export interface FullAgentConfigInputStream {
export interface FullAgentPolicyInputStream {
id: string;
data_stream: {
dataset: string;
@ -39,28 +39,28 @@ export interface FullAgentConfigInputStream {
[key: string]: any;
}
export interface FullAgentConfigInput {
export interface FullAgentPolicyInput {
id: string;
name: string;
type: string;
data_stream: { namespace: string };
use_output: string;
meta?: {
package?: Pick<PackageConfigPackage, 'name' | 'version'>;
package?: Pick<PackagePolicyPackage, 'name' | 'version'>;
[key: string]: unknown;
};
streams: FullAgentConfigInputStream[];
streams: FullAgentPolicyInputStream[];
[key: string]: any;
}
export interface FullAgentConfig {
export interface FullAgentPolicy {
id: string;
outputs: {
[key: string]: Pick<Output, 'type' | 'hosts' | 'ca_sha256' | 'api_key'> & {
[key: string]: any;
};
};
inputs: FullAgentConfigInput[];
inputs: FullAgentPolicyInput[];
revision?: number;
agent?: {
monitoring: {

View file

@ -3,7 +3,6 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { SavedObjectAttributes } from 'src/core/public';
export interface EnrollmentAPIKey {
id: string;
@ -11,13 +10,8 @@ export interface EnrollmentAPIKey {
api_key: string;
name?: string;
active: boolean;
config_id?: string;
policy_id?: string;
created_at: string;
}
export interface EnrollmentAPIKeySOAttributes extends SavedObjectAttributes {
api_key_id: string;
api_key: string;
name?: string;
active: boolean;
config_id?: string;
}
export type EnrollmentAPIKeySOAttributes = Omit<EnrollmentAPIKey, 'id'>;

View file

@ -5,8 +5,8 @@
*/
export * from './agent';
export * from './agent_config';
export * from './package_config';
export * from './agent_policy';
export * from './package_policy';
export * from './data_stream';
export * from './output';
export * from './epm';

View file

@ -1,73 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
export interface PackageConfigPackage {
name: string;
title: string;
version: string;
}
export interface PackageConfigConfigRecordEntry {
type?: string;
value?: any;
}
export type PackageConfigConfigRecord = Record<string, PackageConfigConfigRecordEntry>;
export interface NewPackageConfigInputStream {
id: string;
enabled: boolean;
data_stream: {
dataset: string;
type: string;
};
vars?: PackageConfigConfigRecord;
config?: PackageConfigConfigRecord;
}
export interface PackageConfigInputStream extends NewPackageConfigInputStream {
compiled_stream?: any;
}
export interface NewPackageConfigInput {
type: string;
enabled: boolean;
vars?: PackageConfigConfigRecord;
config?: PackageConfigConfigRecord;
streams: NewPackageConfigInputStream[];
}
export interface PackageConfigInput extends Omit<NewPackageConfigInput, 'streams'> {
streams: PackageConfigInputStream[];
}
export interface NewPackageConfig {
name: string;
description?: string;
namespace: string;
enabled: boolean;
config_id: string;
output_id: string;
package?: PackageConfigPackage;
inputs: NewPackageConfigInput[];
}
export interface UpdatePackageConfig extends NewPackageConfig {
version?: string;
}
export interface PackageConfig extends Omit<NewPackageConfig, 'inputs'> {
id: string;
inputs: PackageConfigInput[];
version?: string;
revision: number;
updated_at: string;
updated_by: string;
created_at: string;
created_by: string;
}
export type PackageConfigSOAttributes = Omit<PackageConfig, 'id' | 'version'>;

View file

@ -0,0 +1,73 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
export interface PackagePolicyPackage {
name: string;
title: string;
version: string;
}
export interface PackagePolicyConfigRecordEntry {
type?: string;
value?: any;
}
export type PackagePolicyConfigRecord = Record<string, PackagePolicyConfigRecordEntry>;
export interface NewPackagePolicyInputStream {
id: string;
enabled: boolean;
data_stream: {
dataset: string;
type: string;
};
vars?: PackagePolicyConfigRecord;
config?: PackagePolicyConfigRecord;
}
export interface PackagePolicyInputStream extends NewPackagePolicyInputStream {
compiled_stream?: any;
}
export interface NewPackagePolicyInput {
type: string;
enabled: boolean;
vars?: PackagePolicyConfigRecord;
config?: PackagePolicyConfigRecord;
streams: NewPackagePolicyInputStream[];
}
export interface PackagePolicyInput extends Omit<NewPackagePolicyInput, 'streams'> {
streams: PackagePolicyInputStream[];
}
export interface NewPackagePolicy {
name: string;
description?: string;
namespace: string;
enabled: boolean;
policy_id: string;
output_id: string;
package?: PackagePolicyPackage;
inputs: NewPackagePolicyInput[];
}
export interface UpdatePackagePolicy extends NewPackagePolicy {
version?: string;
}
export interface PackagePolicy extends Omit<NewPackagePolicy, 'inputs'> {
id: string;
inputs: PackagePolicyInput[];
version?: string;
revision: number;
updated_at: string;
updated_by: string;
created_at: string;
created_by: string;
}
export type PackagePolicySOAttributes = Omit<PackagePolicy, 'id' | 'version'>;

View file

@ -118,7 +118,7 @@ export interface PutAgentReassignRequest {
params: {
agentId: string;
};
body: { config_id: string };
body: { policy_id: string };
}
export interface PutAgentReassignResponse {
@ -161,7 +161,7 @@ export interface UpdateAgentRequest {
export interface GetAgentStatusRequest {
query: {
configId?: string;
policyId?: string;
};
}

View file

@ -1,83 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { AgentConfig, NewAgentConfig, FullAgentConfig } from '../models';
import { ListWithKuery } from './common';
export interface GetAgentConfigsRequest {
query: ListWithKuery & {
full?: boolean;
};
}
export type GetAgentConfigsResponseItem = AgentConfig & { agents?: number };
export interface GetAgentConfigsResponse {
items: GetAgentConfigsResponseItem[];
total: number;
page: number;
perPage: number;
success: boolean;
}
export interface GetOneAgentConfigRequest {
params: {
agentConfigId: string;
};
}
export interface GetOneAgentConfigResponse {
item: AgentConfig;
success: boolean;
}
export interface CreateAgentConfigRequest {
body: NewAgentConfig;
}
export interface CreateAgentConfigResponse {
item: AgentConfig;
success: boolean;
}
export type UpdateAgentConfigRequest = GetOneAgentConfigRequest & {
body: NewAgentConfig;
};
export interface UpdateAgentConfigResponse {
item: AgentConfig;
success: boolean;
}
export interface CopyAgentConfigRequest {
body: Pick<AgentConfig, 'name' | 'description'>;
}
export interface CopyAgentConfigResponse {
item: AgentConfig;
success: boolean;
}
export interface DeleteAgentConfigRequest {
body: {
agentConfigId: string;
};
}
export interface DeleteAgentConfigResponse {
id: string;
success: boolean;
}
export interface GetFullAgentConfigRequest {
params: {
agentConfigId: string;
};
}
export interface GetFullAgentConfigResponse {
item: FullAgentConfig;
success: boolean;
}

View file

@ -0,0 +1,83 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { AgentPolicy, NewAgentPolicy, FullAgentPolicy } from '../models';
import { ListWithKuery } from './common';
export interface GetAgentPoliciesRequest {
query: ListWithKuery & {
full?: boolean;
};
}
export type GetAgentPoliciesResponseItem = AgentPolicy & { agents?: number };
export interface GetAgentPoliciesResponse {
items: GetAgentPoliciesResponseItem[];
total: number;
page: number;
perPage: number;
success: boolean;
}
export interface GetOneAgentPolicyRequest {
params: {
agentPolicyId: string;
};
}
export interface GetOneAgentPolicyResponse {
item: AgentPolicy;
success: boolean;
}
export interface CreateAgentPolicyRequest {
body: NewAgentPolicy;
}
export interface CreateAgentPolicyResponse {
item: AgentPolicy;
success: boolean;
}
export type UpdateAgentPolicyRequest = GetOneAgentPolicyRequest & {
body: NewAgentPolicy;
};
export interface UpdateAgentPolicyResponse {
item: AgentPolicy;
success: boolean;
}
export interface CopyAgentPolicyRequest {
body: Pick<AgentPolicy, 'name' | 'description'>;
}
export interface CopyAgentPolicyResponse {
item: AgentPolicy;
success: boolean;
}
export interface DeleteAgentPolicyRequest {
body: {
agentPolicyId: string;
};
}
export interface DeleteAgentPolicyResponse {
id: string;
success: boolean;
}
export interface GetFullAgentPolicyRequest {
params: {
agentPolicyId: string;
};
}
export interface GetFullAgentPolicyResponse {
item: FullAgentPolicy;
success: boolean;
}

View file

@ -47,7 +47,7 @@ export interface DeleteEnrollmentAPIKeyResponse {
export interface PostEnrollmentAPIKeyRequest {
body: {
name?: string;
config_id: string;
policy_id: string;
expiration?: string;
};
}

View file

@ -4,10 +4,10 @@
* you may not use this file except in compliance with the Elastic License.
*/
export * from './common';
export * from './package_config';
export * from './package_policy';
export * from './data_stream';
export * from './agent';
export * from './agent_config';
export * from './agent_policy';
export * from './fleet_setup';
export * from './epm';
export * from './enrollment_api_key';

View file

@ -1,59 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { PackageConfig, NewPackageConfig, UpdatePackageConfig } from '../models';
export interface GetPackageConfigsRequest {
query: {
page: number;
perPage: number;
kuery?: string;
};
}
export interface GetPackageConfigsResponse {
items: PackageConfig[];
total: number;
page: number;
perPage: number;
success: boolean;
}
export interface GetOnePackageConfigRequest {
params: {
packageConfigId: string;
};
}
export interface GetOnePackageConfigResponse {
item: PackageConfig;
success: boolean;
}
export interface CreatePackageConfigRequest {
body: NewPackageConfig;
}
export interface CreatePackageConfigResponse {
item: PackageConfig;
success: boolean;
}
export type UpdatePackageConfigRequest = GetOnePackageConfigRequest & {
body: UpdatePackageConfig;
};
export type UpdatePackageConfigResponse = CreatePackageConfigResponse;
export interface DeletePackageConfigsRequest {
body: {
packageConfigIds: string[];
};
}
export type DeletePackageConfigsResponse = Array<{
id: string;
success: boolean;
}>;

View file

@ -0,0 +1,59 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { PackagePolicy, NewPackagePolicy, UpdatePackagePolicy } from '../models';
export interface GetPackagePoliciesRequest {
query: {
page: number;
perPage: number;
kuery?: string;
};
}
export interface GetPackagePoliciesResponse {
items: PackagePolicy[];
total: number;
page: number;
perPage: number;
success: boolean;
}
export interface GetOnePackagePolicyRequest {
params: {
packagePolicyId: string;
};
}
export interface GetOnePackagePolicyResponse {
item: PackagePolicy;
success: boolean;
}
export interface CreatePackagePolicyRequest {
body: NewPackagePolicy;
}
export interface CreatePackagePolicyResponse {
item: PackagePolicy;
success: boolean;
}
export type UpdatePackagePolicyRequest = GetOnePackagePolicyRequest & {
body: UpdatePackagePolicy;
};
export type UpdatePackagePolicyResponse = CreatePackagePolicyResponse;
export interface DeletePackagePoliciesRequest {
body: {
packagePolicyIds: string[];
};
}
export type DeletePackagePoliciesResponse = Array<{
id: string;
success: boolean;
}>;

View file

@ -17,7 +17,7 @@ This action is send when a new policy is available, the policy is available unde
"id": "action_id_1",
"data": {
"policy": {
"id": "config_id",
"id": "policy_id",
"outputs": {
"default": {
"api_key": "slfhsdlfhjjkshfkjh:sdfsdfsdfsdf",

View file

@ -45,7 +45,7 @@ The API returns the following:
"item": {
"id": "a4937110-e53e-11e9-934f-47a8e38a522c",
"active": true,
"config_id": "default",
"policy_id": "default",
"type": "PERMANENT",
"enrolled_at": "2019-10-02T18:01:22.337Z",
"user_provided_metadata": {},

View file

@ -5,12 +5,12 @@ Overall documentation of Ingest Management is now maintained in the `elastic/sta
This section is to define terms used across ingest management.
## Package Config
## Package policy
A package config is a definition on how to collect data from a service, for example `nginx`. A package config contains
A package policy is a definition on how to collect data from a service, for example `nginx`. A package policy contains
definitions for one or multiple inputs and each input can contain one or multiple streams.
With the example of the nginx Package Config, it contains two inputs: `logs` and `nginx/metrics`. Logs and metrics are collected
With the example of the nginx Package policy, it contains two inputs: `logs` and `nginx/metrics`. Logs and metrics are collected
differently. The `logs` input contains two streams, `access` and `error`, the `nginx/metrics` input contains the stubstatus stream.
## Data Stream
@ -20,7 +20,7 @@ ingesting data and the setup of Elasticsearch.
## Elastic Agent
A single, unified agent that users can deploy to hosts or containers. It controls which data is collected from the host or containers and where the data is sent. It will run Beats, Endpoint or other monitoring programs as needed. It can operate standalone or pull a configuration policy from Fleet.
A single, unified agent that users can deploy to hosts or containers. It controls which data is collected from the host or containers and where the data is sent. It will run Beats, Endpoint or other monitoring programs as needed. It can operate standalone or pull an agent policy from Fleet.
## Elastic Package Registry
@ -29,8 +29,7 @@ More details about the registry can be found [here](https://github.com/elastic/p
## Fleet
Fleet is the part of the Ingest Manager UI in Kibana that handles the part of enrolling Elastic Agents,
managing agents and sending configurations to the Elastic Agent.
Fleet is the part of the Ingest Manager UI in Kibana that handles the part of enrolling Elastic Agents, managing agents and sending policies to the Elastic Agent.
## Indexing Strategy
@ -40,15 +39,15 @@ the index strategy is sent to Data Streams.
## Input
An input is the configuration unit in an Agent Config that defines the options on how to collect data from
An input is the configuration unit in an Agent policy that defines the options on how to collect data from
an endpoint. This could be username / password which are need to authenticate with a service or a host url
as an example.
An input is part of a Package Config and contains streams.
An input is part of a Package policy and contains streams.
## Integration
An integration is a package with the type integration. An integration package has at least 1 package config
An integration is a package with the type integration. An integration package has at least 1 package policy
and usually collects data from / about a service.
## Namespace
@ -60,9 +59,9 @@ A user-specified string that will be used to part of the index name in Elasticse
A package contains all the assets for the Elastic Stack. A more detailed definition of a
package can be found under https://github.com/elastic/package-registry.
Besides the assets, a package contains the package config definitions with its inputs and streams.
Besides the assets, a package contains the package policy definitions with its inputs and streams.
## Stream
A stream is a configuration unit in the Elastic Agent config. A stream is part of an input and defines how the data
A stream is a configuration unit in the Elastic Agent policy. A stream is part of an input and defines how the data
fetched by this input should be processed and which Data Stream to send it to.

View file

@ -5,26 +5,26 @@ Overall documentation of Ingest Management is now maintained in the `elastic/sta
When upgrading a package between a bugfix or a minor version, no breaking changes should happen. Upgrading a package has the following effect:
* Removal of existing dashboards
* Installation of new dashboards
* Write new ingest pipelines with the version
* Write new Elasticsearch alias templates
* Trigger a rollover for all the affected indices
- Removal of existing dashboards
- Installation of new dashboards
- Write new ingest pipelines with the version
- Write new Elasticsearch alias templates
- Trigger a rollover for all the affected indices
The new ingest pipeline is expected to still work with the data coming from older configurations. In most cases this means some of the fields can be missing. For this to work, each event must contain the version of config / package it is coming from to make such a decision.
The new ingest pipeline is expected to still work with the data coming from older policies. In most cases this means some of the fields can be missing. For this to work, each event must contain the version of policy / package it is coming from to make such a decision.
In case of a breaking change in the data structure, the new ingest pipeline is also expected to deal with this change. In case there are breaking changes which cannot be dealt with in an ingest pipeline, a new package has to be created.
Each package lists its minimal required agent version. In case there are agents enrolled with an older version, the user is notified to upgrade these agents as otherwise the new configs cannot be rolled out.
Each package lists its minimal required agent version. In case there are agents enrolled with an older version, the user is notified to upgrade these agents as otherwise the new policies cannot be rolled out.
# Generated assets
When a package is installed or upgraded, certain Kibana and Elasticsearch assets are generated from . These follow the naming conventions explained above (see "indexing strategy") and contain configuration for the elastic stack that makes ingesting and displaying data work with as little user interaction as possible.
When a package is installed or upgraded, certain Kibana and Elasticsearch assets are generated from . These follow the naming conventions explained above (see "indexing strategy") and contain configuration for the Elastic stack that makes ingesting and displaying data work with as little user interaction as possible.
## Elasticsearch Index Templates
### Generation
* Index templates are generated from `YAML` files contained in the package.
* There is one index template per dataset.
* For the generation of an index template, all `yml` files contained in the package subdirectory `dataset/DATASET_NAME/fields/` are used.
- Index templates are generated from `YAML` files contained in the package.
- There is one index template per dataset.
- For the generation of an index template, all `yml` files contained in the package subdirectory `dataset/DATASET_NAME/fields/` are used.

View file

@ -5,7 +5,7 @@
Fleet workflow:
- an agent enroll to fleet using an enrollment token.
- Every n seconds agent is polling the checkin API to send events and check for new configuration
- Every n seconds agent is polling the checkin API to send events and check for new policy
### Agent enrollment
@ -13,7 +13,7 @@ An agent must enroll using the REST Api provided by fleet.
When an agent enroll Fleet:
- verify the Enrollment token is a valid ES API key
- retrieve the Saved Object (SO) associated to this api key id (this SO contains the configuration|policy id)
- retrieve the Saved Object (SO) associated to this api key id (this SO contains the agent policy id)
- create an ES ApiKey unique to the agent for accessing kibana during checkin
- create an ES ApiKey per output to send logs and metrics to the output
- Save the new agent in a SO with keys encrypted inside the agent SO object
@ -22,15 +22,15 @@ When an agent enroll Fleet:
### Agent checkin
Agent are going to poll the checkin API to send events and check for new configration. To checkin agent are going to use the REST Api provided by fleet.
Agent are going to poll the checkin API to send events and check for new policy. To checkin agent are going to use the REST Api provided by fleet.
When an agent checkin fleet:
- verify the access token is a valid ES API key
- retrieve the agent (SO associated to this api key id)
- Insert events SO
- If the Agent configuration has been updated since last checkin
- generate the agent config
- If the Agent policy has been updated since last checkin
- generate the agent policy
- Create the missing API key for agent -> ES communication
- Save the new agent (with last checkin date) in a SavedObject with keys encrypted inside the agent
@ -44,6 +44,6 @@ An agent can acknowledge one or multiple actions by calling `POST /api/ingest_ma
## Other interactions
### Agent Configuration update
### Agent policy update
When a configuration is updated, every SO agent running this configuration is updated with a timestamp of the latest config.
When a policy is updated, every SO agent running this policy is updated with a timestamp of the latest policy.

View file

@ -12,8 +12,8 @@ sequenceDiagram
Note right of SavedObjects: encrypted SO here
end
alt If configuration updated since last checkin
Fleet API->>SavedObjects: getAgentConfiguration(configId)
alt If policy updated since last checkin
Fleet API->>SavedObjects: getAgentPolicy(agentPolicyId)
opt If there is not API Key for default output
Fleet API->>Elasticsearch: createAgentESApiKey()
@ -34,4 +34,4 @@ sequenceDiagram
end
Fleet API->>Agent: actions|agent config
Fleet API->>Agent: actions|agent policy

View file

@ -1,11 +1,11 @@
classDiagram
agent_configs "1" -- "*" package_configs
agent_configs "1" -- "*" enrollment_api_keys
agent_configs "1" -- "*" agents : is used
agent_configs "*" -- "*" outputs
agent_policies "1" -- "*" package_policies
agent_policies "1" -- "*" enrollment_api_keys
agent_policies "1" -- "*" agents : is used
agent_policies "*" -- "*" outputs
agents "1" -- "*" agent_events
agents "1" -- "*" agent_events
package "1" -- "*" package_configs
package "1" -- "*" package_policies
class package {
installed
@ -14,11 +14,11 @@ classDiagram
class agents {
status
access_api_key_id
config_id
policy_id
last_checkin
local_metadata
user_provided_metadata
actions // Encrypted contains new agent config
actions // Encrypted contains new agent policy
default_api_key // Encrypted
}
@ -28,7 +28,7 @@ classDiagram
subtype
agent_id
action_id
config_id
policy_id
stream_id
timestamp
message
@ -36,18 +36,18 @@ classDiagram
data
}
class agent_configs {
package_configs // package_config ids
class agent_policies {
package_policies // package_policy ids
name
namespace
description
status
}
class package_configs {
class package_policies {
name
namespace
config_id
policy_id
enabled
package
output_id
@ -64,7 +64,7 @@ classDiagram
}
class enrollment_api_keys {
config_id
policy_id
api_key_id
api_key // Encrypted
}

View file

@ -82,7 +82,7 @@ export const TutorialDirectoryNotice: TutorialDirectoryNoticeComponent = memo(()
<FormattedMessage
id="xpack.ingestManager.homeIntegration.tutorialDirectory.noticeText"
defaultMessage="The Elastic Agent provides a simple, unified way to add monitoring for logs, metrics, and other types of data to your hosts.
You no longer need to install multiple Beats and other agents, which makes it easier and faster to deploy configurations across your infrastructure.
You no longer need to install multiple Beats and other agents, which makes it easier and faster to deploy policies across your infrastructure.
For more information, read our {blogPostLink}."
values={{
blogPostLink: (

View file

@ -28,7 +28,7 @@ export const TutorialModuleNotice: TutorialModuleNoticeComponent = memo(({ modul
<FormattedMessage
id="xpack.ingestManager.homeIntegration.tutorialModule.noticeText"
defaultMessage="{notePrefix} a newer version of this module is {availableAsIntegrationLink} in Ingest Manager Beta.
To learn more about agent configurations and the new Elastic Agent, read our {blogPostLink}."
To learn more about agent policies and the new Elastic Agent, read our {blogPostLink}."
values={{
notePrefix: (
<strong>

View file

@ -167,7 +167,7 @@ export const SettingFlyout: React.FunctionComponent<Props> = ({ onClose }) => {
'xpack.ingestManager.settings.integrationUpgradeEnabledFieldLabel',
{
defaultMessage:
'Automatically update integrations to the latest version to receive the latest assets. Agent configurations may need to be updated in order to use new features.',
'Automatically update integrations to the latest version to receive the latest assets. Agent policies may need to be updated in order to use new features.',
}
),
},
@ -210,7 +210,7 @@ export const SettingFlyout: React.FunctionComponent<Props> = ({ onClose }) => {
<EuiText color="subdued" size="s">
<FormattedMessage
id="xpack.ingestManager.settings.globalOutputDescription"
defaultMessage="The global output is applied to all agent configurations and specifies where data is sent."
defaultMessage="The global output is applied to all agent policies and specifies where data is sent."
/>
</EuiText>
<EuiSpacer size="m" />

View file

@ -7,11 +7,11 @@ export {
PLUGIN_ID,
EPM_API_ROUTES,
AGENT_API_ROUTES,
AGENT_CONFIG_SAVED_OBJECT_TYPE,
AGENT_POLICY_SAVED_OBJECT_TYPE,
AGENT_EVENT_SAVED_OBJECT_TYPE,
AGENT_SAVED_OBJECT_TYPE,
ENROLLMENT_API_KEYS_SAVED_OBJECT_TYPE,
PACKAGE_CONFIG_SAVED_OBJECT_TYPE,
PACKAGE_POLICY_SAVED_OBJECT_TYPE,
} from '../../../../common';
export * from './page_paths';

View file

@ -9,17 +9,17 @@ export type StaticPage =
| 'integrations'
| 'integrations_all'
| 'integrations_installed'
| 'configurations'
| 'configurations_list'
| 'policies'
| 'policies_list'
| 'fleet'
| 'fleet_enrollment_tokens'
| 'data_streams';
export type DynamicPage =
| 'integration_details'
| 'configuration_details'
| 'add_integration_from_configuration'
| 'add_integration_to_configuration'
| 'policy_details'
| 'add_integration_from_policy'
| 'add_integration_to_policy'
| 'edit_integration'
| 'fleet_agent_list'
| 'fleet_agent_details';
@ -40,13 +40,13 @@ export const PAGE_ROUTING_PATHS = {
integrations_all: '/integrations',
integrations_installed: '/integrations/installed',
integration_details: '/integrations/detail/:pkgkey/:panel?',
configurations: '/configs',
configurations_list: '/configs',
configuration_details: '/configs/:configId/:tabId?',
configuration_details_settings: '/configs/:configId/settings',
add_integration_from_configuration: '/configs/:configId/add-integration',
add_integration_to_configuration: '/integrations/:pkgkey/add-integration',
edit_integration: '/configs/:configId/edit-integration/:packageConfigId',
policies: '/policies',
policies_list: '/policies',
policy_details: '/policies/:policyId/:tabId?',
policy_details_settings: '/policies/:policyId/settings',
add_integration_from_policy: '/policies/:policyId/add-integration',
add_integration_to_policy: '/integrations/:pkgkey/add-integration',
edit_integration: '/policies/:policyId/edit-integration/:packagePolicyId',
fleet: '/fleet',
fleet_agent_list: '/fleet/agents',
fleet_agent_details: '/fleet/agents/:agentId/:tabId?',
@ -68,13 +68,13 @@ export const pagePathGetters: {
integrations_installed: () => '/integrations/installed',
integration_details: ({ pkgkey, panel }) =>
`/integrations/detail/${pkgkey}${panel ? `/${panel}` : ''}`,
configurations: () => '/configs',
configurations_list: () => '/configs',
configuration_details: ({ configId, tabId }) => `/configs/${configId}${tabId ? `/${tabId}` : ''}`,
add_integration_from_configuration: ({ configId }) => `/configs/${configId}/add-integration`,
add_integration_to_configuration: ({ pkgkey }) => `/integrations/${pkgkey}/add-integration`,
edit_integration: ({ configId, packageConfigId }) =>
`/configs/${configId}/edit-integration/${packageConfigId}`,
policies: () => '/policies',
policies_list: () => '/policies',
policy_details: ({ policyId, tabId }) => `/policies/${policyId}${tabId ? `/${tabId}` : ''}`,
add_integration_from_policy: ({ policyId }) => `/policies/${policyId}/add-integration`,
add_integration_to_policy: ({ pkgkey }) => `/integrations/${pkgkey}/add-integration`,
edit_integration: ({ policyId, packagePolicyId }) =>
`/policies/${policyId}/edit-integration/${packagePolicyId}`,
fleet: () => '/fleet',
fleet_agent_list: ({ kuery }) => `/fleet/agents${kuery ? `?kuery=${kuery}` : ''}`,
fleet_agent_details: ({ agentId, tabId }) =>

View file

@ -72,51 +72,51 @@ const breadcrumbGetters: {
},
{ text: pkgTitle },
],
configurations: () => [
policies: () => [
BASE_BREADCRUMB,
{
text: i18n.translate('xpack.ingestManager.breadcrumbs.configurationsPageTitle', {
defaultMessage: 'Configurations',
text: i18n.translate('xpack.ingestManager.breadcrumbs.policiesPageTitle', {
defaultMessage: 'Policies',
}),
},
],
configurations_list: () => [
policies_list: () => [
BASE_BREADCRUMB,
{
text: i18n.translate('xpack.ingestManager.breadcrumbs.configurationsPageTitle', {
defaultMessage: 'Configurations',
text: i18n.translate('xpack.ingestManager.breadcrumbs.policiesPageTitle', {
defaultMessage: 'Policies',
}),
},
],
configuration_details: ({ configName }) => [
policy_details: ({ policyName }) => [
BASE_BREADCRUMB,
{
href: pagePathGetters.configurations(),
text: i18n.translate('xpack.ingestManager.breadcrumbs.configurationsPageTitle', {
defaultMessage: 'Configurations',
href: pagePathGetters.policies(),
text: i18n.translate('xpack.ingestManager.breadcrumbs.policiesPageTitle', {
defaultMessage: 'Policies',
}),
},
{ text: configName },
{ text: policyName },
],
add_integration_from_configuration: ({ configName, configId }) => [
add_integration_from_policy: ({ policyName, policyId }) => [
BASE_BREADCRUMB,
{
href: pagePathGetters.configurations(),
text: i18n.translate('xpack.ingestManager.breadcrumbs.configurationsPageTitle', {
defaultMessage: 'Configurations',
href: pagePathGetters.policies(),
text: i18n.translate('xpack.ingestManager.breadcrumbs.policiesPageTitle', {
defaultMessage: 'Policies',
}),
},
{
href: pagePathGetters.configuration_details({ configId }),
text: configName,
href: pagePathGetters.policy_details({ policyId }),
text: policyName,
},
{
text: i18n.translate('xpack.ingestManager.breadcrumbs.addPackageConfigPageTitle', {
text: i18n.translate('xpack.ingestManager.breadcrumbs.addPackagePolicyPageTitle', {
defaultMessage: 'Add integration',
}),
},
],
add_integration_to_configuration: ({ pkgTitle, pkgkey }) => [
add_integration_to_policy: ({ pkgTitle, pkgkey }) => [
BASE_BREADCRUMB,
{
href: pagePathGetters.integrations(),
@ -129,25 +129,25 @@ const breadcrumbGetters: {
text: pkgTitle,
},
{
text: i18n.translate('xpack.ingestManager.breadcrumbs.addPackageConfigPageTitle', {
text: i18n.translate('xpack.ingestManager.breadcrumbs.addPackagePolicyPageTitle', {
defaultMessage: 'Add integration',
}),
},
],
edit_integration: ({ configName, configId }) => [
edit_integration: ({ policyName, policyId }) => [
BASE_BREADCRUMB,
{
href: pagePathGetters.configurations(),
text: i18n.translate('xpack.ingestManager.breadcrumbs.configurationsPageTitle', {
defaultMessage: 'Configurations',
href: pagePathGetters.policies(),
text: i18n.translate('xpack.ingestManager.breadcrumbs.policiesPageTitle', {
defaultMessage: 'Policies',
}),
},
{
href: pagePathGetters.configuration_details({ configId }),
text: configName,
href: pagePathGetters.policy_details({ policyId }),
text: policyName,
},
{
text: i18n.translate('xpack.ingestManager.breadcrumbs.editPackageConfigPageTitle', {
text: i18n.translate('xpack.ingestManager.breadcrumbs.editPackagePolicyPageTitle', {
defaultMessage: 'Edit integration',
}),
},

View file

@ -1,109 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import {
useRequest,
sendRequest,
useConditionalRequest,
SendConditionalRequestConfig,
} from './use_request';
import { agentConfigRouteService } from '../../services';
import {
GetAgentConfigsRequest,
GetAgentConfigsResponse,
GetOneAgentConfigResponse,
GetFullAgentConfigResponse,
CreateAgentConfigRequest,
CreateAgentConfigResponse,
UpdateAgentConfigRequest,
UpdateAgentConfigResponse,
CopyAgentConfigRequest,
CopyAgentConfigResponse,
DeleteAgentConfigRequest,
DeleteAgentConfigResponse,
} from '../../types';
export const useGetAgentConfigs = (query?: GetAgentConfigsRequest['query']) => {
return useRequest<GetAgentConfigsResponse>({
path: agentConfigRouteService.getListPath(),
method: 'get',
query,
});
};
export const useGetOneAgentConfig = (agentConfigId: string | undefined) => {
return useConditionalRequest<GetOneAgentConfigResponse>({
path: agentConfigId ? agentConfigRouteService.getInfoPath(agentConfigId) : undefined,
method: 'get',
shouldSendRequest: !!agentConfigId,
} as SendConditionalRequestConfig);
};
export const useGetOneAgentConfigFull = (agentConfigId: string) => {
return useRequest<GetFullAgentConfigResponse>({
path: agentConfigRouteService.getInfoFullPath(agentConfigId),
method: 'get',
});
};
export const sendGetOneAgentConfigFull = (
agentConfigId: string,
query: { standalone?: boolean } = {}
) => {
return sendRequest<GetFullAgentConfigResponse>({
path: agentConfigRouteService.getInfoFullPath(agentConfigId),
method: 'get',
query,
});
};
export const sendGetOneAgentConfig = (agentConfigId: string) => {
return sendRequest<GetOneAgentConfigResponse>({
path: agentConfigRouteService.getInfoPath(agentConfigId),
method: 'get',
});
};
export const sendCreateAgentConfig = (
body: CreateAgentConfigRequest['body'],
{ withSysMonitoring }: { withSysMonitoring: boolean } = { withSysMonitoring: false }
) => {
return sendRequest<CreateAgentConfigResponse>({
path: agentConfigRouteService.getCreatePath(),
method: 'post',
body: JSON.stringify(body),
query: withSysMonitoring ? { sys_monitoring: true } : {},
});
};
export const sendUpdateAgentConfig = (
agentConfigId: string,
body: UpdateAgentConfigRequest['body']
) => {
return sendRequest<UpdateAgentConfigResponse>({
path: agentConfigRouteService.getUpdatePath(agentConfigId),
method: 'put',
body: JSON.stringify(body),
});
};
export const sendCopyAgentConfig = (
agentConfigId: string,
body: CopyAgentConfigRequest['body']
) => {
return sendRequest<CopyAgentConfigResponse>({
path: agentConfigRouteService.getCopyPath(agentConfigId),
method: 'post',
body: JSON.stringify(body),
});
};
export const sendDeleteAgentConfig = (body: DeleteAgentConfigRequest['body']) => {
return sendRequest<DeleteAgentConfigResponse>({
path: agentConfigRouteService.getDeletePath(),
method: 'post',
body: JSON.stringify(body),
});
};

View file

@ -0,0 +1,109 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import {
useRequest,
sendRequest,
useConditionalRequest,
SendConditionalRequestConfig,
} from './use_request';
import { agentPolicyRouteService } from '../../services';
import {
GetAgentPoliciesRequest,
GetAgentPoliciesResponse,
GetOneAgentPolicyResponse,
GetFullAgentPolicyResponse,
CreateAgentPolicyRequest,
CreateAgentPolicyResponse,
UpdateAgentPolicyRequest,
UpdateAgentPolicyResponse,
CopyAgentPolicyRequest,
CopyAgentPolicyResponse,
DeleteAgentPolicyRequest,
DeleteAgentPolicyResponse,
} from '../../types';
export const useGetAgentPolicies = (query?: GetAgentPoliciesRequest['query']) => {
return useRequest<GetAgentPoliciesResponse>({
path: agentPolicyRouteService.getListPath(),
method: 'get',
query,
});
};
export const useGetOneAgentPolicy = (agentPolicyId: string | undefined) => {
return useConditionalRequest<GetOneAgentPolicyResponse>({
path: agentPolicyId ? agentPolicyRouteService.getInfoPath(agentPolicyId) : undefined,
method: 'get',
shouldSendRequest: !!agentPolicyId,
} as SendConditionalRequestConfig);
};
export const useGetOneAgentPolicyFull = (agentPolicyId: string) => {
return useRequest<GetFullAgentPolicyResponse>({
path: agentPolicyRouteService.getInfoFullPath(agentPolicyId),
method: 'get',
});
};
export const sendGetOneAgentPolicyFull = (
agentPolicyId: string,
query: { standalone?: boolean } = {}
) => {
return sendRequest<GetFullAgentPolicyResponse>({
path: agentPolicyRouteService.getInfoFullPath(agentPolicyId),
method: 'get',
query,
});
};
export const sendGetOneAgentPolicy = (agentPolicyId: string) => {
return sendRequest<GetOneAgentPolicyResponse>({
path: agentPolicyRouteService.getInfoPath(agentPolicyId),
method: 'get',
});
};
export const sendCreateAgentPolicy = (
body: CreateAgentPolicyRequest['body'],
{ withSysMonitoring }: { withSysMonitoring: boolean } = { withSysMonitoring: false }
) => {
return sendRequest<CreateAgentPolicyResponse>({
path: agentPolicyRouteService.getCreatePath(),
method: 'post',
body: JSON.stringify(body),
query: withSysMonitoring ? { sys_monitoring: true } : {},
});
};
export const sendUpdateAgentPolicy = (
agentPolicyId: string,
body: UpdateAgentPolicyRequest['body']
) => {
return sendRequest<UpdateAgentPolicyResponse>({
path: agentPolicyRouteService.getUpdatePath(agentPolicyId),
method: 'put',
body: JSON.stringify(body),
});
};
export const sendCopyAgentPolicy = (
agentPolicyId: string,
body: CopyAgentPolicyRequest['body']
) => {
return sendRequest<CopyAgentPolicyResponse>({
path: agentPolicyRouteService.getCopyPath(agentPolicyId),
method: 'post',
body: JSON.stringify(body),
});
};
export const sendDeleteAgentPolicy = (body: DeleteAgentPolicyRequest['body']) => {
return sendRequest<DeleteAgentPolicyResponse>({
path: agentPolicyRouteService.getDeletePath(),
method: 'post',
body: JSON.stringify(body),
});
};

View file

@ -4,8 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/
export { setHttpClient, sendRequest, useRequest } from './use_request';
export * from './agent_config';
export * from './package_config';
export * from './agent_policy';
export * from './package_policy';
export * from './data_stream';
export * from './agents';
export * from './enrollment_api_keys';

View file

@ -1,62 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { sendRequest, useRequest } from './use_request';
import { packageConfigRouteService } from '../../services';
import {
CreatePackageConfigRequest,
CreatePackageConfigResponse,
UpdatePackageConfigRequest,
UpdatePackageConfigResponse,
} from '../../types';
import {
DeletePackageConfigsRequest,
DeletePackageConfigsResponse,
GetPackageConfigsRequest,
GetPackageConfigsResponse,
GetOnePackageConfigResponse,
} from '../../../../../common/types/rest_spec';
export const sendCreatePackageConfig = (body: CreatePackageConfigRequest['body']) => {
return sendRequest<CreatePackageConfigResponse>({
path: packageConfigRouteService.getCreatePath(),
method: 'post',
body: JSON.stringify(body),
});
};
export const sendUpdatePackageConfig = (
packageConfigId: string,
body: UpdatePackageConfigRequest['body']
) => {
return sendRequest<UpdatePackageConfigResponse>({
path: packageConfigRouteService.getUpdatePath(packageConfigId),
method: 'put',
body: JSON.stringify(body),
});
};
export const sendDeletePackageConfig = (body: DeletePackageConfigsRequest['body']) => {
return sendRequest<DeletePackageConfigsResponse>({
path: packageConfigRouteService.getDeletePath(),
method: 'post',
body: JSON.stringify(body),
});
};
export function useGetPackageConfigs(query: GetPackageConfigsRequest['query']) {
return useRequest<GetPackageConfigsResponse>({
method: 'get',
path: packageConfigRouteService.getListPath(),
query,
});
}
export const sendGetOnePackageConfig = (packageConfigId: string) => {
return sendRequest<GetOnePackageConfigResponse>({
path: packageConfigRouteService.getInfoPath(packageConfigId),
method: 'get',
});
};

View file

@ -0,0 +1,62 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { sendRequest, useRequest } from './use_request';
import { packagePolicyRouteService } from '../../services';
import {
CreatePackagePolicyRequest,
CreatePackagePolicyResponse,
UpdatePackagePolicyRequest,
UpdatePackagePolicyResponse,
} from '../../types';
import {
DeletePackagePoliciesRequest,
DeletePackagePoliciesResponse,
GetPackagePoliciesRequest,
GetPackagePoliciesResponse,
GetOnePackagePolicyResponse,
} from '../../../../../common/types/rest_spec';
export const sendCreatePackagePolicy = (body: CreatePackagePolicyRequest['body']) => {
return sendRequest<CreatePackagePolicyResponse>({
path: packagePolicyRouteService.getCreatePath(),
method: 'post',
body: JSON.stringify(body),
});
};
export const sendUpdatePackagePolicy = (
packagePolicyId: string,
body: UpdatePackagePolicyRequest['body']
) => {
return sendRequest<UpdatePackagePolicyResponse>({
path: packagePolicyRouteService.getUpdatePath(packagePolicyId),
method: 'put',
body: JSON.stringify(body),
});
};
export const sendDeletePackagePolicy = (body: DeletePackagePoliciesRequest['body']) => {
return sendRequest<DeletePackagePoliciesResponse>({
path: packagePolicyRouteService.getDeletePath(),
method: 'post',
body: JSON.stringify(body),
});
};
export function useGetPackagePolicies(query: GetPackagePoliciesRequest['query']) {
return useRequest<GetPackagePoliciesResponse>({
method: 'get',
path: packagePolicyRouteService.getListPath(),
query,
});
}
export const sendGetOnePackagePolicy = (packagePolicyId: string) => {
return sendRequest<GetOnePackagePolicyResponse>({
path: packagePolicyRouteService.getInfoPath(packagePolicyId),
method: 'get',
});
};

View file

@ -21,7 +21,7 @@ import {
import { PAGE_ROUTING_PATHS } from './constants';
import { DefaultLayout, WithoutHeaderLayout } from './layouts';
import { Loading, Error } from './components';
import { IngestManagerOverview, EPMApp, AgentConfigApp, FleetApp, DataStreamApp } from './sections';
import { IngestManagerOverview, EPMApp, AgentPolicyApp, FleetApp, DataStreamApp } from './sections';
import { DepsContext, ConfigContext, useConfig } from './hooks';
import { PackageInstallProvider } from './sections/epm/hooks';
import { useCore, sendSetup, sendGetPermissionsCheck } from './hooks';
@ -190,9 +190,9 @@ const IngestManagerRoutes = memo<{ history: AppMountParameters['history']; basep
<EPMApp />
</DefaultLayout>
</Route>
<Route path={PAGE_ROUTING_PATHS.configurations}>
<DefaultLayout section="agent_config">
<AgentConfigApp />
<Route path={PAGE_ROUTING_PATHS.policies}>
<DefaultLayout section="agent_policy">
<AgentPolicyApp />
</DefaultLayout>
</Route>
<Route path={PAGE_ROUTING_PATHS.data_streams}>

View file

@ -77,13 +77,10 @@ export const DefaultLayout: React.FunctionComponent<Props> = ({
defaultMessage="Integrations"
/>
</EuiTab>
<EuiTab
isSelected={section === 'agent_config'}
href={getHref('configurations_list')}
>
<EuiTab isSelected={section === 'agent_policy'} href={getHref('policies_list')}>
<FormattedMessage
id="xpack.ingestManager.appNavigation.configurationsLinkText"
defaultMessage="Configurations"
id="xpack.ingestManager.appNavigation.policiesLinkText"
defaultMessage="Policies"
/>
</EuiTab>
<EuiTab

View file

@ -1,12 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
export { AgentConfigForm, agentConfigFormValidation } from './config_form';
export { AgentConfigDeleteProvider } from './config_delete_provider';
export { PackageConfigDeleteProvider } from './package_config_delete_provider';
export { LinkedAgentCount } from './linked_agent_count';
export { ConfirmDeployConfigModal } from './confirm_deploy_modal';
export { DangerEuiContextMenuItem } from './danger_eui_context_menu_item';
export { AgentConfigActionMenu } from './actions_menu';

View file

@ -1,61 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import React from 'react';
import { FormattedMessage } from '@kbn/i18n/react';
import { EuiEmptyPrompt, EuiText } from '@elastic/eui';
import { NewPackageConfig } from '../../../../types';
import { CreatePackageConfigFrom } from '../types';
export interface CustomConfigurePackageConfigProps {
packageName: string;
from: CreatePackageConfigFrom;
packageConfig: NewPackageConfig;
packageConfigId?: string;
}
/**
* Custom content type that external plugins can provide to Ingest's
* package config UI.
*/
export type CustomConfigurePackageConfigContent = React.FC<CustomConfigurePackageConfigProps>;
type AllowedPackageKey = 'endpoint';
const PackageConfigMapping: {
[key: string]: CustomConfigurePackageConfigContent;
} = {};
/**
* Plugins can call this function from the start lifecycle to
* register a custom component in the Ingest package config.
*/
export function registerPackageConfigComponent(
key: AllowedPackageKey,
value: CustomConfigurePackageConfigContent
) {
PackageConfigMapping[key] = value;
}
const EmptyPackageConfig: CustomConfigurePackageConfigContent = () => (
<EuiEmptyPrompt
iconType="checkInCircleFilled"
iconColor="secondary"
body={
<EuiText>
<p>
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.stepConfigure.noConfigOptionsMessage"
defaultMessage="Nothing to configure"
/>
</p>
</EuiText>
}
/>
);
export const CustomPackageConfig = (props: CustomConfigurePackageConfigProps) => {
const CustomPackageConfigContent = PackageConfigMapping[props.packageName] || EmptyPackageConfig;
return <CustomPackageConfigContent {...props} />;
};

View file

@ -1,8 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
export { PackageConfigsTable } from './package_configs/package_configs_table';
export { ConfigPackageConfigsView } from './package_configs';
export { ConfigSettingsView } from './settings';

View file

@ -1,23 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import React, { memo } from 'react';
import { AgentConfig, PackageConfig } from '../../../../../types';
import { NoPackageConfigs } from './no_package_configs';
import { PackageConfigsTable } from './package_configs_table';
export const ConfigPackageConfigsView = memo<{ config: AgentConfig }>(({ config }) => {
if (config.package_configs.length === 0) {
return <NoPackageConfigs configId={config.id} />;
}
return (
<PackageConfigsTable
config={config}
packageConfigs={(config.package_configs || []) as PackageConfig[]}
/>
);
});

View file

@ -1,36 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import React from 'react';
import { HashRouter as Router, Switch, Route } from 'react-router-dom';
import { PAGE_ROUTING_PATHS } from '../../constants';
import { useBreadcrumbs } from '../../hooks';
import { AgentConfigListPage } from './list_page';
import { AgentConfigDetailsPage } from './details_page';
import { CreatePackageConfigPage } from './create_package_config_page';
import { EditPackageConfigPage } from './edit_package_config_page';
export const AgentConfigApp: React.FunctionComponent = () => {
useBreadcrumbs('configurations');
return (
<Router>
<Switch>
<Route path={PAGE_ROUTING_PATHS.edit_integration}>
<EditPackageConfigPage />
</Route>
<Route path={PAGE_ROUTING_PATHS.add_integration_from_configuration}>
<CreatePackageConfigPage />
</Route>
<Route path={PAGE_ROUTING_PATHS.configuration_details}>
<AgentConfigDetailsPage />
</Route>
<Route path={PAGE_ROUTING_PATHS.configurations_list}>
<AgentConfigListPage />
</Route>
</Switch>
</Router>
);
};

View file

@ -6,22 +6,22 @@
import React, { memo, useState, useMemo } from 'react';
import { FormattedMessage } from '@kbn/i18n/react';
import { EuiContextMenuItem, EuiPortal } from '@elastic/eui';
import { AgentConfig } from '../../../types';
import { AgentPolicy } from '../../../types';
import { useCapabilities } from '../../../hooks';
import { ContextMenuActions } from '../../../components';
import { AgentEnrollmentFlyout } from '../../fleet/components';
import { ConfigYamlFlyout } from './config_yaml_flyout';
import { AgentConfigCopyProvider } from './config_copy_provider';
import { AgentPolicyYamlFlyout } from './agent_policy_yaml_flyout';
import { AgentPolicyCopyProvider } from './agent_policy_copy_provider';
export const AgentConfigActionMenu = memo<{
config: AgentConfig;
onCopySuccess?: (newAgentConfig: AgentConfig) => void;
export const AgentPolicyActionMenu = memo<{
agentPolicy: AgentPolicy;
onCopySuccess?: (newAgentPolicy: AgentPolicy) => void;
fullButton?: boolean;
enrollmentFlyoutOpenByDefault?: boolean;
onCancelEnrollment?: () => void;
}>(
({
config,
agentPolicy,
onCopySuccess,
fullButton = false,
enrollmentFlyoutOpenByDefault = false,
@ -42,21 +42,21 @@ export const AgentConfigActionMenu = memo<{
}, [onCancelEnrollment, setIsEnrollmentFlyoutOpen]);
return (
<AgentConfigCopyProvider>
{(copyAgentConfigPrompt) => {
<AgentPolicyCopyProvider>
{(copyAgentPolicyPrompt) => {
return (
<>
{isYamlFlyoutOpen ? (
<EuiPortal>
<ConfigYamlFlyout
configId={config.id}
<AgentPolicyYamlFlyout
policyId={agentPolicy.id}
onClose={() => setIsYamlFlyoutOpen(false)}
/>
</EuiPortal>
) : null}
{isEnrollmentFlyoutOpen && (
<EuiPortal>
<AgentEnrollmentFlyout agentConfigs={[config]} onClose={onClose} />
<AgentEnrollmentFlyout agentPolicies={[agentPolicy]} onClose={onClose} />
</EuiPortal>
)}
<ContextMenuActions
@ -69,7 +69,7 @@ export const AgentConfigActionMenu = memo<{
},
children: (
<FormattedMessage
id="xpack.ingestManager.agentConfigActionMenu.buttonText"
id="xpack.ingestManager.agentPolicyActionMenu.buttonText"
defaultMessage="Actions"
/>
),
@ -84,31 +84,31 @@ export const AgentConfigActionMenu = memo<{
key="enrollAgents"
>
<FormattedMessage
id="xpack.ingestManager.agentConfigActionMenu.enrollAgentActionText"
id="xpack.ingestManager.agentPolicyActionMenu.enrollAgentActionText"
defaultMessage="Add agent"
/>
</EuiContextMenuItem>,
<EuiContextMenuItem
icon="inspect"
onClick={() => setIsYamlFlyoutOpen(!isYamlFlyoutOpen)}
key="viewConfig"
key="viewPolicy"
>
<FormattedMessage
id="xpack.ingestManager.agentConfigActionMenu.viewConfigText"
defaultMessage="View config"
id="xpack.ingestManager.agentPolicyActionMenu.viewPolicyText"
defaultMessage="View policy"
/>
</EuiContextMenuItem>,
<EuiContextMenuItem
disabled={!hasWriteCapabilities}
icon="copy"
onClick={() => {
copyAgentConfigPrompt(config, onCopySuccess);
copyAgentPolicyPrompt(agentPolicy, onCopySuccess);
}}
key="copyConfig"
key="copyPolicy"
>
<FormattedMessage
id="xpack.ingestManager.agentConfigActionMenu.copyConfigActionText"
defaultMessage="Copy config"
id="xpack.ingestManager.agentPolicyActionMenu.copyPolicyActionText"
defaultMessage="Copy policy"
/>
</EuiContextMenuItem>,
]}
@ -116,7 +116,7 @@ export const AgentConfigActionMenu = memo<{
</>
);
}}
</AgentConfigCopyProvider>
</AgentPolicyCopyProvider>
);
}
);

View file

@ -8,63 +8,63 @@ import React, { Fragment, useRef, useState } from 'react';
import { EuiConfirmModal, EuiOverlayMask, EuiFormRow, EuiFieldText } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import { AgentConfig } from '../../../types';
import { sendCopyAgentConfig, useCore } from '../../../hooks';
import { AgentPolicy } from '../../../types';
import { sendCopyAgentPolicy, useCore } from '../../../hooks';
interface Props {
children: (copyAgentConfig: CopyAgentConfig) => React.ReactElement;
children: (copyAgentPolicy: CopyAgentPolicy) => React.ReactElement;
}
export type CopyAgentConfig = (agentConfig: AgentConfig, onSuccess?: OnSuccessCallback) => void;
export type CopyAgentPolicy = (agentPolicy: AgentPolicy, onSuccess?: OnSuccessCallback) => void;
type OnSuccessCallback = (newAgentConfig: AgentConfig) => void;
type OnSuccessCallback = (newAgentPolicy: AgentPolicy) => void;
export const AgentConfigCopyProvider: React.FunctionComponent<Props> = ({ children }) => {
export const AgentPolicyCopyProvider: React.FunctionComponent<Props> = ({ children }) => {
const { notifications } = useCore();
const [agentConfig, setAgentConfig] = useState<AgentConfig>();
const [newAgentConfig, setNewAgentConfig] = useState<Pick<AgentConfig, 'name' | 'description'>>();
const [agentPolicy, setAgentPolicy] = useState<AgentPolicy>();
const [newAgentPolicy, setNewAgentPolicy] = useState<Pick<AgentPolicy, 'name' | 'description'>>();
const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
const [isLoading, setIsLoading] = useState<boolean>(false);
const onSuccessCallback = useRef<OnSuccessCallback | null>(null);
const copyAgentConfigPrompt: CopyAgentConfig = (
agentConfigToCopy,
const copyAgentPolicyPrompt: CopyAgentPolicy = (
agentPolicyToCopy,
onSuccess = () => undefined
) => {
if (!agentConfigToCopy) {
throw new Error('No agent config specified to copy');
if (!agentPolicyToCopy) {
throw new Error('No agent policy specified to copy');
}
setIsModalOpen(true);
setAgentConfig(agentConfigToCopy);
setNewAgentConfig({
setAgentPolicy(agentPolicyToCopy);
setNewAgentPolicy({
name: i18n.translate(
'xpack.ingestManager.copyAgentConfig.confirmModal.defaultNewConfigName',
'xpack.ingestManager.copyAgentPolicy.confirmModal.defaultNewPolicyName',
{
defaultMessage: '{name} (copy)',
values: { name: agentConfigToCopy.name },
values: { name: agentPolicyToCopy.name },
}
),
description: agentConfigToCopy.description,
description: agentPolicyToCopy.description,
});
onSuccessCallback.current = onSuccess;
};
const closeModal = () => {
setAgentConfig(undefined);
setNewAgentConfig(undefined);
setAgentPolicy(undefined);
setNewAgentPolicy(undefined);
setIsLoading(false);
setIsModalOpen(false);
};
const copyAgentConfig = async () => {
const copyAgentPolicy = async () => {
setIsLoading(true);
try {
const { data } = await sendCopyAgentConfig(agentConfig!.id, newAgentConfig!);
const { data } = await sendCopyAgentPolicy(agentPolicy!.id, newAgentPolicy!);
if (data?.success) {
notifications.toasts.addSuccess(
i18n.translate('xpack.ingestManager.copyAgentConfig.successNotificationTitle', {
defaultMessage: 'Agent config copied',
i18n.translate('xpack.ingestManager.copyAgentPolicy.successNotificationTitle', {
defaultMessage: 'Agent policy copied',
})
);
if (onSuccessCallback.current) {
@ -74,16 +74,16 @@ export const AgentConfigCopyProvider: React.FunctionComponent<Props> = ({ childr
if (!data?.success) {
notifications.toasts.addDanger(
i18n.translate('xpack.ingestManager.copyAgentConfig.failureNotificationTitle', {
defaultMessage: "Error copying agent config '{id}'",
values: { id: agentConfig!.id },
i18n.translate('xpack.ingestManager.copyAgentPolicy.failureNotificationTitle', {
defaultMessage: "Error copying agent policy '{id}'",
values: { id: agentPolicy!.id },
})
);
}
} catch (e) {
notifications.toasts.addDanger(
i18n.translate('xpack.ingestManager.copyAgentConfig.fatalErrorNotificationTitle', {
defaultMessage: 'Error copying agent config',
i18n.translate('xpack.ingestManager.copyAgentPolicy.fatalErrorNotificationTitle', {
defaultMessage: 'Error copying agent policy',
})
);
}
@ -91,7 +91,7 @@ export const AgentConfigCopyProvider: React.FunctionComponent<Props> = ({ childr
};
const renderModal = () => {
if (!isModalOpen || !agentConfig || !newAgentConfig) {
if (!isModalOpen || !agentPolicy || !newAgentPolicy) {
return null;
}
@ -101,55 +101,55 @@ export const AgentConfigCopyProvider: React.FunctionComponent<Props> = ({ childr
title={
<span className="eui-textBreakWord">
<FormattedMessage
id="xpack.ingestManager.copyAgentConfig.confirmModal.copyConfigTitle"
defaultMessage="Copy '{name}' agent configuration"
id="xpack.ingestManager.copyAgentPolicy.confirmModal.copyPolicyTitle"
defaultMessage="Copy '{name}' agent policy"
values={{
name: agentConfig.name,
name: agentPolicy.name,
}}
/>
</span>
}
onCancel={closeModal}
onConfirm={copyAgentConfig}
onConfirm={copyAgentPolicy}
cancelButtonText={
<FormattedMessage
id="xpack.ingestManager.copyAgentConfig.confirmModal.cancelButtonLabel"
id="xpack.ingestManager.copyAgentPolicy.confirmModal.cancelButtonLabel"
defaultMessage="Cancel"
/>
}
confirmButtonText={
<FormattedMessage
id="xpack.ingestManager.copyAgentConfig.confirmModal.confirmButtonLabel"
defaultMessage="Copy configuration"
id="xpack.ingestManager.copyAgentPolicy.confirmModal.confirmButtonLabel"
defaultMessage="Copy policy"
/>
}
confirmButtonDisabled={isLoading || !newAgentConfig.name.trim()}
confirmButtonDisabled={isLoading || !newAgentPolicy.name.trim()}
>
<p>
<FormattedMessage
id="xpack.ingestManager.copyAgentConfig.confirmModal.copyConfigPrompt"
defaultMessage="Choose a name and description for your new agent configuration."
id="xpack.ingestManager.copyAgentPolicy.confirmModal.copyPolicyPrompt"
defaultMessage="Choose a name and description for your new agent policy."
/>
</p>
<EuiFormRow
label={
<FormattedMessage
id="xpack.ingestManager.copyAgentConfig.confirmModal.newNameLabel"
defaultMessage="New configuration name"
id="xpack.ingestManager.copyAgentPolicy.confirmModal.newNameLabel"
defaultMessage="New policy name"
/>
}
fullWidth
>
<EuiFieldText
fullWidth
value={newAgentConfig.name}
onChange={(e) => setNewAgentConfig({ ...newAgentConfig, name: e.target.value })}
value={newAgentPolicy.name}
onChange={(e) => setNewAgentPolicy({ ...newAgentPolicy, name: e.target.value })}
/>
</EuiFormRow>
<EuiFormRow
label={
<FormattedMessage
id="xpack.ingestManager.copyAgentConfig.confirmModal.newDescriptionLabel"
id="xpack.ingestManager.copyAgentPolicy.confirmModal.newDescriptionLabel"
defaultMessage="Description"
/>
}
@ -157,9 +157,9 @@ export const AgentConfigCopyProvider: React.FunctionComponent<Props> = ({ childr
>
<EuiFieldText
fullWidth
value={newAgentConfig.description}
value={newAgentPolicy.description}
onChange={(e) =>
setNewAgentConfig({ ...newAgentConfig, description: e.target.value })
setNewAgentPolicy({ ...newAgentPolicy, description: e.target.value })
}
/>
</EuiFormRow>
@ -170,7 +170,7 @@ export const AgentConfigCopyProvider: React.FunctionComponent<Props> = ({ childr
return (
<Fragment>
{children(copyAgentConfigPrompt)}
{children(copyAgentPolicyPrompt)}
{renderModal()}
</Fragment>
);

View file

@ -9,87 +9,87 @@ import { EuiConfirmModal, EuiOverlayMask, EuiCallOut } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import { AGENT_SAVED_OBJECT_TYPE } from '../../../constants';
import { sendDeleteAgentConfig, useCore, useConfig, sendRequest } from '../../../hooks';
import { sendDeleteAgentPolicy, useCore, useConfig, sendRequest } from '../../../hooks';
interface Props {
children: (deleteAgentConfig: DeleteAgentConfig) => React.ReactElement;
children: (deleteAgentPolicy: DeleteAgentPolicy) => React.ReactElement;
}
export type DeleteAgentConfig = (agentConfig: string, onSuccess?: OnSuccessCallback) => void;
export type DeleteAgentPolicy = (agentPolicy: string, onSuccess?: OnSuccessCallback) => void;
type OnSuccessCallback = (agentConfigDeleted: string) => void;
type OnSuccessCallback = (agentPolicyDeleted: string) => void;
export const AgentConfigDeleteProvider: React.FunctionComponent<Props> = ({ children }) => {
export const AgentPolicyDeleteProvider: React.FunctionComponent<Props> = ({ children }) => {
const { notifications } = useCore();
const {
fleet: { enabled: isFleetEnabled },
} = useConfig();
const [agentConfig, setAgentConfig] = useState<string>();
const [agentPolicy, setAgentPolicy] = useState<string>();
const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
const [isLoadingAgentsCount, setIsLoadingAgentsCount] = useState<boolean>(false);
const [agentsCount, setAgentsCount] = useState<number>(0);
const [isLoading, setIsLoading] = useState<boolean>(false);
const onSuccessCallback = useRef<OnSuccessCallback | null>(null);
const deleteAgentConfigPrompt: DeleteAgentConfig = (
agentConfigToDelete,
const deleteAgentPolicyPrompt: DeleteAgentPolicy = (
agentPolicyToDelete,
onSuccess = () => undefined
) => {
if (!agentConfigToDelete) {
throw new Error('No agent config specified for deletion');
if (!agentPolicyToDelete) {
throw new Error('No agent policy specified for deletion');
}
setIsModalOpen(true);
setAgentConfig(agentConfigToDelete);
fetchAgentsCount(agentConfigToDelete);
setAgentPolicy(agentPolicyToDelete);
fetchAgentsCount(agentPolicyToDelete);
onSuccessCallback.current = onSuccess;
};
const closeModal = () => {
setAgentConfig(undefined);
setAgentPolicy(undefined);
setIsLoading(false);
setIsLoadingAgentsCount(false);
setIsModalOpen(false);
};
const deleteAgentConfig = async () => {
const deleteAgentPolicy = async () => {
setIsLoading(true);
try {
const { data } = await sendDeleteAgentConfig({
agentConfigId: agentConfig!,
const { data } = await sendDeleteAgentPolicy({
agentPolicyId: agentPolicy!,
});
if (data?.success) {
notifications.toasts.addSuccess(
i18n.translate('xpack.ingestManager.deleteAgentConfig.successSingleNotificationTitle', {
defaultMessage: "Deleted agent config '{id}'",
values: { id: agentConfig },
i18n.translate('xpack.ingestManager.deleteAgentPolicy.successSingleNotificationTitle', {
defaultMessage: "Deleted agent policy '{id}'",
values: { id: agentPolicy },
})
);
if (onSuccessCallback.current) {
onSuccessCallback.current(agentConfig!);
onSuccessCallback.current(agentPolicy!);
}
}
if (!data?.success) {
notifications.toasts.addDanger(
i18n.translate('xpack.ingestManager.deleteAgentConfig.failureSingleNotificationTitle', {
defaultMessage: "Error deleting agent config '{id}'",
values: { id: agentConfig },
i18n.translate('xpack.ingestManager.deleteAgentPolicy.failureSingleNotificationTitle', {
defaultMessage: "Error deleting agent policy '{id}'",
values: { id: agentPolicy },
})
);
}
} catch (e) {
notifications.toasts.addDanger(
i18n.translate('xpack.ingestManager.deleteAgentConfig.fatalErrorNotificationTitle', {
defaultMessage: 'Error deleting agent config',
i18n.translate('xpack.ingestManager.deleteAgentPolicy.fatalErrorNotificationTitle', {
defaultMessage: 'Error deleting agent policy',
})
);
}
closeModal();
};
const fetchAgentsCount = async (agentConfigToCheck: string) => {
const fetchAgentsCount = async (agentPolicyToCheck: string) => {
if (!isFleetEnabled || isLoadingAgentsCount) {
return;
}
@ -98,7 +98,7 @@ export const AgentConfigDeleteProvider: React.FunctionComponent<Props> = ({ chil
path: `/api/ingest_manager/fleet/agents`,
method: 'get',
query: {
kuery: `${AGENT_SAVED_OBJECT_TYPE}.config_id : ${agentConfigToCheck}`,
kuery: `${AGENT_SAVED_OBJECT_TYPE}.policy_id : ${agentPolicyToCheck}`,
},
});
setAgentsCount(data?.total || 0);
@ -115,28 +115,28 @@ export const AgentConfigDeleteProvider: React.FunctionComponent<Props> = ({ chil
<EuiConfirmModal
title={
<FormattedMessage
id="xpack.ingestManager.deleteAgentConfig.confirmModal.deleteConfigTitle"
defaultMessage="Delete this agent configuration?"
id="xpack.ingestManager.deleteAgentPolicy.confirmModal.deletePolicyTitle"
defaultMessage="Delete this agent policy?"
/>
}
onCancel={closeModal}
onConfirm={deleteAgentConfig}
onConfirm={deleteAgentPolicy}
cancelButtonText={
<FormattedMessage
id="xpack.ingestManager.deleteAgentConfig.confirmModal.cancelButtonLabel"
id="xpack.ingestManager.deleteAgentPolicy.confirmModal.cancelButtonLabel"
defaultMessage="Cancel"
/>
}
confirmButtonText={
isLoading || isLoadingAgentsCount ? (
<FormattedMessage
id="xpack.ingestManager.deleteAgentConfig.confirmModal.loadingButtonLabel"
id="xpack.ingestManager.deleteAgentPolicy.confirmModal.loadingButtonLabel"
defaultMessage="Loading…"
/>
) : (
<FormattedMessage
id="xpack.ingestManager.deleteAgentConfig.confirmModal.confirmButtonLabel"
defaultMessage="Delete configuration"
id="xpack.ingestManager.deleteAgentPolicy.confirmModal.confirmButtonLabel"
defaultMessage="Delete policy"
/>
)
}
@ -145,22 +145,22 @@ export const AgentConfigDeleteProvider: React.FunctionComponent<Props> = ({ chil
>
{isLoadingAgentsCount ? (
<FormattedMessage
id="xpack.ingestManager.deleteAgentConfig.confirmModal.loadingAgentsCountMessage"
id="xpack.ingestManager.deleteAgentPolicy.confirmModal.loadingAgentsCountMessage"
defaultMessage="Checking amount of affected agents…"
/>
) : agentsCount ? (
<EuiCallOut
color="danger"
title={i18n.translate(
'xpack.ingestManager.deleteAgentConfig.confirmModal.affectedAgentsTitle',
'xpack.ingestManager.deleteAgentPolicy.confirmModal.affectedAgentsTitle',
{
defaultMessage: 'Configuration in use',
defaultMessage: 'Policy in use',
}
)}
>
<FormattedMessage
id="xpack.ingestManager.deleteAgentConfig.confirmModal.affectedAgentsMessage"
defaultMessage="{agentsCount, plural, one {# agent is} other {# agents are}} assigned to this agent configuration. Unassign these agents before deleting this configuration."
id="xpack.ingestManager.deleteAgentPolicy.confirmModal.affectedAgentsMessage"
defaultMessage="{agentsCount, plural, one {# agent is} other {# agents are}} assigned to this agent policy. Unassign these agents before deleting this policy."
values={{
agentsCount,
}}
@ -168,7 +168,7 @@ export const AgentConfigDeleteProvider: React.FunctionComponent<Props> = ({ chil
</EuiCallOut>
) : (
<FormattedMessage
id="xpack.ingestManager.deleteAgentConfig.confirmModal.irreversibleMessage"
id="xpack.ingestManager.deleteAgentPolicy.confirmModal.irreversibleMessage"
defaultMessage="This action cannot be undone."
/>
)}
@ -179,7 +179,7 @@ export const AgentConfigDeleteProvider: React.FunctionComponent<Props> = ({ chil
return (
<Fragment>
{children(deleteAgentConfigPrompt)}
{children(deleteAgentPolicyPrompt)}
{renderModal()}
</Fragment>
);

View file

@ -23,8 +23,8 @@ import {
import { FormattedMessage } from '@kbn/i18n/react';
import { i18n } from '@kbn/i18n';
import styled from 'styled-components';
import { NewAgentConfig, AgentConfig } from '../../../types';
import { AgentConfigDeleteProvider } from './config_delete_provider';
import { NewAgentPolicy, AgentPolicy } from '../../../types';
import { AgentPolicyDeleteProvider } from './agent_policy_delete_provider';
interface ValidationResults {
[key: string]: JSX.Element[];
@ -36,24 +36,24 @@ const StyledEuiAccordion = styled(EuiAccordion)`
}
`;
export const agentConfigFormValidation = (
agentConfig: Partial<NewAgentConfig | AgentConfig>
export const agentPolicyFormValidation = (
agentPolicy: Partial<NewAgentPolicy | AgentPolicy>
): ValidationResults => {
const errors: ValidationResults = {};
if (!agentConfig.name?.trim()) {
if (!agentPolicy.name?.trim()) {
errors.name = [
<FormattedMessage
id="xpack.ingestManager.agentConfigForm.nameRequiredErrorMessage"
defaultMessage="Agent config name is required"
id="xpack.ingestManager.agentPolicyForm.nameRequiredErrorMessage"
defaultMessage="Agent policy name is required"
/>,
];
}
if (!agentConfig.namespace?.trim()) {
if (!agentPolicy.namespace?.trim()) {
errors.namespace = [
<FormattedMessage
id="xpack.ingestManager.agentConfigForm.namespaceRequiredErrorMessage"
id="xpack.ingestManager.agentPolicyForm.namespaceRequiredErrorMessage"
defaultMessage="A namespace is required"
/>,
];
@ -63,8 +63,8 @@ export const agentConfigFormValidation = (
};
interface Props {
agentConfig: Partial<NewAgentConfig | AgentConfig>;
updateAgentConfig: (u: Partial<NewAgentConfig | AgentConfig>) => void;
agentPolicy: Partial<NewAgentPolicy | AgentPolicy>;
updateAgentPolicy: (u: Partial<NewAgentPolicy | AgentPolicy>) => void;
withSysMonitoring: boolean;
updateSysMonitoring: (newValue: boolean) => void;
validation: ValidationResults;
@ -72,9 +72,9 @@ interface Props {
onDelete?: () => void;
}
export const AgentConfigForm: React.FunctionComponent<Props> = ({
agentConfig,
updateAgentConfig,
export const AgentPolicyForm: React.FunctionComponent<Props> = ({
agentPolicy,
updateAgentPolicy,
withSysMonitoring,
updateSysMonitoring,
validation,
@ -92,11 +92,11 @@ export const AgentConfigForm: React.FunctionComponent<Props> = ({
name: 'name',
label: (
<FormattedMessage
id="xpack.ingestManager.agentConfigForm.nameFieldLabel"
id="xpack.ingestManager.agentPolicyForm.nameFieldLabel"
defaultMessage="Name"
/>
),
placeholder: i18n.translate('xpack.ingestManager.agentConfigForm.nameFieldPlaceholder', {
placeholder: i18n.translate('xpack.ingestManager.agentPolicyForm.nameFieldPlaceholder', {
defaultMessage: 'Choose a name',
}),
},
@ -104,14 +104,14 @@ export const AgentConfigForm: React.FunctionComponent<Props> = ({
name: 'description',
label: (
<FormattedMessage
id="xpack.ingestManager.agentConfigForm.descriptionFieldLabel"
id="xpack.ingestManager.agentPolicyForm.descriptionFieldLabel"
defaultMessage="Description"
/>
),
placeholder: i18n.translate(
'xpack.ingestManager.agentConfigForm.descriptionFieldPlaceholder',
'xpack.ingestManager.agentPolicyForm.descriptionFieldPlaceholder',
{
defaultMessage: 'How will this configuration be used?',
defaultMessage: 'How will this policy be used?',
}
),
},
@ -123,15 +123,15 @@ export const AgentConfigForm: React.FunctionComponent<Props> = ({
title={
<h4>
<FormattedMessage
id="xpack.ingestManager.configForm.generalSettingsGroupTitle"
id="xpack.ingestManager.policyForm.generalSettingsGroupTitle"
defaultMessage="General settings"
/>
</h4>
}
description={
<FormattedMessage
id="xpack.ingestManager.configForm.generalSettingsGroupDescription"
defaultMessage="Choose a name and description for your agent configuration."
id="xpack.ingestManager.policyForm.generalSettingsGroupDescription"
defaultMessage="Choose a name and description for your agent policy."
/>
}
>
@ -150,8 +150,8 @@ export const AgentConfigForm: React.FunctionComponent<Props> = ({
>
<EuiFieldText
fullWidth
value={agentConfig[name]}
onChange={(e) => updateAgentConfig({ [name]: e.target.value })}
value={agentPolicy[name]}
onChange={(e) => updateAgentPolicy({ [name]: e.target.value })}
isInvalid={Boolean(touchedFields[name] && validation[name])}
onBlur={() => setTouchedFields({ ...touchedFields, [name]: true })}
placeholder={placeholder}
@ -166,15 +166,15 @@ export const AgentConfigForm: React.FunctionComponent<Props> = ({
title={
<h4>
<FormattedMessage
id="xpack.ingestManager.agentConfigForm.namespaceFieldLabel"
id="xpack.ingestManager.agentPolicyForm.namespaceFieldLabel"
defaultMessage="Default namespace"
/>
</h4>
}
description={
<FormattedMessage
id="xpack.ingestManager.agentConfigForm.namespaceFieldDescription"
defaultMessage="Apply a default namespace to integrations that use this configuration. Integrations can specify their own namespaces."
id="xpack.ingestManager.agentPolicyForm.namespaceFieldDescription"
defaultMessage="Apply a default namespace to integrations that use this policy. Integrations can specify their own namespaces."
/>
}
>
@ -187,12 +187,12 @@ export const AgentConfigForm: React.FunctionComponent<Props> = ({
fullWidth
singleSelection
noSuggestions
selectedOptions={agentConfig.namespace ? [{ label: agentConfig.namespace }] : []}
selectedOptions={agentPolicy.namespace ? [{ label: agentPolicy.namespace }] : []}
onCreateOption={(value: string) => {
updateAgentConfig({ namespace: value });
updateAgentPolicy({ namespace: value });
}}
onChange={(selectedOptions) => {
updateAgentConfig({
updateAgentPolicy({
namespace: (selectedOptions.length ? selectedOptions[0] : '') as string,
});
}}
@ -205,14 +205,14 @@ export const AgentConfigForm: React.FunctionComponent<Props> = ({
title={
<h4>
<FormattedMessage
id="xpack.ingestManager.agentConfigForm.monitoringLabel"
id="xpack.ingestManager.agentPolicyForm.monitoringLabel"
defaultMessage="Agent monitoring"
/>
</h4>
}
description={
<FormattedMessage
id="xpack.ingestManager.agentConfigForm.monitoringDescription"
id="xpack.ingestManager.agentPolicyForm.monitoringDescription"
defaultMessage="Collect data about your agents for debugging and tracking performance."
/>
}
@ -224,15 +224,14 @@ export const AgentConfigForm: React.FunctionComponent<Props> = ({
label: (
<>
<FormattedMessage
id="xpack.ingestManager.agentConfigForm.monitoringLogsFieldLabel"
id="xpack.ingestManager.agentPolicyForm.monitoringLogsFieldLabel"
defaultMessage="Collect agent logs"
/>{' '}
<EuiIconTip
content={i18n.translate(
'xpack.ingestManager.agentConfigForm.monitoringLogsTooltipText',
'xpack.ingestManager.agentPolicyForm.monitoringLogsTooltipText',
{
defaultMessage:
'Collect logs from Elastic Agents that use this configuration.',
defaultMessage: 'Collect logs from Elastic Agents that use this policy.',
}
)}
position="right"
@ -247,15 +246,14 @@ export const AgentConfigForm: React.FunctionComponent<Props> = ({
label: (
<>
<FormattedMessage
id="xpack.ingestManager.agentConfigForm.monitoringMetricsFieldLabel"
id="xpack.ingestManager.agentPolicyForm.monitoringMetricsFieldLabel"
defaultMessage="Collect agent metrics"
/>{' '}
<EuiIconTip
content={i18n.translate(
'xpack.ingestManager.agentConfigForm.monitoringMetricsTooltipText',
'xpack.ingestManager.agentPolicyForm.monitoringMetricsTooltipText',
{
defaultMessage:
'Collect metrics from Elastic Agents that use this configuration.',
defaultMessage: 'Collect metrics from Elastic Agents that use this policy.',
}
)}
position="right"
@ -266,7 +264,7 @@ export const AgentConfigForm: React.FunctionComponent<Props> = ({
),
},
]}
idToSelectedMap={(agentConfig.monitoring_enabled || []).reduce(
idToSelectedMap={(agentPolicy.monitoring_enabled || []).reduce(
(acc: { logs: boolean; metrics: boolean }, key) => {
acc[key] = true;
return acc;
@ -279,10 +277,10 @@ export const AgentConfigForm: React.FunctionComponent<Props> = ({
}
const hasLogs =
agentConfig.monitoring_enabled && agentConfig.monitoring_enabled.indexOf(id) >= 0;
agentPolicy.monitoring_enabled && agentPolicy.monitoring_enabled.indexOf(id) >= 0;
const previousValues = agentConfig.monitoring_enabled || [];
updateAgentConfig({
const previousValues = agentPolicy.monitoring_enabled || [];
updateAgentPolicy({
monitoring_enabled: hasLogs
? previousValues.filter((type) => type !== id)
: [...previousValues, id],
@ -290,46 +288,46 @@ export const AgentConfigForm: React.FunctionComponent<Props> = ({
}}
/>
</EuiDescribedFormGroup>
{isEditing && 'id' in agentConfig ? (
{isEditing && 'id' in agentPolicy ? (
<EuiDescribedFormGroup
title={
<h4>
<FormattedMessage
id="xpack.ingestManager.configForm.deleteConfigGroupTitle"
defaultMessage="Delete configuration"
id="xpack.ingestManager.policyForm.deletePolicyGroupTitle"
defaultMessage="Delete policy"
/>
</h4>
}
description={
<>
<FormattedMessage
id="xpack.ingestManager.configForm.deleteConfigGroupDescription"
id="xpack.ingestManager.policyForm.deletePolicyGroupDescription"
defaultMessage="Existing data will not be deleted."
/>
<EuiSpacer size="s" />
<AgentConfigDeleteProvider>
{(deleteAgentConfigPrompt) => {
<AgentPolicyDeleteProvider>
{(deleteAgentPolicyPrompt) => {
return (
<EuiButton
color="danger"
disabled={Boolean(agentConfig.is_default)}
onClick={() => deleteAgentConfigPrompt(agentConfig.id!, onDelete)}
disabled={Boolean(agentPolicy.is_default)}
onClick={() => deleteAgentPolicyPrompt(agentPolicy.id!, onDelete)}
>
<FormattedMessage
id="xpack.ingestManager.configForm.deleteConfigActionText"
defaultMessage="Delete configuration"
id="xpack.ingestManager.policyForm.deletePolicyActionText"
defaultMessage="Delete policy"
/>
</EuiButton>
);
}}
</AgentConfigDeleteProvider>
{agentConfig.is_default ? (
</AgentPolicyDeleteProvider>
{agentPolicy.is_default ? (
<>
<EuiSpacer size="xs" />
<EuiText color="subdued" size="xs">
<FormattedMessage
id="xpack.ingestManager.configForm.unableToDeleteDefaultConfigText"
defaultMessage="Default configuration cannot be deleted"
id="xpack.ingestManager.policyForm.unableToDeleteDefaultPolicyText"
defaultMessage="Default policy cannot be deleted"
/>
</EuiText>
</>
@ -348,25 +346,25 @@ export const AgentConfigForm: React.FunctionComponent<Props> = ({
<EuiFormRow
label={
<FormattedMessage
id="xpack.ingestManager.agentConfigForm.systemMonitoringFieldLabel"
id="xpack.ingestManager.agentPolicyForm.systemMonitoringFieldLabel"
defaultMessage="System monitoring"
/>
}
>
<EuiCheckbox
id="agentConfigFormSystemMonitoringCheckbox"
id="agentPolicyFormSystemMonitoringCheckbox"
label={
<>
<FormattedMessage
id="xpack.ingestManager.agentConfigForm.systemMonitoringText"
id="xpack.ingestManager.agentPolicyForm.systemMonitoringText"
defaultMessage="Collect system metrics"
/>{' '}
<EuiIconTip
content={i18n.translate(
'xpack.ingestManager.agentConfigForm.systemMonitoringTooltipText',
'xpack.ingestManager.agentPolicyForm.systemMonitoringTooltipText',
{
defaultMessage:
'Enable this option to bootstrap your configuration with an integration that collects system metrics and information.',
'Enable this option to bootstrap your policy with an integration that collects system metrics and information.',
}
)}
position="right"
@ -390,7 +388,7 @@ export const AgentConfigForm: React.FunctionComponent<Props> = ({
id="advancedOptions"
buttonContent={
<FormattedMessage
id="xpack.ingestManager.agentConfigForm.advancedOptionsToggleLabel"
id="xpack.ingestManager.agentPolicyForm.advancedOptionsToggleLabel"
defaultMessage="Advanced options"
/>
}

View file

@ -19,9 +19,9 @@ import {
EuiButtonEmpty,
EuiButton,
} from '@elastic/eui';
import { useGetOneAgentConfigFull, useGetOneAgentConfig, useCore } from '../../../hooks';
import { useGetOneAgentPolicyFull, useGetOneAgentPolicy, useCore } from '../../../hooks';
import { Loading } from '../../../components';
import { configToYaml, agentConfigRouteService } from '../../../services';
import { fullAgentPolicyToYaml, agentPolicyRouteService } from '../../../services';
const FlyoutBody = styled(EuiFlyoutBody)`
.euiFlyoutBody__overflowContent {
@ -29,40 +29,40 @@ const FlyoutBody = styled(EuiFlyoutBody)`
}
`;
export const ConfigYamlFlyout = memo<{ configId: string; onClose: () => void }>(
({ configId, onClose }) => {
export const AgentPolicyYamlFlyout = memo<{ policyId: string; onClose: () => void }>(
({ policyId, onClose }) => {
const core = useCore();
const { isLoading: isLoadingYaml, data: yamlData } = useGetOneAgentConfigFull(configId);
const { data: configData } = useGetOneAgentConfig(configId);
const { isLoading: isLoadingYaml, data: yamlData } = useGetOneAgentPolicyFull(policyId);
const { data: agentPolicyData } = useGetOneAgentPolicy(policyId);
const body =
isLoadingYaml && !yamlData ? (
<Loading />
) : (
<EuiCodeBlock language="yaml" isCopyable fontSize="m">
{configToYaml(yamlData!.item)}
{fullAgentPolicyToYaml(yamlData!.item)}
</EuiCodeBlock>
);
const downloadLink = core.http.basePath.prepend(
agentConfigRouteService.getInfoFullDownloadPath(configId)
agentPolicyRouteService.getInfoFullDownloadPath(policyId)
);
return (
<EuiFlyout onClose={onClose} size="l" maxWidth={640}>
<EuiFlyoutHeader hasBorder aria-labelledby="IngestManagerConfigYamlFlyoutTitle">
<EuiFlyoutHeader hasBorder aria-labelledby="IngestManagerAgentPolicyYamlFlyoutTitle">
<EuiTitle size="m">
<h2 id="IngestManagerConfigYamlFlyoutTitle">
{configData?.item ? (
<h2 id="IngestManagerAgentPolicyYamlFlyoutTitle">
{agentPolicyData?.item ? (
<FormattedMessage
id="xpack.ingestManager.configDetails.yamlflyoutTitleWithName"
defaultMessage="'{name}' agent configuration"
values={{ name: configData.item.name }}
id="xpack.ingestManager.policyDetails.yamlflyoutTitleWithName"
defaultMessage="'{name}' agent policy"
values={{ name: agentPolicyData.item.name }}
/>
) : (
<FormattedMessage
id="xpack.ingestManager.configDetails.yamlflyoutTitleWithoutName"
defaultMessage="Agent configuration"
id="xpack.ingestManager.policyDetails.yamlflyoutTitleWithoutName"
defaultMessage="Agent policy"
/>
)}
</h2>
@ -74,7 +74,7 @@ export const ConfigYamlFlyout = memo<{ configId: string; onClose: () => void }>(
<EuiFlexItem grow={false}>
<EuiButtonEmpty onClick={onClose} flush="left">
<FormattedMessage
id="xpack.ingestManager.configDetails.yamlFlyoutCloseButtonLabel"
id="xpack.ingestManager.policyDetails.yamlFlyoutCloseButtonLabel"
defaultMessage="Close"
/>
</EuiButtonEmpty>
@ -86,8 +86,8 @@ export const ConfigYamlFlyout = memo<{ configId: string; onClose: () => void }>(
isDisabled={Boolean(isLoadingYaml && !yamlData)}
>
<FormattedMessage
id="xpack.ingestManager.configDetails.yamlDownloadButtonLabel"
defaultMessage="Download configuration"
id="xpack.ingestManager.policyDetails.yamlDownloadButtonLabel"
defaultMessage="Download policy"
/>
</EuiButton>
</EuiFlexItem>

View file

@ -8,20 +8,20 @@ import React from 'react';
import { EuiCallOut, EuiOverlayMask, EuiConfirmModal, EuiSpacer } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { i18n } from '@kbn/i18n';
import { AgentConfig } from '../../../types';
import { AgentPolicy } from '../../../types';
export const ConfirmDeployConfigModal: React.FunctionComponent<{
export const ConfirmDeployAgentPolicyModal: React.FunctionComponent<{
onConfirm: () => void;
onCancel: () => void;
agentCount: number;
agentConfig: AgentConfig;
}> = ({ onConfirm, onCancel, agentCount, agentConfig }) => {
agentPolicy: AgentPolicy;
}> = ({ onConfirm, onCancel, agentCount, agentPolicy }) => {
return (
<EuiOverlayMask>
<EuiConfirmModal
title={
<FormattedMessage
id="xpack.ingestManager.agentConfig.confirmModalTitle"
id="xpack.ingestManager.agentPolicy.confirmModalTitle"
defaultMessage="Save and deploy changes"
/>
}
@ -29,13 +29,13 @@ export const ConfirmDeployConfigModal: React.FunctionComponent<{
onConfirm={onConfirm}
cancelButtonText={
<FormattedMessage
id="xpack.ingestManager.agentConfig.confirmModalCancelButtonLabel"
id="xpack.ingestManager.agentPolicy.confirmModalCancelButtonLabel"
defaultMessage="Cancel"
/>
}
confirmButtonText={
<FormattedMessage
id="xpack.ingestManager.agentConfig.confirmModalConfirmButtonLabel"
id="xpack.ingestManager.agentPolicy.confirmModalConfirmButtonLabel"
defaultMessage="Save and deploy changes"
/>
}
@ -43,7 +43,7 @@ export const ConfirmDeployConfigModal: React.FunctionComponent<{
>
<EuiCallOut
iconType="iInCircle"
title={i18n.translate('xpack.ingestManager.agentConfig.confirmModalCalloutTitle', {
title={i18n.translate('xpack.ingestManager.agentPolicy.confirmModalCalloutTitle', {
defaultMessage:
'This action will update {agentCount, plural, one {# agent} other {# agents}}',
values: {
@ -53,19 +53,19 @@ export const ConfirmDeployConfigModal: React.FunctionComponent<{
>
<div className="eui-textBreakWord">
<FormattedMessage
id="xpack.ingestManager.agentConfig.confirmModalCalloutDescription"
defaultMessage="Fleet has detected that the selected agent configuration, {configName}, is already in use by
id="xpack.ingestManager.agentPolicy.confirmModalCalloutDescription"
defaultMessage="Fleet has detected that the selected agent policy, {policyName}, is already in use by
some of your agents. As a result of this action, Fleet will deploy updates to all agents
that use this configuration."
that use this policy."
values={{
configName: <b>{agentConfig.name}</b>,
policyName: <b>{agentPolicy.name}</b>,
}}
/>
</div>
</EuiCallOut>
<EuiSpacer size="l" />
<FormattedMessage
id="xpack.ingestManager.agentConfig.confirmModalDescription"
id="xpack.ingestManager.agentPolicy.confirmModalDescription"
defaultMessage="This action can not be undone. Are you sure you wish to continue?"
/>
</EuiConfirmModal>

View file

@ -0,0 +1,14 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
export { AgentPolicyForm, agentPolicyFormValidation } from './agent_policy_form';
export { AgentPolicyCopyProvider } from './agent_policy_copy_provider';
export { AgentPolicyDeleteProvider } from './agent_policy_delete_provider';
export { PackagePolicyDeleteProvider } from './package_policy_delete_provider';
export { AgentPolicyYamlFlyout } from './agent_policy_yaml_flyout';
export { LinkedAgentCount } from './linked_agent_count';
export { ConfirmDeployAgentPolicyModal } from './confirm_deploy_modal';
export { DangerEuiContextMenuItem } from './danger_eui_context_menu_item';
export { AgentPolicyActionMenu } from './actions_menu';

View file

@ -10,12 +10,12 @@ import { EuiLink } from '@elastic/eui';
import { useLink } from '../../../hooks';
import { AGENT_SAVED_OBJECT_TYPE } from '../../../constants';
export const LinkedAgentCount = memo<{ count: number; agentConfigId: string }>(
({ count, agentConfigId }) => {
export const LinkedAgentCount = memo<{ count: number; agentPolicyId: string }>(
({ count, agentPolicyId }) => {
const { getHref } = useLink();
const displayValue = (
<FormattedMessage
id="xpack.ingestManager.agentConfig.linkedAgentCountText"
id="xpack.ingestManager.agentPolicy.linkedAgentCountText"
defaultMessage="{count, plural, one {# agent} other {# agents}}"
values={{ count }}
/>
@ -23,7 +23,7 @@ export const LinkedAgentCount = memo<{ count: number; agentConfigId: string }>(
return count > 0 ? (
<EuiLink
href={getHref('fleet_agent_list', {
kuery: `${AGENT_SAVED_OBJECT_TYPE}.config_id : ${agentConfigId}`,
kuery: `${AGENT_SAVED_OBJECT_TYPE}.policy_id : ${agentPolicyId}`,
})}
>
{displayValue}

View file

@ -8,31 +8,31 @@ import React, { Fragment, useMemo, useRef, useState } from 'react';
import { EuiCallOut, EuiConfirmModal, EuiOverlayMask, EuiSpacer } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import { useCore, sendRequest, sendDeletePackageConfig, useConfig } from '../../../hooks';
import { useCore, sendRequest, sendDeletePackagePolicy, useConfig } from '../../../hooks';
import { AGENT_API_ROUTES, AGENT_SAVED_OBJECT_TYPE } from '../../../constants';
import { AgentConfig } from '../../../types';
import { AgentPolicy } from '../../../types';
interface Props {
agentConfig: AgentConfig;
children: (deletePackageConfigsPrompt: DeletePackageConfigsPrompt) => React.ReactElement;
agentPolicy: AgentPolicy;
children: (deletePackagePoliciesPrompt: DeletePackagePoliciesPrompt) => React.ReactElement;
}
export type DeletePackageConfigsPrompt = (
packageConfigsToDelete: string[],
export type DeletePackagePoliciesPrompt = (
packagePoliciesToDelete: string[],
onSuccess?: OnSuccessCallback
) => void;
type OnSuccessCallback = (packageConfigsDeleted: string[]) => void;
type OnSuccessCallback = (packagePoliciesDeleted: string[]) => void;
export const PackageConfigDeleteProvider: React.FunctionComponent<Props> = ({
agentConfig,
export const PackagePolicyDeleteProvider: React.FunctionComponent<Props> = ({
agentPolicy,
children,
}) => {
const { notifications } = useCore();
const {
fleet: { enabled: isFleetEnabled },
} = useConfig();
const [packageConfigs, setPackageConfigs] = useState<string[]>([]);
const [packagePolicies, setPackagePolicies] = useState<string[]>([]);
const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
const [isLoadingAgentsCount, setIsLoadingAgentsCount] = useState<boolean>(false);
const [agentsCount, setAgentsCount] = useState<number>(0);
@ -51,22 +51,22 @@ export const PackageConfigDeleteProvider: React.FunctionComponent<Props> = ({
query: {
page: 1,
perPage: 1,
kuery: `${AGENT_SAVED_OBJECT_TYPE}.config_id : ${agentConfig.id}`,
kuery: `${AGENT_SAVED_OBJECT_TYPE}.policy_id : ${agentPolicy.id}`,
},
});
setAgentsCount(data?.total || 0);
setIsLoadingAgentsCount(false);
},
[agentConfig.id, isFleetEnabled, isLoadingAgentsCount]
[agentPolicy.id, isFleetEnabled, isLoadingAgentsCount]
);
const deletePackageConfigsPrompt = useMemo(
(): DeletePackageConfigsPrompt => (packageConfigsToDelete, onSuccess = () => undefined) => {
if (!Array.isArray(packageConfigsToDelete) || packageConfigsToDelete.length === 0) {
throw new Error('No package configs specified for deletion');
const deletePackagePoliciesPrompt = useMemo(
(): DeletePackagePoliciesPrompt => (packagePoliciesToDelete, onSuccess = () => undefined) => {
if (!Array.isArray(packagePoliciesToDelete) || packagePoliciesToDelete.length === 0) {
throw new Error('No package policies specified for deletion');
}
setIsModalOpen(true);
setPackageConfigs(packageConfigsToDelete);
setPackagePolicies(packagePoliciesToDelete);
fetchAgentsCount();
onSuccessCallback.current = onSuccess;
},
@ -75,7 +75,7 @@ export const PackageConfigDeleteProvider: React.FunctionComponent<Props> = ({
const closeModal = useMemo(
() => () => {
setPackageConfigs([]);
setPackagePolicies([]);
setIsLoading(false);
setIsLoadingAgentsCount(false);
setIsModalOpen(false);
@ -83,12 +83,12 @@ export const PackageConfigDeleteProvider: React.FunctionComponent<Props> = ({
[]
);
const deletePackageConfigs = useMemo(
const deletePackagePolicies = useMemo(
() => async () => {
setIsLoading(true);
try {
const { data } = await sendDeletePackageConfig({ packageConfigIds: packageConfigs });
const { data } = await sendDeletePackagePolicy({ packagePolicyIds: packagePolicies });
const successfulResults = data?.filter((result) => result.success) || [];
const failedResults = data?.filter((result) => !result.success) || [];
@ -96,14 +96,14 @@ export const PackageConfigDeleteProvider: React.FunctionComponent<Props> = ({
const hasMultipleSuccesses = successfulResults.length > 1;
const successMessage = hasMultipleSuccesses
? i18n.translate(
'xpack.ingestManager.deletePackageConfig.successMultipleNotificationTitle',
'xpack.ingestManager.deletePackagePolicy.successMultipleNotificationTitle',
{
defaultMessage: 'Deleted {count} integrations',
values: { count: successfulResults.length },
}
)
: i18n.translate(
'xpack.ingestManager.deletePackageConfig.successSingleNotificationTitle',
'xpack.ingestManager.deletePackagePolicy.successSingleNotificationTitle',
{
defaultMessage: "Deleted integration '{id}'",
values: { id: successfulResults[0].id },
@ -116,14 +116,14 @@ export const PackageConfigDeleteProvider: React.FunctionComponent<Props> = ({
const hasMultipleFailures = failedResults.length > 1;
const failureMessage = hasMultipleFailures
? i18n.translate(
'xpack.ingestManager.deletePackageConfig.failureMultipleNotificationTitle',
'xpack.ingestManager.deletePackagePolicy.failureMultipleNotificationTitle',
{
defaultMessage: 'Error deleting {count} integrations',
values: { count: failedResults.length },
}
)
: i18n.translate(
'xpack.ingestManager.deletePackageConfig.failureSingleNotificationTitle',
'xpack.ingestManager.deletePackagePolicy.failureSingleNotificationTitle',
{
defaultMessage: "Error deleting integration '{id}'",
values: { id: failedResults[0].id },
@ -137,14 +137,14 @@ export const PackageConfigDeleteProvider: React.FunctionComponent<Props> = ({
}
} catch (e) {
notifications.toasts.addDanger(
i18n.translate('xpack.ingestManager.deletePackageConfig.fatalErrorNotificationTitle', {
i18n.translate('xpack.ingestManager.deletePackagePolicy.fatalErrorNotificationTitle', {
defaultMessage: 'Error deleting integration',
})
);
}
closeModal();
},
[closeModal, packageConfigs, notifications.toasts]
[closeModal, packagePolicies, notifications.toasts]
);
const renderModal = () => {
@ -157,31 +157,31 @@ export const PackageConfigDeleteProvider: React.FunctionComponent<Props> = ({
<EuiConfirmModal
title={
<FormattedMessage
id="xpack.ingestManager.deletePackageConfig.confirmModal.deleteMultipleTitle"
id="xpack.ingestManager.deletePackagePolicy.confirmModal.deleteMultipleTitle"
defaultMessage="Delete {count, plural, one {integration} other {# integrations}}?"
values={{ count: packageConfigs.length }}
values={{ count: packagePolicies.length }}
/>
}
onCancel={closeModal}
onConfirm={deletePackageConfigs}
onConfirm={deletePackagePolicies}
cancelButtonText={
<FormattedMessage
id="xpack.ingestManager.deletePackageConfig.confirmModal.cancelButtonLabel"
id="xpack.ingestManager.deletePackagePolicy.confirmModal.cancelButtonLabel"
defaultMessage="Cancel"
/>
}
confirmButtonText={
isLoading || isLoadingAgentsCount ? (
<FormattedMessage
id="xpack.ingestManager.deletePackageConfig.confirmModal.loadingButtonLabel"
id="xpack.ingestManager.deletePackagePolicy.confirmModal.loadingButtonLabel"
defaultMessage="Loading…"
/>
) : (
<FormattedMessage
id="xpack.ingestManager.deletePackageConfig.confirmModal.confirmButtonLabel"
defaultMessage="Delete {agentConfigsCount, plural, one {integration} other {integrations}}"
id="xpack.ingestManager.deletePackagePolicy.confirmModal.confirmButtonLabel"
defaultMessage="Delete {agentPoliciesCount, plural, one {integration} other {integrations}}"
values={{
agentConfigsCount: packageConfigs.length,
agentPoliciesCount: packagePolicies.length,
}}
/>
)
@ -191,7 +191,7 @@ export const PackageConfigDeleteProvider: React.FunctionComponent<Props> = ({
>
{isLoadingAgentsCount ? (
<FormattedMessage
id="xpack.ingestManager.deletePackageConfig.confirmModal.loadingAgentsCountMessage"
id="xpack.ingestManager.deletePackagePolicy.confirmModal.loadingAgentsCountMessage"
defaultMessage="Checking affected agents…"
/>
) : agentsCount ? (
@ -200,17 +200,17 @@ export const PackageConfigDeleteProvider: React.FunctionComponent<Props> = ({
color="danger"
title={
<FormattedMessage
id="xpack.ingestManager.deletePackageConfig.confirmModal.affectedAgentsTitle"
id="xpack.ingestManager.deletePackagePolicy.confirmModal.affectedAgentsTitle"
defaultMessage="This action will affect {agentsCount} {agentsCount, plural, one {agent} other {agents}}."
values={{ agentsCount }}
/>
}
>
<FormattedMessage
id="xpack.ingestManager.deletePackageConfig.confirmModal.affectedAgentsMessage"
defaultMessage="Fleet has detected that {agentConfigName} is already in use by some of your agents."
id="xpack.ingestManager.deletePackagePolicy.confirmModal.affectedAgentsMessage"
defaultMessage="Fleet has detected that {agentPolicyName} is already in use by some of your agents."
values={{
agentConfigName: <strong>{agentConfig.name}</strong>,
agentPolicyName: <strong>{agentPolicy.name}</strong>,
}}
/>
</EuiCallOut>
@ -219,7 +219,7 @@ export const PackageConfigDeleteProvider: React.FunctionComponent<Props> = ({
) : null}
{!isLoadingAgentsCount && (
<FormattedMessage
id="xpack.ingestManager.deletePackageConfig.confirmModal.generalMessage"
id="xpack.ingestManager.deletePackagePolicy.confirmModal.generalMessage"
defaultMessage="This action can not be undone. Are you sure you wish to continue?"
/>
)}
@ -230,7 +230,7 @@ export const PackageConfigDeleteProvider: React.FunctionComponent<Props> = ({
return (
<Fragment>
{children(deletePackageConfigsPrompt)}
{children(deletePackagePoliciesPrompt)}
{renderModal()}
</Fragment>
);

View file

@ -0,0 +1,61 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import React from 'react';
import { FormattedMessage } from '@kbn/i18n/react';
import { EuiEmptyPrompt, EuiText } from '@elastic/eui';
import { NewPackagePolicy } from '../../../../types';
import { CreatePackagePolicyFrom } from '../types';
export interface CustomConfigurePackagePolicyProps {
packageName: string;
from: CreatePackagePolicyFrom;
packagePolicy: NewPackagePolicy;
packagePolicyId?: string;
}
/**
* Custom content type that external plugins can provide to Ingest's
* package policy UI.
*/
export type CustomConfigurePackagePolicyContent = React.FC<CustomConfigurePackagePolicyProps>;
type AllowedPackageKey = 'endpoint';
const PackagePolicyMapping: {
[key: string]: CustomConfigurePackagePolicyContent;
} = {};
/**
* Plugins can call this function from the start lifecycle to
* register a custom component in the Ingest package policy.
*/
export function registerPackagePolicyComponent(
key: AllowedPackageKey,
value: CustomConfigurePackagePolicyContent
) {
PackagePolicyMapping[key] = value;
}
const EmptyPackagePolicy: CustomConfigurePackagePolicyContent = () => (
<EuiEmptyPrompt
iconType="checkInCircleFilled"
iconColor="secondary"
body={
<EuiText>
<p>
<FormattedMessage
id="xpack.ingestManager.createPackagePolicy.stepConfigure.noPolicyOptionsMessage"
defaultMessage="Nothing to configure"
/>
</p>
</EuiText>
}
/>
);
export const CustomPackagePolicy = (props: CustomConfigurePackagePolicyProps) => {
const CustomPackagePolicyContent = PackagePolicyMapping[props.packageName] || EmptyPackagePolicy;
return <CustomPackagePolicyContent {...props} />;
};

View file

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
export { CreatePackageConfigPageLayout } from './layout';
export { PackageConfigInputPanel } from './package_config_input_panel';
export { PackageConfigInputVarField } from './package_config_input_var_field';
export { CustomPackageConfig } from './custom_package_config';
export { CreatePackagePolicyPageLayout } from './layout';
export { PackagePolicyInputPanel } from './package_policy_input_panel';
export { PackagePolicyInputVarField } from './package_policy_input_var_field';
export { CustomPackagePolicy } from './custom_package_policy';

View file

@ -16,15 +16,15 @@ import {
EuiSpacer,
} from '@elastic/eui';
import { WithHeaderLayout } from '../../../../layouts';
import { AgentConfig, PackageInfo } from '../../../../types';
import { AgentPolicy, PackageInfo } from '../../../../types';
import { PackageIcon } from '../../../../components/package_icon';
import { CreatePackageConfigFrom } from '../types';
import { CreatePackagePolicyFrom } from '../types';
export const CreatePackageConfigPageLayout: React.FunctionComponent<{
from: CreatePackageConfigFrom;
export const CreatePackagePolicyPageLayout: React.FunctionComponent<{
from: CreatePackagePolicyFrom;
cancelUrl: string;
onCancel?: React.ReactEventHandler;
agentConfig?: AgentConfig;
agentPolicy?: AgentPolicy;
packageInfo?: PackageInfo;
'data-test-subj'?: string;
}> = memo(
@ -32,7 +32,7 @@ export const CreatePackageConfigPageLayout: React.FunctionComponent<{
from,
cancelUrl,
onCancel,
agentConfig,
agentPolicy,
packageInfo,
children,
'data-test-subj': dataTestSubj,
@ -54,7 +54,7 @@ export const CreatePackageConfigPageLayout: React.FunctionComponent<{
<h1>
{from === 'edit' ? (
<FormattedMessage
id="xpack.ingestManager.editPackageConfig.pageTitleWithPackageName"
id="xpack.ingestManager.editPackagePolicy.pageTitleWithPackageName"
defaultMessage="Edit {packageName} integration"
values={{
packageName: packageInfo.title,
@ -62,7 +62,7 @@ export const CreatePackageConfigPageLayout: React.FunctionComponent<{
/>
) : (
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.pageTitleWithPackageName"
id="xpack.ingestManager.createPackagePolicy.pageTitleWithPackageName"
defaultMessage="Add {packageName} integration"
values={{
packageName: packageInfo.title,
@ -80,7 +80,7 @@ export const CreatePackageConfigPageLayout: React.FunctionComponent<{
<EuiText>
<h1>
<FormattedMessage
id="xpack.ingestManager.editPackageConfig.pageTitle"
id="xpack.ingestManager.editPackagePolicy.pageTitle"
defaultMessage="Edit integration"
/>
</h1>
@ -89,7 +89,7 @@ export const CreatePackageConfigPageLayout: React.FunctionComponent<{
<EuiText>
<h1>
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.pageTitle"
id="xpack.ingestManager.createPackagePolicy.pageTitle"
defaultMessage="Add integration"
/>
</h1>
@ -100,18 +100,18 @@ export const CreatePackageConfigPageLayout: React.FunctionComponent<{
const pageDescription = useMemo(() => {
return from === 'edit' ? (
<FormattedMessage
id="xpack.ingestManager.editPackageConfig.pageDescription"
defaultMessage="Modify integration settings and deploy changes to the selected agent configuration."
id="xpack.ingestManager.editPackagePolicy.pageDescription"
defaultMessage="Modify integration settings and deploy changes to the selected agent policy."
/>
) : from === 'config' ? (
) : from === 'policy' ? (
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.pageDescriptionfromConfig"
defaultMessage="Configure an integration for the selected agent configuration."
id="xpack.ingestManager.createPackagePolicy.pageDescriptionfromPolicy"
defaultMessage="Configure an integration for the selected agent policy."
/>
) : (
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.pageDescriptionfromPackage"
defaultMessage="Follow the instructions below to add this integration to an agent configuraiton."
id="xpack.ingestManager.createPackagePolicy.pageDescriptionfromPackage"
defaultMessage="Follow the instructions below to add this integration to an agent policy."
/>
);
}, [from]);
@ -129,7 +129,7 @@ export const CreatePackageConfigPageLayout: React.FunctionComponent<{
data-test-subj={`${dataTestSubj}_cancelBackLink`}
>
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.cancelLinkText"
id="xpack.ingestManager.createPackagePolicy.cancelLinkText"
defaultMessage="Cancel"
/>
</EuiButtonEmpty>
@ -145,16 +145,16 @@ export const CreatePackageConfigPageLayout: React.FunctionComponent<{
);
const rightColumn =
agentConfig && (from === 'config' || from === 'edit') ? (
agentPolicy && (from === 'policy' || from === 'edit') ? (
<EuiDescriptionList className="eui-textRight" textStyle="reverse">
<EuiDescriptionListTitle>
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.agentConfigurationNameLabel"
defaultMessage="Agent configuration"
id="xpack.ingestManager.createPackagePolicy.agentPolicyNameLabel"
defaultMessage="Agent policy"
/>
</EuiDescriptionListTitle>
<EuiDescriptionListDescription className="eui-textBreakWord">
{agentConfig?.name || '-'}
{agentPolicy?.name || '-'}
</EuiDescriptionListDescription>
</EuiDescriptionList>
) : undefined;

View file

@ -14,29 +14,29 @@ import {
EuiSpacer,
EuiButtonEmpty,
} from '@elastic/eui';
import { PackageConfigInput, RegistryVarsEntry } from '../../../../types';
import { PackagePolicyInput, RegistryVarsEntry } from '../../../../types';
import {
isAdvancedVar,
PackageConfigConfigValidationResults,
PackagePolicyConfigValidationResults,
validationHasErrors,
} from '../services';
import { PackageConfigInputVarField } from './package_config_input_var_field';
import { PackagePolicyInputVarField } from './package_policy_input_var_field';
const FlexItemWithMaxWidth = styled(EuiFlexItem)`
max-width: calc(50% - ${(props) => props.theme.eui.euiSizeL});
`;
export const PackageConfigInputConfig: React.FunctionComponent<{
export const PackagePolicyInputConfig: React.FunctionComponent<{
packageInputVars?: RegistryVarsEntry[];
packageConfigInput: PackageConfigInput;
updatePackageConfigInput: (updatedInput: Partial<PackageConfigInput>) => void;
inputVarsValidationResults: PackageConfigConfigValidationResults;
packagePolicyInput: PackagePolicyInput;
updatePackagePolicyInput: (updatedInput: Partial<PackagePolicyInput>) => void;
inputVarsValidationResults: PackagePolicyConfigValidationResults;
forceShowErrors?: boolean;
}> = memo(
({
packageInputVars,
packageConfigInput,
updatePackageConfigInput,
packagePolicyInput,
updatePackagePolicyInput,
inputVarsValidationResults,
forceShowErrors,
}) => {
@ -76,7 +76,7 @@ export const PackageConfigInputConfig: React.FunctionComponent<{
<EuiText>
<h4>
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.stepConfigure.inputSettingsTitle"
id="xpack.ingestManager.createPackagePolicy.stepConfigure.inputSettingsTitle"
defaultMessage="Settings"
/>
</h4>
@ -85,7 +85,7 @@ export const PackageConfigInputConfig: React.FunctionComponent<{
<EuiText color="subdued" size="s">
<p>
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.stepConfigure.inputSettingsDescription"
id="xpack.ingestManager.createPackagePolicy.stepConfigure.inputSettingsDescription"
defaultMessage="The following settings are applicable to all inputs below."
/>
</p>
@ -97,16 +97,16 @@ export const PackageConfigInputConfig: React.FunctionComponent<{
<EuiFlexGroup direction="column" gutterSize="m">
{requiredVars.map((varDef) => {
const { name: varName, type: varType } = varDef;
const value = packageConfigInput.vars![varName].value;
const value = packagePolicyInput.vars![varName].value;
return (
<EuiFlexItem key={varName}>
<PackageConfigInputVarField
<PackagePolicyInputVarField
varDef={varDef}
value={value}
onChange={(newValue: any) => {
updatePackageConfigInput({
updatePackagePolicyInput({
vars: {
...packageConfigInput.vars,
...packagePolicyInput.vars,
[varName]: {
type: varType,
value: newValue,
@ -133,7 +133,7 @@ export const PackageConfigInputConfig: React.FunctionComponent<{
flush="left"
>
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.stepConfigure.toggleAdvancedOptionsButtonText"
id="xpack.ingestManager.createPackagePolicy.stepConfigure.toggleAdvancedOptionsButtonText"
defaultMessage="Advanced options"
/>
</EuiButtonEmpty>
@ -142,7 +142,7 @@ export const PackageConfigInputConfig: React.FunctionComponent<{
<EuiFlexItem grow={false}>
<EuiText color="danger" size="s">
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.stepConfigure.errorCountText"
id="xpack.ingestManager.createPackagePolicy.stepConfigure.errorCountText"
defaultMessage="{count, plural, one {# error} other {# errors}}"
values={{ count: advancedVarsWithErrorsCount }}
/>
@ -154,16 +154,16 @@ export const PackageConfigInputConfig: React.FunctionComponent<{
{isShowingAdvanced
? advancedVars.map((varDef) => {
const { name: varName, type: varType } = varDef;
const value = packageConfigInput.vars![varName].value;
const value = packagePolicyInput.vars![varName].value;
return (
<EuiFlexItem key={varName}>
<PackageConfigInputVarField
<PackagePolicyInputVarField
varDef={varDef}
value={value}
onChange={(newValue: any) => {
updatePackageConfigInput({
updatePackagePolicyInput({
vars: {
...packageConfigInput.vars,
...packagePolicyInput.vars,
[varName]: {
type: varType,
value: newValue,

View file

@ -17,18 +17,18 @@ import {
EuiSpacer,
} from '@elastic/eui';
import {
PackageConfigInput,
PackageConfigInputStream,
PackagePolicyInput,
PackagePolicyInputStream,
RegistryInput,
RegistryStream,
} from '../../../../types';
import {
PackageConfigInputValidationResults,
PackagePolicyInputValidationResults,
hasInvalidButRequiredVar,
countValidationErrors,
} from '../services';
import { PackageConfigInputConfig } from './package_config_input_config';
import { PackageConfigInputStreamConfig } from './package_config_input_stream';
import { PackagePolicyInputConfig } from './package_policy_input_config';
import { PackagePolicyInputStreamConfig } from './package_policy_input_stream';
const ShortenedHorizontalRule = styled(EuiHorizontalRule)`
&&& {
@ -40,18 +40,18 @@ const ShortenedHorizontalRule = styled(EuiHorizontalRule)`
const shouldShowStreamsByDefault = (
packageInput: RegistryInput,
packageInputStreams: Array<RegistryStream & { data_stream: { dataset: string } }>,
packageConfigInput: PackageConfigInput
packagePolicyInput: PackagePolicyInput
): boolean => {
return (
packageConfigInput.enabled &&
(hasInvalidButRequiredVar(packageInput.vars, packageConfigInput.vars) ||
packagePolicyInput.enabled &&
(hasInvalidButRequiredVar(packageInput.vars, packagePolicyInput.vars) ||
Boolean(
packageInputStreams.find(
(stream) =>
stream.enabled &&
hasInvalidButRequiredVar(
stream.vars,
packageConfigInput.streams.find(
packagePolicyInput.streams.find(
(pkgStream) => stream.data_stream.dataset === pkgStream.data_stream.dataset
)?.vars
)
@ -60,25 +60,25 @@ const shouldShowStreamsByDefault = (
);
};
export const PackageConfigInputPanel: React.FunctionComponent<{
export const PackagePolicyInputPanel: React.FunctionComponent<{
packageInput: RegistryInput;
packageInputStreams: Array<RegistryStream & { data_stream: { dataset: string } }>;
packageConfigInput: PackageConfigInput;
updatePackageConfigInput: (updatedInput: Partial<PackageConfigInput>) => void;
inputValidationResults: PackageConfigInputValidationResults;
packagePolicyInput: PackagePolicyInput;
updatePackagePolicyInput: (updatedInput: Partial<PackagePolicyInput>) => void;
inputValidationResults: PackagePolicyInputValidationResults;
forceShowErrors?: boolean;
}> = memo(
({
packageInput,
packageInputStreams,
packageConfigInput,
updatePackageConfigInput,
packagePolicyInput,
updatePackagePolicyInput,
inputValidationResults,
forceShowErrors,
}) => {
// Showing streams toggle state
const [isShowingStreams, setIsShowingStreams] = useState<boolean>(
shouldShowStreamsByDefault(packageInput, packageInputStreams, packageConfigInput)
shouldShowStreamsByDefault(packageInput, packageInputStreams, packagePolicyInput)
);
// Errors state
@ -89,12 +89,12 @@ export const PackageConfigInputPanel: React.FunctionComponent<{
.map((packageInputStream) => {
return {
packageInputStream,
packageConfigInputStream: packageConfigInput.streams.find(
packagePolicyInputStream: packagePolicyInput.streams.find(
(stream) => stream.data_stream.dataset === packageInputStream.data_stream.dataset
),
};
})
.filter((stream) => Boolean(stream.packageConfigInputStream));
.filter((stream) => Boolean(stream.packagePolicyInputStream));
return (
<>
@ -111,12 +111,12 @@ export const PackageConfigInputPanel: React.FunctionComponent<{
</EuiFlexItem>
</EuiFlexGroup>
}
checked={packageConfigInput.enabled}
checked={packagePolicyInput.enabled}
onChange={(e) => {
const enabled = e.target.checked;
updatePackageConfigInput({
updatePackagePolicyInput({
enabled,
streams: packageConfigInput.streams.map((stream) => ({
streams: packagePolicyInput.streams.map((stream) => ({
...stream,
enabled,
})),
@ -133,7 +133,7 @@ export const PackageConfigInputPanel: React.FunctionComponent<{
<EuiFlexItem grow={false}>
<EuiText color="danger" size="s">
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.stepConfigure.errorCountText"
id="xpack.ingestManager.createPackagePolicy.stepConfigure.errorCountText"
defaultMessage="{count, plural, one {# error} other {# errors}}"
values={{ count: errorCount }}
/>
@ -148,7 +148,7 @@ export const PackageConfigInputPanel: React.FunctionComponent<{
aria-label={
isShowingStreams
? i18n.translate(
'xpack.ingestManager.createPackageConfig.stepConfigure.hideStreamsAriaLabel',
'xpack.ingestManager.createPackagePolicy.stepConfigure.hideStreamsAriaLabel',
{
defaultMessage: 'Hide {type} inputs',
values: {
@ -157,7 +157,7 @@ export const PackageConfigInputPanel: React.FunctionComponent<{
}
)
: i18n.translate(
'xpack.ingestManager.createPackageConfig.stepConfigure.showStreamsAriaLabel',
'xpack.ingestManager.createPackagePolicy.stepConfigure.showStreamsAriaLabel',
{
defaultMessage: 'Show {type} inputs',
values: {
@ -175,13 +175,13 @@ export const PackageConfigInputPanel: React.FunctionComponent<{
{/* Header rule break */}
{isShowingStreams ? <EuiSpacer size="l" /> : null}
{/* Input level configuration */}
{/* Input level policy */}
{isShowingStreams && packageInput.vars && packageInput.vars.length ? (
<Fragment>
<PackageConfigInputConfig
<PackagePolicyInputConfig
packageInputVars={packageInput.vars}
packageConfigInput={packageConfigInput}
updatePackageConfigInput={updatePackageConfigInput}
packagePolicyInput={packagePolicyInput}
updatePackagePolicyInput={updatePackagePolicyInput}
inputVarsValidationResults={{ vars: inputValidationResults.vars }}
forceShowErrors={forceShowErrors}
/>
@ -189,45 +189,45 @@ export const PackageConfigInputPanel: React.FunctionComponent<{
</Fragment>
) : null}
{/* Per-stream configuration */}
{/* Per-stream policy */}
{isShowingStreams ? (
<EuiFlexGroup direction="column">
{inputStreams.map(({ packageInputStream, packageConfigInputStream }, index) => (
{inputStreams.map(({ packageInputStream, packagePolicyInputStream }, index) => (
<EuiFlexItem key={index}>
<PackageConfigInputStreamConfig
<PackagePolicyInputStreamConfig
packageInputStream={packageInputStream}
packageConfigInputStream={packageConfigInputStream!}
updatePackageConfigInputStream={(
updatedStream: Partial<PackageConfigInputStream>
packagePolicyInputStream={packagePolicyInputStream!}
updatePackagePolicyInputStream={(
updatedStream: Partial<PackagePolicyInputStream>
) => {
const indexOfUpdatedStream = packageConfigInput.streams.findIndex(
const indexOfUpdatedStream = packagePolicyInput.streams.findIndex(
(stream) =>
stream.data_stream.dataset === packageInputStream.data_stream.dataset
);
const newStreams = [...packageConfigInput.streams];
const newStreams = [...packagePolicyInput.streams];
newStreams[indexOfUpdatedStream] = {
...newStreams[indexOfUpdatedStream],
...updatedStream,
};
const updatedInput: Partial<PackageConfigInput> = {
const updatedInput: Partial<PackagePolicyInput> = {
streams: newStreams,
};
// Update input enabled state if needed
if (!packageConfigInput.enabled && updatedStream.enabled) {
if (!packagePolicyInput.enabled && updatedStream.enabled) {
updatedInput.enabled = true;
} else if (
packageConfigInput.enabled &&
packagePolicyInput.enabled &&
!newStreams.find((stream) => stream.enabled)
) {
updatedInput.enabled = false;
}
updatePackageConfigInput(updatedInput);
updatePackagePolicyInput(updatedInput);
}}
inputStreamValidationResults={
inputValidationResults.streams![packageConfigInputStream!.id]
inputValidationResults.streams![packagePolicyInputStream!.id]
}
forceShowErrors={forceShowErrors}
/>

View file

@ -16,29 +16,29 @@ import {
EuiSpacer,
EuiButtonEmpty,
} from '@elastic/eui';
import { PackageConfigInputStream, RegistryStream, RegistryVarsEntry } from '../../../../types';
import { PackagePolicyInputStream, RegistryStream, RegistryVarsEntry } from '../../../../types';
import {
isAdvancedVar,
PackageConfigConfigValidationResults,
PackagePolicyConfigValidationResults,
validationHasErrors,
} from '../services';
import { PackageConfigInputVarField } from './package_config_input_var_field';
import { PackagePolicyInputVarField } from './package_policy_input_var_field';
const FlexItemWithMaxWidth = styled(EuiFlexItem)`
max-width: calc(50% - ${(props) => props.theme.eui.euiSizeL});
`;
export const PackageConfigInputStreamConfig: React.FunctionComponent<{
export const PackagePolicyInputStreamConfig: React.FunctionComponent<{
packageInputStream: RegistryStream;
packageConfigInputStream: PackageConfigInputStream;
updatePackageConfigInputStream: (updatedStream: Partial<PackageConfigInputStream>) => void;
inputStreamValidationResults: PackageConfigConfigValidationResults;
packagePolicyInputStream: PackagePolicyInputStream;
updatePackagePolicyInputStream: (updatedStream: Partial<PackagePolicyInputStream>) => void;
inputStreamValidationResults: PackagePolicyConfigValidationResults;
forceShowErrors?: boolean;
}> = memo(
({
packageInputStream,
packageConfigInputStream,
updatePackageConfigInputStream,
packagePolicyInputStream,
updatePackagePolicyInputStream,
inputStreamValidationResults,
forceShowErrors,
}) => {
@ -77,10 +77,10 @@ export const PackageConfigInputStreamConfig: React.FunctionComponent<{
<EuiFlexItem grow={5}>
<EuiSwitch
label={packageInputStream.title}
checked={packageConfigInputStream.enabled}
checked={packagePolicyInputStream.enabled}
onChange={(e) => {
const enabled = e.target.checked;
updatePackageConfigInputStream({
updatePackagePolicyInputStream({
enabled,
});
}}
@ -100,16 +100,16 @@ export const PackageConfigInputStreamConfig: React.FunctionComponent<{
<EuiFlexGroup direction="column" gutterSize="m">
{requiredVars.map((varDef) => {
const { name: varName, type: varType } = varDef;
const value = packageConfigInputStream.vars![varName].value;
const value = packagePolicyInputStream.vars![varName].value;
return (
<EuiFlexItem key={varName}>
<PackageConfigInputVarField
<PackagePolicyInputVarField
varDef={varDef}
value={value}
onChange={(newValue: any) => {
updatePackageConfigInputStream({
updatePackagePolicyInputStream({
vars: {
...packageConfigInputStream.vars,
...packagePolicyInputStream.vars,
[varName]: {
type: varType,
value: newValue,
@ -135,7 +135,7 @@ export const PackageConfigInputStreamConfig: React.FunctionComponent<{
flush="left"
>
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.stepConfigure.toggleAdvancedOptionsButtonText"
id="xpack.ingestManager.createPackagePolicy.stepConfigure.toggleAdvancedOptionsButtonText"
defaultMessage="Advanced options"
/>
</EuiButtonEmpty>
@ -144,7 +144,7 @@ export const PackageConfigInputStreamConfig: React.FunctionComponent<{
<EuiFlexItem grow={false}>
<EuiText color="danger" size="s">
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.stepConfigure.errorCountText"
id="xpack.ingestManager.createPackagePolicy.stepConfigure.errorCountText"
defaultMessage="{count, plural, one {# error} other {# errors}}"
values={{ count: advancedVarsWithErrorsCount }}
/>
@ -156,16 +156,16 @@ export const PackageConfigInputStreamConfig: React.FunctionComponent<{
{isShowingAdvanced
? advancedVars.map((varDef) => {
const { name: varName, type: varType } = varDef;
const value = packageConfigInputStream.vars![varName].value;
const value = packagePolicyInputStream.vars![varName].value;
return (
<EuiFlexItem key={varName}>
<PackageConfigInputVarField
<PackagePolicyInputVarField
varDef={varDef}
value={value}
onChange={(newValue: any) => {
updatePackageConfigInputStream({
updatePackagePolicyInputStream({
vars: {
...packageConfigInputStream.vars,
...packagePolicyInputStream.vars,
[varName]: {
type: varType,
value: newValue,

View file

@ -12,7 +12,7 @@ import { RegistryVarsEntry } from '../../../../types';
import 'brace/mode/yaml';
import 'brace/theme/textmate';
export const PackageConfigInputVarField: React.FunctionComponent<{
export const PackagePolicyInputVarField: React.FunctionComponent<{
varDef: RegistryVarsEntry;
value: any;
onChange: (newValue: any) => void;
@ -78,7 +78,7 @@ export const PackageConfigInputVarField: React.FunctionComponent<{
!required ? (
<EuiText size="xs" color="subdued">
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.stepConfigure.inputVarFieldOptionalLabel"
id="xpack.ingestManager.createPackagePolicy.stepConfigure.inputVarFieldOptionalLabel"
defaultMessage="Optional"
/>
</EuiText>

View file

@ -19,32 +19,32 @@ import {
} from '@elastic/eui';
import { EuiStepProps } from '@elastic/eui/src/components/steps/step';
import {
AgentConfig,
AgentPolicy,
PackageInfo,
NewPackageConfig,
CreatePackageConfigRouteState,
NewPackagePolicy,
CreatePackagePolicyRouteState,
} from '../../../types';
import {
useLink,
useBreadcrumbs,
sendCreatePackageConfig,
sendCreatePackagePolicy,
useCore,
useConfig,
sendGetAgentStatus,
} from '../../../hooks';
import { Loading } from '../../../components';
import { ConfirmDeployConfigModal } from '../components';
import { CreatePackageConfigPageLayout } from './components';
import { CreatePackageConfigFrom, PackageConfigFormState } from './types';
import { ConfirmDeployAgentPolicyModal } from '../components';
import { CreatePackagePolicyPageLayout } from './components';
import { CreatePackagePolicyFrom, PackagePolicyFormState } from './types';
import {
PackageConfigValidationResults,
validatePackageConfig,
PackagePolicyValidationResults,
validatePackagePolicy,
validationHasErrors,
} from './services';
import { StepSelectPackage } from './step_select_package';
import { StepSelectConfig } from './step_select_config';
import { StepConfigurePackage } from './step_configure_package';
import { StepDefinePackageConfig } from './step_define_package_config';
import { StepSelectAgentPolicy } from './step_select_agent_policy';
import { StepConfigurePackagePolicy } from './step_configure_package';
import { StepDefinePackagePolicy } from './step_define_package_policy';
import { useIntraAppState } from '../../../hooks/use_intra_app_state';
const StepsWithLessPadding = styled(EuiSteps)`
@ -53,7 +53,7 @@ const StepsWithLessPadding = styled(EuiSteps)`
}
`;
export const CreatePackageConfigPage: React.FunctionComponent = () => {
export const CreatePackagePolicyPage: React.FunctionComponent = () => {
const {
notifications,
chrome: { getIsNavDrawerLocked$ },
@ -64,12 +64,12 @@ export const CreatePackageConfigPage: React.FunctionComponent = () => {
fleet: { enabled: isFleetEnabled },
} = useConfig();
const {
params: { configId, pkgkey },
params: { policyId, pkgkey },
} = useRouteMatch();
const { getHref, getPath } = useLink();
const history = useHistory();
const routeState = useIntraAppState<CreatePackageConfigRouteState>();
const from: CreatePackageConfigFrom = configId ? 'config' : 'package';
const routeState = useIntraAppState<CreatePackagePolicyRouteState>();
const from: CreatePackagePolicyFrom = policyId ? 'policy' : 'package';
const [isNavDrawerLocked, setIsNavDrawerLocked] = useState(false);
useEffect(() => {
@ -80,52 +80,52 @@ export const CreatePackageConfigPage: React.FunctionComponent = () => {
return () => subscription.unsubscribe();
});
// Agent config and package info states
const [agentConfig, setAgentConfig] = useState<AgentConfig>();
// Agent policy and package info states
const [agentPolicy, setAgentPolicy] = useState<AgentPolicy>();
const [packageInfo, setPackageInfo] = useState<PackageInfo>();
const [isLoadingSecondStep, setIsLoadingSecondStep] = useState<boolean>(false);
const agentConfigId = agentConfig?.id;
const agentPolicyId = agentPolicy?.id;
// Retrieve agent count
useEffect(() => {
const getAgentCount = async () => {
if (agentConfigId) {
const { data } = await sendGetAgentStatus({ configId: agentConfigId });
if (agentPolicyId) {
const { data } = await sendGetAgentStatus({ policyId: agentPolicyId });
if (data?.results.total) {
setAgentCount(data.results.total);
}
}
};
if (isFleetEnabled && agentConfigId) {
if (isFleetEnabled && agentPolicyId) {
getAgentCount();
}
}, [agentConfigId, isFleetEnabled]);
}, [agentPolicyId, isFleetEnabled]);
const [agentCount, setAgentCount] = useState<number>(0);
// New package config state
const [packageConfig, setPackageConfig] = useState<NewPackageConfig>({
// New package policy state
const [packagePolicy, setPackagePolicy] = useState<NewPackagePolicy>({
name: '',
description: '',
namespace: '',
config_id: '',
policy_id: '',
enabled: true,
output_id: '', // TODO: Blank for now as we only support default output
inputs: [],
});
// Package config validation state
const [validationResults, setValidationResults] = useState<PackageConfigValidationResults>();
// Package policy validation state
const [validationResults, setValidationResults] = useState<PackagePolicyValidationResults>();
// Form state
const [formState, setFormState] = useState<PackageConfigFormState>('INVALID');
const [formState, setFormState] = useState<PackagePolicyFormState>('INVALID');
// Update package info method
const updatePackageInfo = useCallback(
(updatedPackageInfo: PackageInfo | undefined) => {
if (updatedPackageInfo) {
setPackageInfo(updatedPackageInfo);
if (agentConfig) {
if (agentPolicy) {
setFormState('VALID');
}
} else {
@ -136,70 +136,70 @@ export const CreatePackageConfigPage: React.FunctionComponent = () => {
// eslint-disable-next-line no-console
console.debug('Package info updated', updatedPackageInfo);
},
[agentConfig, setPackageInfo, setFormState]
[agentPolicy, setPackageInfo, setFormState]
);
// Update agent config method
const updateAgentConfig = useCallback(
(updatedAgentConfig: AgentConfig | undefined) => {
if (updatedAgentConfig) {
setAgentConfig(updatedAgentConfig);
// Update agent policy method
const updateAgentPolicy = useCallback(
(updatedAgentPolicy: AgentPolicy | undefined) => {
if (updatedAgentPolicy) {
setAgentPolicy(updatedAgentPolicy);
if (packageInfo) {
setFormState('VALID');
}
} else {
setFormState('INVALID');
setAgentConfig(undefined);
setAgentPolicy(undefined);
}
// eslint-disable-next-line no-console
console.debug('Agent config updated', updatedAgentConfig);
console.debug('Agent policy updated', updatedAgentPolicy);
},
[packageInfo, setAgentConfig, setFormState]
[packageInfo, setAgentPolicy, setFormState]
);
const hasErrors = validationResults ? validationHasErrors(validationResults) : false;
// Update package config validation
const updatePackageConfigValidation = useCallback(
(newPackageConfig?: NewPackageConfig) => {
// Update package policy validation
const updatePackagePolicyValidation = useCallback(
(newPackagePolicy?: NewPackagePolicy) => {
if (packageInfo) {
const newValidationResult = validatePackageConfig(
newPackageConfig || packageConfig,
const newValidationResult = validatePackagePolicy(
newPackagePolicy || packagePolicy,
packageInfo
);
setValidationResults(newValidationResult);
// eslint-disable-next-line no-console
console.debug('Package config validation results', newValidationResult);
console.debug('Package policy validation results', newValidationResult);
return newValidationResult;
}
},
[packageConfig, packageInfo]
[packagePolicy, packageInfo]
);
// Update package config method
const updatePackageConfig = useCallback(
(updatedFields: Partial<NewPackageConfig>) => {
const newPackageConfig = {
...packageConfig,
// Update package policy method
const updatePackagePolicy = useCallback(
(updatedFields: Partial<NewPackagePolicy>) => {
const newPackagePolicy = {
...packagePolicy,
...updatedFields,
};
setPackageConfig(newPackageConfig);
setPackagePolicy(newPackagePolicy);
// eslint-disable-next-line no-console
console.debug('Package config updated', newPackageConfig);
const newValidationResults = updatePackageConfigValidation(newPackageConfig);
const hasPackage = newPackageConfig.package;
console.debug('Package policy updated', newPackagePolicy);
const newValidationResults = updatePackagePolicyValidation(newPackagePolicy);
const hasPackage = newPackagePolicy.package;
const hasValidationErrors = newValidationResults
? validationHasErrors(newValidationResults)
: false;
const hasAgentConfig = newPackageConfig.config_id && newPackageConfig.config_id !== '';
if (hasPackage && hasAgentConfig && !hasValidationErrors) {
const hasAgentPolicy = newPackagePolicy.policy_id && newPackagePolicy.policy_id !== '';
if (hasPackage && hasAgentPolicy && !hasValidationErrors) {
setFormState('VALID');
}
},
[packageConfig, updatePackageConfigValidation]
[packagePolicy, updatePackagePolicyValidation]
);
// Cancel path
@ -207,10 +207,10 @@ export const CreatePackageConfigPage: React.FunctionComponent = () => {
if (routeState && routeState.onCancelUrl) {
return routeState.onCancelUrl;
}
return from === 'config'
? getHref('configuration_details', { configId: agentConfigId || configId })
return from === 'policy'
? getHref('policy_details', { policyId: agentPolicyId || policyId })
: getHref('integration_details', { pkgkey });
}, [agentConfigId, configId, from, getHref, pkgkey, routeState]);
}, [agentPolicyId, policyId, from, getHref, pkgkey, routeState]);
const cancelClickHandler: ReactEventHandler = useCallback(
(ev) => {
@ -222,10 +222,10 @@ export const CreatePackageConfigPage: React.FunctionComponent = () => {
[routeState, navigateToApp]
);
// Save package config
const savePackageConfig = async () => {
// Save package policy
const savePackagePolicy = async () => {
setFormState('LOADING');
const result = await sendCreatePackageConfig(packageConfig);
const result = await sendCreatePackagePolicy(packagePolicy);
setFormState('SUBMITTED');
return result;
};
@ -239,7 +239,7 @@ export const CreatePackageConfigPage: React.FunctionComponent = () => {
setFormState('CONFIRM');
return;
}
const { error, data } = await savePackageConfig();
const { error, data } = await savePackagePolicy();
if (!error) {
if (routeState && routeState.onSaveNavigateTo) {
navigateToApp(
@ -248,26 +248,26 @@ export const CreatePackageConfigPage: React.FunctionComponent = () => {
: routeState.onSaveNavigateTo)
);
} else {
history.push(getPath('configuration_details', { configId: agentConfig?.id || configId }));
history.push(getPath('policy_details', { policyId: agentPolicy?.id || policyId }));
}
notifications.toasts.addSuccess({
title: i18n.translate('xpack.ingestManager.createPackageConfig.addedNotificationTitle', {
defaultMessage: `Successfully added '{packageConfigName}'`,
title: i18n.translate('xpack.ingestManager.createPackagePolicy.addedNotificationTitle', {
defaultMessage: `Successfully added '{packagePolicyName}'`,
values: {
packageConfigName: packageConfig.name,
packagePolicyName: packagePolicy.name,
},
}),
text:
agentCount && agentConfig
? i18n.translate('xpack.ingestManager.createPackageConfig.addedNotificationMessage', {
defaultMessage: `Fleet will deploy updates to all agents that use the '{agentConfigName}' configuration`,
agentCount && agentPolicy
? i18n.translate('xpack.ingestManager.createPackagePolicy.addedNotificationMessage', {
defaultMessage: `Fleet will deploy updates to all agents that use the '{agentPolicyName}' policy`,
values: {
agentConfigName: agentConfig.name,
agentPolicyName: agentPolicy.name,
},
})
: undefined,
'data-test-subj': 'packageConfigCreateSuccessToast',
'data-test-subj': 'packagePolicyCreateSuccessToast',
});
} else {
notifications.toasts.addError(error, {
@ -281,53 +281,53 @@ export const CreatePackageConfigPage: React.FunctionComponent = () => {
from,
cancelUrl,
onCancel: cancelClickHandler,
agentConfig,
agentPolicy,
packageInfo,
};
const stepSelectConfig = useMemo(
const stepSelectAgentPolicy = useMemo(
() => (
<StepSelectConfig
<StepSelectAgentPolicy
pkgkey={pkgkey}
updatePackageInfo={updatePackageInfo}
agentConfig={agentConfig}
updateAgentConfig={updateAgentConfig}
agentPolicy={agentPolicy}
updateAgentPolicy={updateAgentPolicy}
setIsLoadingSecondStep={setIsLoadingSecondStep}
/>
),
[pkgkey, updatePackageInfo, agentConfig, updateAgentConfig]
[pkgkey, updatePackageInfo, agentPolicy, updateAgentPolicy]
);
const stepSelectPackage = useMemo(
() => (
<StepSelectPackage
agentConfigId={configId}
updateAgentConfig={updateAgentConfig}
agentPolicyId={policyId}
updateAgentPolicy={updateAgentPolicy}
packageInfo={packageInfo}
updatePackageInfo={updatePackageInfo}
setIsLoadingSecondStep={setIsLoadingSecondStep}
/>
),
[configId, updateAgentConfig, packageInfo, updatePackageInfo]
[policyId, updateAgentPolicy, packageInfo, updatePackageInfo]
);
const stepConfigurePackage = useMemo(
const stepConfigurePackagePolicy = useMemo(
() =>
isLoadingSecondStep ? (
<Loading />
) : agentConfig && packageInfo ? (
) : agentPolicy && packageInfo ? (
<>
<StepDefinePackageConfig
agentConfig={agentConfig}
<StepDefinePackagePolicy
agentPolicy={agentPolicy}
packageInfo={packageInfo}
packageConfig={packageConfig}
updatePackageConfig={updatePackageConfig}
packagePolicy={packagePolicy}
updatePackagePolicy={updatePackagePolicy}
validationResults={validationResults!}
/>
<StepConfigurePackage
<StepConfigurePackagePolicy
packageInfo={packageInfo}
packageConfig={packageConfig}
updatePackageConfig={updatePackageConfig}
packagePolicy={packagePolicy}
updatePackagePolicy={updatePackagePolicy}
validationResults={validationResults!}
submitAttempted={formState === 'INVALID'}
/>
@ -336,12 +336,12 @@ export const CreatePackageConfigPage: React.FunctionComponent = () => {
<div />
),
[
agentConfig,
agentPolicy,
formState,
isLoadingSecondStep,
packageConfig,
packagePolicy,
packageInfo,
updatePackageConfig,
updatePackagePolicy,
validationResults,
]
);
@ -350,38 +350,38 @@ export const CreatePackageConfigPage: React.FunctionComponent = () => {
from === 'package'
? {
title: i18n.translate(
'xpack.ingestManager.createPackageConfig.stepSelectAgentConfigTitle',
'xpack.ingestManager.createPackagePolicy.stepSelectAgentPolicyTitle',
{
defaultMessage: 'Select an agent configuration',
defaultMessage: 'Select an agent policy',
}
),
children: stepSelectConfig,
children: stepSelectAgentPolicy,
}
: {
title: i18n.translate('xpack.ingestManager.createPackageConfig.stepSelectPackageTitle', {
title: i18n.translate('xpack.ingestManager.createPackagePolicy.stepSelectPackageTitle', {
defaultMessage: 'Select an integration',
}),
children: stepSelectPackage,
},
{
title: i18n.translate(
'xpack.ingestManager.createPackageConfig.stepConfigurePackageConfigTitle',
'xpack.ingestManager.createPackagePolicy.stepConfigurePackagePolicyTitle',
{
defaultMessage: 'Configure integration',
}
),
status: !packageInfo || !agentConfig || isLoadingSecondStep ? 'disabled' : undefined,
status: !packageInfo || !agentPolicy || isLoadingSecondStep ? 'disabled' : undefined,
'data-test-subj': 'dataCollectionSetupStep',
children: stepConfigurePackage,
children: stepConfigurePackagePolicy,
},
];
return (
<CreatePackageConfigPageLayout {...layoutProps} data-test-subj="createPackageConfig">
{formState === 'CONFIRM' && agentConfig && (
<ConfirmDeployConfigModal
<CreatePackagePolicyPageLayout {...layoutProps} data-test-subj="createPackagePolicy">
{formState === 'CONFIRM' && agentPolicy && (
<ConfirmDeployAgentPolicyModal
agentCount={agentCount}
agentConfig={agentConfig}
agentPolicy={agentPolicy}
onConfirm={onSubmit}
onCancel={() => setFormState('VALID')}
/>
@ -393,8 +393,8 @@ export const CreatePackageConfigPage: React.FunctionComponent = () => {
pkgkey={`${packageInfo.name}-${packageInfo.version}`}
/>
)
: agentConfig && (
<ConfigurationBreadcrumb configName={agentConfig.name} configId={agentConfig.id} />
: agentPolicy && (
<PolicyBreadcrumb policyName={agentPolicy.name} policyId={agentPolicy.id} />
)}
<StepsWithLessPadding steps={steps} />
<EuiSpacer size="l" />
@ -410,10 +410,10 @@ export const CreatePackageConfigPage: React.FunctionComponent = () => {
>
<EuiFlexGroup justifyContent="spaceBetween" alignItems="center">
<EuiFlexItem grow={false}>
{!isLoadingSecondStep && agentConfig && packageInfo && formState === 'INVALID' ? (
{!isLoadingSecondStep && agentPolicy && packageInfo && formState === 'INVALID' ? (
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.errorOnSaveText"
defaultMessage="Your integration configuration has errors. Please fix them before saving."
id="xpack.ingestManager.createPackagePolicy.errorOnSaveText"
defaultMessage="Your integration policy has errors. Please fix them before saving."
/>
) : null}
</EuiFlexItem>
@ -425,10 +425,10 @@ export const CreatePackageConfigPage: React.FunctionComponent = () => {
color="ghost"
href={cancelUrl}
onClick={cancelClickHandler}
data-test-subj="createPackageConfigCancelButton"
data-test-subj="createPackagePolicyCancelButton"
>
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.cancelButton"
id="xpack.ingestManager.createPackagePolicy.cancelButton"
defaultMessage="Cancel"
/>
</EuiButtonEmpty>
@ -441,10 +441,10 @@ export const CreatePackageConfigPage: React.FunctionComponent = () => {
iconType="save"
color="primary"
fill
data-test-subj="createPackageConfigSaveButton"
data-test-subj="createPackagePolicySaveButton"
>
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.saveButton"
id="xpack.ingestManager.createPackagePolicy.saveButton"
defaultMessage="Save integration"
/>
</EuiButton>
@ -453,15 +453,15 @@ export const CreatePackageConfigPage: React.FunctionComponent = () => {
</EuiFlexItem>
</EuiFlexGroup>
</EuiBottomBar>
</CreatePackageConfigPageLayout>
</CreatePackagePolicyPageLayout>
);
};
const ConfigurationBreadcrumb: React.FunctionComponent<{
configName: string;
configId: string;
}> = ({ configName, configId }) => {
useBreadcrumbs('add_integration_from_configuration', { configName, configId });
const PolicyBreadcrumb: React.FunctionComponent<{
policyName: string;
policyId: string;
}> = ({ policyName, policyId }) => {
useBreadcrumbs('add_integration_from_policy', { policyName, policyId });
return null;
};
@ -469,6 +469,6 @@ const IntegrationBreadcrumb: React.FunctionComponent<{
pkgTitle: string;
pkgkey: string;
}> = ({ pkgTitle, pkgkey }) => {
useBreadcrumbs('add_integration_to_configuration', { pkgTitle, pkgkey });
useBreadcrumbs('add_integration_to_policy', { pkgTitle, pkgkey });
return null;
};

View file

@ -3,23 +3,23 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { PackageConfigConfigRecord, RegistryVarsEntry } from '../../../../types';
import { validatePackageConfigConfig } from './';
import { PackagePolicyConfigRecord, RegistryVarsEntry } from '../../../../types';
import { validatePackagePolicyConfig } from './';
export const hasInvalidButRequiredVar = (
registryVars?: RegistryVarsEntry[],
packageConfigVars?: PackageConfigConfigRecord
packagePolicyVars?: PackagePolicyConfigRecord
): boolean => {
return (
(registryVars && !packageConfigVars) ||
(registryVars && !packagePolicyVars) ||
Boolean(
registryVars &&
registryVars.find(
(registryVar) =>
registryVar.required &&
(!packageConfigVars ||
!packageConfigVars[registryVar.name] ||
validatePackageConfigConfig(packageConfigVars[registryVar.name], registryVar)?.length)
(!packagePolicyVars ||
!packagePolicyVars[registryVar.name] ||
validatePackagePolicyConfig(packagePolicyVars[registryVar.name], registryVar)?.length)
)
)
);

View file

@ -6,11 +6,11 @@
export { isAdvancedVar } from './is_advanced_var';
export { hasInvalidButRequiredVar } from './has_invalid_but_required_var';
export {
PackageConfigValidationResults,
PackageConfigConfigValidationResults,
PackageConfigInputValidationResults,
validatePackageConfig,
validatePackageConfigConfig,
PackagePolicyValidationResults,
PackagePolicyConfigValidationResults,
PackagePolicyInputValidationResults,
validatePackagePolicy,
validatePackagePolicyConfig,
validationHasErrors,
countValidationErrors,
} from './validate_package_config';
} from './validate_package_policy';

View file

@ -6,12 +6,12 @@
import {
PackageInfo,
InstallationStatus,
NewPackageConfig,
NewPackagePolicy,
RegistryConfigTemplate,
} from '../../../../types';
import { validatePackageConfig, validationHasErrors } from './validate_package_config';
import { validatePackagePolicy, validationHasErrors } from './validate_package_policy';
describe('Ingest Manager - validatePackageConfig()', () => {
describe('Ingest Manager - validatePackagePolicy()', () => {
const mockPackage = ({
name: 'mock-package',
title: 'Mock package',
@ -92,9 +92,9 @@ describe('Ingest Manager - validatePackageConfig()', () => {
],
config_templates: [
{
name: 'pkgConfig1',
title: 'Package config 1',
description: 'test package config',
name: 'pkgPolicy1',
title: 'Package policy 1',
description: 'test package policy',
inputs: [
{
type: 'foo',
@ -141,10 +141,10 @@ describe('Ingest Manager - validatePackageConfig()', () => {
],
} as unknown) as PackageInfo;
const validPackageConfig: NewPackageConfig = {
name: 'pkgConfig1-1',
const validPackagePolicy: NewPackagePolicy = {
name: 'pkgPolicy1-1',
namespace: 'default',
config_id: 'test-config',
policy_id: 'test-policy',
enabled: true,
output_id: 'test-output',
inputs: [
@ -226,8 +226,8 @@ describe('Ingest Manager - validatePackageConfig()', () => {
],
};
const invalidPackageConfig: NewPackageConfig = {
...validPackageConfig,
const invalidPackagePolicy: NewPackagePolicy = {
...validPackagePolicy,
name: '',
inputs: [
{
@ -350,14 +350,14 @@ describe('Ingest Manager - validatePackageConfig()', () => {
},
};
it('returns no errors for valid package config', () => {
expect(validatePackageConfig(validPackageConfig, mockPackage)).toEqual(
it('returns no errors for valid package policy', () => {
expect(validatePackagePolicy(validPackagePolicy, mockPackage)).toEqual(
noErrorsValidationResults
);
});
it('returns errors for invalid package config', () => {
expect(validatePackageConfig(invalidPackageConfig, mockPackage)).toEqual({
it('returns errors for invalid package policy', () => {
expect(validatePackagePolicy(invalidPackagePolicy, mockPackage)).toEqual({
name: ['Name is required'],
description: null,
namespace: null,
@ -397,17 +397,17 @@ describe('Ingest Manager - validatePackageConfig()', () => {
});
it('returns no errors for disabled inputs', () => {
const disabledInputs = invalidPackageConfig.inputs.map((input) => ({
const disabledInputs = invalidPackagePolicy.inputs.map((input) => ({
...input,
enabled: false,
}));
expect(
validatePackageConfig({ ...validPackageConfig, inputs: disabledInputs }, mockPackage)
validatePackagePolicy({ ...validPackagePolicy, inputs: disabledInputs }, mockPackage)
).toEqual(noErrorsValidationResults);
});
it('returns only package config and input-level errors for disabled streams', () => {
const inputsWithDisabledStreams = invalidPackageConfig.inputs.map((input) =>
it('returns only package policy and input-level errors for disabled streams', () => {
const inputsWithDisabledStreams = invalidPackagePolicy.inputs.map((input) =>
input.streams
? {
...input,
@ -416,8 +416,8 @@ describe('Ingest Manager - validatePackageConfig()', () => {
: input
);
expect(
validatePackageConfig(
{ ...invalidPackageConfig, inputs: inputsWithDisabledStreams },
validatePackagePolicy(
{ ...invalidPackagePolicy, inputs: inputsWithDisabledStreams },
mockPackage
)
).toEqual({
@ -461,9 +461,9 @@ describe('Ingest Manager - validatePackageConfig()', () => {
});
});
it('returns no errors for packages with no package configs', () => {
it('returns no errors for packages with no package policies', () => {
expect(
validatePackageConfig(validPackageConfig, {
validatePackagePolicy(validPackagePolicy, {
...mockPackage,
config_templates: undefined,
})
@ -474,7 +474,7 @@ describe('Ingest Manager - validatePackageConfig()', () => {
inputs: null,
});
expect(
validatePackageConfig(validPackageConfig, {
validatePackagePolicy(validPackagePolicy, {
...mockPackage,
config_templates: [],
})
@ -488,7 +488,7 @@ describe('Ingest Manager - validatePackageConfig()', () => {
it('returns no errors for packages with no inputs', () => {
expect(
validatePackageConfig(validPackageConfig, {
validatePackagePolicy(validPackagePolicy, {
...mockPackage,
config_templates: [{} as RegistryConfigTemplate],
})
@ -499,7 +499,7 @@ describe('Ingest Manager - validatePackageConfig()', () => {
inputs: null,
});
expect(
validatePackageConfig(validPackageConfig, {
validatePackagePolicy(validPackagePolicy, {
...mockPackage,
config_templates: [({ inputs: [] } as unknown) as RegistryConfigTemplate],
})
@ -553,7 +553,7 @@ describe('Ingest Manager - validationHasErrors()', () => {
).toBe(false);
});
it('returns true for package config validation results with errors', () => {
it('returns true for package policy validation results with errors', () => {
expect(
validationHasErrors({
name: ['name error'],
@ -595,7 +595,7 @@ describe('Ingest Manager - validationHasErrors()', () => {
).toBe(true);
});
it('returns false for package config validation results with no errors', () => {
it('returns false for package policy validation results with no errors', () => {
expect(
validationHasErrors({
name: null,

View file

@ -7,10 +7,10 @@ import { i18n } from '@kbn/i18n';
import { safeLoad } from 'js-yaml';
import { getFlattenedObject } from '../../../../services';
import {
NewPackageConfig,
PackageConfigInput,
PackageConfigInputStream,
PackageConfigConfigRecordEntry,
NewPackagePolicy,
PackagePolicyInput,
PackagePolicyInputStream,
PackagePolicyConfigRecordEntry,
PackageInfo,
RegistryInput,
RegistryStream,
@ -21,47 +21,47 @@ type Errors = string[] | null;
type ValidationEntry = Record<string, Errors>;
export interface PackageConfigConfigValidationResults {
export interface PackagePolicyConfigValidationResults {
vars?: ValidationEntry;
}
export type PackageConfigInputValidationResults = PackageConfigConfigValidationResults & {
streams?: Record<PackageConfigInputStream['id'], PackageConfigConfigValidationResults>;
export type PackagePolicyInputValidationResults = PackagePolicyConfigValidationResults & {
streams?: Record<PackagePolicyInputStream['id'], PackagePolicyConfigValidationResults>;
};
export interface PackageConfigValidationResults {
export interface PackagePolicyValidationResults {
name: Errors;
description: Errors;
namespace: Errors;
inputs: Record<PackageConfigInput['type'], PackageConfigInputValidationResults> | null;
inputs: Record<PackagePolicyInput['type'], PackagePolicyInputValidationResults> | null;
}
/*
* Returns validation information for a given package config and package info
* Note: this method assumes that `packageConfig` is correctly structured for the given package
* Returns validation information for a given package policy and package info
* Note: this method assumes that `packagePolicy` is correctly structured for the given package
*/
export const validatePackageConfig = (
packageConfig: NewPackageConfig,
export const validatePackagePolicy = (
packagePolicy: NewPackagePolicy,
packageInfo: PackageInfo
): PackageConfigValidationResults => {
const validationResults: PackageConfigValidationResults = {
): PackagePolicyValidationResults => {
const validationResults: PackagePolicyValidationResults = {
name: null,
description: null,
namespace: null,
inputs: {},
};
if (!packageConfig.name.trim()) {
if (!packagePolicy.name.trim()) {
validationResults.name = [
i18n.translate('xpack.ingestManager.packageConfigValidation.nameRequiredErrorMessage', {
i18n.translate('xpack.ingestManager.packagePolicyValidation.nameRequiredErrorMessage', {
defaultMessage: 'Name is required',
}),
];
}
if (!packageConfig.namespace.trim()) {
if (!packagePolicy.namespace.trim()) {
validationResults.namespace = [
i18n.translate('xpack.ingestManager.packageConfigValidation.namespaceRequiredErrorMessage', {
i18n.translate('xpack.ingestManager.packagePolicyValidation.namespaceRequiredErrorMessage', {
defaultMessage: 'Namespace is required',
}),
];
@ -93,13 +93,13 @@ export const validatePackageConfig = (
return datasets;
}, {} as Record<string, RegistryStream[]>);
// Validate each package config input with either its own config fields or streams
packageConfig.inputs.forEach((input) => {
// Validate each package policy input with either its own config fields or streams
packagePolicy.inputs.forEach((input) => {
if (!input.vars && !input.streams) {
return;
}
const inputValidationResults: PackageConfigInputValidationResults = {
const inputValidationResults: PackagePolicyInputValidationResults = {
vars: undefined,
streams: {},
};
@ -117,7 +117,7 @@ export const validatePackageConfig = (
if (inputConfigs.length) {
inputValidationResults.vars = inputConfigs.reduce((results, [name, configEntry]) => {
results[name] = input.enabled
? validatePackageConfigConfig(configEntry, inputVarsByName[name])
? validatePackagePolicyConfig(configEntry, inputVarsByName[name])
: null;
return results;
}, {} as ValidationEntry);
@ -128,7 +128,7 @@ export const validatePackageConfig = (
// Validate each input stream with config fields
if (input.streams.length) {
input.streams.forEach((stream) => {
const streamValidationResults: PackageConfigConfigValidationResults = {};
const streamValidationResults: PackagePolicyConfigValidationResults = {};
// Validate stream-level config fields
if (stream.vars) {
@ -146,7 +146,7 @@ export const validatePackageConfig = (
(results, [name, configEntry]) => {
results[name] =
input.enabled && stream.enabled
? validatePackageConfigConfig(configEntry, streamVarsByName[name])
? validatePackagePolicyConfig(configEntry, streamVarsByName[name])
: null;
return results;
},
@ -171,8 +171,8 @@ export const validatePackageConfig = (
return validationResults;
};
export const validatePackageConfigConfig = (
configEntry: PackageConfigConfigRecordEntry,
export const validatePackagePolicyConfig = (
configEntry: PackagePolicyConfigRecordEntry,
varDef: RegistryVarsEntry
): string[] | null => {
const errors = [];
@ -186,7 +186,7 @@ export const validatePackageConfigConfig = (
if (varDef.required) {
if (parsedValue === undefined || (typeof parsedValue === 'string' && !parsedValue)) {
errors.push(
i18n.translate('xpack.ingestManager.packageConfigValidation.requiredErrorMessage', {
i18n.translate('xpack.ingestManager.packagePolicyValidation.requiredErrorMessage', {
defaultMessage: '{fieldName} is required',
values: {
fieldName: varDef.title || varDef.name,
@ -202,7 +202,7 @@ export const validatePackageConfigConfig = (
} catch (e) {
errors.push(
i18n.translate(
'xpack.ingestManager.packageConfigValidation.invalidYamlFormatErrorMessage',
'xpack.ingestManager.packagePolicyValidation.invalidYamlFormatErrorMessage',
{
defaultMessage: 'Invalid YAML format',
}
@ -214,7 +214,7 @@ export const validatePackageConfigConfig = (
if (varDef.multi) {
if (parsedValue && !Array.isArray(parsedValue)) {
errors.push(
i18n.translate('xpack.ingestManager.packageConfigValidation.invalidArrayErrorMessage', {
i18n.translate('xpack.ingestManager.packagePolicyValidation.invalidArrayErrorMessage', {
defaultMessage: 'Invalid format',
})
);
@ -224,7 +224,7 @@ export const validatePackageConfigConfig = (
(!parsedValue || (Array.isArray(parsedValue) && parsedValue.length === 0))
) {
errors.push(
i18n.translate('xpack.ingestManager.packageConfigValidation.requiredErrorMessage', {
i18n.translate('xpack.ingestManager.packagePolicyValidation.requiredErrorMessage', {
defaultMessage: '{fieldName} is required',
values: {
fieldName: varDef.title || varDef.name,
@ -239,9 +239,9 @@ export const validatePackageConfigConfig = (
export const countValidationErrors = (
validationResults:
| PackageConfigValidationResults
| PackageConfigInputValidationResults
| PackageConfigConfigValidationResults
| PackagePolicyValidationResults
| PackagePolicyInputValidationResults
| PackagePolicyConfigValidationResults
): number => {
const flattenedValidation = getFlattenedObject(validationResults);
const errors = Object.values(flattenedValidation).filter((value) => Boolean(value)) || [];
@ -250,9 +250,9 @@ export const countValidationErrors = (
export const validationHasErrors = (
validationResults:
| PackageConfigValidationResults
| PackageConfigInputValidationResults
| PackageConfigConfigValidationResults
| PackagePolicyValidationResults
| PackagePolicyInputValidationResults
| PackagePolicyConfigValidationResults
): boolean => {
return countValidationErrors(validationResults) > 0;
};

View file

@ -5,11 +5,11 @@
*/
import React from 'react';
import { EuiHorizontalRule, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { PackageInfo, RegistryStream, NewPackageConfig, PackageConfigInput } from '../../../types';
import { PackageInfo, RegistryStream, NewPackagePolicy, PackagePolicyInput } from '../../../types';
import { Loading } from '../../../components';
import { PackageConfigValidationResults } from './services';
import { PackageConfigInputPanel, CustomPackageConfig } from './components';
import { CreatePackageConfigFrom } from './types';
import { PackagePolicyValidationResults } from './services';
import { PackagePolicyInputPanel, CustomPackagePolicy } from './components';
import { CreatePackagePolicyFrom } from './types';
const findStreamsForInputType = (
inputType: string,
@ -33,20 +33,20 @@ const findStreamsForInputType = (
return streams;
};
export const StepConfigurePackage: React.FunctionComponent<{
from?: CreatePackageConfigFrom;
export const StepConfigurePackagePolicy: React.FunctionComponent<{
from?: CreatePackagePolicyFrom;
packageInfo: PackageInfo;
packageConfig: NewPackageConfig;
packageConfigId?: string;
updatePackageConfig: (fields: Partial<NewPackageConfig>) => void;
validationResults: PackageConfigValidationResults;
packagePolicy: NewPackagePolicy;
packagePolicyId?: string;
updatePackagePolicy: (fields: Partial<NewPackagePolicy>) => void;
validationResults: PackagePolicyValidationResults;
submitAttempted: boolean;
}> = ({
from = 'config',
from = 'policy',
packageInfo,
packageConfig,
packageConfigId,
updatePackageConfig,
packagePolicy,
packagePolicyId,
updatePackagePolicy,
validationResults,
submitAttempted,
}) => {
@ -61,30 +61,30 @@ export const StepConfigurePackage: React.FunctionComponent<{
<EuiHorizontalRule margin="m" />
<EuiFlexGroup direction="column" gutterSize="none">
{packageInfo.config_templates[0].inputs.map((packageInput) => {
const packageConfigInput = packageConfig.inputs.find(
const packagePolicyInput = packagePolicy.inputs.find(
(input) => input.type === packageInput.type
);
const packageInputStreams = findStreamsForInputType(packageInput.type, packageInfo);
return packageConfigInput ? (
return packagePolicyInput ? (
<EuiFlexItem key={packageInput.type}>
<PackageConfigInputPanel
<PackagePolicyInputPanel
packageInput={packageInput}
packageInputStreams={packageInputStreams}
packageConfigInput={packageConfigInput}
updatePackageConfigInput={(updatedInput: Partial<PackageConfigInput>) => {
const indexOfUpdatedInput = packageConfig.inputs.findIndex(
packagePolicyInput={packagePolicyInput}
updatePackagePolicyInput={(updatedInput: Partial<PackagePolicyInput>) => {
const indexOfUpdatedInput = packagePolicy.inputs.findIndex(
(input) => input.type === packageInput.type
);
const newInputs = [...packageConfig.inputs];
const newInputs = [...packagePolicy.inputs];
newInputs[indexOfUpdatedInput] = {
...newInputs[indexOfUpdatedInput],
...updatedInput,
};
updatePackageConfig({
updatePackagePolicy({
inputs: newInputs,
});
}}
inputValidationResults={validationResults!.inputs![packageConfigInput.type]}
inputValidationResults={validationResults!.inputs![packagePolicyInput.type]}
forceShowErrors={submitAttempted}
/>
<EuiHorizontalRule margin="m" />
@ -94,11 +94,11 @@ export const StepConfigurePackage: React.FunctionComponent<{
</EuiFlexGroup>
</>
) : (
<CustomPackageConfig
<CustomPackagePolicy
from={from}
packageName={packageInfo.name}
packageConfig={packageConfig}
packageConfigId={packageConfigId}
packagePolicy={packagePolicy}
packagePolicyId={packagePolicyId}
/>
);

View file

@ -16,45 +16,45 @@ import {
EuiFlexGroup,
EuiFlexItem,
} from '@elastic/eui';
import { AgentConfig, PackageInfo, PackageConfig, NewPackageConfig } from '../../../types';
import { packageToPackageConfigInputs } from '../../../services';
import { AgentPolicy, PackageInfo, PackagePolicy, NewPackagePolicy } from '../../../types';
import { packageToPackagePolicyInputs } from '../../../services';
import { Loading } from '../../../components';
import { PackageConfigValidationResults } from './services';
import { PackagePolicyValidationResults } from './services';
export const StepDefinePackageConfig: React.FunctionComponent<{
agentConfig: AgentConfig;
export const StepDefinePackagePolicy: React.FunctionComponent<{
agentPolicy: AgentPolicy;
packageInfo: PackageInfo;
packageConfig: NewPackageConfig;
updatePackageConfig: (fields: Partial<NewPackageConfig>) => void;
validationResults: PackageConfigValidationResults;
}> = ({ agentConfig, packageInfo, packageConfig, updatePackageConfig, validationResults }) => {
packagePolicy: NewPackagePolicy;
updatePackagePolicy: (fields: Partial<NewPackagePolicy>) => void;
validationResults: PackagePolicyValidationResults;
}> = ({ agentPolicy, packageInfo, packagePolicy, updatePackagePolicy, validationResults }) => {
// Form show/hide states
const [isShowingAdvanced, setIsShowingAdvanced] = useState<boolean>(false);
// Update package config's package and config info
// Update package policy's package and agent policy info
useEffect(() => {
const pkg = packageConfig.package;
const pkg = packagePolicy.package;
const currentPkgKey = pkg ? `${pkg.name}-${pkg.version}` : '';
const pkgKey = `${packageInfo.name}-${packageInfo.version}`;
// If package has changed, create shell package config with input&stream values based on package info
// If package has changed, create shell package policy with input&stream values based on package info
if (currentPkgKey !== pkgKey) {
// Existing package configs on the agent config using the package name, retrieve highest number appended to package config name
const dsPackageNamePattern = new RegExp(`${packageInfo.name}-(\\d+)`);
const dsWithMatchingNames = (agentConfig.package_configs as PackageConfig[])
.filter((ds) => Boolean(ds.name.match(dsPackageNamePattern)))
.map((ds) => parseInt(ds.name.match(dsPackageNamePattern)![1], 10))
// Existing package policies on the agent policy using the package name, retrieve highest number appended to package policy name
const pkgPoliciesNamePattern = new RegExp(`${packageInfo.name}-(\\d+)`);
const pkgPoliciesWithMatchingNames = (agentPolicy.package_policies as PackagePolicy[])
.filter((ds) => Boolean(ds.name.match(pkgPoliciesNamePattern)))
.map((ds) => parseInt(ds.name.match(pkgPoliciesNamePattern)![1], 10))
.sort();
updatePackageConfig({
updatePackagePolicy({
name:
// For Endpoint packages, the user must fill in the name, thus we don't attempt to generate
// a default one here.
// FIXME: Improve package configs name uniqueness - https://github.com/elastic/kibana/issues/72948
// FIXME: Improve package policies name uniqueness - https://github.com/elastic/kibana/issues/72948
packageInfo.name !== 'endpoint'
? `${packageInfo.name}-${
dsWithMatchingNames.length
? dsWithMatchingNames[dsWithMatchingNames.length - 1] + 1
pkgPoliciesWithMatchingNames.length
? pkgPoliciesWithMatchingNames[pkgPoliciesWithMatchingNames.length - 1] + 1
: 1
}`
: '',
@ -63,23 +63,23 @@ export const StepDefinePackageConfig: React.FunctionComponent<{
title: packageInfo.title,
version: packageInfo.version,
},
inputs: packageToPackageConfigInputs(packageInfo),
inputs: packageToPackagePolicyInputs(packageInfo),
});
}
// If agent config has changed, update package config's config ID and namespace
if (packageConfig.config_id !== agentConfig.id) {
updatePackageConfig({
config_id: agentConfig.id,
namespace: agentConfig.namespace,
// If agent policy has changed, update package policy's agent policy ID and namespace
if (packagePolicy.policy_id !== agentPolicy.id) {
updatePackagePolicy({
policy_id: agentPolicy.id,
namespace: agentPolicy.namespace,
});
}
}, [
packageConfig.package,
packageConfig.config_id,
agentConfig,
packagePolicy.package,
packagePolicy.policy_id,
agentPolicy,
packageInfo,
updatePackageConfig,
updatePackagePolicy,
]);
return validationResults ? (
@ -87,14 +87,14 @@ export const StepDefinePackageConfig: React.FunctionComponent<{
title={
<h4>
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.stepConfigure.integrationSettingsSectionTitle"
id="xpack.ingestManager.createPackagePolicy.stepConfigure.integrationSettingsSectionTitle"
defaultMessage="Integration settings"
/>
</h4>
}
description={
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.stepConfigure.integrationSettingsSectionDescription"
id="xpack.ingestManager.createPackagePolicy.stepConfigure.integrationSettingsSectionDescription"
defaultMessage="Choose a name and description to help identify how this integration will be used."
/>
}
@ -106,19 +106,19 @@ export const StepDefinePackageConfig: React.FunctionComponent<{
error={validationResults.name}
label={
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.stepConfigure.packageConfigNameInputLabel"
id="xpack.ingestManager.createPackagePolicy.stepConfigure.packagePolicyNameInputLabel"
defaultMessage="Integration name"
/>
}
>
<EuiFieldText
value={packageConfig.name}
value={packagePolicy.name}
onChange={(e) =>
updatePackageConfig({
updatePackagePolicy({
name: e.target.value,
})
}
data-test-subj="packageConfigNameInput"
data-test-subj="packagePolicyNameInput"
/>
</EuiFormRow>
@ -126,14 +126,14 @@ export const StepDefinePackageConfig: React.FunctionComponent<{
<EuiFormRow
label={
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.stepConfigure.packageConfigDescriptionInputLabel"
id="xpack.ingestManager.createPackagePolicy.stepConfigure.packagePolicyDescriptionInputLabel"
defaultMessage="Description"
/>
}
labelAppend={
<EuiText size="xs" color="subdued">
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.stepConfigure.inputVarFieldOptionalLabel"
id="xpack.ingestManager.createPackagePolicy.stepConfigure.inputVarFieldOptionalLabel"
defaultMessage="Optional"
/>
</EuiText>
@ -142,9 +142,9 @@ export const StepDefinePackageConfig: React.FunctionComponent<{
error={validationResults.description}
>
<EuiFieldText
value={packageConfig.description}
value={packagePolicy.description}
onChange={(e) =>
updatePackageConfig({
updatePackagePolicy({
description: e.target.value,
})
}
@ -162,7 +162,7 @@ export const StepDefinePackageConfig: React.FunctionComponent<{
flush="left"
>
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.stepConfigure.advancedOptionsToggleLinkText"
id="xpack.ingestManager.createPackagePolicy.stepConfigure.advancedOptionsToggleLinkText"
defaultMessage="Advanced options"
/>
</EuiButtonEmpty>
@ -171,7 +171,7 @@ export const StepDefinePackageConfig: React.FunctionComponent<{
<EuiFlexItem grow={false}>
<EuiText color="danger" size="s">
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.stepConfigure.errorCountText"
id="xpack.ingestManager.createPackagePolicy.stepConfigure.errorCountText"
defaultMessage="{count, plural, one {# error} other {# errors}}"
values={{ count: 1 }}
/>
@ -190,7 +190,7 @@ export const StepDefinePackageConfig: React.FunctionComponent<{
error={validationResults.namespace}
label={
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.stepConfigure.packageConfigNamespaceInputLabel"
id="xpack.ingestManager.createPackagePolicy.stepConfigure.packagePolicyNamespaceInputLabel"
defaultMessage="Namespace"
/>
}
@ -199,15 +199,15 @@ export const StepDefinePackageConfig: React.FunctionComponent<{
noSuggestions
singleSelection={true}
selectedOptions={
packageConfig.namespace ? [{ label: packageConfig.namespace }] : []
packagePolicy.namespace ? [{ label: packagePolicy.namespace }] : []
}
onCreateOption={(newNamespace: string) => {
updatePackageConfig({
updatePackagePolicy({
namespace: newNamespace,
});
}}
onChange={(newNamespaces: Array<{ label: string }>) => {
updatePackageConfig({
updatePackagePolicy({
namespace: newNamespaces.length ? newNamespaces[0].label : '',
});
}}

View file

@ -18,55 +18,55 @@ import {
EuiLink,
} from '@elastic/eui';
import { Error } from '../../../components';
import { AgentConfig, PackageInfo, GetAgentConfigsResponseItem } from '../../../types';
import { isPackageLimited, doesAgentConfigAlreadyIncludePackage } from '../../../services';
import { AgentPolicy, PackageInfo, GetAgentPoliciesResponseItem } from '../../../types';
import { isPackageLimited, doesAgentPolicyAlreadyIncludePackage } from '../../../services';
import {
useGetPackageInfoByKey,
useGetAgentConfigs,
sendGetOneAgentConfig,
useGetAgentPolicies,
sendGetOneAgentPolicy,
useCapabilities,
useFleetStatus,
} from '../../../hooks';
import { CreateAgentConfigFlyout } from '../list_page/components';
import { CreateAgentPolicyFlyout } from '../list_page/components';
const AgentConfigWrapper = styled(EuiFormRow)`
const AgentPolicyWrapper = styled(EuiFormRow)`
.euiFormRow__label {
width: 100%;
}
`;
// Custom styling for drop down list items due to:
// 1) the max-width and overflow properties is added to prevent long config
// 1) the max-width and overflow properties is added to prevent long agent policy
// names/descriptions from overflowing the flex items
// 2) max-width is built from the grow property on the flex items because the value
// changes based on if Fleet is enabled/setup or not
const AgentConfigNameColumn = styled(EuiFlexItem)`
const AgentPolicyNameColumn = styled(EuiFlexItem)`
max-width: ${(props) => `${((props.grow as number) / 9) * 100}%`};
overflow: hidden;
`;
const AgentConfigDescriptionColumn = styled(EuiFlexItem)`
const AgentPolicyDescriptionColumn = styled(EuiFlexItem)`
max-width: ${(props) => `${((props.grow as number) / 9) * 100}%`};
overflow: hidden;
`;
export const StepSelectConfig: React.FunctionComponent<{
export const StepSelectAgentPolicy: React.FunctionComponent<{
pkgkey: string;
updatePackageInfo: (packageInfo: PackageInfo | undefined) => void;
agentConfig: AgentConfig | undefined;
updateAgentConfig: (config: AgentConfig | undefined) => void;
agentPolicy: AgentPolicy | undefined;
updateAgentPolicy: (agentPolicy: AgentPolicy | undefined) => void;
setIsLoadingSecondStep: (isLoading: boolean) => void;
}> = ({ pkgkey, updatePackageInfo, agentConfig, updateAgentConfig, setIsLoadingSecondStep }) => {
}> = ({ pkgkey, updatePackageInfo, agentPolicy, updateAgentPolicy, setIsLoadingSecondStep }) => {
const { isReady: isFleetReady } = useFleetStatus();
// Selected config state
const [selectedConfigId, setSelectedConfigId] = useState<string | undefined>(
agentConfig ? agentConfig.id : undefined
// Selected agent policy state
const [selectedPolicyId, setSelectedPolicyId] = useState<string | undefined>(
agentPolicy ? agentPolicy.id : undefined
);
const [selectedConfigError, setSelectedConfigError] = useState<Error>();
const [selectedAgentPolicyError, setSelectedAgentPolicyError] = useState<Error>();
// Create new config flyout state
// Create new agent policy flyout state
const hasWriteCapabilites = useCapabilities().write;
const [isCreateAgentConfigFlyoutOpen, setIsCreateAgentConfigFlyoutOpen] = useState<boolean>(
const [isCreateAgentPolicyFlyoutOpen, setIsCreateAgentPolicyFlyoutOpen] = useState<boolean>(
false
);
@ -78,23 +78,23 @@ export const StepSelectConfig: React.FunctionComponent<{
} = useGetPackageInfoByKey(pkgkey);
const isLimitedPackage = (packageInfoData && isPackageLimited(packageInfoData.response)) || false;
// Fetch agent configs info
// Fetch agent policies info
const {
data: agentConfigsData,
error: agentConfigsError,
isLoading: isAgentConfigsLoading,
sendRequest: refreshAgentConfigs,
} = useGetAgentConfigs({
data: agentPoliciesData,
error: agentPoliciesError,
isLoading: isAgentPoliciesLoading,
sendRequest: refreshAgentPolicies,
} = useGetAgentPolicies({
page: 1,
perPage: 1000,
sortField: 'name',
sortOrder: 'asc',
full: true,
});
const agentConfigs = agentConfigsData?.items || [];
const agentConfigsById = agentConfigs.reduce(
(acc: { [key: string]: GetAgentConfigsResponseItem }, config) => {
acc[config.id] = config;
const agentPolicies = agentPoliciesData?.items || [];
const agentPoliciesById = agentPolicies.reduce(
(acc: { [key: string]: GetAgentPoliciesResponseItem }, policy) => {
acc[policy.id] = policy;
return acc;
},
{}
@ -107,63 +107,63 @@ export const StepSelectConfig: React.FunctionComponent<{
}
}, [packageInfoData, updatePackageInfo]);
// Update parent selected agent config state
// Update parent selected agent policy state
useEffect(() => {
const fetchAgentConfigInfo = async () => {
if (selectedConfigId) {
const fetchAgentPolicyInfo = async () => {
if (selectedPolicyId) {
setIsLoadingSecondStep(true);
const { data, error } = await sendGetOneAgentConfig(selectedConfigId);
const { data, error } = await sendGetOneAgentPolicy(selectedPolicyId);
if (error) {
setSelectedConfigError(error);
updateAgentConfig(undefined);
setSelectedAgentPolicyError(error);
updateAgentPolicy(undefined);
} else if (data && data.item) {
setSelectedConfigError(undefined);
updateAgentConfig(data.item);
setSelectedAgentPolicyError(undefined);
updateAgentPolicy(data.item);
}
} else {
setSelectedConfigError(undefined);
updateAgentConfig(undefined);
setSelectedAgentPolicyError(undefined);
updateAgentPolicy(undefined);
}
setIsLoadingSecondStep(false);
};
if (!agentConfig || selectedConfigId !== agentConfig.id) {
fetchAgentConfigInfo();
if (!agentPolicy || selectedPolicyId !== agentPolicy.id) {
fetchAgentPolicyInfo();
}
}, [selectedConfigId, agentConfig, updateAgentConfig, setIsLoadingSecondStep]);
}, [selectedPolicyId, agentPolicy, updateAgentPolicy, setIsLoadingSecondStep]);
const agentConfigOptions: Array<EuiComboBoxOptionOption<string>> = packageInfoData
? agentConfigs.map((agentConf) => {
const agentPolicyOptions: Array<EuiComboBoxOptionOption<string>> = packageInfoData
? agentPolicies.map((agentConf) => {
const alreadyHasLimitedPackage =
(isLimitedPackage &&
doesAgentConfigAlreadyIncludePackage(agentConf, packageInfoData.response.name)) ||
doesAgentPolicyAlreadyIncludePackage(agentConf, packageInfoData.response.name)) ||
false;
return {
label: agentConf.name,
value: agentConf.id,
disabled: alreadyHasLimitedPackage,
'data-test-subj': 'agentConfigItem',
'data-test-subj': 'agentPolicyItem',
};
})
: [];
const selectedConfigOption = agentConfigOptions.find(
(option) => option.value === selectedConfigId
const selectedAgentPolicyOption = agentPolicyOptions.find(
(option) => option.value === selectedPolicyId
);
// Try to select default agent config
// Try to select default agent policy
useEffect(() => {
if (!selectedConfigId && agentConfigs.length && agentConfigOptions.length) {
const defaultAgentConfig = agentConfigs.find((config) => config.is_default);
if (defaultAgentConfig) {
const defaultAgentConfigOption = agentConfigOptions.find(
(option) => option.value === defaultAgentConfig.id
if (!selectedPolicyId && agentPolicies.length && agentPolicyOptions.length) {
const defaultAgentPolicy = agentPolicies.find((policy) => policy.is_default);
if (defaultAgentPolicy) {
const defaultAgentPolicyOption = agentPolicyOptions.find(
(option) => option.value === defaultAgentPolicy.id
);
if (defaultAgentConfigOption && !defaultAgentConfigOption.disabled) {
setSelectedConfigId(defaultAgentConfig.id);
if (defaultAgentPolicyOption && !defaultAgentPolicyOption.disabled) {
setSelectedPolicyId(defaultAgentPolicy.id);
}
}
}
}, [agentConfigs, agentConfigOptions, selectedConfigId]);
}, [agentPolicies, agentPolicyOptions, selectedPolicyId]);
// Display package error if there is one
if (packageInfoError) {
@ -171,7 +171,7 @@ export const StepSelectConfig: React.FunctionComponent<{
<Error
title={
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.StepSelectConfig.errorLoadingPackageTitle"
id="xpack.ingestManager.createPackagePolicy.StepSelectPolicy.errorLoadingPackageTitle"
defaultMessage="Error loading package information"
/>
}
@ -180,31 +180,31 @@ export const StepSelectConfig: React.FunctionComponent<{
);
}
// Display agent configs list error if there is one
if (agentConfigsError) {
// Display agent policies list error if there is one
if (agentPoliciesError) {
return (
<Error
title={
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.StepSelectConfig.errorLoadingAgentConfigsTitle"
defaultMessage="Error loading agent configurations"
id="xpack.ingestManager.createPackagePolicy.StepSelectPolicy.errorLoadingAgentPoliciesTitle"
defaultMessage="Error loading agent policies"
/>
}
error={agentConfigsError}
error={agentPoliciesError}
/>
);
}
return (
<>
{isCreateAgentConfigFlyoutOpen ? (
{isCreateAgentPolicyFlyoutOpen ? (
<EuiPortal>
<CreateAgentConfigFlyout
onClose={(newAgentConfig?: AgentConfig) => {
setIsCreateAgentConfigFlyoutOpen(false);
if (newAgentConfig) {
refreshAgentConfigs();
setSelectedConfigId(newAgentConfig.id);
<CreateAgentPolicyFlyout
onClose={(newAgentPolicy?: AgentPolicy) => {
setIsCreateAgentPolicyFlyoutOpen(false);
if (newAgentPolicy) {
refreshAgentPolicies();
setSelectedPolicyId(newAgentPolicy.id);
}
}}
ownFocus={true}
@ -213,25 +213,25 @@ export const StepSelectConfig: React.FunctionComponent<{
) : null}
<EuiFlexGroup direction="column" gutterSize="m">
<EuiFlexItem>
<AgentConfigWrapper
<AgentPolicyWrapper
fullWidth={true}
label={
<EuiFlexGroup justifyContent="spaceBetween">
<EuiFlexItem>
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.StepSelectConfig.agentConfigLabel"
defaultMessage="Agent configuration"
id="xpack.ingestManager.createPackagePolicy.StepSelectPolicy.agentPolicyLabel"
defaultMessage="Agent policy"
/>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<div>
<EuiLink
disabled={!hasWriteCapabilites}
onClick={() => setIsCreateAgentConfigFlyoutOpen(true)}
onClick={() => setIsCreateAgentPolicyFlyoutOpen(true)}
>
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.StepSelectConfig.addButton"
defaultMessage="Create agent configuration"
id="xpack.ingestManager.createPackagePolicy.StepSelectPolicy.addButton"
defaultMessage="Create agent policy"
/>
</EuiLink>
</div>
@ -239,12 +239,12 @@ export const StepSelectConfig: React.FunctionComponent<{
</EuiFlexGroup>
}
helpText={
isFleetReady && selectedConfigId ? (
isFleetReady && selectedPolicyId ? (
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.StepSelectConfig.agentConfigAgentsDescriptionText"
defaultMessage="{count, plural, one {# agent} other {# agents}} are enrolled with the selected agent configuration."
id="xpack.ingestManager.createPackagePolicy.StepSelectPolicy.agentPolicyAgentsDescriptionText"
defaultMessage="{count, plural, one {# agent} other {# agents}} are enrolled with the selected agent policy."
values={{
count: agentConfigsById[selectedConfigId].agents || 0,
count: agentPoliciesById[selectedPolicyId].agents || 0,
}}
/>
) : null
@ -252,35 +252,35 @@ export const StepSelectConfig: React.FunctionComponent<{
>
<EuiComboBox
placeholder={i18n.translate(
'xpack.ingestManager.createPackageConfig.StepSelectConfig.agentConfigPlaceholderText',
'xpack.ingestManager.createPackagePolicy.StepSelectPolicy.agentPolicyPlaceholderText',
{
defaultMessage: 'Select an agent configuration to add this integration to',
defaultMessage: 'Select an agent policy to add this integration to',
}
)}
singleSelection={{ asPlainText: true }}
isClearable={false}
fullWidth={true}
isLoading={isAgentConfigsLoading || isPackageInfoLoading}
options={agentConfigOptions}
isLoading={isAgentPoliciesLoading || isPackageInfoLoading}
options={agentPolicyOptions}
renderOption={(option: EuiComboBoxOptionOption<string>) => {
return (
<EuiFlexGroup>
<AgentConfigNameColumn grow={2}>
<AgentPolicyNameColumn grow={2}>
<span className="eui-textTruncate">{option.label}</span>
</AgentConfigNameColumn>
<AgentConfigDescriptionColumn grow={isFleetReady ? 5 : 7}>
</AgentPolicyNameColumn>
<AgentPolicyDescriptionColumn grow={isFleetReady ? 5 : 7}>
<EuiTextColor className="eui-textTruncate" color="subdued">
{agentConfigsById[option.value!].description}
{agentPoliciesById[option.value!].description}
</EuiTextColor>
</AgentConfigDescriptionColumn>
</AgentPolicyDescriptionColumn>
{isFleetReady ? (
<EuiFlexItem grow={2} className="eui-textRight">
<EuiTextColor color="subdued">
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.StepSelectConfig.agentConfigAgentsCountText"
id="xpack.ingestManager.createPackagePolicy.StepSelectPolicy.agentPolicyAgentsCountText"
defaultMessage="{count, plural, one {# agent} other {# agents}} enrolled"
values={{
count: agentConfigsById[option.value!].agents || 0,
count: agentPoliciesById[option.value!].agents || 0,
}}
/>
</EuiTextColor>
@ -289,31 +289,31 @@ export const StepSelectConfig: React.FunctionComponent<{
</EuiFlexGroup>
);
}}
selectedOptions={selectedConfigOption ? [selectedConfigOption] : []}
selectedOptions={selectedAgentPolicyOption ? [selectedAgentPolicyOption] : []}
onChange={(options) => {
const selectedOption = options[0] || undefined;
if (selectedOption) {
if (selectedOption.value !== selectedConfigId) {
setSelectedConfigId(selectedOption.value);
if (selectedOption.value !== selectedPolicyId) {
setSelectedPolicyId(selectedOption.value);
}
} else {
setSelectedConfigId(undefined);
setSelectedPolicyId(undefined);
}
}}
/>
</AgentConfigWrapper>
</AgentPolicyWrapper>
</EuiFlexItem>
{/* Display selected agent config error if there is one */}
{selectedConfigError ? (
{/* Display selected agent policy error if there is one */}
{selectedAgentPolicyError ? (
<EuiFlexItem>
<Error
title={
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.StepSelectConfig.errorLoadingSelectedAgentConfigTitle"
defaultMessage="Error loading selected agent config"
id="xpack.ingestManager.createPackagePolicy.StepSelectPolicy.errorLoadingSelectedAgentPolicyTitle"
defaultMessage="Error loading selected agent policy"
/>
}
error={selectedConfigError}
error={selectedAgentPolicyError}
/>
</EuiFlexItem>
) : null}

View file

@ -8,9 +8,9 @@ import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import { EuiFlexGroup, EuiFlexItem, EuiSelectable, EuiSpacer } from '@elastic/eui';
import { Error } from '../../../components';
import { AgentConfig, PackageInfo, PackageConfig, GetPackagesResponse } from '../../../types';
import { AgentPolicy, PackageInfo, PackagePolicy, GetPackagesResponse } from '../../../types';
import {
useGetOneAgentConfig,
useGetOneAgentPolicy,
useGetPackages,
useGetLimitedPackages,
sendGetPackageInfoByKey,
@ -18,14 +18,14 @@ import {
import { PackageIcon } from '../../../components/package_icon';
export const StepSelectPackage: React.FunctionComponent<{
agentConfigId: string;
updateAgentConfig: (config: AgentConfig | undefined) => void;
agentPolicyId: string;
updateAgentPolicy: (agentPolicy: AgentPolicy | undefined) => void;
packageInfo?: PackageInfo;
updatePackageInfo: (packageInfo: PackageInfo | undefined) => void;
setIsLoadingSecondStep: (isLoading: boolean) => void;
}> = ({
agentConfigId,
updateAgentConfig,
agentPolicyId,
updateAgentPolicy,
packageInfo,
updatePackageInfo,
setIsLoadingSecondStep,
@ -36,15 +36,15 @@ export const StepSelectPackage: React.FunctionComponent<{
);
const [selectedPkgError, setSelectedPkgError] = useState<Error>();
// Fetch agent config info
// Fetch agent policy info
const {
data: agentConfigData,
error: agentConfigError,
isLoading: isAgentConfigsLoading,
} = useGetOneAgentConfig(agentConfigId);
data: agentPolicyData,
error: agentPolicyError,
isLoading: isAgentPoliciesLoading,
} = useGetOneAgentPolicy(agentPolicyId);
// Fetch packages info
// Filter out limited packages already part of selected agent config
// Filter out limited packages already part of selected agent policy
const [packages, setPackages] = useState<GetPackagesResponse['response']>([]);
const {
data: packagesData,
@ -56,22 +56,22 @@ export const StepSelectPackage: React.FunctionComponent<{
isLoading: isLimitedPackagesLoading,
} = useGetLimitedPackages();
useEffect(() => {
if (packagesData?.response && limitedPackagesData?.response && agentConfigData?.item) {
if (packagesData?.response && limitedPackagesData?.response && agentPolicyData?.item) {
const allPackages = packagesData.response;
const limitedPackages = limitedPackagesData.response;
const usedLimitedPackages = (agentConfigData.item.package_configs as PackageConfig[])
.map((packageConfig) => packageConfig.package?.name || '')
const usedLimitedPackages = (agentPolicyData.item.package_policies as PackagePolicy[])
.map((packagePolicy) => packagePolicy.package?.name || '')
.filter((pkgName) => limitedPackages.includes(pkgName));
setPackages(allPackages.filter((pkg) => !usedLimitedPackages.includes(pkg.name)));
}
}, [packagesData, limitedPackagesData, agentConfigData]);
}, [packagesData, limitedPackagesData, agentPolicyData]);
// Update parent agent config state
// Update parent agent policy state
useEffect(() => {
if (agentConfigData && agentConfigData.item) {
updateAgentConfig(agentConfigData.item);
if (agentPolicyData && agentPolicyData.item) {
updateAgentPolicy(agentPolicyData.item);
}
}, [agentConfigData, updateAgentConfig]);
}, [agentPolicyData, updateAgentPolicy]);
// Update parent selected package state
useEffect(() => {
@ -97,17 +97,17 @@ export const StepSelectPackage: React.FunctionComponent<{
}
}, [selectedPkgKey, packageInfo, updatePackageInfo, setIsLoadingSecondStep]);
// Display agent config error if there is one
if (agentConfigError) {
// Display agent policy error if there is one
if (agentPolicyError) {
return (
<Error
title={
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.stepSelectPackage.errorLoadingConfigTitle"
defaultMessage="Error loading agent configuration information"
id="xpack.ingestManager.createPackagePolicy.stepSelectPackage.errorLoadingPolicyTitle"
defaultMessage="Error loading agent policy information"
/>
}
error={agentConfigError}
error={agentPolicyError}
/>
);
}
@ -118,7 +118,7 @@ export const StepSelectPackage: React.FunctionComponent<{
<Error
title={
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.stepSelectPackage.errorLoadingPackagesTitle"
id="xpack.ingestManager.createPackagePolicy.stepSelectPackage.errorLoadingPackagesTitle"
defaultMessage="Error loading integrations"
/>
}
@ -134,7 +134,7 @@ export const StepSelectPackage: React.FunctionComponent<{
searchable
allowExclusions={false}
singleSelection={true}
isLoading={isPackagesLoading || isLimitedPackagesLoading || isAgentConfigsLoading}
isLoading={isPackagesLoading || isLimitedPackagesLoading || isAgentPoliciesLoading}
options={packages.map(({ title, name, version, icons }) => {
const pkgkey = `${name}-${version}`;
return {
@ -157,7 +157,7 @@ export const StepSelectPackage: React.FunctionComponent<{
}}
searchProps={{
placeholder: i18n.translate(
'xpack.ingestManager.createPackageConfig.stepSelectPackage.filterPackagesInputPlaceholder',
'xpack.ingestManager.createPackagePolicy.stepSelectPackage.filterPackagesInputPlaceholder',
{
defaultMessage: 'Search for integrations',
}
@ -190,7 +190,7 @@ export const StepSelectPackage: React.FunctionComponent<{
<Error
title={
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.stepSelectPackage.errorLoadingSelectedPackageTitle"
id="xpack.ingestManager.createPackagePolicy.stepSelectPackage.errorLoadingSelectedPackageTitle"
defaultMessage="Error loading selected integration"
/>
}

View file

@ -4,5 +4,5 @@
* you may not use this file except in compliance with the Elastic License.
*/
export type CreatePackageConfigFrom = 'package' | 'config' | 'edit';
export type PackageConfigFormState = 'VALID' | 'INVALID' | 'CONFIRM' | 'LOADING' | 'SUBMITTED';
export type CreatePackagePolicyFrom = 'package' | 'policy' | 'edit';
export type PackagePolicyFormState = 'VALID' | 'INVALID' | 'CONFIRM' | 'LOADING' | 'SUBMITTED';

View file

@ -0,0 +1,8 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
export { PackagePoliciesTable } from './package_policies/package_policies_table';
export { PackagePoliciesView } from './package_policies';
export { SettingsView } from './settings';

View file

@ -0,0 +1,23 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import React, { memo } from 'react';
import { AgentPolicy, PackagePolicy } from '../../../../../types';
import { NoPackagePolicies } from './no_package_policies';
import { PackagePoliciesTable } from './package_policies_table';
export const PackagePoliciesView = memo<{ agentPolicy: AgentPolicy }>(({ agentPolicy }) => {
if (agentPolicy.package_policies.length === 0) {
return <NoPackagePolicies policyId={agentPolicy.id} />;
}
return (
<PackagePoliciesTable
agentPolicy={agentPolicy}
packagePolicies={(agentPolicy.package_policies || []) as PackagePolicy[]}
/>
);
});

View file

@ -8,7 +8,7 @@ import { FormattedMessage } from '@kbn/i18n/react';
import { EuiButton, EuiEmptyPrompt } from '@elastic/eui';
import { useCapabilities, useLink } from '../../../../../hooks';
export const NoPackageConfigs = memo<{ configId: string }>(({ configId }) => {
export const NoPackagePolicies = memo<{ policyId: string }>(({ policyId }) => {
const { getHref } = useLink();
const hasWriteCapabilities = useCapabilities().write;
@ -18,25 +18,25 @@ export const NoPackageConfigs = memo<{ configId: string }>(({ configId }) => {
title={
<h3>
<FormattedMessage
id="xpack.ingestManager.configDetailsPackageConfigs.createFirstTitle"
id="xpack.ingestManager.policyDetailsPackagePolicies.createFirstTitle"
defaultMessage="Add your first integration"
/>
</h3>
}
body={
<FormattedMessage
id="xpack.ingestManager.configDetailsPackageConfigs.createFirstMessage"
defaultMessage="This configuration does not have any integrations yet."
id="xpack.ingestManager.policyDetailsPackagePolicies.createFirstMessage"
defaultMessage="This policy does not have any integrations yet."
/>
}
actions={
<EuiButton
isDisabled={!hasWriteCapabilities}
fill
href={getHref('add_integration_from_configuration', { configId })}
href={getHref('add_integration_from_policy', { policyId })}
>
<FormattedMessage
id="xpack.ingestManager.configDetailsPackageConfigs.createFirstButtonText"
id="xpack.ingestManager.policyDetailsPackagePolicies.createFirstButtonText"
defaultMessage="Add integration"
/>
</EuiButton>

View file

@ -15,13 +15,13 @@ import {
EuiFlexGroup,
EuiFlexItem,
} from '@elastic/eui';
import { AgentConfig, PackageConfig } from '../../../../../types';
import { AgentPolicy, PackagePolicy } from '../../../../../types';
import { PackageIcon, ContextMenuActions } from '../../../../../components';
import { PackageConfigDeleteProvider, DangerEuiContextMenuItem } from '../../../components';
import { PackagePolicyDeleteProvider, DangerEuiContextMenuItem } from '../../../components';
import { useCapabilities, useLink } from '../../../../../hooks';
import { useConfigRefresh } from '../../hooks';
import { useAgentPolicyRefresh } from '../../hooks';
interface InMemoryPackageConfig extends PackageConfig {
interface InMemoryPackagePolicy extends PackagePolicy {
inputTypes: string[];
packageName?: string;
packageTitle?: string;
@ -29,11 +29,11 @@ interface InMemoryPackageConfig extends PackageConfig {
}
interface Props {
packageConfigs: PackageConfig[];
config: AgentConfig;
packagePolicies: PackagePolicy[];
agentPolicy: AgentPolicy;
// Pass through props to InMemoryTable
loading?: EuiInMemoryTableProps<InMemoryPackageConfig>['loading'];
message?: EuiInMemoryTableProps<InMemoryPackageConfig>['message'];
loading?: EuiInMemoryTableProps<InMemoryPackagePolicy>['loading'];
message?: EuiInMemoryTableProps<InMemoryPackagePolicy>['message'];
}
interface FilterOption {
@ -44,29 +44,29 @@ interface FilterOption {
const stringSortAscending = (a: string, b: string): number => a.localeCompare(b);
const toFilterOption = (value: string): FilterOption => ({ name: value, value });
export const PackageConfigsTable: React.FunctionComponent<Props> = ({
packageConfigs: originalPackageConfigs,
config,
export const PackagePoliciesTable: React.FunctionComponent<Props> = ({
packagePolicies: originalPackagePolicies,
agentPolicy,
...rest
}) => {
const { getHref } = useLink();
const hasWriteCapabilities = useCapabilities().write;
const refreshConfig = useConfigRefresh();
const refreshAgentPolicy = useAgentPolicyRefresh();
// With the package configs provided on input, generate the list of package configs
// With the package policies provided on input, generate the list of package policies
// used in the InMemoryTable (flattens some values for search) as well as
// the list of options that will be used in the filters dropdowns
const [packageConfigs, namespaces, inputTypes] = useMemo((): [
InMemoryPackageConfig[],
const [packagePolicies, namespaces, inputTypes] = useMemo((): [
InMemoryPackagePolicy[],
FilterOption[],
FilterOption[]
] => {
const namespacesValues: string[] = [];
const inputTypesValues: string[] = [];
const mappedPackageConfigs = originalPackageConfigs.map<InMemoryPackageConfig>(
(packageConfig) => {
if (packageConfig.namespace && !namespacesValues.includes(packageConfig.namespace)) {
namespacesValues.push(packageConfig.namespace);
const mappedPackagePolicies = originalPackagePolicies.map<InMemoryPackagePolicy>(
(packagePolicy) => {
if (packagePolicy.namespace && !namespacesValues.includes(packagePolicy.namespace)) {
namespacesValues.push(packagePolicy.namespace);
}
const dsInputTypes: string[] = [];
@ -74,11 +74,11 @@ export const PackageConfigsTable: React.FunctionComponent<Props> = ({
dsInputTypes.sort(stringSortAscending);
return {
...packageConfig,
...packagePolicy,
inputTypes: dsInputTypes,
packageName: packageConfig.package?.name ?? '',
packageTitle: packageConfig.package?.title ?? '',
packageVersion: packageConfig.package?.version ?? '',
packageName: packagePolicy.package?.name ?? '',
packageTitle: packagePolicy.package?.title ?? '',
packageVersion: packagePolicy.package?.version ?? '',
};
}
);
@ -87,19 +87,19 @@ export const PackageConfigsTable: React.FunctionComponent<Props> = ({
inputTypesValues.sort(stringSortAscending);
return [
mappedPackageConfigs,
mappedPackagePolicies,
namespacesValues.map(toFilterOption),
inputTypesValues.map(toFilterOption),
];
}, [originalPackageConfigs]);
}, [originalPackagePolicies]);
const columns = useMemo(
(): EuiInMemoryTableProps<InMemoryPackageConfig>['columns'] => [
(): EuiInMemoryTableProps<InMemoryPackagePolicy>['columns'] => [
{
field: 'name',
sortable: true,
name: i18n.translate(
'xpack.ingestManager.configDetails.packageConfigsTable.nameColumnTitle',
'xpack.ingestManager.policyDetails.packagePoliciesTable.nameColumnTitle',
{
defaultMessage: 'Name',
}
@ -113,7 +113,7 @@ export const PackageConfigsTable: React.FunctionComponent<Props> = ({
{
field: 'description',
name: i18n.translate(
'xpack.ingestManager.configDetails.packageConfigsTable.descriptionColumnTitle',
'xpack.ingestManager.policyDetails.packagePoliciesTable.descriptionColumnTitle',
{
defaultMessage: 'Description',
}
@ -128,19 +128,19 @@ export const PackageConfigsTable: React.FunctionComponent<Props> = ({
field: 'packageTitle',
sortable: true,
name: i18n.translate(
'xpack.ingestManager.configDetails.packageConfigsTable.packageNameColumnTitle',
'xpack.ingestManager.policyDetails.packagePoliciesTable.packageNameColumnTitle',
{
defaultMessage: 'Integration',
}
),
render(packageTitle: string, packageConfig: InMemoryPackageConfig) {
render(packageTitle: string, packagePolicy: InMemoryPackagePolicy) {
return (
<EuiFlexGroup gutterSize="s" alignItems="center">
{packageConfig.package && (
{packagePolicy.package && (
<EuiFlexItem grow={false}>
<PackageIcon
packageName={packageConfig.package.name}
version={packageConfig.package.version}
packageName={packagePolicy.package.name}
version={packagePolicy.package.version}
size="m"
tryApi={true}
/>
@ -154,36 +154,36 @@ export const PackageConfigsTable: React.FunctionComponent<Props> = ({
{
field: 'namespace',
name: i18n.translate(
'xpack.ingestManager.configDetails.packageConfigsTable.namespaceColumnTitle',
'xpack.ingestManager.policyDetails.packagePoliciesTable.namespaceColumnTitle',
{
defaultMessage: 'Namespace',
}
),
render: (namespace: InMemoryPackageConfig['namespace']) => {
render: (namespace: InMemoryPackagePolicy['namespace']) => {
return namespace ? <EuiBadge color="hollow">{namespace}</EuiBadge> : '';
},
},
{
name: i18n.translate(
'xpack.ingestManager.configDetails.packageConfigsTable.actionsColumnTitle',
'xpack.ingestManager.policyDetails.packagePoliciesTable.actionsColumnTitle',
{
defaultMessage: 'Actions',
}
),
actions: [
{
render: (packageConfig: InMemoryPackageConfig) => (
render: (packagePolicy: InMemoryPackagePolicy) => (
<ContextMenuActions
items={[
// FIXME: implement View package config action
// FIXME: implement View package policy action
// <EuiContextMenuItem
// disabled
// icon="inspect"
// onClick={() => {}}
// key="packageConfigView"
// key="packagePolicyView"
// >
// <FormattedMessage
// id="xpack.ingestManager.configDetails.packageConfigsTable.viewActionTitle"
// id="xpack.ingestManager.policyDetails.packagePoliciesTable.viewActionTitle"
// defaultMessage="View integration"
// />
// </EuiContextMenuItem>,
@ -191,41 +191,41 @@ export const PackageConfigsTable: React.FunctionComponent<Props> = ({
disabled={!hasWriteCapabilities}
icon="pencil"
href={getHref('edit_integration', {
configId: config.id,
packageConfigId: packageConfig.id,
policyId: agentPolicy.id,
packagePolicyId: packagePolicy.id,
})}
key="packageConfigEdit"
key="packagePolicyEdit"
>
<FormattedMessage
id="xpack.ingestManager.configDetails.packageConfigsTable.editActionTitle"
id="xpack.ingestManager.policyDetails.packagePoliciesTable.editActionTitle"
defaultMessage="Edit integration"
/>
</EuiContextMenuItem>,
// FIXME: implement Copy package config action
// <EuiContextMenuItem disabled icon="copy" onClick={() => {}} key="packageConfigCopy">
// FIXME: implement Copy package policy action
// <EuiContextMenuItem disabled icon="copy" onClick={() => {}} key="packagePolicyCopy">
// <FormattedMessage
// id="xpack.ingestManager.configDetails.packageConfigsTable.copyActionTitle"
// id="xpack.ingestManager.policyDetails.packagePoliciesTable.copyActionTitle"
// defaultMessage="Copy integration"
// />
// </EuiContextMenuItem>,
<PackageConfigDeleteProvider agentConfig={config} key="packageConfigDelete">
{(deletePackageConfigsPrompt) => {
<PackagePolicyDeleteProvider agentPolicy={agentPolicy} key="packagePolicyDelete">
{(deletePackagePoliciesPrompt) => {
return (
<DangerEuiContextMenuItem
disabled={!hasWriteCapabilities}
icon="trash"
onClick={() => {
deletePackageConfigsPrompt([packageConfig.id], refreshConfig);
deletePackagePoliciesPrompt([packagePolicy.id], refreshAgentPolicy);
}}
>
<FormattedMessage
id="xpack.ingestManager.configDetails.packageConfigsTable.deleteActionTitle"
id="xpack.ingestManager.policyDetails.packagePoliciesTable.deleteActionTitle"
defaultMessage="Delete integration"
/>
</DangerEuiContextMenuItem>
);
}}
</PackageConfigDeleteProvider>,
</PackagePolicyDeleteProvider>,
]}
/>
),
@ -233,13 +233,13 @@ export const PackageConfigsTable: React.FunctionComponent<Props> = ({
],
},
],
[config, getHref, hasWriteCapabilities, refreshConfig]
[agentPolicy, getHref, hasWriteCapabilities, refreshAgentPolicy]
);
return (
<EuiInMemoryTable<InMemoryPackageConfig>
<EuiInMemoryTable<InMemoryPackagePolicy>
itemId="id"
items={packageConfigs}
items={packagePolicies}
columns={columns}
sorting={{
sort: {
@ -251,13 +251,13 @@ export const PackageConfigsTable: React.FunctionComponent<Props> = ({
search={{
toolsRight: [
<EuiButton
key="addPackageConfigButton"
key="addPackagePolicyButton"
isDisabled={!hasWriteCapabilities}
iconType="plusInCircle"
href={getHref('add_integration_from_configuration', { configId: config.id })}
href={getHref('add_integration_from_policy', { policyId: agentPolicy.id })}
>
<FormattedMessage
id="xpack.ingestManager.configDetails.addPackageConfigButtonText"
id="xpack.ingestManager.policyDetails.addPackagePolicyButtonText"
defaultMessage="Add integration"
/>
</EuiButton>,

View file

@ -9,21 +9,21 @@ import styled from 'styled-components';
import { EuiBottomBar, EuiFlexGroup, EuiFlexItem, EuiButtonEmpty, EuiButton } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import { AgentConfig } from '../../../../../types';
import { AgentPolicy } from '../../../../../types';
import {
useLink,
useCore,
useCapabilities,
sendUpdateAgentConfig,
sendUpdateAgentPolicy,
useConfig,
sendGetAgentStatus,
} from '../../../../../hooks';
import {
AgentConfigForm,
agentConfigFormValidation,
ConfirmDeployConfigModal,
AgentPolicyForm,
agentPolicyFormValidation,
ConfirmDeployAgentPolicyModal,
} from '../../../components';
import { useConfigRefresh } from '../../hooks';
import { useAgentPolicyRefresh } from '../../hooks';
const FormWrapper = styled.div`
max-width: 800px;
@ -31,8 +31,8 @@ const FormWrapper = styled.div`
margin-left: auto;
`;
export const ConfigSettingsView = memo<{ config: AgentConfig }>(
({ config: originalAgentConfig }) => {
export const SettingsView = memo<{ agentPolicy: AgentPolicy }>(
({ agentPolicy: originalAgentPolicy }) => {
const {
notifications,
chrome: { getIsNavDrawerLocked$ },
@ -44,16 +44,16 @@ export const ConfigSettingsView = memo<{ config: AgentConfig }>(
const history = useHistory();
const { getPath } = useLink();
const hasWriteCapabilites = useCapabilities().write;
const refreshConfig = useConfigRefresh();
const refreshAgentPolicy = useAgentPolicyRefresh();
const [isNavDrawerLocked, setIsNavDrawerLocked] = useState(false);
const [agentConfig, setAgentConfig] = useState<AgentConfig>({
...originalAgentConfig,
const [agentPolicy, setAgentPolicy] = useState<AgentPolicy>({
...originalAgentPolicy,
});
const [isLoading, setIsLoading] = useState<boolean>(false);
const [hasChanges, setHasChanges] = useState<boolean>(false);
const [agentCount, setAgentCount] = useState<number>(0);
const [withSysMonitoring, setWithSysMonitoring] = useState<boolean>(true);
const validation = agentConfigFormValidation(agentConfig);
const validation = agentPolicyFormValidation(agentPolicy);
useEffect(() => {
const subscription = getIsNavDrawerLocked$().subscribe((newIsNavDrawerLocked: boolean) => {
@ -63,20 +63,20 @@ export const ConfigSettingsView = memo<{ config: AgentConfig }>(
return () => subscription.unsubscribe();
});
const updateAgentConfig = (updatedFields: Partial<AgentConfig>) => {
setAgentConfig({
...agentConfig,
const updateAgentPolicy = (updatedFields: Partial<AgentPolicy>) => {
setAgentPolicy({
...agentPolicy,
...updatedFields,
});
setHasChanges(true);
};
const submitUpdateAgentConfig = async () => {
const submitUpdateAgentPolicy = async () => {
setIsLoading(true);
try {
// eslint-disable-next-line @typescript-eslint/naming-convention
const { name, description, namespace, monitoring_enabled } = agentConfig;
const { data, error } = await sendUpdateAgentConfig(agentConfig.id, {
const { name, description, namespace, monitoring_enabled } = agentPolicy;
const { data, error } = await sendUpdateAgentPolicy(agentPolicy.id, {
name,
description,
namespace,
@ -84,26 +84,26 @@ export const ConfigSettingsView = memo<{ config: AgentConfig }>(
});
if (data?.success) {
notifications.toasts.addSuccess(
i18n.translate('xpack.ingestManager.editAgentConfig.successNotificationTitle', {
i18n.translate('xpack.ingestManager.editAgentPolicy.successNotificationTitle', {
defaultMessage: "Successfully updated '{name}' settings",
values: { name: agentConfig.name },
values: { name: agentPolicy.name },
})
);
refreshConfig();
refreshAgentPolicy();
setHasChanges(false);
} else {
notifications.toasts.addDanger(
error
? error.message
: i18n.translate('xpack.ingestManager.editAgentConfig.errorNotificationTitle', {
defaultMessage: 'Unable to update agent config',
: i18n.translate('xpack.ingestManager.editAgentPolicy.errorNotificationTitle', {
defaultMessage: 'Unable to update agent policy',
})
);
}
} catch (e) {
notifications.toasts.addDanger(
i18n.translate('xpack.ingestManager.editAgentConfig.errorNotificationTitle', {
defaultMessage: 'Unable to update agent config',
i18n.translate('xpack.ingestManager.editAgentPolicy.errorNotificationTitle', {
defaultMessage: 'Unable to update agent policy',
})
);
}
@ -114,26 +114,26 @@ export const ConfigSettingsView = memo<{ config: AgentConfig }>(
// Retrieve agent count if fleet is enabled
if (isFleetEnabled) {
setIsLoading(true);
const { data } = await sendGetAgentStatus({ configId: agentConfig.id });
const { data } = await sendGetAgentStatus({ policyId: agentPolicy.id });
if (data?.results.total) {
setAgentCount(data.results.total);
} else {
await submitUpdateAgentConfig();
await submitUpdateAgentPolicy();
}
} else {
await submitUpdateAgentConfig();
await submitUpdateAgentPolicy();
}
};
return (
<FormWrapper>
{agentCount ? (
<ConfirmDeployConfigModal
<ConfirmDeployAgentPolicyModal
agentCount={agentCount}
agentConfig={agentConfig}
agentPolicy={agentPolicy}
onConfirm={() => {
setAgentCount(0);
submitUpdateAgentConfig();
submitUpdateAgentPolicy();
}}
onCancel={() => {
setAgentCount(0);
@ -141,15 +141,15 @@ export const ConfigSettingsView = memo<{ config: AgentConfig }>(
}}
/>
) : null}
<AgentConfigForm
agentConfig={agentConfig}
updateAgentConfig={updateAgentConfig}
<AgentPolicyForm
agentPolicy={agentPolicy}
updateAgentPolicy={updateAgentPolicy}
withSysMonitoring={withSysMonitoring}
updateSysMonitoring={(newValue) => setWithSysMonitoring(newValue)}
validation={validation}
isEditing={true}
onDelete={() => {
history.push(getPath('configurations_list'));
history.push(getPath('policies_list'));
}}
/>
{/* TODO #64541 - Remove classes */}
@ -166,7 +166,7 @@ export const ConfigSettingsView = memo<{ config: AgentConfig }>(
<EuiFlexGroup justifyContent="spaceBetween" alignItems="center">
<EuiFlexItem>
<FormattedMessage
id="xpack.ingestManager.editAgentConfig.unsavedChangesText"
id="xpack.ingestManager.editAgentPolicy.unsavedChangesText"
defaultMessage="You have unsaved changes"
/>
</EuiFlexItem>
@ -176,12 +176,12 @@ export const ConfigSettingsView = memo<{ config: AgentConfig }>(
<EuiButtonEmpty
color="ghost"
onClick={() => {
setAgentConfig({ ...originalAgentConfig });
setAgentPolicy({ ...originalAgentPolicy });
setHasChanges(false);
}}
>
<FormattedMessage
id="xpack.ingestManager.editAgentConfig.cancelButtonText"
id="xpack.ingestManager.editAgentPolicy.cancelButtonText"
defaultMessage="Cancel"
/>
</EuiButtonEmpty>
@ -199,12 +199,12 @@ export const ConfigSettingsView = memo<{ config: AgentConfig }>(
>
{isLoading ? (
<FormattedMessage
id="xpack.ingestManager.editAgentConfig.savingButtonText"
id="xpack.ingestManager.editAgentPolicy.savingButtonText"
defaultMessage="Saving…"
/>
) : (
<FormattedMessage
id="xpack.ingestManager.editAgentConfig.saveButtonText"
id="xpack.ingestManager.editAgentPolicy.saveButtonText"
defaultMessage="Save changes"
/>
)}

View file

@ -4,4 +4,4 @@
* you may not use this file except in compliance with the Elastic License.
*/
export { useGetAgentStatus, AgentStatusRefreshContext } from './use_agent_status';
export { ConfigRefreshContext, useConfigRefresh } from './use_config';
export { AgentPolicyRefreshContext, useAgentPolicyRefresh } from './use_config';

View file

@ -11,11 +11,11 @@ import { UseRequestConfig } from '../../../../hooks/use_request/use_request';
type RequestOptions = Pick<Partial<UseRequestConfig>, 'pollIntervalMs'>;
export function useGetAgentStatus(configId?: string, options?: RequestOptions) {
export function useGetAgentStatus(policyId?: string, options?: RequestOptions) {
const agentStatusRequest = useRequest<GetAgentStatusResponse>({
path: agentRouteService.getStatusPath(),
query: {
configId,
policyId,
},
method: 'get',
...options,

View file

@ -5,8 +5,8 @@
*/
import React from 'react';
export const ConfigRefreshContext = React.createContext({ refresh: () => {} });
export const AgentPolicyRefreshContext = React.createContext({ refresh: () => {} });
export function useConfigRefresh() {
return React.useContext(ConfigRefreshContext).refresh;
export function useAgentPolicyRefresh() {
return React.useContext(AgentPolicyRefreshContext).refresh;
}

View file

@ -20,14 +20,14 @@ import {
} from '@elastic/eui';
import { Props as EuiTabProps } from '@elastic/eui/src/components/tabs/tab';
import styled from 'styled-components';
import { AgentConfig, AgentConfigDetailsDeployAgentAction } from '../../../types';
import { AgentPolicy, AgentPolicyDetailsDeployAgentAction } from '../../../types';
import { PAGE_ROUTING_PATHS } from '../../../constants';
import { useGetOneAgentConfig, useLink, useBreadcrumbs, useCore } from '../../../hooks';
import { useGetOneAgentPolicy, useLink, useBreadcrumbs, useCore } from '../../../hooks';
import { Loading, Error } from '../../../components';
import { WithHeaderLayout } from '../../../layouts';
import { ConfigRefreshContext, useGetAgentStatus, AgentStatusRefreshContext } from './hooks';
import { LinkedAgentCount, AgentConfigActionMenu } from '../components';
import { ConfigPackageConfigsView, ConfigSettingsView } from './components';
import { AgentPolicyRefreshContext, useGetAgentStatus, AgentStatusRefreshContext } from './hooks';
import { LinkedAgentCount, AgentPolicyActionMenu } from '../components';
import { PackagePoliciesView, SettingsView } from './components';
import { useIntraAppState } from '../../../hooks/use_intra_app_state';
const Divider = styled.div`
@ -36,22 +36,22 @@ const Divider = styled.div`
border-left: ${(props) => props.theme.eui.euiBorderThin};
`;
export const AgentConfigDetailsPage: React.FunctionComponent = () => {
export const AgentPolicyDetailsPage: React.FunctionComponent = () => {
const {
params: { configId, tabId = '' },
} = useRouteMatch<{ configId: string; tabId?: string }>();
params: { policyId, tabId = '' },
} = useRouteMatch<{ policyId: string; tabId?: string }>();
const history = useHistory();
const { getHref, getPath } = useLink();
const agentConfigRequest = useGetOneAgentConfig(configId);
const agentConfig = agentConfigRequest.data ? agentConfigRequest.data.item : null;
const { isLoading, error, sendRequest: refreshAgentConfig } = agentConfigRequest;
const [redirectToAgentConfigList] = useState<boolean>(false);
const agentStatusRequest = useGetAgentStatus(configId);
const agentPolicyRequest = useGetOneAgentPolicy(policyId);
const agentPolicy = agentPolicyRequest.data ? agentPolicyRequest.data.item : null;
const { isLoading, error, sendRequest: refreshAgentPolicy } = agentPolicyRequest;
const [redirectToAgentPolicyList] = useState<boolean>(false);
const agentStatusRequest = useGetAgentStatus(policyId);
const { refreshAgentStatus } = agentStatusRequest;
const {
application: { navigateToApp },
} = useCore();
const routeState = useIntraAppState<AgentConfigDetailsDeployAgentAction>();
const routeState = useIntraAppState<AgentPolicyDetailsDeployAgentAction>();
const agentStatus = agentStatusRequest.data?.results;
const queryParams = new URLSearchParams(useLocation().search);
const openEnrollmentFlyoutOpenByDefault = queryParams.get('openEnrollmentFlyout') === 'true';
@ -62,25 +62,25 @@ export const AgentConfigDetailsPage: React.FunctionComponent = () => {
<EuiFlexItem>
<EuiButtonEmpty
iconType="arrowLeft"
href={getHref('configurations_list')}
href={getHref('policies_list')}
flush="left"
size="xs"
>
<FormattedMessage
id="xpack.ingestManager.configDetails.viewAgentListTitle"
defaultMessage="View all agent configurations"
id="xpack.ingestManager.policyDetails.viewAgentListTitle"
defaultMessage="View all agent policies"
/>
</EuiButtonEmpty>
</EuiFlexItem>
<EuiFlexItem>
<EuiText className="eui-textBreakWord">
<h1>
{(agentConfig && agentConfig.name) || (
{(agentPolicy && agentPolicy.name) || (
<FormattedMessage
id="xpack.ingestManager.configDetails.configDetailsTitle"
defaultMessage="Config '{id}'"
id="xpack.ingestManager.policyDetails.policyDetailsTitle"
defaultMessage="Policy '{id}'"
values={{
id: configId,
id: policyId,
}}
/>
)}
@ -88,17 +88,17 @@ export const AgentConfigDetailsPage: React.FunctionComponent = () => {
</EuiText>
</EuiFlexItem>
{agentConfig && agentConfig.description ? (
{agentPolicy && agentPolicy.description ? (
<EuiFlexItem>
<EuiSpacer size="s" />
<EuiText color="subdued" size="s" className="eui-textBreakWord">
{agentConfig.description}
{agentPolicy.description}
</EuiText>
</EuiFlexItem>
) : null}
</EuiFlexGroup>
),
[getHref, agentConfig, configId]
[getHref, agentPolicy, policyId]
);
const enrollmentCancelClickHandler = useCallback(() => {
@ -109,26 +109,26 @@ export const AgentConfigDetailsPage: React.FunctionComponent = () => {
const headerRightContent = useMemo(
() =>
agentConfig ? (
agentPolicy ? (
<EuiFlexGroup justifyContent={'flexEnd'} direction="row">
{[
{
label: i18n.translate('xpack.ingestManager.configDetails.summary.revision', {
label: i18n.translate('xpack.ingestManager.policyDetails.summary.revision', {
defaultMessage: 'Revision',
}),
content: agentConfig?.revision ?? 0,
content: agentPolicy?.revision ?? 0,
},
{ isDivider: true },
{
label: i18n.translate('xpack.ingestManager.configDetails.summary.package_configs', {
label: i18n.translate('xpack.ingestManager.policyDetails.summary.integrations', {
defaultMessage: 'Integrations',
}),
content: (
<EuiI18nNumber
value={
(agentConfig &&
agentConfig.package_configs &&
agentConfig.package_configs.length) ||
(agentPolicy &&
agentPolicy.package_policies &&
agentPolicy.package_policies.length) ||
0
}
/>
@ -136,25 +136,25 @@ export const AgentConfigDetailsPage: React.FunctionComponent = () => {
},
{ isDivider: true },
{
label: i18n.translate('xpack.ingestManager.configDetails.summary.usedBy', {
label: i18n.translate('xpack.ingestManager.policyDetails.summary.usedBy', {
defaultMessage: 'Used by',
}),
content: (
<LinkedAgentCount
count={(agentStatus && agentStatus.total) || 0}
agentConfigId={(agentConfig && agentConfig.id) || ''}
agentPolicyId={(agentPolicy && agentPolicy.id) || ''}
/>
),
},
{ isDivider: true },
{
label: i18n.translate('xpack.ingestManager.configDetails.summary.lastUpdated', {
label: i18n.translate('xpack.ingestManager.policyDetails.summary.lastUpdated', {
defaultMessage: 'Last updated on',
}),
content:
(agentConfig && (
(agentPolicy && (
<FormattedDate
value={agentConfig?.updated_at}
value={agentPolicy?.updated_at}
year="numeric"
month="short"
day="2-digit"
@ -164,12 +164,12 @@ export const AgentConfigDetailsPage: React.FunctionComponent = () => {
},
{ isDivider: true },
{
content: agentConfig && (
<AgentConfigActionMenu
config={agentConfig}
content: agentPolicy && (
<AgentPolicyActionMenu
agentPolicy={agentPolicy}
fullButton={true}
onCopySuccess={(newAgentConfig: AgentConfig) => {
history.push(getPath('configuration_details', { configId: newAgentConfig.id }));
onCopySuccess={(newAgentPolicy: AgentPolicy) => {
history.push(getPath('policy_details', { policyId: newAgentPolicy.id }));
}}
enrollmentFlyoutOpenByDefault={openEnrollmentFlyoutOpenByDefault}
onCancelEnrollment={
@ -201,32 +201,32 @@ export const AgentConfigDetailsPage: React.FunctionComponent = () => {
</EuiFlexGroup>
) : undefined,
/* eslint-disable-next-line react-hooks/exhaustive-deps */
[agentConfig, configId, agentStatus]
[agentPolicy, policyId, agentStatus]
);
const headerTabs = useMemo(() => {
return [
{
id: 'integrations',
name: i18n.translate('xpack.ingestManager.configDetails.subTabs.packageConfigsTabText', {
name: i18n.translate('xpack.ingestManager.policyDetails.subTabs.packagePoliciesTabText', {
defaultMessage: 'Integrations',
}),
href: getHref('configuration_details', { configId, tabId: 'integrations' }),
href: getHref('policy_details', { policyId, tabId: 'integrations' }),
isSelected: tabId === '' || tabId === 'integrations',
},
{
id: 'settings',
name: i18n.translate('xpack.ingestManager.configDetails.subTabs.settingsTabText', {
name: i18n.translate('xpack.ingestManager.policyDetails.subTabs.settingsTabText', {
defaultMessage: 'Settings',
}),
href: getHref('configuration_details', { configId, tabId: 'settings' }),
href: getHref('policy_details', { policyId, tabId: 'settings' }),
isSelected: tabId === 'settings',
},
];
}, [getHref, configId, tabId]);
}, [getHref, policyId, tabId]);
const content = useMemo(() => {
if (redirectToAgentConfigList) {
if (redirectToAgentPolicyList) {
return <Redirect to="/" />;
}
@ -239,8 +239,8 @@ export const AgentConfigDetailsPage: React.FunctionComponent = () => {
<Error
title={
<FormattedMessage
id="xpack.ingestManager.configDetails.unexceptedErrorTitle"
defaultMessage="An error happened while loading the config"
id="xpack.ingestManager.policyDetails.unexceptedErrorTitle"
defaultMessage="An error happened while loading the agent policy"
/>
}
error={error}
@ -248,30 +248,30 @@ export const AgentConfigDetailsPage: React.FunctionComponent = () => {
);
}
if (!agentConfig) {
if (!agentPolicy) {
return (
<Error
title={
<FormattedMessage
id="xpack.ingestManager.configDetails.unexceptedErrorTitle"
defaultMessage="An error happened while loading the config"
id="xpack.ingestManager.policyDetails.unexceptedErrorTitle"
defaultMessage="An error happened while loading the agent policy"
/>
}
error={i18n.translate('xpack.ingestManager.configDetails.configNotFoundErrorTitle', {
defaultMessage: "Config '{id}' not found",
error={i18n.translate('xpack.ingestManager.policyDetails.policyNotFoundErrorTitle', {
defaultMessage: "Policy '{id}' not found",
values: {
id: configId,
id: policyId,
},
})}
/>
);
}
return <AgentConfigDetailsContent agentConfig={agentConfig} />;
}, [agentConfig, configId, error, isLoading, redirectToAgentConfigList]);
return <AgentPolicyDetailsContent agentPolicy={agentPolicy} />;
}, [agentPolicy, policyId, error, isLoading, redirectToAgentPolicyList]);
return (
<ConfigRefreshContext.Provider value={{ refresh: refreshAgentConfig }}>
<AgentPolicyRefreshContext.Provider value={{ refresh: refreshAgentPolicy }}>
<AgentStatusRefreshContext.Provider value={{ refresh: refreshAgentStatus }}>
<WithHeaderLayout
leftColumn={headerLeftContent}
@ -281,26 +281,26 @@ export const AgentConfigDetailsPage: React.FunctionComponent = () => {
{content}
</WithHeaderLayout>
</AgentStatusRefreshContext.Provider>
</ConfigRefreshContext.Provider>
</AgentPolicyRefreshContext.Provider>
);
};
const AgentConfigDetailsContent: React.FunctionComponent<{ agentConfig: AgentConfig }> = ({
agentConfig,
const AgentPolicyDetailsContent: React.FunctionComponent<{ agentPolicy: AgentPolicy }> = ({
agentPolicy,
}) => {
useBreadcrumbs('configuration_details', { configName: agentConfig.name });
useBreadcrumbs('policy_details', { policyName: agentPolicy.name });
return (
<Switch>
<Route
path={PAGE_ROUTING_PATHS.configuration_details_settings}
path={PAGE_ROUTING_PATHS.policy_details_settings}
render={() => {
return <ConfigSettingsView config={agentConfig} />;
return <SettingsView agentPolicy={agentPolicy} />;
}}
/>
<Route
path={PAGE_ROUTING_PATHS.configuration_details}
path={PAGE_ROUTING_PATHS.policy_details}
render={() => {
return <ConfigPackageConfigsView config={agentConfig} />;
return <PackagePoliciesView agentPolicy={agentPolicy} />;
}}
/>
</Switch>

View file

@ -15,34 +15,34 @@ import {
EuiFlexItem,
EuiSpacer,
} from '@elastic/eui';
import { AgentConfig, PackageInfo, UpdatePackageConfig } from '../../../types';
import { AgentPolicy, PackageInfo, UpdatePackagePolicy } from '../../../types';
import {
useLink,
useBreadcrumbs,
useCore,
useConfig,
sendUpdatePackageConfig,
sendUpdatePackagePolicy,
sendGetAgentStatus,
sendGetOneAgentConfig,
sendGetOnePackageConfig,
sendGetOneAgentPolicy,
sendGetOnePackagePolicy,
sendGetPackageInfoByKey,
} from '../../../hooks';
import { Loading, Error } from '../../../components';
import { ConfirmDeployConfigModal } from '../components';
import { CreatePackageConfigPageLayout } from '../create_package_config_page/components';
import { ConfirmDeployAgentPolicyModal } from '../components';
import { CreatePackagePolicyPageLayout } from '../create_package_policy_page/components';
import {
PackageConfigValidationResults,
validatePackageConfig,
PackagePolicyValidationResults,
validatePackagePolicy,
validationHasErrors,
} from '../create_package_config_page/services';
} from '../create_package_policy_page/services';
import {
PackageConfigFormState,
CreatePackageConfigFrom,
} from '../create_package_config_page/types';
import { StepConfigurePackage } from '../create_package_config_page/step_configure_package';
import { StepDefinePackageConfig } from '../create_package_config_page/step_define_package_config';
PackagePolicyFormState,
CreatePackagePolicyFrom,
} from '../create_package_policy_page/types';
import { StepConfigurePackagePolicy } from '../create_package_policy_page/step_configure_package';
import { StepDefinePackagePolicy } from '../create_package_policy_page/step_define_package_policy';
export const EditPackageConfigPage: React.FunctionComponent = () => {
export const EditPackagePolicyPage: React.FunctionComponent = () => {
const {
notifications,
chrome: { getIsNavDrawerLocked$ },
@ -52,7 +52,7 @@ export const EditPackageConfigPage: React.FunctionComponent = () => {
fleet: { enabled: isFleetEnabled },
} = useConfig();
const {
params: { configId, packageConfigId },
params: { policyId, packagePolicyId },
} = useRouteMatch();
const history = useHistory();
const { getHref, getPath } = useLink();
@ -66,36 +66,36 @@ export const EditPackageConfigPage: React.FunctionComponent = () => {
return () => subscription.unsubscribe();
});
// Agent config, package info, and package config states
// Agent policy, package info, and package policy states
const [isLoadingData, setIsLoadingData] = useState<boolean>(true);
const [loadingError, setLoadingError] = useState<Error>();
const [agentConfig, setAgentConfig] = useState<AgentConfig>();
const [agentPolicy, setAgentPolicy] = useState<AgentPolicy>();
const [packageInfo, setPackageInfo] = useState<PackageInfo>();
const [packageConfig, setPackageConfig] = useState<UpdatePackageConfig>({
const [packagePolicy, setPackagePolicy] = useState<UpdatePackagePolicy>({
name: '',
description: '',
namespace: '',
config_id: '',
policy_id: '',
enabled: true,
output_id: '',
inputs: [],
version: '',
});
// Retrieve agent config, package, and package config info
// Retrieve agent policy, package, and package policy info
useEffect(() => {
const getData = async () => {
setIsLoadingData(true);
setLoadingError(undefined);
try {
const [{ data: agentConfigData }, { data: packageConfigData }] = await Promise.all([
sendGetOneAgentConfig(configId),
sendGetOnePackageConfig(packageConfigId),
const [{ data: agentPolicyData }, { data: packagePolicyData }] = await Promise.all([
sendGetOneAgentPolicy(policyId),
sendGetOnePackagePolicy(packagePolicyId),
]);
if (agentConfigData?.item) {
setAgentConfig(agentConfigData.item);
if (agentPolicyData?.item) {
setAgentPolicy(agentPolicyData.item);
}
if (packageConfigData?.item) {
if (packagePolicyData?.item) {
const {
id,
revision,
@ -106,11 +106,11 @@ export const EditPackageConfigPage: React.FunctionComponent = () => {
updated_by,
updated_at,
/* eslint-enable @typescript-eslint/naming-convention */
...restOfPackageConfig
} = packageConfigData.item;
...restOfPackagePolicy
} = packagePolicyData.item;
// Remove `compiled_stream` from all stream info, we assign this after saving
const newPackageConfig = {
...restOfPackageConfig,
const newPackagePolicy = {
...restOfPackagePolicy,
inputs: inputs.map((input) => {
const { streams, ...restOfInput } = input;
return {
@ -123,14 +123,14 @@ export const EditPackageConfigPage: React.FunctionComponent = () => {
};
}),
};
setPackageConfig(newPackageConfig);
if (packageConfigData.item.package) {
setPackagePolicy(newPackagePolicy);
if (packagePolicyData.item.package) {
const { data: packageData } = await sendGetPackageInfoByKey(
`${packageConfigData.item.package.name}-${packageConfigData.item.package.version}`
`${packagePolicyData.item.package.name}-${packagePolicyData.item.package.version}`
);
if (packageData?.response) {
setPackageInfo(packageData.response);
setValidationResults(validatePackageConfig(newPackageConfig, packageData.response));
setValidationResults(validatePackagePolicy(newPackagePolicy, packageData.response));
setFormState('VALID');
}
}
@ -141,13 +141,13 @@ export const EditPackageConfigPage: React.FunctionComponent = () => {
setIsLoadingData(false);
};
getData();
}, [configId, packageConfigId]);
}, [policyId, packagePolicyId]);
// Retrieve agent count
const [agentCount, setAgentCount] = useState<number>(0);
useEffect(() => {
const getAgentCount = async () => {
const { data } = await sendGetAgentStatus({ configId });
const { data } = await sendGetAgentStatus({ policyId });
if (data?.results.total) {
setAgentCount(data.results.total);
}
@ -156,42 +156,42 @@ export const EditPackageConfigPage: React.FunctionComponent = () => {
if (isFleetEnabled) {
getAgentCount();
}
}, [configId, isFleetEnabled]);
}, [policyId, isFleetEnabled]);
// Package config validation state
const [validationResults, setValidationResults] = useState<PackageConfigValidationResults>();
// Package policy validation state
const [validationResults, setValidationResults] = useState<PackagePolicyValidationResults>();
const hasErrors = validationResults ? validationHasErrors(validationResults) : false;
// Update package config validation
const updatePackageConfigValidation = useCallback(
(newPackageConfig?: UpdatePackageConfig) => {
// Update package policy validation
const updatePackagePolicyValidation = useCallback(
(newPackagePolicy?: UpdatePackagePolicy) => {
if (packageInfo) {
const newValidationResult = validatePackageConfig(
newPackageConfig || packageConfig,
const newValidationResult = validatePackagePolicy(
newPackagePolicy || packagePolicy,
packageInfo
);
setValidationResults(newValidationResult);
// eslint-disable-next-line no-console
console.debug('Package config validation results', newValidationResult);
console.debug('Package policy validation results', newValidationResult);
return newValidationResult;
}
},
[packageConfig, packageInfo]
[packagePolicy, packageInfo]
);
// Update package config method
const updatePackageConfig = useCallback(
(updatedFields: Partial<UpdatePackageConfig>) => {
const newPackageConfig = {
...packageConfig,
// Update package policy method
const updatePackagePolicy = useCallback(
(updatedFields: Partial<UpdatePackagePolicy>) => {
const newPackagePolicy = {
...packagePolicy,
...updatedFields,
};
setPackageConfig(newPackageConfig);
setPackagePolicy(newPackagePolicy);
// eslint-disable-next-line no-console
console.debug('Package config updated', newPackageConfig);
const newValidationResults = updatePackageConfigValidation(newPackageConfig);
console.debug('Package policy updated', newPackagePolicy);
const newValidationResults = updatePackagePolicyValidation(newPackagePolicy);
const hasValidationErrors = newValidationResults
? validationHasErrors(newValidationResults)
: false;
@ -199,17 +199,17 @@ export const EditPackageConfigPage: React.FunctionComponent = () => {
setFormState('VALID');
}
},
[packageConfig, updatePackageConfigValidation]
[packagePolicy, updatePackagePolicyValidation]
);
// Cancel url
const cancelUrl = getHref('configuration_details', { configId });
const cancelUrl = getHref('policy_details', { policyId });
// Save package config
const [formState, setFormState] = useState<PackageConfigFormState>('INVALID');
const savePackageConfig = async () => {
// Save package policy
const [formState, setFormState] = useState<PackagePolicyFormState>('INVALID');
const savePackagePolicy = async () => {
setFormState('LOADING');
const result = await sendUpdatePackageConfig(packageConfigId, packageConfig);
const result = await sendUpdatePackagePolicy(packagePolicyId, packagePolicy);
setFormState('SUBMITTED');
return result;
};
@ -223,22 +223,22 @@ export const EditPackageConfigPage: React.FunctionComponent = () => {
setFormState('CONFIRM');
return;
}
const { error } = await savePackageConfig();
const { error } = await savePackagePolicy();
if (!error) {
history.push(getPath('configuration_details', { configId }));
history.push(getPath('policy_details', { policyId }));
notifications.toasts.addSuccess({
title: i18n.translate('xpack.ingestManager.editPackageConfig.updatedNotificationTitle', {
defaultMessage: `Successfully updated '{packageConfigName}'`,
title: i18n.translate('xpack.ingestManager.editPackagePolicy.updatedNotificationTitle', {
defaultMessage: `Successfully updated '{packagePolicyName}'`,
values: {
packageConfigName: packageConfig.name,
packagePolicyName: packagePolicy.name,
},
}),
text:
agentCount && agentConfig
? i18n.translate('xpack.ingestManager.editPackageConfig.updatedNotificationMessage', {
defaultMessage: `Fleet will deploy updates to all agents that use the '{agentConfigName}' configuration`,
agentCount && agentPolicy
? i18n.translate('xpack.ingestManager.editPackagePolicy.updatedNotificationMessage', {
defaultMessage: `Fleet will deploy updates to all agents that use the '{agentPolicyName}' policy`,
values: {
agentConfigName: agentConfig.name,
agentPolicyName: agentPolicy.name,
},
})
: undefined,
@ -246,25 +246,25 @@ export const EditPackageConfigPage: React.FunctionComponent = () => {
} else {
if (error.statusCode === 409) {
notifications.toasts.addError(error, {
title: i18n.translate('xpack.ingestManager.editPackageConfig.failedNotificationTitle', {
defaultMessage: `Error updating '{packageConfigName}'`,
title: i18n.translate('xpack.ingestManager.editPackagePolicy.failedNotificationTitle', {
defaultMessage: `Error updating '{packagePolicyName}'`,
values: {
packageConfigName: packageConfig.name,
packagePolicyName: packagePolicy.name,
},
}),
toastMessage: i18n.translate(
'xpack.ingestManager.editPackageConfig.failedConflictNotificationMessage',
'xpack.ingestManager.editPackagePolicy.failedConflictNotificationMessage',
{
defaultMessage: `Data is out of date. Refresh the page to get the latest configuration.`,
defaultMessage: `Data is out of date. Refresh the page to get the latest policy.`,
}
),
});
} else {
notifications.toasts.addError(error, {
title: i18n.translate('xpack.ingestManager.editPackageConfig.failedNotificationTitle', {
defaultMessage: `Error updating '{packageConfigName}'`,
title: i18n.translate('xpack.ingestManager.editPackagePolicy.failedNotificationTitle', {
defaultMessage: `Error updating '{packagePolicyName}'`,
values: {
packageConfigName: packageConfig.name,
packagePolicyName: packagePolicy.name,
},
}),
});
@ -274,72 +274,72 @@ export const EditPackageConfigPage: React.FunctionComponent = () => {
};
const layoutProps = {
from: 'edit' as CreatePackageConfigFrom,
from: 'edit' as CreatePackagePolicyFrom,
cancelUrl,
agentConfig,
agentPolicy,
packageInfo,
};
const configurePackage = useMemo(
() =>
agentConfig && packageInfo ? (
agentPolicy && packageInfo ? (
<>
<StepDefinePackageConfig
agentConfig={agentConfig}
<StepDefinePackagePolicy
agentPolicy={agentPolicy}
packageInfo={packageInfo}
packageConfig={packageConfig}
updatePackageConfig={updatePackageConfig}
packagePolicy={packagePolicy}
updatePackagePolicy={updatePackagePolicy}
validationResults={validationResults!}
/>
<StepConfigurePackage
<StepConfigurePackagePolicy
from={'edit'}
packageInfo={packageInfo}
packageConfig={packageConfig}
packageConfigId={packageConfigId}
updatePackageConfig={updatePackageConfig}
packagePolicy={packagePolicy}
packagePolicyId={packagePolicyId}
updatePackagePolicy={updatePackagePolicy}
validationResults={validationResults!}
submitAttempted={formState === 'INVALID'}
/>
</>
) : null,
[
agentConfig,
agentPolicy,
formState,
packageConfig,
packageConfigId,
packagePolicy,
packagePolicyId,
packageInfo,
updatePackageConfig,
updatePackagePolicy,
validationResults,
]
);
return (
<CreatePackageConfigPageLayout {...layoutProps} data-test-subj="editPackageConfig">
<CreatePackagePolicyPageLayout {...layoutProps} data-test-subj="editPackagePolicy">
{isLoadingData ? (
<Loading />
) : loadingError || !agentConfig || !packageInfo ? (
) : loadingError || !agentPolicy || !packageInfo ? (
<Error
title={
<FormattedMessage
id="xpack.ingestManager.editPackageConfig.errorLoadingDataTitle"
id="xpack.ingestManager.editPackagePolicy.errorLoadingDataTitle"
defaultMessage="Error loading data"
/>
}
error={
loadingError ||
i18n.translate('xpack.ingestManager.editPackageConfig.errorLoadingDataMessage', {
i18n.translate('xpack.ingestManager.editPackagePolicy.errorLoadingDataMessage', {
defaultMessage: 'There was an error loading this intergration information',
})
}
/>
) : (
<>
<Breadcrumb configName={agentConfig.name} configId={configId} />
<Breadcrumb policyName={agentPolicy.name} policyId={policyId} />
{formState === 'CONFIRM' && (
<ConfirmDeployConfigModal
<ConfirmDeployAgentPolicyModal
agentCount={agentCount}
agentConfig={agentConfig}
agentPolicy={agentPolicy}
onConfirm={onSubmit}
onCancel={() => setFormState('VALID')}
/>
@ -358,10 +358,10 @@ export const EditPackageConfigPage: React.FunctionComponent = () => {
>
<EuiFlexGroup justifyContent="spaceBetween" alignItems="center">
<EuiFlexItem grow={false}>
{agentConfig && packageInfo && formState === 'INVALID' ? (
{agentPolicy && packageInfo && formState === 'INVALID' ? (
<FormattedMessage
id="xpack.ingestManager.createPackageConfig.errorOnSaveText"
defaultMessage="Your integration configuration has errors. Please fix them before saving."
id="xpack.ingestManager.createPackagePolicy.errorOnSaveText"
defaultMessage="Your integration policy has errors. Please fix them before saving."
/>
) : null}
</EuiFlexItem>
@ -370,7 +370,7 @@ export const EditPackageConfigPage: React.FunctionComponent = () => {
<EuiFlexItem grow={false}>
<EuiButtonEmpty color="ghost" href={cancelUrl}>
<FormattedMessage
id="xpack.ingestManager.editPackageConfig.cancelButton"
id="xpack.ingestManager.editPackagePolicy.cancelButton"
defaultMessage="Cancel"
/>
</EuiButtonEmpty>
@ -385,7 +385,7 @@ export const EditPackageConfigPage: React.FunctionComponent = () => {
fill
>
<FormattedMessage
id="xpack.ingestManager.editPackageConfig.saveButton"
id="xpack.ingestManager.editPackagePolicy.saveButton"
defaultMessage="Save integration"
/>
</EuiButton>
@ -396,14 +396,14 @@ export const EditPackageConfigPage: React.FunctionComponent = () => {
</EuiBottomBar>
</>
)}
</CreatePackageConfigPageLayout>
</CreatePackagePolicyPageLayout>
);
};
const Breadcrumb: React.FunctionComponent<{ configName: string; configId: string }> = ({
configName,
configId,
const Breadcrumb: React.FunctionComponent<{ policyName: string; policyId: string }> = ({
policyName,
policyId,
}) => {
useBreadcrumbs('edit_integration', { configName, configId });
useBreadcrumbs('edit_integration', { policyName, policyId });
return null;
};

View file

@ -0,0 +1,36 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import React from 'react';
import { HashRouter as Router, Switch, Route } from 'react-router-dom';
import { PAGE_ROUTING_PATHS } from '../../constants';
import { useBreadcrumbs } from '../../hooks';
import { AgentPolicyListPage } from './list_page';
import { AgentPolicyDetailsPage } from './details_page';
import { CreatePackagePolicyPage } from './create_package_policy_page';
import { EditPackagePolicyPage } from './edit_package_policy_page';
export const AgentPolicyApp: React.FunctionComponent = () => {
useBreadcrumbs('policies');
return (
<Router>
<Switch>
<Route path={PAGE_ROUTING_PATHS.edit_integration}>
<EditPackagePolicyPage />
</Route>
<Route path={PAGE_ROUTING_PATHS.add_integration_from_policy}>
<CreatePackagePolicyPage />
</Route>
<Route path={PAGE_ROUTING_PATHS.policy_details}>
<AgentPolicyDetailsPage />
</Route>
<Route path={PAGE_ROUTING_PATHS.policies_list}>
<AgentPolicyListPage />
</Route>
</Switch>
</Router>
);
};

View file

@ -21,25 +21,25 @@ import {
EuiFlyoutProps,
EuiSpacer,
} from '@elastic/eui';
import { NewAgentConfig, AgentConfig } from '../../../../types';
import { useCapabilities, useCore, sendCreateAgentConfig } from '../../../../hooks';
import { AgentConfigForm, agentConfigFormValidation } from '../../components';
import { NewAgentPolicy, AgentPolicy } from '../../../../types';
import { useCapabilities, useCore, sendCreateAgentPolicy } from '../../../../hooks';
import { AgentPolicyForm, agentPolicyFormValidation } from '../../components';
const FlyoutWithHigherZIndex = styled(EuiFlyout)`
z-index: ${(props) => props.theme.eui.euiZLevel5};
`;
interface Props extends EuiFlyoutProps {
onClose: (createdAgentConfig?: AgentConfig) => void;
onClose: (createdAgentPolicy?: AgentPolicy) => void;
}
export const CreateAgentConfigFlyout: React.FunctionComponent<Props> = ({
export const CreateAgentPolicyFlyout: React.FunctionComponent<Props> = ({
onClose,
...restOfProps
}) => {
const { notifications } = useCore();
const hasWriteCapabilites = useCapabilities().write;
const [agentConfig, setAgentConfig] = useState<NewAgentConfig>({
const [agentPolicy, setAgentPolicy] = useState<NewAgentPolicy>({
name: '',
description: '',
namespace: 'default',
@ -48,26 +48,26 @@ export const CreateAgentConfigFlyout: React.FunctionComponent<Props> = ({
});
const [isLoading, setIsLoading] = useState<boolean>(false);
const [withSysMonitoring, setWithSysMonitoring] = useState<boolean>(true);
const validation = agentConfigFormValidation(agentConfig);
const validation = agentPolicyFormValidation(agentPolicy);
const updateAgentConfig = (updatedFields: Partial<NewAgentConfig>) => {
setAgentConfig({
...agentConfig,
const updateAgentPolicy = (updatedFields: Partial<NewAgentPolicy>) => {
setAgentPolicy({
...agentPolicy,
...updatedFields,
});
};
const createAgentConfig = async () => {
return await sendCreateAgentConfig(agentConfig, { withSysMonitoring });
const createAgentPolicy = async () => {
return await sendCreateAgentPolicy(agentPolicy, { withSysMonitoring });
};
const header = (
<EuiFlyoutHeader hasBorder aria-labelledby="CreateAgentConfigFlyoutTitle">
<EuiFlyoutHeader hasBorder aria-labelledby="CreateAgentPolicyFlyoutTitle">
<EuiTitle size="m">
<h2 id="CreateAgentConfigFlyoutTitle">
<h2 id="CreateAgentPolicyFlyoutTitle">
<FormattedMessage
id="xpack.ingestManager.createAgentConfig.flyoutTitle"
defaultMessage="Create agent configuration"
id="xpack.ingestManager.createAgentPolicy.flyoutTitle"
defaultMessage="Create agent policy"
/>
</h2>
</EuiTitle>
@ -75,8 +75,8 @@ export const CreateAgentConfigFlyout: React.FunctionComponent<Props> = ({
<EuiText size="s">
<p>
<FormattedMessage
id="xpack.ingestManager.createAgentConfig.flyoutTitleDescription"
defaultMessage="Agent configurations are used to manage settings across a group of agents. You can add integrations to your agent configuration to specify what data your agents collect. When you edit an agent configuration, you can use Fleet to deploy updates to a specified group of agents."
id="xpack.ingestManager.createAgentPolicy.flyoutTitleDescription"
defaultMessage="Agent policies are used to manage settings across a group of agents. You can add integrations to your agent policy to specify what data your agents collect. When you edit an agent policy, you can use Fleet to deploy updates to a specified group of agents."
/>
</p>
</EuiText>
@ -85,9 +85,9 @@ export const CreateAgentConfigFlyout: React.FunctionComponent<Props> = ({
const body = (
<EuiFlyoutBody>
<AgentConfigForm
agentConfig={agentConfig}
updateAgentConfig={updateAgentConfig}
<AgentPolicyForm
agentPolicy={agentPolicy}
updateAgentPolicy={updateAgentPolicy}
withSysMonitoring={withSysMonitoring}
updateSysMonitoring={(newValue) => setWithSysMonitoring(newValue)}
validation={validation}
@ -101,7 +101,7 @@ export const CreateAgentConfigFlyout: React.FunctionComponent<Props> = ({
<EuiFlexItem grow={false}>
<EuiButtonEmpty onClick={() => onClose()} flush="left">
<FormattedMessage
id="xpack.ingestManager.createAgentConfig.cancelButtonLabel"
id="xpack.ingestManager.createAgentPolicy.cancelButtonLabel"
defaultMessage="Cancel"
/>
</EuiButtonEmpty>
@ -114,15 +114,15 @@ export const CreateAgentConfigFlyout: React.FunctionComponent<Props> = ({
onClick={async () => {
setIsLoading(true);
try {
const { data, error } = await createAgentConfig();
const { data, error } = await createAgentPolicy();
setIsLoading(false);
if (data?.success) {
notifications.toasts.addSuccess(
i18n.translate(
'xpack.ingestManager.createAgentConfig.successNotificationTitle',
'xpack.ingestManager.createAgentPolicy.successNotificationTitle',
{
defaultMessage: "Agent config '{name}' created",
values: { name: agentConfig.name },
defaultMessage: "Agent policy '{name}' created",
values: { name: agentPolicy.name },
}
)
);
@ -132,9 +132,9 @@ export const CreateAgentConfigFlyout: React.FunctionComponent<Props> = ({
error
? error.message
: i18n.translate(
'xpack.ingestManager.createAgentConfig.errorNotificationTitle',
'xpack.ingestManager.createAgentPolicy.errorNotificationTitle',
{
defaultMessage: 'Unable to create agent config',
defaultMessage: 'Unable to create agent policy',
}
)
);
@ -142,16 +142,16 @@ export const CreateAgentConfigFlyout: React.FunctionComponent<Props> = ({
} catch (e) {
setIsLoading(false);
notifications.toasts.addDanger(
i18n.translate('xpack.ingestManager.createAgentConfig.errorNotificationTitle', {
defaultMessage: 'Unable to create agent config',
i18n.translate('xpack.ingestManager.createAgentPolicy.errorNotificationTitle', {
defaultMessage: 'Unable to create agent policy',
})
);
}
}}
>
<FormattedMessage
id="xpack.ingestManager.createAgentConfig.submitButtonLabel"
defaultMessage="Create agent configuration"
id="xpack.ingestManager.createAgentPolicy.submitButtonLabel"
defaultMessage="Create agent policy"
/>
</EuiButton>
</EuiFlexItem>

View file

@ -3,4 +3,4 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
export { CreateAgentConfigFlyout } from './create_config';
export { CreateAgentPolicyFlyout } from './create_agent_policy';

View file

@ -21,12 +21,12 @@ import { CriteriaWithPagination } from '@elastic/eui/src/components/basic_table/
import { i18n } from '@kbn/i18n';
import { FormattedMessage, FormattedDate } from '@kbn/i18n/react';
import { useHistory } from 'react-router-dom';
import { AgentConfig } from '../../../types';
import { AGENT_CONFIG_SAVED_OBJECT_TYPE } from '../../../constants';
import { AgentPolicy } from '../../../types';
import { AGENT_POLICY_SAVED_OBJECT_TYPE } from '../../../constants';
import { WithHeaderLayout } from '../../../layouts';
import {
useCapabilities,
useGetAgentConfigs,
useGetAgentPolicies,
usePagination,
useSorting,
useLink,
@ -35,10 +35,10 @@ import {
useBreadcrumbs,
} from '../../../hooks';
import { SearchBar } from '../../../components';
import { LinkedAgentCount, AgentConfigActionMenu } from '../components';
import { CreateAgentConfigFlyout } from './components';
import { LinkedAgentCount, AgentPolicyActionMenu } from '../components';
import { CreateAgentPolicyFlyout } from './components';
const AgentConfigListPageLayout: React.FunctionComponent = ({ children }) => (
const AgentPolicyListPageLayout: React.FunctionComponent = ({ children }) => (
<WithHeaderLayout
leftColumn={
<EuiFlexGroup direction="column" gutterSize="m">
@ -46,8 +46,8 @@ const AgentConfigListPageLayout: React.FunctionComponent = ({ children }) => (
<EuiText>
<h1>
<FormattedMessage
id="xpack.ingestManager.agentConfigList.pageTitle"
defaultMessage="Agent Configurations"
id="xpack.ingestManager.agentPolicyList.pageTitle"
defaultMessage="Agent policies"
/>
</h1>
</EuiText>
@ -56,8 +56,8 @@ const AgentConfigListPageLayout: React.FunctionComponent = ({ children }) => (
<EuiText color="subdued">
<p>
<FormattedMessage
id="xpack.ingestManager.agentConfigList.pageSubtitle"
defaultMessage="Use agent configurations to manage your agents and the data they collect."
id="xpack.ingestManager.agentPolicyList.pageSubtitle"
defaultMessage="Use agent policies to manage your agents and the data they collect."
/>
</p>
</EuiText>
@ -69,10 +69,9 @@ const AgentConfigListPageLayout: React.FunctionComponent = ({ children }) => (
</WithHeaderLayout>
);
export const AgentConfigListPage: React.FunctionComponent<{}> = () => {
useBreadcrumbs('configurations_list');
export const AgentPolicyListPage: React.FunctionComponent<{}> = () => {
useBreadcrumbs('policies_list');
const { getHref, getPath } = useLink();
// Config information
const hasWriteCapabilites = useCapabilities().write;
const {
fleet: { enabled: isFleetEnabled },
@ -86,30 +85,30 @@ export const AgentConfigListPage: React.FunctionComponent<{}> = () => {
: urlParams.kuery ?? ''
);
const { pagination, pageSizeOptions, setPagination } = usePagination();
const { sorting, setSorting } = useSorting<AgentConfig>({
const { sorting, setSorting } = useSorting<AgentPolicy>({
field: 'updated_at',
direction: 'desc',
});
const history = useHistory();
const isCreateAgentConfigFlyoutOpen = 'create' in urlParams;
const setIsCreateAgentConfigFlyoutOpen = useCallback(
const isCreateAgentPolicyFlyoutOpen = 'create' in urlParams;
const setIsCreateAgentPolicyFlyoutOpen = useCallback(
(isOpen: boolean) => {
if (isOpen !== isCreateAgentConfigFlyoutOpen) {
if (isOpen !== isCreateAgentPolicyFlyoutOpen) {
if (isOpen) {
history.push(
`${getPath('configurations_list')}?${toUrlParams({ ...urlParams, create: null })}`
`${getPath('policies_list')}?${toUrlParams({ ...urlParams, create: null })}`
);
} else {
const { create, ...params } = urlParams;
history.push(`${getPath('configurations_list')}?${toUrlParams(params)}`);
history.push(`${getPath('policies_list')}?${toUrlParams(params)}`);
}
}
},
[getPath, history, isCreateAgentConfigFlyoutOpen, toUrlParams, urlParams]
[getPath, history, isCreateAgentPolicyFlyoutOpen, toUrlParams, urlParams]
);
// Fetch agent configs
const { isLoading, data: agentConfigData, sendRequest } = useGetAgentConfigs({
// Fetch agent policies
const { isLoading, data: agentPolicyData, sendRequest } = useGetAgentPolicies({
page: pagination.currentPage,
perPage: pagination.pageSize,
sortField: sorting?.field,
@ -117,35 +116,35 @@ export const AgentConfigListPage: React.FunctionComponent<{}> = () => {
kuery: search,
});
// Some configs retrieved, set up table props
// Some policies retrieved, set up table props
const columns = useMemo(() => {
const cols: Array<
EuiTableFieldDataColumnType<AgentConfig> | EuiTableActionsColumnType<AgentConfig>
EuiTableFieldDataColumnType<AgentPolicy> | EuiTableActionsColumnType<AgentPolicy>
> = [
{
field: 'name',
sortable: true,
name: i18n.translate('xpack.ingestManager.agentConfigList.nameColumnTitle', {
name: i18n.translate('xpack.ingestManager.agentPolicyList.nameColumnTitle', {
defaultMessage: 'Name',
}),
width: '20%',
render: (name: string, agentConfig: AgentConfig) => (
render: (name: string, agentPolicy: AgentPolicy) => (
<EuiFlexGroup gutterSize="s" alignItems="baseline" style={{ minWidth: 0 }}>
<EuiFlexItem grow={false} className="eui-textTruncate">
<EuiLink
className="eui-textTruncate"
href={getHref('configuration_details', { configId: agentConfig.id })}
title={name || agentConfig.id}
href={getHref('policy_details', { policyId: agentPolicy.id })}
title={name || agentPolicy.id}
>
{name || agentConfig.id}
{name || agentPolicy.id}
</EuiLink>
</EuiFlexItem>
<EuiFlexItem grow={true}>
<EuiText color="subdued" size="xs" style={{ whiteSpace: 'nowrap' }}>
<FormattedMessage
id="xpack.ingestManager.agentConfigList.revisionNumber"
id="xpack.ingestManager.agentPolicyList.revisionNumber"
defaultMessage="rev. {revNumber}"
values={{ revNumber: agentConfig.revision }}
values={{ revNumber: agentPolicy.revision }}
/>
</EuiText>
</EuiFlexItem>
@ -154,7 +153,7 @@ export const AgentConfigListPage: React.FunctionComponent<{}> = () => {
},
{
field: 'description',
name: i18n.translate('xpack.ingestManager.agentConfigList.descriptionColumnTitle', {
name: i18n.translate('xpack.ingestManager.agentPolicyList.descriptionColumnTitle', {
defaultMessage: 'Description',
}),
width: '35%',
@ -167,40 +166,46 @@ export const AgentConfigListPage: React.FunctionComponent<{}> = () => {
{
field: 'updated_at',
sortable: true,
name: i18n.translate('xpack.ingestManager.agentConfigList.updatedOnColumnTitle', {
name: i18n.translate('xpack.ingestManager.agentPolicyList.updatedOnColumnTitle', {
defaultMessage: 'Last updated on',
}),
render: (date: AgentConfig['updated_at']) => (
render: (date: AgentPolicy['updated_at']) => (
<FormattedDate value={date} year="numeric" month="short" day="2-digit" />
),
},
{
field: 'agents',
name: i18n.translate('xpack.ingestManager.agentConfigList.agentsColumnTitle', {
name: i18n.translate('xpack.ingestManager.agentPolicyList.agentsColumnTitle', {
defaultMessage: 'Agents',
}),
dataType: 'number',
render: (agents: number, config: AgentConfig) => (
<LinkedAgentCount count={agents} agentConfigId={config.id} />
render: (agents: number, agentPolicy: AgentPolicy) => (
<LinkedAgentCount count={agents} agentPolicyId={agentPolicy.id} />
),
},
{
field: 'package_configs',
name: i18n.translate('xpack.ingestManager.agentConfigList.packageConfigsCountColumnTitle', {
defaultMessage: 'Integrations',
}),
field: 'package_policies',
name: i18n.translate(
'xpack.ingestManager.agentPolicyList.packagePoliciesCountColumnTitle',
{
defaultMessage: 'Integrations',
}
),
dataType: 'number',
render: (packageConfigs: AgentConfig['package_configs']) =>
packageConfigs ? packageConfigs.length : 0,
render: (packagePolicies: AgentPolicy['package_policies']) =>
packagePolicies ? packagePolicies.length : 0,
},
{
name: i18n.translate('xpack.ingestManager.agentConfigList.actionsColumnTitle', {
name: i18n.translate('xpack.ingestManager.agentPolicyList.actionsColumnTitle', {
defaultMessage: 'Actions',
}),
actions: [
{
render: (config: AgentConfig) => (
<AgentConfigActionMenu config={config} onCopySuccess={() => sendRequest()} />
render: (agentPolicy: AgentPolicy) => (
<AgentPolicyActionMenu
agentPolicy={agentPolicy}
onCopySuccess={() => sendRequest()}
/>
),
},
],
@ -215,21 +220,21 @@ export const AgentConfigListPage: React.FunctionComponent<{}> = () => {
return cols;
}, [getHref, isFleetEnabled, sendRequest]);
const createAgentConfigButton = useMemo(
const createAgentPolicyButton = useMemo(
() => (
<EuiButton
fill
iconType="plusInCircle"
isDisabled={!hasWriteCapabilites}
onClick={() => setIsCreateAgentConfigFlyoutOpen(true)}
onClick={() => setIsCreateAgentPolicyFlyoutOpen(true)}
>
<FormattedMessage
id="xpack.ingestManager.agentConfigList.addButton"
defaultMessage="Create agent configuration"
id="xpack.ingestManager.agentPolicyList.addButton"
defaultMessage="Create agent policy"
/>
</EuiButton>
),
[hasWriteCapabilites, setIsCreateAgentConfigFlyoutOpen]
[hasWriteCapabilites, setIsCreateAgentPolicyFlyoutOpen]
);
const emptyPrompt = useMemo(
@ -238,18 +243,18 @@ export const AgentConfigListPage: React.FunctionComponent<{}> = () => {
title={
<h2>
<FormattedMessage
id="xpack.ingestManager.agentConfigList.noAgentConfigsPrompt"
defaultMessage="No agent configurations"
id="xpack.ingestManager.agentPolicyList.noAgentPoliciesPrompt"
defaultMessage="No agent policies"
/>
</h2>
}
actions={createAgentConfigButton}
actions={createAgentPolicyButton}
/>
),
[createAgentConfigButton]
[createAgentPolicyButton]
);
const onTableChange = (criteria: CriteriaWithPagination<AgentConfig>) => {
const onTableChange = (criteria: CriteriaWithPagination<AgentPolicy>) => {
const newPagination = {
...pagination,
currentPage: criteria.page.index + 1,
@ -260,11 +265,11 @@ export const AgentConfigListPage: React.FunctionComponent<{}> = () => {
};
return (
<AgentConfigListPageLayout>
{isCreateAgentConfigFlyoutOpen ? (
<CreateAgentConfigFlyout
<AgentPolicyListPageLayout>
{isCreateAgentPolicyFlyoutOpen ? (
<CreateAgentPolicyFlyout
onClose={() => {
setIsCreateAgentConfigFlyoutOpen(false);
setIsCreateAgentPolicyFlyoutOpen(false);
sendRequest();
}}
/>
@ -280,41 +285,41 @@ export const AgentConfigListPage: React.FunctionComponent<{}> = () => {
});
setSearch(newSearch);
}}
fieldPrefix={AGENT_CONFIG_SAVED_OBJECT_TYPE}
fieldPrefix={AGENT_POLICY_SAVED_OBJECT_TYPE}
/>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButton color="primary" iconType="refresh" onClick={() => sendRequest()}>
<FormattedMessage
id="xpack.ingestManager.agentConfigList.reloadAgentConfigsButtonText"
id="xpack.ingestManager.agentPolicyList.reloadAgentPoliciesButtonText"
defaultMessage="Reload"
/>
</EuiButton>
</EuiFlexItem>
<EuiFlexItem grow={false}>{createAgentConfigButton}</EuiFlexItem>
<EuiFlexItem grow={false}>{createAgentPolicyButton}</EuiFlexItem>
</EuiFlexGroup>
<EuiSpacer size="m" />
<EuiBasicTable<AgentConfig>
<EuiBasicTable<AgentPolicy>
loading={isLoading}
hasActions={true}
noItemsMessage={
isLoading ? (
<FormattedMessage
id="xpack.ingestManager.agentConfigList.loadingAgentConfigsMessage"
defaultMessage="Loading agent configurations…"
id="xpack.ingestManager.agentPolicyList.loadingAgentPoliciesMessage"
defaultMessage="Loading agent policies…"
/>
) : !search.trim() && (agentConfigData?.total ?? 0) === 0 ? (
) : !search.trim() && (agentPolicyData?.total ?? 0) === 0 ? (
emptyPrompt
) : (
<FormattedMessage
id="xpack.ingestManager.agentConfigList.noFilteredAgentConfigsPrompt"
defaultMessage="No agent configurations found. {clearFiltersLink}"
id="xpack.ingestManager.agentPolicyList.noFilteredAgentPoliciesPrompt"
defaultMessage="No agent policies found. {clearFiltersLink}"
values={{
clearFiltersLink: (
<EuiLink onClick={() => setSearch('')}>
<FormattedMessage
id="xpack.ingestManager.agentConfigList.clearFiltersLinkText"
id="xpack.ingestManager.agentPolicyList.clearFiltersLinkText"
defaultMessage="Clear filters"
/>
</EuiLink>
@ -323,19 +328,19 @@ export const AgentConfigListPage: React.FunctionComponent<{}> = () => {
/>
)
}
items={agentConfigData ? agentConfigData.items : []}
items={agentPolicyData ? agentPolicyData.items : []}
itemId="id"
columns={columns}
isSelectable={false}
pagination={{
pageIndex: pagination.currentPage - 1,
pageSize: pagination.pageSize,
totalItemCount: agentConfigData ? agentConfigData.total : 0,
totalItemCount: agentPolicyData ? agentPolicyData.total : 0,
pageSizeOptions,
}}
sorting={{ sort: sorting }}
onChange={onTableChange}
/>
</AgentConfigListPageLayout>
</AgentPolicyListPageLayout>
);
};

Some files were not shown because too many files have changed in this diff Show more