mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[SecuritySolution][Endpoint][Response Actions] Remove scan feature flag and branch logic. (#190601)
This commit is contained in:
parent
dda6cd9d9e
commit
74ba0b4f54
17 changed files with 102 additions and 207 deletions
|
@ -673,11 +673,13 @@ export const getSecuritySubFeaturesMap = ({
|
|||
[SecuritySubFeatureId.processOperations, processOperationsSubFeature],
|
||||
[SecuritySubFeatureId.fileOperations, fileOperationsSubFeature],
|
||||
[SecuritySubFeatureId.executeAction, executeActionSubFeature],
|
||||
[SecuritySubFeatureId.scanAction, scanActionSubFeature],
|
||||
];
|
||||
|
||||
if (experimentalFeatures.responseActionScanEnabled) {
|
||||
securitySubFeaturesList.push([SecuritySubFeatureId.scanAction, scanActionSubFeature]);
|
||||
}
|
||||
// Use the following code to add feature based on feature flag
|
||||
// if (experimentalFeatures.featureFlagName) {
|
||||
// securitySubFeaturesList.push([SecuritySubFeatureId.featureId, featureSubFeature]);
|
||||
// }
|
||||
|
||||
const securitySubFeaturesMap = new Map<SecuritySubFeatureId, SubFeatureConfig>(
|
||||
securitySubFeaturesList
|
||||
|
|
|
@ -83,11 +83,6 @@ export const allowedExperimentalValues = Object.freeze({
|
|||
*/
|
||||
responseActionsCrowdstrikeManualHostIsolationEnabled: true,
|
||||
|
||||
/**
|
||||
* Enables scan response action on Endpoint
|
||||
*/
|
||||
responseActionScanEnabled: true,
|
||||
|
||||
/**
|
||||
* Enables new notes
|
||||
*/
|
||||
|
|
|
@ -58,7 +58,6 @@ describe('When using scan action from response actions console', () => {
|
|||
beforeEach(() => {
|
||||
mockedContext = createAppRootMockRenderer();
|
||||
|
||||
mockedContext.setExperimentalFlag({ responseActionScanEnabled: true });
|
||||
apiMocks = responseActionsHttpMocks(mockedContext.coreStart.http);
|
||||
endpointPrivileges = {
|
||||
...getEndpointAuthzInitialStateMock(),
|
||||
|
|
|
@ -164,7 +164,6 @@ export const getEndpointConsoleCommands = ({
|
|||
const featureFlags = ExperimentalFeaturesService.get();
|
||||
|
||||
const isUploadEnabled = featureFlags.responseActionUploadEnabled;
|
||||
const isScanEnabled = featureFlags.responseActionScanEnabled;
|
||||
|
||||
const doesEndpointSupportCommand = (commandName: ConsoleResponseActionCommands) => {
|
||||
// Agent capabilities is only validated for Endpoint agent types
|
||||
|
@ -486,43 +485,41 @@ export const getEndpointConsoleCommands = ({
|
|||
});
|
||||
}
|
||||
|
||||
if (isScanEnabled) {
|
||||
consoleCommands.push({
|
||||
name: 'scan',
|
||||
about: getCommandAboutInfo({
|
||||
aboutInfo: CONSOLE_COMMANDS.scan.about,
|
||||
isSupported: doesEndpointSupportCommand('scan'),
|
||||
}),
|
||||
RenderComponent: ScanActionResult,
|
||||
meta: {
|
||||
agentType,
|
||||
endpointId: endpointAgentId,
|
||||
capabilities: endpointCapabilities,
|
||||
privileges: endpointPrivileges,
|
||||
consoleCommands.push({
|
||||
name: 'scan',
|
||||
about: getCommandAboutInfo({
|
||||
aboutInfo: CONSOLE_COMMANDS.scan.about,
|
||||
isSupported: doesEndpointSupportCommand('scan'),
|
||||
}),
|
||||
RenderComponent: ScanActionResult,
|
||||
meta: {
|
||||
agentType,
|
||||
endpointId: endpointAgentId,
|
||||
capabilities: endpointCapabilities,
|
||||
privileges: endpointPrivileges,
|
||||
},
|
||||
exampleUsage: 'scan --path "/full/path/to/folder" --comment "Scan folder for malware"',
|
||||
exampleInstruction: ENTER_OR_ADD_COMMENT_ARG_INSTRUCTION,
|
||||
validate: capabilitiesAndPrivilegesValidator(agentType),
|
||||
mustHaveArgs: true,
|
||||
args: {
|
||||
path: {
|
||||
required: true,
|
||||
allowMultiples: false,
|
||||
mustHaveValue: 'non-empty-string',
|
||||
about: CONSOLE_COMMANDS.scan.args.path.about,
|
||||
},
|
||||
exampleUsage: 'scan --path "/full/path/to/folder" --comment "Scan folder for malware"',
|
||||
exampleInstruction: ENTER_OR_ADD_COMMENT_ARG_INSTRUCTION,
|
||||
validate: capabilitiesAndPrivilegesValidator(agentType),
|
||||
mustHaveArgs: true,
|
||||
args: {
|
||||
path: {
|
||||
required: true,
|
||||
allowMultiples: false,
|
||||
mustHaveValue: 'non-empty-string',
|
||||
about: CONSOLE_COMMANDS.scan.args.path.about,
|
||||
},
|
||||
...commandCommentArgument(),
|
||||
},
|
||||
helpGroupLabel: HELP_GROUPS.responseActions.label,
|
||||
helpGroupPosition: HELP_GROUPS.responseActions.position,
|
||||
helpCommandPosition: 8,
|
||||
helpDisabled: !doesEndpointSupportCommand('scan'),
|
||||
helpHidden: !getRbacControl({
|
||||
commandName: 'scan',
|
||||
privileges: endpointPrivileges,
|
||||
}),
|
||||
});
|
||||
}
|
||||
...commandCommentArgument(),
|
||||
},
|
||||
helpGroupLabel: HELP_GROUPS.responseActions.label,
|
||||
helpGroupPosition: HELP_GROUPS.responseActions.position,
|
||||
helpCommandPosition: 8,
|
||||
helpDisabled: !doesEndpointSupportCommand('scan'),
|
||||
helpHidden: !getRbacControl({
|
||||
commandName: 'scan',
|
||||
privileges: endpointPrivileges,
|
||||
}),
|
||||
});
|
||||
|
||||
switch (agentType) {
|
||||
case 'sentinel_one':
|
||||
|
|
|
@ -46,7 +46,6 @@ describe('When displaying Endpoint Response Actions', () => {
|
|||
beforeEach(() => {
|
||||
(ExperimentalFeaturesService.get as jest.Mock).mockReturnValue({
|
||||
responseActionUploadEnabled: true,
|
||||
responseActionScanEnabled: true,
|
||||
});
|
||||
commands = getEndpointConsoleCommands({
|
||||
agentType: 'endpoint',
|
||||
|
|
|
@ -334,11 +334,6 @@ export const useActionsLogFilter = ({
|
|||
return false;
|
||||
}
|
||||
|
||||
// `scan` - v8.15
|
||||
if (commandName === 'scan' && !featureFlags.responseActionScanEnabled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}).map((commandName) => ({
|
||||
key: commandName,
|
||||
|
|
|
@ -1491,7 +1491,6 @@ describe('Response actions history', () => {
|
|||
beforeEach(() => {
|
||||
featureFlags = {
|
||||
responseActionUploadEnabled: true,
|
||||
responseActionScanEnabled: false,
|
||||
};
|
||||
|
||||
mockedContext.setExperimentalFlag(featureFlags);
|
||||
|
@ -1511,37 +1510,7 @@ describe('Response actions history', () => {
|
|||
);
|
||||
});
|
||||
|
||||
it('should show a list of actions (without `scan`) when opened', () => {
|
||||
mockedContext.setExperimentalFlag({
|
||||
...featureFlags,
|
||||
responseActionScanEnabled: false,
|
||||
});
|
||||
render();
|
||||
const { getByTestId, getAllByTestId } = renderResult;
|
||||
|
||||
userEvent.click(getByTestId(`${testPrefix}-${filterPrefix}-popoverButton`));
|
||||
const filterList = getByTestId(`${testPrefix}-${filterPrefix}-popoverList`);
|
||||
expect(filterList).toBeTruthy();
|
||||
expect(getAllByTestId(`${filterPrefix}-option`).length).toEqual(
|
||||
RESPONSE_ACTION_API_COMMANDS_NAMES.length - 1
|
||||
);
|
||||
expect(getAllByTestId(`${filterPrefix}-option`).map((option) => option.textContent)).toEqual([
|
||||
'isolate. To check this option, press Enter.',
|
||||
'release. To check this option, press Enter.',
|
||||
'kill-process. To check this option, press Enter.',
|
||||
'suspend-process. To check this option, press Enter.',
|
||||
'processes. To check this option, press Enter.',
|
||||
'get-file. To check this option, press Enter.',
|
||||
'execute. To check this option, press Enter.',
|
||||
'upload. To check this option, press Enter.',
|
||||
]);
|
||||
});
|
||||
|
||||
it('should show a list of actions (with `scan`) when opened', () => {
|
||||
mockedContext.setExperimentalFlag({
|
||||
...featureFlags,
|
||||
responseActionScanEnabled: true,
|
||||
});
|
||||
render();
|
||||
const { getByTestId, getAllByTestId } = renderResult;
|
||||
|
||||
|
|
|
@ -25,11 +25,13 @@ describe(
|
|||
{
|
||||
env: {
|
||||
ftrConfig: {
|
||||
kbnServerArgs: [
|
||||
`--xpack.securitySolution.enableExperimental=${JSON.stringify([
|
||||
'responseActionScanEnabled',
|
||||
])}`,
|
||||
],
|
||||
// This is not needed for this test, but it's a good example of
|
||||
// how to enable experimental features in the Cypress tests.
|
||||
// kbnServerArgs: [
|
||||
// `--xpack.securitySolution.enableExperimental=${JSON.stringify([
|
||||
// 'featureFlagName',
|
||||
// ])}`,
|
||||
// ],
|
||||
},
|
||||
},
|
||||
tags: ['@ess', '@serverless', '@skipInServerlessMKI'],
|
||||
|
|
|
@ -18,11 +18,13 @@ describe(
|
|||
env: {
|
||||
ftrConfig: {
|
||||
productTypes: [{ product_line: 'security', product_tier: 'complete' }],
|
||||
kbnServerArgs: [
|
||||
`--xpack.securitySolution.enableExperimental=${JSON.stringify([
|
||||
'responseActionScanEnabled',
|
||||
])}`,
|
||||
],
|
||||
// This is not needed for this test, but it's a good example of
|
||||
// how to enable experimental features in the Cypress tests.
|
||||
// kbnServerArgs: [
|
||||
// `--xpack.securitySolution.enableExperimental=${JSON.stringify([
|
||||
// 'featureFlagName',
|
||||
// ])}`,
|
||||
// ],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -24,11 +24,13 @@ describe(
|
|||
{ product_line: 'security', product_tier: 'complete' },
|
||||
{ product_line: 'endpoint', product_tier: 'complete' },
|
||||
],
|
||||
kbnServerArgs: [
|
||||
`--xpack.securitySolution.enableExperimental=${JSON.stringify([
|
||||
'responseActionScanEnabled',
|
||||
])}`,
|
||||
],
|
||||
// This is not needed for this test, but it's a good example of
|
||||
// how to enable experimental features in the Cypress tests.
|
||||
// kbnServerArgs: [
|
||||
// `--xpack.securitySolution.enableExperimental=${JSON.stringify([
|
||||
// 'featureFlagName',
|
||||
// ])}`,
|
||||
// ],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -18,11 +18,13 @@ describe(
|
|||
env: {
|
||||
ftrConfig: {
|
||||
productTypes: [{ product_line: 'security', product_tier: 'essentials' }],
|
||||
kbnServerArgs: [
|
||||
`--xpack.securitySolution.enableExperimental=${JSON.stringify([
|
||||
'responseActionScanEnabled',
|
||||
])}`,
|
||||
],
|
||||
// This is not needed for this test, but it's a good example of
|
||||
// how to enable experimental features in the Cypress tests.
|
||||
// kbnServerArgs: [
|
||||
// `--xpack.securitySolution.enableExperimental=${JSON.stringify([
|
||||
// 'featureFlagName',
|
||||
// ])}`,
|
||||
// ],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -24,11 +24,13 @@ describe(
|
|||
{ product_line: 'security', product_tier: 'essentials' },
|
||||
{ product_line: 'endpoint', product_tier: 'essentials' },
|
||||
],
|
||||
kbnServerArgs: [
|
||||
`--xpack.securitySolution.enableExperimental=${JSON.stringify([
|
||||
'responseActionScanEnabled',
|
||||
])}`,
|
||||
],
|
||||
// This is not needed for this test, but it's a good example of
|
||||
// how to enable experimental features in the Cypress tests.
|
||||
// kbnServerArgs: [
|
||||
// `--xpack.securitySolution.enableExperimental=${JSON.stringify([
|
||||
// 'featureFlagName',
|
||||
// ])}`,
|
||||
// ],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -40,11 +40,13 @@ describe(
|
|||
{ product_line: 'security', product_tier: 'complete' },
|
||||
{ product_line: 'endpoint', product_tier: 'complete' },
|
||||
],
|
||||
kbnServerArgs: [
|
||||
`--xpack.securitySolution.enableExperimental=${JSON.stringify([
|
||||
'responseActionScanEnabled',
|
||||
])}`,
|
||||
],
|
||||
// This is not needed for this test, but it's a good example of
|
||||
// how to enable experimental features in the Cypress tests.
|
||||
// kbnServerArgs: [
|
||||
// `--xpack.securitySolution.enableExperimental=${JSON.stringify([
|
||||
// 'featureFlagName',
|
||||
// ])}`,
|
||||
// ],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -461,33 +461,7 @@ describe('Response actions history page', () => {
|
|||
expect(history.location.search).toEqual('?page=1&pageSize=20');
|
||||
});
|
||||
|
||||
// TODO: remove this test when responseActionScanEnabled is removed
|
||||
it('should set selected command filter options to URL params (without `responseActionScanEnabled`)', () => {
|
||||
mockedContext.setExperimentalFlag({
|
||||
responseActionScanEnabled: false,
|
||||
});
|
||||
|
||||
const filterPrefix = 'actions-filter';
|
||||
render();
|
||||
const { getAllByTestId, getByTestId } = renderResult;
|
||||
userEvent.click(getByTestId(`${testPrefix}-${filterPrefix}-popoverButton`));
|
||||
const allFilterOptions = getAllByTestId(`${filterPrefix}-option`);
|
||||
|
||||
allFilterOptions.forEach((option) => {
|
||||
option.style.pointerEvents = 'all';
|
||||
userEvent.click(option);
|
||||
});
|
||||
|
||||
expect(history.location.search).toEqual(
|
||||
'?commands=isolate%2Crelease%2Ckill-process%2Csuspend-process%2Cprocesses%2Cget-file%2Cexecute%2Cupload'
|
||||
);
|
||||
});
|
||||
|
||||
it('should set selected command filter options to URL params (with `responseActionScanEnabled`)', () => {
|
||||
mockedContext.setExperimentalFlag({
|
||||
responseActionScanEnabled: true,
|
||||
});
|
||||
|
||||
it('should set selected command filter options to URL params', () => {
|
||||
const filterPrefix = 'actions-filter';
|
||||
render();
|
||||
const { getAllByTestId, getByTestId } = renderResult;
|
||||
|
@ -631,38 +605,7 @@ describe('Response actions history page', () => {
|
|||
});
|
||||
|
||||
describe('Clear all selected options on a filter', () => {
|
||||
// TODO: remove this test when responseActionScanEnabled is removed
|
||||
it('should clear all selected options on `actions` filter (without `responseActionScanEnabled`)', () => {
|
||||
mockedContext.setExperimentalFlag({
|
||||
responseActionScanEnabled: false,
|
||||
});
|
||||
|
||||
const filterPrefix = 'actions-filter';
|
||||
render();
|
||||
const { getAllByTestId, getByTestId } = renderResult;
|
||||
userEvent.click(getByTestId(`${testPrefix}-${filterPrefix}-popoverButton`));
|
||||
const allFilterOptions = getAllByTestId(`${filterPrefix}-option`);
|
||||
|
||||
allFilterOptions.forEach((option) => {
|
||||
option.style.pointerEvents = 'all';
|
||||
userEvent.click(option);
|
||||
});
|
||||
|
||||
expect(history.location.search).toEqual(
|
||||
'?commands=isolate%2Crelease%2Ckill-process%2Csuspend-process%2Cprocesses%2Cget-file%2Cexecute%2Cupload'
|
||||
);
|
||||
|
||||
const clearAllButton = getByTestId(`${testPrefix}-${filterPrefix}-clearAllButton`);
|
||||
clearAllButton.style.pointerEvents = 'all';
|
||||
userEvent.click(clearAllButton);
|
||||
expect(history.location.search).toEqual('');
|
||||
});
|
||||
|
||||
it('should clear all selected options on `actions` filter (with `responseActionScanEnabled`)', () => {
|
||||
mockedContext.setExperimentalFlag({
|
||||
responseActionScanEnabled: true,
|
||||
});
|
||||
|
||||
it('should clear all selected options on `actions` filter', () => {
|
||||
const filterPrefix = 'actions-filter';
|
||||
render();
|
||||
const { getAllByTestId, getByTestId } = renderResult;
|
||||
|
|
|
@ -12,10 +12,7 @@ import { getDefaultConfigSettings } from '../common/config_settings';
|
|||
import type { ConfigType } from './config';
|
||||
|
||||
export const createMockConfig = (): ConfigType => {
|
||||
const enableExperimental: Array<keyof ExperimentalFeatures> = [
|
||||
'responseActionUploadEnabled',
|
||||
'responseActionScanEnabled',
|
||||
];
|
||||
const enableExperimental: Array<keyof ExperimentalFeatures> = ['responseActionUploadEnabled'];
|
||||
|
||||
return {
|
||||
[SIGNALS_INDEX_KEY]: DEFAULT_SIGNALS_INDEX,
|
||||
|
|
|
@ -78,7 +78,6 @@ import type { ActionsApiRequestHandlerContext } from '@kbn/actions-plugin/server
|
|||
import { sentinelOneMock } from '../../services/actions/clients/sentinelone/mocks';
|
||||
import { ResponseActionsClientError } from '../../services/actions/clients/errors';
|
||||
import type { EndpointAppContext } from '../../types';
|
||||
import type { ExperimentalFeatures } from '../../../../common';
|
||||
|
||||
jest.mock('../../services', () => {
|
||||
const realModule = jest.requireActual('../../services');
|
||||
|
@ -135,13 +134,6 @@ describe('Response actions', () => {
|
|||
|
||||
const docGen = new EndpointDocGenerator();
|
||||
|
||||
const setFeatureFlag = (ff: Partial<ExperimentalFeatures>) => {
|
||||
endpointContext.experimentalFeatures = {
|
||||
...endpointContext.experimentalFeatures,
|
||||
...ff,
|
||||
};
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
// instantiate... everything
|
||||
const mockScopedClient = elasticsearchServiceMock.createScopedClusterClient();
|
||||
|
@ -174,8 +166,6 @@ describe('Response actions', () => {
|
|||
licenseService,
|
||||
});
|
||||
|
||||
setFeatureFlag({ responseActionScanEnabled: true });
|
||||
|
||||
// add the host isolation route handlers to routerMock
|
||||
registerResponseActionRoutes(routerMock, endpointContext);
|
||||
|
||||
|
|
|
@ -286,28 +286,25 @@ export function registerResponseActionRoutes(
|
|||
)
|
||||
);
|
||||
|
||||
// 8.15 route
|
||||
if (endpointContext.experimentalFeatures.responseActionScanEnabled) {
|
||||
router.versioned
|
||||
.post({
|
||||
access: 'public',
|
||||
path: SCAN_ROUTE,
|
||||
options: { authRequired: true, tags: ['access:securitySolution'] },
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: '2023-10-31',
|
||||
validate: {
|
||||
request: ScanActionRequestSchema,
|
||||
},
|
||||
router.versioned
|
||||
.post({
|
||||
access: 'public',
|
||||
path: SCAN_ROUTE,
|
||||
options: { authRequired: true, tags: ['access:securitySolution'] },
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: '2023-10-31',
|
||||
validate: {
|
||||
request: ScanActionRequestSchema,
|
||||
},
|
||||
withEndpointAuthz(
|
||||
{ all: ['canWriteScanOperations'] },
|
||||
logger,
|
||||
responseActionRequestHandler<ResponseActionScanParameters>(endpointContext, 'scan')
|
||||
)
|
||||
);
|
||||
}
|
||||
},
|
||||
withEndpointAuthz(
|
||||
{ all: ['canWriteScanOperations'] },
|
||||
logger,
|
||||
responseActionRequestHandler<ResponseActionScanParameters>(endpointContext, 'scan')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function responseActionRequestHandler<T extends EndpointActionDataParameterTypes>(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue