Skip to content

Commit

Permalink
Merge branch 'main' into eui-ghost/fleet
Browse files Browse the repository at this point in the history
  • Loading branch information
cee-chen authored Oct 18, 2023
2 parents d186936 + 8fd827f commit ffcad9e
Show file tree
Hide file tree
Showing 14 changed files with 455 additions and 34 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -1093,7 +1093,7 @@
"@babel/preset-react": "^7.18.6",
"@babel/preset-typescript": "^7.21.0",
"@babel/register": "^7.21.0",
"@babel/traverse": "^7.21.2",
"@babel/traverse": "^7.23.2",
"@babel/types": "^7.21.2",
"@bazel/ibazel": "^0.16.2",
"@bazel/typescript": "4.6.2",
Expand Down
4 changes: 2 additions & 2 deletions x-pack/plugins/fleet/server/services/files/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ import { Readable } from 'stream';
import type { estypes } from '@elastic/elasticsearch';

import type {
FleetFile,
FleetFromHostFileClientInterface,
FleetToHostFileClientInterface,
HapiReadableStream,
HostUploadedFileMetadata,
} from './types';
import type { FleetFile } from './types';
import type { HostUploadedFileMetadata } from './types';

export const createFleetFromHostFilesClientMock =
(): jest.Mocked<FleetFromHostFileClientInterface> => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ describe(
const [endpointAgentId, endpointHostname] = generateRandomStringName(2);

before(() => {
login(ROLE.endpoint_response_actions_access);

indexEndpointHosts({ numResponseActions: 2 }).then((indexEndpoints) => {
endpointData = indexEndpoints;
});
Expand Down Expand Up @@ -59,6 +57,10 @@ describe(
}
});

beforeEach(() => {
login(ROLE.endpoint_response_actions_access);
});

it('enable filtering by type', () => {
cy.visit(`/app/security/administration/response_actions_history`);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { closeAllToasts } from '../../tasks/toasts';
import {
getAlertsTableRows,
openAlertDetailsView,
openInvestigateInTimelineView,
openResponderFromEndpointAlertDetails,
} from '../../screens/alerts';
import { ensureOnResponder } from '../../screens/responder';
import { cleanupRule, loadRule } from '../../tasks/api_fixtures';
import type { PolicyData } from '../../../../../common/endpoint/types';
import type { CreateAndEnrollEndpointHostResponse } from '../../../../../scripts/endpoint/common/endpoint_host_services';
import { waitForEndpointListPageToBeLoaded } from '../../tasks/response_console';
import type { IndexedFleetEndpointPolicyResponse } from '../../../../../common/endpoint/data_loaders/index_fleet_endpoint_policy';
import { createAgentPolicyTask, getEndpointIntegrationVersion } from '../../tasks/fleet';
import { toggleRuleOffAndOn, visitRuleAlerts } from '../../tasks/isolate';

import { login } from '../../tasks/login';
import { enableAllPolicyProtections } from '../../tasks/endpoint_policy';
import { createEndpointHost } from '../../tasks/create_endpoint_host';
import { deleteAllLoadedEndpointData } from '../../tasks/delete_all_endpoint_data';

describe('Response console', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => {
let indexedPolicy: IndexedFleetEndpointPolicyResponse;
let policy: PolicyData;
let createdHost: CreateAndEnrollEndpointHostResponse;

beforeEach(() => {
login();
});

before(() => {
getEndpointIntegrationVersion().then((version) =>
createAgentPolicyTask(version).then((data) => {
indexedPolicy = data;
policy = indexedPolicy.integrationPolicies[0];

return enableAllPolicyProtections(policy.id).then(() => {
// Create and enroll a new Endpoint host
return createEndpointHost(policy.policy_id).then((host) => {
createdHost = host as CreateAndEnrollEndpointHostResponse;
});
});
})
);
});

after(() => {
if (createdHost) {
cy.task('destroyEndpointHost', createdHost);
}

if (indexedPolicy) {
cy.task('deleteIndexedFleetEndpointPolicies', indexedPolicy);
}

if (createdHost) {
deleteAllLoadedEndpointData({ endpointAgentIds: [createdHost.agentId] });
}
});

describe('From Alerts', () => {
let ruleId: string;
let ruleName: string;

before(() => {
loadRule(
{ query: `agent.name: ${createdHost.hostname} and agent.type: endpoint` },
false
).then((data) => {
ruleId = data.id;
ruleName = data.name;
});
});

after(() => {
if (ruleId) {
cleanupRule(ruleId);
}
});

it('should open responder from alert details flyout', () => {
waitForEndpointListPageToBeLoaded(createdHost.hostname);
toggleRuleOffAndOn(ruleName);
visitRuleAlerts(ruleName);
closeAllToasts();
getAlertsTableRows().should('have.length.greaterThan', 0);
openAlertDetailsView();

openResponderFromEndpointAlertDetails();
ensureOnResponder();
});

it('should open responder from timeline view alert details flyout', () => {
waitForEndpointListPageToBeLoaded(createdHost.hostname);
toggleRuleOffAndOn(ruleName);
visitRuleAlerts(ruleName);
closeAllToasts();

getAlertsTableRows().should('have.length.greaterThan', 0);
openInvestigateInTimelineView();
cy.getByTestSubj('timeline-flyout').within(() => {
openAlertDetailsView();
});
openResponderFromEndpointAlertDetails();
ensureOnResponder();
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { loadPage } from '../../tasks/common';
import { closeAllToasts } from '../../tasks/toasts';
import {
addAlertToCase,
getAlertsTableRows,
openAlertDetailsView,
openResponderFromEndpointAlertDetails,
} from '../../screens/alerts';
import { ensureOnResponder } from '../../screens/responder';
import { cleanupCase, cleanupRule, loadCase, loadRule } from '../../tasks/api_fixtures';
import type { PolicyData } from '../../../../../common/endpoint/types';
import type { CreateAndEnrollEndpointHostResponse } from '../../../../../scripts/endpoint/common/endpoint_host_services';
import { waitForEndpointListPageToBeLoaded } from '../../tasks/response_console';
import type { IndexedFleetEndpointPolicyResponse } from '../../../../../common/endpoint/data_loaders/index_fleet_endpoint_policy';
import { createAgentPolicyTask, getEndpointIntegrationVersion } from '../../tasks/fleet';
import { openCaseAlertDetails, toggleRuleOffAndOn, visitRuleAlerts } from '../../tasks/isolate';

import { login } from '../../tasks/login';
import { enableAllPolicyProtections } from '../../tasks/endpoint_policy';
import { createEndpointHost } from '../../tasks/create_endpoint_host';
import { deleteAllLoadedEndpointData } from '../../tasks/delete_all_endpoint_data';
import { APP_CASES_PATH } from '../../../../../common/constants';

describe('Response console', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => {
let indexedPolicy: IndexedFleetEndpointPolicyResponse;
let policy: PolicyData;
let createdHost: CreateAndEnrollEndpointHostResponse;

before(() => {
getEndpointIntegrationVersion().then((version) =>
createAgentPolicyTask(version).then((data) => {
indexedPolicy = data;
policy = indexedPolicy.integrationPolicies[0];

return enableAllPolicyProtections(policy.id).then(() => {
// Create and enroll a new Endpoint host
return createEndpointHost(policy.policy_id).then((host) => {
createdHost = host as CreateAndEnrollEndpointHostResponse;
});
});
})
);
});

beforeEach(() => {
login();
});

after(() => {
if (createdHost) {
cy.task('destroyEndpointHost', createdHost);
}

if (indexedPolicy) {
cy.task('deleteIndexedFleetEndpointPolicies', indexedPolicy);
}

if (createdHost) {
deleteAllLoadedEndpointData({ endpointAgentIds: [createdHost.agentId] });
}
});

describe('From Cases', () => {
let ruleId: string;
let ruleName: string;
let caseId: string;
const caseOwner = 'securitySolution';

beforeEach(() => {
loadRule(
{ query: `agent.name: ${createdHost.hostname} and agent.type: endpoint` },
false
).then((data) => {
ruleId = data.id;
ruleName = data.name;
});
loadCase(caseOwner).then((data) => {
caseId = data.id;
});
});

afterEach(() => {
if (ruleId) {
cleanupRule(ruleId);
}
if (caseId) {
cleanupCase(caseId);
}
});

it('should open responder', () => {
waitForEndpointListPageToBeLoaded(createdHost.hostname);
toggleRuleOffAndOn(ruleName);
visitRuleAlerts(ruleName);
closeAllToasts();

getAlertsTableRows().should('have.length.greaterThan', 0);
openAlertDetailsView();
addAlertToCase(caseId, caseOwner);

// visit case details page
cy.intercept('GET', `/api/cases/${caseId}/user_actions/_find*`).as('case');
loadPage(`${APP_CASES_PATH}/${caseId}`);

cy.wait('@case', { timeout: 30000 }).then(({ response: res }) => {
const caseAlertId = res?.body.userActions[1].id;
closeAllToasts();
openCaseAlertDetails(caseAlertId);
});

openResponderFromEndpointAlertDetails();
ensureOnResponder();
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { ensureOnResponder } from '../../screens/responder';
import type { PolicyData } from '../../../../../common/endpoint/types';
import type { CreateAndEnrollEndpointHostResponse } from '../../../../../scripts/endpoint/common/endpoint_host_services';
import {
openResponseConsoleFromEndpointList,
waitForEndpointListPageToBeLoaded,
} from '../../tasks/response_console';
import type { IndexedFleetEndpointPolicyResponse } from '../../../../../common/endpoint/data_loaders/index_fleet_endpoint_policy';
import { createAgentPolicyTask, getEndpointIntegrationVersion } from '../../tasks/fleet';

import { login } from '../../tasks/login';
import { enableAllPolicyProtections } from '../../tasks/endpoint_policy';
import { createEndpointHost } from '../../tasks/create_endpoint_host';
import { deleteAllLoadedEndpointData } from '../../tasks/delete_all_endpoint_data';

describe('Response console', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => {
beforeEach(() => {
login();
});

describe('From endpoint list', () => {
let indexedPolicy: IndexedFleetEndpointPolicyResponse;
let policy: PolicyData;
let createdHost: CreateAndEnrollEndpointHostResponse;

before(() => {
getEndpointIntegrationVersion().then((version) =>
createAgentPolicyTask(version).then((data) => {
indexedPolicy = data;
policy = indexedPolicy.integrationPolicies[0];

return enableAllPolicyProtections(policy.id).then(() => {
// Create and enroll a new Endpoint host
return createEndpointHost(policy.policy_id).then((host) => {
createdHost = host as CreateAndEnrollEndpointHostResponse;
});
});
})
);
});

after(() => {
if (createdHost) {
cy.task('destroyEndpointHost', createdHost);
}

if (indexedPolicy) {
cy.task('deleteIndexedFleetEndpointPolicies', indexedPolicy);
}

if (createdHost) {
deleteAllLoadedEndpointData({ endpointAgentIds: [createdHost.agentId] });
}
});

it('should open responder', () => {
waitForEndpointListPageToBeLoaded(createdHost.hostname);
openResponseConsoleFromEndpointList();
ensureOnResponder();
});
});
});
Loading

0 comments on commit ffcad9e

Please sign in to comment.