diff --git a/.eslintrc.js b/.eslintrc.js index 6657ba3cb1f01..4e46336ec70ae 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -908,6 +908,7 @@ module.exports = { }, { files: [ + 'x-pack/plugins/aiops/**/*.{js,mjs,ts,tsx}', 'x-pack/plugins/apm/**/*.{js,mjs,ts,tsx}', 'x-pack/plugins/exploratory_view/**/*.{js,mjs,ts,tsx}', 'x-pack/plugins/infra/**/*.{js,mjs,ts,tsx}', diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index be401c26dc0d2..89f769c0f12ec 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -67,6 +67,7 @@ packages/kbn-ci-stats-performance-metrics @elastic/kibana-operations packages/kbn-ci-stats-reporter @elastic/kibana-operations packages/kbn-ci-stats-shipper-cli @elastic/kibana-operations packages/kbn-cli-dev-mode @elastic/kibana-operations +packages/cloud @elastic/kibana-core x-pack/plugins/cloud_integrations/cloud_chat @elastic/kibana-core x-pack/plugins/cloud_integrations/cloud_chat_provider @elastic/kibana-core x-pack/plugins/cloud_integrations/cloud_data_migration @elastic/platform-onboarding diff --git a/.github/workflows/create-deploy-tag.yml b/.github/workflows/create-deploy-tag.yml index abe2e131165ec..85e226d384cc2 100644 --- a/.github/workflows/create-deploy-tag.yml +++ b/.github/workflows/create-deploy-tag.yml @@ -102,7 +102,7 @@ jobs: "", "", " (use Elastic Cloud Staging VPN)", - "", + "", "" ] - name: Post Slack failure message diff --git a/.i18nrc.json b/.i18nrc.json index b5e17c18d3542..4657840019f6c 100644 --- a/.i18nrc.json +++ b/.i18nrc.json @@ -15,6 +15,7 @@ "customIntegrations": "src/plugins/custom_integrations", "customIntegrationsPackage": "packages/kbn-custom-integrations", "dashboard": "src/plugins/dashboard", + "cloud": "packages/cloud", "domDragDrop": "packages/kbn-dom-drag-drop", "controls": "src/plugins/controls", "data": "src/plugins/data", diff --git a/dev_docs/tutorials/performance/running_performance_journey_in_cloud.mdx b/dev_docs/tutorials/performance/running_performance_journey_in_cloud.mdx index 3f8b373afad39..6ab160ac93328 100644 --- a/dev_docs/tutorials/performance/running_performance_journey_in_cloud.mdx +++ b/dev_docs/tutorials/performance/running_performance_journey_in_cloud.mdx @@ -11,7 +11,7 @@ tags: ['kibana', 'onboarding', 'setup', 'performance', 'development', 'telemetry As a way to better understand user experience with Kibana in cloud, we support running performance journeys against Cloud deployments. The process takes a few steps: -- Create a cloud deployment +- Create a cloud deployment (8.11.0+ is supported) - Re-configure deployment with APM enabled and reporting metrics to the monitoring cluster - Create a user with `superuser` role to run tests with - Checkout the branch that matches your cloud deployment version @@ -35,7 +35,7 @@ Navigate to `Advanced Edit` page and change `Deployment Configuration` by adding ``` "user_settings_override_json": { "tracing.apm.enabled": "true", - "tracing.apm.environment": "development", + "tracing.apm.agent.environment": "development", "tracing.apm.agent.service_name": "elasticsearch", "tracing.apm.agent.server_url": "", "tracing.apm.agent.metrics_interval": "120s", @@ -50,6 +50,7 @@ Navigate to `Advanced Edit` page and change `Deployment Configuration` by adding ``` "user_settings_override_json": { + "coreApp.allowDynamicConfigOverrides": true, "elastic.apm.active": true, "elastic.apm.breakdownMetrics": false, "elastic.apm.captureBody": "all", @@ -74,8 +75,28 @@ Note: DEPLOYMENT_ID and YOUR_JOURNEY_NAME values are optional labels to find the Save changes and make sure cluster is restarted successfully. +### Use QAF to prepare the deployment +The quickest way to prepare ESS deployment is to use [QAF](https://github.com/elastic/qaf): + +- Make sure to add `~/.elastic/cloud.json` and ~/.elastic/cloud-admin.json with Cloud API (to create deployment) & Cloud Admin API (to modify it) keys +``` +{ + "api_key": { + "production": "", + "staging": "", + "qa": "" + } +} +``` +- Create deployment and modify it +``` +export EC_DEPLOYMENT_NAME=kibana-perf-8.11 +qaf elastic-cloud deployments create --stack-version 8.11.0-SNAPSHOT --environment staging --region gcp-us-central1 +qaf elastic-cloud deployments configure-for-performance-journeys +``` + ### Run the journey -Make sure you have created user with `superuser` role and the Kibana repo branch is matching your deployment version. +Make sure the Kibana repo branch is matching your deployment version. Set env variables to run FTR against your cloud deployment: ``` @@ -90,4 +111,6 @@ Run your journey with the command: node scripts/functional_test_runner.js --config x-pack/performance/journeys/$YOUR_JOURNEY_NAME.ts` ``` +APM & Telemetry labels will be updated on the fly and metrics/traces should be available in Telemetry Staging and kibana-ops-e2e-perf cluster. + diff --git a/docs/setup/connect-to-elasticsearch.asciidoc b/docs/setup/connect-to-elasticsearch.asciidoc index e271eb6cce5c0..fef9ae71a085b 100644 --- a/docs/setup/connect-to-elasticsearch.asciidoc +++ b/docs/setup/connect-to-elasticsearch.asciidoc @@ -54,8 +54,9 @@ Details for each programming language library that Elastic provides are in the https://www.elastic.co/guide/en/elasticsearch/client/index.html[{es} Client documentation]. If you are running {kib} on our hosted {es} Service, -click *View deployment details* on the *Integrations* view +click *Endpoints* on the *Integrations* view to verify your {es} endpoint and Cloud ID, and create API keys for integration. +Alternatively, the *Endpoints* are also accessible through the top bar help menu. [float] === Add sample data diff --git a/package.json b/package.json index 3b7f8c030fc8f..313ee86a8171d 100644 --- a/package.json +++ b/package.json @@ -173,6 +173,7 @@ "@kbn/chart-expressions-common": "link:src/plugins/chart_expressions/common", "@kbn/chart-icons": "link:packages/kbn-chart-icons", "@kbn/charts-plugin": "link:src/plugins/charts", + "@kbn/cloud": "link:packages/cloud", "@kbn/cloud-chat-plugin": "link:x-pack/plugins/cloud_integrations/cloud_chat", "@kbn/cloud-chat-provider-plugin": "link:x-pack/plugins/cloud_integrations/cloud_chat_provider", "@kbn/cloud-data-migration-plugin": "link:x-pack/plugins/cloud_integrations/cloud_data_migration", diff --git a/packages/cloud/README.md b/packages/cloud/README.md new file mode 100644 index 0000000000000..e387c4b9be959 --- /dev/null +++ b/packages/cloud/README.md @@ -0,0 +1,3 @@ +# @kbn/cloud + +Empty package generated by @kbn/generate diff --git a/packages/cloud/deployment_details/deployment_details.tsx b/packages/cloud/deployment_details/deployment_details.tsx new file mode 100644 index 0000000000000..278709f7b6d32 --- /dev/null +++ b/packages/cloud/deployment_details/deployment_details.tsx @@ -0,0 +1,81 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +import React from 'react'; + +import { + EuiForm, + EuiFlexGroup, + EuiFlexItem, + EuiLink, + EuiButtonEmpty, + EuiSpacer, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { useDeploymentDetails } from './services'; +import { DeploymentDetailsEsInput } from './deployment_details_es_input'; +import { DeploymentDetailsCloudIdInput } from './deployment_details_cloudid_input'; + +const hasActiveModifierKey = (event: React.MouseEvent): boolean => { + return event.metaKey || event.altKey || event.ctrlKey || event.shiftKey; +}; + +export const DeploymentDetails = ({ closeModal }: { closeModal?: () => void }) => { + const { cloudId, elasticsearchUrl, managementUrl, learnMoreUrl, navigateToUrl } = + useDeploymentDetails(); + const isInsideModal = !!closeModal; + + if (!cloudId) { + return null; + } + + return ( + + {/* Elastic endpoint */} + {elasticsearchUrl && } + + {/* Cloud ID */} + + + + + {managementUrl && ( + + + {/* eslint-disable-next-line @elastic/eui/href-or-on-click */} + { + if (!hasActiveModifierKey(e)) { + e.preventDefault(); + navigateToUrl(managementUrl); + } + if (closeModal) { + closeModal(); + } + }} + flush="left" + > + {i18n.translate('cloud.deploymentDetails.createManageApiKeysButtonLabel', { + defaultMessage: 'Create and manage API keys', + })} + + + {!isInsideModal && ( + + + {i18n.translate('cloud.deploymentDetails.learnMoreButtonLabel', { + defaultMessage: 'Learn more', + })} + + + )} + + )} + + ); +}; diff --git a/packages/cloud/deployment_details/deployment_details_cloudid_input.tsx b/packages/cloud/deployment_details/deployment_details_cloudid_input.tsx new file mode 100644 index 0000000000000..a749fe4371715 --- /dev/null +++ b/packages/cloud/deployment_details/deployment_details_cloudid_input.tsx @@ -0,0 +1,46 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +import React, { type FC } from 'react'; +import { + EuiFormRow, + EuiFieldText, + EuiCopy, + EuiButtonIcon, + EuiFlexGroup, + EuiFlexItem, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +export const DeploymentDetailsCloudIdInput: FC<{ cloudId: string }> = ({ cloudId }) => { + return ( + + + + + + + + {(copy) => ( + + )} + + + + + ); +}; diff --git a/packages/cloud/deployment_details/deployment_details_es_input.tsx b/packages/cloud/deployment_details/deployment_details_es_input.tsx new file mode 100644 index 0000000000000..2998b5bade543 --- /dev/null +++ b/packages/cloud/deployment_details/deployment_details_es_input.tsx @@ -0,0 +1,48 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +import React, { type FC } from 'react'; +import { + EuiFormRow, + EuiFieldText, + EuiCopy, + EuiButtonIcon, + EuiFlexGroup, + EuiFlexItem, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +export const DeploymentDetailsEsInput: FC<{ elasticsearchUrl: string }> = ({ + elasticsearchUrl, +}) => { + return ( + + + + + + + + {(copy) => ( + + )} + + + + + ); +}; diff --git a/packages/cloud/deployment_details/deployment_details_modal.tsx b/packages/cloud/deployment_details/deployment_details_modal.tsx new file mode 100644 index 0000000000000..2f3d628c2ca47 --- /dev/null +++ b/packages/cloud/deployment_details/deployment_details_modal.tsx @@ -0,0 +1,69 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +import React, { type FC } from 'react'; +import { i18n } from '@kbn/i18n'; +import { + EuiButton, + EuiFlexGroup, + EuiFlexItem, + EuiLink, + EuiModal, + EuiModalBody, + EuiModalFooter, + EuiModalHeader, + EuiModalHeaderTitle, +} from '@elastic/eui'; +import { useDeploymentDetails } from './services'; +import { DeploymentDetails } from './deployment_details'; + +interface Props { + closeModal: () => void; +} + +export const DeploymentDetailsModal: FC = ({ closeModal }) => { + const { learnMoreUrl } = useDeploymentDetails(); + + return ( + { + closeModal(); + }} + style={{ width: 600 }} + data-test-subj="deploymentDetailsModal" + > + + + {i18n.translate('cloud.deploymentDetails.helpMenuLinks.endpoints', { + defaultMessage: 'Endpoints', + })} + + + + + + + + + + {i18n.translate('cloud.deploymentDetails.modal.learnMoreButtonLabel', { + defaultMessage: 'Learn more', + })} + + + + + {i18n.translate('cloud.deploymentDetails.modal.closeButtonLabel', { + defaultMessage: 'Close', + })} + + + + + + ); +}; diff --git a/packages/cloud/deployment_details/index.ts b/packages/cloud/deployment_details/index.ts new file mode 100644 index 0000000000000..2f37291eecd7c --- /dev/null +++ b/packages/cloud/deployment_details/index.ts @@ -0,0 +1,11 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { DeploymentDetailsKibanaProvider, DeploymentDetailsProvider } from './services'; +export { DeploymentDetails } from './deployment_details'; +export { DeploymentDetailsModal } from './deployment_details_modal'; diff --git a/packages/cloud/deployment_details/services.tsx b/packages/cloud/deployment_details/services.tsx new file mode 100644 index 0000000000000..c4e8be12bb547 --- /dev/null +++ b/packages/cloud/deployment_details/services.tsx @@ -0,0 +1,123 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import React, { FC, useContext } from 'react'; + +export interface DeploymentDetailsContextValue { + cloudId?: string; + elasticsearchUrl?: string; + managementUrl?: string; + learnMoreUrl: string; + navigateToUrl(url: string): Promise; +} + +const DeploymentDetailsContext = React.createContext(null); + +/** + * Abstract external service Provider. + */ +export const DeploymentDetailsProvider: FC = ({ + children, + ...services +}) => { + return ( + + {children} + + ); +}; + +/** + * Kibana-specific service types. + */ +export interface DeploymentDetailsKibanaDependencies { + /** CoreStart contract */ + core: { + application: { + navigateToUrl(url: string): Promise; + }; + }; + /** SharePluginStart contract */ + share: { + url: { + locators: { + get( + id: string + ): undefined | { useUrl: (params: { sectionId: string; appId: string }) => string }; + }; + }; + }; + /** CloudSetup contract */ + cloud: { + isCloudEnabled: boolean; + cloudId?: string; + elasticsearchUrl?: string; + }; + /** DocLinksStart contract */ + docLinks: { + links: { + fleet: { + apiKeysLearnMore: string; + }; + }; + }; +} + +/** + * Kibana-specific Provider that maps to known dependency types. + */ +export const DeploymentDetailsKibanaProvider: FC = ({ + children, + ...services +}) => { + const { + core: { + application: { navigateToUrl }, + }, + cloud: { isCloudEnabled, cloudId, elasticsearchUrl }, + share: { + url: { locators }, + }, + docLinks: { + links: { + fleet: { apiKeysLearnMore }, + }, + }, + } = services; + + const managementUrl = locators + .get('MANAGEMENT_APP_LOCATOR') + ?.useUrl({ sectionId: 'security', appId: 'api_keys' }); + + return ( + + {children} + + ); +}; + +/** + * React hook for accessing pre-wired services. + */ +export function useDeploymentDetails() { + const context = useContext(DeploymentDetailsContext); + + if (!context) { + throw new Error( + 'DeploymentDetailsContext is missing. Ensure your component or React root is wrapped with or .' + ); + } + + return context; +} diff --git a/packages/cloud/jest.config.js b/packages/cloud/jest.config.js new file mode 100644 index 0000000000000..174f01cfc1be6 --- /dev/null +++ b/packages/cloud/jest.config.js @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../..', + roots: ['/packages/cloud'], +}; diff --git a/packages/cloud/kibana.jsonc b/packages/cloud/kibana.jsonc new file mode 100644 index 0000000000000..e39a0dbe40617 --- /dev/null +++ b/packages/cloud/kibana.jsonc @@ -0,0 +1,5 @@ +{ + "type": "shared-common", + "id": "@kbn/cloud", + "owner": "@elastic/kibana-core" +} diff --git a/packages/cloud/package.json b/packages/cloud/package.json new file mode 100644 index 0000000000000..8e0023dc5c7a3 --- /dev/null +++ b/packages/cloud/package.json @@ -0,0 +1,6 @@ +{ + "name": "@kbn/cloud", + "private": true, + "version": "1.0.0", + "license": "SSPL-1.0 OR Elastic License 2.0" +} \ No newline at end of file diff --git a/packages/cloud/tsconfig.json b/packages/cloud/tsconfig.json new file mode 100644 index 0000000000000..c4703bc51cf6c --- /dev/null +++ b/packages/cloud/tsconfig.json @@ -0,0 +1,21 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "outDir": "target/types", + "types": [ + "jest", + "node", + "react" + ] + }, + "include": [ + "**/*.ts", + "**/*.tsx", + ], + "exclude": [ + "target/**/*" + ], + "kbn_references": [ + "@kbn/i18n", + ] +} diff --git a/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header_help_menu.tsx b/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header_help_menu.tsx index e1e43d43ab401..5c3d5bb048737 100644 --- a/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header_help_menu.tsx +++ b/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header_help_menu.tsx @@ -67,6 +67,7 @@ const buildDefaultContentLinks = ({ defaultMessage: 'Open an issue in GitHub', }), href: docLinks.links.kibana.createGithubIssue, + iconType: 'logoGithub', }, ]; @@ -201,17 +202,40 @@ export class HeaderHelpMenu extends Component { return ( - {defaultContentLinks.map(({ href, title, iconType }, i) => { - const isLast = i === defaultContentLinks.length - 1; - return ( - - - {title} - - {!isLast && } - - ); - })} + {defaultContentLinks.map( + ({ href, title, iconType, onClick: _onClick, dataTestSubj }, i) => { + const isLast = i === defaultContentLinks.length - 1; + + if (href && _onClick) { + throw new Error( + 'Only one of `href` and `onClick` should be provided for the help menu link.' + ); + } + + const hrefProps = href ? { href, target: '_blank' } : {}; + const onClick = () => { + if (!_onClick) return; + _onClick(); + this.closeMenu(); + }; + + return ( + + + {title} + + {!isLast && } + + ); + } + )} ); } diff --git a/packages/core/chrome/core-chrome-browser/src/nav_controls.ts b/packages/core/chrome/core-chrome-browser/src/nav_controls.ts index 39b5d1b3b59b1..22c074862151b 100644 --- a/packages/core/chrome/core-chrome-browser/src/nav_controls.ts +++ b/packages/core/chrome/core-chrome-browser/src/nav_controls.ts @@ -18,8 +18,10 @@ export interface ChromeNavControl { /** @public */ export interface ChromeHelpMenuLink { title: string; - href: string; + href?: string; iconType?: string; + onClick?: () => void; + dataTestSubj?: string; } /** diff --git a/packages/kbn-journeys/journey/journey.ts b/packages/kbn-journeys/journey/journey.ts index 7952b8ee7408d..bf3de796265f9 100644 --- a/packages/kbn-journeys/journey/journey.ts +++ b/packages/kbn-journeys/journey/journey.ts @@ -12,14 +12,9 @@ import { Page } from 'playwright'; import callsites from 'callsites'; import { ToolingLog } from '@kbn/tooling-log'; import { FtrConfigProvider } from '@kbn/test'; -import { - FtrProviderContext, - KibanaServer, - Es, - RetryService, -} from '@kbn/ftr-common-functional-services'; - -import { Auth } from '../services/auth'; +import { FtrProviderContext } from '../services/ftr_context_provider'; +import { Es, KibanaServer, Retry, Auth } from '../services'; + import { InputDelays } from '../services/input_delays'; import { KibanaUrl } from '../services/kibana_url'; @@ -37,7 +32,7 @@ export interface BaseStepCtx { kbnUrl: KibanaUrl; kibanaServer: KibanaServer; es: Es; - retry: RetryService; + retry: Retry; auth: Auth; } @@ -141,7 +136,7 @@ export class Journey { getService('kibanaServer'), getService('es'), getService('retry'), - new Auth(getService('config'), getService('log'), getService('kibanaServer')), + getService('auth'), this.config ).initMochaSuite(this.#steps); } diff --git a/packages/kbn-journeys/journey/journey_ftr_config.ts b/packages/kbn-journeys/journey/journey_ftr_config.ts index 1abc141c7bbae..b60f6fa191978 100644 --- a/packages/kbn-journeys/journey/journey_ftr_config.ts +++ b/packages/kbn-journeys/journey/journey_ftr_config.ts @@ -11,7 +11,7 @@ import Path from 'path'; import { v4 as uuidV4 } from 'uuid'; import { REPO_ROOT } from '@kbn/repo-info'; import type { FtrConfigProviderContext, FtrConfigProvider } from '@kbn/test'; -import { commonFunctionalServices } from '@kbn/ftr-common-functional-services'; +import { services } from '../services'; import { AnyStep } from './journey'; import { JourneyConfig } from './journey_config'; @@ -66,7 +66,7 @@ export function makeFtrConfigProvider( bail: true, }, - services: commonFunctionalServices, + services, pageObjects: {}, servicesRequiredForTestAnalysis: ['performance', 'journeyConfig'], diff --git a/packages/kbn-journeys/journey/journey_ftr_harness.ts b/packages/kbn-journeys/journey/journey_ftr_harness.ts index 9df84821de032..0f649e7a1de27 100644 --- a/packages/kbn-journeys/journey/journey_ftr_harness.ts +++ b/packages/kbn-journeys/journey/journey_ftr_harness.ts @@ -9,20 +9,19 @@ import Url from 'url'; import { inspect, format } from 'util'; import { setTimeout } from 'timers/promises'; - import * as Rx from 'rxjs'; import apmNode from 'elastic-apm-node'; import playwright, { ChromiumBrowser, Page, BrowserContext, CDPSession, Request } from 'playwright'; import { asyncMap, asyncForEach } from '@kbn/std'; import { ToolingLog } from '@kbn/tooling-log'; import { Config } from '@kbn/test'; -import { EsArchiver, KibanaServer, Es, RetryService } from '@kbn/ftr-common-functional-services'; import { ELASTIC_HTTP_VERSION_HEADER, X_ELASTIC_INTERNAL_ORIGIN_REQUEST, } from '@kbn/core-http-common'; -import { Auth } from '../services/auth'; +import { AxiosError } from 'axios'; +import { Auth, Es, EsArchiver, KibanaServer, Retry } from '../services'; import { getInputDelays } from '../services/input_delays'; import { KibanaUrl } from '../services/kibana_url'; @@ -40,7 +39,7 @@ export class JourneyFtrHarness { private readonly esArchiver: EsArchiver, private readonly kibanaServer: KibanaServer, private readonly es: Es, - private readonly retry: RetryService, + private readonly retry: Retry, private readonly auth: Auth, private readonly journeyConfig: JourneyConfig ) { @@ -63,15 +62,24 @@ export class JourneyFtrHarness { private async updateTelemetryAndAPMLabels(labels: { [k: string]: string }) { this.log.info(`Updating telemetry & APM labels: ${JSON.stringify(labels)}`); - await this.kibanaServer.request({ - path: '/internal/core/_settings', - method: 'PUT', - headers: { - [ELASTIC_HTTP_VERSION_HEADER]: '1', - [X_ELASTIC_INTERNAL_ORIGIN_REQUEST]: 'ftr', - }, - body: { telemetry: { labels } }, - }); + try { + await this.kibanaServer.request({ + path: '/internal/core/_settings', + method: 'PUT', + headers: { + [ELASTIC_HTTP_VERSION_HEADER]: '1', + [X_ELASTIC_INTERNAL_ORIGIN_REQUEST]: 'ftr', + }, + body: { telemetry: { labels } }, + }); + } catch (error) { + const statusCode = (error as AxiosError).response?.status; + if (statusCode === 404) { + throw new Error( + `Failed to update labels, supported Kibana version is 8.11.0+ and must be started with "coreApp.allowDynamicConfigOverrides:true"` + ); + } else throw error; + } } private async setupApm() { @@ -385,7 +393,7 @@ export class JourneyFtrHarness { } const isServerlessProject = !!this.config.get('serverless'); - const kibanaPage = getNewPageObject(isServerlessProject, page, this.log); + const kibanaPage = getNewPageObject(isServerlessProject, page, this.log, this.retry); this.#_ctx = this.journeyConfig.getExtendedStepCtx({ kibanaPage, diff --git a/packages/kbn-journeys/services/auth.ts b/packages/kbn-journeys/services/auth.ts index 2a2a9719bd49b..1bc015d9f81cc 100644 --- a/packages/kbn-journeys/services/auth.ts +++ b/packages/kbn-journeys/services/auth.ts @@ -10,9 +10,7 @@ import Url from 'url'; import { format } from 'util'; import axios, { AxiosResponse } from 'axios'; -import { ToolingLog } from '@kbn/tooling-log'; -import { Config } from '@kbn/test'; -import { KibanaServer } from '@kbn/ftr-common-functional-services'; +import { FtrService } from './ftr_context_provider'; export interface Credentials { username: string; @@ -22,12 +20,10 @@ export interface Credentials { function extractCookieValue(authResponse: AxiosResponse) { return authResponse.headers['set-cookie']?.[0].toString().split(';')[0].split('sid=')[1] ?? ''; } -export class Auth { - constructor( - private readonly config: Config, - private readonly log: ToolingLog, - private readonly kibanaServer: KibanaServer - ) {} +export class AuthService extends FtrService { + private readonly config = this.ctx.getService('config'); + private readonly log = this.ctx.getService('log'); + private readonly kibanaServer = this.ctx.getService('kibanaServer'); public async login(credentials?: Credentials) { const baseUrl = new URL( diff --git a/packages/kbn-journeys/services/es.ts b/packages/kbn-journeys/services/es.ts new file mode 100644 index 0000000000000..16ca3079a2ab0 --- /dev/null +++ b/packages/kbn-journeys/services/es.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { Client } from '@elastic/elasticsearch'; + +import { createEsClientForFtrConfig, ProvidedType } from '@kbn/test'; +import { FtrProviderContext } from './ftr_context_provider'; + +export function EsProvider({ getService }: FtrProviderContext): Client { + const config = getService('config'); + + return createEsClientForFtrConfig(config); +} + +export type Es = ProvidedType; diff --git a/packages/kbn-journeys/services/ftr_context_provider.ts b/packages/kbn-journeys/services/ftr_context_provider.ts new file mode 100644 index 0000000000000..7dd5038ef3f19 --- /dev/null +++ b/packages/kbn-journeys/services/ftr_context_provider.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { GenericFtrProviderContext, GenericFtrService } from '@kbn/test'; +import { services } from '.'; + +export type FtrProviderContext = GenericFtrProviderContext; +export class FtrService extends GenericFtrService {} diff --git a/packages/kbn-journeys/services/index.ts b/packages/kbn-journeys/services/index.ts new file mode 100644 index 0000000000000..93611e5d5a3f8 --- /dev/null +++ b/packages/kbn-journeys/services/index.ts @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { commonFunctionalServices, RetryService } from '@kbn/ftr-common-functional-services'; +import { EsArchiverProvider } from '@kbn/ftr-common-functional-services/services/es_archiver'; +import { KibanaServerProvider } from '@kbn/ftr-common-functional-services/services/kibana_server'; +import { ProvidedType } from '@kbn/test'; +import { EsProvider } from './es'; +import { AuthService } from './auth'; + +export const services = { + es: EsProvider, + kibanaServer: commonFunctionalServices.kibanaServer, + esArchiver: commonFunctionalServices.esArchiver, + retry: commonFunctionalServices.retry, + auth: AuthService, +}; + +export type EsArchiver = ProvidedType; +export type KibanaServer = ProvidedType; +export type Es = ProvidedType; +export type Auth = AuthService; +export type Retry = RetryService; diff --git a/packages/kbn-journeys/services/page/index.ts b/packages/kbn-journeys/services/page/index.ts index 6a809eb7480f6..6e0aaafcfdc27 100644 --- a/packages/kbn-journeys/services/page/index.ts +++ b/packages/kbn-journeys/services/page/index.ts @@ -8,9 +8,10 @@ import { ToolingLog } from '@kbn/tooling-log'; import { Page } from 'playwright'; +import { Retry } from '..'; import { KibanaPage } from './kibana_page'; import { ProjectPage } from './project_page'; -export function getNewPageObject(isServerless: boolean, page: Page, log: ToolingLog) { - return isServerless ? new ProjectPage(page, log) : new KibanaPage(page, log); +export function getNewPageObject(isServerless: boolean, page: Page, log: ToolingLog, retry: Retry) { + return isServerless ? new ProjectPage(page, log, retry) : new KibanaPage(page, log, retry); } diff --git a/packages/kbn-journeys/services/page/kibana_page.ts b/packages/kbn-journeys/services/page/kibana_page.ts index 72e595601473a..170e009d0cd29 100644 --- a/packages/kbn-journeys/services/page/kibana_page.ts +++ b/packages/kbn-journeys/services/page/kibana_page.ts @@ -9,6 +9,7 @@ import { subj } from '@kbn/test-subj-selector'; import { ToolingLog } from '@kbn/tooling-log'; import { Page } from 'playwright'; +import { Retry } from '..'; interface WaitForRenderArgs { expectedItemsCount: number; @@ -19,10 +20,12 @@ interface WaitForRenderArgs { export class KibanaPage { readonly page: Page; readonly log: ToolingLog; + readonly retry: Retry; - constructor(page: Page, log: ToolingLog) { + constructor(page: Page, log: ToolingLog, retry: Retry) { this.page = page; this.log = log; + this.retry = retry; } async waitForHeader() { @@ -36,25 +39,32 @@ export class KibanaPage { } async waitForRender({ expectedItemsCount, itemLocator, checkAttribute }: WaitForRenderArgs) { - try { - await this.page.waitForFunction( - function renderCompleted(args: WaitForRenderArgs) { - const renderingItems = Array.from(document.querySelectorAll(args.itemLocator)); - const allItemsLoaded = renderingItems.length === args.expectedItemsCount; - return allItemsLoaded - ? renderingItems.every((e) => e.getAttribute(args.checkAttribute) === 'true') - : false; - }, - { expectedItemsCount, itemLocator, checkAttribute } - ); - } catch (err) { - const loaded = await this.page.$$(itemLocator); - const rendered = await this.page.$$(`${itemLocator}[${checkAttribute}="true"]`); - this.log.error( - `'waitForRendering' failed: loaded - ${loaded.length}, rendered - ${rendered.length}, expected count - ${expectedItemsCount}` - ); - throw err; - } + // we can't use `page.waitForFunction` because of CSP while testing on Cloud + await this.retry.waitFor( + `rendering of ${expectedItemsCount} elements with selector ${itemLocator} is completed`, + async () => { + const renderingItems = await this.page.$$(itemLocator); + if (renderingItems.length === expectedItemsCount) { + // all components are loaded, checking if all are rendered + const renderStatuses = await Promise.all( + renderingItems.map(async (item) => { + return (await item.getAttribute(checkAttribute)) === 'true'; + }) + ); + const rendered = renderStatuses.filter((isRendered) => isRendered === true); + this.log.debug( + `waitForRender: ${rendered.length} out of ${expectedItemsCount} are rendered...` + ); + return rendered.length === expectedItemsCount; + } else { + // not all components are loaded yet + this.log.debug( + `waitForRender: ${renderingItems.length} out of ${expectedItemsCount} are loaded...` + ); + return false; + } + } + ); } async waitForVisualizations(count: number) { diff --git a/tsconfig.base.json b/tsconfig.base.json index 030b5c9bbed4c..bb2aec9d5819f 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -128,6 +128,8 @@ "@kbn/ci-stats-shipper-cli/*": ["packages/kbn-ci-stats-shipper-cli/*"], "@kbn/cli-dev-mode": ["packages/kbn-cli-dev-mode"], "@kbn/cli-dev-mode/*": ["packages/kbn-cli-dev-mode/*"], + "@kbn/cloud": ["packages/cloud"], + "@kbn/cloud/*": ["packages/cloud/*"], "@kbn/cloud-chat-plugin": ["x-pack/plugins/cloud_integrations/cloud_chat"], "@kbn/cloud-chat-plugin/*": ["x-pack/plugins/cloud_integrations/cloud_chat/*"], "@kbn/cloud-chat-provider-plugin": ["x-pack/plugins/cloud_integrations/cloud_chat_provider"], diff --git a/x-pack/packages/ml/date_picker/src/components/full_time_range_selector.tsx b/x-pack/packages/ml/date_picker/src/components/full_time_range_selector.tsx index 20e4ca43e233b..5b2a9d880c1b8 100644 --- a/x-pack/packages/ml/date_picker/src/components/full_time_range_selector.tsx +++ b/x-pack/packages/ml/date_picker/src/components/full_time_range_selector.tsx @@ -109,7 +109,9 @@ export const FullTimeRangeSelector: FC = (props) => toasts, http, query, - showFrozenDataTierChoice ? frozenDataPreference === FROZEN_TIER_PREFERENCE.EXCLUDE : false, + showFrozenDataTierChoice === false + ? false + : frozenDataPreference === FROZEN_TIER_PREFERENCE.EXCLUDE, apiPath ); if (typeof callback === 'function' && fullTimeRange !== undefined) { @@ -192,9 +194,16 @@ export const FullTimeRangeSelector: FC = (props) => [sortOptions, frozenDataPreference, setPreference] ); - const buttonTooltip = useMemo( - () => - frozenDataPreference === FROZEN_TIER_PREFERENCE.EXCLUDE ? ( + const buttonTooltip = useMemo(() => { + if (showFrozenDataTierChoice === false) { + return ( + + ); + } else { + return frozenDataPreference === FROZEN_TIER_PREFERENCE.EXCLUDE ? ( = (props) => id="xpack.ml.datePicker.fullTimeRangeSelector.useFullDataIncludingFrozenButtonTooltip" defaultMessage="Use full range of data including frozen data tier, which might have slower search results." /> - ), - [frozenDataPreference] - ); + ); + } + }, [frozenDataPreference, showFrozenDataTierChoice]); return ( @@ -222,7 +231,7 @@ export const FullTimeRangeSelector: FC = (props) => /> - {showFrozenDataTierChoice ? ( + {showFrozenDataTierChoice === false ? null : ( = (props) => {popoverContent} - ) : null} + )} ); }; diff --git a/x-pack/performance/journeys/many_fields_discover.ts b/x-pack/performance/journeys/many_fields_discover.ts index a37207f6e092d..2a801dea4478f 100644 --- a/x-pack/performance/journeys/many_fields_discover.ts +++ b/x-pack/performance/journeys/many_fields_discover.ts @@ -13,7 +13,11 @@ export const journey = new Journey({ esArchives: ['test/functional/fixtures/es_archiver/many_fields'], }) .step('Go to Discover Page', async ({ page, kbnUrl, kibanaPage }) => { - await page.goto(kbnUrl.get(`/app/discover`)); + await page.goto( + kbnUrl.get( + `/app/discover#/?_g=(filters:!(),refreshInterval:(pause:!t,value:60000),time:(from:now-15m,to:now))&_a=(columns:!(),filters:!(),index:'35796250-bb09-11ec-a8e4-a9868e049a39',interval:auto,query:(language:kuery,query:''),sort:!())` + ) + ); await kibanaPage.waitForHeader(); await page.waitForSelector('[data-test-subj="discoverDocTable"][data-render-complete="true"]'); await page.waitForSelector(subj('globalLoadingIndicator-hidden')); diff --git a/x-pack/plugins/aiops/public/components/change_point_detection/fields_config.tsx b/x-pack/plugins/aiops/public/components/change_point_detection/fields_config.tsx index 45b2ccc1c097a..c07af22a5f16a 100644 --- a/x-pack/plugins/aiops/public/components/change_point_detection/fields_config.tsx +++ b/x-pack/plugins/aiops/public/components/change_point_detection/fields_config.tsx @@ -356,6 +356,7 @@ const FieldPanel: FC = ({ = ({ !prevState)} aria-label={i18n.translate('xpack.aiops.changePointDetection.expandConfigLabel', { @@ -480,6 +482,7 @@ const FieldPanel: FC = ({ id={`panelContextMenu_${panelIndex}`} button={ = ({ <> openInDiscover(QUERY_MODE.INCLUDE)} iconType="plusInCircle" @@ -61,6 +62,7 @@ export const TableHeader: FC = ({ openInDiscover(QUERY_MODE.EXCLUDE)} iconType="minusInCircle" diff --git a/x-pack/plugins/aiops/public/components/log_categorization/loading_categorization.tsx b/x-pack/plugins/aiops/public/components/log_categorization/loading_categorization.tsx index 77ba11fd46cc5..208302083fd0c 100644 --- a/x-pack/plugins/aiops/public/components/log_categorization/loading_categorization.tsx +++ b/x-pack/plugins/aiops/public/components/log_categorization/loading_categorization.tsx @@ -43,7 +43,12 @@ export const LoadingCategorization: FC = ({ onClose }) => ( - onClose()}>Cancel + onClose()} + > + Cancel + diff --git a/x-pack/plugins/aiops/public/components/log_categorization/log_categorization_page.tsx b/x-pack/plugins/aiops/public/components/log_categorization/log_categorization_page.tsx index 5ccdca64d1036..bfa609bb5dd21 100644 --- a/x-pack/plugins/aiops/public/components/log_categorization/log_categorization_page.tsx +++ b/x-pack/plugins/aiops/public/components/log_categorization/log_categorization_page.tsx @@ -324,7 +324,12 @@ export const LogCategorizationPage: FC = () => { /> ) : ( - cancelRequest()}>Cancel + cancelRequest()} + > + Cancel + )} diff --git a/x-pack/plugins/aiops/public/components/log_categorization/sampling_menu/random_sampler_range_slider.tsx b/x-pack/plugins/aiops/public/components/log_categorization/sampling_menu/random_sampler_range_slider.tsx index 4f2b62729ca46..2cd70b35d139e 100644 --- a/x-pack/plugins/aiops/public/components/log_categorization/sampling_menu/random_sampler_range_slider.tsx +++ b/x-pack/plugins/aiops/public/components/log_categorization/sampling_menu/random_sampler_range_slider.tsx @@ -92,6 +92,7 @@ export const RandomSamplerRangeSlider = ({ data-test-subj="dvRandomSamplerProbabilityRange" append={ { if (setSamplingProbability && isDefined(samplingProbabilityInput)) { diff --git a/x-pack/plugins/aiops/public/components/log_categorization/sampling_menu/sampling_menu.tsx b/x-pack/plugins/aiops/public/components/log_categorization/sampling_menu/sampling_menu.tsx index e4d18f6dbc260..c4e16d4fabbe6 100644 --- a/x-pack/plugins/aiops/public/components/log_categorization/sampling_menu/sampling_menu.tsx +++ b/x-pack/plugins/aiops/public/components/log_categorization/sampling_menu/sampling_menu.tsx @@ -118,6 +118,7 @@ export const SamplingMenu: FC = ({ randomSampler, reload }) => { id="aiopsSamplingOptions" button={ setShowSamplingOptionsPopover(!showSamplingOptionsPopover)} iconSide="right" iconType="arrowDown" diff --git a/x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_results.tsx b/x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_results.tsx index f1b1a6d38de12..a62db054d4d52 100644 --- a/x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_results.tsx +++ b/x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_results.tsx @@ -409,7 +409,11 @@ export const LogRateAnalysisResults: FC = ({ )} {overrides !== undefined ? (

- startHandler(true)}> + startHandler(true)} + > void; + core: CoreStart; + docLinks: DocLinksStart; + cloud: CloudStart; + share: SharePluginStart; +} + +export const EndpointsModal = ({ core, share, cloud, docLinks, closeModal }: Props) => { + return ( + + + + ); +}; diff --git a/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/help_menu_links.ts b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/help_menu_links.tsx similarity index 53% rename from x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/help_menu_links.ts rename to x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/help_menu_links.tsx index 82b0e86e6569a..15270c5876214 100644 --- a/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/help_menu_links.ts +++ b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/help_menu_links.tsx @@ -4,17 +4,32 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +import React from 'react'; import { i18n } from '@kbn/i18n'; import { ChromeHelpMenuLink } from '@kbn/core-chrome-browser'; import type { DocLinksStart } from '@kbn/core-doc-links-browser'; +import type { CoreStart } from '@kbn/core/public'; +import type { CloudStart } from '@kbn/cloud-plugin/public'; +import type { SharePluginStart } from '@kbn/share-plugin/public'; +import { toMountPoint } from '@kbn/react-kibana-mount'; + +import { EndpointsModal } from './endpoints_modal'; export const createHelpMenuLinks = ({ docLinks, helpSupportUrl, + core, + cloud, + share, }: { docLinks: DocLinksStart; + core: CoreStart; + cloud: CloudStart; + share: SharePluginStart; helpSupportUrl: string; }) => { + const { overlays } = core; + const helpMenuLinks: ChromeHelpMenuLink[] = [ { title: i18n.translate('xpack.cloudLinks.helpMenuLinks.documentation', { @@ -34,6 +49,27 @@ export const createHelpMenuLinks = ({ }), href: docLinks.links.kibana.feedback, }, + { + title: i18n.translate('xpack.cloudLinks.helpMenuLinks.endpoints', { + defaultMessage: 'Endpoints', + }), + iconType: 'console', + dataTestSubj: 'endpointsHelpLink', + onClick: () => { + const modal = overlays.openModal( + toMountPoint( + modal.close()} + />, + { theme: core.theme, i18n: core.i18n } + ) + ); + }, + }, ]; return helpMenuLinks; diff --git a/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/maybe_add_cloud_links.test.ts b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/maybe_add_cloud_links.test.ts index b9045fdc9a59f..d680d6cce4f4f 100644 --- a/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/maybe_add_cloud_links.test.ts +++ b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/maybe_add_cloud_links.test.ts @@ -8,6 +8,7 @@ import { cloudMock } from '@kbn/cloud-plugin/public/mocks'; import { coreMock } from '@kbn/core/public/mocks'; import { securityMock } from '@kbn/security-plugin/public/mocks'; +import { sharePluginMock } from '@kbn/share-plugin/public/mocks'; import { maybeAddCloudLinks } from './maybe_add_cloud_links'; @@ -18,6 +19,7 @@ describe('maybeAddCloudLinks', () => { maybeAddCloudLinks({ core, security, + share: sharePluginMock.createStartContract(), cloud: { ...cloudMock.createStart(), isCloudEnabled: false }, }); // Since there's a promise, let's wait for the next tick @@ -35,6 +37,7 @@ describe('maybeAddCloudLinks', () => { maybeAddCloudLinks({ security, core, + share: sharePluginMock.createStartContract(), cloud: { ...cloudMock.createStart(), isCloudEnabled: true }, }); // Since there's a promise, let's wait for the next tick @@ -90,6 +93,12 @@ describe('maybeAddCloudLinks', () => { "href": "https://www.elastic.co/products/kibana/feedback?blade=kibanafeedback", "title": "Give feedback", }, + Object { + "dataTestSubj": "endpointsHelpLink", + "iconType": "console", + "onClick": [Function], + "title": "Endpoints", + }, ], ] `); @@ -103,6 +112,7 @@ describe('maybeAddCloudLinks', () => { maybeAddCloudLinks({ security, core, + share: sharePluginMock.createStartContract(), cloud: { ...cloudMock.createStart(), isCloudEnabled: true }, }); // Since there's a promise, let's wait for the next tick @@ -157,6 +167,12 @@ describe('maybeAddCloudLinks', () => { "href": "https://www.elastic.co/products/kibana/feedback?blade=kibanafeedback", "title": "Give feedback", }, + Object { + "dataTestSubj": "endpointsHelpLink", + "iconType": "console", + "onClick": [Function], + "title": "Endpoints", + }, ], ] `); @@ -172,6 +188,7 @@ describe('maybeAddCloudLinks', () => { maybeAddCloudLinks({ security, core, + share: sharePluginMock.createStartContract(), cloud: { ...cloudMock.createStart(), isCloudEnabled: true }, }); // Since there's a promise, let's wait for the next tick diff --git a/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/maybe_add_cloud_links.ts b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/maybe_add_cloud_links.ts index 33fb4df7bfce2..2772c87d124d3 100644 --- a/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/maybe_add_cloud_links.ts +++ b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/maybe_add_cloud_links.ts @@ -11,6 +11,7 @@ import { i18n } from '@kbn/i18n'; import type { CloudStart } from '@kbn/cloud-plugin/public'; import type { CoreStart } from '@kbn/core/public'; import type { SecurityPluginStart } from '@kbn/security-plugin/public'; +import type { SharePluginStart } from '@kbn/share-plugin/public'; import { createUserMenuLinks } from './user_menu_links'; import { createHelpMenuLinks } from './help_menu_links'; @@ -18,9 +19,10 @@ export interface MaybeAddCloudLinksDeps { core: CoreStart; security: SecurityPluginStart; cloud: CloudStart; + share: SharePluginStart; } -export function maybeAddCloudLinks({ core, security, cloud }: MaybeAddCloudLinksDeps): void { +export function maybeAddCloudLinks({ core, security, cloud, share }: MaybeAddCloudLinksDeps): void { const userObservable = defer(() => security.authc.getCurrentUser()).pipe( // Check if user is a cloud user. map((user) => user.elastic_cloud_user), @@ -54,6 +56,9 @@ export function maybeAddCloudLinks({ core, security, cloud }: MaybeAddCloudLinks const helpMenuLinks = createHelpMenuLinks({ docLinks: core.docLinks, helpSupportUrl, + core, + share, + cloud, }); core.chrome.setHelpMenuLinks(helpMenuLinks); diff --git a/x-pack/plugins/cloud_integrations/cloud_links/public/plugin.test.ts b/x-pack/plugins/cloud_integrations/cloud_links/public/plugin.test.ts index d928b7a6f0e8a..d2f987337a440 100644 --- a/x-pack/plugins/cloud_integrations/cloud_links/public/plugin.test.ts +++ b/x-pack/plugins/cloud_integrations/cloud_links/public/plugin.test.ts @@ -11,6 +11,7 @@ import { coreMock } from '@kbn/core/public/mocks'; import { cloudMock } from '@kbn/cloud-plugin/public/mocks'; import { securityMock } from '@kbn/security-plugin/public/mocks'; import { guidedOnboardingMock } from '@kbn/guided-onboarding-plugin/public/mocks'; +import { sharePluginMock } from '@kbn/share-plugin/public/mocks'; describe('Cloud Links Plugin - public', () => { let plugin: CloudLinksPlugin; @@ -40,7 +41,11 @@ describe('Cloud Links Plugin - public', () => { coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(false); const cloud = { ...cloudMock.createStart(), isCloudEnabled: true }; - plugin.start(coreStart, { cloud, guidedOnboarding }); + plugin.start(coreStart, { + cloud, + guidedOnboarding, + share: sharePluginMock.createStartContract(), + }); expect(coreStart.chrome.registerGlobalHelpExtensionMenuLink).toHaveBeenCalledTimes(1); }); @@ -48,14 +53,22 @@ describe('Cloud Links Plugin - public', () => { const coreStart = coreMock.createStart(); coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(true); const cloud = { ...cloudMock.createStart(), isCloudEnabled: true }; - plugin.start(coreStart, { cloud, guidedOnboarding }); + plugin.start(coreStart, { + cloud, + guidedOnboarding, + share: sharePluginMock.createStartContract(), + }); expect(coreStart.chrome.registerGlobalHelpExtensionMenuLink).not.toHaveBeenCalled(); }); test('does not register the Onboarding Setup Guide link when cloud is not enabled', () => { const coreStart = coreMock.createStart(); const cloud = { ...cloudMock.createStart(), isCloudEnabled: false }; - plugin.start(coreStart, { cloud, guidedOnboarding }); + plugin.start(coreStart, { + cloud, + guidedOnboarding, + share: sharePluginMock.createStartContract(), + }); expect(coreStart.chrome.registerGlobalHelpExtensionMenuLink).not.toHaveBeenCalled(); }); }); @@ -72,7 +85,11 @@ describe('Cloud Links Plugin - public', () => { coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(false); const cloud = { ...cloudMock.createStart(), isCloudEnabled: true }; - plugin.start(coreStart, { cloud, guidedOnboarding }); + plugin.start(coreStart, { + cloud, + guidedOnboarding, + share: sharePluginMock.createStartContract(), + }); expect(coreStart.chrome.registerGlobalHelpExtensionMenuLink).not.toHaveBeenCalled(); }); }); @@ -83,7 +100,7 @@ describe('Cloud Links Plugin - public', () => { coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(false); const cloud = { ...cloudMock.createStart(), isCloudEnabled: true }; const security = securityMock.createStart(); - plugin.start(coreStart, { cloud, security }); + plugin.start(coreStart, { cloud, security, share: sharePluginMock.createStartContract() }); expect(maybeAddCloudLinksMock).toHaveBeenCalledTimes(1); }); @@ -91,7 +108,7 @@ describe('Cloud Links Plugin - public', () => { const coreStart = coreMock.createStart(); coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(false); const cloud = { ...cloudMock.createStart(), isCloudEnabled: true }; - plugin.start(coreStart, { cloud }); + plugin.start(coreStart, { cloud, share: sharePluginMock.createStartContract() }); expect(maybeAddCloudLinksMock).toHaveBeenCalledTimes(0); }); @@ -100,7 +117,7 @@ describe('Cloud Links Plugin - public', () => { coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(true); const cloud = { ...cloudMock.createStart(), isCloudEnabled: true }; const security = securityMock.createStart(); - plugin.start(coreStart, { cloud, security }); + plugin.start(coreStart, { cloud, security, share: sharePluginMock.createStartContract() }); expect(maybeAddCloudLinksMock).toHaveBeenCalledTimes(0); }); @@ -108,7 +125,7 @@ describe('Cloud Links Plugin - public', () => { const coreStart = coreMock.createStart(); coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(false); const security = securityMock.createStart(); - plugin.start(coreStart, { security }); + plugin.start(coreStart, { security, share: sharePluginMock.createStartContract() }); expect(maybeAddCloudLinksMock).toHaveBeenCalledTimes(0); }); @@ -117,7 +134,7 @@ describe('Cloud Links Plugin - public', () => { coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(false); const cloud = { ...cloudMock.createStart(), isCloudEnabled: false }; const security = securityMock.createStart(); - plugin.start(coreStart, { cloud, security }); + plugin.start(coreStart, { cloud, security, share: sharePluginMock.createStartContract() }); expect(maybeAddCloudLinksMock).toHaveBeenCalledTimes(0); }); }); diff --git a/x-pack/plugins/cloud_integrations/cloud_links/public/plugin.tsx b/x-pack/plugins/cloud_integrations/cloud_links/public/plugin.tsx index 38b568791b70b..bfebe531276d4 100755 --- a/x-pack/plugins/cloud_integrations/cloud_links/public/plugin.tsx +++ b/x-pack/plugins/cloud_integrations/cloud_links/public/plugin.tsx @@ -11,6 +11,7 @@ import type { CoreStart, Plugin } from '@kbn/core/public'; import type { CloudSetup, CloudStart } from '@kbn/cloud-plugin/public'; import type { SecurityPluginSetup, SecurityPluginStart } from '@kbn/security-plugin/public'; import type { GuidedOnboardingPluginStart } from '@kbn/guided-onboarding-plugin/public'; +import type { SharePluginStart } from '@kbn/share-plugin/public'; import { maybeAddCloudLinks } from './maybe_add_cloud_links'; interface CloudLinksDepsSetup { @@ -21,6 +22,7 @@ interface CloudLinksDepsSetup { interface CloudLinksDepsStart { cloud?: CloudStart; security?: SecurityPluginStart; + share: SharePluginStart; guidedOnboarding?: GuidedOnboardingPluginStart; } @@ -29,7 +31,7 @@ export class CloudLinksPlugin { public setup() {} - public start(core: CoreStart, { cloud, security, guidedOnboarding }: CloudLinksDepsStart) { + public start(core: CoreStart, { cloud, security, guidedOnboarding, share }: CloudLinksDepsStart) { if (cloud?.isCloudEnabled && !core.http.anonymousPaths.isAnonymous(window.location.pathname)) { if (guidedOnboarding?.guidedOnboardingApi?.isEnabled) { core.chrome.registerGlobalHelpExtensionMenuLink({ @@ -42,11 +44,13 @@ export class CloudLinksPlugin priority: 1000, // We want this link to be at the very top. }); } + if (security) { maybeAddCloudLinks({ core, security, cloud, + share, }); } } diff --git a/x-pack/plugins/cloud_integrations/cloud_links/tsconfig.json b/x-pack/plugins/cloud_integrations/cloud_links/tsconfig.json index f1a67895cdd5e..43f411cadf060 100644 --- a/x-pack/plugins/cloud_integrations/cloud_links/tsconfig.json +++ b/x-pack/plugins/cloud_integrations/cloud_links/tsconfig.json @@ -23,6 +23,9 @@ "@kbn/user-profile-components", "@kbn/core-lifecycle-browser", "@kbn/kibana-react-plugin", + "@kbn/share-plugin", + "@kbn/cloud", + "@kbn/react-kibana-mount", ], "exclude": [ "target/**/*", diff --git a/x-pack/plugins/fleet/public/applications/integrations/components/header/deployment_details.component.tsx b/x-pack/plugins/fleet/public/applications/integrations/components/header/deployment_details.component.tsx deleted file mode 100644 index 7e3b414cf0f6d..0000000000000 --- a/x-pack/plugins/fleet/public/applications/integrations/components/header/deployment_details.component.tsx +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import styled from 'styled-components'; - -import { - EuiPopover, - EuiText, - EuiForm, - EuiFormRow, - EuiFieldText, - EuiCopy, - EuiButtonIcon, - EuiFlexGroup, - EuiFlexItem, - EuiButton, - EuiLink, - EuiHeaderLink, -} from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; - -export interface Props { - cloudId: string; - managementUrl?: string; - learnMoreUrl: string; -} - -const Description = styled(EuiText)` - margin-bottom: ${({ theme }) => theme.eui.euiSizeL}; -`; - -export const DeploymentDetails = ({ cloudId, learnMoreUrl, managementUrl }: Props) => { - const [isOpen, setIsOpen] = React.useState(false); - - const button = ( - setIsOpen(!isOpen)} iconType="iInCircle" iconSide="left" isActive> - {i18n.translate('xpack.fleet.integrations.deploymentButton', { - defaultMessage: 'View deployment details', - })} - - ); - - const management = managementUrl ? ( - - - - Create and manage API keys - - - - Learn more - - - - - ) : null; - - return ( - setIsOpen(false)} - button={button} - anchorPosition="downCenter" - > -

- - {i18n.translate('xpack.fleet.integrations.deploymentDescription', { - defaultMessage: - 'Send data to Elastic from your applications by referencing your deployment.', - })} - - - - - - - - - - {(copy) => ( - - )} - - - - - {management} - -
- - ); -}; diff --git a/x-pack/plugins/fleet/public/applications/integrations/components/header/deployment_details.stories.tsx b/x-pack/plugins/fleet/public/applications/integrations/components/header/deployment_details.stories.tsx deleted file mode 100644 index 5b311b3443e36..0000000000000 --- a/x-pack/plugins/fleet/public/applications/integrations/components/header/deployment_details.stories.tsx +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import type { Meta } from '@storybook/react'; -import { EuiHeader } from '@elastic/eui'; - -import { DeploymentDetails as ConnectedComponent } from './deployment_details'; -import type { Props as PureComponentProps } from './deployment_details.component'; -import { DeploymentDetails as PureComponent } from './deployment_details.component'; - -export default { - title: 'Sections/EPM/Deployment Details', - description: '', - decorators: [ - (storyFn) => { - const sections = [{ items: [] }, { items: [storyFn()] }]; - return ; - }, - ], -} as Meta; - -export const DeploymentDetails = () => { - return ; -}; - -DeploymentDetails.args = { - isCloudEnabled: true, -}; - -DeploymentDetails.argTypes = { - isCloudEnabled: { - type: { - name: 'boolean', - }, - defaultValue: true, - control: { - type: 'boolean', - }, - }, -}; - -export const Component = (props: PureComponentProps) => { - return ; -}; - -Component.args = { - cloudId: 'cloud-id', - learnMoreUrl: 'https://learn-more-url', - managementUrl: 'https://management-url', -}; diff --git a/x-pack/plugins/fleet/public/applications/integrations/components/header/deployment_details.tsx b/x-pack/plugins/fleet/public/applications/integrations/components/header/deployment_details.tsx index 968d596a5f9d5..ea17bc3f201c4 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/components/header/deployment_details.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/components/header/deployment_details.tsx @@ -6,13 +6,18 @@ */ import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { EuiPopover, EuiHeaderLink } from '@elastic/eui'; +import { + DeploymentDetailsKibanaProvider, + DeploymentDetails as DeploymentDetailsComponent, +} from '@kbn/cloud/deployment_details'; import { useStartServices } from '../../hooks'; -import { DeploymentDetails as Component } from './deployment_details.component'; - export const DeploymentDetails = () => { - const { share, cloud, docLinks } = useStartServices(); + const [isOpen, setIsOpen] = React.useState(false); + const { share, cloud, docLinks, application } = useStartServices(); // If the cloud plugin isn't enabled, we can't display the flyout. if (!cloud) { @@ -21,16 +26,36 @@ export const DeploymentDetails = () => { const { isCloudEnabled, cloudId } = cloud; - // If cloud isn't enabled or we don't have a cloudId we can't display the flyout. + // If cloud isn't enabled or we don't have a cloudId we don't render the button. if (!isCloudEnabled || !cloudId) { return null; } - const managementUrl = share.url.locators - .get('MANAGEMENT_APP_LOCATOR') - ?.useUrl({ sectionId: 'security', appId: 'api_keys' }); - - const learnMoreUrl = docLinks.links.fleet.apiKeysLearnMore; - - return ; + const button = ( + setIsOpen(!isOpen)} iconType="iInCircle" iconSide="left" isActive> + {i18n.translate('xpack.fleet.integrations.endpointsButton', { + defaultMessage: 'Endpoints', + })} + + ); + + return ( + + setIsOpen(false)} + button={button} + anchorPosition="downCenter" + > +
+ +
+
+
+ ); }; diff --git a/x-pack/plugins/fleet/server/integration_tests/fleet_usage_telemetry.test.ts b/x-pack/plugins/fleet/server/integration_tests/fleet_usage_telemetry.test.ts index b841c641c3af4..e2e7e9f7887e6 100644 --- a/x-pack/plugins/fleet/server/integration_tests/fleet_usage_telemetry.test.ts +++ b/x-pack/plugins/fleet/server/integration_tests/fleet_usage_telemetry.test.ts @@ -20,8 +20,7 @@ import { waitForFleetSetup } from './helpers'; const logFilePath = path.join(__dirname, 'logs.log'); -// Failing: See https://github.com/elastic/kibana/issues/156245 -describe.skip('fleet usage telemetry', () => { +describe('fleet usage telemetry', () => { let core: any; let esServer: TestElasticsearchUtils; let kbnServer: TestKibanaUtils; @@ -218,7 +217,7 @@ describe.skip('fleet usage telemetry', () => { version: '8.6.0', }, last_checkin_status: 'online', - last_checkin: '2023-09-13T12:26:24Z', + last_checkin: new Date(Date.now() - 1000 * 60 * 6).toISOString(), active: true, policy_id: 'policy2', }, diff --git a/x-pack/plugins/fleet/tsconfig.json b/x-pack/plugins/fleet/tsconfig.json index b3f8a96417f9a..58cdfa25d1e08 100644 --- a/x-pack/plugins/fleet/tsconfig.json +++ b/x-pack/plugins/fleet/tsconfig.json @@ -101,5 +101,6 @@ "@kbn/core-saved-objects-base-server-internal", "@kbn/core-http-common", "@kbn/dashboard-plugin", + "@kbn/cloud", ] } diff --git a/x-pack/plugins/infra/common/inventory_models/host/index.ts b/x-pack/plugins/infra/common/inventory_models/host/index.ts index 04aa00fbdf2be..18af8bbfadc99 100644 --- a/x-pack/plugins/infra/common/inventory_models/host/index.ts +++ b/x-pack/plugins/infra/common/inventory_models/host/index.ts @@ -8,10 +8,6 @@ import { i18n } from '@kbn/i18n'; import { metrics } from './metrics'; import { InventoryModel } from '../types'; -import { - aws as awsRequiredMetrics, - nginx as nginxRequireMetrics, -} from '../shared/metrics/required_metrics'; export { hostSnapshotMetricTypes } from './metrics'; @@ -38,19 +34,5 @@ export const host: InventoryModel = { cloudProvider: 'cloud.provider', }, metrics, - requiredMetrics: [ - 'hostSystemOverview', - 'hostCpuUsage', - 'hostLoad', - 'hostMemoryUsage', - 'hostNetworkTraffic', - 'hostK8sOverview', - 'hostK8sCpuCap', - 'hostK8sMemoryCap', - 'hostK8sDiskCap', - 'hostK8sPodCap', - ...awsRequiredMetrics, - ...nginxRequireMetrics, - ], tooltipMetrics: ['cpu', 'memory', 'tx', 'rx'], }; diff --git a/x-pack/plugins/infra/common/inventory_models/host/metrics/index.ts b/x-pack/plugins/infra/common/inventory_models/host/metrics/index.ts index e59aaefb2b82b..3eff64ccb6a7a 100644 --- a/x-pack/plugins/infra/common/inventory_models/host/metrics/index.ts +++ b/x-pack/plugins/infra/common/inventory_models/host/metrics/index.ts @@ -18,24 +18,6 @@ import { normalizedLoad1m } from './snapshot/normalized_load_1m'; import { rx } from './snapshot/rx'; import { tx } from './snapshot/tx'; -import { hostSystemOverview } from './tsvb/host_system_overview'; -import { hostCpuUsage } from './tsvb/host_cpu_usage'; -import { hostLoad } from './tsvb/host_load'; -import { hostMemoryUsage } from './tsvb/host_memory_usage'; -import { hostNetworkTraffic } from './tsvb/host_network_traffic'; -import { hostFilesystem } from './tsvb/host_filesystem'; - -import { hostK8sOverview } from './tsvb/host_k8s_overview'; -import { hostK8sCpuCap } from './tsvb/host_k8s_cpu_cap'; -import { hostK8sPodCap } from './tsvb/host_k8s_pod_cap'; -import { hostK8sDiskCap } from './tsvb/host_k8s_disk_cap'; -import { hostK8sMemoryCap } from './tsvb/host_k8s_memory_cap'; - -import { hostDockerTop5ByMemory } from './tsvb/host_docker_top_5_by_memory'; -import { hostDockerTop5ByCpu } from './tsvb/host_docker_top_5_by_cpu'; -import { hostDockerOverview } from './tsvb/host_docker_overview'; -import { hostDockerInfo } from './tsvb/host_docker_info'; - import { InventoryMetrics } from '../../types'; const exposedHostSnapshotMetrics = { @@ -59,23 +41,6 @@ export const hostSnapshotMetricTypes = Object.keys(exposedHostSnapshotMetrics) a >; export const metrics: InventoryMetrics = { - tsvb: { - hostSystemOverview, - hostCpuUsage, - hostLoad, - hostMemoryUsage, - hostNetworkTraffic, - hostFilesystem, - hostK8sOverview, - hostK8sCpuCap, - hostK8sPodCap, - hostK8sDiskCap, - hostK8sMemoryCap, - hostDockerOverview, - hostDockerInfo, - hostDockerTop5ByMemory, - hostDockerTop5ByCpu, - }, snapshot: hostSnapshotMetrics, defaultSnapshot: 'cpu', defaultTimeRangeInSeconds: 3600, // 1 hour diff --git a/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_cpu_usage.ts b/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_cpu_usage.ts deleted file mode 100644 index bcafeb4ebc4cf..0000000000000 --- a/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_cpu_usage.ts +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { TSVBMetricModelCreator, TSVBMetricModel } from '../../../types'; - -export const hostCpuUsage: TSVBMetricModelCreator = ( - timeField, - indexPattern, - interval -): TSVBMetricModel => ({ - id: 'hostCpuUsage', - requires: ['system.cpu'], - index_pattern: indexPattern, - interval, - time_field: timeField, - type: 'timeseries', - series: [ - { - id: 'user', - metrics: [ - { - field: 'system.cpu.user.pct', - id: 'avg-cpu-user', - type: 'avg', - }, - { - field: 'system.cpu.cores', - id: 'max-cpu-cores', - type: 'max', - }, - { - id: 'calc-avg-cores', - script: 'params.avg / params.cores', - type: 'calculation', - variables: [ - { - field: 'max-cpu-cores', - id: 'var-cores', - name: 'cores', - }, - { - field: 'avg-cpu-user', - id: 'var-avg', - name: 'avg', - }, - ], - }, - ], - split_mode: 'everything', - }, - { - id: 'system', - metrics: [ - { - field: 'system.cpu.system.pct', - id: 'avg-cpu-system', - type: 'avg', - }, - { - field: 'system.cpu.cores', - id: 'max-cpu-cores', - type: 'max', - }, - { - id: 'calc-avg-cores', - script: 'params.avg / params.cores', - type: 'calculation', - variables: [ - { - field: 'max-cpu-cores', - id: 'var-cores', - name: 'cores', - }, - { - field: 'avg-cpu-system', - id: 'var-avg', - name: 'avg', - }, - ], - }, - ], - split_mode: 'everything', - }, - { - id: 'steal', - metrics: [ - { - field: 'system.cpu.steal.pct', - id: 'avg-cpu-steal', - type: 'avg', - }, - { - field: 'system.cpu.cores', - id: 'max-cpu-cores', - type: 'max', - }, - { - id: 'calc-avg-cores', - script: 'params.avg / params.cores', - type: 'calculation', - variables: [ - { - field: 'avg-cpu-steal', - id: 'var-avg', - name: 'avg', - }, - { - field: 'max-cpu-cores', - id: 'var-cores', - name: 'cores', - }, - ], - }, - ], - split_mode: 'everything', - }, - { - id: 'irq', - metrics: [ - { - field: 'system.cpu.irq.pct', - id: 'avg-cpu-irq', - type: 'avg', - }, - { - field: 'system.cpu.cores', - id: 'max-cpu-cores', - type: 'max', - }, - { - id: 'calc-avg-cores', - script: 'params.avg / params.cores', - type: 'calculation', - variables: [ - { - field: 'max-cpu-cores', - id: 'var-cores', - name: 'cores', - }, - { - field: 'avg-cpu-irq', - id: 'var-avg', - name: 'avg', - }, - ], - }, - ], - split_mode: 'everything', - }, - { - id: 'softirq', - metrics: [ - { - field: 'system.cpu.softirq.pct', - id: 'avg-cpu-softirq', - type: 'avg', - }, - { - field: 'system.cpu.cores', - id: 'max-cpu-cores', - type: 'max', - }, - { - id: 'calc-avg-cores', - script: 'params.avg / params.cores', - type: 'calculation', - variables: [ - { - field: 'max-cpu-cores', - id: 'var-cores', - name: 'cores', - }, - { - field: 'avg-cpu-softirq', - id: 'var-avg', - name: 'avg', - }, - ], - }, - ], - split_mode: 'everything', - }, - { - id: 'iowait', - metrics: [ - { - field: 'system.cpu.iowait.pct', - id: 'avg-cpu-iowait', - type: 'avg', - }, - { - field: 'system.cpu.cores', - id: 'max-cpu-cores', - type: 'max', - }, - { - id: 'calc-avg-cores', - script: 'params.avg / params.cores', - type: 'calculation', - variables: [ - { - field: 'max-cpu-cores', - id: 'var-cores', - name: 'cores', - }, - { - field: 'avg-cpu-iowait', - id: 'var-avg', - name: 'avg', - }, - ], - }, - ], - split_mode: 'everything', - }, - { - id: 'nice', - metrics: [ - { - field: 'system.cpu.nice.pct', - id: 'avg-cpu-nice', - type: 'avg', - }, - { - field: 'system.cpu.cores', - id: 'max-cpu-cores', - type: 'max', - }, - { - id: 'calc-avg-cores', - script: 'params.avg / params.cores', - type: 'calculation', - variables: [ - { - field: 'max-cpu-cores', - id: 'var-cores', - name: 'cores', - }, - { - field: 'avg-cpu-nice', - id: 'var-avg', - name: 'avg', - }, - ], - }, - ], - split_mode: 'everything', - }, - ], -}); diff --git a/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_docker_info.ts b/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_docker_info.ts deleted file mode 100644 index 4cc2b574362d7..0000000000000 --- a/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_docker_info.ts +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { TSVBMetricModelCreator, TSVBMetricModel } from '../../../types'; - -export const hostDockerInfo: TSVBMetricModelCreator = ( - timeField, - indexPattern, - interval -): TSVBMetricModel => ({ - id: 'hostDockerInfo', - requires: ['docker.info'], - index_pattern: indexPattern, - interval, - time_field: timeField, - type: 'timeseries', - series: [ - { - id: 'running', - metrics: [ - { - field: 'docker.info.containers.running', - id: 'max-running', - type: 'max', - }, - ], - split_mode: 'everything', - }, - { - id: 'paused', - metrics: [ - { - field: 'docker.info.containers.paused', - id: 'max-paused', - type: 'max', - }, - ], - split_mode: 'everything', - }, - { - id: 'stopped', - metrics: [ - { - field: 'docker.info.containers.stopped', - id: 'max-stopped', - type: 'max', - }, - ], - split_mode: 'everything', - }, - ], -}); diff --git a/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_docker_overview.ts b/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_docker_overview.ts deleted file mode 100644 index df56a21dbf5b7..0000000000000 --- a/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_docker_overview.ts +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { TSVBMetricModelCreator, TSVBMetricModel } from '../../../types'; - -export const hostDockerOverview: TSVBMetricModelCreator = ( - timeField, - indexPattern, - interval -): TSVBMetricModel => ({ - id: 'hostDockerOverview', - requires: ['docker.info'], - index_pattern: indexPattern, - interval, - time_field: timeField, - type: 'top_n', - series: [ - { - id: 'total', - metrics: [ - { - field: 'docker.info.containers.total', - id: 'max-total', - type: 'max', - }, - ], - split_mode: 'everything', - }, - { - id: 'running', - metrics: [ - { - field: 'docker.info.containers.running', - id: 'max-running', - type: 'max', - }, - ], - split_mode: 'everything', - }, - { - id: 'paused', - metrics: [ - { - field: 'docker.info.containers.paused', - id: 'max-paused', - type: 'max', - }, - ], - split_mode: 'everything', - }, - { - id: 'stopped', - metrics: [ - { - field: 'docker.info.containers.stopped', - id: 'max-stopped', - type: 'max', - }, - ], - split_mode: 'everything', - }, - ], -}); diff --git a/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_docker_top_5_by_cpu.ts b/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_docker_top_5_by_cpu.ts deleted file mode 100644 index fd9eb97419736..0000000000000 --- a/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_docker_top_5_by_cpu.ts +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { TSVBMetricModelCreator, TSVBMetricModel } from '../../../types'; - -export const hostDockerTop5ByCpu: TSVBMetricModelCreator = ( - timeField, - indexPattern, - interval -): TSVBMetricModel => ({ - id: 'hostDockerTop5ByCpu', - requires: ['docker.cpu'], - index_pattern: indexPattern, - interval, - time_field: timeField, - type: 'timeseries', - series: [ - { - id: 'avg-cpu', - metrics: [ - { - field: 'docker.cpu.total.pct', - id: 'avg-cpu-metric', - type: 'avg', - }, - ], - split_mode: 'terms', - terms_field: 'container.name', - terms_order_by: 'avg-cpu', - terms_size: 5, - }, - ], -}); diff --git a/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_docker_top_5_by_memory.ts b/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_docker_top_5_by_memory.ts deleted file mode 100644 index cad828671d232..0000000000000 --- a/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_docker_top_5_by_memory.ts +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { TSVBMetricModelCreator, TSVBMetricModel } from '../../../types'; - -export const hostDockerTop5ByMemory: TSVBMetricModelCreator = ( - timeField, - indexPattern, - interval -): TSVBMetricModel => ({ - id: 'hostDockerTop5ByMemory', - requires: ['docker.memory'], - index_pattern: indexPattern, - interval, - time_field: timeField, - type: 'timeseries', - series: [ - { - id: 'avg-memory', - metrics: [ - { - field: 'docker.memory.usage.pct', - id: 'avg-memory-metric', - type: 'avg', - }, - ], - split_mode: 'terms', - terms_field: 'container.name', - terms_order_by: 'avg-memory', - terms_size: 5, - }, - ], -}); diff --git a/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_filesystem.ts b/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_filesystem.ts deleted file mode 100644 index ce284345410fc..0000000000000 --- a/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_filesystem.ts +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { TSVBMetricModelCreator, TSVBMetricModel } from '../../../types'; - -export const hostFilesystem: TSVBMetricModelCreator = ( - timeField, - indexPattern, - interval -): TSVBMetricModel => ({ - id: 'hostFilesystem', - requires: ['system.filesystem'], - filter: 'system.filesystem.device_name:\\/*', - index_pattern: indexPattern, - time_field: timeField, - interval, - type: 'timeseries', - series: [ - { - id: 'used', - metrics: [ - { - field: 'system.filesystem.used.pct', - id: 'avg-filesystem-used', - type: 'avg', - }, - ], - split_mode: 'terms', - terms_field: 'system.filesystem.device_name', - terms_order_by: 'used', - terms_size: 5, - }, - ], -}); diff --git a/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_k8s_cpu_cap.ts b/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_k8s_cpu_cap.ts deleted file mode 100644 index d33e4cdeb34cd..0000000000000 --- a/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_k8s_cpu_cap.ts +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { TSVBMetricModelCreator, TSVBMetricModel } from '../../../types'; - -export const hostK8sCpuCap: TSVBMetricModelCreator = ( - timeField, - indexPattern, - interval -): TSVBMetricModel => ({ - id: 'hostK8sCpuCap', - map_field_to: 'kubernetes.node.name', - requires: ['kubernetes.node'], - index_pattern: indexPattern, - interval, - time_field: timeField, - type: 'timeseries', - series: [ - { - id: 'capacity', - metrics: [ - { - field: 'kubernetes.node.cpu.allocatable.cores', - id: 'max-cpu-cap', - type: 'max', - }, - { - id: 'calc-nanocores', - type: 'calculation', - variables: [ - { - id: 'var-cores', - field: 'max-cpu-cap', - name: 'cores', - }, - ], - script: 'params.cores * 1000000000', - }, - ], - split_mode: 'everything', - }, - { - id: 'used', - metrics: [ - { - field: 'kubernetes.node.cpu.usage.nanocores', - id: 'avg-cpu-usage', - type: 'avg', - }, - ], - split_mode: 'everything', - }, - ], -}); diff --git a/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_k8s_disk_cap.ts b/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_k8s_disk_cap.ts deleted file mode 100644 index e9e512a136631..0000000000000 --- a/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_k8s_disk_cap.ts +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { TSVBMetricModelCreator, TSVBMetricModel } from '../../../types'; -export const hostK8sDiskCap: TSVBMetricModelCreator = ( - timeField, - indexPattern, - interval -): TSVBMetricModel => ({ - id: 'hostK8sDiskCap', - map_field_to: 'kubernetes.node.name', - requires: ['kubernetes.node'], - index_pattern: indexPattern, - interval, - time_field: timeField, - type: 'timeseries', - series: [ - { - id: 'capacity', - metrics: [ - { - field: 'kubernetes.node.fs.capacity.bytes', - id: 'max-fs-cap', - type: 'max', - }, - ], - split_mode: 'everything', - }, - { - id: 'used', - metrics: [ - { - field: 'kubernetes.node.fs.used.bytes', - id: 'avg-fs-used', - type: 'avg', - }, - ], - split_mode: 'everything', - }, - ], -}); diff --git a/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_k8s_memory_cap.ts b/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_k8s_memory_cap.ts deleted file mode 100644 index ccc227ef1854e..0000000000000 --- a/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_k8s_memory_cap.ts +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { TSVBMetricModelCreator, TSVBMetricModel } from '../../../types'; - -export const hostK8sMemoryCap: TSVBMetricModelCreator = ( - timeField, - indexPattern, - interval -): TSVBMetricModel => ({ - id: 'hostK8sMemoryCap', - map_field_to: 'kubernetes.node.name', - requires: ['kubernetes.node'], - index_pattern: indexPattern, - interval, - time_field: timeField, - type: 'timeseries', - series: [ - { - id: 'capacity', - metrics: [ - { - field: 'kubernetes.node.memory.allocatable.bytes', - id: 'max-memory-cap', - type: 'max', - }, - ], - split_mode: 'everything', - }, - { - id: 'used', - metrics: [ - { - field: 'kubernetes.node.memory.usage.bytes', - id: 'avg-memory-usage', - type: 'avg', - }, - ], - split_mode: 'everything', - }, - ], -}); diff --git a/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_k8s_overview.ts b/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_k8s_overview.ts deleted file mode 100644 index 2da74d50dff1b..0000000000000 --- a/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_k8s_overview.ts +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { TSVBMetricModelCreator, TSVBMetricModel } from '../../../types'; - -export const hostK8sOverview: TSVBMetricModelCreator = ( - timeField, - indexPattern, - interval -): TSVBMetricModel => ({ - id: 'hostK8sOverview', - requires: ['kubernetes'], - index_pattern: indexPattern, - interval, - time_field: timeField, - type: 'top_n', - series: [ - { - id: 'cpucap', - split_mode: 'everything', - metrics: [ - { - field: 'kubernetes.node.cpu.allocatable.cores', - id: 'max-cpu-cap', - type: 'max', - }, - { - field: 'kubernetes.node.cpu.usage.nanocores', - id: 'avg-cpu-usage', - type: 'avg', - }, - { - id: 'calc-used-cap', - script: 'params.used / (params.cap * 1000000000)', - type: 'calculation', - variables: [ - { - field: 'max-cpu-cap', - id: 'var-cap', - name: 'cap', - }, - { - field: 'avg-cpu-usage', - id: 'var-used', - name: 'used', - }, - ], - }, - ], - }, - { - id: 'diskcap', - metrics: [ - { - field: 'kubernetes.node.fs.capacity.bytes', - id: 'max-fs-cap', - type: 'max', - }, - { - field: 'kubernetes.node.fs.used.bytes', - id: 'avg-fs-used', - type: 'avg', - }, - { - id: 'calc-used-cap', - script: 'params.used / params.cap', - type: 'calculation', - variables: [ - { - field: 'max-fs-cap', - id: 'var-cap', - name: 'cap', - }, - { - field: 'avg-fs-used', - id: 'var-used', - name: 'used', - }, - ], - }, - ], - split_mode: 'everything', - }, - { - id: 'memorycap', - metrics: [ - { - field: 'kubernetes.node.memory.allocatable.bytes', - id: 'max-memory-cap', - type: 'max', - }, - { - field: 'kubernetes.node.memory.usage.bytes', - id: 'avg-memory-usage', - type: 'avg', - }, - { - id: 'calc-used-cap', - script: 'params.used / params.cap', - type: 'calculation', - variables: [ - { - field: 'max-memory-cap', - id: 'var-cap', - name: 'cap', - }, - { - field: 'avg-memory-usage', - id: 'var-used', - name: 'used', - }, - ], - }, - ], - split_mode: 'everything', - }, - { - id: 'podcap', - metrics: [ - { - field: 'kubernetes.node.pod.capacity.total', - id: 'max-pod-cap', - type: 'max', - }, - { - field: 'kubernetes.pod.uid', - id: 'card-pod-name', - type: 'cardinality', - }, - { - id: 'calc-used-cap', - script: 'params.used / params.cap', - type: 'calculation', - variables: [ - { - field: 'max-pod-cap', - id: 'var-cap', - name: 'cap', - }, - { - field: 'card-pod-name', - id: 'var-used', - name: 'used', - }, - ], - }, - ], - split_mode: 'everything', - }, - ], -}); diff --git a/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_k8s_pod_cap.ts b/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_k8s_pod_cap.ts deleted file mode 100644 index 85cb798eaf9b9..0000000000000 --- a/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_k8s_pod_cap.ts +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { TSVBMetricModelCreator, TSVBMetricModel } from '../../../types'; - -export const hostK8sPodCap: TSVBMetricModelCreator = ( - timeField, - indexPattern, - interval -): TSVBMetricModel => ({ - id: 'hostK8sPodCap', - requires: ['kubernetes.node'], - map_field_to: 'kubernetes.node.name', - index_pattern: indexPattern, - interval, - time_field: timeField, - type: 'timeseries', - - series: [ - { - id: 'capacity', - metrics: [ - { - field: 'kubernetes.node.pod.allocatable.total', - id: 'max-pod-cap', - type: 'max', - }, - ], - split_mode: 'everything', - }, - { - id: 'used', - metrics: [ - { - field: 'kubernetes.pod.uid', - id: 'avg-pod', - type: 'cardinality', - }, - ], - split_mode: 'everything', - }, - ], -}); diff --git a/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_load.ts b/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_load.ts deleted file mode 100644 index bef170c743e6c..0000000000000 --- a/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_load.ts +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { TSVBMetricModelCreator, TSVBMetricModel } from '../../../types'; - -export const hostLoad: TSVBMetricModelCreator = ( - timeField, - indexPattern, - interval -): TSVBMetricModel => ({ - id: 'hostLoad', - requires: ['system.cpu'], - index_pattern: indexPattern, - interval, - time_field: timeField, - type: 'timeseries', - series: [ - { - id: 'load_1m', - metrics: [ - { - field: 'system.load.1', - id: 'avg-load-1m', - type: 'avg', - }, - ], - split_mode: 'everything', - }, - { - id: 'load_5m', - metrics: [ - { - field: 'system.load.5', - id: 'avg-load-5m', - type: 'avg', - }, - ], - split_mode: 'everything', - }, - { - id: 'load_15m', - metrics: [ - { - field: 'system.load.15', - id: 'avg-load-15m', - type: 'avg', - }, - ], - split_mode: 'everything', - }, - ], -}); diff --git a/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_memory_usage.ts b/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_memory_usage.ts deleted file mode 100644 index bda81dea4bd28..0000000000000 --- a/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_memory_usage.ts +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { TSVBMetricModelCreator, TSVBMetricModel } from '../../../types'; - -export const hostMemoryUsage: TSVBMetricModelCreator = ( - timeField, - indexPattern, - interval -): TSVBMetricModel => ({ - id: 'hostMemoryUsage', - requires: ['system.memory'], - index_pattern: indexPattern, - interval, - time_field: timeField, - type: 'timeseries', - series: [ - { - id: 'free', - metrics: [ - { - field: 'system.memory.free', - id: 'avg-memory-free', - type: 'avg', - }, - ], - split_mode: 'everything', - }, - { - id: 'used', - metrics: [ - { - field: 'system.memory.actual.used.bytes', - id: 'avg-memory-used', - type: 'avg', - }, - ], - split_mode: 'everything', - }, - { - id: 'cache', - metrics: [ - { - field: 'system.memory.actual.used.bytes', - id: 'avg-memory-actual-used', - type: 'avg', - }, - { - field: 'system.memory.used.bytes', - id: 'avg-memory-used', - type: 'avg', - }, - { - id: 'calc-used-actual', - script: 'params.used - params.actual', - type: 'calculation', - variables: [ - { - field: 'avg-memory-actual-used', - id: 'var-actual', - name: 'actual', - }, - { - field: 'avg-memory-used', - id: 'var-used', - name: 'used', - }, - ], - }, - ], - split_mode: 'everything', - }, - ], -}); diff --git a/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_network_traffic.ts b/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_network_traffic.ts deleted file mode 100644 index b3dfc5e91ba0a..0000000000000 --- a/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_network_traffic.ts +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { TSVBMetricModelCreator, TSVBMetricModel } from '../../../types'; - -export const hostNetworkTraffic: TSVBMetricModelCreator = ( - timeField, - indexPattern, - interval -): TSVBMetricModel => ({ - id: 'hostNetworkTraffic', - requires: ['system.network'], - index_pattern: indexPattern, - interval, - time_field: timeField, - type: 'timeseries', - series: [ - { - id: 'tx', - metrics: [ - { - field: 'host.network.egress.bytes', - id: 'avg-net-out', - type: 'avg', - }, - { - id: 'max-period', - type: 'max', - field: 'metricset.period', - }, - { - id: '3216b170-f192-11ec-a8e3-dd984b7213e2', - type: 'calculation', - variables: [ - { - id: '34e64c30-f192-11ec-a8e3-dd984b7213e2', - name: 'value', - field: 'avg-net-out', - }, - { - id: '3886cb80-f192-11ec-a8e3-dd984b7213e2', - name: 'period', - field: 'max-period', - }, - ], - script: 'params.value / (params.period / 1000)', - }, - ], - filter: { - language: 'kuery', - query: 'host.network.egress.bytes : * ', - }, - split_mode: 'everything', - }, - { - id: 'rx', - metrics: [ - { - field: 'host.network.ingress.bytes', - id: 'avg-net-in', - type: 'avg', - }, - { - id: 'calc-invert-rate', - script: 'params.rate * -1', - type: 'calculation', - variables: [ - { - field: 'avg-net-in', - id: 'var-rate', - name: 'rate', - }, - ], - }, - { - id: 'max-period', - type: 'max', - field: 'metricset.period', - }, - { - id: '3216b170-f192-11ec-a8e3-dd984b7213e2', - type: 'calculation', - variables: [ - { - id: '34e64c30-f192-11ec-a8e3-dd984b7213e2', - name: 'value', - field: 'calc-invert-rate', - }, - { - id: '3886cb80-f192-11ec-a8e3-dd984b7213e2', - name: 'period', - field: 'max-period', - }, - ], - script: 'params.value / (params.period / 1000)', - }, - ], - filter: { - language: 'kuery', - query: 'host.network.ingress.bytes : * ', - }, - split_mode: 'everything', - }, - ], -}); diff --git a/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_system_overview.ts b/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_system_overview.ts deleted file mode 100644 index 69ebd0aa35947..0000000000000 --- a/x-pack/plugins/infra/common/inventory_models/host/metrics/tsvb/host_system_overview.ts +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { TSVBMetricModelCreator, TSVBMetricModel } from '../../../types'; - -export const hostSystemOverview: TSVBMetricModelCreator = ( - timeField, - indexPattern, - interval -): TSVBMetricModel => ({ - id: 'hostSystemOverview', - requires: ['system.cpu', 'system.memory', 'system.load', 'system.network'], - index_pattern: indexPattern, - interval, - time_field: timeField, - type: 'top_n', - series: [ - { - id: 'cpu', - split_mode: 'everything', - metrics: [ - { - field: 'system.cpu.total.norm.pct', - id: 'avg-cpu-total', - type: 'avg', - }, - ], - }, - { - id: 'load', - split_mode: 'everything', - metrics: [ - { - field: 'system.load.5', - id: 'avg-load-5m', - type: 'avg', - }, - ], - }, - { - id: 'memory', - split_mode: 'everything', - metrics: [ - { - field: 'system.memory.actual.used.pct', - id: 'avg-memory-actual-used', - type: 'avg', - }, - ], - }, - { - id: 'rx', - metrics: [ - { - field: 'host.network.ingress.bytes', - id: 'avg-net-in', - type: 'avg', - }, - { - id: 'max-period', - type: 'max', - field: 'metricset.period', - }, - { - id: '3216b170-f192-11ec-a8e3-dd984b7213e2', - type: 'calculation', - variables: [ - { - id: '34e64c30-f192-11ec-a8e3-dd984b7213e2', - name: 'value', - field: 'avg-net-in', - }, - { - id: '3886cb80-f192-11ec-a8e3-dd984b7213e2', - name: 'period', - field: 'max-period', - }, - ], - script: 'params.value / (params.period / 1000)', - }, - ], - filter: { - language: 'kuery', - query: 'host.network.ingress.bytes : * ', - }, - split_mode: 'everything', - }, - { - id: 'tx', - metrics: [ - { - field: 'host.network.egress.bytes', - id: 'avg-net-out', - type: 'avg', - }, - { - id: 'max-period', - type: 'max', - field: 'metricset.period', - }, - { - id: '3216b170-f192-11ec-a8e3-dd984b7213e2', - type: 'calculation', - variables: [ - { - id: '34e64c30-f192-11ec-a8e3-dd984b7213e2', - name: 'value', - field: 'avg-net-out', - }, - { - id: '3886cb80-f192-11ec-a8e3-dd984b7213e2', - name: 'period', - field: 'max-period', - }, - ], - script: 'params.value / (params.period / 1000)', - }, - ], - filter: { - language: 'kuery', - query: 'host.network.egress.bytes : * ', - }, - split_mode: 'everything', - }, - ], -}); diff --git a/x-pack/plugins/infra/common/inventory_models/shared/metrics/index.ts b/x-pack/plugins/infra/common/inventory_models/shared/metrics/index.ts index 775dff525b7f5..2dac80de51161 100644 --- a/x-pack/plugins/infra/common/inventory_models/shared/metrics/index.ts +++ b/x-pack/plugins/infra/common/inventory_models/shared/metrics/index.ts @@ -10,12 +10,6 @@ import { nginxActiveConnections } from './tsvb/nginx_active_connections'; import { nginxHits } from './tsvb/nginx_hits'; import { nginxRequestsPerConnection } from './tsvb/nginx_requests_per_connection'; -import { awsCpuUtilization } from './tsvb/aws_cpu_utilization'; -import { awsDiskioBytes } from './tsvb/aws_diskio_bytes'; -import { awsDiskioOps } from './tsvb/aws_diskio_ops'; -import { awsNetworkBytes } from './tsvb/aws_network_bytes'; -import { awsNetworkPackets } from './tsvb/aws_network_packets'; -import { awsOverview } from './tsvb/aws_overview'; import { InventoryMetrics } from '../../types'; import { count } from './snapshot/count'; @@ -25,12 +19,6 @@ export const metrics: InventoryMetrics = { nginxHits, nginxRequestRate, nginxRequestsPerConnection, - awsCpuUtilization, - awsDiskioBytes, - awsDiskioOps, - awsNetworkBytes, - awsNetworkPackets, - awsOverview, }, snapshot: { count, diff --git a/x-pack/plugins/infra/common/inventory_models/shared/metrics/required_metrics.ts b/x-pack/plugins/infra/common/inventory_models/shared/metrics/required_metrics.ts index 5b29fc93e0d0c..172b48a1ba68d 100644 --- a/x-pack/plugins/infra/common/inventory_models/shared/metrics/required_metrics.ts +++ b/x-pack/plugins/infra/common/inventory_models/shared/metrics/required_metrics.ts @@ -13,12 +13,3 @@ export const nginx: InventoryMetric[] = [ 'nginxActiveConnections', 'nginxRequestsPerConnection', ]; - -export const aws: InventoryMetric[] = [ - 'awsOverview', - 'awsCpuUtilization', - 'awsNetworkBytes', - 'awsNetworkPackets', - 'awsDiskioOps', - 'awsDiskioBytes', -]; diff --git a/x-pack/plugins/infra/common/inventory_models/shared/metrics/tsvb/aws_cpu_utilization.ts b/x-pack/plugins/infra/common/inventory_models/shared/metrics/tsvb/aws_cpu_utilization.ts deleted file mode 100644 index 51b9a4cfc7b3f..0000000000000 --- a/x-pack/plugins/infra/common/inventory_models/shared/metrics/tsvb/aws_cpu_utilization.ts +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { TSVBMetricModelCreator, TSVBMetricModel } from '../../../types'; - -export const awsCpuUtilization: TSVBMetricModelCreator = ( - timeField, - indexPattern -): TSVBMetricModel => ({ - id: 'awsCpuUtilization', - requires: ['aws.ec2'], - map_field_to: 'cloud.instance.id', - id_type: 'cloud', - index_pattern: indexPattern, - interval: '>=5m', - time_field: timeField, - type: 'timeseries', - series: [ - { - id: 'cpu-util', - metrics: [ - { - field: 'aws.ec2.cpu.total.pct', - id: 'avg-cpu-util', - type: 'avg', - }, - ], - split_mode: 'everything', - }, - ], -}); diff --git a/x-pack/plugins/infra/common/inventory_models/shared/metrics/tsvb/aws_diskio_bytes.ts b/x-pack/plugins/infra/common/inventory_models/shared/metrics/tsvb/aws_diskio_bytes.ts deleted file mode 100644 index 5224545c006b7..0000000000000 --- a/x-pack/plugins/infra/common/inventory_models/shared/metrics/tsvb/aws_diskio_bytes.ts +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { TSVBMetricModelCreator, TSVBMetricModel } from '../../../types'; - -export const awsDiskioBytes: TSVBMetricModelCreator = ( - timeField, - indexPattern -): TSVBMetricModel => ({ - id: 'awsDiskioBytes', - requires: ['aws.ec2'], - index_pattern: indexPattern, - map_field_to: 'cloud.instance.id', - id_type: 'cloud', - interval: '>=5m', - time_field: timeField, - type: 'timeseries', - series: [ - { - id: 'writes', - metrics: [ - { - field: 'aws.ec2.diskio.write.bytes', - id: 'sum-diskio-out', - type: 'sum', - }, - { - id: 'csum-sum-diskio-out', - field: 'sum-diskio-out', - type: 'cumulative_sum', - }, - { - id: 'deriv-csum-sum-diskio-out', - unit: '1s', - type: 'derivative', - field: 'csum-sum-diskio-out', - }, - { - id: 'posonly-deriv-csum-sum-diskio-out', - field: 'deriv-csum-sum-diskio-out', - type: 'positive_only', - }, - ], - split_mode: 'everything', - }, - { - id: 'reads', - metrics: [ - { - field: 'aws.ec2.diskio.read.bytes', - id: 'sum-diskio-in', - type: 'sum', - }, - { - id: 'csum-sum-diskio-in', - field: 'sum-diskio-in', - type: 'cumulative_sum', - }, - { - id: 'deriv-csum-sum-diskio-in', - unit: '1s', - type: 'derivative', - field: 'csum-sum-diskio-in', - }, - { - id: 'posonly-deriv-csum-sum-diskio-in', - field: 'deriv-csum-sum-diskio-in', - type: 'positive_only', - }, - { - id: 'inverted-posonly-deriv-csum-sum-diskio-in', - type: 'calculation', - variables: [{ id: 'var-rate', name: 'rate', field: 'posonly-deriv-csum-sum-diskio-in' }], - script: 'params.rate * -1', - }, - ], - split_mode: 'everything', - }, - ], -}); diff --git a/x-pack/plugins/infra/common/inventory_models/shared/metrics/tsvb/aws_diskio_ops.ts b/x-pack/plugins/infra/common/inventory_models/shared/metrics/tsvb/aws_diskio_ops.ts deleted file mode 100644 index c362a6d88c27a..0000000000000 --- a/x-pack/plugins/infra/common/inventory_models/shared/metrics/tsvb/aws_diskio_ops.ts +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { TSVBMetricModelCreator, TSVBMetricModel } from '../../../types'; - -export const awsDiskioOps: TSVBMetricModelCreator = (timeField, indexPattern): TSVBMetricModel => ({ - id: 'awsDiskioOps', - requires: ['aws.ec2'], - index_pattern: indexPattern, - map_field_to: 'cloud.instance.id', - id_type: 'cloud', - interval: '>=5m', - time_field: timeField, - type: 'timeseries', - series: [ - { - id: 'writes', - metrics: [ - { - field: 'aws.ec2.diskio.write.count', - id: 'sum-diskio-writes', - type: 'sum', - }, - { - id: 'csum-sum-diskio-writes', - field: 'sum-diskio-writes', - type: 'cumulative_sum', - }, - { - id: 'deriv-csum-sum-diskio-writes', - unit: '1s', - type: 'derivative', - field: 'csum-sum-diskio-writes', - }, - { - id: 'posonly-deriv-csum-sum-diskio-writes', - field: 'deriv-csum-sum-diskio-writes', - type: 'positive_only', - }, - ], - split_mode: 'everything', - }, - { - id: 'reads', - metrics: [ - { - field: 'aws.ec2.diskio.read.count', - id: 'sum-diskio-reads', - type: 'sum', - }, - { - id: 'csum-sum-diskio-reads', - field: 'sum-diskio-reads', - type: 'cumulative_sum', - }, - { - id: 'deriv-csum-sum-diskio-reads', - unit: '1s', - type: 'derivative', - field: 'csum-sum-diskio-reads', - }, - { - id: 'posonly-deriv-csum-sum-diskio-reads', - field: 'deriv-csum-sum-diskio-reads', - type: 'positive_only', - }, - { - id: 'inverted-posonly-deriv-csum-sum-diskio-reads', - type: 'calculation', - variables: [ - { id: 'var-rate', name: 'rate', field: 'posonly-deriv-csum-sum-diskio-reads' }, - ], - script: 'params.rate * -1', - }, - ], - split_mode: 'everything', - }, - ], -}); diff --git a/x-pack/plugins/infra/common/inventory_models/shared/metrics/tsvb/aws_network_bytes.ts b/x-pack/plugins/infra/common/inventory_models/shared/metrics/tsvb/aws_network_bytes.ts deleted file mode 100644 index b142feb95450c..0000000000000 --- a/x-pack/plugins/infra/common/inventory_models/shared/metrics/tsvb/aws_network_bytes.ts +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { TSVBMetricModelCreator, TSVBMetricModel } from '../../../types'; - -// see discussion in: https://github.com/elastic/kibana/issues/42687 - -export const awsNetworkBytes: TSVBMetricModelCreator = ( - timeField, - indexPattern -): TSVBMetricModel => ({ - id: 'awsNetworkBytes', - requires: ['aws.ec2'], - index_pattern: indexPattern, - map_field_to: 'cloud.instance.id', - id_type: 'cloud', - interval: '>=5m', - time_field: timeField, - type: 'timeseries', - series: [ - { - id: 'tx', - metrics: [ - { - field: 'aws.ec2.network.out.bytes', - id: 'sum-net-out', - type: 'sum', - }, - { - id: 'csum-sum-net-out', - field: 'sum-net-out', - type: 'cumulative_sum', - }, - { - id: 'deriv-csum-sum-net-out', - unit: '1s', - type: 'derivative', - field: 'csum-sum-net-out', - }, - { - id: 'posonly-deriv-csum-sum-net-out', - field: 'deriv-csum-sum-net-out', - type: 'positive_only', - }, - ], - split_mode: 'everything', - }, - { - id: 'rx', - metrics: [ - { - field: 'aws.ec2.network.in.bytes', - id: 'sum-net-in', - type: 'sum', - }, - { - id: 'csum-sum-net-in', - field: 'sum-net-in', - type: 'cumulative_sum', - }, - { - id: 'deriv-csum-sum-net-in', - unit: '1s', - type: 'derivative', - field: 'csum-sum-net-in', - }, - { - id: 'posonly-deriv-csum-sum-net-in', - field: 'deriv-csum-sum-net-in', - type: 'positive_only', - }, - { - id: 'inverted-posonly-deriv-csum-sum-net-in', - type: 'calculation', - variables: [{ id: 'var-rate', name: 'rate', field: 'posonly-deriv-csum-sum-net-in' }], - script: 'params.rate * -1', - }, - ], - split_mode: 'everything', - }, - ], -}); diff --git a/x-pack/plugins/infra/common/inventory_models/shared/metrics/tsvb/aws_network_packets.ts b/x-pack/plugins/infra/common/inventory_models/shared/metrics/tsvb/aws_network_packets.ts deleted file mode 100644 index 9d39582b66864..0000000000000 --- a/x-pack/plugins/infra/common/inventory_models/shared/metrics/tsvb/aws_network_packets.ts +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { TSVBMetricModelCreator, TSVBMetricModel } from '../../../types'; - -export const awsNetworkPackets: TSVBMetricModelCreator = ( - timeField, - indexPattern -): TSVBMetricModel => ({ - id: 'awsNetworkPackets', - requires: ['aws.ec2'], - index_pattern: indexPattern, - map_field_to: 'cloud.instance.id', - id_type: 'cloud', - interval: '>=5m', - time_field: timeField, - type: 'timeseries', - series: [ - { - id: 'packets-out', - metrics: [ - { - field: 'aws.ec2.network.out.packets', - id: 'avg-net-out', - type: 'avg', - }, - ], - split_mode: 'everything', - }, - { - id: 'packets-in', - metrics: [ - { - field: 'aws.ec2.network.in.packets', - id: 'avg-net-in', - type: 'avg', - }, - { - id: 'inverted-avg-net-in', - type: 'calculation', - variables: [{ id: 'var-avg', name: 'avg', field: 'avg-net-in' }], - script: 'params.avg * -1', - }, - ], - split_mode: 'everything', - }, - ], -}); diff --git a/x-pack/plugins/infra/common/inventory_models/shared/metrics/tsvb/aws_overview.ts b/x-pack/plugins/infra/common/inventory_models/shared/metrics/tsvb/aws_overview.ts deleted file mode 100644 index 3fe12d62d3352..0000000000000 --- a/x-pack/plugins/infra/common/inventory_models/shared/metrics/tsvb/aws_overview.ts +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { TSVBMetricModelCreator, TSVBMetricModel } from '../../../types'; - -export const awsOverview: TSVBMetricModelCreator = (timeField, indexPattern): TSVBMetricModel => ({ - id: 'awsOverview', - requires: ['aws.ec2'], - index_pattern: indexPattern, - map_field_to: 'cloud.instance.id', - id_type: 'cloud', - interval: '>=5m', - time_field: timeField, - type: 'top_n', - series: [ - { - id: 'cpu-util', - split_mode: 'everything', - metrics: [ - { - field: 'aws.ec2.cpu.total.pct', - id: 'cpu-total-pct', - type: 'max', - }, - ], - }, - { - id: 'status-check-failed', - split_mode: 'everything', - metrics: [ - { - field: 'aws.ec2.status.check_failed', - id: 'status-check-failed', - type: 'max', - }, - ], - }, - { - id: 'packets-out', - split_mode: 'everything', - metrics: [ - { - field: 'aws.ec2.network.out.packets', - id: 'network-out-packets', - type: 'avg', - }, - ], - }, - { - id: 'packets-in', - split_mode: 'everything', - metrics: [ - { - field: 'aws.ec2.network.in.packets', - id: 'network-in-packets', - type: 'avg', - }, - ], - }, - ], -}); diff --git a/x-pack/plugins/infra/common/inventory_models/types.ts b/x-pack/plugins/infra/common/inventory_models/types.ts index 5bc36429e2ba2..fd52c1c230c17 100644 --- a/x-pack/plugins/infra/common/inventory_models/types.ts +++ b/x-pack/plugins/infra/common/inventory_models/types.ts @@ -37,21 +37,6 @@ export type InventoryFormatterType = rt.TypeOf; export type InventoryItemType = rt.TypeOf; export const InventoryMetricRT = rt.keyof({ - hostSystemOverview: null, - hostCpuUsage: null, - hostFilesystem: null, - hostK8sOverview: null, - hostK8sCpuCap: null, - hostK8sDiskCap: null, - hostK8sMemoryCap: null, - hostK8sPodCap: null, - hostLoad: null, - hostMemoryUsage: null, - hostNetworkTraffic: null, - hostDockerOverview: null, - hostDockerInfo: null, - hostDockerTop5ByCpu: null, - hostDockerTop5ByMemory: null, podOverview: null, podCpuUsage: null, podMemoryUsage: null, @@ -71,12 +56,6 @@ export const InventoryMetricRT = rt.keyof({ nginxRequestRate: null, nginxActiveConnections: null, nginxRequestsPerConnection: null, - awsOverview: null, - awsCpuUtilization: null, - awsNetworkBytes: null, - awsNetworkPackets: null, - awsDiskioBytes: null, - awsDiskioOps: null, awsEC2CpuUtilization: null, awsEC2NetworkTraffic: null, awsEC2DiskIOBytes: null, @@ -377,7 +356,7 @@ export const SnapshotMetricTypeRT = rt.keyof(SnapshotMetricTypeKeys); export type SnapshotMetricType = rt.TypeOf; export interface InventoryMetrics { - tsvb: { [name: string]: TSVBMetricModelCreator }; + tsvb?: { [name: string]: TSVBMetricModelCreator }; snapshot: { [name: string]: MetricsUIAggregation | undefined }; defaultSnapshot: SnapshotMetricType; /** This is used by the inventory view to calculate the appropriate amount of time for the metrics detail page. Some metris like awsS3 require multiple days where others like host only need an hour.*/ @@ -403,7 +382,7 @@ export interface InventoryModel { uptime: boolean; }; metrics: InventoryMetrics; - requiredMetrics: InventoryMetric[]; + requiredMetrics?: InventoryMetric[]; tooltipMetrics: SnapshotMetricType[]; nodeFilter?: object[]; } diff --git a/x-pack/plugins/infra/public/components/asset_details/hooks/use_metadata.ts b/x-pack/plugins/infra/public/components/asset_details/hooks/use_metadata.ts index 2750394da702f..c06344270c2f0 100644 --- a/x-pack/plugins/infra/public/components/asset_details/hooks/use_metadata.ts +++ b/x-pack/plugins/infra/public/components/asset_details/hooks/use_metadata.ts @@ -15,16 +15,23 @@ import { throwErrors, createPlainError } from '../../../../common/runtime_types' import { getFilteredMetrics } from '../../../pages/metrics/metric_detail/lib/get_filtered_metrics'; import type { InventoryItemType, InventoryMetric } from '../../../../common/inventory_models/types'; -export function useMetadata( - nodeId: string, - nodeType: InventoryItemType, - requiredMetrics: InventoryMetric[], - sourceId: string, +interface UseMetadataProps { + assetId: string; + assetType: InventoryItemType; + requiredMetrics?: InventoryMetric[]; + sourceId: string; timeRange: { from: number; to: number; - } -) { + }; +} +export function useMetadata({ + assetId, + assetType, + sourceId, + timeRange, + requiredMetrics = [], +}: UseMetadataProps) { const decodeResponse = (response: any) => { return pipe(InfraMetadataRT.decode(response), fold(throwErrors(createPlainError), identity)); }; @@ -32,8 +39,8 @@ export function useMetadata( '/api/infra/metadata', 'POST', JSON.stringify({ - nodeId, - nodeType, + nodeId: assetId, + nodeType: assetType, sourceId, timeRange, }), @@ -49,17 +56,13 @@ export function useMetadata( return { name: (response && response.name) || '', filteredRequiredMetrics: - (response && getFilteredMetrics(requiredMetrics, response.features)) || [], + response && requiredMetrics.length > 0 + ? getFilteredMetrics(requiredMetrics, response.features) + : [], error: (error && error.message) || null, loading, metadata: response, - cloudId: - (response && - response.info && - response.info.cloud && - response.info.cloud.instance && - response.info.cloud.instance.id) || - '', + cloudId: response?.info?.cloud?.instance?.id || '', reload: makeRequest, }; } diff --git a/x-pack/plugins/infra/public/components/asset_details/hooks/use_metadata_state.ts b/x-pack/plugins/infra/public/components/asset_details/hooks/use_metadata_state.ts index 4d0f0c66f67c8..0df9ae9a152dd 100644 --- a/x-pack/plugins/infra/public/components/asset_details/hooks/use_metadata_state.ts +++ b/x-pack/plugins/infra/public/components/asset_details/hooks/use_metadata_state.ts @@ -7,7 +7,6 @@ import { useEffect, useCallback } from 'react'; import createContainer from 'constate'; -import { findInventoryModel } from '../../../../common/inventory_models'; import { useSourceContext } from '../../../containers/metrics_source'; import { useMetadata } from './use_metadata'; import { AssetDetailsProps } from '../types'; @@ -19,16 +18,14 @@ export type UseMetadataProviderProps = Pick { reload(); diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/osquery/index.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/osquery/index.tsx index 26ff945d04025..7339043ffa98f 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/osquery/index.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/osquery/index.tsx @@ -11,7 +11,6 @@ import React, { useMemo } from 'react'; import { useKibanaContextForPlugin } from '../../../../../../../hooks/use_kibana'; import { TabContent, TabProps } from '../shared'; import { useSourceContext } from '../../../../../../../containers/metrics_source'; -import { findInventoryModel } from '../../../../../../../../common/inventory_models'; import { InventoryItemType } from '../../../../../../../../common/inventory_models/types'; import { useMetadata } from '../../../../../../../components/asset_details/hooks/use_metadata'; import { useWaffleTimeContext } from '../../../../hooks/use_waffle_time'; @@ -19,16 +18,14 @@ import { useWaffleTimeContext } from '../../../../hooks/use_waffle_time'; const TabComponent = (props: TabProps) => { const nodeId = props.node.id; const nodeType = props.nodeType as InventoryItemType; - const inventoryModel = findInventoryModel(nodeType); const { sourceId } = useSourceContext(); const { currentTimeRange } = useWaffleTimeContext(); - const { loading, metadata } = useMetadata( - nodeId, - nodeType, - inventoryModel.requiredMetrics, + const { loading, metadata } = useMetadata({ + assetId: nodeId, + assetType: nodeType, sourceId, - currentTimeRange - ); + timeRange: currentTimeRange, + }); const { services: { osquery }, } = useKibanaContextForPlugin(); diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/index.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/index.tsx index bc0ee279b2cbd..c8550a4d05163 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/index.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/index.tsx @@ -11,7 +11,6 @@ import { EuiLoadingChart } from '@elastic/eui'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; import { TabContent, TabProps } from '../shared'; import { useSourceContext } from '../../../../../../../containers/metrics_source'; -import { findInventoryModel } from '../../../../../../../../common/inventory_models'; import { InventoryItemType } from '../../../../../../../../common/inventory_models/types'; import { useMetadata } from '../../../../../../../components/asset_details/hooks/use_metadata'; import { getFields } from './build_fields'; @@ -22,17 +21,15 @@ import { useWaffleFiltersContext } from '../../../../hooks/use_waffle_filters'; const TabComponent = (props: TabProps) => { const nodeId = props.node.id; const nodeType = props.nodeType as InventoryItemType; - const inventoryModel = findInventoryModel(nodeType); const { sourceId } = useSourceContext(); const { currentTimeRange } = useWaffleTimeContext(); const { applyFilterQuery } = useWaffleFiltersContext(); - const { loading: metadataLoading, metadata } = useMetadata( - nodeId, - nodeType, - inventoryModel.requiredMetrics, + const { loading: metadataLoading, metadata } = useMetadata({ + assetId: nodeId, + assetType: nodeType, sourceId, - currentTimeRange - ); + timeRange: currentTimeRange, + }); const hostFields = useMemo(() => { if (!metadata) return null; diff --git a/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/layout.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/layout.tsx index a2b48e9b7f2f3..c89fa6f7fe601 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/layout.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/layout.tsx @@ -13,7 +13,6 @@ import { AwsRDSLayout } from './layouts/aws_rds_layout'; import { AwsS3Layout } from './layouts/aws_s3_layout'; import { AwsSQSLayout } from './layouts/aws_sqs_layout'; import { ContainerLayout } from './layouts/container_layout'; -import { HostLayout } from './layouts/host_layout'; import { PodLayout } from './layouts/pod_layout'; export const Layout = ({ @@ -31,9 +30,9 @@ export const Layout = ({ return ; case 'container': return ; - case 'host': - return ; case 'pod': return ; + default: + throw new Error(`${inventoryItemType} is not supported.`); } }; diff --git a/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/layouts/aws_layout_sections.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/layouts/aws_layout_sections.tsx deleted file mode 100644 index 75c06c30b968a..0000000000000 --- a/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/layouts/aws_layout_sections.tsx +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; -import { withTheme } from '@kbn/kibana-react-plugin/common'; -import React from 'react'; -import type { LayoutPropsWithTheme } from '../../types'; -import { ChartSectionVis } from '../chart_section_vis'; -import { GaugesSectionVis } from '../gauges_section_vis'; -import { Section } from '../section'; -import { SubSection } from '../sub_section'; - -export const AwsLayoutSection = withTheme( - ({ metrics, onChangeRangeTime, theme }: LayoutPropsWithTheme) => ( - -
- - - - - - - - - - - - - - - - - - -
-
- ) -); diff --git a/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/layouts/host_layout.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/layouts/host_layout.tsx deleted file mode 100644 index 41e0204bc7b29..0000000000000 --- a/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/layouts/host_layout.tsx +++ /dev/null @@ -1,376 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { EuiPanel } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import { withTheme } from '@kbn/kibana-react-plugin/common'; -import React from 'react'; -import type { LayoutPropsWithTheme } from '../../types'; -import { ChartSectionVis } from '../chart_section_vis'; -import { GaugesSectionVis } from '../gauges_section_vis'; -import { MetadataDetails } from '../metadata_details'; -import { Section } from '../section'; -import { SubSection } from '../sub_section'; -import { AwsLayoutSection } from './aws_layout_sections'; -import { NginxLayoutSection } from './nginx_layout_sections'; - -export const HostLayout = withTheme( - ({ metrics, onChangeRangeTime, theme }: LayoutPropsWithTheme) => ( - - - -
- - - - - - - - - - - - - - - -
-
- - - - - - - - - - - - - - - -
- - -
-
- ) -); diff --git a/x-pack/plugins/infra/public/pages/metrics/metric_detail/metric_detail_page.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/metric_detail_page.tsx index 1f049814a23d3..15425ef618049 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metric_detail/metric_detail_page.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/metric_detail_page.tsx @@ -42,7 +42,13 @@ export const MetricDetailPage = () => { loading: metadataLoading, cloudId, metadata, - } = useMetadata(nodeId, nodeType, inventoryModel.requiredMetrics, sourceId, parsedTimeRange); + } = useMetadata({ + assetId: nodeId, + assetType: nodeType, + requiredMetrics: inventoryModel.requiredMetrics, + sourceId, + timeRange: parsedTimeRange, + }); const [sideNav, setSideNav] = useState([]); diff --git a/x-pack/plugins/infra/server/routes/node_details/index.ts b/x-pack/plugins/infra/server/routes/node_details/index.ts index cd92c902a110e..56eccbbe160e9 100644 --- a/x-pack/plugins/infra/server/routes/node_details/index.ts +++ b/x-pack/plugins/infra/server/routes/node_details/index.ts @@ -34,30 +34,46 @@ export const initNodeDetailsRoute = (libs: InfraBackendLibs) => { }, }, async (requestContext, request, response) => { - const { nodeId, cloudId, nodeType, metrics, timerange, sourceId } = pipe( - NodeDetailsRequestRT.decode(request.body), - fold(throwErrors(Boom.badRequest), identity) - ); - const soClient = (await requestContext.core).savedObjects.client; - const source = await libs.sources.getSourceConfiguration(soClient, sourceId); - - UsageCollector.countNode(nodeType); - - const options: InfraMetricsRequestOptions = { - nodeIds: { - nodeId, - cloudId, - }, - nodeType, - sourceConfiguration: source.configuration, - metrics, - timerange, - }; - return response.ok({ - body: NodeDetailsMetricDataResponseRT.encode({ - metrics: await libs.metrics.getMetrics(requestContext, options, request), - }), - }); + try { + const { nodeId, cloudId, nodeType, metrics, timerange, sourceId } = pipe( + NodeDetailsRequestRT.decode(request.body), + fold(throwErrors(Boom.badRequest), identity) + ); + const soClient = (await requestContext.core).savedObjects.client; + const source = await libs.sources.getSourceConfiguration(soClient, sourceId); + + UsageCollector.countNode(nodeType); + + const options: InfraMetricsRequestOptions = { + nodeIds: { + nodeId, + cloudId, + }, + nodeType, + sourceConfiguration: source.configuration, + metrics, + timerange, + }; + return response.ok({ + body: NodeDetailsMetricDataResponseRT.encode({ + metrics: await libs.metrics.getMetrics(requestContext, options, request), + }), + }); + } catch (err) { + if (Boom.isBoom(err)) { + return response.customError({ + statusCode: err.output.statusCode, + body: { message: err.output.payload.message }, + }); + } + + return response.customError({ + statusCode: err.statusCode ?? 500, + body: { + message: err.message ?? 'An unexpected error occurred', + }, + }); + } } ); }; diff --git a/x-pack/plugins/log_explorer/common/dataset_selection/index.ts b/x-pack/plugins/log_explorer/common/dataset_selection/index.ts index 3284610f53bcc..f390f7a89f87c 100644 --- a/x-pack/plugins/log_explorer/common/dataset_selection/index.ts +++ b/x-pack/plugins/log_explorer/common/dataset_selection/index.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { DataViewListItem } from '@kbn/data-views-plugin/common'; import { AllDatasetSelection } from './all_dataset_selection'; import { SingleDatasetSelection } from './single_dataset_selection'; import { UnresolvedDatasetSelection } from './unresolved_dataset_selection'; @@ -14,6 +15,7 @@ export type DatasetSelection = | SingleDatasetSelection | UnresolvedDatasetSelection; export type DatasetSelectionChange = (datasetSelection: DatasetSelection) => void; +export type DataViewSelection = (dataView: DataViewListItem) => void; export const isDatasetSelection = (input: any): input is DatasetSelection => { return ( diff --git a/x-pack/plugins/log_explorer/public/components/dataset_selector/constants.tsx b/x-pack/plugins/log_explorer/public/components/dataset_selector/constants.tsx index 1cbcd6a0f032a..28a5401f98048 100644 --- a/x-pack/plugins/log_explorer/public/components/dataset_selector/constants.tsx +++ b/x-pack/plugins/log_explorer/public/components/dataset_selector/constants.tsx @@ -12,8 +12,10 @@ export const INTEGRATIONS_PANEL_ID = 'dataset-selector-integrations-panel'; export const INTEGRATIONS_TAB_ID = 'dataset-selector-integrations-tab'; export const UNCATEGORIZED_PANEL_ID = 'dataset-selector-uncategorized-panel'; export const UNCATEGORIZED_TAB_ID = 'dataset-selector-uncategorized-tab'; +export const DATA_VIEWS_PANEL_ID = 'dataset-selector-data-views-panel'; +export const DATA_VIEWS_TAB_ID = 'dataset-selector-data-views-tab'; -export const DATA_VIEW_POPOVER_CONTENT_WIDTH = 300; +export const DATA_VIEW_POPOVER_CONTENT_WIDTH = 400; export const showAllLogsLabel = i18n.translate('xpack.logExplorer.datasetSelector.showAllLogs', { defaultMessage: 'Show all logs', @@ -28,6 +30,14 @@ export const uncategorizedLabel = i18n.translate( { defaultMessage: 'Uncategorized' } ); +export const dataViewsLabel = i18n.translate('xpack.logExplorer.datasetSelector.dataViews', { + defaultMessage: 'Data Views', +}); + +export const openDiscoverLabel = i18n.translate('xpack.logExplorer.datasetSelector.openDiscover', { + defaultMessage: 'Opens in Discover', +}); + export const sortOrdersLabel = i18n.translate('xpack.logExplorer.datasetSelector.sortOrders', { defaultMessage: 'Sort directions', }); @@ -43,6 +53,17 @@ export const noDatasetsDescriptionLabel = i18n.translate( } ); +export const noDataViewsLabel = i18n.translate('xpack.logExplorer.datasetSelector.noDataViews', { + defaultMessage: 'No data views found', +}); + +export const noDataViewsDescriptionLabel = i18n.translate( + 'xpack.logExplorer.datasetSelector.noDataViewsDescription', + { + defaultMessage: 'No data views or search results found.', + } +); + export const noIntegrationsLabel = i18n.translate( 'xpack.logExplorer.datasetSelector.noIntegrations', { defaultMessage: 'No integrations found' } diff --git a/x-pack/plugins/log_explorer/public/components/dataset_selector/dataset_selector.stories.tsx b/x-pack/plugins/log_explorer/public/components/dataset_selector/dataset_selector.stories.tsx index 10bc958c8f2ce..82178164994eb 100644 --- a/x-pack/plugins/log_explorer/public/components/dataset_selector/dataset_selector.stories.tsx +++ b/x-pack/plugins/log_explorer/public/components/dataset_selector/dataset_selector.stories.tsx @@ -11,6 +11,7 @@ import React, { useState } from 'react'; import { I18nProvider } from '@kbn/i18n-react'; import type { Meta, Story } from '@storybook/react'; import { IndexPattern } from '@kbn/io-ts-utils'; +import { DataViewListItem } from '@kbn/data-views-plugin/common'; import { AllDatasetSelection, DatasetSelection, @@ -29,6 +30,10 @@ const meta: Meta = { options: [null, { message: 'Failed to fetch data streams' }], control: { type: 'radio' }, }, + dataViewsError: { + options: [null, { message: 'Failed to fetch data data views' }], + control: { type: 'radio' }, + }, integrationsError: { options: [null, { message: 'Failed to fetch data integrations' }], control: { type: 'radio' }, @@ -71,20 +76,39 @@ const DatasetSelectorTemplate: Story = (args) => { const sortedDatasets = search.sortOrder === 'asc' ? filteredDatasets : filteredDatasets.reverse(); + const filteredDataViews = mockDataViews.filter((dataView) => + dataView.name?.includes(search.name as string) + ); + + const sortedDataViews = + search.sortOrder === 'asc' ? filteredDataViews : filteredDataViews.reverse(); + + const { + datasetsError, + dataViewsError, + integrationsError, + isLoadingDataViews, + isLoadingIntegrations, + isLoadingUncategorized, + } = args; + return ( ); }; @@ -92,12 +116,18 @@ const DatasetSelectorTemplate: Story = (args) => { export const Basic = DatasetSelectorTemplate.bind({}); Basic.args = { datasetsError: null, + dataViewsError: null, integrationsError: null, + isLoadingDataViews: false, isLoadingIntegrations: false, - isLoadingStreams: false, + isLoadingUncategorized: false, + isSearchingIntegrations: false, + onDataViewsReload: () => alert('Reload data views...'), + onDataViewSelection: (dataView) => alert(`Navigate to data view "${dataView.name}"`), + onDataViewsTabClick: () => console.log('Load data views...'), onIntegrationsReload: () => alert('Reload integrations...'), - onStreamsEntryClick: () => console.log('Load uncategorized streams...'), - onUnmanagedStreamsReload: () => alert('Reloading streams...'), + onUncategorizedTabClick: () => console.log('Load uncategorized streams...'), + onUncategorizedReload: () => alert('Reloading streams...'), }; const mockIntegrations: Integration[] = [ @@ -477,3 +507,25 @@ const mockDatasets: Dataset[] = [ { name: 'data-load-balancing-logs-*' as IndexPattern }, { name: 'data-scaling-logs-*' as IndexPattern }, ].map((dataset) => Dataset.create(dataset)); + +const mockDataViews: DataViewListItem[] = [ + { + id: 'logs-*', + namespaces: ['default'], + title: 'logs-*', + name: 'logs-*', + }, + { + id: 'metrics-*', + namespaces: ['default'], + title: 'metrics-*', + name: 'metrics-*', + }, + { + id: '7258d186-6430-4b51-bb67-2603cdfb4652', + namespaces: ['default'], + title: 'synthetics-*', + typeMeta: {}, + name: 'synthetics-dashboard', + }, +]; diff --git a/x-pack/plugins/log_explorer/public/components/dataset_selector/dataset_selector.tsx b/x-pack/plugins/log_explorer/public/components/dataset_selector/dataset_selector.tsx index f9e722effc784..10d8b4c046c9a 100644 --- a/x-pack/plugins/log_explorer/public/components/dataset_selector/dataset_selector.tsx +++ b/x-pack/plugins/log_explorer/public/components/dataset_selector/dataset_selector.tsx @@ -10,6 +10,9 @@ import styled from '@emotion/styled'; import { EuiContextMenu, EuiHorizontalRule, EuiTab, EuiTabs } from '@elastic/eui'; import { useIntersectionRef } from '../../hooks/use_intersection_ref'; import { + dataViewsLabel, + DATA_VIEWS_PANEL_ID, + DATA_VIEWS_TAB_ID, DATA_VIEW_POPOVER_CONTENT_WIDTH, integrationsLabel, INTEGRATIONS_PANEL_ID, @@ -25,19 +28,30 @@ import { SelectorActions } from './sub_components/selector_actions'; import { DatasetSelectorProps } from './types'; import { buildIntegrationsTree, + createDataViewsStatusItem, createIntegrationStatusItem, createUncategorizedStatusItem, } from './utils'; +import { getDataViewTestSubj } from '../../utils/get_data_view_test_subj'; +import { DataViewsPanelTitle } from './sub_components/data_views_panel_title'; export function DatasetSelector({ datasets, - datasetsError, datasetSelection, + datasetsError, + dataViews, + dataViewsError, integrations, integrationsError, + isLoadingDataViews, isLoadingIntegrations, - isLoadingStreams, + isLoadingUncategorized, isSearchingIntegrations, + onDataViewSelection, + onDataViewsReload, + onDataViewsSearch, + onDataViewsSort, + onDataViewsTabClick, onIntegrationsLoadMore, onIntegrationsReload, onIntegrationsSearch, @@ -45,10 +59,10 @@ export function DatasetSelector({ onIntegrationsStreamsSearch, onIntegrationsStreamsSort, onSelectionChange, - onStreamsEntryClick, - onUnmanagedStreamsReload, - onUnmanagedStreamsSearch, - onUnmanagedStreamsSort, + onUncategorizedReload, + onUncategorizedSearch, + onUncategorizedSort, + onUncategorizedTabClick, }: DatasetSelectorProps) { const { panelId, @@ -62,21 +76,26 @@ export function DatasetSelector({ searchByName, selectAllLogDataset, selectDataset, + selectDataView, sortByOrder, switchToIntegrationsTab, switchToUncategorizedTab, + switchToDataViewsTab, togglePopover, } = useDatasetSelector({ initialContext: { selection: datasetSelection }, + onDataViewSelection, + onDataViewsSearch, + onDataViewsSort, onIntegrationsLoadMore, onIntegrationsReload, onIntegrationsSearch, onIntegrationsSort, onIntegrationsStreamsSearch, onIntegrationsStreamsSort, - onUnmanagedStreamsSearch, - onUnmanagedStreamsSort, - onUnmanagedStreamsReload, + onUncategorizedSearch, + onUncategorizedSort, + onUncategorizedReload, onSelectionChange, }); @@ -117,8 +136,8 @@ export function DatasetSelector({ createUncategorizedStatusItem({ data: datasets, error: datasetsError, - isLoading: isLoadingStreams, - onRetry: onUnmanagedStreamsReload, + isLoading: isLoadingUncategorized, + onRetry: onUncategorizedReload, }), ]; } @@ -127,7 +146,26 @@ export function DatasetSelector({ name: dataset.title, onClick: () => selectDataset(dataset), })); - }, [datasets, datasetsError, isLoadingStreams, selectDataset, onUnmanagedStreamsReload]); + }, [datasets, datasetsError, isLoadingUncategorized, selectDataset, onUncategorizedReload]); + + const dataViewsItems = useMemo(() => { + if (!dataViews || dataViews.length === 0) { + return [ + createDataViewsStatusItem({ + data: dataViews, + error: dataViewsError, + isLoading: isLoadingDataViews, + onRetry: onDataViewsReload, + }), + ]; + } + + return dataViews.map((dataView) => ({ + 'data-test-subj': getDataViewTestSubj(dataView.title), + name: dataView.name, + onClick: () => selectDataView(dataView), + })); + }, [dataViews, dataViewsError, isLoadingDataViews, selectDataView, onDataViewsReload]); const tabs = [ { @@ -140,11 +178,20 @@ export function DatasetSelector({ id: UNCATEGORIZED_TAB_ID, name: uncategorizedLabel, onClick: () => { - onStreamsEntryClick(); // Lazy-load uncategorized datasets only when accessing the Uncategorized tab + onUncategorizedTabClick(); // Lazy-load uncategorized datasets only when accessing the Uncategorized tab switchToUncategorizedTab(); }, 'data-test-subj': 'datasetSelectorUncategorizedTab', }, + { + id: DATA_VIEWS_TAB_ID, + name: dataViewsLabel, + onClick: () => { + onDataViewsTabClick(); // Lazy-load data views only when accessing the Data Views tab + switchToDataViewsTab(); + }, + 'data-test-subj': 'datasetSelectorDataViewsTab', + }, ]; const tabEntries = tabs.map((tab) => ( @@ -175,7 +222,7 @@ export function DatasetSelector({ search={search} onSearch={searchByName} onSort={sortByOrder} - isLoading={isSearchingIntegrations || isLoadingStreams} + isLoading={isSearchingIntegrations || isLoadingUncategorized} /> {/* For a smoother user experience, we keep each tab content mount and we only show the select one @@ -215,6 +262,22 @@ export function DatasetSelector({ data-test-subj="uncategorizedContextMenu" size="s" /> + {/* Data views tab content */} +