Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Security Solution][Endpoint][Exceptions] Only write manifest to policy when there are changes #72000

Merged
merged 18 commits into from
Jul 17, 2020

Conversation

madirey
Copy link
Contributor

@madirey madirey commented Jul 16, 2020

Summary

This PR changes the semantics of the user-artifact-manifest SO from "last dispatched" to "last computed".

There is no need to keep track of the last dispatched. We give each manifest a version, which is essentially just a sha256 hash of the artifacts that it contains. Then, when the current policy does not match our hash, we know to update.

In the course of testing this PR, some additional improvements were made:

  • Extended mocks and unit tests extensively
  • Removed some lingering @ts-ignore instances and cleaned up types
  • Removed the confusing getSnapshot terminology in ManifestManager. Updates are now more explicit.
  • The callback on policy creation was greatly simplified. We now use the first policy creation to initialize the user manifest, and subsequent policy creations will just grab the last computed manifest value and return relatively quickly. @paul-tavares @XavierM
  • Cleaned up logs.

Checklist

Delete any items that are not applicable to this PR.

For maintainers

@madirey madirey added v8.0.0 Team:Endpoint Response Endpoint Response Team Feature:Endpoint Elastic Endpoint feature v7.9.0 labels Jul 16, 2020
@madirey madirey added the bug Fixes for quality problems that affect the customer experience label Jul 16, 2020
@madirey madirey marked this pull request as ready for review July 17, 2020 02:31
@madirey madirey requested a review from a team as a code owner July 17, 2020 02:31
@madirey madirey requested a review from a team July 17, 2020 02:31
@madirey madirey requested a review from a team as a code owner July 17, 2020 02:31
@elasticmachine
Copy link
Contributor

Pinging @elastic/endpoint-app-team (Feature:Endpoint)

@botelastic botelastic bot added the Team:Fleet Team label for Observability Data Collection Fleet team label Jul 17, 2020
@elasticmachine
Copy link
Contributor

Pinging @elastic/endpoint-response (Team:Endpoint Response)

@elasticmachine
Copy link
Contributor

Pinging @elastic/ingest-management (Team:Ingest Management)

@madirey madirey changed the title [DRAFT] Changes to manifest dispatch / policy update [Security Solution][Endpoint][Exceptions] Only write manifest to policy when there are changes Jul 17, 2020
@madirey madirey added release_note:fix release_note:skip Skip the PR/issue when compiling release notes and removed release_note:fix release_note:skip Skip the PR/issue when compiling release notes labels Jul 17, 2020
const adds = diffs.filter((diff) => diff.type === 'add').map((diff) => diff.id);
for (const artifactId of adds) {
const compressError = await newManifest.compressArtifact(artifactId);
if (compressError) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this call the reportError function?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alexk307 Each case is a little different and it's sometimes not entirely clear. Generally, I'm just using reportErrors when there are multiple errors that I can't just log directly. In this case, there's just 1 error that gets rethrown, and it will be caught in the catch clause and logged on line 63. So I don't think we need to log it again.

if (manifest == null) {
// New computed manifest based on current state of exception list
const newManifest = await manifestManager.buildNewManifest(ManifestConstants.SCHEMA_VERSION);
const diffs = newManifest.diff(Manifest.getDefault(ManifestConstants.SCHEMA_VERSION));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this always be empty since this is the first manifest? Or are diffs created since they are going from nothing to something?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alexk307 There will be a diff that just contains all 3 of the artifacts.

@@ -340,4 +341,95 @@ describe('buildEventTypeSignal', () => {
const resp = await getFullEndpointExceptionList(mockExceptionClient, 'linux', 'v1');
expect(resp.entries.length).toEqual(0);
});

test('it should return a stable hash regardless of order of entries', async () => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💯

public getSha256(): string {
let sha256 = createHash('sha256');
Object.keys(this.entries)
.sort()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we are sorting before generating the hash, won't we need to make sure that the sort is persisted since the Endpoint will have to hash as well to verify the package?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alexk307 The endpoint doesn't verify this hash. This is just for us to know whether or not a policy needs to be updated (if the manifest hashes don't match, we need to update the policy).

@@ -31,85 +85,37 @@ export const getPackageConfigCreateCallback = (
// follow the types/schema expected
let updatedPackageConfig = newPackageConfig as NewPolicyData;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would let updatedPackageConfig: NewPolicyData = newPackageConfig; work here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, we can't use it that way because our type enforces the inputs[] to have 1 member, but inputs[] in the NewPackageConfig can be empty.

TS error:
image

@@ -44,3 +44,90 @@ export const createPackageConfigMock = (): PackageConfig => {
],
};
};

export const createPackageConfigWithInitialManifestMock = (): PackageConfig => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe me more specific in the naming, any reason to no keep this in the security_solution plugin? it will make future change easier no?

Suggested change
export const createPackageConfigWithInitialManifestMock = (): PackageConfig => {
export const createEndpointPackageConfigWithInitialManifestMock = (): PackageConfig => {

Copy link
Contributor Author

@madirey madirey Jul 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nchaulet These are mocks related to the policy, so IMO they belong here. The manifest is part of the policy. I'm happy to rename or move though if that's the consensus. Can we address in a quick follow-up to this one?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We discussed and in our next PR, I'll see if I can make the names more descriptive. Leaving them here for now, as they may be useful for future tests. We can move them to security_solution if they don't end up being useful here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@madirey sorry for the late response.
I agree with @nchaulet on this here - these are endpoint specific mocks that Ingest knows nothing about. We only use their data structure to store our Policy data in (the area where we store it accepts any json blob).

We should really move them to our Plugin (probably under the generator we have in /common/endpoint.

@kibanamachine
Copy link
Contributor

💚 Build Succeeded

Build metrics

✅ unchanged

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

@madirey madirey merged commit 5356941 into elastic:master Jul 17, 2020
@madirey madirey deleted the policy-creation-callbacks branch July 17, 2020 20:51
madirey added a commit to madirey/kibana that referenced this pull request Jul 17, 2020
…cy when there are changes (elastic#72000)

* Refactor security_solution policy creation callback - part 1

* Fix manifest dispatch

* Change how dispatches are performed

* simplify manifest types

* Remove unused mock

* Fix tests

* one place to construct artifact ids

* fixing linter exceptions

* Add tests for stable hashes

* Additional testing and type cleanup

* Remove unnecessary log

* Minor fixup

* jsdoc

* type fixup

* Additional type adjustments
madirey added a commit that referenced this pull request Jul 17, 2020
…cy when there are changes (#72000) (#72345)

* Refactor security_solution policy creation callback - part 1

* Fix manifest dispatch

* Change how dispatches are performed

* simplify manifest types

* Remove unused mock

* Fix tests

* one place to construct artifact ids

* fixing linter exceptions

* Add tests for stable hashes

* Additional testing and type cleanup

* Remove unnecessary log

* Minor fixup

* jsdoc

* type fixup

* Additional type adjustments
madirey added a commit that referenced this pull request Jul 17, 2020
…cy when there are changes (#72000) (#72344)

* Refactor security_solution policy creation callback - part 1

* Fix manifest dispatch

* Change how dispatches are performed

* simplify manifest types

* Remove unused mock

* Fix tests

* one place to construct artifact ids

* fixing linter exceptions

* Add tests for stable hashes

* Additional testing and type cleanup

* Remove unnecessary log

* Minor fixup

* jsdoc

* type fixup

* Additional type adjustments
gmmorris added a commit to gmmorris/kibana that referenced this pull request Jul 20, 2020
* master:
  [Observability] Remove app logos (elastic#72259)
  Fix float percentiles line chart (elastic#71902)
  update chromedriver to 84 (elastic#72228)
  [esArchiver] actually re-delete the .kibana index if we lose recreate race (elastic#72354)
  [Maps] convert SavedGisMap to TS (elastic#72286)
  [DOCS] Removes occurrences of X-Pack Security and Reporting (elastic#72302)
  use WORKSPACE env var for stack_functional_integration tests, fix navigate path (elastic#71908)
  [Monitoring] Fix issue with ES node detail status (elastic#72298)
  [SIEM] Updates consumer in export_rule archive (elastic#72324)
  [kbn/dev-utils] add RunWithCommands utility (elastic#72311)
  [Security Solution][Endpoint][Exceptions] Only write manifest to policy when there are changes (elastic#72000)
  skip flaky suite (elastic#72339)
  [ML] Fix annotations pagination & change labels from letters to numbers (elastic#72204)
  [Lens] Fix switching with layers (elastic#71982)
  [Maps] 7.9 documenation updates (elastic#71893)
  docs: ✏️ add "Explore underlying data" user docs (elastic#70807)
  [Security Solution][Exceptions] - Remove initial add exception item button in builder (elastic#72215)
  Fix indentation level in code exploration doc (elastic#72274)
  register graph usage (elastic#72041)
  [Monitoring] Added a case for Alerting if security/ssl is disabled (elastic#71846)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Fixes for quality problems that affect the customer experience Feature:Endpoint Elastic Endpoint feature release_note:enhancement Team:Endpoint Response Endpoint Response Team Team:Fleet Team label for Observability Data Collection Fleet team v7.9.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants