Skip to content

Commit

Permalink
[SecuritySolution] Ingest pipelines conflict when upgrading host risk…
Browse files Browse the repository at this point in the history
… scores (#145232)

## Summary

Original issue: #144916
Users installed via
https://github.com/elastic/detection-rules/blob/main/docs/experimental-machine-learning/host-risk-score.md
and
https://github.com/elastic/detection-rules/blob/main/docs/experimental-machine-learning/user-risk-score.md
couldn't upgrade successfully.

**Fixes**:
1. Remove all the legacy scripts and ingest pipelines with or without
space name
2. Add version history to
x-pack/plugins/security_solution/server/lib/risk_score/readme.md
<img width="1459" alt="Screenshot 2022-11-15 at 13 49 43"
src="https://user-images.githubusercontent.com/6295984/201936206-e73ab61c-9a0f-4cfe-8a01-9666217bb863.png">

<img width="1429" alt="Screenshot 2022-11-15 at 13 53 54"
src="https://user-images.githubusercontent.com/6295984/201936751-c3a65f46-1f6e-4b2f-a04a-58f1f32a546f.png">


**Steps to reproduce**:

Option 1: **Cypress**: Run `upgrade_risk_score.cy.ts`

Option 2: **Manually**: 
1. Follow the steps of
https://github.com/elastic/detection-rules/blob/main/docs/experimental-machine-learning/host-risk-score.md
and
https://github.com/elastic/detection-rules/blob/main/docs/experimental-machine-learning/user-risk-score.md
to install the module.
4. Back to `/app/security/entity_analytics` and click the upgrade
buttons.
5. Observe if the installation success.

### Checklist

Delete any items that are not applicable to this PR.

- [x]
[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)
was added for features that require explanation or tutorials
- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios

Co-authored-by: Steph Milovic <stephanie.milovic@elastic.co>
  • Loading branch information
angorayc and stephmilovic committed Nov 16, 2022
1 parent e76f15c commit b6693bd
Show file tree
Hide file tree
Showing 12 changed files with 306 additions and 190 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { RiskScoreEntity, RiskScoreFields } from '../search_strategy';
import type { Pipeline, Processor } from '../types/risk_scores';

/**
* * Since 8.5, all the transforms, scripts,
* Aside from 8.4, all the transforms, scripts,
* and ingest pipelines (and dashboard saved objects) are created with spaceId
* so they won't affect each other across different spaces.
*/
Expand Down Expand Up @@ -45,7 +45,7 @@ export const getRiskScoreReduceScriptId = (riskScoreEntity: RiskScoreEntity, spa
`ml_${riskScoreEntity}riskscore_reduce_script_${spaceId}`;

/**
* These scripts and Ingest pipeline were not space awared before 8.5.
* These scripts and Ingest pipeline were not space aware in 8.4
* They were shared across spaces and therefore affected each other.
* New scripts and ingest pipeline are all independent in each space, so these ids
* are Deprecated.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,14 @@ describe('Enable risk scores', () => {
});

beforeEach(() => {
deleteRiskScore({ riskScoreEntity: RiskScoreEntity.host, spaceId, deleteAll: true });
deleteRiskScore({ riskScoreEntity: RiskScoreEntity.user, spaceId, deleteAll: true });
deleteRiskScore({ riskScoreEntity: RiskScoreEntity.host, spaceId });
deleteRiskScore({ riskScoreEntity: RiskScoreEntity.user, spaceId });
visit(ENTITY_ANALYTICS_URL);
});

afterEach(() => {
deleteRiskScore({ riskScoreEntity: RiskScoreEntity.host, spaceId, deleteAll: true });
deleteRiskScore({ riskScoreEntity: RiskScoreEntity.user, spaceId, deleteAll: true });
deleteRiskScore({ riskScoreEntity: RiskScoreEntity.host, spaceId });
deleteRiskScore({ riskScoreEntity: RiskScoreEntity.user, spaceId });
});

it('shows enable host risk button', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,29 +43,21 @@ describe('Upgrade risk scores', () => {
});

beforeEach(() => {
deleteRiskScore({ riskScoreEntity: RiskScoreEntity.host, spaceId, deleteAll: true });
deleteRiskScore({ riskScoreEntity: RiskScoreEntity.user, spaceId, deleteAll: true });
deleteRiskScore({ riskScoreEntity: RiskScoreEntity.host, spaceId });
deleteRiskScore({ riskScoreEntity: RiskScoreEntity.user, spaceId });
installLegacyRiskScoreModule(RiskScoreEntity.host, spaceId);
installLegacyRiskScoreModule(RiskScoreEntity.user, spaceId);
visit(ENTITY_ANALYTICS_URL);
});

afterEach(() => {
deleteRiskScore({ riskScoreEntity: RiskScoreEntity.host, spaceId, deleteAll: true });
deleteRiskScore({ riskScoreEntity: RiskScoreEntity.user, spaceId, deleteAll: true });
});

it('shows upgrade host risk button', () => {
it('shows upgrade risk button for host and user', () => {
cy.get(UPGRADE_HOST_RISK_SCORE_BUTTON).should('be.visible');
cy.get(UPGRADE_USER_RISK_SCORE_BUTTON).should('be.visible');
});

it('should show a confirmation modal for upgrading host risk score', () => {
it('should show a confirmation modal for upgrading host risk score and display a link to host risk score Elastic doc', () => {
clickUpgradeRiskScore(RiskScoreEntity.host);
cy.get(UPGRADE_CONFIRMATION_MODAL(RiskScoreEntity.host)).should('exist');
});

it('display a link to host risk score Elastic doc', () => {
clickUpgradeRiskScore(RiskScoreEntity.host);

cy.get(UPGRADE_CANCELLATION_BUTTON)
.get(`${UPGRADE_CONFIRMATION_MODAL(RiskScoreEntity.host)} a`)
Expand All @@ -76,51 +68,9 @@ describe('Upgrade risk scores', () => {
});
});

it('should upgrade host risk score successfully', () => {
clickUpgradeRiskScore(RiskScoreEntity.host);

interceptUpgradeRiskScoreModule(RiskScoreEntity.host);

clickUpgradeRiskScoreConfirmed();
waitForUpgradeRiskScoreModule();

cy.get(UPGRADE_HOST_RISK_SCORE_BUTTON).should('be.disabled');

cy.get(RISK_SCORE_INSTALLATION_SUCCESS_TOAST(RiskScoreEntity.host)).should('exist');
cy.get(RISK_SCORE_DASHBOARDS_INSTALLATION_SUCCESS_TOAST(RiskScoreEntity.host)).should('exist');

cy.get(UPGRADE_HOST_RISK_SCORE_BUTTON).should('not.exist');
getTransformState(getRiskScorePivotTransformId(RiskScoreEntity.host, spaceId)).then((res) => {
expect(res.status).to.eq(200);
expect(res.body.transforms[0].id).to.eq(
getRiskScorePivotTransformId(RiskScoreEntity.host, spaceId)
);
expect(res.body.transforms[0].state).to.eq('started');
});
getTransformState(getRiskScoreLatestTransformId(RiskScoreEntity.host, spaceId)).then((res) => {
expect(res.status).to.eq(200);
expect(res.body.transforms[0].id).to.eq(
getRiskScoreLatestTransformId(RiskScoreEntity.host, spaceId)
);
expect(res.body.transforms[0].state).to.eq('started');
});
findSavedObjects(RiskScoreEntity.host, spaceId).then((res) => {
expect(res.status).to.eq(200);
expect(res.body.saved_objects.length).to.eq(11);
});
});

it('shows upgrade user risk button', () => {
cy.get(UPGRADE_USER_RISK_SCORE_BUTTON).should('be.visible');
});

it('should show a confirmation modal for upgrading user risk score', () => {
it('should show a confirmation modal for upgrading user risk score and display a link to user risk score Elastic doc', () => {
clickUpgradeRiskScore(RiskScoreEntity.user);
cy.get(UPGRADE_CONFIRMATION_MODAL(RiskScoreEntity.user)).should('exist');
});

it('display a link to user risk score Elastic doc', () => {
clickUpgradeRiskScore(RiskScoreEntity.user);

cy.get(UPGRADE_CANCELLATION_BUTTON)
.get(`${UPGRADE_CONFIRMATION_MODAL(RiskScoreEntity.user)} a`)
Expand All @@ -130,36 +80,102 @@ describe('Upgrade risk scores', () => {
);
});
});
});

it('should upgrade user risk score successfully', () => {
clickUpgradeRiskScore(RiskScoreEntity.user);
interceptUpgradeRiskScoreModule(RiskScoreEntity.user);
clickUpgradeRiskScoreConfirmed();
waitForUpgradeRiskScoreModule();
cy.get(UPGRADE_USER_RISK_SCORE_BUTTON).should('be.disabled');

cy.get(RISK_SCORE_INSTALLATION_SUCCESS_TOAST(RiskScoreEntity.user)).should('exist');
cy.get(RISK_SCORE_DASHBOARDS_INSTALLATION_SUCCESS_TOAST(RiskScoreEntity.user)).should('exist');

cy.get(UPGRADE_USER_RISK_SCORE_BUTTON).should('not.exist');
getTransformState(getRiskScorePivotTransformId(RiskScoreEntity.user, spaceId)).then((res) => {
expect(res.status).to.eq(200);
expect(res.body.transforms[0].id).to.eq(
getRiskScorePivotTransformId(RiskScoreEntity.user, spaceId)
);
expect(res.body.transforms[0].state).to.eq('started');
const versions: Array<'8.3' | '8.4'> = ['8.3', '8.4'];
versions.forEach((version) =>
describe(`handles version ${version} upgrades`, () => {
before(() => {
cleanKibana();
login();
createCustomRuleEnabled(getNewRule(), 'rule1');
});

beforeEach(() => {
deleteRiskScore({ riskScoreEntity: RiskScoreEntity.host, spaceId });
deleteRiskScore({ riskScoreEntity: RiskScoreEntity.user, spaceId });
installLegacyRiskScoreModule(RiskScoreEntity.host, spaceId, version);
installLegacyRiskScoreModule(RiskScoreEntity.user, spaceId, version);
visit(ENTITY_ANALYTICS_URL);
});
getTransformState(getRiskScoreLatestTransformId(RiskScoreEntity.user, spaceId)).then((res) => {
expect(res.status).to.eq(200);
expect(res.body.transforms[0].id).to.eq(
getRiskScoreLatestTransformId(RiskScoreEntity.user, spaceId)

afterEach(() => {
deleteRiskScore({ riskScoreEntity: RiskScoreEntity.host, spaceId });
deleteRiskScore({ riskScoreEntity: RiskScoreEntity.user, spaceId });
});

it('should upgrade host risk score successfully', () => {
clickUpgradeRiskScore(RiskScoreEntity.host);

interceptUpgradeRiskScoreModule(RiskScoreEntity.host, version);

clickUpgradeRiskScoreConfirmed();
waitForUpgradeRiskScoreModule();

cy.get(UPGRADE_HOST_RISK_SCORE_BUTTON).should('be.disabled');

cy.get(RISK_SCORE_INSTALLATION_SUCCESS_TOAST(RiskScoreEntity.host)).should('exist');
cy.get(RISK_SCORE_DASHBOARDS_INSTALLATION_SUCCESS_TOAST(RiskScoreEntity.host)).should(
'exist'
);

cy.get(UPGRADE_HOST_RISK_SCORE_BUTTON).should('not.exist');
getTransformState(getRiskScorePivotTransformId(RiskScoreEntity.host, spaceId)).then((res) => {
expect(res.status).to.eq(200);
expect(res.body.transforms[0].id).to.eq(
getRiskScorePivotTransformId(RiskScoreEntity.host, spaceId)
);
expect(res.body.transforms[0].state).to.eq('started');
});
getTransformState(getRiskScoreLatestTransformId(RiskScoreEntity.host, spaceId)).then(
(res) => {
expect(res.status).to.eq(200);
expect(res.body.transforms[0].id).to.eq(
getRiskScoreLatestTransformId(RiskScoreEntity.host, spaceId)
);
expect(res.body.transforms[0].state).to.eq('started');
}
);
expect(res.body.transforms[0].state).to.eq('started');
findSavedObjects(RiskScoreEntity.host, spaceId).then((res) => {
expect(res.status).to.eq(200);
expect(res.body.saved_objects.length).to.eq(11);
});
});

findSavedObjects(RiskScoreEntity.user, spaceId).then((res) => {
expect(res.status).to.eq(200);
expect(res.body.saved_objects.length).to.eq(11);
it('should upgrade user risk score successfully', () => {
clickUpgradeRiskScore(RiskScoreEntity.user);
interceptUpgradeRiskScoreModule(RiskScoreEntity.user);
clickUpgradeRiskScoreConfirmed();
waitForUpgradeRiskScoreModule();
cy.get(UPGRADE_USER_RISK_SCORE_BUTTON).should('be.disabled');

cy.get(RISK_SCORE_INSTALLATION_SUCCESS_TOAST(RiskScoreEntity.user)).should('exist');
cy.get(RISK_SCORE_DASHBOARDS_INSTALLATION_SUCCESS_TOAST(RiskScoreEntity.user)).should(
'exist'
);

cy.get(UPGRADE_USER_RISK_SCORE_BUTTON).should('not.exist');
getTransformState(getRiskScorePivotTransformId(RiskScoreEntity.user, spaceId)).then((res) => {
expect(res.status).to.eq(200);
expect(res.body.transforms[0].id).to.eq(
getRiskScorePivotTransformId(RiskScoreEntity.user, spaceId)
);
expect(res.body.transforms[0].state).to.eq('started');
});
getTransformState(getRiskScoreLatestTransformId(RiskScoreEntity.user, spaceId)).then(
(res) => {
expect(res.status).to.eq(200);
expect(res.body.transforms[0].id).to.eq(
getRiskScoreLatestTransformId(RiskScoreEntity.user, spaceId)
);
expect(res.body.transforms[0].state).to.eq('started');
}
);

findSavedObjects(RiskScoreEntity.user, spaceId).then((res) => {
expect(res.status).to.eq(200);
expect(res.body.saved_objects.length).to.eq(11);
});
});
});
});
})
);
Loading

0 comments on commit b6693bd

Please sign in to comment.