[8.x] [ResponseOps][Rules] Fix case action templates in stack for security serverless (#195763) (#196110)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[ResponseOps][Rules] Fix case action templates in stack for security
serverless (#195763)](https://github.com/elastic/kibana/pull/195763)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT
[{"author":{"name":"Antonio","email":"antonio.coelho@elastic.co"},"sourceCommit":{"committedDate":"2024-10-14T11:25:29Z","message":"[ResponseOps][Rules]
Fix case action templates in stack for security serverless
(#195763)\n\nFixes #195599\r\n\r\n## Summary\r\n\r\nThis PR ensures that
we can use templates in the case action when:\r\n1. the project is
serverless security, and\r\n2. the rule is created in stack
management\r\n\r\n### How to test\r\n\r\n1. Add the following line to
`serverless.yml` -\r\n`xpack.cloud.serverless.project_id:
test-123`\r\n3. Start Elastic search in serverless security mode - `yarn
es\r\nserverless --projectType security`\r\n4. Start Kibana in
serverless security mode - `yarn start\r\n--serverless=security`\r\n5.
Go to Security > Cases > Settings and add a template.\r\n6. Go to stack
and create a rule with the case action.\r\n7. Confirm the template
created in step 5 can be selected.\r\n\r\n<img width=\"586\"
alt=\"Screenshot 2024-10-10 at 15 00
46\"\r\nsrc=\"https://github.com/user-attachments/assets/5379e1d1-f0eb-4829-9604-ee5a0e3d050b\">\r\n\r\n**Please
double-check also that the templates in the case action still\r\nwork as
expected in normal scenarios.**\r\n\r\n---------\r\n\r\nCo-authored-by:
kibanamachine
<42973632+kibanamachine@users.noreply.github.com>","sha":"97322a871357ba69e7c64543831fbf1597ca8ff9","branchLabelMapping":{"^v9.0.0$":"main","^v8.16.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["bug","release_note:skip","Team:ResponseOps","v9.0.0","Feature:Cases","backport:prev-minor","v8.16.0"],"title":"[ResponseOps][Rules]
Fix case action templates in stack for security
serverless","number":195763,"url":"https://github.com/elastic/kibana/pull/195763","mergeCommit":{"message":"[ResponseOps][Rules]
Fix case action templates in stack for security serverless
(#195763)\n\nFixes #195599\r\n\r\n## Summary\r\n\r\nThis PR ensures that
we can use templates in the case action when:\r\n1. the project is
serverless security, and\r\n2. the rule is created in stack
management\r\n\r\n### How to test\r\n\r\n1. Add the following line to
`serverless.yml` -\r\n`xpack.cloud.serverless.project_id:
test-123`\r\n3. Start Elastic search in serverless security mode - `yarn
es\r\nserverless --projectType security`\r\n4. Start Kibana in
serverless security mode - `yarn start\r\n--serverless=security`\r\n5.
Go to Security > Cases > Settings and add a template.\r\n6. Go to stack
and create a rule with the case action.\r\n7. Confirm the template
created in step 5 can be selected.\r\n\r\n<img width=\"586\"
alt=\"Screenshot 2024-10-10 at 15 00
46\"\r\nsrc=\"https://github.com/user-attachments/assets/5379e1d1-f0eb-4829-9604-ee5a0e3d050b\">\r\n\r\n**Please
double-check also that the templates in the case action still\r\nwork as
expected in normal scenarios.**\r\n\r\n---------\r\n\r\nCo-authored-by:
kibanamachine
<42973632+kibanamachine@users.noreply.github.com>","sha":"97322a871357ba69e7c64543831fbf1597ca8ff9"}},"sourceBranch":"main","suggestedTargetBranches":["8.x"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/195763","number":195763,"mergeCommit":{"message":"[ResponseOps][Rules]
Fix case action templates in stack for security serverless
(#195763)\n\nFixes #195599\r\n\r\n## Summary\r\n\r\nThis PR ensures that
we can use templates in the case action when:\r\n1. the project is
serverless security, and\r\n2. the rule is created in stack
management\r\n\r\n### How to test\r\n\r\n1. Add the following line to
`serverless.yml` -\r\n`xpack.cloud.serverless.project_id:
test-123`\r\n3. Start Elastic search in serverless security mode - `yarn
es\r\nserverless --projectType security`\r\n4. Start Kibana in
serverless security mode - `yarn start\r\n--serverless=security`\r\n5.
Go to Security > Cases > Settings and add a template.\r\n6. Go to stack
and create a rule with the case action.\r\n7. Confirm the template
created in step 5 can be selected.\r\n\r\n<img width=\"586\"
alt=\"Screenshot 2024-10-10 at 15 00
46\"\r\nsrc=\"https://github.com/user-attachments/assets/5379e1d1-f0eb-4829-9604-ee5a0e3d050b\">\r\n\r\n**Please
double-check also that the templates in the case action still\r\nwork as
expected in normal scenarios.**\r\n\r\n---------\r\n\r\nCo-authored-by:
kibanamachine
<42973632+kibanamachine@users.noreply.github.com>","sha":"97322a871357ba69e7c64543831fbf1597ca8ff9"}},{"branch":"8.x","label":"v8.16.0","branchLabelMappingKey":"^v8.16.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->

Co-authored-by: Antonio <antonio.coelho@elastic.co>
This commit is contained in:
Kibana Machine 2024-10-15 00:12:58 +11:00 committed by GitHub
parent 3f89635abf
commit 742ae89748
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 72 additions and 8 deletions

View file

@ -18,6 +18,7 @@ import { createStartServicesMock } from '../../../common/lib/kibana/kibana_react
import { useGetAllCaseConfigurations } from '../../../containers/configure/use_get_all_case_configurations';
import { useGetAllCaseConfigurationsResponse } from '../../configure_cases/__mock__';
import { templatesConfigurationMock } from '../../../containers/mock';
import * as utils from '../../../containers/configure/utils';
jest.mock('@kbn/alerts-ui-shared/src/common/hooks/use_alerts_data_view');
jest.mock('../../../common/lib/kibana/use_application');
@ -29,10 +30,6 @@ const useAlertsDataViewMock = jest.mocked(useAlertsDataView);
const useApplicationMock = useApplication as jest.Mock;
const useGetAllCaseConfigurationsMock = useGetAllCaseConfigurations as jest.Mock;
useKibanaMock.mockReturnValue({
services: { ...createStartServicesMock(), data: { dataViews: {} } },
} as unknown as ReturnType<typeof useKibana>);
const actionParams = {
subAction: 'run',
subActionParams: {
@ -98,6 +95,9 @@ describe('CasesParamsFields renders', () => {
},
});
useGetAllCaseConfigurationsMock.mockImplementation(() => useGetAllCaseConfigurationsResponse);
useKibanaMock.mockReturnValue({
services: { ...createStartServicesMock(), data: { dataViews: {} } },
} as unknown as ReturnType<typeof useKibana>);
});
afterEach(() => {
@ -268,6 +268,54 @@ describe('CasesParamsFields renders', () => {
expect(await screen.findByText(templatesConfigurationMock[1].name)).toBeInTheDocument();
});
it('renders security templates if the project is serverless security', async () => {
useKibanaMock.mockReturnValue({
services: {
...createStartServicesMock(),
// simulate a serverless security project
cloud: { isServerlessEnabled: true, serverless: { projectType: 'security' } },
data: { dataViews: {} },
},
} as unknown as ReturnType<typeof useKibana>);
const configuration = {
...useGetAllCaseConfigurationsResponse.data[0],
templates: templatesConfigurationMock,
};
useGetAllCaseConfigurationsMock.mockImplementation(() => ({
...useGetAllCaseConfigurationsResponse,
data: [configuration],
}));
const getConfigurationByOwnerSpy = jest
.spyOn(utils, 'getConfigurationByOwner')
.mockImplementation(() => configuration);
const observabilityOwnedRule = {
...defaultProps,
// these two would normally produce an observability owner
producerId: 'observability',
featureId: 'observability',
actionParams: {
subAction: 'run',
subActionParams: {
...actionParams.subActionParams,
templateId: templatesConfigurationMock[1].key,
},
},
};
render(<CasesParamsFields {...observabilityOwnedRule} />);
expect(getConfigurationByOwnerSpy).toHaveBeenCalledWith(
expect.objectContaining({
// the security owner was forced
owner: 'securitySolution',
})
);
getConfigurationByOwnerSpy.mockRestore();
});
it('updates template correctly', async () => {
useGetAllCaseConfigurationsMock.mockReturnValueOnce({
...useGetAllCaseConfigurationsResponse,

View file

@ -39,11 +39,20 @@ export const CasesParamsFieldsComponent: React.FunctionComponent<
ActionParamsProps<CasesActionParams>
> = ({ actionParams, editAction, errors, index, producerId, featureId }) => {
const {
cloud,
data: { dataViews: dataViewsService },
http,
notifications: { toasts },
data: { dataViews: dataViewsService },
} = useKibana().services;
const owner = getOwnerFromRuleConsumerProducer({ consumer: featureId, producer: producerId });
const owner = getOwnerFromRuleConsumerProducer({
consumer: featureId,
producer: producerId,
// This is a workaround for a very specific bug with the cases action in serverless security
// More info here: https://github.com/elastic/kibana/issues/195599
isServerlessSecurity:
cloud?.isServerlessEnabled && cloud?.serverless.projectType === 'security',
});
const { dataView, isLoading: loadingAlertDataViews } = useAlertsDataView({
http,

View file

@ -30,6 +30,7 @@ import type { ContentManagementPublicStart } from '@kbn/content-management-plugi
import type { UiActionsStart } from '@kbn/ui-actions-plugin/public';
import type { ServerlessPluginSetup, ServerlessPluginStart } from '@kbn/serverless/public';
import type { CloudStart } from '@kbn/cloud-plugin/public';
import type { UseCasesAddToExistingCaseModal } from './components/all_cases/selector_modal/use_cases_add_to_existing_case_modal';
import type { UseCasesAddToNewCaseFlyout } from './components/create/flyout/use_cases_add_to_new_case_flyout';
import type { UseIsAddToCaseOpen } from './components/cases_context/state/use_is_add_to_case_open';
@ -73,6 +74,7 @@ export interface CasesPublicSetupDependencies {
export interface CasesPublicStartDependencies {
apm?: ApmBase;
cloud?: CloudStart;
data: DataPublicPluginStart;
embeddable: EmbeddableStart;
features: FeaturesPluginStart;

View file

@ -35,6 +35,7 @@ import { ruleDetailsRoute } from '@kbn/rule-data-utils';
import { QueryClientProvider } from '@tanstack/react-query';
import { DashboardStart } from '@kbn/dashboard-plugin/public';
import { ExpressionsStart } from '@kbn/expressions-plugin/public';
import { CloudSetup } from '@kbn/cloud-plugin/public';
import { suspendedComponentWithProps } from './lib/suspended_component_with_props';
import {
ActionTypeRegistryContract,
@ -61,6 +62,7 @@ const RuleDetailsRoute = lazy(
export interface TriggersAndActionsUiServices extends CoreStart {
actions: ActionsPublicPluginSetup;
cloud?: CloudSetup;
data: DataPublicPluginStart;
dataViews: DataViewsPublicPluginStart;
dataViewEditor: DataViewEditorStart;

View file

@ -32,6 +32,7 @@ import { FieldFormatsRegistry } from '@kbn/field-formats-plugin/common';
import { LensPublicStart } from '@kbn/lens-plugin/public';
import { RuleAction } from '@kbn/alerting-plugin/common';
import { TypeRegistry } from '@kbn/alerts-ui-shared/src/common/type_registry';
import { CloudSetup } from '@kbn/cloud-plugin/public';
import { getAlertsTableDefaultAlertActionsLazy } from './common/get_alerts_table_default_row_actions';
import type { AlertActionsProps, RuleUiAction } from './types';
import type { AlertsSearchBarProps } from './application/sections/alerts_search_bar';
@ -167,7 +168,7 @@ export interface TriggersAndActionsUIPublicPluginStart {
interface PluginsSetup {
management: ManagementSetup;
home?: HomePublicPluginSetup;
cloud?: { isCloudEnabled: boolean };
cloud?: CloudSetup;
actions: ActionsPublicPluginSetup;
}
@ -305,6 +306,7 @@ export class Plugin
...coreStart,
actions: plugins.actions,
dashboard: pluginsStart.dashboard,
cloud: plugins.cloud,
data: pluginsStart.data,
dataViews: pluginsStart.dataViews,
dataViewEditor: pluginsStart.dataViewEditor,

View file

@ -71,7 +71,8 @@
"@kbn/visualization-utils",
"@kbn/core-ui-settings-browser",
"@kbn/observability-alerting-rule-utils",
"@kbn/core-application-browser"
"@kbn/core-application-browser",
"@kbn/cloud-plugin"
],
"exclude": ["target/**/*"]
}