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

[Fleet] Add toggle for experimental synthetic _source support in Fleet data streams #140132

Merged
merged 13 commits into from
Sep 12, 2022

Conversation

kpollich
Copy link
Member

@kpollich kpollich commented Sep 6, 2022

Summary

Closes #140095

Adds a "synthetic source" toggle to the policy editor for all data streams.

image

In cases where a data stream contains mappings that are incompatible with synthetic source, the errors will be bubbled directly to the user and the policy will not be save-able. e.g.

image

TODO

  • Figure out docs link

@kpollich kpollich added release_note:enhancement Team:Fleet Team label for Observability Data Collection Fleet team labels Sep 6, 2022
@kpollich kpollich self-assigned this Sep 6, 2022
@@ -85,7 +86,7 @@ export const onPackagePolicyPostCreateCallback = async (
* Callback to handle deletion of PackagePolicies in Fleet
*/
export const removeCspRulesInstancesCallback = async (
deletedPackagePolicy: DeletePackagePoliciesResponse[number],
deletedPackagePolicy: DeepReadonly<DeletePackagePoliciesResponse[number]>,
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 fixes a type issue that was revealed when we added an array field to the PackagePolicyPackage type that gets used in the DeletePackagePoliciesResponse type.

I think updating this type to expect a DeepReadOnly is actually just correct based on the usage of this callback.

const varConfigEntry = packagePolicyInputStream.vars?.[varName];
const value = varConfigEntry?.value;
const frozen = varConfigEntry?.frozen ?? false;
<>
Copy link
Member Author

Choose a reason for hiding this comment

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

A lot of this diff is whitespace due to introducing a fragment at the top level. GitHub's ignore whitespace setting for this PR is probably your friend here 🙂

features: {
type: 'nested',
properties: {
synthetic_source: { type: 'boolean' },
Copy link
Member Author

Choose a reason for hiding this comment

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

I felt it was better to be explicit about what features exist here, rather than just accepting any set of key/values. We'll need to expand this with additional settings moving forward.

);

// Delete the experimental features map from the package policy so it doesn't get persisted
delete packagePolicy.package.experimental_data_stream_features;
Copy link
Member Author

Choose a reason for hiding this comment

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

We pass the experimental data stream features array on the actual package policy object that comes back through the package policy create/update APIs. This is great for getting the data into our service here, but we don't actually want to persist that experimental features array on the package policy object.

This function "hoists" the experimental features array up out of the package policy to store it at a higher level, so we need to clean it up at the end.

@kpollich kpollich marked this pull request as ready for review September 7, 2022 15:45
@kpollich kpollich requested review from a team as code owners September 7, 2022 15:45
@elasticmachine
Copy link
Contributor

Pinging @elastic/fleet (Team:Fleet)

mappings: {
...componentTemplate.template.mappings,
_source: {
mode: featureMapEntry.features.synthetic_source ? 'synthetic' : 'stored',
Copy link
Member Author

Choose a reason for hiding this comment

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

@nchaulet here we determine the value for the synthetic source property.

Although looking at this now I think we can optimize to not perform a PUT if the value is unchanged.

@nchaulet
Copy link
Member

nchaulet commented Sep 7, 2022

@kpollich Are missing some code also to handle the upgrade of a package, I think the experiment will be loss on package update here no? maybe the same for force reinstall too?

@@ -873,6 +907,10 @@ class PackagePolicyService implements PackagePolicyServiceInterface {
namespace: newPolicy.namespace ?? 'default',
description: newPolicy.description ?? '',
enabled: newPolicy.enabled ?? true,
package: {
...newPP.package!,
experimental_data_stream_features: newPolicy.package?.experimental_data_stream_features,
Copy link
Member

Choose a reason for hiding this comment

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

Should we persist the experimental features on the package policy, or populate that from the package saved object? it seems to me that that feature is shared by all the package policy using this package

Copy link
Member Author

Choose a reason for hiding this comment

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

We only have the value on the package policy here so we can pass it easily to and from the policy editor. It gets persisted on the epm-package saved object.

Putting it on packagePolicy.package here just made it easiest to access when rendering the policy editor. Open to other approaches.

Copy link
Member

Choose a reason for hiding this comment

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

Putting it on packagePolicy.package here just made it easiest to access when rendering the policy editor. Open to other approaches.

let's consider you have two package policy using nginx package (package policy 1, package policy 2)

  1. you edit package policy 1 to enable the experiment
  2. you visit package policy 2 the experiment is shown as disabled but in reality it's enabled no?

I think we should fetch the installation in the package policy editor.

it is clearer?

Copy link
Member Author

Choose a reason for hiding this comment

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

I added logic to packagePolicyService.get in this PR to provide the experimental info on packagePolicy.package in the API response for package policies. We do fetch from the installation saved object and hydrate the resulting API response body with the experimental feature data.

It might make a little more sense to return it separately somehow, or to have a separate API request for the policy editor to fetch the installation on its own, though. I could see an argument for that.

Copy link
Member

Choose a reason for hiding this comment

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

If we fetch it in the API response there is probably no need to persist on the package policy saved object no?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah we don't want to persist it on the package policy saved object. It shouldn't be saved there at all. We are deleteing the property before it gets saved. If it's being saved then it's a bug in this PR.

@kpollich
Copy link
Member Author

kpollich commented Sep 7, 2022

@kpollich Are missing some code also to handle the upgrade of a package, I think the experiment will be loss on package update here no? maybe the same for force reinstall too?

Yeah I think we need some logic in our upgrade API to pull the values of these experimental opt-ins. I will take a look at this.

@kpollich
Copy link
Member Author

kpollich commented Sep 7, 2022

Force install is an interesting case. I would expect a force reinstall to wipe out any existing package level settings like this, so I think this is working as intended. Curious to hear if there are objections to that approach.

Comment on lines +293 to 318
let experimentalFeatures: ExperimentalDataStreamFeature[] | undefined;

if (packagePolicySO.attributes.package?.name) {
const installation = await soClient.get<Installation>(
PACKAGES_SAVED_OBJECT_TYPE,
packagePolicySO.attributes.package?.name
);

if (installation && !installation.error) {
experimentalFeatures = installation.attributes?.experimental_data_stream_features;
}
}

const response = {
id: packagePolicySO.id,
version: packagePolicySO.version,
...packagePolicySO.attributes,
};

// If possible, return the experimental features map for the package policy's `package` field
if (experimentalFeatures && response.package) {
response.package.experimental_data_stream_features = experimentalFeatures;
}

return response;
}
Copy link
Member Author

Choose a reason for hiding this comment

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

@nchaulet here's where we fetch the installation and include it in the package policy object returned from packagePolicyService.get()

@nchaulet
Copy link
Member

nchaulet commented Sep 7, 2022

I think I found another path where we need to handle that, when you bump FLEET_INSTALL_FORMAT_VERSION looks like the settings is not preserved on the next setup

@kpollich
Copy link
Member Author

kpollich commented Sep 8, 2022

Upgrade path has been updated to handle these new settings in 50f2edd..

I think I found another path where we need to handle that, when you bump FLEET_INSTALL_FORMAT_VERSION looks like the settings is not preserved on the next setup

Taking a look at this next.

@kpollich
Copy link
Member Author

kpollich commented Sep 8, 2022

@elasticmachine merge upstream

@kpollich
Copy link
Member Author

kpollich commented Sep 9, 2022

@nchaulet Can you clarify the code path where FLEET_FORMAT_VERSION is being updated and blowing away the experimental features settings? I've been digging through the code but it's not something I've come across before and I'm having trouble tracking down the specific path we're talking about here.

@kpollich
Copy link
Member Author

kpollich commented Sep 9, 2022

I removed the "Review our docs" link from this UI for now since we don't have docs to link to for these experimental features. When we take on the other two features it'd probably make sense to reach out to the docs team to get something together then, but for now with just the one-off synthetic source toggle that's mainly going to be used by integration maintainers to test the feature I think it's fine to remove the link.

@kpollich
Copy link
Member Author

kpollich commented Sep 9, 2022

@elasticmachine merge upstream

@kpollich
Copy link
Member Author

kpollich commented Sep 9, 2022

I ran through this process and everything worked as expected

  • Install a package and set synthetic source = true on a data stream
  • Bump the hard coded FLEET_INSTALL_FORMAT_VERSION constant in Fleet’s config
  • Re-run Fleet setup
  • Verify that the synthetic source setting remains enabled on the data stream

All of this worked as expected after a few fixes I made in d8d751a

I've also added a few tests for the experimental data stream settings utilities.

@kpollich
Copy link
Member Author

kpollich commented Sep 9, 2022

@elasticmachine merge upstream

@kpollich kpollich requested a review from nchaulet September 12, 2022 12:34
@kpollich
Copy link
Member Author

@elasticmachine merge upstream

@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 873 875 +2

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
fleet 865.8KB 867.6KB +1.7KB

Public APIs missing exports

Total count of every type that is part of your API that should be exported but is not. This will cause broken links in the API documentation system. Target amount is 0. Run node scripts/build_api_docs --plugin [yourplugin] --stats exports for more detailed information.

id before after diff
fleet 10 11 +1

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
fleet 105.7KB 105.7KB +40.0B

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/saved-objects-service.html#_mappings

id before after diff
epm-packages 22 26 +4
Unknown metric groups

API count

id before after diff
fleet 970 972 +2

History

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

cc @kpollich

@kpollich kpollich merged commit cc5ff75 into elastic:main Sep 12, 2022
@kibanamachine kibanamachine added v8.5.0 backport:skip This commit does not require backporting labels Sep 12, 2022
@jen-huang jen-huang added the QA:Ready for Testing Code is merged and ready for QA to validate label Sep 19, 2022
@kpollich kpollich deleted the 140095-synthetic-source-toggle branch September 23, 2022 12:45
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 QA:Ready for Testing Code is merged and ready for QA to validate release_note:enhancement 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.

[Fleet] Add UI toggle for synthetic _source to data streams
7 participants