mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 01:13:23 -04:00
# Backport This will backport the following commits from `main` to `8.10`: - [[Security Solution] Unskip related integrations tests (#164933)](https://github.com/elastic/kibana/pull/164933) <!--- Backport version: 8.9.8 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Maxim Palenov","email":"maxim.palenov@elastic.co"},"sourceCommit":{"committedDate":"2023-08-31T10:28:16Z","message":"[Security Solution] Unskip related integrations tests (#164933)\n\n**Fixes: https://github.com/elastic/kibana/issues/154663**\r\n**Fixes: https://github.com/elastic/kibana/issues/153684**\r\n\r\n## Summary\r\n\r\nThis PR unskips Cypress rule related integration tests ([related_integrations.cy.ts](https://github.com/elastic/kibana/blob/main/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/related_integrations/related_integrations.cy.ts)).\r\n\r\n## Details\r\n\r\nTesting approach has changed. Instead of importing a rule and installing agent and package policies via Fleet UI the rule is created by mocking a prebuilt rule asset and Fleet API is used to install required integrations. Along the way it required to add and update some testing selectors as UI had changed while the tests were skipped.\r\n\r\n## Flaky test runner\r\n\r\n[related_integrations.cy.ts (150 runs)](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/2995) 🟢","sha":"2c3464ca8457e09f51852c6c0d60ab7f6e21afc0","branchLabelMapping":{"^v8.11.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["test","release_note:skip","Team:Detections and Resp","Team: SecuritySolution","Feature:Rule Management","Team:Detection Rule Management","v8.10.0","v8.11.0","flake-docs"],"number":164933,"url":"https://github.com/elastic/kibana/pull/164933","mergeCommit":{"message":"[Security Solution] Unskip related integrations tests (#164933)\n\n**Fixes: https://github.com/elastic/kibana/issues/154663**\r\n**Fixes: https://github.com/elastic/kibana/issues/153684**\r\n\r\n## Summary\r\n\r\nThis PR unskips Cypress rule related integration tests ([related_integrations.cy.ts](https://github.com/elastic/kibana/blob/main/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/related_integrations/related_integrations.cy.ts)).\r\n\r\n## Details\r\n\r\nTesting approach has changed. Instead of importing a rule and installing agent and package policies via Fleet UI the rule is created by mocking a prebuilt rule asset and Fleet API is used to install required integrations. Along the way it required to add and update some testing selectors as UI had changed while the tests were skipped.\r\n\r\n## Flaky test runner\r\n\r\n[related_integrations.cy.ts (150 runs)](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/2995) 🟢","sha":"2c3464ca8457e09f51852c6c0d60ab7f6e21afc0"}},"sourceBranch":"main","suggestedTargetBranches":["8.10"],"targetPullRequestStates":[{"branch":"8.10","label":"v8.10.0","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v8.11.0","labelRegex":"^v8.11.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/164933","number":164933,"mergeCommit":{"message":"[Security Solution] Unskip related integrations tests (#164933)\n\n**Fixes: https://github.com/elastic/kibana/issues/154663**\r\n**Fixes: https://github.com/elastic/kibana/issues/153684**\r\n\r\n## Summary\r\n\r\nThis PR unskips Cypress rule related integration tests ([related_integrations.cy.ts](https://github.com/elastic/kibana/blob/main/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/related_integrations/related_integrations.cy.ts)).\r\n\r\n## Details\r\n\r\nTesting approach has changed. Instead of importing a rule and installing agent and package policies via Fleet UI the rule is created by mocking a prebuilt rule asset and Fleet API is used to install required integrations. Along the way it required to add and update some testing selectors as UI had changed while the tests were skipped.\r\n\r\n## Flaky test runner\r\n\r\n[related_integrations.cy.ts (150 runs)](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/2995) 🟢","sha":"2c3464ca8457e09f51852c6c0d60ab7f6e21afc0"}}]}] BACKPORT-->
This commit is contained in:
parent
638b971055
commit
39b7ebe45d
27 changed files with 563 additions and 261 deletions
|
@ -32,6 +32,7 @@ export const search = {
|
|||
incremental: true,
|
||||
placeholder: i18n.PLACEHOLDER,
|
||||
schema: true,
|
||||
'data-test-subj': 'search-input',
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -527,7 +527,7 @@ const RuleDetailsPageComponent: React.FC<DetectionEngineComponentProps> = ({
|
|||
) : (
|
||||
<RuleStatus status={lastExecutionStatus} date={lastExecutionDate}>
|
||||
<EuiButtonIcon
|
||||
data-test-subj="refreshButton"
|
||||
data-test-subj="ruleLastExecutionStatusRefreshButton"
|
||||
color="primary"
|
||||
onClick={refreshRule}
|
||||
iconType="refresh"
|
||||
|
|
|
@ -108,11 +108,10 @@ import {
|
|||
goToScheduleStepTab,
|
||||
importSavedQuery,
|
||||
waitForAlertsToPopulate,
|
||||
waitForTheRuleToBeExecuted,
|
||||
} from '../../../tasks/create_new_rule';
|
||||
import { saveEditedRule } from '../../../tasks/edit_rule';
|
||||
import { login, visit, visitSecurityDetectionRulesPage } from '../../../tasks/login';
|
||||
import { enablesRule, getDetails } from '../../../tasks/rule_details';
|
||||
import { enablesRule, getDetails, waitForTheRuleToBeExecuted } from '../../../tasks/rule_details';
|
||||
|
||||
import { RULE_CREATION } from '../../../urls/navigation';
|
||||
|
||||
|
|
|
@ -62,11 +62,10 @@ import {
|
|||
fillDefineCustomRuleAndContinue,
|
||||
fillScheduleRuleAndContinue,
|
||||
waitForAlertsToPopulate,
|
||||
waitForTheRuleToBeExecuted,
|
||||
} from '../../../tasks/create_new_rule';
|
||||
|
||||
import { login, visit } from '../../../tasks/login';
|
||||
import { getDetails } from '../../../tasks/rule_details';
|
||||
import { getDetails, waitForTheRuleToBeExecuted } from '../../../tasks/rule_details';
|
||||
|
||||
import { RULE_CREATION } from '../../../urls/navigation';
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ import {
|
|||
TIMELINE_TEMPLATE_DETAILS,
|
||||
} from '../../../screens/rule_details';
|
||||
|
||||
import { getDetails } from '../../../tasks/rule_details';
|
||||
import { getDetails, waitForTheRuleToBeExecuted } from '../../../tasks/rule_details';
|
||||
import {
|
||||
expectNumberOfRules,
|
||||
goToRuleDetails,
|
||||
|
@ -57,7 +57,6 @@ import {
|
|||
fillScheduleRuleAndContinue,
|
||||
selectEqlRuleType,
|
||||
waitForAlertsToPopulate,
|
||||
waitForTheRuleToBeExecuted,
|
||||
} from '../../../tasks/create_new_rule';
|
||||
import { login, visit } from '../../../tasks/login';
|
||||
|
||||
|
|
|
@ -94,7 +94,6 @@ import {
|
|||
getIndicatorOrButton,
|
||||
selectIndicatorMatchType,
|
||||
waitForAlertsToPopulate,
|
||||
waitForTheRuleToBeExecuted,
|
||||
} from '../../../tasks/create_new_rule';
|
||||
import {
|
||||
SCHEDULE_INTERVAL_AMOUNT_INPUT,
|
||||
|
@ -104,7 +103,11 @@ import {
|
|||
} from '../../../screens/create_new_rule';
|
||||
import { goBackToRuleDetails } from '../../../tasks/edit_rule';
|
||||
import { login, visit, visitWithoutDateRange } from '../../../tasks/login';
|
||||
import { goBackToRulesTable, getDetails } from '../../../tasks/rule_details';
|
||||
import {
|
||||
goBackToRulesTable,
|
||||
getDetails,
|
||||
waitForTheRuleToBeExecuted,
|
||||
} from '../../../tasks/rule_details';
|
||||
|
||||
import { DETECTIONS_RULE_MANAGEMENT_URL, RULE_CREATION } from '../../../urls/navigation';
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ import {
|
|||
NEW_TERMS_FIELDS_DETAILS,
|
||||
} from '../../../screens/rule_details';
|
||||
|
||||
import { getDetails } from '../../../tasks/rule_details';
|
||||
import { getDetails, waitForTheRuleToBeExecuted } from '../../../tasks/rule_details';
|
||||
import { expectNumberOfRules, goToRuleDetails } from '../../../tasks/alerts_detection_rules';
|
||||
import { cleanKibana, deleteAlertsAndRules } from '../../../tasks/common';
|
||||
import {
|
||||
|
@ -55,7 +55,6 @@ import {
|
|||
fillScheduleRuleAndContinue,
|
||||
selectNewTermsRuleType,
|
||||
waitForAlertsToPopulate,
|
||||
waitForTheRuleToBeExecuted,
|
||||
} from '../../../tasks/create_new_rule';
|
||||
import { login, visit } from '../../../tasks/login';
|
||||
|
||||
|
|
|
@ -50,16 +50,16 @@ import {
|
|||
} from '../../../screens/rule_details';
|
||||
|
||||
import { expectNumberOfRules, goToRuleDetails } from '../../../tasks/alerts_detection_rules';
|
||||
import { deleteAlertsAndRules } from '../../../tasks/common';
|
||||
import {
|
||||
createAndEnableRule,
|
||||
fillAboutRuleWithOverrideAndContinue,
|
||||
fillDefineCustomRuleAndContinue,
|
||||
fillScheduleRuleAndContinue,
|
||||
waitForAlertsToPopulate,
|
||||
waitForTheRuleToBeExecuted,
|
||||
} from '../../../tasks/create_new_rule';
|
||||
import { login, visitWithoutDateRange } from '../../../tasks/login';
|
||||
import { getDetails } from '../../../tasks/rule_details';
|
||||
import { getDetails, waitForTheRuleToBeExecuted } from '../../../tasks/rule_details';
|
||||
|
||||
import { RULE_CREATION } from '../../../urls/navigation';
|
||||
|
||||
|
@ -73,6 +73,7 @@ describe('Detection rules, override', { tags: [tag.ESS, tag.BROKEN_IN_SERVERLESS
|
|||
|
||||
beforeEach(() => {
|
||||
login();
|
||||
deleteAlertsAndRules();
|
||||
});
|
||||
|
||||
it('Creates and enables a new custom rule with override option', function () {
|
||||
|
|
|
@ -45,7 +45,7 @@ import {
|
|||
TIMELINE_TEMPLATE_DETAILS,
|
||||
} from '../../../screens/rule_details';
|
||||
|
||||
import { getDetails } from '../../../tasks/rule_details';
|
||||
import { getDetails, waitForTheRuleToBeExecuted } from '../../../tasks/rule_details';
|
||||
import { expectNumberOfRules, goToRuleDetails } from '../../../tasks/alerts_detection_rules';
|
||||
import { cleanKibana, deleteAlertsAndRules } from '../../../tasks/common';
|
||||
import {
|
||||
|
@ -55,7 +55,6 @@ import {
|
|||
fillScheduleRuleAndContinue,
|
||||
selectThresholdRuleType,
|
||||
waitForAlertsToPopulate,
|
||||
waitForTheRuleToBeExecuted,
|
||||
} from '../../../tasks/create_new_rule';
|
||||
import { login, visitWithoutDateRange } from '../../../tasks/login';
|
||||
|
||||
|
|
|
@ -5,241 +5,406 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { PerformRuleInstallationResponseBody } from '@kbn/security-solution-plugin/common/api/detection_engine';
|
||||
import { omit } from 'lodash';
|
||||
import { tag } from '../../../../tags';
|
||||
|
||||
import { DETECTIONS_RULE_MANAGEMENT_URL } from '../../../../urls/navigation';
|
||||
|
||||
import { filterBy, openTable } from '../../../../tasks/rule_details_flyout';
|
||||
import { generateEvent } from '../../../../objects/event';
|
||||
import { createDocument, deleteDataStream } from '../../../../tasks/api_calls/elasticsearch';
|
||||
import { FIELD } from '../../../../screens/alerts_details';
|
||||
import { INTEGRATIONS, INTEGRATIONS_STATUS } from '../../../../screens/rule_details';
|
||||
import { INTEGRATION_LINK, INTEGRATION_STATUS } from '../../../../screens/rule_details';
|
||||
import {
|
||||
INTEGRATIONS_POPOVER,
|
||||
INTEGRATIONS_POPOVER_TITLE,
|
||||
RULE_NAME,
|
||||
} from '../../../../screens/alerts_detection_rules';
|
||||
|
||||
import {
|
||||
installPrebuiltRuleAssets,
|
||||
installAllPrebuiltRulesRequest,
|
||||
SAMPLE_PREBUILT_RULE,
|
||||
} from '../../../../tasks/api_calls/prebuilt_rules';
|
||||
import { cleanFleet } from '../../../../tasks/api_calls/fleet';
|
||||
import { importRule } from '../../../../tasks/api_calls/rules';
|
||||
import {
|
||||
disableRelatedIntegrations,
|
||||
enableRelatedIntegrations,
|
||||
} from '../../../../tasks/api_calls/kibana_advanced_settings';
|
||||
|
||||
import { cleanKibana } from '../../../../tasks/common';
|
||||
import { login, visit } from '../../../../tasks/login';
|
||||
import { expandFirstAlert } from '../../../../tasks/alerts';
|
||||
import { filterBy, openTable } from '../../../../tasks/alerts_details';
|
||||
import { waitForAlertsToPopulate } from '../../../../tasks/create_new_rule';
|
||||
import { installAwsCloudFrontWithPolicy } from '../../../../tasks/integrations';
|
||||
import { deleteAlertsAndRules } from '../../../../tasks/common';
|
||||
import {
|
||||
enableRule,
|
||||
goToTheRuleDetailsOf,
|
||||
login,
|
||||
visitSecurityDetectionRulesPage,
|
||||
visitWithoutDateRange,
|
||||
} from '../../../../tasks/login';
|
||||
import { expandFirstAlert } from '../../../../tasks/alerts';
|
||||
import { waitForAlertsToPopulate } from '../../../../tasks/create_new_rule';
|
||||
import {
|
||||
installIntegrations,
|
||||
PackagePolicyWithoutAgentPolicyId,
|
||||
} from '../../../../tasks/integrations';
|
||||
import {
|
||||
disableAutoRefresh,
|
||||
openIntegrationsPopover,
|
||||
waitForRulesTableToShow,
|
||||
waitForRuleToUpdate,
|
||||
} from '../../../../tasks/alerts_detection_rules';
|
||||
|
||||
/*
|
||||
Note that the rule we are using for testing purposes has the following characteristics, changing that may affect the coverage.
|
||||
|
||||
- Single-integration
|
||||
- Package: system
|
||||
- Multi-integration package
|
||||
- Package: aws
|
||||
- Integration: cloudtrail
|
||||
- Integration: cloudfront
|
||||
- Not existing package:
|
||||
- Package: unknown
|
||||
- Not existing integration & existing package:
|
||||
- Package: aws
|
||||
- Integration: unknown
|
||||
*/
|
||||
import { ruleDetailsUrl } from '../../../../urls/navigation';
|
||||
import { enablesRule, waitForPageToBeLoaded } from '../../../../tasks/rule_details';
|
||||
import { createRuleAssetSavedObject } from '../../../../helpers/rules';
|
||||
|
||||
describe('Related integrations', { tags: [tag.ESS, tag.BROKEN_IN_SERVERLESS] }, () => {
|
||||
before(() => {
|
||||
cleanKibana();
|
||||
const DATA_STREAM_NAME = 'logs-related-integrations-test';
|
||||
const PREBUILT_RULE_NAME = 'Prebuilt rule with related integrations';
|
||||
const RULE_RELATED_INTEGRATIONS: IntegrationDefinition[] = [
|
||||
{
|
||||
package: 'aws',
|
||||
version: '1.17.0',
|
||||
integration: 'cloudfront',
|
||||
installed: true,
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
package: 'aws',
|
||||
version: '1.17.0',
|
||||
integration: 'cloudtrail',
|
||||
installed: true,
|
||||
enabled: false,
|
||||
},
|
||||
{ package: 'aws', version: '1.17.0', integration: 'unknown', installed: false, enabled: false },
|
||||
{ package: 'system', version: '1.17.0', installed: true, enabled: true },
|
||||
];
|
||||
const PREBUILT_RULE = createRuleAssetSavedObject({
|
||||
name: PREBUILT_RULE_NAME,
|
||||
index: [DATA_STREAM_NAME],
|
||||
query: '*:*',
|
||||
rule_id: 'rule_1',
|
||||
related_integrations: RULE_RELATED_INTEGRATIONS.map((x) => omit(x, ['installed', 'enabled'])),
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
login();
|
||||
importRule('related_integrations.ndjson');
|
||||
cleanFleet();
|
||||
deleteAlertsAndRules();
|
||||
addAndInstallPrebuiltRules([PREBUILT_RULE]);
|
||||
});
|
||||
|
||||
context('integrations not installed', () => {
|
||||
const rule = {
|
||||
name: 'Related integrations rule',
|
||||
integrations: ['Aws Cloudfront', 'Aws Cloudtrail', 'Aws Unknown', 'System'],
|
||||
enabledIntegrations: '0',
|
||||
};
|
||||
|
||||
before(() => {
|
||||
cleanFleet();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
login();
|
||||
visit(DETECTIONS_RULE_MANAGEMENT_URL);
|
||||
waitForRulesTableToShow();
|
||||
});
|
||||
|
||||
it('should display a badge with the installed integrations on the rule management page', () => {
|
||||
cy.get(INTEGRATIONS_POPOVER).should(
|
||||
'have.text',
|
||||
`${rule.enabledIntegrations}/${rule.integrations.length} integrations`
|
||||
);
|
||||
});
|
||||
|
||||
it('should display a popover when clicking the badge with the installed integrations on the rule management page', () => {
|
||||
openIntegrationsPopover();
|
||||
|
||||
cy.get(INTEGRATIONS_POPOVER_TITLE).should(
|
||||
'have.text',
|
||||
`[${rule.integrations.length}] Related integrations available`
|
||||
);
|
||||
cy.get(INTEGRATIONS).should('have.length', rule.integrations.length);
|
||||
cy.get(INTEGRATIONS_STATUS).should('have.length', rule.integrations.length);
|
||||
|
||||
rule.integrations.forEach((integration, index) => {
|
||||
cy.get(INTEGRATIONS).eq(index).should('contain', integration);
|
||||
cy.get(INTEGRATIONS_STATUS).eq(index).should('have.text', 'Not installed');
|
||||
});
|
||||
});
|
||||
|
||||
it('should display the integrations on the definition section', () => {
|
||||
goToTheRuleDetailsOf(rule.name);
|
||||
|
||||
cy.get(INTEGRATIONS).should('have.length', rule.integrations.length);
|
||||
cy.get(INTEGRATIONS_STATUS).should('have.length', rule.integrations.length);
|
||||
|
||||
rule.integrations.forEach((integration, index) => {
|
||||
cy.get(INTEGRATIONS).eq(index).should('contain', integration);
|
||||
cy.get(INTEGRATIONS_STATUS).eq(index).should('have.text', 'Not installed');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context.skip(
|
||||
'installed integrations: Amazon CloudFront, AWS CloudTrail, System, enabled integrations: Amazon CloudFront, Aws Cloudfront, System',
|
||||
() => {
|
||||
const rule = {
|
||||
name: 'Related integrations rule',
|
||||
integrations: [
|
||||
{ name: 'AWS Cloudfront', installed: true, enabled: true },
|
||||
{ name: 'AWS CloudTrail', installed: true, enabled: false },
|
||||
{ name: 'Aws Unknown', installed: false, enabled: false },
|
||||
{ name: 'System', installed: true, enabled: true },
|
||||
],
|
||||
enabledIntegrations: '2',
|
||||
};
|
||||
|
||||
before(() => {
|
||||
cleanFleet().then(() => {
|
||||
installAwsCloudFrontWithPolicy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('integrations not installed', () => {
|
||||
describe('rules management table', () => {
|
||||
beforeEach(() => {
|
||||
login();
|
||||
visit(DETECTIONS_RULE_MANAGEMENT_URL);
|
||||
waitForRulesTableToShow();
|
||||
visitSecurityDetectionRulesPage();
|
||||
disableAutoRefresh();
|
||||
});
|
||||
|
||||
it('should display a badge with the installed integrations on the rule management page', () => {
|
||||
it('should display a badge with the installed integrations', () => {
|
||||
cy.get(INTEGRATIONS_POPOVER).should(
|
||||
'have.text',
|
||||
`${rule.enabledIntegrations}/${rule.integrations.length} integrations`
|
||||
`0/${RULE_RELATED_INTEGRATIONS.length} integrations`
|
||||
);
|
||||
});
|
||||
|
||||
it('should display a popover when clicking the badge with the installed integrations on the rule management page', () => {
|
||||
it('should display a popover when clicking the badge with the installed integrations', () => {
|
||||
openIntegrationsPopover();
|
||||
|
||||
cy.get(INTEGRATIONS_POPOVER_TITLE).should(
|
||||
'have.text',
|
||||
`[${rule.integrations.length}] Related integrations available`
|
||||
`[${RULE_RELATED_INTEGRATIONS.length}] Related integrations available`
|
||||
);
|
||||
cy.get(INTEGRATIONS).should('have.length', rule.integrations.length);
|
||||
cy.get(INTEGRATIONS_STATUS).should('have.length', rule.integrations.length);
|
||||
cy.get(INTEGRATION_LINK).should('have.length', RULE_RELATED_INTEGRATIONS.length);
|
||||
cy.get(INTEGRATION_STATUS).should('have.length', RULE_RELATED_INTEGRATIONS.length);
|
||||
|
||||
rule.integrations.forEach((integration, index) => {
|
||||
let expectedStatus = integration.installed ? 'Installed' : 'Not installed';
|
||||
if (integration.enabled) expectedStatus += ': enabled';
|
||||
|
||||
cy.get(INTEGRATIONS).eq(index).should('contain', integration.name);
|
||||
cy.get(INTEGRATIONS_STATUS).eq(index).should('have.text', expectedStatus);
|
||||
RULE_RELATED_INTEGRATIONS.forEach((integration, index) => {
|
||||
cy.get(INTEGRATION_LINK).eq(index).contains(getIntegrationName(integration), {
|
||||
matchCase: false,
|
||||
});
|
||||
cy.get(INTEGRATION_STATUS).eq(index).should('have.text', 'Not installed');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should display the integrations on the definition section', () => {
|
||||
goToTheRuleDetailsOf(rule.name);
|
||||
describe('rule details', () => {
|
||||
beforeEach(() => {
|
||||
visitFirstInstalledPrebuiltRuleDetailsPage();
|
||||
});
|
||||
|
||||
cy.get(INTEGRATIONS).should('have.length', rule.integrations.length);
|
||||
cy.get(INTEGRATIONS_STATUS).should('have.length', rule.integrations.length);
|
||||
it('should display the integrations in the definition section', () => {
|
||||
cy.get(INTEGRATION_LINK).should('have.length', RULE_RELATED_INTEGRATIONS.length);
|
||||
cy.get(INTEGRATION_STATUS).should('have.length', RULE_RELATED_INTEGRATIONS.length);
|
||||
|
||||
rule.integrations.forEach((integration, index) => {
|
||||
let expectedStatus = integration.installed ? 'Installed' : 'Not installed';
|
||||
if (integration.enabled) expectedStatus += ': enabled';
|
||||
RULE_RELATED_INTEGRATIONS.forEach((integration, index) => {
|
||||
cy.get(INTEGRATION_LINK).eq(index).contains(getIntegrationName(integration), {
|
||||
matchCase: false,
|
||||
});
|
||||
cy.get(INTEGRATION_STATUS).eq(index).should('have.text', 'Not installed');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
cy.get(INTEGRATIONS).eq(index).should('contain', integration.name);
|
||||
cy.get(INTEGRATIONS_STATUS).eq(index).should('have.text', expectedStatus);
|
||||
describe('integrations installed (AWS CloudFront (enabled), AWS CloudTrail (disabled), System (enabled))', () => {
|
||||
beforeEach(() => {
|
||||
installIntegrations({
|
||||
packages: [
|
||||
{ name: 'aws', version: '1.17.0' },
|
||||
{ name: 'system', version: '1.17.0' },
|
||||
],
|
||||
agentPolicy: {
|
||||
name: 'Agent policy',
|
||||
namespace: 'default',
|
||||
monitoring_enabled: ['logs'],
|
||||
inactivity_timeout: 1209600,
|
||||
},
|
||||
packagePolicy: AWS_PACKAGE_POLICY,
|
||||
});
|
||||
});
|
||||
|
||||
describe('rules management table', () => {
|
||||
beforeEach(() => {
|
||||
visitSecurityDetectionRulesPage();
|
||||
disableAutoRefresh();
|
||||
});
|
||||
|
||||
it('should display a badge with the installed integrations', () => {
|
||||
const enabledIntegrations = RULE_RELATED_INTEGRATIONS.filter((x) => x.enabled).length;
|
||||
const totalIntegrations = RULE_RELATED_INTEGRATIONS.length;
|
||||
|
||||
cy.get(INTEGRATIONS_POPOVER).should(
|
||||
'have.text',
|
||||
`${enabledIntegrations}/${totalIntegrations} integrations`
|
||||
);
|
||||
});
|
||||
|
||||
it('should display a popover when clicking the badge with the installed integrations', () => {
|
||||
openIntegrationsPopover();
|
||||
|
||||
cy.get(INTEGRATIONS_POPOVER_TITLE).should(
|
||||
'have.text',
|
||||
`[${RULE_RELATED_INTEGRATIONS.length}] Related integrations available`
|
||||
);
|
||||
cy.get(INTEGRATION_LINK).should('have.length', RULE_RELATED_INTEGRATIONS.length);
|
||||
cy.get(INTEGRATION_STATUS).should('have.length', RULE_RELATED_INTEGRATIONS.length);
|
||||
|
||||
RULE_RELATED_INTEGRATIONS.forEach((integration, index) => {
|
||||
cy.get(INTEGRATION_LINK).eq(index).contains(getIntegrationName(integration), {
|
||||
matchCase: false,
|
||||
});
|
||||
cy.get(INTEGRATION_STATUS)
|
||||
.eq(index)
|
||||
.should('have.text', getIntegrationStatus(integration));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('rule details', () => {
|
||||
beforeEach(() => {
|
||||
visitFirstInstalledPrebuiltRuleDetailsPage();
|
||||
});
|
||||
|
||||
it('should display the integrations in the definition section', () => {
|
||||
cy.get(INTEGRATION_LINK).should('have.length', RULE_RELATED_INTEGRATIONS.length);
|
||||
cy.get(INTEGRATION_STATUS).should('have.length', RULE_RELATED_INTEGRATIONS.length);
|
||||
|
||||
RULE_RELATED_INTEGRATIONS.forEach((integration, index) => {
|
||||
cy.get(INTEGRATION_LINK).eq(index).contains(getIntegrationName(integration), {
|
||||
matchCase: false,
|
||||
});
|
||||
cy.get(INTEGRATION_STATUS)
|
||||
.eq(index)
|
||||
.should('have.text', getIntegrationStatus(integration));
|
||||
});
|
||||
});
|
||||
|
||||
it('the alerts generated should have a "kibana.alert.rule.parameters.related_integrations" field containing the integrations', () => {
|
||||
const firstRule = 0;
|
||||
const relatedIntegrationsField = 'kibana.alert.rule.parameters.related_integrations';
|
||||
const expectedRelatedIntegrationsText =
|
||||
'{"package":"system","version":"1.17.0"}{"package":"aws","integration":"cloudtrail","version":"1.17.0"}{"package":"aws","integration":"cloudfront","version":"1.17.0"}{"package":"aws","integration":"unknown","version":"1.17.0"}';
|
||||
const RELATED_INTEGRATION_FIELD = 'kibana.alert.rule.parameters.related_integrations';
|
||||
|
||||
enableRule(firstRule);
|
||||
waitForRuleToUpdate();
|
||||
goToTheRuleDetailsOf(rule.name);
|
||||
deleteDataStream(DATA_STREAM_NAME);
|
||||
createDocument(DATA_STREAM_NAME, generateEvent());
|
||||
|
||||
waitForPageToBeLoaded(PREBUILT_RULE_NAME);
|
||||
enablesRule();
|
||||
waitForAlertsToPopulate();
|
||||
expandFirstAlert();
|
||||
openTable();
|
||||
filterBy(relatedIntegrationsField);
|
||||
cy.get(FIELD(relatedIntegrationsField)).should(
|
||||
'have.text',
|
||||
expectedRelatedIntegrationsText
|
||||
);
|
||||
filterBy(RELATED_INTEGRATION_FIELD);
|
||||
|
||||
RULE_RELATED_INTEGRATIONS.forEach((integration) => {
|
||||
cy.contains(
|
||||
FIELD(RELATED_INTEGRATION_FIELD),
|
||||
`{"package":"${integration.package}"${
|
||||
integration.integration ? `,"integration":"${integration.integration}"` : ''
|
||||
},"version":"${integration.version}"}`
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
context('related Integrations Advanced Setting is disabled', () => {
|
||||
const rule = {
|
||||
name: 'Related integrations rule',
|
||||
integrations: ['Aws Cloudfront', 'Aws Cloudtrail', 'Aws Unknown', 'System'],
|
||||
enabledIntegrations: '0',
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
describe('related Integrations Advanced Setting is disabled', () => {
|
||||
before(() => {
|
||||
cleanFleet().then(() => {
|
||||
disableRelatedIntegrations();
|
||||
});
|
||||
disableRelatedIntegrations();
|
||||
});
|
||||
|
||||
after(() => {
|
||||
enableRelatedIntegrations();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
login();
|
||||
visit(DETECTIONS_RULE_MANAGEMENT_URL);
|
||||
waitForRulesTableToShow();
|
||||
describe('rules management table', () => {
|
||||
beforeEach(() => {
|
||||
visitSecurityDetectionRulesPage();
|
||||
disableAutoRefresh();
|
||||
});
|
||||
|
||||
it('should not display a badge with the installed integrations', () => {
|
||||
cy.get(RULE_NAME).should('have.text', PREBUILT_RULE_NAME);
|
||||
cy.get(INTEGRATION_LINK).should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
it('should not display a badge with the installed integrations on the rule management page', () => {
|
||||
cy.get(RULE_NAME).should('have.text', rule.name);
|
||||
cy.get(INTEGRATIONS).should('not.exist');
|
||||
});
|
||||
describe('rule details', () => {
|
||||
beforeEach(() => {
|
||||
visitFirstInstalledPrebuiltRuleDetailsPage();
|
||||
});
|
||||
|
||||
it('should display the integrations on the definition section', () => {
|
||||
goToTheRuleDetailsOf(rule.name);
|
||||
it('should display the integrations in the definition section', () => {
|
||||
cy.get(INTEGRATION_LINK).should('have.length', RULE_RELATED_INTEGRATIONS.length);
|
||||
cy.get(INTEGRATION_STATUS).should('have.length', RULE_RELATED_INTEGRATIONS.length);
|
||||
|
||||
cy.get(INTEGRATIONS).should('have.length', rule.integrations.length);
|
||||
cy.get(INTEGRATIONS_STATUS).should('have.length', rule.integrations.length);
|
||||
|
||||
rule.integrations.forEach((integration, index) => {
|
||||
cy.get(INTEGRATIONS).eq(index).should('contain', integration);
|
||||
cy.get(INTEGRATIONS_STATUS).eq(index).should('have.text', 'Not installed');
|
||||
RULE_RELATED_INTEGRATIONS.forEach((integration, index) => {
|
||||
cy.get(INTEGRATION_LINK).eq(index).contains(getIntegrationName(integration), {
|
||||
matchCase: false,
|
||||
});
|
||||
cy.get(INTEGRATION_STATUS).eq(index).should('have.text', 'Not installed');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
const INSTALLED_PREBUILT_RULES_RESPONSE_ALIAS = 'prebuiltRules';
|
||||
|
||||
function addAndInstallPrebuiltRules(rules: Array<typeof SAMPLE_PREBUILT_RULE>): void {
|
||||
installPrebuiltRuleAssets(rules);
|
||||
installAllPrebuiltRulesRequest().as(INSTALLED_PREBUILT_RULES_RESPONSE_ALIAS);
|
||||
}
|
||||
|
||||
function visitFirstInstalledPrebuiltRuleDetailsPage(): void {
|
||||
cy.get<Cypress.Response<PerformRuleInstallationResponseBody>>(
|
||||
`@${INSTALLED_PREBUILT_RULES_RESPONSE_ALIAS}`
|
||||
).then((response) => visitWithoutDateRange(ruleDetailsUrl(response.body.results.created[0].id)));
|
||||
}
|
||||
|
||||
interface IntegrationDefinition {
|
||||
package: string;
|
||||
version: string;
|
||||
installed: boolean;
|
||||
enabled: boolean;
|
||||
integration?: string;
|
||||
}
|
||||
|
||||
function getIntegrationName(integration: IntegrationDefinition): string {
|
||||
return `${integration.package} ${integration.integration ?? ''}`.trim();
|
||||
}
|
||||
|
||||
function getIntegrationStatus(integration: IntegrationDefinition): string {
|
||||
return `${integration.installed ? 'Installed' : 'Not installed'}${
|
||||
integration.enabled ? ': enabled' : ''
|
||||
}`.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* AWS package policy has been generated by Kibana. Instead of copying the whole output the policy below
|
||||
* contains only required for testing inputs.
|
||||
*/
|
||||
const AWS_PACKAGE_POLICY: PackagePolicyWithoutAgentPolicyId = {
|
||||
package: {
|
||||
name: 'aws',
|
||||
version: '1.17.0',
|
||||
},
|
||||
name: 'aws-1',
|
||||
namespace: 'default',
|
||||
inputs: {
|
||||
'cloudtrail-aws-s3': {
|
||||
enabled: false,
|
||||
streams: {
|
||||
'aws.cloudtrail': {
|
||||
enabled: true,
|
||||
vars: {
|
||||
fips_enabled: false,
|
||||
tags: ['forwarded', 'aws-cloudtrail'],
|
||||
preserve_original_event: false,
|
||||
cloudtrail_regex: '/CloudTrail/',
|
||||
cloudtrail_digest_regex: '/CloudTrail-Digest/',
|
||||
cloudtrail_insight_regex: '/CloudTrail-Insight/',
|
||||
max_number_of_messages: 5,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'elb-aws-s3': {
|
||||
enabled: false,
|
||||
streams: {
|
||||
'aws.elb_logs': {
|
||||
enabled: true,
|
||||
vars: {
|
||||
fips_enabled: false,
|
||||
tags: ['forwarded', 'aws-elb-logs'],
|
||||
preserve_original_event: false,
|
||||
max_number_of_messages: 5,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'firewall-aws-s3': {
|
||||
enabled: false,
|
||||
streams: {
|
||||
'aws.firewall_logs': {
|
||||
enabled: true,
|
||||
vars: {
|
||||
fips_enabled: false,
|
||||
tags: ['forwarded', 'aws-firewall-logs'],
|
||||
preserve_original_event: false,
|
||||
max_number_of_messages: 5,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
's3-aws-s3': {
|
||||
enabled: false,
|
||||
streams: {
|
||||
'aws.s3access': {
|
||||
enabled: true,
|
||||
vars: {
|
||||
fips_enabled: false,
|
||||
tags: ['forwarded', 'aws-s3access'],
|
||||
preserve_original_event: false,
|
||||
max_number_of_messages: 5,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'waf-aws-s3': {
|
||||
enabled: false,
|
||||
streams: {
|
||||
'aws.waf': {
|
||||
enabled: true,
|
||||
vars: {
|
||||
fips_enabled: false,
|
||||
tags: ['forwarded', 'aws-waf'],
|
||||
preserve_original_event: false,
|
||||
max_number_of_messages: 5,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'cloudfront-aws-s3': {
|
||||
enabled: true,
|
||||
streams: {
|
||||
'aws.cloudfront_logs': {
|
||||
enabled: true,
|
||||
vars: {
|
||||
queue_url: 'https://example.com',
|
||||
fips_enabled: false,
|
||||
tags: ['forwarded', 'aws-cloudfront'],
|
||||
preserve_original_event: false,
|
||||
max_number_of_messages: 5,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -19,10 +19,7 @@ import { login, visitWithoutDateRange } from '../../../tasks/login';
|
|||
import { getEndpointRule } from '../../../objects/rule';
|
||||
import { goToRuleDetails } from '../../../tasks/alerts_detection_rules';
|
||||
import { createRule } from '../../../tasks/api_calls/rules';
|
||||
import {
|
||||
waitForAlertsToPopulate,
|
||||
waitForTheRuleToBeExecuted,
|
||||
} from '../../../tasks/create_new_rule';
|
||||
import { waitForAlertsToPopulate } from '../../../tasks/create_new_rule';
|
||||
import { DETECTIONS_RULE_MANAGEMENT_URL } from '../../../urls/navigation';
|
||||
import {
|
||||
addExceptionEntryFieldValueAndSelectSuggestion,
|
||||
|
@ -40,7 +37,7 @@ import {
|
|||
EXCEPTION_CARD_ITEM_NAME,
|
||||
EXCEPTION_ITEM_VIEWER_CONTAINER,
|
||||
} from '../../../screens/exceptions';
|
||||
import { goToEndpointExceptionsTab } from '../../../tasks/rule_details';
|
||||
import { goToEndpointExceptionsTab, waitForTheRuleToBeExecuted } from '../../../tasks/rule_details';
|
||||
|
||||
// See https://github.com/elastic/kibana/issues/163967
|
||||
describe.skip(
|
||||
|
|
|
@ -13,11 +13,9 @@ import { OVERVIEW } from '../../../screens/security_header';
|
|||
import { goToRuleDetails } from '../../../tasks/alerts_detection_rules';
|
||||
import { createRule } from '../../../tasks/api_calls/rules';
|
||||
import { cleanKibana } from '../../../tasks/common';
|
||||
import {
|
||||
waitForAlertsToPopulate,
|
||||
waitForTheRuleToBeExecuted,
|
||||
} from '../../../tasks/create_new_rule';
|
||||
import { waitForAlertsToPopulate } from '../../../tasks/create_new_rule';
|
||||
import { login, visitWithoutDateRange } from '../../../tasks/login';
|
||||
import { waitForTheRuleToBeExecuted } from '../../../tasks/rule_details';
|
||||
import { navigateFromHeaderTo } from '../../../tasks/security_header';
|
||||
import { DETECTIONS_RULE_MANAGEMENT_URL } from '../../../urls/navigation';
|
||||
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
{"id":"6cc39c80-da3a-11ec-9fce-65c1a0bee904","updated_at":"2022-05-23T01:48:23.422Z","updated_by":"elastic","created_at":"2022-05-23T01:48:20.940Z","created_by":"elastic","name":"Related integrations rule","tags":["Elastic","Endpoint Security"],"interval":"5m","enabled":false,"description":"Generates a detection alert each time an Elastic Endpoint Security alert is received. Enabling this rule allows you to immediately begin investigating your Endpoint alerts.","risk_score":47,"severity":"medium","license":"Elastic License v2","output_index":".siem-signals-default","meta":{"from":"5m"},"rule_name_override":"message","timestamp_override":"event.ingested","author":["Elastic"],"false_positives":[],"from":"now-50000h","rule_id":"2c66bf23-6ae9-4eb2-859e-446bea181ae9","max_signals":10000,"risk_score_mapping":[{"field":"event.risk_score","operator":"equals","value":""}],"severity_mapping":[{"field":"event.severity","operator":"equals","severity":"low","value":"21"},{"field":"event.severity","operator":"equals","severity":"medium","value":"47"},{"field":"event.severity","operator":"equals","severity":"high","value":"73"},{"field":"event.severity","operator":"equals","severity":"critical","value":"99"}],"threat":[],"to":"now","references":[],"version":7,"exceptions_list":[{"id":"endpoint_list","list_id":"endpoint_list","namespace_type":"agnostic","type":"endpoint"}],"immutable":false,"related_integrations":[{"package":"system","version":"1.17.0"},{"package":"aws","integration":"cloudtrail","version":"1.17.0"},{"package":"aws","integration":"cloudfront","version":"1.17.0"},{"package":"aws","integration":"unknown","version":"1.17.0"}],"type":"query","language":"kuery","index":["auditbeat-*"],"query":"*:*","filters":[],"throttle":"no_actions","actions":[]}
|
||||
{"exported_count":1,"exported_rules_count":1,"missing_rules":[],"missing_rules_count":0,"exported_exception_list_count":0,"exported_exception_list_item_count":0,"missing_exception_list_item_count":0,"missing_exception_list_items":[],"missing_exception_lists":[],"missing_exception_lists_count":0}
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* 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 { SecurityEvent } from './types';
|
||||
|
||||
export function generateEvent(extra: Record<string, unknown> = {}): SecurityEvent {
|
||||
return {
|
||||
'@timestamp': Date.now(),
|
||||
ecs: { version: '1.4.0' },
|
||||
event: { kind: 'event', category: 'process', type: 'start' },
|
||||
...extra,
|
||||
};
|
||||
}
|
|
@ -12,3 +12,16 @@ export type CreateRulePropsRewrites<CreateRuleProps> = Partial<Exclude<CreateRul
|
|||
export interface Actions {
|
||||
connectors: Connectors[];
|
||||
}
|
||||
|
||||
export interface SecurityEvent {
|
||||
[field: string]: unknown;
|
||||
'@timestamp': number;
|
||||
ecs: {
|
||||
version: string;
|
||||
};
|
||||
event: {
|
||||
kind: 'event';
|
||||
category: string;
|
||||
type: string;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -11,4 +11,6 @@ export const NOT_FOUND = '[data-test-subj="notFoundPage"]';
|
|||
|
||||
export const LOADING_SPINNER = '.euiLoadingSpinner';
|
||||
|
||||
export const PAGE_CONTENT_SPINNER = `[data-test-subj="pageContainer"] ${LOADING_SPINNER}`;
|
||||
export const PAGE_CONTENT = '[data-test-subj="pageContainer"]';
|
||||
|
||||
export const PAGE_CONTENT_SPINNER = `${PAGE_CONTENT} ${LOADING_SPINNER}`;
|
||||
|
|
|
@ -136,8 +136,6 @@ export const MITRE_ATTACK_ADD_SUBTECHNIQUE_BUTTON = '[data-test-subj="addMitreAt
|
|||
export const REFERENCE_URLS_INPUT =
|
||||
'[data-test-subj="detectionEngineStepAboutRuleReferenceUrls"] input';
|
||||
|
||||
export const REFRESH_BUTTON = '[data-test-subj="refreshButton"]';
|
||||
|
||||
export const DEFAULT_RISK_SCORE_INPUT =
|
||||
'[data-test-subj="detectionEngineStepAboutRuleRiskScore-defaultRiskRange"].euiRangeInput';
|
||||
|
||||
|
|
|
@ -58,9 +58,9 @@ export const INDICATOR_INDEX_QUERY = 'Indicator index query';
|
|||
|
||||
export const INDICATOR_MAPPING = 'Indicator mapping';
|
||||
|
||||
export const INTEGRATIONS = '[data-test-subj="integrationLink"]';
|
||||
export const INTEGRATION_LINK = '[data-test-subj="integrationLink"]';
|
||||
|
||||
export const INTEGRATIONS_STATUS = '[data-test-subj="statusBadge"]';
|
||||
export const INTEGRATION_STATUS = '[data-test-subj="statusBadge"]';
|
||||
|
||||
export const INVESTIGATION_NOTES_MARKDOWN = 'test markdown';
|
||||
|
||||
|
@ -79,7 +79,8 @@ export const NEW_TERMS_HISTORY_WINDOW_DETAILS = 'History Window Size';
|
|||
export const FIELDS_BROWSER_BTN =
|
||||
'[data-test-subj="alertsTable"] [data-test-subj="show-field-browser"]';
|
||||
|
||||
export const REFRESH_BUTTON = '[data-test-subj="refreshButton"]';
|
||||
export const LAST_EXECUTION_STATUS_REFRESH_BUTTON =
|
||||
'[data-test-subj="ruleLastExecutionStatusRefreshButton"]';
|
||||
|
||||
export const RULE_NAME_HEADER = '[data-test-subj="header-page-title"]';
|
||||
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export const TABLE_TAB = '[data-test-subj="securitySolutionDocumentDetailsFlyoutTableTab"]';
|
||||
|
||||
export const FILTER_INPUT =
|
||||
'[data-test-subj="securitySolutionDocumentDetailsFlyoutBody"] [data-test-subj="search-input"]';
|
|
@ -9,12 +9,34 @@ import { rootRequest } from '../common';
|
|||
export const deleteIndex = (index: string) => {
|
||||
rootRequest({
|
||||
method: 'DELETE',
|
||||
url: `${Cypress.env('ELASTICSEARCH_URL')}/${index}`,
|
||||
url: `${Cypress.env('ELASTICSEARCH_URL')}/${index}?refresh=wait_for`,
|
||||
headers: { 'kbn-xsrf': 'cypress-creds', 'x-elastic-internal-origin': 'security-solution' },
|
||||
failOnStatusCode: false,
|
||||
});
|
||||
};
|
||||
|
||||
export const deleteDataStream = (dataStreamName: string) => {
|
||||
rootRequest({
|
||||
method: 'DELETE',
|
||||
url: `${Cypress.env('ELASTICSEARCH_URL')}/_data_stream/${dataStreamName}`,
|
||||
headers: { 'kbn-xsrf': 'cypress-creds', 'x-elastic-internal-origin': 'security-solution' },
|
||||
failOnStatusCode: false,
|
||||
});
|
||||
};
|
||||
|
||||
export const deleteAllDocuments = (target: string) =>
|
||||
rootRequest({
|
||||
method: 'POST',
|
||||
url: `${Cypress.env(
|
||||
'ELASTICSEARCH_URL'
|
||||
)}/${target}/_delete_by_query?conflicts=proceed&scroll_size=10000&refresh`,
|
||||
body: {
|
||||
query: {
|
||||
match_all: {},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const createIndex = (indexName: string, properties: Record<string, unknown>) =>
|
||||
rootRequest({
|
||||
method: 'PUT',
|
||||
|
@ -29,7 +51,7 @@ export const createIndex = (indexName: string, properties: Record<string, unknow
|
|||
export const createDocument = (indexName: string, document: Record<string, unknown>) =>
|
||||
rootRequest({
|
||||
method: 'POST',
|
||||
url: `${Cypress.env('ELASTICSEARCH_URL')}/${indexName}/_doc`,
|
||||
url: `${Cypress.env('ELASTICSEARCH_URL')}/${indexName}/_doc?refresh=wait_for`,
|
||||
body: document,
|
||||
});
|
||||
|
||||
|
|
|
@ -5,6 +5,10 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import {
|
||||
PerformRuleInstallationResponseBody,
|
||||
PERFORM_RULE_INSTALLATION_URL,
|
||||
} from '@kbn/security-solution-plugin/common/api/detection_engine';
|
||||
import { ELASTIC_SECURITY_RULE_ID } from '@kbn/security-solution-plugin/common/detection_engine/constants';
|
||||
import type { PrePackagedRulesStatusResponse } from '@kbn/security-solution-plugin/public/detection_engine/rule_management/logic/types';
|
||||
import { getPrebuiltRuleWithExceptionsMock } from '@kbn/security-solution-plugin/server/lib/detection_engine/prebuilt_rules/mocks';
|
||||
|
@ -30,16 +34,15 @@ export const SAMPLE_PREBUILT_RULE = createRuleAssetSavedObject({
|
|||
* `createNewRuleAsset` to create mocked prebuilt rules and install only those
|
||||
* instead of all rules available in the `security_detection_engine` package
|
||||
*/
|
||||
export const installAllPrebuiltRulesRequest = () => {
|
||||
return cy.request({
|
||||
export const installAllPrebuiltRulesRequest = () =>
|
||||
cy.request<PerformRuleInstallationResponseBody>({
|
||||
method: 'POST',
|
||||
url: 'internal/detection_engine/prebuilt_rules/installation/_perform',
|
||||
url: PERFORM_RULE_INSTALLATION_URL,
|
||||
headers: { 'kbn-xsrf': 'cypress-creds', 'x-elastic-internal-origin': 'security-solution' },
|
||||
body: {
|
||||
mode: 'ALL_RULES',
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export const getAvailablePrebuiltRulesCount = () => {
|
||||
cy.log('Get prebuilt rules count');
|
||||
|
@ -187,6 +190,24 @@ export const preventPrebuiltRulesPackageInstallation = () => {
|
|||
cy.intercept('POST', '/api/fleet/epm/packages/security_detection_engine/*', {});
|
||||
};
|
||||
|
||||
/**
|
||||
* Install prebuilt rule assets. After installing these assets become available to be installed
|
||||
* as prebuilt rules. Prebuilt rule assets can be generated via `createRuleAssetSavedObject()` helper function.
|
||||
*
|
||||
* It's also important to take into account that business logic tries to fetch prebuilt rules Fleet package
|
||||
* and you need to add `preventPrebuiltRulesPackageInstallation()` to `beforeEach` section (before visit commands)
|
||||
* to avoid actually pulling a real Fleet package and have only provided prebuilt rule assets for testing.
|
||||
*/
|
||||
export const installPrebuiltRuleAssets = (ruleAssets: Array<typeof SAMPLE_PREBUILT_RULE>): void => {
|
||||
cy.log('Create mocked available to install prebuilt rules', ruleAssets.length);
|
||||
preventPrebuiltRulesPackageInstallation();
|
||||
// TODO: use this bulk method once the issue with Cypress is fixed
|
||||
// bulkCreateRuleAssets({ rules });
|
||||
ruleAssets.forEach((rule) => {
|
||||
createNewRuleAsset({ rule });
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Prevent the installation of the `security_detection_engine` package from Fleet.
|
||||
* The create a `security-rule` asset for each rule provided in the `rules` array.
|
||||
|
@ -199,21 +220,16 @@ export const preventPrebuiltRulesPackageInstallation = () => {
|
|||
* * @param {string} installToKibana - Flag to decide whether to install the rules as 'alerts' SO. Defaults to true.
|
||||
*/
|
||||
export const createAndInstallMockedPrebuiltRules = ({
|
||||
rules,
|
||||
rules: ruleAssets,
|
||||
installToKibana = true,
|
||||
}: {
|
||||
rules: Array<typeof SAMPLE_PREBUILT_RULE>;
|
||||
installToKibana?: boolean;
|
||||
}) => {
|
||||
cy.log('Install prebuilt rules', rules?.length);
|
||||
preventPrebuiltRulesPackageInstallation();
|
||||
// TODO: use this bulk method once the issue with Cypress is fixed
|
||||
// bulkCreateRuleAssets({ rules });
|
||||
rules.forEach((rule) => {
|
||||
createNewRuleAsset({ rule });
|
||||
});
|
||||
installPrebuiltRuleAssets(ruleAssets);
|
||||
|
||||
if (installToKibana) {
|
||||
cy.log('Install prebuilt rules', ruleAssets.length);
|
||||
return installAllPrebuiltRulesRequest();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -9,6 +9,7 @@ import { DATA_VIEW_PATH, INITIAL_REST_VERSION } from '@kbn/data-views-plugin/ser
|
|||
import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common';
|
||||
import { KIBANA_LOADING_ICON } from '../screens/security_header';
|
||||
import { EUI_BASIC_TABLE_LOADING } from '../screens/common/controls';
|
||||
import { deleteAllDocuments } from './api_calls/elasticsearch';
|
||||
|
||||
const primaryButton = 0;
|
||||
|
||||
|
@ -130,17 +131,7 @@ export const deleteAlertsAndRules = () => {
|
|||
},
|
||||
});
|
||||
|
||||
rootRequest({
|
||||
method: 'POST',
|
||||
url: `${Cypress.env(
|
||||
'ELASTICSEARCH_URL'
|
||||
)}/.lists-*,.items-*,.alerts-security.alerts-*/_delete_by_query?conflicts=proceed&scroll_size=10000&refresh`,
|
||||
body: {
|
||||
query: {
|
||||
match_all: {},
|
||||
},
|
||||
},
|
||||
});
|
||||
deleteAllDocuments('.lists-*,.items-*,.alerts-security.alerts-*');
|
||||
};
|
||||
|
||||
export const deleteTimelines = () => {
|
||||
|
|
|
@ -69,13 +69,11 @@ import {
|
|||
MITRE_TACTIC,
|
||||
QUERY_BAR,
|
||||
REFERENCE_URLS_INPUT,
|
||||
REFRESH_BUTTON,
|
||||
RISK_MAPPING_OVERRIDE_OPTION,
|
||||
RISK_OVERRIDE,
|
||||
RULE_DESCRIPTION_INPUT,
|
||||
RULE_NAME_INPUT,
|
||||
RULE_NAME_OVERRIDE,
|
||||
RULE_STATUS,
|
||||
RULE_TIMESTAMP_OVERRIDE,
|
||||
RULES_CREATION_FORM,
|
||||
RULES_CREATION_PREVIEW_BUTTON,
|
||||
|
@ -696,16 +694,6 @@ export const waitForAlertsToPopulate = (alertCountThreshold = 1) => {
|
|||
waitForAlerts();
|
||||
};
|
||||
|
||||
export const waitForTheRuleToBeExecuted = () => {
|
||||
cy.waitUntil(() => {
|
||||
cy.get(REFRESH_BUTTON).click({ force: true });
|
||||
return cy
|
||||
.get(RULE_STATUS)
|
||||
.invoke('text')
|
||||
.then((ruleStatus) => ruleStatus === 'succeeded');
|
||||
});
|
||||
};
|
||||
|
||||
export const selectAndLoadSavedQuery = (queryName: string, queryValue: string) => {
|
||||
cy.get(QUERY_BAR).find(SHOW_QUERY_BAR_BUTTON).click();
|
||||
|
||||
|
|
|
@ -5,23 +5,77 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { TypeOf } from '@kbn/config-schema';
|
||||
import {
|
||||
ADD_INTEGRATION_BTN,
|
||||
INTEGRATION_ADDED_POP_UP,
|
||||
QUEUE_URL,
|
||||
SAVE_AND_CONTINUE_BTN,
|
||||
SKIP_AGENT_INSTALLATION_BTN,
|
||||
} from '../screens/integrations';
|
||||
AGENT_POLICY_API_ROUTES,
|
||||
CreateAgentPolicyResponse,
|
||||
EPM_API_ROUTES,
|
||||
PACKAGE_POLICY_API_ROUTES,
|
||||
} from '@kbn/fleet-plugin/common';
|
||||
import {
|
||||
NewAgentPolicySchema,
|
||||
SimplifiedCreatePackagePolicyRequestBodySchema,
|
||||
} from '@kbn/fleet-plugin/server/types';
|
||||
import { rootRequest } from './common';
|
||||
|
||||
import { visit } from './login';
|
||||
interface Package {
|
||||
name: string;
|
||||
version: string;
|
||||
}
|
||||
|
||||
export const installAwsCloudFrontWithPolicy = () => {
|
||||
visit('app/integrations/detail/aws-1.17.0/overview?integration=cloudfront');
|
||||
cy.get(ADD_INTEGRATION_BTN).click();
|
||||
cy.get(SKIP_AGENT_INSTALLATION_BTN).click();
|
||||
cy.get(QUEUE_URL).type('http://www.example.com');
|
||||
export type AgentPolicy = TypeOf<typeof NewAgentPolicySchema>;
|
||||
export type PackagePolicy = TypeOf<typeof SimplifiedCreatePackagePolicyRequestBodySchema>;
|
||||
export type PackagePolicyWithoutAgentPolicyId = Omit<PackagePolicy, 'policy_id'>;
|
||||
|
||||
// Fleet installs an integration very slowly, so we have to increase the timeout here.
|
||||
cy.get(SAVE_AND_CONTINUE_BTN).click();
|
||||
cy.get(INTEGRATION_ADDED_POP_UP, { timeout: 120000 }).should('exist');
|
||||
};
|
||||
/**
|
||||
* Installs provided integrations by installing provided packages, creating an agent policy and adding a package policy.
|
||||
* An agent policy is created with System integration enabled (with `?sys_monitoring=true` query param).
|
||||
*
|
||||
* Agent and package policies can be generated in Kibana by opening Fleet UI e.g. for AWS CloudFront the steps are following
|
||||
*
|
||||
* - open `app/integrations/detail/aws-1.17.0/overview?integration=cloudfront`
|
||||
* - click the button `Add Amazon CloudFront`
|
||||
* - fill in `Queue URL`
|
||||
* - press `Preview API request` at the bottom
|
||||
* - copy shown policies
|
||||
*/
|
||||
export function installIntegrations({
|
||||
packages,
|
||||
agentPolicy,
|
||||
packagePolicy,
|
||||
}: {
|
||||
packages: Package[];
|
||||
agentPolicy: AgentPolicy;
|
||||
packagePolicy: Omit<PackagePolicy, 'policy_id'>;
|
||||
}): void {
|
||||
// Bulk install provided packages
|
||||
rootRequest({
|
||||
method: 'POST',
|
||||
url: EPM_API_ROUTES.BULK_INSTALL_PATTERN,
|
||||
body: {
|
||||
packages,
|
||||
force: true,
|
||||
},
|
||||
headers: { 'kbn-xsrf': 'cypress-creds', 'x-elastic-internal-origin': 'security-solution' },
|
||||
});
|
||||
|
||||
// Install agent and package policies
|
||||
rootRequest<CreateAgentPolicyResponse>({
|
||||
method: 'POST',
|
||||
url: `${AGENT_POLICY_API_ROUTES.CREATE_PATTERN}?sys_monitoring=true`,
|
||||
body: agentPolicy,
|
||||
headers: { 'kbn-xsrf': 'cypress-creds', 'x-elastic-internal-origin': 'security-solution' },
|
||||
}).then((response) => {
|
||||
const packagePolicyWithAgentPolicyId: PackagePolicy = {
|
||||
...packagePolicy,
|
||||
policy_id: response.body.item.id,
|
||||
};
|
||||
|
||||
rootRequest({
|
||||
method: 'POST',
|
||||
url: PACKAGE_POLICY_API_ROUTES.CREATE_PATTERN,
|
||||
body: packagePolicyWithAgentPolicyId,
|
||||
headers: { 'kbn-xsrf': 'cypress-creds', 'x-elastic-internal-origin': 'security-solution' },
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
import type { Exception } from '../objects/exception';
|
||||
import { PAGE_CONTENT_SPINNER } from '../screens/common/page';
|
||||
import { RULE_STATUS } from '../screens/create_new_rule';
|
||||
import {
|
||||
ADD_EXCEPTIONS_BTN_FROM_EMPTY_PROMPT_BTN,
|
||||
|
@ -17,7 +18,7 @@ import {
|
|||
ALERTS_TAB,
|
||||
EXCEPTIONS_TAB,
|
||||
FIELDS_BROWSER_BTN,
|
||||
REFRESH_BUTTON,
|
||||
LAST_EXECUTION_STATUS_REFRESH_BUTTON,
|
||||
REMOVE_EXCEPTION_BTN,
|
||||
RULE_SWITCH,
|
||||
DEFINITION_DETAILS,
|
||||
|
@ -31,6 +32,7 @@ import {
|
|||
BACK_TO_RULES_TABLE,
|
||||
EXCEPTIONS_TAB_EXPIRED_FILTER,
|
||||
EXCEPTIONS_TAB_ACTIVE_FILTER,
|
||||
RULE_NAME_HEADER,
|
||||
} from '../screens/rule_details';
|
||||
import {
|
||||
addExceptionConditions,
|
||||
|
@ -114,10 +116,22 @@ export const removeException = () => {
|
|||
cy.get(REMOVE_EXCEPTION_BTN).click();
|
||||
};
|
||||
|
||||
/**
|
||||
* Waits for rule details page to be loaded
|
||||
*
|
||||
* @param ruleName rule's name
|
||||
*/
|
||||
export const waitForPageToBeLoaded = (ruleName: string): void => {
|
||||
cy.get(PAGE_CONTENT_SPINNER).should('be.visible');
|
||||
cy.contains(RULE_NAME_HEADER, ruleName).should('be.visible');
|
||||
cy.get(PAGE_CONTENT_SPINNER).should('not.exist');
|
||||
};
|
||||
|
||||
export const waitForTheRuleToBeExecuted = () => {
|
||||
cy.waitUntil(() => {
|
||||
cy.log('Wating for the rule to be executed');
|
||||
cy.get(REFRESH_BUTTON).click({ force: true });
|
||||
cy.log('Waiting for the rule to be executed');
|
||||
cy.get(LAST_EXECUTION_STATUS_REFRESH_BUTTON).click();
|
||||
|
||||
return cy
|
||||
.get(RULE_STATUS)
|
||||
.invoke('text')
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* 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 { FILTER_INPUT, TABLE_TAB } from '../screens/rule_details_flyout';
|
||||
|
||||
export const openTable = (): void => {
|
||||
cy.get(TABLE_TAB).click();
|
||||
};
|
||||
|
||||
export const filterBy = (value: string): void => {
|
||||
cy.get(FILTER_INPUT).type(value);
|
||||
};
|
|
@ -44,5 +44,6 @@
|
|||
"@kbn/cases-components",
|
||||
"@kbn/security-solution-plugin",
|
||||
"@kbn/expandable-flyout",
|
||||
"@kbn/config-schema",
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue