mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[Defend Workflows][E2E]Get file command from response console (#156159)
This PR tackles `get-file` command issued from response console. Two tests are included: 1. `x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/response_console.cy.ts` mocked data 2. `x-pack/plugins/security_solution/public/management/cypress/e2e/endpoint/response_console.cy.ts` real endpoint --------- Co-authored-by: Patryk Kopycinski <contact@patrykkopycinski.com>
This commit is contained in:
parent
82108060e7
commit
cf6f350ed2
4 changed files with 206 additions and 0 deletions
|
@ -145,6 +145,30 @@ declare global {
|
|||
arg: { endpointAgentIds: string[] },
|
||||
options?: Partial<Loggable & Timeoutable>
|
||||
): Chainable<DeleteAllEndpointDataResponse>;
|
||||
|
||||
task(
|
||||
name: 'createFileOnEndpoint',
|
||||
arg: { hostname: string; path: string; content: string },
|
||||
options?: Partial<Loggable & Timeoutable>
|
||||
): Chainable<null>;
|
||||
|
||||
task(
|
||||
name: 'uploadFileToEndpoint',
|
||||
arg: { hostname: string; srcPath: string; destPath: string },
|
||||
options?: Partial<Loggable & Timeoutable>
|
||||
): Chainable<null>;
|
||||
|
||||
task(
|
||||
name: 'installPackagesOnEndpoint',
|
||||
arg: { hostname: string; packages: string[] },
|
||||
options?: Partial<Loggable & Timeoutable>
|
||||
): Chainable<null>;
|
||||
|
||||
task(
|
||||
name: 'readZippedFileContentOnEndpoint',
|
||||
arg: { hostname: string; path: string; password?: string },
|
||||
options?: Partial<Loggable & Timeoutable>
|
||||
): Chainable<string>;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -168,6 +168,74 @@ describe('Response console', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('User journey for Get file command', () => {
|
||||
let response: IndexedFleetEndpointPolicyResponse;
|
||||
let initialAgentData: Agent;
|
||||
|
||||
const fileContent = 'This is a test file for the get-file command.';
|
||||
const filePath = `/home/ubuntu/test_file.txt`;
|
||||
|
||||
before(() => {
|
||||
getAgentByHostName(endpointHostname).then((agentData) => {
|
||||
initialAgentData = agentData;
|
||||
});
|
||||
|
||||
getEndpointIntegrationVersion().then((version) =>
|
||||
createAgentPolicyTask(version).then((data) => {
|
||||
response = data;
|
||||
})
|
||||
);
|
||||
|
||||
cy.task('installPackagesOnEndpoint', { hostname: endpointHostname, packages: ['unzip'] });
|
||||
|
||||
cy.task('createFileOnEndpoint', {
|
||||
hostname: endpointHostname,
|
||||
path: filePath,
|
||||
content: fileContent,
|
||||
});
|
||||
});
|
||||
|
||||
after(() => {
|
||||
if (initialAgentData?.policy_id) {
|
||||
reassignAgentPolicy(initialAgentData.id, initialAgentData.policy_id);
|
||||
}
|
||||
if (response) {
|
||||
cy.task('deleteIndexedFleetEndpointPolicies', response);
|
||||
}
|
||||
});
|
||||
|
||||
it('"get-file --path" - should retrieve a file', () => {
|
||||
waitForEndpointListPageToBeLoaded(endpointHostname);
|
||||
openResponseConsoleFromEndpointList();
|
||||
inputConsoleCommand(`get-file --path ${filePath}`);
|
||||
submitCommand();
|
||||
cy.getByTestSubj('getFileSuccess', { timeout: 60000 }).within(() => {
|
||||
cy.contains('File retrieved from the host.');
|
||||
cy.contains('(ZIP file passcode: elastic)');
|
||||
cy.contains(
|
||||
'Files are periodically deleted to clear storage space. Download and save file locally if needed.'
|
||||
);
|
||||
cy.contains('Click here to download').click();
|
||||
const downloadsFolder = Cypress.config('downloadsFolder');
|
||||
cy.readFile(`${downloadsFolder}/upload.zip`);
|
||||
|
||||
cy.task('uploadFileToEndpoint', {
|
||||
hostname: endpointHostname,
|
||||
srcPath: `${downloadsFolder}/upload.zip`,
|
||||
destPath: '/home/ubuntu/upload.zip',
|
||||
});
|
||||
|
||||
cy.task('readZippedFileContentOnEndpoint', {
|
||||
hostname: endpointHostname,
|
||||
path: '/home/ubuntu/upload.zip',
|
||||
password: 'elastic',
|
||||
}).then((unzippedFileContent) => {
|
||||
expect(unzippedFileContent).to.equal(fileContent);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('document signing', () => {
|
||||
let response: IndexedFleetEndpointPolicyResponse;
|
||||
let initialAgentData: Agent;
|
||||
|
|
|
@ -227,4 +227,53 @@ describe('Response console', () => {
|
|||
cy.contains('Action completed.', { timeout: 120000 }).should('exist');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Get file command', () => {
|
||||
let endpointData: ReturnTypeFromChainable<typeof indexEndpointHosts>;
|
||||
let endpointHostname: string;
|
||||
let getFileRequestResponse: ActionDetails;
|
||||
|
||||
before(() => {
|
||||
indexEndpointHosts({ withResponseActions: false, isolation: false }).then(
|
||||
(indexEndpoints) => {
|
||||
endpointData = indexEndpoints;
|
||||
endpointHostname = endpointData.data.hosts[0].host.name;
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
after(() => {
|
||||
if (endpointData) {
|
||||
endpointData.cleanup();
|
||||
// @ts-expect-error ignore setting to undefined
|
||||
endpointData = undefined;
|
||||
}
|
||||
});
|
||||
|
||||
it('should get file from response console', () => {
|
||||
waitForEndpointListPageToBeLoaded(endpointHostname);
|
||||
openResponseConsoleFromEndpointList();
|
||||
inputConsoleCommand(`get-file --path /test/path/test.txt`);
|
||||
|
||||
interceptActionRequests((responseBody) => {
|
||||
getFileRequestResponse = responseBody;
|
||||
}, 'get-file');
|
||||
submitCommand();
|
||||
cy.contains('Retrieving the file from host.').should('exist');
|
||||
cy.wait('@get-file').then(() => {
|
||||
sendActionResponse(getFileRequestResponse);
|
||||
});
|
||||
cy.getByTestSubj('getFileSuccess').within(() => {
|
||||
cy.contains('File retrieved from the host.');
|
||||
cy.contains('(ZIP file passcode: elastic)');
|
||||
cy.contains(
|
||||
'Files are periodically deleted to clear storage space. Download and save file locally if needed.'
|
||||
);
|
||||
cy.contains('Click here to download').click();
|
||||
});
|
||||
|
||||
const downloadsFolder = Cypress.config('downloadsFolder');
|
||||
cy.readFile(`${downloadsFolder}/upload.zip`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
// / <reference types="cypress" />
|
||||
|
||||
import type { CasePostRequest } from '@kbn/cases-plugin/common/api';
|
||||
import execa from 'execa';
|
||||
import {
|
||||
sendEndpointActionResponse,
|
||||
sendFleetActionResponse,
|
||||
|
@ -224,6 +225,70 @@ export const dataLoadersForRealEndpoints = (
|
|||
return destroyEndpointHost(kbnClient, createdHost).then(() => null);
|
||||
},
|
||||
|
||||
createFileOnEndpoint: async ({
|
||||
hostname,
|
||||
path,
|
||||
content,
|
||||
}: {
|
||||
hostname: string;
|
||||
path: string;
|
||||
content: string;
|
||||
}): Promise<null> => {
|
||||
await execa(`multipass`, ['exec', hostname, '--', 'sh', '-c', `echo ${content} > ${path}`]);
|
||||
return null;
|
||||
},
|
||||
|
||||
uploadFileToEndpoint: async ({
|
||||
hostname,
|
||||
srcPath,
|
||||
destPath = '.',
|
||||
}: {
|
||||
hostname: string;
|
||||
srcPath: string;
|
||||
destPath: string;
|
||||
}): Promise<null> => {
|
||||
await execa(`multipass`, ['transfer', srcPath, `${hostname}:${destPath}`]);
|
||||
return null;
|
||||
},
|
||||
|
||||
installPackagesOnEndpoint: async ({
|
||||
hostname,
|
||||
packages,
|
||||
}: {
|
||||
hostname: string;
|
||||
packages: string[];
|
||||
}): Promise<null> => {
|
||||
await execa(`multipass`, [
|
||||
'exec',
|
||||
hostname,
|
||||
'--',
|
||||
'sh',
|
||||
'-c',
|
||||
`sudo apt install -y ${packages.join(' ')}`,
|
||||
]);
|
||||
return null;
|
||||
},
|
||||
|
||||
readZippedFileContentOnEndpoint: async ({
|
||||
hostname,
|
||||
path,
|
||||
password,
|
||||
}: {
|
||||
hostname: string;
|
||||
path: string;
|
||||
password?: string;
|
||||
}): Promise<string> => {
|
||||
const result = await execa(`multipass`, [
|
||||
'exec',
|
||||
hostname,
|
||||
'--',
|
||||
'sh',
|
||||
'-c',
|
||||
`unzip -p ${password ? `-P ${password} ` : ''}${path}`,
|
||||
]);
|
||||
return result.stdout;
|
||||
},
|
||||
|
||||
stopEndpointHost: async () => {
|
||||
const hosts = await getEndpointHosts();
|
||||
const hostName = hosts[0].name;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue