diff --git a/test/functional/apps/dashboard/embeddable_rendering.js b/test/functional/apps/dashboard/embeddable_rendering.js
index 9ba0c07c744fc..c00f01d060f4a 100644
--- a/test/functional/apps/dashboard/embeddable_rendering.js
+++ b/test/functional/apps/dashboard/embeddable_rendering.js
@@ -98,8 +98,7 @@ export default function ({ getService, getPageObjects }) {
await dashboardExpect.vegaTextsDoNotExist(['5,000']);
};
- // FLAKY: https://github.com/elastic/kibana/issues/46305
- describe.skip('dashboard embeddable rendering', function describeIndexTests() {
+ describe('dashboard embeddable rendering', function describeIndexTests() {
before(async () => {
await esArchiver.load('dashboard/current/kibana');
await kibanaServer.uiSettings.replace({
diff --git a/x-pack/plugins/canvas/public/state/selectors/workpad.ts b/x-pack/plugins/canvas/public/state/selectors/workpad.ts
index 1d7ea05daaa61..a677bcaf29e61 100644
--- a/x-pack/plugins/canvas/public/state/selectors/workpad.ts
+++ b/x-pack/plugins/canvas/public/state/selectors/workpad.ts
@@ -497,7 +497,7 @@ export function getRenderedWorkpad(state: State) {
const workpad = getWorkpad(state);
// eslint-disable-next-line no-unused-vars
- const { pages, ...rest } = workpad;
+ const { pages, variables, ...rest } = workpad;
return {
pages: renderedPages,
diff --git a/x-pack/plugins/canvas/shareable_runtime/README.md b/x-pack/plugins/canvas/shareable_runtime/README.md
index 8fdeb6ca6258e..3839e7c4ecb3f 100644
--- a/x-pack/plugins/canvas/shareable_runtime/README.md
+++ b/x-pack/plugins/canvas/shareable_runtime/README.md
@@ -207,7 +207,7 @@ There are a number of options for the build script:
### Prerequisite
-Before testing or running this PR locally, you **must** run `node scripts/runtime` from `/canvas` _after_ `yarn kbn bootstrap` and _before_ starting Kibana. It is only built automatically when Kibana is built to avoid slowing down other development activities.
+Before testing or running this PR locally, you **must** run `node scripts/shareable_runtime` from `/canvas` _after_ `yarn kbn bootstrap` and _before_ starting Kibana. It is only built automatically when Kibana is built to avoid slowing down other development activities.
### Webpack Dev Server
diff --git a/x-pack/plugins/canvas/shareable_runtime/webpack.config.js b/x-pack/plugins/canvas/shareable_runtime/webpack.config.js
index 1a5a21985ba72..93dc3dbccd549 100644
--- a/x-pack/plugins/canvas/shareable_runtime/webpack.config.js
+++ b/x-pack/plugins/canvas/shareable_runtime/webpack.config.js
@@ -55,7 +55,6 @@ module.exports = {
options: {
presets: [require.resolve('@kbn/babel-preset/webpack_preset')],
},
- sideEffects: false,
},
{
test: /\.tsx?$/,
@@ -92,6 +91,7 @@ module.exports = {
},
},
],
+ sideEffects: true,
},
{
test: /\.module\.s(a|c)ss$/,
diff --git a/x-pack/plugins/ingest_manager/common/openapi/spec_oas3.json b/x-pack/plugins/ingest_manager/common/openapi/spec_oas3.json
index 4b10dab5d1ae5..e16edac5ddb7a 100644
--- a/x-pack/plugins/ingest_manager/common/openapi/spec_oas3.json
+++ b/x-pack/plugins/ingest_manager/common/openapi/spec_oas3.json
@@ -4203,6 +4203,7 @@
"FAILED",
"STOPPING",
"STOPPED",
+ "DEGRADED",
"DATA_DUMP",
"ACKNOWLEDGED",
"UNKNOWN"
diff --git a/x-pack/plugins/ingest_manager/common/types/models/agent.ts b/x-pack/plugins/ingest_manager/common/types/models/agent.ts
index d3789c58a2c22..f31d33e73c76f 100644
--- a/x-pack/plugins/ingest_manager/common/types/models/agent.ts
+++ b/x-pack/plugins/ingest_manager/common/types/models/agent.ts
@@ -53,6 +53,7 @@ export interface NewAgentEvent {
| 'FAILED'
| 'STOPPING'
| 'STOPPED'
+ | 'DEGRADED'
// Action results
| 'DATA_DUMP'
// Actions
diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_package_config_page/step_define_package_config.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_package_config_page/step_define_package_config.tsx
index a04d023ebcc48..f487b4e5235e7 100644
--- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_package_config_page/step_define_package_config.tsx
+++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_package_config_page/step_define_package_config.tsx
@@ -47,9 +47,17 @@ export const StepDefinePackageConfig: React.FunctionComponent<{
.sort();
updatePackageConfig({
- name: `${packageInfo.name}-${
- dsWithMatchingNames.length ? dsWithMatchingNames[dsWithMatchingNames.length - 1] + 1 : 1
- }`,
+ name:
+ // For Endpoint packages, the user must fill in the name, thus we don't attempt to generate
+ // a default one here.
+ // FIXME: Improve package configs name uniqueness - https://github.com/elastic/kibana/issues/72948
+ packageInfo.name !== 'endpoint'
+ ? `${packageInfo.name}-${
+ dsWithMatchingNames.length
+ ? dsWithMatchingNames[dsWithMatchingNames.length - 1] + 1
+ : 1
+ }`
+ : '',
package: {
name: packageInfo.name,
title: packageInfo.title,
diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_details_page/components/type_labels.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_details_page/components/type_labels.tsx
index e9cb59be37892..43e4d696ded66 100644
--- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_details_page/components/type_labels.tsx
+++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_details_page/components/type_labels.tsx
@@ -95,6 +95,14 @@ export const SUBTYPE_LABEL: { [key in AgentEvent['subtype']]: JSX.Element } = {
/>
),
+ DEGRADED: (
+
+
+
+ ),
DATA_DUMP: (
fetchOrCreateListError || exceptionItemsToAdd.length === 0,
+ const isSubmitButtonDisabled = useMemo(
+ () => fetchOrCreateListError || exceptionItemsToAdd.every((item) => item.entries.length === 0),
[fetchOrCreateListError, exceptionItemsToAdd]
);
@@ -377,7 +377,7 @@ export const AddExceptionModal = memo(function AddExceptionModal({
{i18n.ADD_EXCEPTION}
diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_entry_item.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_entry_item.test.tsx
index b845848bd14d8..3dcc3eb5a8329 100644
--- a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_entry_item.test.tsx
+++ b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_entry_item.test.tsx
@@ -213,7 +213,7 @@ describe('BuilderEntryItem', () => {
title: 'logstash-*',
fields,
}}
- showLabel={false}
+ showLabel={true}
listType="detection"
addNested={false}
onChange={jest.fn()}
@@ -245,7 +245,7 @@ describe('BuilderEntryItem', () => {
title: 'logstash-*',
fields,
}}
- showLabel={false}
+ showLabel={true}
listType="detection"
addNested={false}
onChange={jest.fn()}
diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_entry_item.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_entry_item.tsx
index 736e88ee9fe06..dcc8a0e4fb1ba 100644
--- a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_entry_item.tsx
+++ b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_entry_item.tsx
@@ -27,6 +27,7 @@ import {
getEntryOnMatchAnyChange,
getEntryOnListChange,
} from './helpers';
+import { EXCEPTION_OPERATORS_ONLY_LISTS } from '../../autocomplete/operators';
interface EntryItemProps {
entry: FormattedBuilderEntry;
@@ -35,6 +36,7 @@ interface EntryItemProps {
listType: ExceptionListType;
addNested: boolean;
onChange: (arg: BuilderEntry, i: number) => void;
+ onlyShowListOperators?: boolean;
}
export const BuilderEntryItem: React.FC = ({
@@ -44,6 +46,7 @@ export const BuilderEntryItem: React.FC = ({
addNested,
showLabel,
onChange,
+ onlyShowListOperators = false,
}): JSX.Element => {
const handleFieldChange = useCallback(
([newField]: IFieldType[]): void => {
@@ -124,11 +127,14 @@ export const BuilderEntryItem: React.FC = ({
);
const renderOperatorInput = (isFirst: boolean): JSX.Element => {
- const operatorOptions = getOperatorOptions(
- entry,
- listType,
- entry.field != null && entry.field.type === 'boolean'
- );
+ const operatorOptions = onlyShowListOperators
+ ? EXCEPTION_OPERATORS_ONLY_LISTS
+ : getOperatorOptions(
+ entry,
+ listType,
+ entry.field != null && entry.field.type === 'boolean',
+ isFirst
+ );
const comboBox = (
void;
onChangeExceptionItem: (item: ExceptionsBuilderExceptionItem, index: number) => void;
+ onlyShowListOperators?: boolean;
}
export const ExceptionListItemComponent = React.memo(
@@ -58,6 +59,7 @@ export const ExceptionListItemComponent = React.memo(
andLogicIncluded,
onDeleteExceptionItem,
onChangeExceptionItem,
+ onlyShowListOperators = false,
}) => {
const handleEntryChange = useCallback(
(entry: BuilderEntry, entryIndex: number): void => {
@@ -169,6 +171,7 @@ export const ExceptionListItemComponent = React.memo(
exceptionItemIndex === 0 && index === 0 && item.nested !== 'child'
}
onChange={handleEntryChange}
+ onlyShowListOperators={onlyShowListOperators}
/>
{getDeleteButton(
diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/helpers.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/helpers.test.tsx
index 8b74d44f29a18..17c94adf42648 100644
--- a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/helpers.test.tsx
+++ b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/helpers.test.tsx
@@ -14,32 +14,33 @@ import { getEntryExistsMock } from '../../../../../../lists/common/schemas/types
import { getExceptionListItemSchemaMock } from '../../../../../../lists/common/schemas/response/exception_list_item_schema.mock';
import { getListResponseMock } from '../../../../../../lists/common/schemas/response/list_schema.mock';
import {
- isOperator,
- isOneOfOperator,
- isNotOperator,
- isNotOneOfOperator,
- existsOperator,
doesNotExistOperator,
- isInListOperator,
EXCEPTION_OPERATORS,
+ EXCEPTION_OPERATORS_SANS_LISTS,
+ existsOperator,
+ isInListOperator,
+ isNotOneOfOperator,
+ isNotOperator,
+ isOneOfOperator,
+ isOperator,
} from '../../autocomplete/operators';
-import { FormattedBuilderEntry, BuilderEntry, ExceptionsBuilderExceptionItem } from '../types';
-import { IIndexPattern, IFieldType } from '../../../../../../../../src/plugins/data/common';
-import { EntryNested, Entry } from '../../../../lists_plugin_deps';
+import { BuilderEntry, ExceptionsBuilderExceptionItem, FormattedBuilderEntry } from '../types';
+import { IFieldType, IIndexPattern } from '../../../../../../../../src/plugins/data/common';
+import { Entry, EntryNested } from '../../../../lists_plugin_deps';
import {
- getFilteredIndexPatterns,
- getFormattedBuilderEntry,
- isEntryNested,
- getFormattedBuilderEntries,
- getUpdatedEntriesOnDelete,
getEntryFromOperator,
- getOperatorOptions,
getEntryOnFieldChange,
- getEntryOnOperatorChange,
- getEntryOnMatchChange,
- getEntryOnMatchAnyChange,
getEntryOnListChange,
+ getEntryOnMatchAnyChange,
+ getEntryOnMatchChange,
+ getEntryOnOperatorChange,
+ getFilteredIndexPatterns,
+ getFormattedBuilderEntries,
+ getFormattedBuilderEntry,
+ getOperatorOptions,
+ getUpdatedEntriesOnDelete,
+ isEntryNested,
} from './helpers';
import { OperatorOption } from '../../autocomplete/types';
@@ -672,6 +673,18 @@ describe('Exception builder helpers', () => {
const expected: OperatorOption[] = [isOperator, existsOperator];
expect(output).toEqual(expected);
});
+
+ test('it returns list operators if specified to', () => {
+ const payloadItem: FormattedBuilderEntry = getMockBuilderEntry();
+ const output = getOperatorOptions(payloadItem, 'detection', false, true);
+ expect(output).toEqual(EXCEPTION_OPERATORS);
+ });
+
+ test('it does not return list operators if specified not to', () => {
+ const payloadItem: FormattedBuilderEntry = getMockBuilderEntry();
+ const output = getOperatorOptions(payloadItem, 'detection', false, false);
+ expect(output).toEqual(EXCEPTION_OPERATORS_SANS_LISTS);
+ });
});
describe('#getEntryOnFieldChange', () => {
diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/helpers.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/helpers.tsx
index 2fe2c68941ae6..93bae091885c1 100644
--- a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/helpers.tsx
+++ b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/helpers.tsx
@@ -22,6 +22,7 @@ import {
existsOperator,
isOneOfOperator,
EXCEPTION_OPERATORS,
+ EXCEPTION_OPERATORS_SANS_LISTS,
} from '../../autocomplete/operators';
import { OperatorOption } from '../../autocomplete/types';
import {
@@ -40,7 +41,6 @@ import { getEntryValue, getExceptionOperatorSelect } from '../helpers';
*
* @param patterns IIndexPattern containing available fields on rule index
* @param item exception item entry
- * @param addNested boolean noting whether or not UI is currently
* set to add a nested field
*/
export const getFilteredIndexPatterns = (
@@ -295,12 +295,14 @@ export const getEntryFromOperator = (
*
* @param item
* @param listType
- *
+ * @param isBoolean
+ * @param includeValueListOperators whether or not to include the 'is in list' and 'is not in list' operators
*/
export const getOperatorOptions = (
item: FormattedBuilderEntry,
listType: ExceptionListType,
- isBoolean: boolean
+ isBoolean: boolean,
+ includeValueListOperators = true
): OperatorOption[] => {
if (item.nested === 'parent' || item.field == null) {
return [isOperator];
@@ -309,7 +311,11 @@ export const getOperatorOptions = (
} else if (item.nested != null && listType === 'detection') {
return isBoolean ? [isOperator, existsOperator] : [isOperator, isOneOfOperator, existsOperator];
} else {
- return isBoolean ? [isOperator, existsOperator] : EXCEPTION_OPERATORS;
+ return isBoolean
+ ? [isOperator, existsOperator]
+ : includeValueListOperators
+ ? EXCEPTION_OPERATORS
+ : EXCEPTION_OPERATORS_SANS_LISTS;
}
};
@@ -547,3 +553,6 @@ export const getDefaultNestedEmptyEntry = (): EmptyNestedEntry => ({
type: OperatorTypeEnum.NESTED,
entries: [],
});
+
+export const containsValueListEntry = (items: ExceptionsBuilderExceptionItem[]): boolean =>
+ items.some((item) => item.entries.some((entry) => entry.type === OperatorTypeEnum.LIST));
diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/index.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/index.tsx
index 141429f152790..1ec49425ce8fd 100644
--- a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/index.tsx
+++ b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/index.tsx
@@ -24,7 +24,11 @@ import { BuilderButtonOptions } from './builder_button_options';
import { getNewExceptionItem, filterExceptionItems } from '../helpers';
import { ExceptionsBuilderExceptionItem, CreateExceptionListItemBuilderSchema } from '../types';
import { State, exceptionsBuilderReducer } from './reducer';
-import { getDefaultEmptyEntry, getDefaultNestedEmptyEntry } from './helpers';
+import {
+ containsValueListEntry,
+ getDefaultEmptyEntry,
+ getDefaultNestedEmptyEntry,
+} from './helpers';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import exceptionableFields from '../exceptionable_fields.json';
@@ -44,6 +48,7 @@ const MyButtonsContainer = styled(EuiFlexItem)`
const initialState: State = {
disableAnd: false,
+ disableNested: false,
disableOr: false,
andLogicIncluded: false,
addNested: false,
@@ -82,12 +87,21 @@ export const ExceptionBuilder = ({
onChange,
}: ExceptionBuilderProps) => {
const [
- { exceptions, exceptionsToDelete, andLogicIncluded, disableAnd, disableOr, addNested },
+ {
+ exceptions,
+ exceptionsToDelete,
+ andLogicIncluded,
+ disableAnd,
+ disableNested,
+ disableOr,
+ addNested,
+ },
dispatch,
] = useReducer(exceptionsBuilderReducer(), {
...initialState,
disableAnd: isAndDisabled,
disableOr: isOrDisabled,
+ disableNested: isNestedDisabled,
});
const setUpdateExceptions = useCallback(
@@ -362,6 +376,7 @@ export const ExceptionBuilder = ({
isOnlyItem={exceptions.length === 1}
onDeleteExceptionItem={handleDeleteExceptionItem}
onChangeExceptionItem={handleExceptionItemChange}
+ onlyShowListOperators={containsValueListEntry(exceptions)}
/>
@@ -379,7 +394,7 @@ export const ExceptionBuilder = ({
(state: State, action: Action): St
const isAndDisabled =
lastEntry != null && lastEntry.type === 'nested' && lastEntry.entries.length === 0;
const isOrDisabled = lastEntry != null && lastEntry.type === 'nested';
+ const containsValueList = action.exceptions.some(
+ ({ entries }) => entries.filter(({ type }) => type === OperatorTypeEnum.LIST).length > 0
+ );
return {
...state,
@@ -67,6 +71,7 @@ export const exceptionsBuilderReducer = () => (state: State, action: Action): St
addNested: isAddNested,
disableAnd: isAndDisabled,
disableOr: isOrDisabled,
+ disableNested: containsValueList,
};
}
case 'setDefault': {
diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/edit_exception_modal/index.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/edit_exception_modal/index.tsx
index 4ad077edf66ff..47c3498cb6ab4 100644
--- a/x-pack/plugins/security_solution/public/common/components/exceptions/edit_exception_modal/index.tsx
+++ b/x-pack/plugins/security_solution/public/common/components/exceptions/edit_exception_modal/index.tsx
@@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import React, { memo, useState, useCallback, useEffect } from 'react';
+import React, { memo, useState, useCallback, useEffect, useMemo } from 'react';
import styled, { css } from 'styled-components';
import {
EuiModal,
@@ -146,6 +146,11 @@ export const EditExceptionModal = memo(function EditExceptionModal({
}
}, [shouldDisableBulkClose]);
+ const isSubmitButtonDisabled = useMemo(
+ () => exceptionItemsToAdd.every((item) => item.entries.length === 0),
+ [exceptionItemsToAdd]
+ );
+
const handleBuilderOnChange = useCallback(
({
exceptionItems,
@@ -261,7 +266,12 @@ export const EditExceptionModal = memo(function EditExceptionModal({
{i18n.CANCEL}
-
+
{i18n.EDIT_EXCEPTION_SAVE_BUTTON}
diff --git a/x-pack/test/security_solution_endpoint/apps/endpoint/policy_list.ts b/x-pack/test/security_solution_endpoint/apps/endpoint/policy_list.ts
index a4b3a51c49513..0c5e15ed4104c 100644
--- a/x-pack/test/security_solution_endpoint/apps/endpoint/policy_list.ts
+++ b/x-pack/test/security_solution_endpoint/apps/endpoint/policy_list.ts
@@ -131,6 +131,11 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
expect(endpointConfig).not.to.be(undefined);
});
+ it('should have empty value for package configuration name', async () => {
+ await pageObjects.ingestManagerCreatePackageConfig.selectAgentConfig();
+ expect(await pageObjects.ingestManagerCreatePackageConfig.getPackageConfigName()).to.be('');
+ });
+
it('should redirect user back to Policy List after a successful save', async () => {
const newPolicyName = `endpoint policy ${Date.now()}`;
await pageObjects.ingestManagerCreatePackageConfig.selectAgentConfig();
diff --git a/x-pack/test/security_solution_endpoint/page_objects/ingest_manager_create_package_config_page.ts b/x-pack/test/security_solution_endpoint/page_objects/ingest_manager_create_package_config_page.ts
index dd3fc637a3d6c..dfdb528b7362c 100644
--- a/x-pack/test/security_solution_endpoint/page_objects/ingest_manager_create_package_config_page.ts
+++ b/x-pack/test/security_solution_endpoint/page_objects/ingest_manager_create_package_config_page.ts
@@ -62,6 +62,13 @@ export function IngestManagerCreatePackageConfig({
}
},
+ /**
+ * Returns the package config name currently populated on the input field
+ */
+ async getPackageConfigName() {
+ return testSubjects.getAttribute('packageConfigNameInput', 'value');
+ },
+
/**
* Set the name of the package config on the input field
* @param name