From d213107c15ac6df7c2997c8022402c783517e559 Mon Sep 17 00:00:00 2001 From: Sean Story Date: Mon, 17 Apr 2023 08:43:46 -0500 Subject: [PATCH 01/17] Have createPipeline pass along fieldMappings (#154951) ## Summary previously createPipeline wasn't passing along fieldMappings, which was leading to errors like: screenshot ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --- .../enterprise_search/common/types/pipelines.ts | 3 +++ .../pipelines/create_ml_inference_pipeline.ts | 10 +++++++--- .../ml_inference/ml_inference_logic.test.ts | 16 ++++++++++++++-- .../pipelines/ml_inference/ml_inference_logic.ts | 5 +++-- 4 files changed, 27 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/enterprise_search/common/types/pipelines.ts b/x-pack/plugins/enterprise_search/common/types/pipelines.ts index 3e652d97c6f4f..ea86183ce9ea8 100644 --- a/x-pack/plugins/enterprise_search/common/types/pipelines.ts +++ b/x-pack/plugins/enterprise_search/common/types/pipelines.ts @@ -7,6 +7,8 @@ import { IngestInferenceConfig, IngestPipeline } from '@elastic/elasticsearch/lib/api/types'; +import { FieldMapping } from '../ml_inference_pipeline'; + export interface InferencePipeline { modelId: string | undefined; modelState: TrainedModelState; @@ -81,6 +83,7 @@ export interface CreateMlInferencePipelineParameters { } export interface CreateMLInferencePipelineDefinition { + field_mappings: FieldMapping[]; pipeline_definition: MlInferencePipeline; pipeline_name: string; } diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/pipelines/create_ml_inference_pipeline.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/pipelines/create_ml_inference_pipeline.ts index cc224093cc4e8..5161ec751bd77 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/pipelines/create_ml_inference_pipeline.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/pipelines/create_ml_inference_pipeline.ts @@ -4,6 +4,8 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +import { FieldMapping } from '../../../../../common/ml_inference_pipeline'; + import { CreateMlInferencePipelineParameters, CreateMLInferencePipelineDefinition, @@ -23,9 +25,10 @@ interface CreateMlInferencePipelineApiLogicArgsWithPipelineParameters { } interface CreateMlInferencePipelineApiLogicArgsWithPipelineDefinition { + fieldMappings: FieldMapping[]; indexName: string; - pipelineName: string; pipelineDefinition: MlInferencePipeline; + pipelineName: string; } export type CreateMlInferencePipelineApiLogicArgs = @@ -64,14 +67,15 @@ export const createMlInferencePipeline = async ( destination_field: args.destinationField, inference_config: args.inferenceConfig, model_id: args.modelId, - pipeline_name: args.pipelineName, pipeline_definition: undefined, + pipeline_name: args.pipelineName, source_field: args.sourceField, }; } else if (isArgsWithPipelineDefinition(args)) { params = { - pipeline_name: args.pipelineName, + field_mappings: args.fieldMappings, pipeline_definition: args.pipelineDefinition, + pipeline_name: args.pipelineName, }; } return await HttpLogic.values.http.post(route, { diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.test.ts index 531678629aeb7..1c38c99bd5c93 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.test.ts @@ -531,10 +531,16 @@ describe('MlInferenceLogic', () => { MLModelsApiLogic.actions.apiSuccess([textExpansionModel]); MLInferenceLogic.actions.setInferencePipelineConfiguration({ - destinationField: 'my-dest-field', + destinationField: mockModelConfiguration.configuration.destinationField, + fieldMappings: [ + { + sourceField: 'source', + targetField: 'ml.inference.dest', + }, + ], modelID: textExpansionModel.model_id, pipelineName: mockModelConfiguration.configuration.pipelineName, - sourceField: 'my-field', + sourceField: mockModelConfiguration.configuration.sourceField, }); MLInferenceLogic.actions.createPipeline(); @@ -542,6 +548,12 @@ describe('MlInferenceLogic', () => { indexName: mockModelConfiguration.indexName, pipelineName: mockModelConfiguration.configuration.pipelineName, pipelineDefinition: expect.any(Object), // Generation logic is tested elsewhere + fieldMappings: [ + { + sourceField: 'source', + targetField: 'ml.inference.dest', + }, + ], }); }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.ts index 996ae0e6e8708..98bcaa6671495 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.ts @@ -257,11 +257,12 @@ export const MLInferenceLogic = kea< mlInferencePipeline, // Full pipeline definition } = values; actions.makeCreatePipelineRequest( - isTextExpansionModelSelected && mlInferencePipeline + isTextExpansionModelSelected && mlInferencePipeline && configuration.fieldMappings ? { indexName, - pipelineName: configuration.pipelineName, + fieldMappings: configuration.fieldMappings, pipelineDefinition: mlInferencePipeline, + pipelineName: configuration.pipelineName, } : { destinationField: From eb6bfd8476c77b31361b1c1a914ec047e53799d0 Mon Sep 17 00:00:00 2001 From: Lola Date: Mon, 17 Apr 2023 10:17:47 -0400 Subject: [PATCH 02/17] [Cloud Posture] Vul mgmt flyout details panel (#154873) ## Summary Summarize your PR. If it involves visual changes include a screenshot or gif. Screen Shot 2023-04-12 at 5 04 30 PM Screen Shot 2023-04-12 at 5 30 55 PM Screen Shot 2023-04-12 at 5 31 09 PM Flyou details Feature includes: Results are fetched from the logs-cloud_security_posture.vulnerabilities-default index. A Flyout opens when clicking the Expand Icon in the Vulnerabilities table. The Flyout has two tabs: Overview and JSON. The Overview tab consists of four sections: CVSS, Data source, Publish date, Description, Fixes, and Vulnerability Scores TODO Add pagination in follow up pr Add unit tests --- .../components/vulnerability_badges.tsx | 33 +-- .../public/pages/vulnerabilities/types.ts | 98 ++++--- .../public/pages/vulnerabilities/utils.ts | 27 ++ .../pages/vulnerabilities/vulnerabilities.tsx | 143 ++++++---- .../vulnerability_finding_flyout.tsx | 149 ++++++++++ .../vulnerability_json_tab.tsx | 32 +++ .../vulnerability_overview_tab.tsx | 260 ++++++++++++++++++ 7 files changed, 616 insertions(+), 126 deletions(-) create mode 100644 x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/vulnerabilities_finding_flyout/vulnerability_finding_flyout.tsx create mode 100644 x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/vulnerabilities_finding_flyout/vulnerability_json_tab.tsx create mode 100644 x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/vulnerabilities_finding_flyout/vulnerability_overview_tab.tsx diff --git a/x-pack/plugins/cloud_security_posture/public/components/vulnerability_badges.tsx b/x-pack/plugins/cloud_security_posture/public/components/vulnerability_badges.tsx index 713b29d06b573..61d8f4b849550 100644 --- a/x-pack/plugins/cloud_security_posture/public/components/vulnerability_badges.tsx +++ b/x-pack/plugins/cloud_security_posture/public/components/vulnerability_badges.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { EuiBadge, EuiIcon, EuiTextColor, useEuiFontSize } from '@elastic/eui'; +import { EuiBadge, EuiIcon, EuiTextColor } from '@elastic/eui'; import React from 'react'; import { css } from '@emotion/react'; import { float } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; @@ -21,10 +21,6 @@ interface SeverityStatusBadgeProps { score: float; } -interface ExploitsStatusBadgeProps { - totalExploits: number; -} - export const CVSScoreBadge = ({ score, version }: CVSScoreBadgeProps) => { const color = getCvsScoreColor(score); const versionDisplay = version ? `v${version.split('.')[0]}` : null; @@ -60,28 +56,15 @@ export const SeverityStatusBadge = ({ score, status }: SeverityStatusBadgeProps) const color = getCvsScoreColor(score); return ( - <> - - {status} - - ); -}; - -export const ExploitsStatusBadge = ({ totalExploits }: ExploitsStatusBadgeProps) => { - const xxsFontSize = useEuiFontSize('xxs').fontSize; - - return ( - - {totalExploits} - + + {status} + ); }; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/types.ts b/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/types.ts index d7810fde2a1fb..8f01271677321 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/types.ts +++ b/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/types.ts @@ -20,48 +20,7 @@ export interface VulnerabilityRecord { sequence: number; outcome: string; }; - vulnerability: { - score: { - version: string; - impact: number; - base: number; - }; - cwe: string[]; - id: string; - title: string; - reference: string; - severity: string; - cvss: { - nvd: { - V3Vector: string; - V3Score: number; - }; - redhat?: { - V3Vector: string; - V3Score: number; - }; - ghsa?: { - V3Vector: string; - V3Score: number; - }; - }; - data_source: { - ID: string; - Name: string; - URL: string; - }; - enumeration: string; - description: string; - classification: string; - scanner: { - vendor: string; - }; - package: { - version: string; - name: string; - fixed_version: string; - }; - }; + vulnerability: Vulnerability; ecs: { version: string; }; @@ -116,3 +75,58 @@ export interface VulnerabilityRecord { commit_time: string; }; } + +export interface Vulnerability { + published_at: string; + score: { + version: string; + impact: number; + base: number; + }; + cwe: string[]; + id: string; + title: string; + reference: string; + severity: string; + cvss: { + nvd: VectorScoreBase; + redhat?: VectorScoreBase; + ghsa?: VectorScoreBase; + }; + data_source: { + ID: string; + Name: string; + URL: string; + }; + enumeration: string; + description: string; + classification: string; + scanner: { + vendor: string; + }; + package: { + version: string; + name: string; + fixed_version: string; + }; +} + +export interface VectorScoreBase { + V3Score?: number; + V3Vector?: string; + V2Score?: number; + V2Vector?: string; +} + +export type Vendor = 'NVD' | 'Red Hat' | 'GHSA'; + +export interface CVSScoreProps { + vectorBaseScore: VectorScoreBase; + vendor: string; +} + +export interface Vector { + version: string; + vector: string; + score: number | undefined; +} diff --git a/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/utils.ts b/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/utils.ts index ff2171aa76013..4e9c346e3969a 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/utils.ts +++ b/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/utils.ts @@ -7,6 +7,7 @@ import { EuiDataGridColumn } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { VectorScoreBase, Vector } from './types'; export const vulnerabilitiesColumns = { actions: 'actions', @@ -85,3 +86,29 @@ export const getVulnerabilitiesColumnsGrid = (): EuiDataGridColumn[] => { }, ]; }; + +export const getVectorScoreList = (vectorBaseScore: VectorScoreBase) => { + const result: Vector[] = []; + const v2Vector = vectorBaseScore?.V2Vector; + const v2Score = vectorBaseScore?.V2Score; + const v3Vector = vectorBaseScore?.V3Vector; + const v3Score = vectorBaseScore?.V3Score; + + if (v2Vector) { + result.push({ + version: '2.0', + vector: v2Vector, + score: v2Score, + }); + } + + if (v3Vector) { + result.push({ + version: '2.0', + vector: v3Vector, + score: v3Score, + }); + } + + return result; +}; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/vulnerabilities.tsx b/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/vulnerabilities.tsx index 174939a5e0f99..c63d45d9592d6 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/vulnerabilities.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/vulnerabilities.tsx @@ -17,7 +17,7 @@ import { import { css } from '@emotion/react'; import { FormattedMessage } from '@kbn/i18n-react'; import { DataView } from '@kbn/data-views-plugin/common'; -import React, { useMemo } from 'react'; +import React, { useMemo, useState } from 'react'; import { i18n } from '@kbn/i18n'; import { LOCAL_STORAGE_PAGE_SIZE_FINDINGS_KEY } from '../../common/constants'; import { useCloudPostureTable } from '../../common/hooks/use_cloud_posture_table'; @@ -29,6 +29,7 @@ import { ErrorCallout } from '../configurations/layout/error_callout'; import { FindingsSearchBar } from '../configurations/layout/findings_search_bar'; import { useFilteredDataView } from '../../common/api/use_filtered_data_view'; import { CVSScoreBadge, SeverityStatusBadge } from '../../components/vulnerability_badges'; +import { VulnerabilityFindingFlyout } from './vulnerabilities_finding_flyout/vulnerability_finding_flyout'; import { NoVulnerabilitiesStates } from '../../components/no_vulnerabilities_states'; import { useCspSetupStatusApi } from '../../common/api/use_setup_status_api'; @@ -79,6 +80,21 @@ const VulnerabilitiesContent = ({ dataView }: { dataView: DataView }) => { enabled: !queryError, }); + const [isVulnerabilityDetailFlyoutVisible, setIsVulnerabilityDetailFlyoutVisible] = + useState(false); + + const [vulnerability, setVulnerability] = useState(); + + const showFlyout = (vulnerabilityRecord: VulnerabilityRecord) => { + setIsVulnerabilityDetailFlyoutVisible(true); + setVulnerability(vulnerabilityRecord); + }; + + const hideFlyout = () => { + setIsVulnerabilityDetailFlyoutVisible(false); + setVulnerability(undefined); + }; + const renderCellValue = useMemo(() => { return ({ rowIndex, columnId }: EuiDataGridCellValueElementProps) => { const vulnerabilityRow = data?.page[rowIndex] as VulnerabilityRecord; @@ -92,7 +108,7 @@ const VulnerabilitiesContent = ({ dataView }: { dataView: DataView }) => { iconType="expand" aria-label="View" onClick={() => { - alert(`Flyout id ${vulnerabilityRow.vulnerability.id}`); + showFlyout(vulnerabilityRow); }} /> ); @@ -181,64 +197,73 @@ const VulnerabilitiesContent = ({ dataView }: { dataView: DataView }) => { } /> ) : ( - id), - setVisibleColumns: () => {}, - }} - rowCount={data?.total} - toolbarVisibility={{ - showColumnSelector: false, - showDisplaySelector: false, - showKeyboardShortcuts: false, - additionalControls: { - left: { - prepend: ( - - {i18n.translate('xpack.csp.vulnerabilities.totalVulnerabilities', { - defaultMessage: - '{total, plural, one {# Vulnerability} other {# Vulnerabilities}}', - values: { total: data?.total }, - })} - - ), + <> + id), + setVisibleColumns: () => {}, + }} + rowCount={data?.total} + toolbarVisibility={{ + showColumnSelector: false, + showDisplaySelector: false, + showKeyboardShortcuts: false, + additionalControls: { + left: { + prepend: ( + + {i18n.translate('xpack.csp.vulnerabilities.totalVulnerabilities', { + defaultMessage: + '{total, plural, one {# Vulnerability} other {# Vulnerabilities}}', + values: { total: data?.total }, + })} + + ), + }, }, - }, - }} - gridStyle={{ - border: 'horizontal', - cellPadding: 'l', - stripes: false, - rowHover: 'none', - header: 'underline', - }} - renderCellValue={renderCellValue} - inMemory={{ level: 'sorting' }} - sorting={{ columns: sort, onSort }} - pagination={{ - pageIndex, - pageSize, - pageSizeOptions: [10, 25, 100], - onChangeItemsPerPage, - onChangePage, - }} - /> + }} + gridStyle={{ + border: 'horizontal', + cellPadding: 'l', + stripes: false, + rowHover: 'none', + header: 'underline', + }} + renderCellValue={renderCellValue} + inMemory={{ level: 'sorting' }} + sorting={{ columns: sort, onSort }} + pagination={{ + pageIndex, + pageSize, + pageSizeOptions: [10, 25, 100], + onChangeItemsPerPage, + onChangePage, + }} + /> + {/* Todo: Add Pagination */} + {isVulnerabilityDetailFlyoutVisible && !!vulnerability && ( + + )} + )} ); diff --git a/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/vulnerabilities_finding_flyout/vulnerability_finding_flyout.tsx b/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/vulnerabilities_finding_flyout/vulnerability_finding_flyout.tsx new file mode 100644 index 0000000000000..b29239f2dc275 --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/vulnerabilities_finding_flyout/vulnerability_finding_flyout.tsx @@ -0,0 +1,149 @@ +/* + * 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, { useMemo, useState } from 'react'; +import { + EuiFlexGroup, + EuiFlexItem, + EuiFlyout, + EuiFlyoutBody, + EuiFlyoutHeader, + EuiLink, + EuiTab, + EuiTabs, + EuiTitle, +} from '@elastic/eui'; + +import { FormattedMessage } from '@kbn/i18n-react'; +import { euiThemeVars } from '@kbn/ui-theme'; +import { css } from '@emotion/react'; +import { VulnerabilityOverviewTab } from './vulnerability_overview_tab'; +import { VulnerabilityJsonTab } from './vulnerability_json_tab'; +import { SeverityStatusBadge } from '../../../components/vulnerability_badges'; +import { VulnerabilityRecord } from '../types'; + +const overviewTabId = 'overview'; +const jsonTabId = 'json'; + +export const VulnerabilityFindingFlyout = ({ + closeFlyout, + vulnerabilityRecord, +}: { + closeFlyout: () => void; + vulnerabilityRecord: VulnerabilityRecord; +}) => { + const [selectedTabId, setSelectedTabId] = useState(overviewTabId); + const vulnerability = vulnerabilityRecord?.vulnerability; + const resourceName = vulnerabilityRecord?.resource?.name; + + const tabs = useMemo( + () => [ + { + id: overviewTabId, + name: ( + + ), + content: , + }, + { + id: jsonTabId, + name: ( + + ), + content: , + }, + ], + [vulnerability, vulnerabilityRecord] + ); + + const onSelectedTabChanged = (id: string) => setSelectedTabId(id); + + const renderTabs = () => + tabs.map((tab, index) => ( + onSelectedTabChanged(tab.id)} + isSelected={tab.id === selectedTabId} + key={index} + > + {tab.name} + + )); + + const selectedTabContent = useMemo( + () => tabs.find((obj) => obj.id === selectedTabId)?.content, + [selectedTabId, tabs] + ); + const nvdDomain = 'https://nvd'; + const nvdWebsite = `${nvdDomain}.nist.gov/vuln/detail/${vulnerabilityRecord?.vulnerability?.id}`; + + const vulnerabilityReference = vulnerability?.reference.startsWith(nvdDomain) + ? vulnerability?.reference + : nvdWebsite; + + return ( + + + + + + + + + + + + {vulnerability?.id} + + + + +

+ {`${resourceName} | ${vulnerability?.package?.name} ${vulnerability?.package?.version}`} +

+
+
+
+ + {renderTabs()} + +
+
+ {selectedTabContent} + {/* Todo: Add Pagination */} +
+ ); +}; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/vulnerabilities_finding_flyout/vulnerability_json_tab.tsx b/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/vulnerabilities_finding_flyout/vulnerability_json_tab.tsx new file mode 100644 index 0000000000000..99f0da1eb4454 --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/vulnerabilities_finding_flyout/vulnerability_json_tab.tsx @@ -0,0 +1,32 @@ +/* + * 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 { CodeEditor } from '@kbn/kibana-react-plugin/public'; +import React from 'react'; +import { XJsonLang } from '@kbn/monaco'; +import { VulnerabilityRecord } from '../types'; +interface VulnerabilityJsonTabProps { + vulnerabilityRecord: VulnerabilityRecord; +} +export const VulnerabilityJsonTab = ({ vulnerabilityRecord }: VulnerabilityJsonTabProps) => { + const offsetHeight = 188; + return ( +
+ +
+ ); +}; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/vulnerabilities_finding_flyout/vulnerability_overview_tab.tsx b/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/vulnerabilities_finding_flyout/vulnerability_overview_tab.tsx new file mode 100644 index 0000000000000..9ecfbdd5eb917 --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/vulnerabilities_finding_flyout/vulnerability_overview_tab.tsx @@ -0,0 +1,260 @@ +/* + * 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 { EuiFlexGroup, EuiFlexItem, EuiHorizontalRule, EuiLink, EuiText } from '@elastic/eui'; +import { css } from '@emotion/react'; +import { FormattedMessage } from '@kbn/i18n-react'; +import moment from 'moment'; +import React from 'react'; +import { euiThemeVars } from '@kbn/ui-theme'; +import { i18n } from '@kbn/i18n'; +import { CVSScoreBadge } from '../../../components/vulnerability_badges'; +import { CVSScoreProps, VectorScoreBase, Vendor, Vulnerability } from '../types'; +import { getVectorScoreList } from '../utils'; + +const cvssVendors: Record = { + nvd: 'NVD', + redhat: 'Red Hat', + ghsa: 'GHSA', +}; + +interface VulnerabilityTabProps { + vulnerability: Vulnerability; +} + +const CVSScore = ({ vectorBaseScore, vendor }: CVSScoreProps) => { + const vendorName = + cvssVendors[vendor] ?? + i18n.translate( + 'xpack.csp.vulnerabilities.vulnerabilityOverviewTab.cvsScore.unknownVendorName', + { + defaultMessage: 'Unknown vendor', + } + ); + + const vectorScores = getVectorScoreList(vectorBaseScore); + + return ( + + + {vendorName} + + + {vectorScores.length > 0 && + vectorScores.map((vectorScore) => )} + + + ); +}; + +const VectorScore = ({ + vectorScore, +}: { + vectorScore: { + vector: string; + score: number | undefined; + version: string; + }; +}) => { + const { score, vector, version } = vectorScore; + return ( + <> + + + + {vector}{' '} + + + + + {score && } + + + + ); +}; + +const VulnerabilityOverviewTiles = ({ vulnerability }: VulnerabilityTabProps) => { + const tileStyle = css` + padding: ${euiThemeVars.euiFontSizeM}; + background: ${euiThemeVars.euiColorLightestShade}; + border-radius: 6px; + height: 74px; + `; + const tileTitleTextStyle = css` + line-height: 20px; + margin-bottom: 6px; + `; + + const date = moment(vulnerability?.published_at).format('LL').toString(); + + return ( + + + + + +
+ +
+
+ + + + + + {vulnerability?.data_source?.ID} + + + + + + + + + + + +
+ ); +}; + +export const VulnerabilityOverviewTab = ({ vulnerability }: VulnerabilityTabProps) => { + const emptyFixesMessageState = i18n.translate( + 'xpack.csp.vulnerabilities.vulnerabilityOverviewTab.emptyFixesMessage', + { + defaultMessage: 'No available fixes yet.', + } + ); + + const fixesDisplayText = vulnerability?.package?.fixed_version + ? `${vulnerability?.package?.name} ${vulnerability?.package?.fixed_version}` + : emptyFixesMessageState; + + const cvssScores: JSX.Element[] = Object.entries(vulnerability?.cvss).map( + ([vendor, vectorScoreBase]: [string, VectorScoreBase]) => { + return ( + + + + ); + } + ); + + const horizontalStyle = css` + margin-block: 12px; + `; + + const flyoutSubheadingStyle = css` + font-size: ${euiThemeVars.euiFontSizeM}; + line-height: 24px; + margin-bottom: ${euiThemeVars.euiSizeS}; + font-weight: 600; + `; + + return ( + + + + + + + + +

+ +

+ + + +
+ + + + +

+ +

+ {fixesDisplayText} +
+ + + + {cvssScores?.length > 0 && ( + +

+ +

+ + {cvssScores} + +
+ )} +
+ ); +}; From 4edb583c189b705e00dc388428fc1669ae0882df Mon Sep 17 00:00:00 2001 From: Anton Dosov Date: Mon, 17 Apr 2023 16:25:58 +0200 Subject: [PATCH 03/17] [Content Management] Remove dep from content_management -> saved_object_finder (#155013) ## Summary Follow up https://github.com/elastic/kibana/pull/154819, @mattkime pointed out a problem that cm can't depend on saved_object_finder https://github.com/elastic/kibana/pull/154819/files#diff-635bc20df585b656afebba3ebf338ff997e735df933f704cc5f253a74b3503ddR17 --- .github/CODEOWNERS | 1 + package.json | 1 + packages/kbn-saved-objects-settings/README.md | 3 +++ packages/kbn-saved-objects-settings/index.ts | 10 ++++++++++ .../kbn-saved-objects-settings/jest.config.js | 13 +++++++++++++ .../kbn-saved-objects-settings/kibana.jsonc | 5 +++++ .../kbn-saved-objects-settings/package.json | 6 ++++++ .../kbn-saved-objects-settings/tsconfig.json | 17 +++++++++++++++++ .../server/rpc/routes/routes.ts | 2 +- src/plugins/content_management/tsconfig.json | 2 +- .../saved_objects_finder/common/index.ts | 3 +-- src/plugins/saved_objects_finder/tsconfig.json | 1 + tsconfig.base.json | 2 ++ yarn.lock | 4 ++++ 14 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 packages/kbn-saved-objects-settings/README.md create mode 100644 packages/kbn-saved-objects-settings/index.ts create mode 100644 packages/kbn-saved-objects-settings/jest.config.js create mode 100644 packages/kbn-saved-objects-settings/kibana.jsonc create mode 100644 packages/kbn-saved-objects-settings/package.json create mode 100644 packages/kbn-saved-objects-settings/tsconfig.json diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 26be09f9bb2f0..a6a4ed6d9b210 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -529,6 +529,7 @@ test/plugin_functional/plugins/saved_objects_hidden_from_http_apis_type @elastic test/plugin_functional/plugins/saved_objects_hidden_type @elastic/kibana-core src/plugins/saved_objects_management @elastic/kibana-core src/plugins/saved_objects @elastic/kibana-core +packages/kbn-saved-objects-settings @elastic/appex-sharedux src/plugins/saved_objects_tagging_oss @elastic/appex-sharedux x-pack/plugins/saved_objects_tagging @elastic/appex-sharedux src/plugins/saved_search @elastic/kibana-data-discovery diff --git a/package.json b/package.json index 2b2f4ff6326f1..83660bd976f88 100644 --- a/package.json +++ b/package.json @@ -531,6 +531,7 @@ "@kbn/saved-objects-hidden-type-plugin": "link:test/plugin_functional/plugins/saved_objects_hidden_type", "@kbn/saved-objects-management-plugin": "link:src/plugins/saved_objects_management", "@kbn/saved-objects-plugin": "link:src/plugins/saved_objects", + "@kbn/saved-objects-settings": "link:packages/kbn-saved-objects-settings", "@kbn/saved-objects-tagging-oss-plugin": "link:src/plugins/saved_objects_tagging_oss", "@kbn/saved-objects-tagging-plugin": "link:x-pack/plugins/saved_objects_tagging", "@kbn/saved-search-plugin": "link:src/plugins/saved_search", diff --git a/packages/kbn-saved-objects-settings/README.md b/packages/kbn-saved-objects-settings/README.md new file mode 100644 index 0000000000000..48e2630354b02 --- /dev/null +++ b/packages/kbn-saved-objects-settings/README.md @@ -0,0 +1,3 @@ +# @kbn/saved-objects-settings + +Contains constants for some of saved objects related ui settings that had to be re-used between plugins without causing circular dependencies. diff --git a/packages/kbn-saved-objects-settings/index.ts b/packages/kbn-saved-objects-settings/index.ts new file mode 100644 index 0000000000000..f2a1aa7c06e54 --- /dev/null +++ b/packages/kbn-saved-objects-settings/index.ts @@ -0,0 +1,10 @@ +/* + * 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 const PER_PAGE_SETTING = 'savedObjects:perPage'; +export const LISTING_LIMIT_SETTING = 'savedObjects:listingLimit'; diff --git a/packages/kbn-saved-objects-settings/jest.config.js b/packages/kbn-saved-objects-settings/jest.config.js new file mode 100644 index 0000000000000..562e1f12ecceb --- /dev/null +++ b/packages/kbn-saved-objects-settings/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/jest_node', + rootDir: '../..', + roots: ['/packages/kbn-saved-objects-settings'], +}; diff --git a/packages/kbn-saved-objects-settings/kibana.jsonc b/packages/kbn-saved-objects-settings/kibana.jsonc new file mode 100644 index 0000000000000..40486e1ef0cf1 --- /dev/null +++ b/packages/kbn-saved-objects-settings/kibana.jsonc @@ -0,0 +1,5 @@ +{ + "type": "shared-common", + "id": "@kbn/saved-objects-settings", + "owner": "@elastic/appex-sharedux" +} diff --git a/packages/kbn-saved-objects-settings/package.json b/packages/kbn-saved-objects-settings/package.json new file mode 100644 index 0000000000000..38ef61439d47d --- /dev/null +++ b/packages/kbn-saved-objects-settings/package.json @@ -0,0 +1,6 @@ +{ + "name": "@kbn/saved-objects-settings", + "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/kbn-saved-objects-settings/tsconfig.json b/packages/kbn-saved-objects-settings/tsconfig.json new file mode 100644 index 0000000000000..2f9ddddbeea23 --- /dev/null +++ b/packages/kbn-saved-objects-settings/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "outDir": "target/types", + "types": [ + "jest", + "node" + ] + }, + "include": [ + "**/*.ts", + ], + "exclude": [ + "target/**/*" + ], + "kbn_references": [] +} diff --git a/src/plugins/content_management/server/rpc/routes/routes.ts b/src/plugins/content_management/server/rpc/routes/routes.ts index 6d40e37d533c8..ea529aae11188 100644 --- a/src/plugins/content_management/server/rpc/routes/routes.ts +++ b/src/plugins/content_management/server/rpc/routes/routes.ts @@ -8,7 +8,7 @@ import { schema } from '@kbn/config-schema'; import type { IRouter } from '@kbn/core/server'; -import { LISTING_LIMIT_SETTING, PER_PAGE_SETTING } from '@kbn/saved-objects-finder-plugin/common'; +import { LISTING_LIMIT_SETTING, PER_PAGE_SETTING } from '@kbn/saved-objects-settings'; import { ProcedureName } from '../../../common'; import type { ContentRegistry } from '../../core'; import { MSearchService } from '../../core/msearch'; diff --git a/src/plugins/content_management/tsconfig.json b/src/plugins/content_management/tsconfig.json index 93aacaecff0c9..dd87f182de476 100644 --- a/src/plugins/content_management/tsconfig.json +++ b/src/plugins/content_management/tsconfig.json @@ -14,7 +14,7 @@ "@kbn/object-versioning", "@kbn/core-saved-objects-api-server-mocks", "@kbn/core-saved-objects-api-server", - "@kbn/saved-objects-finder-plugin", + "@kbn/saved-objects-settings", ], "exclude": [ "target/**/*", diff --git a/src/plugins/saved_objects_finder/common/index.ts b/src/plugins/saved_objects_finder/common/index.ts index 056d0b4638efc..8a0964edc100b 100644 --- a/src/plugins/saved_objects_finder/common/index.ts +++ b/src/plugins/saved_objects_finder/common/index.ts @@ -6,6 +6,5 @@ * Side Public License, v 1. */ -export const PER_PAGE_SETTING = 'savedObjects:perPage'; -export const LISTING_LIMIT_SETTING = 'savedObjects:listingLimit'; +export { PER_PAGE_SETTING, LISTING_LIMIT_SETTING } from '@kbn/saved-objects-settings'; export type { SavedObjectCommon, FindQueryHTTP, FindResponseHTTP, FinderAttributes } from './types'; diff --git a/src/plugins/saved_objects_finder/tsconfig.json b/src/plugins/saved_objects_finder/tsconfig.json index 813379f02a313..217f4f7f0dbe3 100644 --- a/src/plugins/saved_objects_finder/tsconfig.json +++ b/src/plugins/saved_objects_finder/tsconfig.json @@ -14,6 +14,7 @@ "@kbn/config-schema", "@kbn/core-ui-settings-browser", "@kbn/core-http-browser", + "@kbn/saved-objects-settings", ], "exclude": [ "target/**/*", diff --git a/tsconfig.base.json b/tsconfig.base.json index 85fa70f831719..71c2a3d250a51 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -1052,6 +1052,8 @@ "@kbn/saved-objects-management-plugin/*": ["src/plugins/saved_objects_management/*"], "@kbn/saved-objects-plugin": ["src/plugins/saved_objects"], "@kbn/saved-objects-plugin/*": ["src/plugins/saved_objects/*"], + "@kbn/saved-objects-settings": ["packages/kbn-saved-objects-settings"], + "@kbn/saved-objects-settings/*": ["packages/kbn-saved-objects-settings/*"], "@kbn/saved-objects-tagging-oss-plugin": ["src/plugins/saved_objects_tagging_oss"], "@kbn/saved-objects-tagging-oss-plugin/*": ["src/plugins/saved_objects_tagging_oss/*"], "@kbn/saved-objects-tagging-plugin": ["x-pack/plugins/saved_objects_tagging"], diff --git a/yarn.lock b/yarn.lock index c480dd98324b0..365c976479508 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4841,6 +4841,10 @@ version "0.0.0" uid "" +"@kbn/saved-objects-settings@link:packages/kbn-saved-objects-settings": + version "0.0.0" + uid "" + "@kbn/saved-objects-tagging-oss-plugin@link:src/plugins/saved_objects_tagging_oss": version "0.0.0" uid "" From d60107467d748cb36b7b67296da6dfc2bf6a20a4 Mon Sep 17 00:00:00 2001 From: Rodney Norris Date: Mon, 17 Apr 2023 09:48:22 -0500 Subject: [PATCH 04/17] Enterprise Search(nav): refactor nav with applications (#154783) ## Summary ### Screenshots ![image](https://user-images.githubusercontent.com/1972968/231289135-39950694-9877-4a37-8a7e-988c40905ec2.png) Selected Search App ![image](https://user-images.githubusercontent.com/1972968/231289205-a117e26a-2148-450e-bc1d-823169cb9d0b.png) Selected Analytics Collection ![image](https://user-images.githubusercontent.com/1972968/231289259-569c24fb-dced-4e34-a69c-359fa2688836.png) --- .../applications/shared/layout/nav.test.tsx | 179 ++++++++---------- .../public/applications/shared/layout/nav.tsx | 94 +++++---- .../translations/translations/fr-FR.json | 3 - .../translations/translations/ja-JP.json | 3 - .../translations/translations/zh-CN.json | 3 - 5 files changed, 123 insertions(+), 159 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/layout/nav.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/layout/nav.test.tsx index 79588ba3361ea..ffcb70dcb770b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/layout/nav.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/layout/nav.test.tsx @@ -41,6 +41,18 @@ describe('useEnterpriseSearchContentNav', () => { { href: '/app/enterprise_search/overview', id: 'es_overview', + items: [ + { + href: '/app/enterprise_search/elasticsearch', + id: 'elasticsearch', + name: 'Elasticsearch', + }, + { + id: 'searchExperiences', + name: 'Search Experiences', + href: '/app/enterprise_search/search_experiences', + }, + ], name: 'Overview', }, { @@ -61,36 +73,20 @@ describe('useEnterpriseSearchContentNav', () => { name: 'Content', }, { - id: 'enginesSearch', - name: 'Search', + id: 'applications', + name: 'Applications', items: [ { - href: '/app/enterprise_search/elasticsearch', - id: 'elasticsearch', - name: 'Elasticsearch', - }, - { - id: 'enterpriseSearchEngines', - name: 'Engines', + id: 'searchApplications', + name: 'Search Applications', href: '/app/enterprise_search/content/engines', }, - { - id: 'searchExperiences', - name: 'Search Experiences', - href: '/app/enterprise_search/search_experiences', - }, - ], - }, - { - id: 'enterpriseSearchAnalytics', - items: [ { href: '/app/enterprise_search/analytics', - id: 'analytics_collections', - name: 'Collections', + id: 'analyticsCollections', + name: 'Behavioral Analytics', }, ], - name: 'Behavioral Analytics', }, { id: 'standaloneExperiences', @@ -197,6 +193,18 @@ describe('useEnterpriseSearchEngineNav', () => { { href: '/app/enterprise_search/overview', id: 'es_overview', + items: [ + { + href: '/app/enterprise_search/elasticsearch', + id: 'elasticsearch', + name: 'Elasticsearch', + }, + { + id: 'searchExperiences', + name: 'Search Experiences', + href: '/app/enterprise_search/search_experiences', + }, + ], name: 'Overview', }, { @@ -210,43 +218,26 @@ describe('useEnterpriseSearchEngineNav', () => { { href: '/app/enterprise_search/content/settings', id: 'settings', - items: undefined, name: 'Settings', }, ], name: 'Content', }, { - id: 'enginesSearch', - name: 'Search', + id: 'applications', + name: 'Applications', items: [ { - href: '/app/enterprise_search/elasticsearch', - id: 'elasticsearch', - name: 'Elasticsearch', - }, - { - id: 'enterpriseSearchEngines', - name: 'Engines', + id: 'searchApplications', + name: 'Search Applications', href: '/app/enterprise_search/content/engines', }, - { - id: 'searchExperiences', - name: 'Search Experiences', - href: '/app/enterprise_search/search_experiences', - }, - ], - }, - { - id: 'enterpriseSearchAnalytics', - items: [ { href: '/app/enterprise_search/analytics', - id: 'analytics_collections', - name: 'Collections', + id: 'analyticsCollections', + name: 'Behavioral Analytics', }, ], - name: 'Behavioral Analytics', }, { id: 'standaloneExperiences', @@ -273,16 +264,15 @@ describe('useEnterpriseSearchEngineNav', () => { expect(navItems?.map((ni) => ni.name)).toEqual([ 'Overview', 'Content', - 'Search', - 'Behavioral Analytics', + 'Applications', 'Standalone Experiences', ]); - const searchItem = navItems?.find((ni) => ni.id === 'enginesSearch'); + const searchItem = navItems?.find((ni) => ni.id === 'applications'); expect(searchItem).not.toBeUndefined(); expect(searchItem!.items).not.toBeUndefined(); // @ts-ignore const enginesItem: EuiSideNavItemType = searchItem?.items?.find( - (si: EuiSideNavItemType) => si.id === 'enterpriseSearchEngines' + (si: EuiSideNavItemType) => si.id === 'searchApplications' ); expect(enginesItem).not.toBeUndefined(); expect(enginesItem!.items).not.toBeUndefined(); @@ -330,16 +320,15 @@ describe('useEnterpriseSearchEngineNav', () => { expect(navItems?.map((ni) => ni.name)).toEqual([ 'Overview', 'Content', - 'Search', - 'Behavioral Analytics', + 'Applications', 'Standalone Experiences', ]); - const searchItem = navItems?.find((ni) => ni.id === 'enginesSearch'); + const searchItem = navItems?.find((ni) => ni.id === 'applications'); expect(searchItem).not.toBeUndefined(); expect(searchItem!.items).not.toBeUndefined(); // @ts-ignore const enginesItem: EuiSideNavItemType = searchItem?.items?.find( - (si: EuiSideNavItemType) => si.id === 'enterpriseSearchEngines' + (si: EuiSideNavItemType) => si.id === 'searchApplications' ); expect(enginesItem).not.toBeUndefined(); expect(enginesItem!.items).not.toBeUndefined(); @@ -360,6 +349,18 @@ describe('useEnterpriseSearchAnalyticsNav', () => { { href: '/app/enterprise_search/overview', id: 'es_overview', + items: [ + { + href: '/app/enterprise_search/elasticsearch', + id: 'elasticsearch', + name: 'Elasticsearch', + }, + { + id: 'searchExperiences', + name: 'Search Experiences', + href: '/app/enterprise_search/search_experiences', + }, + ], name: 'Overview', }, { @@ -374,36 +375,20 @@ describe('useEnterpriseSearchAnalyticsNav', () => { name: 'Content', }, { - id: 'enginesSearch', - name: 'Search', + id: 'applications', + name: 'Applications', items: [ { - href: '/app/enterprise_search/elasticsearch', - id: 'elasticsearch', - name: 'Elasticsearch', - }, - { - id: 'enterpriseSearchEngines', - name: 'Engines', href: '/app/enterprise_search/content/engines', + id: 'searchApplications', + name: 'Search Applications', }, - { - id: 'searchExperiences', - name: 'Search Experiences', - href: '/app/enterprise_search/search_experiences', - }, - ], - }, - { - id: 'enterpriseSearchAnalytics', - items: [ { href: '/app/enterprise_search/analytics', - id: 'analytics_collections', - name: 'Collections', + id: 'analyticsCollections', + name: 'Behavioral Analytics', }, ], - name: 'Behavioral Analytics', }, { id: 'standaloneExperiences', @@ -444,38 +429,34 @@ describe('useEnterpriseSearchAnalyticsNav', () => { integration: '/integration-path', overview: '/overview-path', }); - const analyticsNav = navItems?.find((item) => item.id === 'enterpriseSearchAnalytics'); + const applicationsNav = navItems?.find((item) => item.id === 'applications'); + expect(applicationsNav).not.toBeUndefined(); + const analyticsNav = applicationsNav?.items?.[1]; expect(analyticsNav).not.toBeUndefined(); expect(analyticsNav).toEqual({ - id: 'enterpriseSearchAnalytics', + href: '/app/enterprise_search/analytics', + id: 'analyticsCollections', items: [ { - href: '/app/enterprise_search/analytics', - id: 'analytics_collections', + id: 'analyticsCollection', items: [ { - id: 'analytics_collections', - items: [ - { - href: '/app/enterprise_search/analytics/overview-path', - id: 'enterpriseSearchEngineOverview', - name: 'Overview', - }, - { - href: '/app/enterprise_search/analytics/explorer-path', - id: 'enterpriseSearchEngineIndices', - name: 'Explorer', - }, - { - href: '/app/enterprise_search/analytics/integration-path', - id: 'enterpriseSearchEngineSchema', - name: 'Integration', - }, - ], - name: 'my-test-collection', + href: '/app/enterprise_search/analytics/overview-path', + id: 'analyticsCollectionOverview', + name: 'Overview', + }, + { + href: '/app/enterprise_search/analytics/explorer-path', + id: 'analyticsCollectionExplorer', + name: 'Explorer', + }, + { + href: '/app/enterprise_search/analytics/integration-path', + id: 'analyticsCollectionIntegration', + name: 'Integration', }, ], - name: 'Collections', + name: 'my-test-collection', }, ], name: 'Behavioral Analytics', diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/layout/nav.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/layout/nav.tsx index 51b22389b87f8..a6861b6d29e36 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/layout/nav.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/layout/nav.tsx @@ -42,6 +42,28 @@ export const useEnterpriseSearchNav = () => { shouldNotCreateHref: true, to: ENTERPRISE_SEARCH_OVERVIEW_PLUGIN.URL, }), + items: [ + { + id: 'elasticsearch', + name: i18n.translate('xpack.enterpriseSearch.nav.elasticsearchTitle', { + defaultMessage: 'Elasticsearch', + }), + ...generateNavLink({ + shouldNotCreateHref: true, + to: ELASTICSEARCH_PLUGIN.URL, + }), + }, + { + id: 'searchExperiences', + name: i18n.translate('xpack.enterpriseSearch.nav.searchExperiencesTitle', { + defaultMessage: 'Search Experiences', + }), + ...generateNavLink({ + shouldNotCreateHref: true, + to: SEARCH_EXPERIENCES_PLUGIN.URL, + }), + }, + ], }, { id: 'content', @@ -78,22 +100,12 @@ export const useEnterpriseSearchNav = () => { }), }, { - id: 'enginesSearch', + id: 'applications', items: [ { - id: 'elasticsearch', - name: i18n.translate('xpack.enterpriseSearch.nav.elasticsearchTitle', { - defaultMessage: 'Elasticsearch', - }), - ...generateNavLink({ - shouldNotCreateHref: true, - to: ELASTICSEARCH_PLUGIN.URL, - }), - }, - { - id: 'enterpriseSearchEngines', - name: i18n.translate('xpack.enterpriseSearch.nav.enginesTitle', { - defaultMessage: 'Engines', + id: 'searchApplications', + name: i18n.translate('xpack.enterpriseSearch.nav.searchApplicationsTitle', { + defaultMessage: 'Search Applications', }), ...generateNavLink({ shouldNotCreateHref: true, @@ -101,27 +113,9 @@ export const useEnterpriseSearchNav = () => { }), }, { - id: 'searchExperiences', - name: i18n.translate('xpack.enterpriseSearch.nav.searchExperiencesTitle', { - defaultMessage: 'Search Experiences', - }), - ...generateNavLink({ - shouldNotCreateHref: true, - to: SEARCH_EXPERIENCES_PLUGIN.URL, - }), - }, - ], - name: i18n.translate('xpack.enterpriseSearch.nav.searchTitle', { - defaultMessage: 'Search', - }), - }, - { - id: 'enterpriseSearchAnalytics', - items: [ - { - id: 'analytics_collections', - name: i18n.translate('xpack.enterpriseSearch.nav.analyticsCollectionsTitle', { - defaultMessage: 'Collections', + id: 'analyticsCollections', + name: i18n.translate('xpack.enterpriseSearch.nav.analyticsTitle', { + defaultMessage: 'Behavioral Analytics', }), ...generateNavLink({ shouldNotCreateHref: true, @@ -129,8 +123,8 @@ export const useEnterpriseSearchNav = () => { }), }, ], - name: i18n.translate('xpack.enterpriseSearch.nav.analyticsTitle', { - defaultMessage: 'Behavioral Analytics', + name: i18n.translate('xpack.enterpriseSearch.nav.applicationsTitle', { + defaultMessage: 'Applications', }), }, ...(productAccess.hasAppSearchAccess || productAccess.hasWorkplaceSearchAccess @@ -181,10 +175,10 @@ export const useEnterpriseSearchNav = () => { export const useEnterpriseSearchEngineNav = (engineName?: string, isEmptyState?: boolean) => { const navItems = useEnterpriseSearchNav(); if (!engineName) return navItems; - const searchItem = navItems.find((item) => item.id === 'enginesSearch'); - if (!searchItem || !searchItem.items) return navItems; - const enginesItem = searchItem.items[1]; - if (!enginesItem || enginesItem.id !== 'enterpriseSearchEngines') return navItems; + const applicationsItem = navItems.find((item) => item.id === 'applications'); + if (!applicationsItem || !applicationsItem.items) return navItems; + const enginesItem = applicationsItem.items?.find((item) => item.id === 'searchApplications'); + if (!enginesItem || enginesItem.id !== 'searchApplications') return navItems; const enginePath = `${ENTERPRISE_SEARCH_CONTENT_PLUGIN.URL}${ENGINES_PATH}/${engineName}`; @@ -275,19 +269,17 @@ export const useEnterpriseSearchAnalyticsNav = ( } ) => { const navItems = useEnterpriseSearchNav(); - const collectionNav = navItems.find( - (item) => - item.id === 'enterpriseSearchAnalytics' && item.items?.[0]?.id === 'analytics_collections' - )?.items?.[0]; + const applicationsNav = navItems.find((item) => item.id === 'applications'); + const analyticsNav = applicationsNav?.items?.find((item) => item.id === 'analyticsCollections'); - if (!name || !paths || !collectionNav) return navItems; + if (!name || !paths || !analyticsNav) return navItems; - collectionNav.items = [ + analyticsNav.items = [ { - id: 'analytics_collections', + id: 'analyticsCollection', items: [ { - id: 'enterpriseSearchEngineOverview', + id: 'analyticsCollectionOverview', name: i18n.translate('xpack.enterpriseSearch.nav.analyticsCollections.overviewTitle', { defaultMessage: 'Overview', }), @@ -297,7 +289,7 @@ export const useEnterpriseSearchAnalyticsNav = ( }), }, { - id: 'enterpriseSearchEngineIndices', + id: 'analyticsCollectionExplorer', name: i18n.translate('xpack.enterpriseSearch.nav.analyticsCollections.explorerTitle', { defaultMessage: 'Explorer', }), @@ -307,7 +299,7 @@ export const useEnterpriseSearchAnalyticsNav = ( }), }, { - id: 'enterpriseSearchEngineSchema', + id: 'analyticsCollectionIntegration', name: i18n.translate('xpack.enterpriseSearch.nav.analyticsCollections.integrationTitle', { defaultMessage: 'Integration', }), diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index e71e35dc488b8..ca87bd58cff99 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -13186,7 +13186,6 @@ "xpack.enterpriseSearch.nativeConnectors.mysql.configuration.sslCertificateLabel": "Certificat SSL", "xpack.enterpriseSearch.nativeConnectors.mysql.configuration.usernameLabel": "Nom d'utilisateur", "xpack.enterpriseSearch.nativeConnectors.mysql.name": "MySQL", - "xpack.enterpriseSearch.nav.analyticsCollectionsTitle": "Collections", "xpack.enterpriseSearch.nav.analyticsTitle": "Behavioral Analytics", "xpack.enterpriseSearch.nav.appSearchTitle": "App Search", "xpack.enterpriseSearch.nav.contentSettingsTitle": "Paramètres", @@ -13196,11 +13195,9 @@ "xpack.enterpriseSearch.nav.engine.indicesTitle": "Index", "xpack.enterpriseSearch.nav.engine.overviewTitle": "Aperçu", "xpack.enterpriseSearch.nav.engine.schemaTitle": "Schéma", - "xpack.enterpriseSearch.nav.enginesTitle": "Moteurs", "xpack.enterpriseSearch.nav.enterpriseSearchOverviewTitle": "Aperçu", "xpack.enterpriseSearch.nav.searchExperiencesTitle": "Expériences de recherche", "xpack.enterpriseSearch.nav.searchIndicesTitle": "Index", - "xpack.enterpriseSearch.nav.searchTitle": "Recherche", "xpack.enterpriseSearch.nav.standaloneExperiencesTitle": "Expériences autonomes", "xpack.enterpriseSearch.nav.workplaceSearchTitle": "Workplace Search", "xpack.enterpriseSearch.notFound.action1": "Retour à votre tableau de bord", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index f8e1f66528696..2363c92879f22 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -13185,7 +13185,6 @@ "xpack.enterpriseSearch.nativeConnectors.mysql.configuration.sslCertificateLabel": "SSL証明書", "xpack.enterpriseSearch.nativeConnectors.mysql.configuration.usernameLabel": "ユーザー名", "xpack.enterpriseSearch.nativeConnectors.mysql.name": "MySQL", - "xpack.enterpriseSearch.nav.analyticsCollectionsTitle": "コレクション", "xpack.enterpriseSearch.nav.analyticsTitle": "Behavioral Analytics", "xpack.enterpriseSearch.nav.appSearchTitle": "App Search", "xpack.enterpriseSearch.nav.contentSettingsTitle": "設定", @@ -13195,11 +13194,9 @@ "xpack.enterpriseSearch.nav.engine.indicesTitle": "インデックス", "xpack.enterpriseSearch.nav.engine.overviewTitle": "概要", "xpack.enterpriseSearch.nav.engine.schemaTitle": "スキーマ", - "xpack.enterpriseSearch.nav.enginesTitle": "エンジン", "xpack.enterpriseSearch.nav.enterpriseSearchOverviewTitle": "概要", "xpack.enterpriseSearch.nav.searchExperiencesTitle": "検索エクスペリエンス", "xpack.enterpriseSearch.nav.searchIndicesTitle": "インデックス", - "xpack.enterpriseSearch.nav.searchTitle": "検索", "xpack.enterpriseSearch.nav.standaloneExperiencesTitle": "スタンドアロン経験", "xpack.enterpriseSearch.nav.workplaceSearchTitle": "Workplace Search", "xpack.enterpriseSearch.notFound.action1": "ダッシュボードに戻す", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 536018bf4b341..2ffdd43bb24ca 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -13186,7 +13186,6 @@ "xpack.enterpriseSearch.nativeConnectors.mysql.configuration.sslCertificateLabel": "SSL 证书", "xpack.enterpriseSearch.nativeConnectors.mysql.configuration.usernameLabel": "用户名", "xpack.enterpriseSearch.nativeConnectors.mysql.name": "MySQL", - "xpack.enterpriseSearch.nav.analyticsCollectionsTitle": "集合", "xpack.enterpriseSearch.nav.analyticsTitle": "行为分析", "xpack.enterpriseSearch.nav.appSearchTitle": "App Search", "xpack.enterpriseSearch.nav.contentSettingsTitle": "设置", @@ -13196,11 +13195,9 @@ "xpack.enterpriseSearch.nav.engine.indicesTitle": "索引", "xpack.enterpriseSearch.nav.engine.overviewTitle": "概览", "xpack.enterpriseSearch.nav.engine.schemaTitle": "架构", - "xpack.enterpriseSearch.nav.enginesTitle": "引擎", "xpack.enterpriseSearch.nav.enterpriseSearchOverviewTitle": "概览", "xpack.enterpriseSearch.nav.searchExperiencesTitle": "搜索体验", "xpack.enterpriseSearch.nav.searchIndicesTitle": "索引", - "xpack.enterpriseSearch.nav.searchTitle": "搜索", "xpack.enterpriseSearch.nav.standaloneExperiencesTitle": "独立体验", "xpack.enterpriseSearch.nav.workplaceSearchTitle": "Workplace Search", "xpack.enterpriseSearch.notFound.action1": "返回到您的仪表板", From 07a341277e52b002ac430a51918e41ccbe9afc3c Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Mon, 17 Apr 2023 10:55:17 -0400 Subject: [PATCH 05/17] skip failing test suite (#151636) --- .../api_integration/apis/lists/create_exception_list_item.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/api_integration/apis/lists/create_exception_list_item.ts b/x-pack/test/api_integration/apis/lists/create_exception_list_item.ts index b24cc7d14fef7..037d2750e84f6 100644 --- a/x-pack/test/api_integration/apis/lists/create_exception_list_item.ts +++ b/x-pack/test/api_integration/apis/lists/create_exception_list_item.ts @@ -12,7 +12,8 @@ import { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const supertest = getService('supertest'); - describe('Lists API', () => { + // Failing: See https://github.com/elastic/kibana/issues/151636 + describe.skip('Lists API', () => { before(async () => await esArchiver.load('x-pack/test/functional/es_archives/lists')); after(async () => await esArchiver.unload('x-pack/test/functional/es_archives/lists')); From 049b7c8866d6a2eba08ba323b27bcbf1f3fe0b35 Mon Sep 17 00:00:00 2001 From: gchaps <33642766+gchaps@users.noreply.github.com> Date: Mon, 17 Apr 2023 07:59:31 -0700 Subject: [PATCH 06/17] Updates docs landing page (#154400) ## Summary This PR updates the Kibana docs landing page to move the most visited docs higher on the page. [Preview](https://kibana_154400.docs-preview.app.elstc.co/guide/en/kibana/master/index.html) --------- Co-authored-by: lcawl --- docs/index-custom-title-page.html | 150 ++++++++++++++++-------------- 1 file changed, 81 insertions(+), 69 deletions(-) diff --git a/docs/index-custom-title-page.html b/docs/index-custom-title-page.html index 87405c783a0a7..5d768eab3484e 100644 --- a/docs/index-custom-title-page.html +++ b/docs/index-custom-title-page.html @@ -45,6 +45,13 @@ -moz-columns: 2; } } + #guide h3.gtk { + margin-top: 0; +} + +.mb-4, .my-4 { + margin-bottom: 0!important; +}
@@ -63,53 +70,17 @@

Bring your data to life

- How-to videos -

+ What's new + Release notes + Install +

-

Explore by Elastic solution

- - - -

Get to know Kibana

+

Get to know Kibana

@@ -134,6 +105,28 @@

+
+
+

+ + Install and upgrade +

+
+ +
+
-
+

Explore by Elastic solution

+ +

View all Elastic docs

From 47c71b30253cf1bdd1339af5f471a6d747871c64 Mon Sep 17 00:00:00 2001 From: Chenhui Wang <54903978+wangch079@users.noreply.github.com> Date: Mon, 17 Apr 2023 22:59:48 +0800 Subject: [PATCH 07/17] Use unsigned_long for field indexed_document_volume (#155014) ## Summary ### Part of https://github.com/elastic/connectors-python/issues/735 The field `indexed_document_volume` (in bytes) in `.elastic-connectors-sync-jobs` is of type `integer`, which can hold a maximum value of `2^31-1`, which is equivalent to 2-ish GB. This PR changes it to `unsigned_long`, which can hold a maximum value of `2^64-1`, which is equivalent to 18-ish Exa Bytes (1 Exa Byte = 1000 PB). ### Checklist Delete any items that are not applicable to this PR. - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --- .../server/index_management/setup_indices.test.ts | 2 +- .../enterprise_search/server/index_management/setup_indices.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/enterprise_search/server/index_management/setup_indices.test.ts b/x-pack/plugins/enterprise_search/server/index_management/setup_indices.test.ts index 525434e326a3b..a62333a9abd5a 100644 --- a/x-pack/plugins/enterprise_search/server/index_management/setup_indices.test.ts +++ b/x-pack/plugins/enterprise_search/server/index_management/setup_indices.test.ts @@ -214,7 +214,7 @@ describe('Setup Indices', () => { deleted_document_count: { type: 'integer' }, error: { type: 'keyword' }, indexed_document_count: { type: 'integer' }, - indexed_document_volume: { type: 'integer' }, + indexed_document_volume: { type: 'unsigned_long' }, last_seen: { type: 'date' }, metadata: { type: 'object' }, started_at: { type: 'date' }, diff --git a/x-pack/plugins/enterprise_search/server/index_management/setup_indices.ts b/x-pack/plugins/enterprise_search/server/index_management/setup_indices.ts index 050b85a872c01..c660ac2aa0e5b 100644 --- a/x-pack/plugins/enterprise_search/server/index_management/setup_indices.ts +++ b/x-pack/plugins/enterprise_search/server/index_management/setup_indices.ts @@ -238,7 +238,7 @@ const indices: IndexDefinition[] = [ deleted_document_count: { type: 'integer' }, error: { type: 'keyword' }, indexed_document_count: { type: 'integer' }, - indexed_document_volume: { type: 'integer' }, + indexed_document_volume: { type: 'unsigned_long' }, last_seen: { type: 'date' }, metadata: { type: 'object' }, started_at: { type: 'date' }, From bd664eb690b36a2f22c2ec9006061541a01f465f Mon Sep 17 00:00:00 2001 From: Anton Dosov Date: Mon, 17 Apr 2023 17:02:10 +0200 Subject: [PATCH 08/17] add BlueOak-1.0.0 to the list of allowed licences (#155018) ## Summary Adding `BlueOak-1.0.0` to the list of allowed licenses as it was green-listed. We need this license in Kibana [to update Puppeteer](https://github.com/elastic/kibana/issues/151211#issuecomment-1489959322) as one of its nested dependencies now uses this license. --- src/dev/license_checker/config.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dev/license_checker/config.ts b/src/dev/license_checker/config.ts index 72c269ae3bd2d..28c22aad734d5 100644 --- a/src/dev/license_checker/config.ts +++ b/src/dev/license_checker/config.ts @@ -68,6 +68,7 @@ export const LICENSE_ALLOWED = [ 'Nuclide software', 'Python-2.0', '(Apache-2.0 AND MIT)', + 'BlueOak-1.0.0', ]; // The following list only applies to licenses that From 70d5dad847881e39ca713f54db884c4899f2cd61 Mon Sep 17 00:00:00 2001 From: Elastic Machine Date: Mon, 17 Apr 2023 11:09:59 -0400 Subject: [PATCH 09/17] [main] Sync bundled packages with Package Storage (#155040) Automated by https://internal-ci.elastic.co/job/package_storage/job/sync-bundled-packages-job/job/main/3162/ Co-authored-by: apmmachine --- fleet_packages.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fleet_packages.json b/fleet_packages.json index ae7bdca17b4c6..e78e1fbe6451f 100644 --- a/fleet_packages.json +++ b/fleet_packages.json @@ -46,6 +46,6 @@ }, { "name": "security_detection_engine", - "version": "8.7.1" + "version": "8.7.2" } ] \ No newline at end of file From bcfe4b0005754b61d70d490eba771f639f634138 Mon Sep 17 00:00:00 2001 From: Patrick Mueller Date: Mon, 17 Apr 2023 11:19:16 -0400 Subject: [PATCH 10/17] [ResponseOps] provide config to turn off email action footer (#154919) resolves https://github.com/elastic/kibana/issues/135402 Allows deployments to not have the default footer added to alerting emails via the new `xpack.actions.enableFooterInEmail` config setting. The default value is `true`, which renders the footer. Setting the value to `false` will cause no footer to be rendered. Also changes the footer separator from `--` to `---`, which renders nicer in HTML, as a `
` element. --- docs/settings/alert-action-settings.asciidoc | 3 ++ .../actions/server/actions_client.test.ts | 1 + .../actions/server/actions_config.mock.ts | 1 + .../actions/server/actions_config.test.ts | 1 + .../plugins/actions/server/actions_config.ts | 2 ++ x-pack/plugins/actions/server/config.test.ts | 3 ++ x-pack/plugins/actions/server/config.ts | 1 + .../axios_utils_connection.test.ts | 1 + .../axios_utils_proxy.test.ts | 1 + .../server/lib/custom_host_settings.test.ts | 1 + x-pack/plugins/actions/server/plugin.test.ts | 4 +++ .../connector_types/email/index.test.ts | 36 ++++++++++++++++--- .../server/connector_types/email/index.ts | 16 +++++---- .../alerting_api_integration/common/config.ts | 3 ++ .../server/ms_exchage_server_simulation.ts | 2 +- .../tests/actions/connector_types/email.ts | 16 ++++----- .../spaces_only/tests/actions/config.ts | 1 + .../actions/connector_types/stack/email.ts | 23 ++++++++++++ 18 files changed, 96 insertions(+), 20 deletions(-) diff --git a/docs/settings/alert-action-settings.asciidoc b/docs/settings/alert-action-settings.asciidoc index a2ac56be64ebf..7fa35c0df57d7 100644 --- a/docs/settings/alert-action-settings.asciidoc +++ b/docs/settings/alert-action-settings.asciidoc @@ -130,6 +130,9 @@ A list of allowed email domains which can be used with the email connector. When WARNING: This feature is available in {kib} 7.17.4 and 8.3.0 onwards but is not supported in {kib} 8.0, 8.1 or 8.2. As such, this setting should be removed before upgrading from 7.17 to 8.0, 8.1 or 8.2. It is possible to configure the settings in 7.17.4 and then upgrade to 8.3.0 directly. +`xpack.actions.enableFooterInEmail` {ess-icon}:: +A boolean value indicating that a footer with a relevant link should be added to emails sent as alerting actions. Default: true. + `xpack.actions.enabledActionTypes` {ess-icon}:: A list of action types that are enabled. It defaults to `[*]`, enabling all types. The names for built-in {kib} action types are prefixed with a `.` and include: `.email`, `.index`, `.jira`, `.opsgenie`, `.pagerduty`, `.resilient`, `.server-log`, `.servicenow`, .`servicenow-itom`, `.servicenow-sir`, `.slack`, `.swimlane`, `.teams`, `.tines`, `.torq`, `.xmatters`, and `.webhook`. An empty list `[]` will disable all action types. + diff --git a/x-pack/plugins/actions/server/actions_client.test.ts b/x-pack/plugins/actions/server/actions_client.test.ts index 6cf9d741d248e..3c4b1a876c522 100644 --- a/x-pack/plugins/actions/server/actions_client.test.ts +++ b/x-pack/plugins/actions/server/actions_client.test.ts @@ -580,6 +580,7 @@ describe('create()', () => { verificationMode: 'full', proxyVerificationMode: 'full', }, + enableFooterInEmail: true, }); const localActionTypeRegistryParams = { diff --git a/x-pack/plugins/actions/server/actions_config.mock.ts b/x-pack/plugins/actions/server/actions_config.mock.ts index 26a626cd88bf4..95c6ec1c0cc11 100644 --- a/x-pack/plugins/actions/server/actions_config.mock.ts +++ b/x-pack/plugins/actions/server/actions_config.mock.ts @@ -27,6 +27,7 @@ const createActionsConfigMock = () => { getMicrosoftGraphApiUrl: jest.fn().mockReturnValue(undefined), validateEmailAddresses: jest.fn().mockReturnValue(undefined), getMaxAttempts: jest.fn().mockReturnValue(3), + enableFooterInEmail: jest.fn().mockReturnValue(true), }; return mocked; }; diff --git a/x-pack/plugins/actions/server/actions_config.test.ts b/x-pack/plugins/actions/server/actions_config.test.ts index 2c987ae7d48bd..e1b761ee30001 100644 --- a/x-pack/plugins/actions/server/actions_config.test.ts +++ b/x-pack/plugins/actions/server/actions_config.test.ts @@ -33,6 +33,7 @@ const defaultActionsConfig: ActionsConfig = { proxyVerificationMode: 'full', verificationMode: 'full', }, + enableFooterInEmail: true, }; describe('ensureUriAllowed', () => { diff --git a/x-pack/plugins/actions/server/actions_config.ts b/x-pack/plugins/actions/server/actions_config.ts index 43dd35ba38021..78e62684ad898 100644 --- a/x-pack/plugins/actions/server/actions_config.ts +++ b/x-pack/plugins/actions/server/actions_config.ts @@ -53,6 +53,7 @@ export interface ActionsConfigurationUtilities { addresses: string[], options?: ValidateEmailAddressesOptions ): string | undefined; + enableFooterInEmail: () => boolean; } function allowListErrorMessage(field: AllowListingField, value: string) { @@ -215,5 +216,6 @@ export function getActionsConfigurationUtilities( DEFAULT_MAX_ATTEMPTS ); }, + enableFooterInEmail: () => config.enableFooterInEmail, }; } diff --git a/x-pack/plugins/actions/server/config.test.ts b/x-pack/plugins/actions/server/config.test.ts index a1e6e96dcc69b..f5971a8650681 100644 --- a/x-pack/plugins/actions/server/config.test.ts +++ b/x-pack/plugins/actions/server/config.test.ts @@ -23,6 +23,7 @@ describe('config validation', () => { "allowedHosts": Array [ "*", ], + "enableFooterInEmail": true, "enabledActionTypes": Array [ "*", ], @@ -57,6 +58,7 @@ describe('config validation', () => { "allowedHosts": Array [ "*", ], + "enableFooterInEmail": true, "enabledActionTypes": Array [ "*", ], @@ -198,6 +200,7 @@ describe('config validation', () => { "allowedHosts": Array [ "*", ], + "enableFooterInEmail": true, "enabledActionTypes": Array [ "*", ], diff --git a/x-pack/plugins/actions/server/config.ts b/x-pack/plugins/actions/server/config.ts index bbac076783179..9a620d1452f23 100644 --- a/x-pack/plugins/actions/server/config.ts +++ b/x-pack/plugins/actions/server/config.ts @@ -125,6 +125,7 @@ export const configSchema = schema.object({ connectorTypeOverrides: schema.maybe(schema.arrayOf(connectorTypeSchema)), }) ), + enableFooterInEmail: schema.boolean({ defaultValue: true }), }); export type ActionsConfig = TypeOf; diff --git a/x-pack/plugins/actions/server/integration_tests/axios_utils_connection.test.ts b/x-pack/plugins/actions/server/integration_tests/axios_utils_connection.test.ts index ddd128422f25b..04b8b412e3647 100644 --- a/x-pack/plugins/actions/server/integration_tests/axios_utils_connection.test.ts +++ b/x-pack/plugins/actions/server/integration_tests/axios_utils_connection.test.ts @@ -580,6 +580,7 @@ const BaseActionsConfig: ActionsConfig = { maxResponseContentLength: ByteSizeValue.parse('1mb'), responseTimeout: momentDuration(1000 * 30), customHostSettings: undefined, + enableFooterInEmail: true, }; function getACUfromConfig(config: Partial = {}): ActionsConfigurationUtilities { diff --git a/x-pack/plugins/actions/server/integration_tests/axios_utils_proxy.test.ts b/x-pack/plugins/actions/server/integration_tests/axios_utils_proxy.test.ts index 2be4e04aaba5b..d56818f2c6d3e 100644 --- a/x-pack/plugins/actions/server/integration_tests/axios_utils_proxy.test.ts +++ b/x-pack/plugins/actions/server/integration_tests/axios_utils_proxy.test.ts @@ -592,6 +592,7 @@ const BaseActionsConfig: ActionsConfig = { maxResponseContentLength: ByteSizeValue.parse('1mb'), responseTimeout: momentDuration(1000 * 30), customHostSettings: undefined, + enableFooterInEmail: true, }; function getACUfromConfig(config: Partial = {}): ActionsConfigurationUtilities { diff --git a/x-pack/plugins/actions/server/lib/custom_host_settings.test.ts b/x-pack/plugins/actions/server/lib/custom_host_settings.test.ts index 4bb0825a24ab0..f5cd9c268bd7e 100644 --- a/x-pack/plugins/actions/server/lib/custom_host_settings.test.ts +++ b/x-pack/plugins/actions/server/lib/custom_host_settings.test.ts @@ -73,6 +73,7 @@ describe('custom_host_settings', () => { rejectUnauthorized: true, maxResponseContentLength: new ByteSizeValue(1000000), responseTimeout: moment.duration(60000), + enableFooterInEmail: true, }; test('ensure it copies over the config parts that it does not touch', () => { diff --git a/x-pack/plugins/actions/server/plugin.test.ts b/x-pack/plugins/actions/server/plugin.test.ts index c0c89238edb5d..0136410920c66 100644 --- a/x-pack/plugins/actions/server/plugin.test.ts +++ b/x-pack/plugins/actions/server/plugin.test.ts @@ -46,6 +46,7 @@ describe('Actions Plugin', () => { rejectUnauthorized: true, maxResponseContentLength: new ByteSizeValue(1000000), responseTimeout: moment.duration(60000), + enableFooterInEmail: true, }); plugin = new ActionsPlugin(context); coreSetup = coreMock.createSetup(); @@ -218,6 +219,7 @@ describe('Actions Plugin', () => { rejectUnauthorized: true, maxResponseContentLength: new ByteSizeValue(1000000), responseTimeout: moment.duration('60s'), + enableFooterInEmail: true, ...overrides, }; } @@ -273,6 +275,7 @@ describe('Actions Plugin', () => { rejectUnauthorized: true, maxResponseContentLength: new ByteSizeValue(1000000), responseTimeout: moment.duration(60000), + enableFooterInEmail: true, }); plugin = new ActionsPlugin(context); coreSetup = coreMock.createSetup(); @@ -341,6 +344,7 @@ describe('Actions Plugin', () => { rejectUnauthorized: true, maxResponseContentLength: new ByteSizeValue(1000000), responseTimeout: moment.duration('60s'), + enableFooterInEmail: true, ...overrides, }; } diff --git a/x-pack/plugins/stack_connectors/server/connector_types/email/index.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/email/index.test.ts index 05f080d8c0b3e..ef504b70ec942 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/email/index.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/email/index.test.ts @@ -523,6 +523,10 @@ describe('execute()', () => { logger: mockedLogger, }; + beforeEach(() => { + executorOptions.configurationUtilities = actionsConfigMock.create(); + }); + test('ensure parameters are as expected', async () => { sendEmailMock.mockReset(); const result = await connectorType.executor(executorOptions); @@ -540,7 +544,7 @@ describe('execute()', () => { "content": Object { "message": "a message to you - -- + --- This message was sent by Elastic.", "subject": "the subject", @@ -591,7 +595,7 @@ describe('execute()', () => { "content": Object { "message": "a message to you - -- + --- This message was sent by Elastic.", "subject": "the subject", @@ -642,7 +646,7 @@ describe('execute()', () => { "content": Object { "message": "a message to you - -- + --- This message was sent by Elastic.", "subject": "the subject", @@ -738,6 +742,28 @@ describe('execute()', () => { `); }); + test('provides no footer link when enableFooterInEmail is false', async () => { + const customExecutorOptions: EmailConnectorTypeExecutorOptions = { + ...executorOptions, + configurationUtilities: { + ...configurationUtilities, + enableFooterInEmail: jest.fn().mockReturnValue(false), + }, + }; + + const connectorTypeWithPublicUrl = getConnectorType({ + publicBaseUrl: 'https://localhost:1234/foo/bar', + }); + + await connectorTypeWithPublicUrl.executor(customExecutorOptions); + + expect(customExecutorOptions.configurationUtilities.enableFooterInEmail).toHaveBeenCalledTimes( + 1 + ); + const sendMailCall = sendEmailMock.mock.calls[0][1]; + expect(sendMailCall.content.message).toMatchInlineSnapshot(`"a message to you"`); + }); + test('provides a footer link to Elastic when publicBaseUrl is defined', async () => { const connectorTypeWithPublicUrl = getConnectorType({ publicBaseUrl: 'https://localhost:1234/foo/bar', @@ -750,7 +776,7 @@ describe('execute()', () => { expect(sendMailCall.content.message).toMatchInlineSnapshot(` "a message to you - -- + --- This message was sent by Elastic. [Go to Elastic](https://localhost:1234/foo/bar)." `); @@ -779,7 +805,7 @@ describe('execute()', () => { expect(sendMailCall.content.message).toMatchInlineSnapshot(` "a message to you - -- + --- This message was sent by Elastic. [View this in Elastic](https://localhost:1234/foo/bar/my/app)." `); diff --git a/x-pack/plugins/stack_connectors/server/connector_types/email/index.ts b/x-pack/plugins/stack_connectors/server/connector_types/email/index.ts index 17669a5a32329..11f18b2ca3c9d 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/email/index.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/email/index.ts @@ -54,7 +54,7 @@ export const ELASTIC_CLOUD_SERVICE: SMTPConnection.Options = { secure: false, }; -const EMAIL_FOOTER_DIVIDER = '\n\n--\n\n'; +const EMAIL_FOOTER_DIVIDER = '\n\n---\n\n'; const ConfigSchemaProps = { service: schema.string({ defaultValue: 'other' }), @@ -319,10 +319,14 @@ async function executor( transport.service = config.service; } - const footerMessage = getFooterMessage({ - publicBaseUrl, - kibanaFooterLink: params.kibanaFooterLink, - }); + let actualMessage = params.message; + if (configurationUtilities.enableFooterInEmail()) { + const footerMessage = getFooterMessage({ + publicBaseUrl, + kibanaFooterLink: params.kibanaFooterLink, + }); + actualMessage = `${params.message}${EMAIL_FOOTER_DIVIDER}${footerMessage}`; + } const sendEmailOptions: SendEmailOptions = { connectorId: actionId, @@ -335,7 +339,7 @@ async function executor( }, content: { subject: params.subject, - message: `${params.message}${EMAIL_FOOTER_DIVIDER}${footerMessage}`, + message: actualMessage, }, hasAuth: config.hasAuth, configurationUtilities, diff --git a/x-pack/test/alerting_api_integration/common/config.ts b/x-pack/test/alerting_api_integration/common/config.ts index 927a677aa5eab..4e8f8c45abb5b 100644 --- a/x-pack/test/alerting_api_integration/common/config.ts +++ b/x-pack/test/alerting_api_integration/common/config.ts @@ -27,6 +27,7 @@ interface CreateTestConfigOptions { testFiles?: string[]; reportName?: string; useDedicatedTaskRunner: boolean; + enableFooterInEmail?: boolean; } // test.not-enabled is specifically not enabled @@ -75,6 +76,7 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) testFiles = undefined, reportName = undefined, useDedicatedTaskRunner, + enableFooterInEmail = true, } = options; return async ({ readConfigFile }: FtrConfigProviderContext) => { @@ -173,6 +175,7 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) 'some.non.existent.com', 'smtp.live.com', ])}`, + `--xpack.actions.enableFooterInEmail=${enableFooterInEmail}`, '--xpack.encryptedSavedObjects.encryptionKey="wuGNaIhoMpk5sO4UBxgr3NyW1sFcLgIf"', '--xpack.alerting.invalidateApiKeysTask.interval="15s"', '--xpack.alerting.healthCheck.interval="1s"', diff --git a/x-pack/test/alerting_api_integration/common/plugins/actions_simulators/server/ms_exchage_server_simulation.ts b/x-pack/test/alerting_api_integration/common/plugins/actions_simulators/server/ms_exchage_server_simulation.ts index eba9d41dff32b..0f5f4805d28bc 100644 --- a/x-pack/test/alerting_api_integration/common/plugins/actions_simulators/server/ms_exchage_server_simulation.ts +++ b/x-pack/test/alerting_api_integration/common/plugins/actions_simulators/server/ms_exchage_server_simulation.ts @@ -43,7 +43,7 @@ export function initPlugin(router: IRouter, path: string) { cc: null, bcc: null, subject: 'email-subject', - html: `

email-message

\n

--

\n

This message was sent by Elastic. Go to Elastic.

\n`, + html: `

email-message

\n
\n

This message was sent by Elastic. Go to Elastic.

\n`, text: 'email-message\n\n--\n\nThis message was sent by Elastic. [Go to Elastic](https://localhost:5601).', headers: {}, }, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/email.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/email.ts index 6cd612c3fc431..e2b4e3fa9e346 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/email.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/email.ts @@ -124,8 +124,8 @@ export default function emailTest({ getService }: FtrProviderContext) { cc: null, bcc: null, subject: 'email-subject', - html: `

email-message

\n

--

\n

This message was sent by Elastic. Go to Elastic.

\n`, - text: 'email-message\n\n--\n\nThis message was sent by Elastic. [Go to Elastic](https://localhost:5601).', + html: `

email-message

\n
\n

This message was sent by Elastic. Go to Elastic.

\n`, + text: 'email-message\n\n---\n\nThis message was sent by Elastic. [Go to Elastic](https://localhost:5601).', headers: {}, }, }); @@ -147,10 +147,10 @@ export default function emailTest({ getService }: FtrProviderContext) { .then((resp: any) => { const { text, html } = resp.body.data.message; expect(text).to.eql( - '_italic_ **bold** https://elastic.co link\n\n--\n\nThis message was sent by Elastic. [Go to Elastic](https://localhost:5601).' + '_italic_ **bold** https://elastic.co link\n\n---\n\nThis message was sent by Elastic. [Go to Elastic](https://localhost:5601).' ); expect(html).to.eql( - `

italic bold https://elastic.co link

\n

--

\n

This message was sent by Elastic. Go to Elastic.

\n` + `

italic bold https://elastic.co link

\n
\n

This message was sent by Elastic. Go to Elastic.

\n` ); }); }); @@ -174,10 +174,10 @@ export default function emailTest({ getService }: FtrProviderContext) { .then((resp: any) => { const { text, html } = resp.body.data.message; expect(text).to.eql( - 'message\n\n--\n\nThis message was sent by Elastic. [View my path in Elastic](https://localhost:5601/my/path).' + 'message\n\n---\n\nThis message was sent by Elastic. [View my path in Elastic](https://localhost:5601/my/path).' ); expect(html).to.eql( - `

message

\n

--

\n

This message was sent by Elastic. View my path in Elastic.

\n` + `

message

\n
\n

This message was sent by Elastic. View my path in Elastic.

\n` ); }); }); @@ -325,8 +325,8 @@ export default function emailTest({ getService }: FtrProviderContext) { cc: null, bcc: null, subject: 'email-subject', - html: `

email-message

\n

--

\n

This message was sent by Elastic. Go to Elastic.

\n`, - text: 'email-message\n\n--\n\nThis message was sent by Elastic. [Go to Elastic](https://localhost:5601).', + html: `

email-message

\n
\n

This message was sent by Elastic. Go to Elastic.

\n`, + text: 'email-message\n\n---\n\nThis message was sent by Elastic. [Go to Elastic](https://localhost:5601).', headers: {}, }, }); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/config.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/config.ts index 3274d91ceb732..009529addea59 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/config.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/config.ts @@ -21,4 +21,5 @@ export default createTestConfig('spaces_only', { useDedicatedTaskRunner: true, testFiles: [require.resolve('.')], reportName: 'X-Pack Alerting API Integration Tests - Actions', + enableFooterInEmail: false, }); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/connector_types/stack/email.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/connector_types/stack/email.ts index 9bb924fd5c945..f3e31cda00eb2 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/connector_types/stack/email.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/connector_types/stack/email.ts @@ -54,6 +54,29 @@ export default function emailTest({ getService }: FtrProviderContext) { } }); + it('does not have a footer', async () => { + const from = `bob@${EmailDomainAllowed}`; + const conn = await createConnector(from); + expect(conn.status).to.be(200); + + const { id } = conn.body; + expect(id).to.be.a('string'); + + const to = EmailDomainsAllowed.map((domain) => `jeb@${domain}`).sort(); + const cc = EmailDomainsAllowed.map((domain) => `jim@${domain}`).sort(); + const bcc = EmailDomainsAllowed.map((domain) => `joe@${domain}`).sort(); + + const ccNames = cc.map((email) => `Jimmy Jack <${email}>`); + + const run = await runConnector(id, to, ccNames, bcc); + expect(run.status).to.be(200); + + const { status } = run.body || {}; + expect(status).to.be('ok'); + + expect(run.body.data.message.text).to.be('email-message'); + }); + describe('fails for invalid email domains', () => { it('in create when invalid "from" used', async () => { const from = `bob@not.allowed`; From 41cd8cb96ab3601a8209aed97e796a182e2d6a2e Mon Sep 17 00:00:00 2001 From: Terrance DeJesus <99630311+terrancedejesus@users.noreply.github.com> Date: Mon, 17 Apr 2023 11:41:19 -0400 Subject: [PATCH 11/17] [Security Solution] Filterlist Update for Endpoint Process API Events (#154746) ## Related * https://github.com/elastic/security-team/issues/4613 ## Summary Updates endpoint alerts telemetry filter list to add fields for API events. --- .../server/lib/telemetry/filterlists/endpoint_alerts.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/filterlists/endpoint_alerts.ts b/x-pack/plugins/security_solution/server/lib/telemetry/filterlists/endpoint_alerts.ts index 84963b78ab4ef..2a852292d60f3 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/filterlists/endpoint_alerts.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/filterlists/endpoint_alerts.ts @@ -22,6 +22,7 @@ const baseAllowlistFields: AllowlistFields = { uptime: true, Ext: { ancestry: true, + api: true, architecture: true, code_signature: true, dll: true, From 1b7830775ee30ca42c14b3fe0f85079bb6ced46c Mon Sep 17 00:00:00 2001 From: Abdul Wahab Zahid Date: Mon, 17 Apr 2023 17:42:22 +0200 Subject: [PATCH 12/17] Make "Text Assertion" form field optional for Single Page monitors (#154795) (#153929) Makes the "Text Assertion" field optional in Monitor Add/Edit form. --- .../components/monitor_add_edit/form/field_config.tsx | 4 ++-- .../components/monitor_add_edit/form/formatter.ts | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/field_config.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/field_config.tsx index fe2035efb481f..7e1ea329fe3f8 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/field_config.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/field_config.tsx @@ -1090,12 +1090,12 @@ export const FIELD = (readOnly?: boolean): FieldMap => ({ label: i18n.translate('xpack.synthetics.monitorConfig.textAssertion.label', { defaultMessage: 'Text assertion', }), - required: true, + required: false, helpText: i18n.translate('xpack.synthetics.monitorConfig.textAssertion.helpText', { defaultMessage: 'Consider the page loaded when the specified text is rendered.', }), validation: () => ({ - required: true, + required: false, }), props: (): EuiFieldTextProps => ({ readOnly, diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/formatter.ts b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/formatter.ts index e7a42d067533a..f38149d6d6e75 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/formatter.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/formatter.ts @@ -24,14 +24,15 @@ export const ALLOWED_FIELDS = [ConfigKey.ENABLED, ConfigKey.ALERT_CONFIG]; export const format = (fields: Record, readOnly: boolean = false) => { const formattedFields = formatter(fields) as MonitorFields; + const textAssertion = formattedFields[ConfigKey.TEXT_ASSERTION] + ? ` + await page.getByText('${formattedFields[ConfigKey.TEXT_ASSERTION]}').first().waitFor();` + : ``; const formattedMap = { [FormMonitorType.SINGLE]: { ...formattedFields, [ConfigKey.SOURCE_INLINE]: `step('Go to ${formattedFields[ConfigKey.URLS]}', async () => { - await page.goto('${formattedFields[ConfigKey.URLS]}'); - expect(await page.isVisible('text=${ - formattedFields[ConfigKey.TEXT_ASSERTION] - }')).toBeTruthy(); + await page.goto('${formattedFields[ConfigKey.URLS]}');${textAssertion} });`, [ConfigKey.FORM_MONITOR_TYPE]: FormMonitorType.SINGLE, }, From 404ec586601ab3fce523e076cd0e37de699a196c Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Mon, 17 Apr 2023 11:44:31 -0400 Subject: [PATCH 13/17] skip failing test suite (#137032) --- .../apps/ml/data_visualizer/index_data_visualizer.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer.ts b/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer.ts index 6dcfcba1a66ba..72d84fd1e63a1 100644 --- a/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer.ts +++ b/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer.ts @@ -140,7 +140,8 @@ export default function ({ getPageObject, getService }: FtrProviderContext) { }); } - describe('index based', function () { + // Failing: See https://github.com/elastic/kibana/issues/137032 + describe.skip('index based', function () { this.tags(['ml']); before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); From 644e0a81d40b8fb852988f9900e7cb6ee6ba6d22 Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Mon, 17 Apr 2023 11:44:58 -0400 Subject: [PATCH 14/17] skip failing test suite (#154452) --- .../functional/apps/ml/data_visualizer/index_data_visualizer.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer.ts b/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer.ts index 72d84fd1e63a1..f68dc7e0e245d 100644 --- a/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer.ts +++ b/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer.ts @@ -141,6 +141,7 @@ export default function ({ getPageObject, getService }: FtrProviderContext) { } // Failing: See https://github.com/elastic/kibana/issues/137032 + // Failing: See https://github.com/elastic/kibana/issues/154452 describe.skip('index based', function () { this.tags(['ml']); before(async () => { From 50cedc25e017b00925da6670886c1850c4c02a43 Mon Sep 17 00:00:00 2001 From: Nicolas Chaulet Date: Mon, 17 Apr 2023 11:48:34 -0400 Subject: [PATCH 15/17] [Fleet] Update instructions for Fleet server port (#154674) --- .../steps/add_fleet_server_host.tsx | 21 +++++++- .../steps/get_started.tsx | 21 +++++++- .../utils/install_command_utils.test.ts | 48 ++++++++++++------- .../utils/install_command_utils.ts | 2 + .../translations/translations/fr-FR.json | 2 - .../translations/translations/ja-JP.json | 2 - .../translations/translations/zh-CN.json | 2 - 7 files changed, 72 insertions(+), 26 deletions(-) diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/add_fleet_server_host.tsx b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/add_fleet_server_host.tsx index aeaf70e37aaec..debefdb5ca997 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/add_fleet_server_host.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/add_fleet_server_host.tsx @@ -7,6 +7,7 @@ import React, { useState, useCallback } from 'react'; import type { EuiStepProps } from '@elastic/eui'; +import { EuiIconTip } from '@elastic/eui'; import { EuiSwitch, EuiButton, @@ -111,8 +112,24 @@ export const AddFleetServerHostStepContent = ({ 8220 }} + defaultMessage="First, set the public IP or host name and port that agents will use to reach Fleet Server. It uses port {port} by default {toolTip}. We'll then generate a policy for you automatically. " + values={{ + port: 8220, + toolTip: ( + + } + position="right" + /> + ), + }} /> diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/get_started.tsx b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/get_started.tsx index 8d9b9667e4c1e..41014b1aa97ad 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/get_started.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/get_started.tsx @@ -8,6 +8,7 @@ import React from 'react'; import type { EuiStepProps } from '@elastic/eui'; +import { EuiIconTip } from '@elastic/eui'; import { EuiButton, EuiCallOut, @@ -92,8 +93,24 @@ const GettingStartedStepContent: React.FunctionComponent = 8220 }} + defaultMessage="First, set the public IP or host name and port that agents will use to reach Fleet Server. It uses port {port} by default {toolTip}. We'll then generate a policy for you automatically." + values={{ + port: 8220, + toolTip: ( + + } + position="right" + /> + ), + }} /> diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/utils/install_command_utils.test.ts b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/utils/install_command_utils.test.ts index ebe450bdfae8e..35dbd5e70c99f 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/utils/install_command_utils.test.ts +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/utils/install_command_utils.test.ts @@ -22,7 +22,8 @@ describe('getInstallCommandForPlatform', () => { cd elastic-agent--linux-x86_64 sudo ./elastic-agent install \\\\ --fleet-server-es=http://elasticsearch:9200 \\\\ - --fleet-server-service-token=service-token-1" + --fleet-server-service-token=service-token-1 \\\\ + --fleet-server-port=8220" `); }); @@ -39,7 +40,8 @@ describe('getInstallCommandForPlatform', () => { cd elastic-agent--darwin-x86_64 sudo ./elastic-agent install \\\\ --fleet-server-es=http://elasticsearch:9200 \\\\ - --fleet-server-service-token=service-token-1" + --fleet-server-service-token=service-token-1 \\\\ + --fleet-server-port=8220" `); }); @@ -57,7 +59,8 @@ describe('getInstallCommandForPlatform', () => { cd elastic-agent--windows-x86_64 .\\\\elastic-agent.exe install \` --fleet-server-es=http://elasticsearch:9200 \` - --fleet-server-service-token=service-token-1" + --fleet-server-service-token=service-token-1 \` + --fleet-server-port=8220" `); }); @@ -73,7 +76,8 @@ describe('getInstallCommandForPlatform', () => { sudo rpm -vi elastic-agent--x86_64.rpm sudo elastic-agent enroll \\\\ --fleet-server-es=http://elasticsearch:9200 \\\\ - --fleet-server-service-token=service-token-1 + --fleet-server-service-token=service-token-1 \\\\ + --fleet-server-port=8220 sudo systemctl enable elastic-agent sudo systemctl start elastic-agent" `); @@ -91,7 +95,8 @@ describe('getInstallCommandForPlatform', () => { sudo dpkg -i elastic-agent--amd64.deb sudo elastic-agent enroll \\\\ --fleet-server-es=http://elasticsearch:9200 \\\\ - --fleet-server-service-token=service-token-1 + --fleet-server-service-token=service-token-1 \\\\ + --fleet-server-port=8220 sudo systemctl enable elastic-agent sudo systemctl start elastic-agent" `); @@ -115,7 +120,8 @@ describe('getInstallCommandForPlatform', () => { sudo ./elastic-agent install \\\\ --fleet-server-es=http://elasticsearch:9200 \\\\ --fleet-server-service-token=service-token-1 \\\\ - --fleet-server-es-ca-trusted-fingerprint=fingerprint123456" + --fleet-server-es-ca-trusted-fingerprint=fingerprint123456 \\\\ + --fleet-server-port=8220" `); }); }); @@ -136,7 +142,8 @@ describe('getInstallCommandForPlatform', () => { sudo ./elastic-agent install \\\\ --fleet-server-es=http://elasticsearch:9200 \\\\ --fleet-server-service-token=service-token-1 \\\\ - --fleet-server-policy=policy-1" + --fleet-server-policy=policy-1 \\\\ + --fleet-server-port=8220" `); }); @@ -155,7 +162,8 @@ describe('getInstallCommandForPlatform', () => { sudo ./elastic-agent install \\\\ --fleet-server-es=http://elasticsearch:9200 \\\\ --fleet-server-service-token=service-token-1 \\\\ - --fleet-server-policy=policy-1" + --fleet-server-policy=policy-1 \\\\ + --fleet-server-port=8220" `); }); @@ -175,7 +183,8 @@ describe('getInstallCommandForPlatform', () => { .\\\\elastic-agent.exe install \` --fleet-server-es=http://elasticsearch:9200 \` --fleet-server-service-token=service-token-1 \` - --fleet-server-policy=policy-1" + --fleet-server-policy=policy-1 \` + --fleet-server-port=8220" `); }); @@ -193,7 +202,8 @@ describe('getInstallCommandForPlatform', () => { sudo elastic-agent enroll \\\\ --fleet-server-es=http://elasticsearch:9200 \\\\ --fleet-server-service-token=service-token-1 \\\\ - --fleet-server-policy=policy-1 + --fleet-server-policy=policy-1 \\\\ + --fleet-server-port=8220 sudo systemctl enable elastic-agent sudo systemctl start elastic-agent" `); @@ -213,7 +223,8 @@ describe('getInstallCommandForPlatform', () => { sudo elastic-agent enroll \\\\ --fleet-server-es=http://elasticsearch:9200 \\\\ --fleet-server-service-token=service-token-1 \\\\ - --fleet-server-policy=policy-1 + --fleet-server-policy=policy-1 \\\\ + --fleet-server-port=8220 sudo systemctl enable elastic-agent sudo systemctl start elastic-agent" `); @@ -242,7 +253,8 @@ describe('getInstallCommandForPlatform', () => { --certificate-authorities= \\\\ --fleet-server-es-ca= \\\\ --fleet-server-cert= \\\\ - --fleet-server-cert-key=" + --fleet-server-cert-key= \\\\ + --fleet-server-port=8220" `); }); @@ -267,7 +279,8 @@ describe('getInstallCommandForPlatform', () => { --certificate-authorities= \\\\ --fleet-server-es-ca= \\\\ --fleet-server-cert= \\\\ - --fleet-server-cert-key=" + --fleet-server-cert-key= \\\\ + --fleet-server-port=8220" `); }); @@ -293,7 +306,8 @@ describe('getInstallCommandForPlatform', () => { --certificate-authorities= \` --fleet-server-es-ca= \` --fleet-server-cert= \` - --fleet-server-cert-key=" + --fleet-server-cert-key= \` + --fleet-server-port=8220" `); }); @@ -317,7 +331,8 @@ describe('getInstallCommandForPlatform', () => { --certificate-authorities= \\\\ --fleet-server-es-ca= \\\\ --fleet-server-cert= \\\\ - --fleet-server-cert-key= + --fleet-server-cert-key= \\\\ + --fleet-server-port=8220 sudo systemctl enable elastic-agent sudo systemctl start elastic-agent" `); @@ -343,7 +358,8 @@ describe('getInstallCommandForPlatform', () => { --certificate-authorities= \\\\ --fleet-server-es-ca= \\\\ --fleet-server-cert= \\\\ - --fleet-server-cert-key= + --fleet-server-cert-key= \\\\ + --fleet-server-port=8220 sudo systemctl enable elastic-agent sudo systemctl start elastic-agent" `); diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/utils/install_command_utils.ts b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/utils/install_command_utils.ts index c5a58bef884f1..1e392db8fff70 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/utils/install_command_utils.ts +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/utils/install_command_utils.ts @@ -96,6 +96,8 @@ export function getInstallCommandForPlatform( commandArguments.push(['fleet-server-cert-key', '']); } + commandArguments.push(['fleet-server-port', '8220']); + const commandArgumentsStr = commandArguments .reduce((acc, [key, val]) => { if (acc === '' && key === 'url') { diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index ca87bd58cff99..dfc13818c3e8f 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -14298,12 +14298,10 @@ "xpack.fleet.fleetServerLanding.instructions": "Un serveur Fleet est nécessaire pour enregistrer des agents avec Fleet. Suivez les instructions ci-après pour configurer un serveur Fleet. Pour en savoir plus, consultez {userGuideLink}", "xpack.fleet.fleetServerOnPremRequiredCallout.calloutDescription": "Suivez les instructions ci-après pour configurer un serveur Fleet. Pour en savoir plus, consultez {guideLink}.", "xpack.fleet.fleetServerOnPremUnhealthyCallout.calloutDescription": "Un serveur Fleet intègre est nécessaire pour enregistrer des agents avec Fleet. Pour en savoir plus, consultez {guideLink}.", - "xpack.fleet.fleetServerSetup.addFleetServerHostStepDescription": "Tout d'abord, définissez l'IP public ou le nom d'hôte et le port que les agents utiliseront pour atteindre le serveur Fleet. Par défaut, le port {port} est utilisé. Nous générerons ensuite automatiquement une politique à votre place. ", "xpack.fleet.fleetServerSetup.addFleetServerHostSuccessText": "{host} ajouté. Vous pouvez modifier les hôtes de votre serveur Fleet dans {fleetSettingsLink}.", "xpack.fleet.fleetServerSetup.cloudSetupText": "Un serveur Fleet est nécessaire pour enregistrer des agents avec Fleet. Le moyen le plus simple d’en obtenir un est d’ajouter un serveur d’intégration, qui prend en charge l’intégration du serveur Fleet. Vous pouvez l’ajouter à votre déploiement dans la console cloud. Pour en savoir plus, consultez {link}", "xpack.fleet.fleetServerSetup.deploymentModeProductionOption": "{production} – Fournissez vos propres certificats. Cette option demande aux agents de préciser une clé de certificat lors de leur enregistrement avec Fleet", "xpack.fleet.fleetServerSetup.deploymentModeQuickStartOption": "{quickStart} – Le serveur Fleet va générer un certificat autosigné. Les agents suivants doivent être enregistrés avec l'indicateur --insecure. Non recommandé pour les cas d'utilisation en production.", - "xpack.fleet.fleetServerSetup.getStartedInstructions": "Tout d'abord, définissez l'IP public ou le nom d'hôte et le port que les agents utiliseront pour atteindre le serveur Fleet. Par défaut, le port {port} est utilisé. Nous générerons ensuite automatiquement une politique à votre place.", "xpack.fleet.fleetServerSetupPermissionDeniedErrorMessage": "Le serveur Fleet doit être configuré. Pour cela, le privilège de cluster {roleName} est requis. Contactez votre administrateur.", "xpack.fleet.homeIntegration.tutorialModule.noticeText": "{notePrefix} Une version plus récente de ce module est {availableAsIntegrationLink}. Pour en savoir plus sur les intégrations et le nouvel agent Elastic, lisez notre {blogPostLink}.", "xpack.fleet.integration.settings.versionInfo.updatesAvailableBody": "Passez à la version {latestVersion} pour bénéficier des fonctionnalités les plus récentes", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 2363c92879f22..270f4940d2e64 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -14297,12 +14297,10 @@ "xpack.fleet.fleetServerLanding.instructions": "Fleetにエージェントを登録する前に、Fleetサーバーが必要です。Fleetサーバーのセットアップについては、次の手順に従ってください。詳細は{userGuideLink}をご覧ください", "xpack.fleet.fleetServerOnPremRequiredCallout.calloutDescription": "Fleetサーバーのセットアップについては、次の手順に従ってください。詳細は{guideLink}をご覧ください。", "xpack.fleet.fleetServerOnPremUnhealthyCallout.calloutDescription": "Fleetにエージェントを登録する前に、正常なFleetサーバーが必要です。 詳細は{guideLink}をご覧ください。", - "xpack.fleet.fleetServerSetup.addFleetServerHostStepDescription": "まず、エージェントがFleetサーバーに接続するために使用する、公開IPまたはホスト名とポートを設定します。デフォルトでは、ポート{port}が使用されます。これで、自動的にポリシーが生成されます。", "xpack.fleet.fleetServerSetup.addFleetServerHostSuccessText": "{host}を追加しました。{fleetSettingsLink}でFleetサーバーを編集できます。", "xpack.fleet.fleetServerSetup.cloudSetupText": "Fleetにエージェントを登録する前に、Fleetサーバーが必要です。取得するための最も簡単な方法は、Fleetサーバー統合を実行する統合サーバーを追加することです。クラウドコンソールでデプロイに追加できます。詳細は{link}をご覧ください", "xpack.fleet.fleetServerSetup.deploymentModeProductionOption": "{production} – 独自の証明書を指定します。このオプションでは、Fleetに登録するときに、エージェントで証明書鍵を指定する必要があります。", "xpack.fleet.fleetServerSetup.deploymentModeQuickStartOption": "{quickStart} – Fleetサーバーは自己署名証明書を生成します。後続のエージェントは--insecureフラグを使用して登録する必要があります。本番ユースケースには推奨されません。", - "xpack.fleet.fleetServerSetup.getStartedInstructions": "まず、エージェントがFleetサーバーに接続するために使用する、公開IPまたはホスト名とポートを設定します。デフォルトでは、ポート{port}が使用されます。これで、自動的にポリシーが生成されます。", "xpack.fleet.fleetServerSetupPermissionDeniedErrorMessage": "Fleetサーバーを設定する必要があります。これには{roleName}クラスター権限が必要です。管理者にお問い合わせください。", "xpack.fleet.homeIntegration.tutorialModule.noticeText": "{notePrefix}このモジュールの新しいバージョンが{availableAsIntegrationLink}。統合とElasticエージェントの詳細については、{blogPostLink}をお読みください。", "xpack.fleet.integration.settings.versionInfo.updatesAvailableBody": "バージョン{latestVersion}にアップグレードして最新の機能を入手", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 2ffdd43bb24ca..f0fa0b6dfb136 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -14298,12 +14298,10 @@ "xpack.fleet.fleetServerLanding.instructions": "需要提供 Fleet 服务器,才能使用 Fleet 注册代理。按照下面的说明设置 Fleet 服务器。有关更多信息,请参见 {userGuideLink}", "xpack.fleet.fleetServerOnPremRequiredCallout.calloutDescription": "按照下面的说明设置 Fleet 服务器。有关更多信息,请参见 {guideLink}。", "xpack.fleet.fleetServerOnPremUnhealthyCallout.calloutDescription": "在使用 Fleet 注册代理之前,需要提供运行正常的 Fleet 服务器。 有关更多信息,请参见 {guideLink}。", - "xpack.fleet.fleetServerSetup.addFleetServerHostStepDescription": "首先,设置代理将用于访问 Fleet 服务器的公共 IP 或主机名和端口。它默认使用端口 {port}。然后,将自动为您生成策略。", "xpack.fleet.fleetServerSetup.addFleetServerHostSuccessText": "已添加 {host}。您可以在{fleetSettingsLink}中编辑 Fleet 服务器主机。", "xpack.fleet.fleetServerSetup.cloudSetupText": "需要提供 Fleet 服务器,才能使用 Fleet 注册代理。获取 Fleet 服务器的最简单方法是添加集成服务器,它会运行 Fleet 服务器集成。您可以在云控制台中将其添加到部署中。有关更多信息,请参见 {link}", "xpack.fleet.fleetServerSetup.deploymentModeProductionOption": "{production} – 提供您自己的证书。注册到 Fleet 时,此选项将需要代理指定证书密钥", "xpack.fleet.fleetServerSetup.deploymentModeQuickStartOption": "{quickStart} – Fleet 服务器将生成自签名证书。必须使用 --insecure 标志注册后续代理。不推荐用于生产用例。", - "xpack.fleet.fleetServerSetup.getStartedInstructions": "首先,设置代理将用于访问 Fleet 服务器的公共 IP 或主机名和端口。它默认使用端口 {port}。然后,将自动为您生成策略。", "xpack.fleet.fleetServerSetupPermissionDeniedErrorMessage": "需要设置 Fleet 服务器。这需要 {roleName} 集群权限。请联系您的管理员。", "xpack.fleet.homeIntegration.tutorialModule.noticeText": "{notePrefix} 此模块的较新版本为 {availableAsIntegrationLink}。要详细了解集成和新 Elastic 代理,请阅读我们的 {blogPostLink}。", "xpack.fleet.integration.settings.versionInfo.updatesAvailableBody": "升级到版本 {latestVersion} 可获取最新功能", From 406fe970168ca7754ae34ff588197fa2204d2594 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loix?= Date: Mon, 17 Apr 2023 16:51:16 +0100 Subject: [PATCH 16/17] [Table list view] Fix sort by label (#154922) --- .../table_list/src/table_list_view.test.tsx | 42 ++++++++++++++++--- .../table_list/src/table_list_view.tsx | 26 ++++++++++-- 2 files changed, 59 insertions(+), 9 deletions(-) diff --git a/packages/content-management/table_list/src/table_list_view.test.tsx b/packages/content-management/table_list/src/table_list_view.test.tsx index 24ffc82eb0c51..62c83fb5b9454 100644 --- a/packages/content-management/table_list/src/table_list_view.test.tsx +++ b/packages/content-management/table_list/src/table_list_view.test.tsx @@ -66,6 +66,12 @@ const twoDaysAgoToString = new Date(twoDaysAgo.getTime()).toDateString(); const yesterday = new Date(new Date().setDate(new Date().getDate() - 1)); const yesterdayToString = new Date(yesterday.getTime()).toDateString(); +const getActions = (testBed: TestBed) => ({ + openSortSelect() { + testBed.find('tableSortSelectBtn').at(0).simulate('click'); + }, +}); + describe('TableListView', () => { beforeAll(() => { jest.useFakeTimers({ legacyFakeTimers: true }); @@ -306,6 +312,36 @@ describe('TableListView', () => { expect(lastRowTitle).toBe('Item 19'); }); + test('should allow changing the number of rows in the table', async () => { + let testBed: TestBed; + + await act(async () => { + testBed = await setup({ + initialPageSize, + findItems: jest.fn().mockResolvedValue({ total: hits.length, hits: [...hits] }), + }); + }); + + const { component, table, find } = testBed!; + component.update(); + + let { tableCellsValues } = table.getMetaData('itemsInMemTable'); + expect(tableCellsValues.length).toBe(requiredProps.initialPageSize); + + // Changing the "Rows per page" also sends the "sort" column information and thus updates the sorting. + // We test that the "sort by" column has not changed before and after changing the number of rows + expect(find('tableSortSelectBtn').at(0).text()).toBe('Recently updated'); + + // Open the "Rows per page" drop down + find('tablePaginationPopoverButton').simulate('click'); + find('tablePagination-10-rows').simulate('click'); + + ({ tableCellsValues } = table.getMetaData('itemsInMemTable')); + expect(tableCellsValues.length).toBe(10); + + expect(find('tableSortSelectBtn').at(0).text()).toBe('Recently updated'); // Still the same + }); + test('should navigate to page 2', async () => { let testBed: TestBed; @@ -350,12 +386,6 @@ describe('TableListView', () => { } ); - const getActions = (testBed: TestBed) => ({ - openSortSelect() { - testBed.find('tableSortSelectBtn').at(0).simulate('click'); - }, - }); - const hits: UserContentCommonSchema[] = [ { id: '123', diff --git a/packages/content-management/table_list/src/table_list_view.tsx b/packages/content-management/table_list/src/table_list_view.tsx index f397b8f2d999c..1612649f80bda 100644 --- a/packages/content-management/table_list/src/table_list_view.tsx +++ b/packages/content-management/table_list/src/table_list_view.tsx @@ -218,6 +218,17 @@ const urlStateSerializer = (updated: { return updatedQueryParams; }; +const tableColumnMetadata = { + title: { + field: 'attributes.title', + name: 'Name, description, tags', + }, + updatedAt: { + field: 'updatedAt', + name: 'Last updated', + }, +} as const; + function TableListViewComp({ tableListTitle, tableListDescription, @@ -437,7 +448,7 @@ function TableListViewComp({ const tableColumns = useMemo(() => { const columns: Array> = [ { - field: 'attributes.title', + field: tableColumnMetadata.title.field, name: titleColumnName ?? i18n.translate('contentManagement.tableList.mainColumnName', { @@ -471,7 +482,7 @@ function TableListViewComp({ if (hasUpdatedAtMetadata) { columns.push({ - field: 'updatedAt', + field: tableColumnMetadata.updatedAt.field, name: i18n.translate('contentManagement.tableList.lastUpdatedColumnTitle', { defaultMessage: 'Last updated', }), @@ -630,8 +641,17 @@ function TableListViewComp({ } = {}; if (criteria.sort) { + // We need to serialise the field as the return either (1) the field _name_ (e.g. "Last updated") + // when changing the "Rows per page" select value or (2) the field _value_ (e.g. "updatedAt") when clicking the column title + let fieldSerialized: unknown = criteria.sort.field; + if (fieldSerialized === tableColumnMetadata.title.name) { + fieldSerialized = tableColumnMetadata.title.field; + } else if (fieldSerialized === tableColumnMetadata.updatedAt.name) { + fieldSerialized = tableColumnMetadata.updatedAt.field; + } + data.sort = { - field: criteria.sort.field as SortColumnField, + field: fieldSerialized as SortColumnField, direction: criteria.sort.direction, }; } From 6259bb909834a83722f792dea9fe5c27c2b44dc9 Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Mon, 17 Apr 2023 12:03:49 -0400 Subject: [PATCH 17/17] skip failing test suite (#154913) --- x-pack/test/accessibility/apps/maps.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/accessibility/apps/maps.ts b/x-pack/test/accessibility/apps/maps.ts index 0f0054684c4d4..5a315260a0b2d 100644 --- a/x-pack/test/accessibility/apps/maps.ts +++ b/x-pack/test/accessibility/apps/maps.ts @@ -14,7 +14,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const inspector = getService('inspector'); const PageObjects = getPageObjects(['common', 'settings', 'header', 'home', 'maps']); - describe('Maps app Accessibility', () => { + // Failing: See https://github.com/elastic/kibana/issues/154913 + describe.skip('Maps app Accessibility', () => { before(async () => { await PageObjects.common.navigateToUrl('home', '/tutorial_directory/sampleData', { useActualUrl: true,