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] add package_policy_id to .fleet-policies inputs #137355

Merged
merged 2 commits into from
Aug 15, 2022

Conversation

joeypoon
Copy link
Member

Summary

Add migration for enriching .fleet-policies.inputs with package_policy_id as discussed in https://github.com/elastic/security-team/issues/3918#issuecomment-1176815273.

Checklist

For maintainers

@joeypoon joeypoon added release_note:skip Skip the PR/issue when compiling release notes Team:Fleet Team label for Observability Data Collection Fleet team v8.5.0 labels Jul 27, 2022
@joeypoon joeypoon requested review from joshdover and kpollich July 27, 2022 20:46
const policies = await agentPolicyService.getByIDsAsMap(soClient, agentPolicyIds);
const fullPolicies = await Promise.all(
agentPolicyIds.map((agentPolicyId) =>
// TODO: make this a bulk
Copy link
Member Author

Choose a reason for hiding this comment

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

making this a bulk seemed a bit more involved so wanted to get some thoughts on logic so far and whether this would even be needed.

Copy link
Contributor

@joshdover joshdover Aug 2, 2022

Choose a reason for hiding this comment

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

Taking a bit deeper look at getFullAgentPolicy, using it this way will fetch a few objects that will be re-used across agent policies (outputs, settings, upgrade download source uri), so we could save some round trips to ES in doing these fetches once and re-using them here.

This will likely only be a problem for users that have many thousands of agent policies, which we do have some users who use that many.

That said, this migration is a one time event for users upgrading from <8.5 so I don't want to spend a whole of time refactoring this if we can avoid it. @kpollich what do you think about deferring on optimizing this?

Copy link
Member

Choose a reason for hiding this comment

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

I'm +1 on deferring those optimizations here with the caveat that we capture essentially what @joshdover has said above in a code comment replacing the current TODO

refresh: 'wait_for',
});

// TODO: make this a bulk
Copy link
Member Author

Choose a reason for hiding this comment

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

}
})
);
await agentPolicyService.deployPolicies(soClient, outdatedAgentPolicyIds);
Copy link
Member Author

Choose a reason for hiding this comment

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

this change wasn't really necessary but since I took the time to make deployPolicies, I figured it was a quick change 🤷‍♂️ .

@joeypoon joeypoon force-pushed the feature/package-policy-id branch from 3892256 to 2a77c2f Compare July 28, 2022 22:34
@joeypoon joeypoon marked this pull request as ready for review July 29, 2022 14:33
@joeypoon joeypoon requested a review from a team as a code owner July 29, 2022 14:33
@elasticmachine
Copy link
Contributor

Pinging @elastic/fleet (Team:Fleet)

}, [] as FleetServerPolicy[]);

