-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
Conversation
Pinging @elastic/endpoint-app-team (Feature:Endpoint) |
Pinging @elastic/endpoint-response (Team:Endpoint Response) |
Pinging @elastic/ingest-management (Team:Ingest Management) |
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) { |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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)); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 () => { |
There was a problem hiding this comment.
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() |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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).
x-pack/plugins/security_solution/server/endpoint/ingest_integration.ts
Outdated
Show resolved
Hide resolved
@@ -31,85 +85,37 @@ export const getPackageConfigCreateCallback = ( | |||
// follow the types/schema expected | |||
let updatedPackageConfig = newPackageConfig as NewPolicyData; |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
x-pack/plugins/security_solution/server/endpoint/lib/artifacts/task.ts
Outdated
Show resolved
Hide resolved
x-pack/plugins/security_solution/server/endpoint/services/artifacts/artifact_client.test.ts
Outdated
Show resolved
Hide resolved
@@ -44,3 +44,90 @@ export const createPackageConfigMock = (): PackageConfig => { | |||
], | |||
}; | |||
}; | |||
|
|||
export const createPackageConfigWithInitialManifestMock = (): PackageConfig => { |
There was a problem hiding this comment.
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?
export const createPackageConfigWithInitialManifestMock = (): PackageConfig => { | |
export const createEndpointPackageConfigWithInitialManifestMock = (): PackageConfig => { |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
.
💚 Build SucceededBuild metrics
History
To update your PR or re-run it, just comment with: |
…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
…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
…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
* 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)
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:
@ts-ignore
instances and cleaned up typesgetSnapshot
terminology in ManifestManager. Updates are now more explicit.Checklist
Delete any items that are not applicable to this PR.
For maintainers