From 38d88f6869f54c44ff6351882fed6571cb4d95fa Mon Sep 17 00:00:00 2001 From: Nicolas Chaulet Date: Mon, 25 Nov 2019 17:44:06 -0500 Subject: [PATCH] [Fleet] Move agent status server side and API to get aggregated status for a policy --- .../plugins/fleet/common/types/domain_data.ts | 6 +- .../fleet/public/components/agent_health.tsx | 53 +- .../agent.contract.test.slap_snap | 669 +++++++++++------- .../fleet/server/libs/agent.contract.test.ts | 70 ++ .../legacy/plugins/fleet/server/libs/agent.ts | 24 + .../server/libs/agent_status_helper.test.ts | 93 +++ .../fleet/server/libs/agent_status_helper.ts | 56 ++ .../fleet/server/routes/agents/enroll.ts | 3 +- .../plugins/fleet/server/routes/agents/get.ts | 3 +- .../fleet/server/routes/agents/list.ts | 12 +- .../fleet/server/routes/agents/status.ts | 28 + .../plugins/fleet/server/routes/init_api.ts | 3 + 12 files changed, 735 insertions(+), 285 deletions(-) create mode 100644 x-pack/legacy/plugins/fleet/server/libs/agent_status_helper.test.ts create mode 100644 x-pack/legacy/plugins/fleet/server/libs/agent_status_helper.ts create mode 100644 x-pack/legacy/plugins/fleet/server/routes/agents/status.ts diff --git a/x-pack/legacy/plugins/fleet/common/types/domain_data.ts b/x-pack/legacy/plugins/fleet/common/types/domain_data.ts index 2456e2f472bd9..f4c404c1ffa9d 100644 --- a/x-pack/legacy/plugins/fleet/common/types/domain_data.ts +++ b/x-pack/legacy/plugins/fleet/common/types/domain_data.ts @@ -32,7 +32,11 @@ export interface ConfigurationBlock id: string; } -export type Agent = t.TypeOf; +export type AgentStatus = 'offline' | 'error' | 'online' | 'inactive' | 'warning'; + +export type Agent = t.TypeOf & { + status: AgentStatus; +}; export type AgentAction = t.TypeOf; export type AgentEvent = t.TypeOf; diff --git a/x-pack/legacy/plugins/fleet/public/components/agent_health.tsx b/x-pack/legacy/plugins/fleet/public/components/agent_health.tsx index 8007934c63dfa..9c10272d52ddb 100644 --- a/x-pack/legacy/plugins/fleet/public/components/agent_health.tsx +++ b/x-pack/legacy/plugins/fleet/public/components/agent_health.tsx @@ -6,11 +6,6 @@ import React from 'react'; import { FormattedMessage, FormattedRelative } from '@kbn/i18n/react'; import { EuiHealth, EuiToolTip } from '@elastic/eui'; -import { - AGENT_TYPE_PERMANENT, - AGENT_TYPE_TEMPORARY, - AGENT_POLLING_THRESHOLD_MS, -} from '../../common/constants'; import { Agent } from '../../common/types/domain_data'; interface Props { @@ -40,41 +35,29 @@ const Status = { ), Error: ( - + ), }; +function getStatusComponent(agent: Agent): React.ReactElement { + switch (agent.status) { + case 'error': + return Status.Error; + case 'inactive': + return Status.Inactive; + case 'offline': + return Status.Offline; + case 'warning': + return Status.Warning; + default: + return Status.Online; + } +} + export const AgentHealth: React.SFC = ({ agent }) => { - // TODO: Use agent events as part of health calculation once we have them; - // until then, we just use last check in time - const { type, last_checkin: lastCheckIn } = agent; + const { last_checkin: lastCheckIn } = agent; const msLastCheckIn = new Date(lastCheckIn || 0).getTime(); - const msSinceLastCheckIn = new Date().getTime() - msLastCheckIn; - const intervalsSinceLastCheckIn = Math.floor(msSinceLastCheckIn / AGENT_POLLING_THRESHOLD_MS); - - let status: React.ReactElement = Status.Online; - - if (!agent.active) { - status = Status.Inactive; - } else { - switch (type) { - case AGENT_TYPE_PERMANENT: - if (intervalsSinceLastCheckIn >= 4) { - status = Status.Error; - break; - } - if (intervalsSinceLastCheckIn >= 2) { - status = Status.Warning; - break; - } - case AGENT_TYPE_TEMPORARY: - if (intervalsSinceLastCheckIn >= 3) { - status = Status.Offline; - break; - } - } - } return ( = ({ agent }) => { ) } > - {status} + {getStatusComponent(agent)} ); }; diff --git a/x-pack/legacy/plugins/fleet/server/libs/__memorize_snapshots__/agent.contract.test.slap_snap b/x-pack/legacy/plugins/fleet/server/libs/__memorize_snapshots__/agent.contract.test.slap_snap index ba58de97ecc5d..84bb8a72b1967 100644 --- a/x-pack/legacy/plugins/fleet/server/libs/__memorize_snapshots__/agent.contract.test.slap_snap +++ b/x-pack/legacy/plugins/fleet/server/libs/__memorize_snapshots__/agent.contract.test.slap_snap @@ -29,29 +29,29 @@ exports['Agent lib Enroll Should enroll a new PERMANENT agent - find:"agents" (2 exports['Agent lib Enroll Should enroll a new PERMANENT agent - create:agents (3)'] = { "results": { "type": "agents", - "id": "86bd7020-0625-11ea-9674-75a3ee7c8618", + "id": "99314300-0fd3-11ea-af46-9724fc51c031", "attributes": { "shared_id": "agent-1", "active": true, "policy_id": "policyId", "type": "PERMANENT", - "enrolled_at": "2019-11-13T14:54:43.233Z", + "enrolled_at": "2019-11-25T22:33:27.086Z", "user_provided_metadata": "{}", "local_metadata": "{}", "actions": [] }, "references": [], - "updated_at": "2019-11-13T14:54:43.234Z", - "version": "WzIyNywxXQ==" + "updated_at": "2019-11-25T22:33:27.087Z", + "version": "WzIsMV0=" } } exports['Agent lib Enroll Should enroll a new PERMANENT agent - update:agents (4)'] = { "results": { - "id": "86bd7020-0625-11ea-9674-75a3ee7c8618", + "id": "99314300-0fd3-11ea-af46-9724fc51c031", "type": "agents", - "updated_at": "2019-11-13T14:54:44.297Z", - "version": "WzIyOCwxXQ==", + "updated_at": "2019-11-25T22:33:27.203Z", + "version": "WzMsMV0=", "attributes": { "access_api_key_id": "mock-access-api-key-id-1" } @@ -66,21 +66,21 @@ exports['Agent lib Enroll Should allow to enroll a new PERMANENT agent again if "saved_objects": [ { "type": "agents", - "id": "86bd7020-0625-11ea-9674-75a3ee7c8618", + "id": "99314300-0fd3-11ea-af46-9724fc51c031", "attributes": { "shared_id": "agent-1", "active": true, "policy_id": "policyId", "type": "PERMANENT", - "enrolled_at": "2019-11-13T14:54:43.233Z", + "enrolled_at": "2019-11-25T22:33:27.086Z", "user_provided_metadata": "{}", "local_metadata": "{}", "actions": [], "access_api_key_id": "mock-access-api-key-id-1" }, "references": [], - "updated_at": "2019-11-13T14:54:44.297Z", - "version": "WzIyOCwxXQ==" + "updated_at": "2019-11-25T22:33:27.203Z", + "version": "WzMsMV0=" } ] } @@ -102,28 +102,28 @@ exports['Agent lib Enroll Should allow to enroll a new PERMANENT agent again if exports['Agent lib Enroll Should allow to enroll a new PERMANENT agent again if this agent is active - create:agents (4)'] = { "results": { "type": "agents", - "id": "889eb340-0625-11ea-9674-75a3ee7c8618", + "id": "9a79efa0-0fd3-11ea-af46-9724fc51c031", "attributes": { "shared_id": "agent-1", "active": true, "type": "PERMANENT", - "enrolled_at": "2019-11-13T14:54:46.387Z", + "enrolled_at": "2019-11-25T22:33:29.240Z", "user_provided_metadata": "{}", "local_metadata": "{}", "actions": [] }, "references": [], - "updated_at": "2019-11-13T14:54:46.388Z", - "version": "WzIzMCwxXQ==" + "updated_at": "2019-11-25T22:33:29.242Z", + "version": "WzUsMV0=" } } exports['Agent lib Enroll Should allow to enroll a new PERMANENT agent again if this agent is active - update:agents (5)'] = { "results": { - "id": "889eb340-0625-11ea-9674-75a3ee7c8618", + "id": "9a79efa0-0fd3-11ea-af46-9724fc51c031", "type": "agents", - "updated_at": "2019-11-13T14:54:47.399Z", - "version": "WzIzMSwxXQ==", + "updated_at": "2019-11-25T22:33:30.256Z", + "version": "WzYsMV0=", "attributes": { "access_api_key_id": "mock-access-api-key-id-1" } @@ -132,10 +132,10 @@ exports['Agent lib Enroll Should allow to enroll a new PERMANENT agent again if exports['Agent lib Enroll Should allow to enroll a new PERMANENT agent again if this agent is active - update:agents (6)'] = { "results": { - "id": "889eb340-0625-11ea-9674-75a3ee7c8618", + "id": "9a79efa0-0fd3-11ea-af46-9724fc51c031", "type": "agents", - "updated_at": "2019-11-13T14:54:48.433Z", - "version": "WzIzMiwxXQ==", + "updated_at": "2019-11-25T22:33:31.275Z", + "version": "WzcsMV0=", "attributes": { "active": false } @@ -150,20 +150,20 @@ exports['Agent lib Enroll Should allow to enroll a new PERMANENT agent again if "saved_objects": [ { "type": "agents", - "id": "889eb340-0625-11ea-9674-75a3ee7c8618", + "id": "9a79efa0-0fd3-11ea-af46-9724fc51c031", "attributes": { "shared_id": "agent-1", "active": false, "type": "PERMANENT", - "enrolled_at": "2019-11-13T14:54:46.387Z", + "enrolled_at": "2019-11-25T22:33:29.240Z", "user_provided_metadata": "{}", "local_metadata": "{}", "actions": [], "access_api_key_id": "mock-access-api-key-id-1" }, "references": [], - "updated_at": "2019-11-13T14:54:48.433Z", - "version": "WzIzMiwxXQ==" + "updated_at": "2019-11-25T22:33:31.275Z", + "version": "WzcsMV0=" } ] } @@ -171,25 +171,25 @@ exports['Agent lib Enroll Should allow to enroll a new PERMANENT agent again if exports['Agent lib Enroll Should allow to enroll a new PERMANENT agent again if this agent is active - update:agents (8)'] = { "results": { - "id": "889eb340-0625-11ea-9674-75a3ee7c8618", + "id": "9a79efa0-0fd3-11ea-af46-9724fc51c031", "type": "agents", - "updated_at": "2019-11-13T14:54:49.451Z", - "version": "WzIzMywxXQ==", + "updated_at": "2019-11-25T22:33:32.304Z", + "version": "WzgsMV0=", "attributes": { "shared_id": "agent-1", "active": true, "type": "PERMANENT", - "enrolled_at": "2019-11-13T14:54:49.450Z" + "enrolled_at": "2019-11-25T22:33:32.303Z" } } } exports['Agent lib Enroll Should allow to enroll a new PERMANENT agent again if this agent is active - update:agents (9)'] = { "results": { - "id": "889eb340-0625-11ea-9674-75a3ee7c8618", + "id": "9a79efa0-0fd3-11ea-af46-9724fc51c031", "type": "agents", - "updated_at": "2019-11-13T14:54:50.456Z", - "version": "WzIzNCwxXQ==", + "updated_at": "2019-11-25T22:33:33.319Z", + "version": "WzksMV0=", "attributes": { "access_api_key_id": "mock-access-api-key-id-2" } @@ -204,20 +204,20 @@ exports['Agent lib Enroll Should not enroll a new PERMANENT agent if this agent "saved_objects": [ { "type": "agents", - "id": "889eb340-0625-11ea-9674-75a3ee7c8618", + "id": "9a79efa0-0fd3-11ea-af46-9724fc51c031", "attributes": { "shared_id": "agent-1", "active": true, "type": "PERMANENT", - "enrolled_at": "2019-11-13T14:54:49.450Z", + "enrolled_at": "2019-11-25T22:33:32.303Z", "user_provided_metadata": "{}", "local_metadata": "{}", "actions": [], "access_api_key_id": "mock-access-api-key-id-2" }, "references": [], - "updated_at": "2019-11-13T14:54:50.456Z", - "version": "WzIzNCwxXQ==" + "updated_at": "2019-11-25T22:33:33.319Z", + "version": "WzksMV0=" } ] } @@ -239,28 +239,28 @@ exports['Agent lib Enroll Should not enroll a new PERMANENT agent if this agent exports['Agent lib Enroll Should not enroll a new PERMANENT agent if this agent is already active - create:agents (4)'] = { "results": { "type": "agents", - "id": "8c415570-0625-11ea-9674-75a3ee7c8618", + "id": "9e20fea0-0fd3-11ea-af46-9724fc51c031", "attributes": { "shared_id": "agent-1", "active": true, "type": "PERMANENT", - "enrolled_at": "2019-11-13T14:54:52.486Z", + "enrolled_at": "2019-11-25T22:33:35.369Z", "user_provided_metadata": "{}", "local_metadata": "{}", "actions": [] }, "references": [], - "updated_at": "2019-11-13T14:54:52.487Z", - "version": "WzIzNiwxXQ==" + "updated_at": "2019-11-25T22:33:35.370Z", + "version": "WzExLDFd" } } exports['Agent lib Enroll Should not enroll a new PERMANENT agent if this agent is already active - update:agents (5)'] = { "results": { - "id": "8c415570-0625-11ea-9674-75a3ee7c8618", + "id": "9e20fea0-0fd3-11ea-af46-9724fc51c031", "type": "agents", - "updated_at": "2019-11-13T14:54:53.498Z", - "version": "WzIzNywxXQ==", + "updated_at": "2019-11-25T22:33:36.377Z", + "version": "WzEyLDFd", "attributes": { "access_api_key_id": "mock-access-api-key-id-1" } @@ -275,20 +275,20 @@ exports['Agent lib Enroll Should not enroll a new PERMANENT agent if this agent "saved_objects": [ { "type": "agents", - "id": "8c415570-0625-11ea-9674-75a3ee7c8618", + "id": "9e20fea0-0fd3-11ea-af46-9724fc51c031", "attributes": { "shared_id": "agent-1", "active": true, "type": "PERMANENT", - "enrolled_at": "2019-11-13T14:54:52.486Z", + "enrolled_at": "2019-11-25T22:33:35.369Z", "user_provided_metadata": "{}", "local_metadata": "{}", "actions": [], "access_api_key_id": "mock-access-api-key-id-1" }, "references": [], - "updated_at": "2019-11-13T14:54:53.498Z", - "version": "WzIzNywxXQ==" + "updated_at": "2019-11-25T22:33:36.377Z", + "version": "WzEyLDFd" } ] } @@ -302,20 +302,20 @@ exports['Agent lib Enroll Should enroll a new EPHEMERAL agent - find:"agents" (1 "saved_objects": [ { "type": "agents", - "id": "8c415570-0625-11ea-9674-75a3ee7c8618", + "id": "9e20fea0-0fd3-11ea-af46-9724fc51c031", "attributes": { "shared_id": "agent-1", "active": true, "type": "PERMANENT", - "enrolled_at": "2019-11-13T14:54:52.486Z", + "enrolled_at": "2019-11-25T22:33:35.369Z", "user_provided_metadata": "{}", "local_metadata": "{}", "actions": [], "access_api_key_id": "mock-access-api-key-id-1" }, "references": [], - "updated_at": "2019-11-13T14:54:53.498Z", - "version": "WzIzNywxXQ==" + "updated_at": "2019-11-25T22:33:36.377Z", + "version": "WzEyLDFd" } ] } @@ -328,28 +328,28 @@ exports['Agent lib Enroll Should enroll a new EPHEMERAL agent - delete (2)'] = { exports['Agent lib Enroll Should enroll a new EPHEMERAL agent - create:agents (3)'] = { "results": { "type": "agents", - "id": "8e132f40-0625-11ea-9674-75a3ee7c8618", + "id": "9ff39bc0-0fd3-11ea-af46-9724fc51c031", "attributes": { "active": true, "policy_id": "policyId", "type": "EPHEMERAL", - "enrolled_at": "2019-11-13T14:54:55.538Z", + "enrolled_at": "2019-11-25T22:33:38.427Z", "user_provided_metadata": "{}", "local_metadata": "{}", "actions": [] }, "references": [], - "updated_at": "2019-11-13T14:54:55.540Z", - "version": "WzIzOSwxXQ==" + "updated_at": "2019-11-25T22:33:38.428Z", + "version": "WzE0LDFd" } } exports['Agent lib Enroll Should enroll a new EPHEMERAL agent - update:agents (4)'] = { "results": { - "id": "8e132f40-0625-11ea-9674-75a3ee7c8618", + "id": "9ff39bc0-0fd3-11ea-af46-9724fc51c031", "type": "agents", - "updated_at": "2019-11-13T14:54:56.551Z", - "version": "WzI0MCwxXQ==", + "updated_at": "2019-11-25T22:33:39.446Z", + "version": "WzE1LDFd", "attributes": { "access_api_key_id": "mock-access-api-key-id-1" } @@ -364,20 +364,20 @@ exports['Agent lib Delete should delete ephemeral instances - find:"agents" (1)' "saved_objects": [ { "type": "agents", - "id": "8e132f40-0625-11ea-9674-75a3ee7c8618", + "id": "9ff39bc0-0fd3-11ea-af46-9724fc51c031", "attributes": { "active": true, "policy_id": "policyId", "type": "EPHEMERAL", - "enrolled_at": "2019-11-13T14:54:55.538Z", + "enrolled_at": "2019-11-25T22:33:38.427Z", "user_provided_metadata": "{}", "local_metadata": "{}", "actions": [], "access_api_key_id": "mock-access-api-key-id-1" }, "references": [], - "updated_at": "2019-11-13T14:54:56.551Z", - "version": "WzI0MCwxXQ==" + "updated_at": "2019-11-25T22:33:39.446Z", + "version": "WzE1LDFd" } ] } @@ -390,7 +390,7 @@ exports['Agent lib Delete should delete ephemeral instances - delete (2)'] = { exports['Agent lib Delete should delete ephemeral instances - create:agents (3)'] = { "results": { "type": "agents", - "id": "8fe2bf20-0625-11ea-9674-75a3ee7c8618", + "id": "a1c5c3b0-0fd3-11ea-af46-9724fc51c031", "attributes": { "type": "EPHEMERAL", "active": true, @@ -398,8 +398,8 @@ exports['Agent lib Delete should delete ephemeral instances - create:agents (3)' "user_provided_metadata": "{}" }, "references": [], - "updated_at": "2019-11-13T14:54:58.578Z", - "version": "WzI0MiwxXQ==" + "updated_at": "2019-11-25T22:33:41.483Z", + "version": "WzE3LDFd" } } @@ -432,7 +432,7 @@ exports['Agent lib Delete should desactivate other agent - find:"agents" (1)'] = exports['Agent lib Delete should desactivate other agent - create:agents (2)'] = { "results": { "type": "agents", - "id": "91180ad0-0625-11ea-9674-75a3ee7c8618", + "id": "a2fd3240-0fd3-11ea-af46-9724fc51c031", "attributes": { "type": "PERMANENT", "active": true, @@ -440,17 +440,17 @@ exports['Agent lib Delete should desactivate other agent - create:agents (2)'] = "user_provided_metadata": "{}" }, "references": [], - "updated_at": "2019-11-13T14:55:00.605Z", - "version": "WzI0NCwxXQ==" + "updated_at": "2019-11-25T22:33:43.524Z", + "version": "WzE5LDFd" } } exports['Agent lib Delete should desactivate other agent - update:agents (3)'] = { "results": { - "id": "91180ad0-0625-11ea-9674-75a3ee7c8618", + "id": "a2fd3240-0fd3-11ea-af46-9724fc51c031", "type": "agents", - "updated_at": "2019-11-13T14:55:01.614Z", - "version": "WzI0NSwxXQ==", + "updated_at": "2019-11-25T22:33:44.534Z", + "version": "WzIwLDFd", "attributes": { "active": false } @@ -459,10 +459,10 @@ exports['Agent lib Delete should desactivate other agent - update:agents (3)'] = exports['Agent lib Delete should desactivate other agent - get:agents (4)'] = { "results": { - "id": "91180ad0-0625-11ea-9674-75a3ee7c8618", + "id": "a2fd3240-0fd3-11ea-af46-9724fc51c031", "type": "agents", - "updated_at": "2019-11-13T14:55:01.614Z", - "version": "WzI0NSwxXQ==", + "updated_at": "2019-11-25T22:33:44.534Z", + "version": "WzIwLDFd", "attributes": { "type": "PERMANENT", "active": false, @@ -481,7 +481,7 @@ exports['Agent lib list should return all agents - find:"agents" (1)'] = { "saved_objects": [ { "type": "agents", - "id": "91180ad0-0625-11ea-9674-75a3ee7c8618", + "id": "a2fd3240-0fd3-11ea-af46-9724fc51c031", "attributes": { "type": "PERMANENT", "active": false, @@ -489,8 +489,8 @@ exports['Agent lib list should return all agents - find:"agents" (1)'] = { "user_provided_metadata": "{}" }, "references": [], - "updated_at": "2019-11-13T14:55:01.614Z", - "version": "WzI0NSwxXQ==" + "updated_at": "2019-11-25T22:33:44.534Z", + "version": "WzIwLDFd" } ] } @@ -503,7 +503,7 @@ exports['Agent lib list should return all agents - delete (2)'] = { exports['Agent lib list should return all agents - create:agents (3)'] = { "results": { "type": "agents", - "id": "92e74c90-0625-11ea-9674-75a3ee7c8618", + "id": "a4cfcf60-0fd3-11ea-af46-9724fc51c031", "attributes": { "type": "PERMANENT", "active": true, @@ -511,15 +511,15 @@ exports['Agent lib list should return all agents - create:agents (3)'] = { "user_provided_metadata": "{}" }, "references": [], - "updated_at": "2019-11-13T14:55:03.641Z", - "version": "WzI0NywxXQ==" + "updated_at": "2019-11-25T22:33:46.582Z", + "version": "WzIyLDFd" } } exports['Agent lib list should return all agents - create:agents (4)'] = { "results": { "type": "agents", - "id": "93844fe0-0625-11ea-9674-75a3ee7c8618", + "id": "a569c570-0fd3-11ea-af46-9724fc51c031", "attributes": { "type": "PERMANENT", "active": true, @@ -527,8 +527,8 @@ exports['Agent lib list should return all agents - create:agents (4)'] = { "user_provided_metadata": "{}" }, "references": [], - "updated_at": "2019-11-13T14:55:04.670Z", - "version": "WzI0OCwxXQ==" + "updated_at": "2019-11-25T22:33:47.591Z", + "version": "WzIzLDFd" } } @@ -540,7 +540,7 @@ exports['Agent lib list should return all agents - find:"agents" (5)'] = { "saved_objects": [ { "type": "agents", - "id": "92e74c90-0625-11ea-9674-75a3ee7c8618", + "id": "a4cfcf60-0fd3-11ea-af46-9724fc51c031", "attributes": { "type": "PERMANENT", "active": true, @@ -548,12 +548,12 @@ exports['Agent lib list should return all agents - find:"agents" (5)'] = { "user_provided_metadata": "{}" }, "references": [], - "updated_at": "2019-11-13T14:55:03.641Z", - "version": "WzI0NywxXQ==" + "updated_at": "2019-11-25T22:33:46.582Z", + "version": "WzIyLDFd" }, { "type": "agents", - "id": "93844fe0-0625-11ea-9674-75a3ee7c8618", + "id": "a569c570-0fd3-11ea-af46-9724fc51c031", "attributes": { "type": "PERMANENT", "active": true, @@ -561,8 +561,8 @@ exports['Agent lib list should return all agents - find:"agents" (5)'] = { "user_provided_metadata": "{}" }, "references": [], - "updated_at": "2019-11-13T14:55:04.670Z", - "version": "WzI0OCwxXQ==" + "updated_at": "2019-11-25T22:33:47.591Z", + "version": "WzIzLDFd" } ] } @@ -576,7 +576,7 @@ exports['Agent lib checkin should throw if the agens do not exists - find:"agent "saved_objects": [ { "type": "agents", - "id": "92e74c90-0625-11ea-9674-75a3ee7c8618", + "id": "a4cfcf60-0fd3-11ea-af46-9724fc51c031", "attributes": { "type": "PERMANENT", "active": true, @@ -584,12 +584,12 @@ exports['Agent lib checkin should throw if the agens do not exists - find:"agent "user_provided_metadata": "{}" }, "references": [], - "updated_at": "2019-11-13T14:55:03.641Z", - "version": "WzI0NywxXQ==" + "updated_at": "2019-11-25T22:33:46.582Z", + "version": "WzIyLDFd" }, { "type": "agents", - "id": "93844fe0-0625-11ea-9674-75a3ee7c8618", + "id": "a569c570-0fd3-11ea-af46-9724fc51c031", "attributes": { "type": "PERMANENT", "active": true, @@ -597,8 +597,8 @@ exports['Agent lib checkin should throw if the agens do not exists - find:"agent "user_provided_metadata": "{}" }, "references": [], - "updated_at": "2019-11-13T14:55:04.670Z", - "version": "WzI0OCwxXQ==" + "updated_at": "2019-11-25T22:33:47.591Z", + "version": "WzIzLDFd" } ] } @@ -633,7 +633,7 @@ exports['Agent lib checkin should throw is the agent is not active - find:"agent exports['Agent lib checkin should throw is the agent is not active - create:agents (2)'] = { "results": { "type": "agents", - "id": "95578940-0625-11ea-9674-75a3ee7c8618", + "id": "a73e1040-0fd3-11ea-af46-9724fc51c031", "attributes": { "actions": [], "active": false, @@ -643,8 +643,8 @@ exports['Agent lib checkin should throw is the agent is not active - create:agen "user_provided_metadata": "{}" }, "references": [], - "updated_at": "2019-11-13T14:55:07.732Z", - "version": "WzI1MSwxXQ==" + "updated_at": "2019-11-25T22:33:50.660Z", + "version": "WzI2LDFd" } } @@ -656,7 +656,7 @@ exports['Agent lib checkin should throw is the agent is not active - find:"agent "saved_objects": [ { "type": "agents", - "id": "95578940-0625-11ea-9674-75a3ee7c8618", + "id": "a73e1040-0fd3-11ea-af46-9724fc51c031", "attributes": { "actions": [], "active": false, @@ -666,8 +666,8 @@ exports['Agent lib checkin should throw is the agent is not active - find:"agent "user_provided_metadata": "{}" }, "references": [], - "updated_at": "2019-11-13T14:55:07.732Z", - "version": "WzI1MSwxXQ==" + "updated_at": "2019-11-25T22:33:50.660Z", + "version": "WzI2LDFd" } ] } @@ -681,7 +681,7 @@ exports['Agent lib checkin should persist new events - find:"agents" (1)'] = { "saved_objects": [ { "type": "agents", - "id": "95578940-0625-11ea-9674-75a3ee7c8618", + "id": "a73e1040-0fd3-11ea-af46-9724fc51c031", "attributes": { "actions": [], "active": false, @@ -691,8 +691,8 @@ exports['Agent lib checkin should persist new events - find:"agents" (1)'] = { "user_provided_metadata": "{}" }, "references": [], - "updated_at": "2019-11-13T14:55:07.732Z", - "version": "WzI1MSwxXQ==" + "updated_at": "2019-11-25T22:33:50.660Z", + "version": "WzI2LDFd" } ] } @@ -705,7 +705,7 @@ exports['Agent lib checkin should persist new events - delete (2)'] = { exports['Agent lib checkin should persist new events - create:agents (3)'] = { "results": { "type": "agents", - "id": "96890460-0625-11ea-9674-75a3ee7c8618", + "id": "a870c3e0-0fd3-11ea-af46-9724fc51c031", "attributes": { "actions": [], "active": true, @@ -715,8 +715,8 @@ exports['Agent lib checkin should persist new events - create:agents (3)'] = { "user_provided_metadata": "{}" }, "references": [], - "updated_at": "2019-11-13T14:55:09.734Z", - "version": "WzI1MywxXQ==" + "updated_at": "2019-11-25T22:33:52.670Z", + "version": "WzI4LDFd" } } @@ -728,7 +728,7 @@ exports['Agent lib checkin should persist new events - find:"agents" (4)'] = { "saved_objects": [ { "type": "agents", - "id": "96890460-0625-11ea-9674-75a3ee7c8618", + "id": "a870c3e0-0fd3-11ea-af46-9724fc51c031", "attributes": { "actions": [], "active": true, @@ -738,8 +738,8 @@ exports['Agent lib checkin should persist new events - find:"agents" (4)'] = { "user_provided_metadata": "{}" }, "references": [], - "updated_at": "2019-11-13T14:55:09.734Z", - "version": "WzI1MywxXQ==" + "updated_at": "2019-11-25T22:33:52.670Z", + "version": "WzI4LDFd" } ] } @@ -747,12 +747,12 @@ exports['Agent lib checkin should persist new events - find:"agents" (4)'] = { exports['Agent lib checkin should persist new events - update:agents (5)'] = { "results": { - "id": "96890460-0625-11ea-9674-75a3ee7c8618", + "id": "a870c3e0-0fd3-11ea-af46-9724fc51c031", "type": "agents", - "updated_at": "2019-11-13T14:55:10.747Z", - "version": "WzI1NCwxXQ==", + "updated_at": "2019-11-25T22:33:53.694Z", + "version": "WzI5LDFd", "attributes": { - "last_checkin": "2019-11-13T14:55:10.745Z", + "last_checkin": "2019-11-25T22:33:53.692Z", "actions": [] } } @@ -762,12 +762,12 @@ exports['Agent lib checkin should persist new events - bulkCreate (6)'] = { "results": { "saved_objects": [ { - "id": "agent_events:97bd3ea0-0625-11ea-9674-75a3ee7c8618", + "id": "agent_events:a9a6f9f0-0fd3-11ea-af46-9724fc51c031", "type": "agent_events", - "updated_at": "2019-11-13T14:55:11.754Z", - "version": "WzI1NSwxXQ==", + "updated_at": "2019-11-25T22:33:54.703Z", + "version": "WzMwLDFd", "attributes": { - "agent_id": "96890460-0625-11ea-9674-75a3ee7c8618", + "agent_id": "a870c3e0-0fd3-11ea-af46-9724fc51c031", "timestamp": "2019-09-05T15:41:26+0000", "type": "STATE", "subtype": "STARTING", @@ -787,17 +787,17 @@ exports['Agent lib checkin should persist new events - find:"agent_events" (7)'] "saved_objects": [ { "type": "agent_events", - "id": "97bd3ea0-0625-11ea-9674-75a3ee7c8618", + "id": "a9a6f9f0-0fd3-11ea-af46-9724fc51c031", "attributes": { - "agent_id": "96890460-0625-11ea-9674-75a3ee7c8618", + "agent_id": "a870c3e0-0fd3-11ea-af46-9724fc51c031", "timestamp": "2019-09-05T15:41:26+0000", "type": "STATE", "subtype": "STARTING", "message": "State changed from PAUSE to STARTING" }, "references": [], - "updated_at": "2019-11-13T14:55:11.754Z", - "version": "WzI1NSwxXQ==" + "updated_at": "2019-11-25T22:33:54.703Z", + "version": "WzMwLDFd" } ] } @@ -811,7 +811,7 @@ exports['Agent lib checkin should not update agent metadata if none are provided "saved_objects": [ { "type": "agents", - "id": "96890460-0625-11ea-9674-75a3ee7c8618", + "id": "a870c3e0-0fd3-11ea-af46-9724fc51c031", "attributes": { "actions": [], "active": true, @@ -819,11 +819,11 @@ exports['Agent lib checkin should not update agent metadata if none are provided "access_api_key_id": "key1", "local_metadata": "{}", "user_provided_metadata": "{}", - "last_checkin": "2019-11-13T14:55:10.745Z" + "last_checkin": "2019-11-25T22:33:53.692Z" }, "references": [], - "updated_at": "2019-11-13T14:55:10.747Z", - "version": "WzI1NCwxXQ==" + "updated_at": "2019-11-25T22:33:53.694Z", + "version": "WzI5LDFd" } ] } @@ -836,7 +836,7 @@ exports['Agent lib checkin should not update agent metadata if none are provided exports['Agent lib checkin should not update agent metadata if none are provided - create:agents (3)'] = { "results": { "type": "agents", - "id": "98f71e30-0625-11ea-9674-75a3ee7c8618", + "id": "aae06450-0fd3-11ea-af46-9724fc51c031", "attributes": { "local_metadata": "{\"key\":\"local1\"}", "user_provided_metadata": "{\"key\":\"user1\"}", @@ -846,8 +846,8 @@ exports['Agent lib checkin should not update agent metadata if none are provided "access_api_key_id": "key1" }, "references": [], - "updated_at": "2019-11-13T14:55:13.811Z", - "version": "WzI1NywxXQ==" + "updated_at": "2019-11-25T22:33:56.757Z", + "version": "WzMyLDFd" } } @@ -859,7 +859,7 @@ exports['Agent lib checkin should not update agent metadata if none are provided "saved_objects": [ { "type": "agents", - "id": "98f71e30-0625-11ea-9674-75a3ee7c8618", + "id": "aae06450-0fd3-11ea-af46-9724fc51c031", "attributes": { "local_metadata": "{\"key\":\"local1\"}", "user_provided_metadata": "{\"key\":\"user1\"}", @@ -869,8 +869,8 @@ exports['Agent lib checkin should not update agent metadata if none are provided "access_api_key_id": "key1" }, "references": [], - "updated_at": "2019-11-13T14:55:13.811Z", - "version": "WzI1NywxXQ==" + "updated_at": "2019-11-25T22:33:56.757Z", + "version": "WzMyLDFd" } ] } @@ -878,12 +878,12 @@ exports['Agent lib checkin should not update agent metadata if none are provided exports['Agent lib checkin should not update agent metadata if none are provided - update:agents (5)'] = { "results": { - "id": "98f71e30-0625-11ea-9674-75a3ee7c8618", + "id": "aae06450-0fd3-11ea-af46-9724fc51c031", "type": "agents", - "updated_at": "2019-11-13T14:55:14.823Z", - "version": "WzI1OCwxXQ==", + "updated_at": "2019-11-25T22:33:57.775Z", + "version": "WzMzLDFd", "attributes": { - "last_checkin": "2019-11-13T14:55:14.821Z", + "last_checkin": "2019-11-25T22:33:57.774Z", "actions": [] } } @@ -891,10 +891,10 @@ exports['Agent lib checkin should not update agent metadata if none are provided exports['Agent lib checkin should not update agent metadata if none are provided - get:agents (6)'] = { "results": { - "id": "98f71e30-0625-11ea-9674-75a3ee7c8618", + "id": "aae06450-0fd3-11ea-af46-9724fc51c031", "type": "agents", - "updated_at": "2019-11-13T14:55:14.823Z", - "version": "WzI1OCwxXQ==", + "updated_at": "2019-11-25T22:33:57.775Z", + "version": "WzMzLDFd", "attributes": { "local_metadata": "{\"key\":\"local1\"}", "user_provided_metadata": "{\"key\":\"user1\"}", @@ -902,7 +902,7 @@ exports['Agent lib checkin should not update agent metadata if none are provided "active": true, "policy_id": "policy:1", "access_api_key_id": "key1", - "last_checkin": "2019-11-13T14:55:14.821Z" + "last_checkin": "2019-11-25T22:33:57.774Z" }, "references": [] } @@ -916,7 +916,7 @@ exports['Agent lib checkin should return the full policy for this agent - find:" "saved_objects": [ { "type": "agents", - "id": "98f71e30-0625-11ea-9674-75a3ee7c8618", + "id": "aae06450-0fd3-11ea-af46-9724fc51c031", "attributes": { "local_metadata": "{\"key\":\"local1\"}", "user_provided_metadata": "{\"key\":\"user1\"}", @@ -924,11 +924,11 @@ exports['Agent lib checkin should return the full policy for this agent - find:" "active": true, "policy_id": "policy:1", "access_api_key_id": "key1", - "last_checkin": "2019-11-13T14:55:14.821Z" + "last_checkin": "2019-11-25T22:33:57.774Z" }, "references": [], - "updated_at": "2019-11-13T14:55:14.823Z", - "version": "WzI1OCwxXQ==" + "updated_at": "2019-11-25T22:33:57.775Z", + "version": "WzMzLDFd" } ] } @@ -941,7 +941,7 @@ exports['Agent lib checkin should return the full policy for this agent - delete exports['Agent lib checkin should return the full policy for this agent - create:agents (3)'] = { "results": { "type": "agents", - "id": "9ac6d520-0625-11ea-9674-75a3ee7c8618", + "id": "acb12cb0-0fd3-11ea-af46-9724fc51c031", "attributes": { "local_metadata": "{\"key\":\"local1\"}", "user_provided_metadata": "{\"key\":\"user1\"}", @@ -951,8 +951,8 @@ exports['Agent lib checkin should return the full policy for this agent - create "access_api_key_id": "key1" }, "references": [], - "updated_at": "2019-11-13T14:55:16.850Z", - "version": "WzI2MCwxXQ==" + "updated_at": "2019-11-25T22:33:59.803Z", + "version": "WzM1LDFd" } } @@ -964,7 +964,7 @@ exports['Agent lib checkin should return the full policy for this agent - find:" "saved_objects": [ { "type": "agents", - "id": "9ac6d520-0625-11ea-9674-75a3ee7c8618", + "id": "acb12cb0-0fd3-11ea-af46-9724fc51c031", "attributes": { "local_metadata": "{\"key\":\"local1\"}", "user_provided_metadata": "{\"key\":\"user1\"}", @@ -974,8 +974,8 @@ exports['Agent lib checkin should return the full policy for this agent - find:" "access_api_key_id": "key1" }, "references": [], - "updated_at": "2019-11-13T14:55:16.850Z", - "version": "WzI2MCwxXQ==" + "updated_at": "2019-11-25T22:33:59.803Z", + "version": "WzM1LDFd" } ] } @@ -983,12 +983,12 @@ exports['Agent lib checkin should return the full policy for this agent - find:" exports['Agent lib checkin should return the full policy for this agent - update:agents (5)'] = { "results": { - "id": "9ac6d520-0625-11ea-9674-75a3ee7c8618", + "id": "acb12cb0-0fd3-11ea-af46-9724fc51c031", "type": "agents", - "updated_at": "2019-11-13T14:55:17.873Z", - "version": "WzI2MSwxXQ==", + "updated_at": "2019-11-25T22:34:00.827Z", + "version": "WzM2LDFd", "attributes": { - "last_checkin": "2019-11-13T14:55:17.868Z", + "last_checkin": "2019-11-25T22:34:00.825Z", "actions": [] } } @@ -1002,7 +1002,7 @@ exports['Agent lib checkin should update agent metadata if provided - find:"agen "saved_objects": [ { "type": "agents", - "id": "9ac6d520-0625-11ea-9674-75a3ee7c8618", + "id": "acb12cb0-0fd3-11ea-af46-9724fc51c031", "attributes": { "local_metadata": "{\"key\":\"local1\"}", "user_provided_metadata": "{\"key\":\"user1\"}", @@ -1010,11 +1010,11 @@ exports['Agent lib checkin should update agent metadata if provided - find:"agen "active": true, "policy_id": "policy:1", "access_api_key_id": "key1", - "last_checkin": "2019-11-13T14:55:17.868Z" + "last_checkin": "2019-11-25T22:34:00.825Z" }, "references": [], - "updated_at": "2019-11-13T14:55:17.873Z", - "version": "WzI2MSwxXQ==" + "updated_at": "2019-11-25T22:34:00.827Z", + "version": "WzM2LDFd" } ] } @@ -1027,7 +1027,7 @@ exports['Agent lib checkin should update agent metadata if provided - delete (2) exports['Agent lib checkin should update agent metadata if provided - create:agents (3)'] = { "results": { "type": "agents", - "id": "9c979d80-0625-11ea-9674-75a3ee7c8618", + "id": "ae824330-0fd3-11ea-af46-9724fc51c031", "attributes": { "local_metadata": "{\"key\":\"local1\"}", "user_provided_metadata": "{\"key\":\"user1\"}", @@ -1037,8 +1037,8 @@ exports['Agent lib checkin should update agent metadata if provided - create:age "access_api_key_id": "key1" }, "references": [], - "updated_at": "2019-11-13T14:55:19.895Z", - "version": "WzI2MywxXQ==" + "updated_at": "2019-11-25T22:34:02.851Z", + "version": "WzM4LDFd" } } @@ -1050,7 +1050,7 @@ exports['Agent lib checkin should update agent metadata if provided - find:"agen "saved_objects": [ { "type": "agents", - "id": "9c979d80-0625-11ea-9674-75a3ee7c8618", + "id": "ae824330-0fd3-11ea-af46-9724fc51c031", "attributes": { "local_metadata": "{\"key\":\"local1\"}", "user_provided_metadata": "{\"key\":\"user1\"}", @@ -1060,8 +1060,8 @@ exports['Agent lib checkin should update agent metadata if provided - find:"agen "access_api_key_id": "key1" }, "references": [], - "updated_at": "2019-11-13T14:55:19.895Z", - "version": "WzI2MywxXQ==" + "updated_at": "2019-11-25T22:34:02.851Z", + "version": "WzM4LDFd" } ] } @@ -1069,12 +1069,12 @@ exports['Agent lib checkin should update agent metadata if provided - find:"agen exports['Agent lib checkin should update agent metadata if provided - update:agents (5)'] = { "results": { - "id": "9c979d80-0625-11ea-9674-75a3ee7c8618", + "id": "ae824330-0fd3-11ea-af46-9724fc51c031", "type": "agents", - "updated_at": "2019-11-13T14:55:20.906Z", - "version": "WzI2NCwxXQ==", + "updated_at": "2019-11-25T22:34:03.866Z", + "version": "WzM5LDFd", "attributes": { - "last_checkin": "2019-11-13T14:55:20.904Z", + "last_checkin": "2019-11-25T22:34:03.865Z", "actions": [], "local_metadata": "{\"key\":\"local2\"}" } @@ -1083,10 +1083,10 @@ exports['Agent lib checkin should update agent metadata if provided - update:age exports['Agent lib checkin should update agent metadata if provided - get:agents (6)'] = { "results": { - "id": "9c979d80-0625-11ea-9674-75a3ee7c8618", + "id": "ae824330-0fd3-11ea-af46-9724fc51c031", "type": "agents", - "updated_at": "2019-11-13T14:55:20.906Z", - "version": "WzI2NCwxXQ==", + "updated_at": "2019-11-25T22:34:03.866Z", + "version": "WzM5LDFd", "attributes": { "local_metadata": "{\"key\":\"local2\"}", "user_provided_metadata": "{\"key\":\"user1\"}", @@ -1094,7 +1094,7 @@ exports['Agent lib checkin should update agent metadata if provided - get:agents "active": true, "policy_id": "policy:1", "access_api_key_id": "key1", - "last_checkin": "2019-11-13T14:55:20.904Z" + "last_checkin": "2019-11-25T22:34:03.865Z" }, "references": [] } @@ -1108,7 +1108,7 @@ exports['Agent lib checkin should return new actions - find:"agents" (1)'] = { "saved_objects": [ { "type": "agents", - "id": "9c979d80-0625-11ea-9674-75a3ee7c8618", + "id": "ae824330-0fd3-11ea-af46-9724fc51c031", "attributes": { "local_metadata": "{\"key\":\"local2\"}", "user_provided_metadata": "{\"key\":\"user1\"}", @@ -1116,11 +1116,11 @@ exports['Agent lib checkin should return new actions - find:"agents" (1)'] = { "active": true, "policy_id": "policy:1", "access_api_key_id": "key1", - "last_checkin": "2019-11-13T14:55:20.904Z" + "last_checkin": "2019-11-25T22:34:03.865Z" }, "references": [], - "updated_at": "2019-11-13T14:55:20.906Z", - "version": "WzI2NCwxXQ==" + "updated_at": "2019-11-25T22:34:03.866Z", + "version": "WzM5LDFd" } ] } @@ -1133,7 +1133,7 @@ exports['Agent lib checkin should return new actions - delete (2)'] = { exports['Agent lib checkin should return new actions - create:agents (3)'] = { "results": { "type": "agents", - "id": "9e677b80-0625-11ea-9674-75a3ee7c8618", + "id": "b0546b20-0fd3-11ea-af46-9724fc51c031", "attributes": { "active": true, "policy_id": "policy:1", @@ -1155,8 +1155,8 @@ exports['Agent lib checkin should return new actions - create:agents (3)'] = { "user_provided_metadata": "{}" }, "references": [], - "updated_at": "2019-11-13T14:55:22.936Z", - "version": "WzI2NiwxXQ==" + "updated_at": "2019-11-25T22:34:05.906Z", + "version": "WzQxLDFd" } } @@ -1168,7 +1168,7 @@ exports['Agent lib checkin should return new actions - find:"agents" (4)'] = { "saved_objects": [ { "type": "agents", - "id": "9e677b80-0625-11ea-9674-75a3ee7c8618", + "id": "b0546b20-0fd3-11ea-af46-9724fc51c031", "attributes": { "active": true, "policy_id": "policy:1", @@ -1190,8 +1190,8 @@ exports['Agent lib checkin should return new actions - find:"agents" (4)'] = { "user_provided_metadata": "{}" }, "references": [], - "updated_at": "2019-11-13T14:55:22.936Z", - "version": "WzI2NiwxXQ==" + "updated_at": "2019-11-25T22:34:05.906Z", + "version": "WzQxLDFd" } ] } @@ -1199,18 +1199,18 @@ exports['Agent lib checkin should return new actions - find:"agents" (4)'] = { exports['Agent lib checkin should return new actions - update:agents (5)'] = { "results": { - "id": "9e677b80-0625-11ea-9674-75a3ee7c8618", + "id": "b0546b20-0fd3-11ea-af46-9724fc51c031", "type": "agents", - "updated_at": "2019-11-13T14:55:23.960Z", - "version": "WzI2NywxXQ==", + "updated_at": "2019-11-25T22:34:06.926Z", + "version": "WzQyLDFd", "attributes": { - "last_checkin": "2019-11-13T14:55:23.958Z", + "last_checkin": "2019-11-25T22:34:06.923Z", "actions": [ { "created_at": "2019-09-05T15:43:26+0000", "type": "PAUSE", "id": "this-a-unique-id", - "sent_at": "2019-11-13T14:55:23.958Z" + "sent_at": "2019-11-25T22:34:06.923Z" } ] } @@ -1225,14 +1225,14 @@ exports['Agent lib unenroll should set the list of agents as inactive - find:"ag "saved_objects": [ { "type": "agents", - "id": "9e677b80-0625-11ea-9674-75a3ee7c8618", + "id": "b0546b20-0fd3-11ea-af46-9724fc51c031", "attributes": { "active": true, "policy_id": "policy:1", "access_api_key_id": "key1", "actions": [ { - "sent_at": "2019-11-13T14:55:23.958Z", + "sent_at": "2019-11-25T22:34:06.923Z", "created_at": "2019-09-05T15:43:26+0000", "id": "this-a-unique-id", "type": "PAUSE" @@ -1240,11 +1240,11 @@ exports['Agent lib unenroll should set the list of agents as inactive - find:"ag ], "local_metadata": "{}", "user_provided_metadata": "{}", - "last_checkin": "2019-11-13T14:55:23.958Z" + "last_checkin": "2019-11-25T22:34:06.923Z" }, "references": [], - "updated_at": "2019-11-13T14:55:23.960Z", - "version": "WzI2NywxXQ==" + "updated_at": "2019-11-25T22:34:06.926Z", + "version": "WzQyLDFd" } ] } @@ -1257,7 +1257,7 @@ exports['Agent lib unenroll should set the list of agents as inactive - delete ( exports['Agent lib unenroll should set the list of agents as inactive - create:agents (3)'] = { "results": { "type": "agents", - "id": "a0389200-0625-11ea-9674-75a3ee7c8618", + "id": "b224be50-0fd3-11ea-af46-9724fc51c031", "attributes": { "local_metadata": "{\"key\":\"local1\"}", "user_provided_metadata": "{\"key\":\"user1\"}", @@ -1266,15 +1266,15 @@ exports['Agent lib unenroll should set the list of agents as inactive - create:a "policy_id": "policy:1" }, "references": [], - "updated_at": "2019-11-13T14:55:25.984Z", - "version": "WzI2OSwxXQ==" + "updated_at": "2019-11-25T22:34:08.949Z", + "version": "WzQ0LDFd" } } exports['Agent lib unenroll should set the list of agents as inactive - create:agents (4)'] = { "results": { "type": "agents", - "id": "a0d32450-0625-11ea-9674-75a3ee7c8618", + "id": "b2c06210-0fd3-11ea-af46-9724fc51c031", "attributes": { "local_metadata": "{\"key\":\"local1\"}", "user_provided_metadata": "{\"key\":\"user1\"}", @@ -1283,17 +1283,17 @@ exports['Agent lib unenroll should set the list of agents as inactive - create:a "policy_id": "policy:1" }, "references": [], - "updated_at": "2019-11-13T14:55:26.997Z", - "version": "WzI3MCwxXQ==" + "updated_at": "2019-11-25T22:34:09.969Z", + "version": "WzQ1LDFd" } } exports['Agent lib unenroll should set the list of agents as inactive - update:agents (5)'] = { "results": { - "id": "a0389200-0625-11ea-9674-75a3ee7c8618", + "id": "b224be50-0fd3-11ea-af46-9724fc51c031", "type": "agents", - "updated_at": "2019-11-13T14:55:28.012Z", - "version": "WzI3MSwxXQ==", + "updated_at": "2019-11-25T22:34:10.987Z", + "version": "WzQ2LDFd", "attributes": { "active": false } @@ -1302,10 +1302,10 @@ exports['Agent lib unenroll should set the list of agents as inactive - update:a exports['Agent lib unenroll should set the list of agents as inactive - update:agents (6)'] = { "results": { - "id": "a0d32450-0625-11ea-9674-75a3ee7c8618", + "id": "b2c06210-0fd3-11ea-af46-9724fc51c031", "type": "agents", - "updated_at": "2019-11-13T14:55:29.019Z", - "version": "WzI3MiwxXQ==", + "updated_at": "2019-11-25T22:34:12.012Z", + "version": "WzQ3LDFd", "attributes": { "active": false } @@ -1314,10 +1314,10 @@ exports['Agent lib unenroll should set the list of agents as inactive - update:a exports['Agent lib unenroll should set the list of agents as inactive - get:agents (7)'] = { "results": { - "id": "a0389200-0625-11ea-9674-75a3ee7c8618", + "id": "b224be50-0fd3-11ea-af46-9724fc51c031", "type": "agents", - "updated_at": "2019-11-13T14:55:28.012Z", - "version": "WzI3MSwxXQ==", + "updated_at": "2019-11-25T22:34:10.987Z", + "version": "WzQ2LDFd", "attributes": { "local_metadata": "{\"key\":\"local1\"}", "user_provided_metadata": "{\"key\":\"user1\"}", @@ -1331,10 +1331,10 @@ exports['Agent lib unenroll should set the list of agents as inactive - get:agen exports['Agent lib unenroll should set the list of agents as inactive - get:agents (8)'] = { "results": { - "id": "a0d32450-0625-11ea-9674-75a3ee7c8618", + "id": "b2c06210-0fd3-11ea-af46-9724fc51c031", "type": "agents", - "updated_at": "2019-11-13T14:55:29.019Z", - "version": "WzI3MiwxXQ==", + "updated_at": "2019-11-25T22:34:12.012Z", + "version": "WzQ3LDFd", "attributes": { "local_metadata": "{\"key\":\"local1\"}", "user_provided_metadata": "{\"key\":\"user1\"}", @@ -1354,7 +1354,7 @@ exports['Agent lib unenrollForPolicy should set all the of agents for this polic "saved_objects": [ { "type": "agents", - "id": "a0389200-0625-11ea-9674-75a3ee7c8618", + "id": "b224be50-0fd3-11ea-af46-9724fc51c031", "attributes": { "local_metadata": "{\"key\":\"local1\"}", "user_provided_metadata": "{\"key\":\"user1\"}", @@ -1363,12 +1363,12 @@ exports['Agent lib unenrollForPolicy should set all the of agents for this polic "policy_id": "policy:1" }, "references": [], - "updated_at": "2019-11-13T14:55:28.012Z", - "version": "WzI3MSwxXQ==" + "updated_at": "2019-11-25T22:34:10.987Z", + "version": "WzQ2LDFd" }, { "type": "agents", - "id": "a0d32450-0625-11ea-9674-75a3ee7c8618", + "id": "b2c06210-0fd3-11ea-af46-9724fc51c031", "attributes": { "local_metadata": "{\"key\":\"local1\"}", "user_provided_metadata": "{\"key\":\"user1\"}", @@ -1377,8 +1377,8 @@ exports['Agent lib unenrollForPolicy should set all the of agents for this polic "policy_id": "policy:1" }, "references": [], - "updated_at": "2019-11-13T14:55:29.019Z", - "version": "WzI3MiwxXQ==" + "updated_at": "2019-11-25T22:34:12.012Z", + "version": "WzQ3LDFd" } ] } @@ -1395,7 +1395,7 @@ exports['Agent lib unenrollForPolicy should set all the of agents for this polic exports['Agent lib unenrollForPolicy should set all the of agents for this policy as inactive - create:agents (4)'] = { "results": { "type": "agents", - "id": "a3d6ee70-0625-11ea-9674-75a3ee7c8618", + "id": "b5cabbe0-0fd3-11ea-af46-9724fc51c031", "attributes": { "local_metadata": "{\"key\":\"local1\"}", "user_provided_metadata": "{\"key\":\"user1\"}", @@ -1404,15 +1404,15 @@ exports['Agent lib unenrollForPolicy should set all the of agents for this polic "policy_id": "policy:1" }, "references": [], - "updated_at": "2019-11-13T14:55:32.055Z", - "version": "WzI3NSwxXQ==" + "updated_at": "2019-11-25T22:34:15.070Z", + "version": "WzUwLDFd" } } exports['Agent lib unenrollForPolicy should set all the of agents for this policy as inactive - create:agents (5)'] = { "results": { "type": "agents", - "id": "a4743fe0-0625-11ea-9674-75a3ee7c8618", + "id": "b6654e30-0fd3-11ea-af46-9724fc51c031", "attributes": { "local_metadata": "{\"key\":\"local1\"}", "user_provided_metadata": "{\"key\":\"user1\"}", @@ -1421,8 +1421,8 @@ exports['Agent lib unenrollForPolicy should set all the of agents for this polic "policy_id": "policy:1" }, "references": [], - "updated_at": "2019-11-13T14:55:33.086Z", - "version": "WzI3NiwxXQ==" + "updated_at": "2019-11-25T22:34:16.083Z", + "version": "WzUxLDFd" } } @@ -1434,7 +1434,7 @@ exports['Agent lib unenrollForPolicy should set all the of agents for this polic "saved_objects": [ { "type": "agents", - "id": "a3d6ee70-0625-11ea-9674-75a3ee7c8618", + "id": "b5cabbe0-0fd3-11ea-af46-9724fc51c031", "attributes": { "local_metadata": "{\"key\":\"local1\"}", "user_provided_metadata": "{\"key\":\"user1\"}", @@ -1443,12 +1443,12 @@ exports['Agent lib unenrollForPolicy should set all the of agents for this polic "policy_id": "policy:1" }, "references": [], - "updated_at": "2019-11-13T14:55:32.055Z", - "version": "WzI3NSwxXQ==" + "updated_at": "2019-11-25T22:34:15.070Z", + "version": "WzUwLDFd" }, { "type": "agents", - "id": "a4743fe0-0625-11ea-9674-75a3ee7c8618", + "id": "b6654e30-0fd3-11ea-af46-9724fc51c031", "attributes": { "local_metadata": "{\"key\":\"local1\"}", "user_provided_metadata": "{\"key\":\"user1\"}", @@ -1457,8 +1457,8 @@ exports['Agent lib unenrollForPolicy should set all the of agents for this polic "policy_id": "policy:1" }, "references": [], - "updated_at": "2019-11-13T14:55:33.086Z", - "version": "WzI3NiwxXQ==" + "updated_at": "2019-11-25T22:34:16.083Z", + "version": "WzUxLDFd" } ] } @@ -1466,10 +1466,10 @@ exports['Agent lib unenrollForPolicy should set all the of agents for this polic exports['Agent lib unenrollForPolicy should set all the of agents for this policy as inactive - update:agents (7)'] = { "results": { - "id": "a3d6ee70-0625-11ea-9674-75a3ee7c8618", + "id": "b5cabbe0-0fd3-11ea-af46-9724fc51c031", "type": "agents", - "updated_at": "2019-11-13T14:55:34.128Z", - "version": "WzI3NywxXQ==", + "updated_at": "2019-11-25T22:34:17.140Z", + "version": "WzUyLDFd", "attributes": { "active": false } @@ -1478,10 +1478,10 @@ exports['Agent lib unenrollForPolicy should set all the of agents for this polic exports['Agent lib unenrollForPolicy should set all the of agents for this policy as inactive - update:agents (8)'] = { "results": { - "id": "a4743fe0-0625-11ea-9674-75a3ee7c8618", + "id": "b6654e30-0fd3-11ea-af46-9724fc51c031", "type": "agents", - "updated_at": "2019-11-13T14:55:35.103Z", - "version": "WzI3OCwxXQ==", + "updated_at": "2019-11-25T22:34:18.112Z", + "version": "WzUzLDFd", "attributes": { "active": false } @@ -1499,10 +1499,10 @@ exports['Agent lib unenrollForPolicy should set all the of agents for this polic exports['Agent lib unenrollForPolicy should set all the of agents for this policy as inactive - get:agents (10)'] = { "results": { - "id": "a3d6ee70-0625-11ea-9674-75a3ee7c8618", + "id": "b5cabbe0-0fd3-11ea-af46-9724fc51c031", "type": "agents", - "updated_at": "2019-11-13T14:55:34.128Z", - "version": "WzI3NywxXQ==", + "updated_at": "2019-11-25T22:34:17.140Z", + "version": "WzUyLDFd", "attributes": { "local_metadata": "{\"key\":\"local1\"}", "user_provided_metadata": "{\"key\":\"user1\"}", @@ -1516,10 +1516,10 @@ exports['Agent lib unenrollForPolicy should set all the of agents for this polic exports['Agent lib unenrollForPolicy should set all the of agents for this policy as inactive - get:agents (11)'] = { "results": { - "id": "a4743fe0-0625-11ea-9674-75a3ee7c8618", + "id": "b6654e30-0fd3-11ea-af46-9724fc51c031", "type": "agents", - "updated_at": "2019-11-13T14:55:35.103Z", - "version": "WzI3OCwxXQ==", + "updated_at": "2019-11-25T22:34:18.112Z", + "version": "WzUzLDFd", "attributes": { "local_metadata": "{\"key\":\"local1\"}", "user_provided_metadata": "{\"key\":\"user1\"}", @@ -1539,7 +1539,7 @@ exports['Agent lib addAction should throw if the agent do not exists - find:"age "saved_objects": [ { "type": "agents", - "id": "a3d6ee70-0625-11ea-9674-75a3ee7c8618", + "id": "b5cabbe0-0fd3-11ea-af46-9724fc51c031", "attributes": { "local_metadata": "{\"key\":\"local1\"}", "user_provided_metadata": "{\"key\":\"user1\"}", @@ -1548,12 +1548,12 @@ exports['Agent lib addAction should throw if the agent do not exists - find:"age "policy_id": "policy:1" }, "references": [], - "updated_at": "2019-11-13T14:55:34.128Z", - "version": "WzI3NywxXQ==" + "updated_at": "2019-11-25T22:34:17.140Z", + "version": "WzUyLDFd" }, { "type": "agents", - "id": "a4743fe0-0625-11ea-9674-75a3ee7c8618", + "id": "b6654e30-0fd3-11ea-af46-9724fc51c031", "attributes": { "local_metadata": "{\"key\":\"local1\"}", "user_provided_metadata": "{\"key\":\"user1\"}", @@ -1562,8 +1562,8 @@ exports['Agent lib addAction should throw if the agent do not exists - find:"age "policy_id": "policy:1" }, "references": [], - "updated_at": "2019-11-13T14:55:35.103Z", - "version": "WzI3OCwxXQ==" + "updated_at": "2019-11-25T22:34:18.112Z", + "version": "WzUzLDFd" } ] } @@ -1580,3 +1580,180 @@ exports['Agent lib addAction should throw if the agent do not exists - delete (3 exports['Agent lib addAction should throw if the agent do not exists - get:agents (4)'] = { "results": null } + +exports['Agent lib getAgentsStatusForPolicy should return all agents - find:"agents" (1)'] = { + "results": { + "page": 1, + "per_page": 1000, + "total": 0, + "saved_objects": [] + } +} + +exports['Agent lib getAgentsStatusForPolicy should return all agents - create:agents (2)'] = { + "results": { + "type": "agents", + "id": "b96cc1d0-0fd3-11ea-af46-9724fc51c031", + "attributes": { + "type": "PERMANENT", + "active": true, + "policy_id": "policy:2", + "local_metadata": "{}", + "user_provided_metadata": "{}" + }, + "references": [], + "updated_at": "2019-11-25T22:34:21.165Z", + "version": "WzU2LDFd" + } +} + +exports['Agent lib getAgentsStatusForPolicy should return all agents - create:agents (3)'] = { + "results": { + "type": "agents", + "id": "ba1584f0-0fd3-11ea-af46-9724fc51c031", + "attributes": { + "type": "PERMANENT", + "active": true, + "policy_id": "policy:3", + "local_metadata": "{}", + "user_provided_metadata": "{}" + }, + "references": [], + "updated_at": "2019-11-25T22:34:22.271Z", + "version": "WzU3LDFd" + } +} + +exports['Agent lib getAgentsStatusForPolicy should return all agents - create:agents (4)'] = { + "results": { + "type": "agents", + "id": "bab26130-0fd3-11ea-af46-9724fc51c031", + "attributes": { + "type": "TEMPORARY", + "active": true, + "policy_id": "policy:3", + "local_metadata": "{}", + "user_provided_metadata": "{}" + }, + "references": [], + "updated_at": "2019-11-25T22:34:23.299Z", + "version": "WzU4LDFd" + } +} + +exports['Agent lib getAgentsStatusForPolicy should return all agents - create:agents (5)'] = { + "results": { + "type": "agents", + "id": "bb4db6d0-0fd3-11ea-af46-9724fc51c031", + "attributes": { + "type": "PERMANENT", + "active": true, + "policy_id": "policy:1", + "last_checkin": "2019-11-25T22:29:21.163Z", + "local_metadata": "{}", + "user_provided_metadata": "{}" + }, + "references": [], + "updated_at": "2019-11-25T22:34:24.317Z", + "version": "WzU5LDFd" + } +} + +exports['Agent lib getAgentsStatusForPolicy should return all agents - create:agents (6)'] = { + "results": { + "type": "agents", + "id": "bbe87030-0fd3-11ea-af46-9724fc51c031", + "attributes": { + "type": "PERMANENT", + "active": true, + "policy_id": "policy:1", + "last_checkin": "2019-11-25T22:34:21.163Z", + "local_metadata": "{}", + "user_provided_metadata": "{}" + }, + "references": [], + "updated_at": "2019-11-25T22:34:25.331Z", + "version": "WzYwLDFd" + } +} + +exports['Agent lib getAgentsStatusForPolicy should return all agents - create:agents (7)'] = { + "results": { + "type": "agents", + "id": "bc81ca00-0fd3-11ea-af46-9724fc51c031", + "attributes": { + "type": "PERMANENT", + "active": true, + "policy_id": "policy:1", + "last_checkin": "2019-11-25T22:34:21.163Z", + "local_metadata": "{}", + "user_provided_metadata": "{}" + }, + "references": [], + "updated_at": "2019-11-25T22:34:26.336Z", + "version": "WzYxLDFd" + } +} + +exports['Agent lib getAgentsStatusForPolicy should return all agents - create:agents (8)'] = { + "results": { + "type": "agents", + "id": "bd1e5820-0fd3-11ea-af46-9724fc51c031", + "attributes": { + "type": "TEMPORARY", + "active": true, + "policy_id": "policy:1", + "last_checkin": "2019-11-25T22:29:21.163Z", + "local_metadata": "{}", + "user_provided_metadata": "{}" + }, + "references": [], + "updated_at": "2019-11-25T22:34:27.361Z", + "version": "WzYyLDFd" + } +} + +exports['Agent lib getAgentsStatusForPolicy should return all agents - create:agents (9)'] = { + "results": { + "type": "agents", + "id": "bdba7110-0fd3-11ea-af46-9724fc51c031", + "attributes": { + "type": "TEMPORARY", + "active": true, + "policy_id": "policy:1", + "last_checkin": "2019-11-25T22:34:21.163Z", + "local_metadata": "{}", + "user_provided_metadata": "{}" + }, + "references": [], + "updated_at": "2019-11-25T22:34:28.385Z", + "version": "WzYzLDFd" + } +} + +exports['Agent lib getAgentsStatusForPolicy should return all agents - find:"agents" (12)'] = { + "results": { + "page": 1, + "per_page": 0, + "total": 1, + "saved_objects": [] + } +} + +exports['Agent lib getAgentsStatusForPolicy should return all agents - find:"agents" (11)'] = { + "results": { + "page": 1, + "per_page": 0, + "total": 1, + "saved_objects": [] + } +} + +exports['Agent lib getAgentsStatusForPolicy should return all agents - find:"agents" (10)'] = { + "results": { + "page": 1, + "per_page": 0, + "total": 5, + "saved_objects": [] + } +} diff --git a/x-pack/legacy/plugins/fleet/server/libs/agent.contract.test.ts b/x-pack/legacy/plugins/fleet/server/libs/agent.contract.test.ts index cbccd37bd97b5..07634d727e882 100644 --- a/x-pack/legacy/plugins/fleet/server/libs/agent.contract.test.ts +++ b/x-pack/legacy/plugins/fleet/server/libs/agent.contract.test.ts @@ -12,6 +12,7 @@ import { FleetServerLib } from './types'; import { SODatabaseAdapter } from '../adapters/saved_objects_database/default'; import { MemorizeSODatabaseAdapter } from '../adapters/saved_objects_database/memorize_adapter'; import { SavedObject } from 'kibana/server'; +import { AGENT_POLLING_THRESHOLD_MS } from '../../common/constants'; jest.mock('./api_keys'); jest.mock('./policy'); @@ -471,4 +472,73 @@ describe('Agent lib', () => { ).rejects.toThrowError(/Agent not found/); }); }); + + describe('getAgentsStatusForPolicy', () => { + it('should return all agents', async () => { + const { agents } = libs; + const policyId = 'policy:1'; + await loadFixtures([ + // Other policies + { + type: 'PERMANENT', + active: true, + policy_id: 'policy:2', + }, + { + type: 'PERMANENT', + active: true, + policy_id: 'policy:3', + }, + { + type: 'TEMPORARY', + active: true, + policy_id: 'policy:3', + }, + // PERMANENT + // ERROR + { + type: 'PERMANENT', + active: true, + policy_id: policyId, + last_checkin: new Date(Date.now() - AGENT_POLLING_THRESHOLD_MS * 10).toISOString(), + }, + // ACTIVE + { + type: 'PERMANENT', + active: true, + policy_id: policyId, + last_checkin: new Date().toISOString(), + }, + { + type: 'PERMANENT', + active: true, + policy_id: policyId, + last_checkin: new Date().toISOString(), + }, + // TEMPORARY + // OFFLINE + { + type: 'TEMPORARY', + active: true, + policy_id: policyId, + last_checkin: new Date(Date.now() - AGENT_POLLING_THRESHOLD_MS * 10).toISOString(), + }, + // Active + { + type: 'TEMPORARY', + active: true, + policy_id: policyId, + last_checkin: new Date().toISOString(), + }, + ]); + + const res = await agents.getAgentsStatusForPolicy(getUser(), policyId); + expect(res).toMatchObject({ + total: 5, + online: 3, + error: 1, + offline: 1, + }); + }); + }); }); diff --git a/x-pack/legacy/plugins/fleet/server/libs/agent.ts b/x-pack/legacy/plugins/fleet/server/libs/agent.ts index cdfe029deca40..d72763db9325a 100644 --- a/x-pack/legacy/plugins/fleet/server/libs/agent.ts +++ b/x-pack/legacy/plugins/fleet/server/libs/agent.ts @@ -20,6 +20,7 @@ import { PolicyLib } from './policy'; import { FullPolicyFile } from '../repositories/policies/types'; import { FrameworkUser } from '../adapters/framework/adapter_types'; import { AgentEventsRepository, AgentEvent } from '../repositories/agent_events/types'; +import { AgentStatusHelper } from './agent_status_helper'; export class AgentLib { constructor( @@ -269,10 +270,33 @@ export class AgentLib { return action; } + public async getAgentsStatusForPolicy(user: FrameworkUser, policyId: string) { + const [all, error, offline] = await Promise.all( + [ + undefined, + AgentStatusHelper.buildKueryForErrorAgents(), + AgentStatusHelper.buildKueryForOfflineAgents(), + ].map(kuery => { + return this.agentsRepository.listForPolicy(user, policyId, { + perPage: 0, + kuery, + }); + }) + ); + + return { + total: all.total, + online: all.total - error.total - offline.total, + error: error.total, + offline: offline.total, + }; + } + /** * List agents * * @param sortOptions + * * @param page * @param perPage */ diff --git a/x-pack/legacy/plugins/fleet/server/libs/agent_status_helper.test.ts b/x-pack/legacy/plugins/fleet/server/libs/agent_status_helper.test.ts new file mode 100644 index 0000000000000..ee1c49171f3d7 --- /dev/null +++ b/x-pack/legacy/plugins/fleet/server/libs/agent_status_helper.test.ts @@ -0,0 +1,93 @@ +/* + * 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 { + AGENT_TYPE_TEMPORARY, + AGENT_POLLING_THRESHOLD_MS, + AGENT_TYPE_PERMANENT, + AGENT_TYPE_EPHEMERAL, +} from '../../common/constants'; +import { Agent } from '../repositories/agents/types'; +import { AgentStatusHelper } from './agent_status_helper'; + +describe('AgentStatusHelper', () => { + describe('getAgentStatus', () => { + it('return inactive for a not active agent', () => { + const status = AgentStatusHelper.getAgentStatus({ active: false } as Agent); + + expect(status).toBe('inactive'); + }); + describe('EPHEMERAL agents', () => { + it('return online for an active agent', () => { + const status = AgentStatusHelper.getAgentStatus({ + active: true, + type: AGENT_TYPE_EPHEMERAL, + last_checkin: new Date().toISOString(), + } as Agent); + + expect(status).toBe('online'); + }); + it('return inactive for an agent that did not checkin recently', () => { + const status = AgentStatusHelper.getAgentStatus({ + active: true, + type: AGENT_TYPE_EPHEMERAL, + last_checkin: new Date(Date.now() - 10 * AGENT_POLLING_THRESHOLD_MS).toISOString(), + } as Agent); + + expect(status).toBe('inactive'); + }); + }); + describe('TEMPORARY agents', () => { + it('return online for an active agent', () => { + const status = AgentStatusHelper.getAgentStatus({ + active: true, + type: AGENT_TYPE_TEMPORARY, + last_checkin: new Date().toISOString(), + } as Agent); + + expect(status).toBe('online'); + }); + it('return offline for an agent that did not checkin recently', () => { + const status = AgentStatusHelper.getAgentStatus({ + active: true, + type: AGENT_TYPE_TEMPORARY, + last_checkin: new Date(Date.now() - 10 * AGENT_POLLING_THRESHOLD_MS).toISOString(), + } as Agent); + + expect(status).toBe('offline'); + }); + }); + describe('PERMANENT agents', () => { + it('return online for an active agent', () => { + const status = AgentStatusHelper.getAgentStatus({ + active: true, + type: AGENT_TYPE_PERMANENT, + last_checkin: new Date().toISOString(), + } as Agent); + + expect(status).toBe('online'); + }); + it('return warning for a agent that did not check in the last 60 seconds', () => { + const status = AgentStatusHelper.getAgentStatus({ + active: true, + type: AGENT_TYPE_PERMANENT, + last_checkin: new Date(Date.now() - 2 * AGENT_POLLING_THRESHOLD_MS).toISOString(), + } as Agent); + + expect(status).toBe('warning'); + }); + it('return error for a inactive agent', () => { + const status = AgentStatusHelper.getAgentStatus({ + active: true, + type: AGENT_TYPE_PERMANENT, + last_checkin: new Date(Date.now() - 5 * AGENT_POLLING_THRESHOLD_MS).toISOString(), + } as Agent); + + expect(status).toBe('error'); + }); + }); + }); +}); diff --git a/x-pack/legacy/plugins/fleet/server/libs/agent_status_helper.ts b/x-pack/legacy/plugins/fleet/server/libs/agent_status_helper.ts new file mode 100644 index 0000000000000..37c2af4829074 --- /dev/null +++ b/x-pack/legacy/plugins/fleet/server/libs/agent_status_helper.ts @@ -0,0 +1,56 @@ +/* + * 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 { + AGENT_TYPE_TEMPORARY, + AGENT_POLLING_THRESHOLD_MS, + AGENT_TYPE_PERMANENT, + AGENT_TYPE_EPHEMERAL, +} from '../../common/constants'; +import { Agent } from '../repositories/agents/types'; +import { AgentStatus } from '../../common/types/domain_data'; + +export class AgentStatusHelper { + public static buildKueryForOfflineAgents(now: number = Date.now()) { + return `agents.type:${AGENT_TYPE_TEMPORARY} AND agents.last_checkin < ${now - + 3 * AGENT_POLLING_THRESHOLD_MS}`; + } + + public static buildKueryForErrorAgents(now: number = Date.now()) { + return `agents.type:${AGENT_TYPE_PERMANENT} AND agents.last_checkin < ${now - + 4 * AGENT_POLLING_THRESHOLD_MS}`; + } + + public static getAgentStatus(agent: Agent, now: number = Date.now()): AgentStatus { + const { type, last_checkin: lastCheckIn } = agent; + const msLastCheckIn = new Date(lastCheckIn || 0).getTime(); + const msSinceLastCheckIn = new Date().getTime() - msLastCheckIn; + const intervalsSinceLastCheckIn = Math.floor(msSinceLastCheckIn / AGENT_POLLING_THRESHOLD_MS); + + if (!agent.active) { + return 'inactive'; + } + + switch (type) { + case AGENT_TYPE_PERMANENT: + if (intervalsSinceLastCheckIn >= 4) { + return 'error'; + } + if (intervalsSinceLastCheckIn >= 2) { + return 'warning'; + } + case AGENT_TYPE_TEMPORARY: + if (intervalsSinceLastCheckIn >= 3) { + return 'offline'; + } + case AGENT_TYPE_EPHEMERAL: + if (intervalsSinceLastCheckIn >= 3) { + return 'inactive'; + } + } + return 'online'; + } +} diff --git a/x-pack/legacy/plugins/fleet/server/routes/agents/enroll.ts b/x-pack/legacy/plugins/fleet/server/routes/agents/enroll.ts index 22f0a4253d404..28b39a0ff2ff9 100644 --- a/x-pack/legacy/plugins/fleet/server/routes/agents/enroll.ts +++ b/x-pack/legacy/plugins/fleet/server/routes/agents/enroll.ts @@ -9,6 +9,7 @@ import { FrameworkRequest } from '../../adapters/framework/adapter_types'; import { ReturnTypeCreate } from '../../../common/return_types'; import { FleetServerLib } from '../../libs/types'; import { Agent } from '../../../common/types/domain_data'; +import { AgentStatusHelper } from '../../libs/agent_status_helper'; export const createEnrollAgentsRoute = (libs: FleetServerLib) => ({ method: 'POST', @@ -54,7 +55,7 @@ export const createEnrollAgentsRoute = (libs: FleetServerLib) => ({ return { action: 'created', success: true, - item: agent, + item: { ...agent, status: AgentStatusHelper.getAgentStatus(agent) }, }; }, }); diff --git a/x-pack/legacy/plugins/fleet/server/routes/agents/get.ts b/x-pack/legacy/plugins/fleet/server/routes/agents/get.ts index 9f13f315008c8..38bf6467d569b 100644 --- a/x-pack/legacy/plugins/fleet/server/routes/agents/get.ts +++ b/x-pack/legacy/plugins/fleet/server/routes/agents/get.ts @@ -9,6 +9,7 @@ import { FrameworkRequest } from '../../adapters/framework/adapter_types'; import { ReturnTypeGet } from '../../../common/return_types'; import { FleetServerLib } from '../../libs/types'; import { Agent } from '../../../common/types/domain_data'; +import { AgentStatusHelper } from '../../libs/agent_status_helper'; export const createGETAgentsRoute = (libs: FleetServerLib) => ({ method: 'GET', @@ -25,6 +26,6 @@ export const createGETAgentsRoute = (libs: FleetServerLib) => ({ throw Boom.notFound('Agent not found'); } - return { item: agent, success: true }; + return { item: { ...agent, status: AgentStatusHelper.getAgentStatus(agent) }, success: true }; }, }); diff --git a/x-pack/legacy/plugins/fleet/server/routes/agents/list.ts b/x-pack/legacy/plugins/fleet/server/routes/agents/list.ts index 0d4ac5639fa95..e195fda881758 100644 --- a/x-pack/legacy/plugins/fleet/server/routes/agents/list.ts +++ b/x-pack/legacy/plugins/fleet/server/routes/agents/list.ts @@ -10,6 +10,7 @@ import { ReturnTypeList } from '../../../common/return_types'; import { FleetServerLib } from '../../libs/types'; import { Agent } from '../../../common/types/domain_data'; import { DEFAULT_AGENTS_PAGE_SIZE } from '../../../common/constants'; +import { AgentStatusHelper } from '../../libs/agent_status_helper'; export const createListAgentsRoute = (libs: FleetServerLib) => ({ method: 'GET', @@ -39,6 +40,15 @@ export const createListAgentsRoute = (libs: FleetServerLib) => ({ showInactive: Boolean(request.query.showInactive), }); - return { list: agents, success: true, total, page, perPage }; + return { + list: agents.map(agent => ({ + ...agent, + status: AgentStatusHelper.getAgentStatus(agent), + })), + success: true, + total, + page, + perPage, + }; }, }); diff --git a/x-pack/legacy/plugins/fleet/server/routes/agents/status.ts b/x-pack/legacy/plugins/fleet/server/routes/agents/status.ts new file mode 100644 index 0000000000000..3f1442be7d103 --- /dev/null +++ b/x-pack/legacy/plugins/fleet/server/routes/agents/status.ts @@ -0,0 +1,28 @@ +/* + * 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 { FrameworkRequest } from '../../adapters/framework/adapter_types'; +import { ReturnTypeAction } from '../../../common/return_types'; +import { FleetServerLib } from '../../libs/types'; + +export const createGETAgentsStatusRoute = (libs: FleetServerLib) => ({ + method: 'GET', + path: '/api/fleet/policy/{policyId}/agent-status', + options: { + tags: ['access:fleet-read'], + validate: {}, + }, + handler: async ( + request: FrameworkRequest<{ params: { policyId: string } }> + ): Promise => { + const result = await libs.agents.getAgentsStatusForPolicy( + request.user, + request.params.policyId + ); + + return { result, success: true }; + }, +}); diff --git a/x-pack/legacy/plugins/fleet/server/routes/init_api.ts b/x-pack/legacy/plugins/fleet/server/routes/init_api.ts index 29a4e86fbe0da..440d301f2e6c1 100644 --- a/x-pack/legacy/plugins/fleet/server/routes/init_api.ts +++ b/x-pack/legacy/plugins/fleet/server/routes/init_api.ts @@ -29,6 +29,7 @@ import { createDELETEEnrollmentApiKeyRoute, createGETEnrollmentApiKeyRoute, } from './enrollment_api_keys'; +import { createGETAgentsStatusRoute } from './agents/status'; export function initRestApi(server: Server, libs: FleetServerLib) { const frameworkAdapter = new HapiFrameworkAdapter(server); @@ -50,6 +51,8 @@ function createAgentsRoutes(adapter: HapiFrameworkAdapter, libs: FleetServerLib) adapter.registerRoute(createCheckinAgentsRoute(libs)); adapter.registerRoute(createAgentsAddActionRoute(libs)); adapter.registerRoute(createGETAgentEventsRoute(libs)); + + adapter.registerRoute(createGETAgentsStatusRoute(libs)); } function createEnrollmentApiKeysRoutes(adapter: HapiFrameworkAdapter, libs: FleetServerLib) {