const fleetServerPoliciesBulkBody = fleetServerPolicies.flatMap((fleetServerPolicy) => [
{ index: { _id: uuid() } },
Copy link
Contributor

Choose a reason for hiding this comment

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

Since this migration could potentially be executed more than once by different Kibana nodes, I think we should use a deterministic ID here to avoid creating duplicate documents in .fleet-policies.

In other places in Kibana, we've used uuid.v5() with an appropriate seed for this. IMO the policy_id and revision_idx fields should be sufficient, something like this:

import uuidv5 from 'uuid/v5';

// ...

{ index: { _id: uuidv5(`${fleetServerPolicy.policy_id}:${fleetServerPolicy.revision_idx}`, uuidv5.DNS) } }

We'll then need to handle the error on the esClient.bulk correctly (and maybe log a debug message?)

Copy link
Member Author

Choose a reason for hiding this comment

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

makes sense, I'll get this updated.

Copy link
Member

@kpollich kpollich left a comment

Choose a reason for hiding this comment

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

Awesome work so far, @joeypoon - I've just left a few comments here and there. I'll review further in depth when @joshdover's requested changes are made.

soClient: SavedObjectsClientContract,
ids: string[],
options: { fields?: string[] } = {}
): Promise<{ [id: string]: AgentPolicy }> {
Copy link
Member

Choose a reason for hiding this comment

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

I think this function could likely be shortened or possibly replaced by keyBy from Lodash, especially since we only consume this public method in one place. The service methods don't need to be overly concerned with the structure of the results if callers can use transformation utilities directly.

const policies = await agentPolicyService.getByIDsAsMap(soClient, agentPolicyIds);
const fullPolicies = await Promise.all(
agentPolicyIds.map((agentPolicyId) =>
// TODO: make this a bulk
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// TODO: make this a bulk
// There are some potential performance concerns around using `getFullAgentPolicy` in this context, e.g.
// re-fetching outputs, settings, and upgrade download source URI data for each policy. This could potentially
// be a bottleneck in environments with several thousand agent policies being deployed here.

@joeypoon joeypoon force-pushed the feature/package-policy-id branch from 1050a35 to cc71d01 Compare August 4, 2022 21:57
@juliaElastic
Copy link
Contributor

@elasticmachine merge upstream

@kpollich kpollich self-requested a review August 9, 2022 14:51
Copy link
Member

@kpollich kpollich left a comment

Choose a reason for hiding this comment

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

Just a few tiny nitpicks on some minor things, but otherwise LGTM! Thanks for your contributions here @joeypoon! 🚀


import { DEFAULT_SPACE_ID } from '@kbn/spaces-plugin/common/constants';

import { lt } from 'semver';
Copy link
Member

Choose a reason for hiding this comment

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

(nit) Can we group this dependency with the other "external package" imports above - e.g. below p-map?

Comment on lines +743 to +744
if (!policy) {
return acc;
}
Copy link
Member

Choose a reason for hiding this comment

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

Thanks for using a guard clause here - much appreciated 👍

return [...acc, value];
}, [] as BulkResponseItem[]);

logger.debug(`deployPolicies failed to index: ${JSON.stringify(erroredDocuments)}`);
Copy link
Member

Choose a reason for hiding this comment

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

Hmm, super nitpicky here, but could we avoid having the method name in this debug log and lean towards "plain english" logging output? e.g.

logger.debug(`Failed to index documents during policy deployment: ${JSON.stringify(erroredDocuments)}`)

@joeypoon joeypoon force-pushed the feature/package-policy-id branch from b5323fa to a3a9992 Compare August 15, 2022 20:03
@joeypoon joeypoon enabled auto-merge (squash) August 15, 2022 20:03
@kibana-ci
Copy link
Collaborator

💚 Build Succeeded

Metrics [docs]

Public APIs missing comments

Total count of every public API that lacks a comment. Target amount is 0. Run node scripts/build_api_docs --plugin [yourplugin] --stats comments for more detailed information.

id before after diff
fleet 860 862 +2

Saved Objects .kibana field count

Every field in each saved object type adds overhead to Elasticsearch. Kibana needs to keep the total field count below Elasticsearch's default limit of 1000 fields. Only specify field mappings for the fields you wish to search on or query. See https://www.elastic.co/guide/en/kibana/master/development-plugin-saved-objects.html#_mappings

id before after diff
ingest-agent-policies 18 19 +1
Unknown metric groups

API count

id before after diff
fleet 955 957 +2

History

  • 💚 Build #63487 succeeded b5323fa1d5370209658082190b36a41ec95bafea
  • 💛 Build #63356 was flaky 9fd330f5ed07da69820dd9f36729a3553ca62592
  • 💚 Build #61637 succeeded 1050a3501e3177b9f32725aa62f1bacabe301005
  • 💔 Build #61327 failed 3892256fb03452989ae32e855b3f2affaab5bbb2

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

@joeypoon joeypoon merged commit 2c96643 into elastic:main Aug 15, 2022
@kibanamachine kibanamachine added the backport:skip This commit does not require backporting label Aug 15, 2022
@joeypoon joeypoon deleted the feature/package-policy-id branch August 15, 2022 21:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport:skip This commit does not require backporting release_note:skip Skip the PR/issue when compiling release notes Team:Fleet Team label for Observability Data Collection Fleet team v8.5.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants