Skip to content

[Dataset quality] Add Flyout Integration Actions#179401

Merged
mohamedhamed-ahmed merged 18 commits intoelastic:mainfrom
mohamedhamed-ahmed:178843-add-integration-actions
Apr 2, 2024
Merged

[Dataset quality] Add Flyout Integration Actions#179401
mohamedhamed-ahmed merged 18 commits intoelastic:mainfrom
mohamedhamed-ahmed:178843-add-integration-actions

Conversation

@mohamedhamed-ahmed
Copy link
Copy Markdown
Contributor

@mohamedhamed-ahmed mohamedhamed-ahmed commented Mar 26, 2024

closes #178843

📝 Summary

This PR adds actions to the integration section in the dataset quality flyout.
These actions navigate to different integration-related pages.
The Dashboards action is only visible if the integration does have dashboard assets installed, otherwise its hidden.

🎥 Demo

IntegrationActions.mov

@ghost
Copy link
Copy Markdown

ghost commented Mar 26, 2024

🤖 GitHub comments

Expand to view the GitHub comments

Just comment with:

  • /oblt-deploy : Deploy a Kibana instance using the Observability test environments.
  • /oblt-deploy-serverless : Deploy a serverless Kibana instance using the Observability test environments.
  • run elasticsearch-ci/docs : Re-trigger the docs validation. (use unformatted text in the comment!)

@mohamedhamed-ahmed mohamedhamed-ahmed added release_note:skip Skip the PR/issue when compiling release notes backport:skip This PR does not require backporting Team:obs-onboarding Observability Onboarding Team v8.14.0 labels Mar 27, 2024
@mohamedhamed-ahmed mohamedhamed-ahmed marked this pull request as ready for review March 27, 2024 02:02
@mohamedhamed-ahmed mohamedhamed-ahmed requested a review from a team as a code owner March 27, 2024 02:02
@elasticmachine
Copy link
Copy Markdown
Contributor

Pinging @elastic/obs-ux-logs-team (Team:obs-ux-logs)

@mohamedhamed-ahmed
Copy link
Copy Markdown
Contributor Author

/ci

@yngrdyn yngrdyn self-assigned this Mar 27, 2024
@yngrdyn
Copy link
Copy Markdown
Contributor

yngrdyn commented Mar 27, 2024

/oblt-deploy-serverless

@mohamedhamed-ahmed
Copy link
Copy Markdown
Contributor Author

By my understanding it should be avoided to use the saved object client on saved objects that are not defined by the current plugin (instead, the owner plugin should expose logic to do so via the contract).

@flash1293 I see the point there and I agree on the concept in general. Let me just try to explain what I have in mind.

So in our case we want to query 2 different SOs to get the data we need:

  1. epm_pckages => this is owned by fleet and we can use the service you referred to, the only thing that need to be modified there is to make that function accept filtration options so that we can send filters to the SO. Maybe @kpollich can advice here

  2. dashboard => I don't think this is owned by fleet and that is why they are doing the query and filtration on their side after they query the epm_packages SO, and we will still need to do the same on our side, unless this service is exposed from somewhere else that we can make use of.

Ideally how I see that interaction with SO is either types are exposed from a central place and we use the abstraction already provided by the SO, or each SO type owner exposes a service that we can use as the case with fleet here.

@flash1293
Copy link
Copy Markdown
Contributor

For dashboards there is the find dashboards service on the client that works on ids:

findByIds: (ids: string[]) => Promise<FindDashboardsByIdResponse[]>;

So we could use the fleet API on the server side to get the dashboard ids we care about (with the extension on the fleet side as mentioned, but that makes sense to me) and the dashboard find service on the client:

findByIds: (ids: string[]) => Promise<FindDashboardsByIdResponse[]>;

It looks like we need only the name, not the full saved object, maybe that's worth an extension as well. @ThomThomson do you have any guidance here? It seems like the dashboard find service sits on top of the content management service and it shouldn't be hard for it to extend to to handle this use case as well./

@mohamedhamed-ahmed mohamedhamed-ahmed requested review from a team as code owners March 28, 2024 12:59
@kpollich
Copy link
Copy Markdown
Member

I don't think it would be a reason to block this PR, but I'm interested what @kpollich thinks about this - Kyle, in your opinion what's the "right" way to access integration details like in this PR? I can imagine this will also become relevant in the context of onboarding as it will have a similar integration of showing/linking to assets of an integration. The packageService exposed via the fleet plugin looks related in this context:

I think directly querying for saved objects managed by other plugins is probably a bit of an antipattern in Kibana, and generally the recommendation from the Kibana core folks is for plugins to wrap any saved object operations needed by other plugins in either a server side API exposed in the plugin's start contract or a REST API. Fleet actually does both in this case. Maybe it's worth pinging @elastic/kibana-core just to make sure my understanding of Kibana's recommendations here is not off-base.

The right way to access this data from another Kibana plugin is (in my opinion) probably by consuming the packageService exposed by Fleet's server-side plugin contract, then wrapping that data in an API owned by your plugin if it needs to be exposed client side.

Here's some examples of other plugins that need integration data that take that approach:

packageService.asInternalUser.getInstallation(INTEGRATION_PACKAGE_NAME),
packageService.asInternalUser.fetchFindLatestPackage(INTEGRATION_PACKAGE_NAME),

