Skip to content

Commit

Permalink
Merge branch 'main' into feature/FIPS_ESLint_Rule
Browse files Browse the repository at this point in the history
  • Loading branch information
elasticmachine authored Sep 25, 2024
2 parents 2f55ed9 + 66f2027 commit 6e214de
Show file tree
Hide file tree
Showing 37 changed files with 1,110 additions and 66 deletions.
54 changes: 54 additions & 0 deletions oas_docs/output/kibana.serverless.staging.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15392,6 +15392,39 @@ paths:
tags:
- Security Timeline API
- access:securitySolution
/api/risk_score/engine/dangerously_delete_data:
delete:
description: >-
Cleaning up the the Risk Engine by removing the indices, mapping and
transforms
operationId: CleanUpRiskEngine
responses:
'200':
content:
application/json; Elastic-Api-Version=2023-10-31:
schema:
type: object
properties:
cleanup_successful:
type: boolean
description: Successful response
'400':
content:
application/json; Elastic-Api-Version=2023-10-31:
schema:
$ref: >-
#/components/schemas/Security_Entity_Analytics_API_TaskManagerUnavailableResponse
description: Task manager is unavailable
default:
content:
application/json; Elastic-Api-Version=2023-10-31:
schema:
$ref: >-
#/components/schemas/Security_Entity_Analytics_API_CleanUpRiskEngineErrorResponse
description: Unexpected error
summary: Cleanup the Risk Engine
tags:
- Security Entity Analytics API
/api/risk_score/engine/schedule_now:
post:
description: >-
Expand Down Expand Up @@ -29750,6 +29783,27 @@ components:
required:
- id_value
- id_field
Security_Entity_Analytics_API_CleanUpRiskEngineErrorResponse:
type: object
properties:
cleanup_successful:
example: false
type: boolean
errors:
items:
type: object
properties:
error:
type: string
seq:
type: integer
required:
- seq
- error
type: array
required:
- cleanup_successful
- errors
Security_Entity_Analytics_API_CreateAssetCriticalityRecord:
allOf:
- $ref: >-
Expand Down
54 changes: 54 additions & 0 deletions oas_docs/output/kibana.staging.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18822,6 +18822,39 @@ paths:
tags:
- Security Timeline API
- access:securitySolution
/api/risk_score/engine/dangerously_delete_data:
delete:
description: >-
Cleaning up the the Risk Engine by removing the indices, mapping and
transforms
operationId: CleanUpRiskEngine
responses:
'200':
content:
application/json; Elastic-Api-Version=2023-10-31:
schema:
type: object
properties:
cleanup_successful:
type: boolean
description: Successful response
'400':
content:
application/json; Elastic-Api-Version=2023-10-31:
schema:
$ref: >-
#/components/schemas/Security_Entity_Analytics_API_TaskManagerUnavailableResponse
description: Task manager is unavailable
default:
content:
application/json; Elastic-Api-Version=2023-10-31:
schema:
$ref: >-
#/components/schemas/Security_Entity_Analytics_API_CleanUpRiskEngineErrorResponse
description: Unexpected error
summary: Cleanup the Risk Engine
tags:
- Security Entity Analytics API
/api/risk_score/engine/schedule_now:
post:
description: >-
Expand Down Expand Up @@ -37759,6 +37792,27 @@ components:
required:
- id_value
- id_field
Security_Entity_Analytics_API_CleanUpRiskEngineErrorResponse:
type: object
properties:
cleanup_successful:
example: false
type: boolean
errors:
items:
type: object
properties:
error:
type: string
seq:
type: integer
required:
- seq
- error
type: array
required:
- cleanup_successful
- errors
Security_Entity_Analytics_API_CreateAssetCriticalityRecord:
allOf:
- $ref: >-
Expand Down
5 changes: 4 additions & 1 deletion packages/kbn-test/src/es/test_es_cluster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,10 @@ export function createTestEsCluster<
`transport.port=${transportPort ?? esTestConfig.getTransportPort()}`,
// For multi-node clusters, we make all nodes master-eligible by default.
...(nodes.length > 1
? ['discovery.type=zen', `cluster.initial_master_nodes=${nodes.map((n) => n.name).join(',')}`]
? [
'discovery.type=multi-node',
`cluster.initial_master_nodes=${nodes.map((n) => n.name).join(',')}`,
]
: ['discovery.type=single-node']),
];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export const FilterInBtn = ({
}) => {
const context = useContext(UnifiedDataTableContext);
const filteringDisabled =
isPlainRecord && Array.isArray(context.rows[rowIndex]?.flattened[columnId]);
isPlainRecord && Array.isArray(context.getRowByIndex(rowIndex)?.flattened[columnId]);
const buttonTitle = i18n.translate('unifiedDataTable.grid.filterForAria', {
defaultMessage: 'Filter for this {value}',
values: { value: columnId },
Expand Down Expand Up @@ -85,7 +85,7 @@ export const FilterOutBtn = ({
}) => {
const context = useContext(UnifiedDataTableContext);
const filteringDisabled =
isPlainRecord && Array.isArray(context.rows[rowIndex]?.flattened[columnId]);
isPlainRecord && Array.isArray(context.getRowByIndex(rowIndex)?.flattened[columnId]);
const buttonTitle = i18n.translate('unifiedDataTable.grid.filterOutAria', {
defaultMessage: 'Filter out this {value}',
values: { value: columnId },
Expand Down
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,7 @@ function createRoot({ logFileName, hosts }: RootConfig) {
});
}

// Failing 9.0 version update: https://github.com/elastic/kibana/issues/192624
describe.skip('migration v2', () => {
describe('migration v2', () => {
let esServer: TestElasticsearchUtils;
let root: Root;
const migratedIndexAlias = `.kibana_${pkg.version}`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ describe('createFieldMapping', () => {
type: keyword
`;

expect(createSync).toHaveBeenCalledWith(`${dataStreamPath}/base-fields.yml`, mockedTemplate);
expect(createSync).toHaveBeenCalledWith(
`${dataStreamPath}/fields/base-fields.yml`,
mockedTemplate
);
expect(createSync).toHaveBeenCalledWith(`${dataStreamPath}/fields/fields.yml`, expectedFields);
});

Expand All @@ -56,7 +59,10 @@ describe('createFieldMapping', () => {
const expectedFields = `[]
`;

expect(createSync).toHaveBeenCalledWith(`${dataStreamPath}/base-fields.yml`, mockedTemplate);
expect(createSync).toHaveBeenCalledWith(
`${dataStreamPath}/fields/base-fields.yml`,
mockedTemplate
);
expect(createSync).toHaveBeenCalledWith(`${dataStreamPath}/fields/fields.yml`, expectedFields);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@ export function createFieldMapping(
specificDataStreamDir: string,
docs: object[]
): void {
createBaseFields(specificDataStreamDir, packageName, dataStreamName);
createCustomFields(specificDataStreamDir, docs);
const dataStreamFieldsDir = `${specificDataStreamDir}/fields`;
createBaseFields(dataStreamFieldsDir, packageName, dataStreamName);
createCustomFields(dataStreamFieldsDir, docs);
}

function createBaseFields(
specificDataStreamDir: string,
dataStreamFieldsDir: string,
packageName: string,
dataStreamName: string
): void {
Expand All @@ -30,11 +31,11 @@ function createBaseFields(
dataset: datasetName,
});

createSync(`${specificDataStreamDir}/base-fields.yml`, baseFields);
createSync(`${dataStreamFieldsDir}/base-fields.yml`, baseFields);
}

function createCustomFields(specificDataStreamDir: string, pipelineResults: object[]): void {
function createCustomFields(dataStreamFieldsDir: string, pipelineResults: object[]): void {
const mergedResults = mergeSamples(pipelineResults);
const fieldKeys = generateFields(mergedResults);
createSync(`${specificDataStreamDir}/fields/fields.yml`, fieldKeys);
createSync(`${dataStreamFieldsDir}/fields.yml`, fieldKeys);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import React from 'react';
import { render, fireEvent, screen } from '@testing-library/react';
import { BadgeFilterWithPopover } from '.';
import { EuiThemeProvider, copyToClipboard } from '@elastic/eui';
import { ENTITY_TYPE } from '../../../common/es_fields/entities';

jest.mock('@elastic/eui', () => ({
...jest.requireActual('@elastic/eui'),
copyToClipboard: jest.fn(),
}));

describe('BadgeFilterWithPopover', () => {
const mockOnFilter = jest.fn();
const field = ENTITY_TYPE;
const value = 'host';
const label = 'Host';
const popoverContentDataTestId = 'inventoryBadgeFilterWithPopoverContent';
const popoverContentTitleTestId = 'inventoryBadgeFilterWithPopoverTitle';

beforeEach(() => {
jest.clearAllMocks();
});

it('renders the badge with the correct label', () => {
render(
<BadgeFilterWithPopover field={field} value={value} onFilter={mockOnFilter} label={label} />,
{ wrapper: EuiThemeProvider }
);
expect(screen.queryByText(label)).toBeInTheDocument();
expect(screen.getByText(label).textContent).toBe(label);
});

it('opens the popover when the badge is clicked', () => {
render(<BadgeFilterWithPopover field={field} value={value} onFilter={mockOnFilter} />);
expect(screen.queryByTestId(popoverContentDataTestId)).not.toBeInTheDocument();
fireEvent.click(screen.getByText(value));
expect(screen.queryByTestId(popoverContentDataTestId)).toBeInTheDocument();
expect(screen.queryByTestId(popoverContentTitleTestId)?.textContent).toBe(`${field}:${value}`);
});

it('calls onFilter when the "Filter for" button is clicked', () => {
render(<BadgeFilterWithPopover field={field} value={value} onFilter={mockOnFilter} />);
fireEvent.click(screen.getByText(value));
fireEvent.click(screen.getByTestId('inventoryBadgeFilterWithPopoverFilterForButton'));
expect(mockOnFilter).toHaveBeenCalled();
});

it('copies value to clipboard when the "Copy value" button is clicked', () => {
render(<BadgeFilterWithPopover field={field} value={value} onFilter={mockOnFilter} />);
fireEvent.click(screen.getByText(value));
fireEvent.click(screen.getByTestId('inventoryBadgeFilterWithPopoverCopyValueButton'));
expect(copyToClipboard).toHaveBeenCalledWith(value);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
* 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 {
EuiBadge,
EuiButtonEmpty,
EuiFlexGrid,
EuiFlexGroup,
EuiFlexItem,
EuiPopover,
EuiPopoverFooter,
copyToClipboard,
useEuiTheme,
} from '@elastic/eui';
import { css } from '@emotion/react';
import { i18n } from '@kbn/i18n';
import React, { useState } from 'react';

interface Props {
field: string;
value: string;
label?: string;
onFilter: () => void;
}

export function BadgeFilterWithPopover({ field, value, onFilter, label }: Props) {
const [isOpen, setIsOpen] = useState(false);
const theme = useEuiTheme();

return (
<EuiPopover
button={
<EuiBadge
data-test-subj="inventoryBadgeFilterWithPopoverButton"
color="hollow"
onClick={() => setIsOpen((state) => !state)}
onClickAriaLabel={i18n.translate(
'xpack.inventory.badgeFilterWithPopover.openPopoverBadgeLabel',
{ defaultMessage: 'Open popover' }
)}
>
{label || value}
</EuiBadge>
}
isOpen={isOpen}
closePopover={() => setIsOpen(false)}
>
<span data-test-subj="inventoryBadgeFilterWithPopoverTitle">
<EuiFlexGroup
data-test-subj="inventoryBadgeFilterWithPopoverContent"
responsive={false}
gutterSize="xs"
css={css`
font-family: ${theme.euiTheme.font.familyCode};
`}
>
<EuiFlexItem grow={false}>
<span
css={css`
font-weight: bold;
`}
>
{field}:
</span>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<span className="eui-textBreakWord">{value}</span>
</EuiFlexItem>
</EuiFlexGroup>
</span>
<EuiPopoverFooter>
<EuiFlexGrid responsive={false} columns={2}>
<EuiFlexItem>
<EuiButtonEmpty
data-test-subj="inventoryBadgeFilterWithPopoverFilterForButton"
iconType="plusInCircle"
onClick={onFilter}
>
{i18n.translate('xpack.inventory.badgeFilterWithPopover.filterForButtonEmptyLabel', {
defaultMessage: 'Filter for',
})}
</EuiButtonEmpty>
</EuiFlexItem>
<EuiFlexItem>
<EuiButtonEmpty
data-test-subj="inventoryBadgeFilterWithPopoverCopyValueButton"
iconType="copyClipboard"
onClick={() => copyToClipboard(value)}
>
{i18n.translate('xpack.inventory.badgeFilterWithPopover.copyValueButtonEmptyLabel', {
defaultMessage: 'Copy value',
})}
</EuiButtonEmpty>
</EuiFlexItem>
</EuiFlexGrid>
</EuiPopoverFooter>
</EuiPopover>
);
}
Loading

0 comments on commit 6e214de

Please sign in to comment.