mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
# Backport This will backport the following commits from `main` to `8.8`: - [[Defend Workflows][E2E]Get file command from response console (#156159)](https://github.com/elastic/kibana/pull/156159) <!--- Backport version: 8.9.7 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Konrad Szwarc","email":"konrad.szwarc@elastic.co"},"sourceCommit":{"committedDate":"2023-05-16T17:55:57Z","message":"[Defend Workflows][E2E]Get file command from response console (#156159)\n\nThis PR tackles `get-file` command issued from response console. Two\r\ntests are included:\r\n1.\r\n`x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/response_console.cy.ts`\r\nmocked data\r\n2.\r\n`x-pack/plugins/security_solution/public/management/cypress/e2e/endpoint/response_console.cy.ts`\r\nreal endpoint\r\n\r\n---------\r\n\r\nCo-authored-by: Patryk Kopycinski <contact@patrykkopycinski.com>","sha":"cf6f350ed21eb86053e54005a5d59b1ff64a2d0d","branchLabelMapping":{"^v8.9.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","Team:Defend Workflows","v8.8.0","v8.9.0"],"number":156159,"url":"https://github.com/elastic/kibana/pull/156159","mergeCommit":{"message":"[Defend Workflows][E2E]Get file command from response console (#156159)\n\nThis PR tackles `get-file` command issued from response console. Two\r\ntests are included:\r\n1.\r\n`x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/response_console.cy.ts`\r\nmocked data\r\n2.\r\n`x-pack/plugins/security_solution/public/management/cypress/e2e/endpoint/response_console.cy.ts`\r\nreal endpoint\r\n\r\n---------\r\n\r\nCo-authored-by: Patryk Kopycinski <contact@patrykkopycinski.com>","sha":"cf6f350ed21eb86053e54005a5d59b1ff64a2d0d"}},"sourceBranch":"main","suggestedTargetBranches":["8.8"],"targetPullRequestStates":[{"branch":"8.8","label":"v8.8.0","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v8.9.0","labelRegex":"^v8.9.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/156159","number":156159,"mergeCommit":{"message":"[Defend Workflows][E2E]Get file command from response console (#156159)\n\nThis PR tackles `get-file` command issued from response console. Two\r\ntests are included:\r\n1.\r\n`x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/response_console.cy.ts`\r\nmocked data\r\n2.\r\n`x-pack/plugins/security_solution/public/management/cypress/e2e/endpoint/response_console.cy.ts`\r\nreal endpoint\r\n\r\n---------\r\n\r\nCo-authored-by: Patryk Kopycinski <contact@patrykkopycinski.com>","sha":"cf6f350ed21eb86053e54005a5d59b1ff64a2d0d"}}]}] BACKPORT--> Co-authored-by: Ashokaditya <1849116+ashokaditya@users.noreply.github.com>
This commit is contained in:
parent
a47810d7c8
commit
f97c2cc0cd
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`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
// / <reference types="cypress" />
|
||||
|
||||
import execa from 'execa';
|
||||
import type { CasePostRequest } from '@kbn/cases-plugin/common/api';
|
||||
import {
|
||||
sendEndpointActionResponse,
|
||||
|
@ -227,6 +228,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