Skip to content

Commit

Permalink
[EDR Workflows][MKI][Osquery] Osquery Cypress tests in MKI (#190675)
Browse files Browse the repository at this point in the history
This PR introduces osquery Cypress tests to the MKI environment. These
tests will be executed within the **Kibana / Serverless / Security
Solution Quality Gate / Defend Workflows** scope. You can find an
example of the build here: [Buildkite
Example](https://buildkite.com/elastic/kibana-serverless-security-solution-quality-gate-defend-workflows/builds/1049).

The main challenge with running osquery tests in MKI is that we cannot
continuously log in users as we do in other environments. This is due to
an issue where users are logged out when switching apps. To address
this, I've added a simple check in the login method to prevent the login
function from being called unnecessarily in MKI. This is a temporary
solution until we can properly log in users via API calls using
authentication tokens.

All the `chalk` & `log.indent` changes were made to make logs more
beautiful 😸
![Screenshot 2024-08-09 at 13 00
50](https://github.com/user-attachments/assets/a113e2a2-7e9c-42f0-800d-4883de8a34d2)

---------

Co-authored-by: kibanamachine <[email protected]>
  • Loading branch information
szwarckonrad and kibanamachine authored Aug 20, 2024
1 parent 69a842e commit 7027b0b
Show file tree
Hide file tree
Showing 24 changed files with 320 additions and 142 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ steps:
- group: "Cypress MKI - Defend Workflows"
key: cypress_test_defend_workflows
steps:
- label: "Running cypress:dw:qa:serverless:run"
- label: "Cypress - DW - Running cypress:dw:qa:serverless:run"
command: .buildkite/scripts/pipelines/security_solution_quality_gate/edr_workflows/mki_security_solution_defend_workflows.sh cypress:dw:qa:serverless:run
key: test_defend_workflows
agents:
Expand All @@ -14,7 +14,7 @@ steps:
localSsdInterface: nvme
machineType: n2-standard-4
timeout_in_minutes: 300
parallelism: 6
parallelism: 5
retry:
automatic:
- exit_status: "*"
Expand Down Expand Up @@ -91,7 +91,7 @@ steps:
# - exit_status: "1"
# limit: 1

- label: "Running edr_workflows:policy_response:qa:serverless"
- label: "API - DW - Running edr_workflows:policy_response:qa:serverless"
command: .buildkite/scripts/pipelines/security_solution_quality_gate/api_integration/api-integration-tests.sh edr_workflows:policy_response:qa:serverless
key: edr_workflows:policy_response:qa:serverless
agents:
Expand All @@ -108,7 +108,7 @@ steps:
- exit_status: "1"
limit: 1

- label: "Running edr_workflows:resolver:qa:serverless"
- label: "API - DW - Running edr_workflows:resolver:qa:serverless"
command: .buildkite/scripts/pipelines/security_solution_quality_gate/api_integration/api-integration-tests.sh edr_workflows:resolver:qa:serverless
key: edr_workflows:resolver:qa:serverless
agents:
Expand All @@ -125,7 +125,7 @@ steps:
- exit_status: "1"
limit: 1

- label: "Running edr_workflows:response_actions:qa:serverless"
- label: "API - DW - Running edr_workflows:response_actions:qa:serverless"
command: .buildkite/scripts/pipelines/security_solution_quality_gate/api_integration/api-integration-tests.sh edr_workflows:response_actions:qa:serverless
key: edr_workflows:response_actions:qa:serverless
agents:
Expand All @@ -141,3 +141,24 @@ steps:
automatic:
- exit_status: "1"
limit: 1

- group: "Osquery MKI - Defend Workflows"
key: cypress_test_osquery_defend_workflows
steps:
- label: "Osquery - Cypress - DW - Running cypress:qa:serverless:run"
command: .buildkite/scripts/pipelines/security_solution_quality_gate/edr_workflows/mki_security_solution_defend_workflows_osquery.sh cypress:qa:serverless:run
key: test_osquery_defend_workflows
agents:
image: family/kibana-ubuntu-2004
imageProject: elastic-images-prod
provider: gcp
enableNestedVirtualization: true
localSsds: 1
localSsdInterface: nvme
machineType: n2-standard-4
timeout_in_minutes: 300
parallelism: 3
retry:
automatic:
- exit_status: "*"
limit: 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/bin/bash

set -euo pipefail

if [ -z "$1" ]
then
echo "No target script from the package.json file, is supplied"
exit 1
fi


source .buildkite/scripts/common/util.sh
.buildkite/scripts/bootstrap.sh

export JOB=kibana-defend-workflows-osquery-serverless-cypress

buildkite-agent meta-data set "${BUILDKITE_JOB_ID}_is_test_execution_step" "true"

source .buildkite/scripts/pipelines/security_solution_quality_gate/prepare_vault_entries.sh

cd x-pack/plugins/osquery
set +e

export BK_ANALYTICS_API_KEY=$(vault_get security-solution-quality-gate serverless-cypress-defend-workflows)

echo "--- Running the tests for target $1"
BK_ANALYTICS_API_KEY=$BK_ANALYTICS_API_KEY yarn $1; status=$?; yarn junit:merge || :; exit $status
65 changes: 10 additions & 55 deletions x-pack/plugins/osquery/cypress/cypress.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,60 +7,15 @@

import { defineCypressConfig } from '@kbn/cypress-config';

import path from 'path';
import { safeLoad as loadYaml } from 'js-yaml';
import { readFileSync } from 'fs';
import { getCypressBaseConfig } from './cypress_base.config';

import type { YamlRoleDefinitions } from '@kbn/test-suites-serverless/shared/lib';
import { setupUserDataLoader } from '@kbn/test-suites-serverless/functional/test_suites/security/cypress/support/setup_data_loader_tasks';
import { getFailedSpecVideos } from './support/filter_videos';
const ROLES_YAML_FILE_PATH = path.join(
`${__dirname}/support`,
'project_controller_osquery_roles.yml'
);
const roleDefinitions = loadYaml(readFileSync(ROLES_YAML_FILE_PATH, 'utf8')) as YamlRoleDefinitions;

export default defineCypressConfig({
reporter: '../../../node_modules/cypress-multi-reporters',
reporterOptions: {
configFile: './cypress/reporter_config.json',
},

defaultCommandTimeout: 60000,
execTimeout: 120000,
pageLoadTimeout: 12000,

retries: {
runMode: 1,
openMode: 0,
},

screenshotsFolder: '../../../target/kibana-osquery/cypress/screenshots',
trashAssetsBeforeRuns: false,
video: true,
videosFolder: '../../../target/kibana-osquery/cypress/videos',
videoCompression: 15,
viewportHeight: 900,
viewportWidth: 1440,
experimentalStudio: true,

env: {
grepFilterSpecs: true,
grepTags: '@ess',
grepOmitFiltered: true,
},

e2e: {
specPattern: './cypress/e2e/**/*.cy.ts',
baseUrl: 'http://localhost:5601',
experimentalRunAllSpecs: true,
experimentalMemoryManagement: true,
numTestsKeptInMemory: 3,
setupNodeEvents(on, config) {
setupUserDataLoader(on, config, { roleDefinitions, additionalRoleName: 'viewer' });
on('after:spec', getFailedSpecVideos);

return config;
export default defineCypressConfig(
getCypressBaseConfig({
env: {
grepTags: '@ess',
},
},
});
e2e: {
baseUrl: 'http://localhost:5601',
},
})
);
70 changes: 70 additions & 0 deletions x-pack/plugins/osquery/cypress/cypress_base.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* 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 { merge } from 'lodash';
import path from 'path';
import { safeLoad as loadYaml } from 'js-yaml';
import { readFileSync } from 'fs';
import type { YamlRoleDefinitions } from '@kbn/test-suites-serverless/shared/lib';
import { setupUserDataLoader } from '@kbn/test-suites-serverless/functional/test_suites/security/cypress/support/setup_data_loader_tasks';
import { samlAuthentication } from '@kbn/security-solution-plugin/public/management/cypress/support/saml_authentication';
import { getFailedSpecVideos } from './support/filter_videos';

const ROLES_YAML_FILE_PATH = path.join(
`${__dirname}/support`,
'project_controller_osquery_roles.yml'
);
const roleDefinitions = loadYaml(readFileSync(ROLES_YAML_FILE_PATH, 'utf8')) as YamlRoleDefinitions;

export const getCypressBaseConfig = (
overrides: Cypress.ConfigOptions = {}
): Cypress.ConfigOptions =>
merge(
{
reporter: '../../../node_modules/cypress-multi-reporters',
reporterOptions: {
configFile: './cypress/reporter_config.json',
},

defaultCommandTimeout: 60000,
execTimeout: 120000,
pageLoadTimeout: 12000,
screenshotsFolder: '../../../target/kibana-osquery/cypress/screenshots',
trashAssetsBeforeRuns: false,
video: true,
videosFolder: '../../../target/kibana-osquery/cypress/videos',

retries: {
runMode: 1,
openMode: 0,
},
videoCompression: 15,
viewportHeight: 900,
viewportWidth: 1440,
experimentalStudio: true,

env: {
grepFilterSpecs: true,
grepOmitFiltered: true,
},

e2e: {
specPattern: './cypress/e2e/**/*.cy.ts',
experimentalRunAllSpecs: true,
experimentalMemoryManagement: true,
numTestsKeptInMemory: 3,
setupNodeEvents(on: Cypress.PluginEvents, config: Cypress.PluginConfigOptions) {
setupUserDataLoader(on, config, { roleDefinitions, additionalRoleName: 'viewer' });
samlAuthentication(on, config);
on('after:spec', getFailedSpecVideos);

return config;
},
},
},
overrides
);
8 changes: 3 additions & 5 deletions x-pack/plugins/osquery/cypress/e2e/all/alerts_cases.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,9 @@ describe('Alert Event Details - Cases', { tags: ['@ess', '@serverless'] }, () =>
let packId: string;
let packName: string;
const packData = packFixture();
before(() => {
initializeDataViews();
});

beforeEach(() => {
initializeDataViews();
loadPack(packData).then((data) => {
packId = data.saved_object_id;
packName = data.name;
Expand Down Expand Up @@ -89,13 +87,13 @@ describe('Alert Event Details - Cases', { tags: ['@ess', '@serverless'] }, () =>
describe('Case', () => {
let caseId: string;

before(() => {
beforeEach(() => {
loadCase('securitySolution').then((data) => {
caseId = data.id;
});
});

after(() => {
afterEach(() => {
cleanupCase(caseId);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { RESULTS_TABLE, RESULTS_TABLE_BUTTON } from '../../screens/live_query';
describe(
'Alert Event Details',
{
tags: ['@ess', '@serverless'],
tags: ['@ess', '@serverless', '@skipInServerlessMKI'],
},
() => {
let ruleId: string;
Expand Down
6 changes: 3 additions & 3 deletions x-pack/plugins/osquery/cypress/e2e/all/cases.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* 2.0.
*/

import { ServerlessRoleName } from '../../support/roles';
import { initializeDataViews } from '../../tasks/login';
import {
addLiveQueryToCase,
Expand All @@ -13,7 +14,6 @@ import {
} from '../../tasks/live_query';
import { navigateTo } from '../../tasks/navigation';
import { loadLiveQuery, loadCase, cleanupCase } from '../../tasks/api_fixtures';
import { ServerlessRoleName } from '../../support/roles';

describe('Add to Cases', () => {
let liveQueryId: string;
Expand All @@ -38,7 +38,7 @@ describe('Add to Cases', () => {
caseId = caseInfo.id;
caseTitle = caseInfo.title;
});
cy.login(ServerlessRoleName.SOC_MANAGER);
cy.login(ServerlessRoleName.SOC_MANAGER, false);
navigateTo('/app/osquery');
});

Expand Down Expand Up @@ -70,7 +70,7 @@ describe('Add to Cases', () => {
caseId = caseInfo.id;
caseTitle = caseInfo.title;
});
cy.login(ServerlessRoleName.SOC_MANAGER);
cy.login(ServerlessRoleName.SOC_MANAGER, false);
navigateTo('/app/osquery');
});

Expand Down
7 changes: 1 addition & 6 deletions x-pack/plugins/osquery/cypress/e2e/all/ecs_mappings.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,10 @@ import {
typeInECSFieldInput,
typeInOsqueryFieldInput,
} from '../../tasks/live_query';
import { ServerlessRoleName } from '../../support/roles';

describe('EcsMapping', { tags: ['@ess', '@serverless'] }, () => {
before(() => {
initializeDataViews();
});

beforeEach(() => {
cy.login(ServerlessRoleName.SOC_MANAGER);
initializeDataViews();
});

it('should properly show static values in form and results', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { checkOsqueryResponseActionsPermissions } from '../../tasks/response_act
describe(
'App Features for Security Complete PLI',
{
tags: ['@serverless'],
tags: ['@serverless', '@skipInServerlessMKI'],
env: {
ftrConfig: {
productTypes: [{ product_line: 'security', product_tier: 'complete' }],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ describe(
{
tags: ['@serverless'],
env: {
ftrConfig: { productTypes: [{ product_line: 'security', product_tier: 'essentials' }] },
ftrConfig: {
productTypes: [
{ product_line: 'security', product_tier: 'essentials' },
{ product_line: 'endpoint', product_tier: 'essentials' },
],
},
},
},
() => checkOsqueryResponseActionsPermissions(false)
Expand Down
Loading

0 comments on commit 7027b0b

Please sign in to comment.