packageService.asInternalUser.getInstallation(CLOUD_SECURITY_POSTURE_PACKAGE_NAME),
packageService.asInternalUser.fetchFindLatestPackage(CLOUD_SECURITY_POSTURE_PACKAGE_NAME),

export async function getLatestApmPackage({
fleetPluginStart,
request,
}: {
fleetPluginStart: NonNullable<APMPluginStartDependencies['fleet']>;
request: KibanaRequest;
}) {
const packageClient = fleetPluginStart.packageService.asScoped(request);
const latestPackage = await packageClient.fetchFindLatestPackage(
APM_PACKAGE_NAME
);
const packageInfo =
'getBuffer' in latestPackage
? (await packageClient.readBundledPackage(latestPackage)).packageInfo
: latestPackage;
const {
name,
version,
title,
policy_templates: policyTemplates,
} = packageInfo;
const firstTemplate = policyTemplates?.[0];
const policyTemplateInputVars =
firstTemplate && 'inputs' in firstTemplate
? firstTemplate.inputs?.[0].vars || []
: [];
return { package: { name, version, title }, policyTemplateInputVars };
}

epm_pckages => this is owned by fleet and we can use the service you referred to, the only thing that need to be modified there is to make that function accept filtration options so that we can send filters to the SO. Maybe @kpollich can advice here

More than happy to accept a PR that extends the PackageService methods with new parameters that do the filtering you're expecting here, but the filtering can also happen server side in your plugin before sending back an API response if you'd prefer to avoid codeowner churn.

Copy link
Copy Markdown
Contributor

@jughosta jughosta left a comment

Choose a reason for hiding this comment

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

Changes in packages/deeplinks/analytics LGTM

@mohamedhamed-ahmed
Copy link
Copy Markdown
Contributor Author

and the dashboard find service on the client:

@flash1293 good find, I oversaw this. TIL
I think we can use both services in this case after we get some thoughts on passing the filtration params.

Copy link
Copy Markdown
Contributor

@dej611 dej611 left a comment

Choose a reason for hiding this comment

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

Code review only for packages/deeplinks/analytics team owned files 👍

@ThomThomson
Copy link
Copy Markdown
Contributor

ThomThomson commented Apr 1, 2024

It looks like we need only the name, not the full saved object

@flash1293 I remember this was discussed back when we were onboarding Dashboard to content management because there are other places where we only needed a subset of the SO's attributes. We decided to just return the full attributes in all cases but I can't remember the reasoning behind this. Maybe @sebelga would know?

Either way, I'd say it's best practice to use the findDashboardsById method and just throw away the extra data.

@mohamedhamed-ahmed
Copy link
Copy Markdown
Contributor Author

@ThomThomson @kpollich Thanks both for the input here. I will update the PR shortly to consume both services and I guess I will go with filtering out what is not needed on my side and pass only the needed data to the client afterward.

@mohamedhamed-ahmed
Copy link
Copy Markdown
Contributor Author

@flash1293 I have made the necessary changes to consume the fleet service.

Created an issue for the presentation team as discussed with @ThomThomson to expose the dashboard service from the server contract so that we can use it on our side.

For the time being will keep the dashboard SO querying code as is until the above ticket is tackled.

Copy link
Copy Markdown
Contributor

@ThomThomson ThomThomson left a comment

Choose a reason for hiding this comment

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

Deep links changes LGTM! Code only review

await PageObjects.observabilityLogsExplorer.navigateTo();

// Add initial integrations
await PageObjects.observabilityLogsExplorer.setupInitialIntegrations();
Copy link
Copy Markdown
Contributor

@yngrdyn yngrdyn Apr 2, 2024

Choose a reason for hiding this comment

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

Could we move this to before section? I see this is being called in two different it but being cleaned only at the end of these describe. Would that create issues when running the tests?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I see its being called in 3 different tests, I would honestly keep this way so that its not enforced on all tests in case we want to install only 1 specific package or test a case where no packages are installed


await action.click();

await retry.tryForTime(5000, async () => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could we extract this into a helper that checks users have been redirected correctly?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

the thing is checking a user is redirected could be done in many ways and some logic internally can be done differently I am not sure if this can be extracted out

Copy link
Copy Markdown
Contributor

@yngrdyn yngrdyn left a comment

Choose a reason for hiding this comment

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

LGTM, thanks for this work 🚀

@kibana-ci
Copy link
Copy Markdown

💚 Build Succeeded

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
datasetQuality 174 184 +10
management 116 117 +1
total +11

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
@kbn/deeplinks-analytics 6 7 +1

Async chunks

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

id before after diff
datasetQuality 146.5KB 151.1KB +4.6KB

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
@kbn/router-utils 0 1 +1

Page load bundle

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

id before after diff
dashboard 37.0KB 37.1KB +106.0B
datasetQuality 32.3KB 33.2KB +912.0B
total +1018.0B
Unknown metric groups

API count

id before after diff
@kbn/deeplinks-analytics 6 7 +1

History

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

cc @yngrdyn

@mohamedhamed-ahmed mohamedhamed-ahmed merged commit 6d55cc8 into elastic:main Apr 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport:skip This PR does not require backporting release_note:skip Skip the PR/issue when compiling release notes Team:obs-onboarding Observability Onboarding Team v8.14.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Dataset quality] Add integration actions