mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[Cloud Security] Serverless PLI auth block using UI extension infra (#184665)
This commit is contained in:
parent
96024b8d40
commit
6fc0663d2a
34 changed files with 505 additions and 220 deletions
|
@ -442,7 +442,8 @@ enabled:
|
|||
- x-pack/test_serverless/functional/test_suites/search/common_configs/config.group6.ts
|
||||
- x-pack/test_serverless/functional/test_suites/security/config.ts
|
||||
- x-pack/test_serverless/functional/test_suites/security/config.examples.ts
|
||||
- x-pack/test_serverless/functional/test_suites/security/config.cloud_security_posture.ts
|
||||
- x-pack/test_serverless/functional/test_suites/security/config.cloud_security_posture.basic.ts
|
||||
- x-pack/test_serverless/functional/test_suites/security/config.cloud_security_posture.essentials.ts
|
||||
- x-pack/test_serverless/functional/test_suites/security/config.saved_objects_management.ts
|
||||
- x-pack/test_serverless/functional/test_suites/security/common_configs/config.group1.ts
|
||||
- x-pack/test_serverless/functional/test_suites/security/common_configs/config.group2.ts
|
||||
|
|
3
.github/CODEOWNERS
vendored
3
.github/CODEOWNERS
vendored
|
@ -1651,7 +1651,8 @@ x-pack/test/security_solution_api_integration/test_suites/genai @elastic/securit
|
|||
/x-pack/test/cloud_security_posture_functional/ @elastic/kibana-cloud-security-posture
|
||||
/x-pack/test/cloud_security_posture_api/ @elastic/kibana-cloud-security-posture
|
||||
/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/ @elastic/kibana-cloud-security-posture
|
||||
/x-pack/test_serverless/functional/test_suites/security/config.cloud_security_posture.ts @elastic/kibana-cloud-security-posture
|
||||
/x-pack/test_serverless/functional/test_suites/security/config.cloud_security_posture.basic.ts @elastic/kibana-cloud-security-posture
|
||||
/x-pack/test_serverless/functional/test_suites/security/config.cloud_security_posture.essentials.ts @elastic/kibana-cloud-security-posture
|
||||
/x-pack/test_serverless/api_integration/test_suites/security/cloud_security_posture/ @elastic/kibana-cloud-security-posture
|
||||
/x-pack/plugins/fleet/public/components/cloud_security_posture @elastic/fleet @elastic/kibana-cloud-security-posture
|
||||
/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/components/cloud_security_posture @elastic/fleet @elastic/kibana-cloud-security-posture
|
||||
|
|
|
@ -67,6 +67,11 @@ export enum ProductFeatureSecurityKey {
|
|||
* enables all rule actions
|
||||
*/
|
||||
externalRuleActions = 'external_rule_actions',
|
||||
|
||||
/**
|
||||
* enables Cloud Security Posture - CSPM, KSPM, CNVM
|
||||
*/
|
||||
cloudSecurityPosture = 'cloud_security_posture',
|
||||
}
|
||||
|
||||
export enum ProductFeatureCasesKey {
|
||||
|
|
|
@ -121,4 +121,5 @@ export const securityDefaultProductFeaturesConfig: DefaultSecurityProductFeature
|
|||
[ProductFeatureSecurityKey.endpointProtectionUpdates]: {},
|
||||
[ProductFeatureSecurityKey.endpointAgentTamperProtection]: {},
|
||||
[ProductFeatureSecurityKey.externalRuleActions]: {},
|
||||
[ProductFeatureSecurityKey.cloudSecurityPosture]: {},
|
||||
};
|
||||
|
|
|
@ -17,6 +17,7 @@ export type UpsellingSectionId =
|
|||
| 'osquery_automated_response_actions'
|
||||
| 'endpoint_protection_updates'
|
||||
| 'endpoint_agent_tamper_protection'
|
||||
| 'cloud_security_posture_integration_installation'
|
||||
| 'ruleDetailsEndpointExceptions';
|
||||
|
||||
export type UpsellingMessageId =
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import React, { useCallback, useEffect, useMemo, useState, Suspense } from 'react';
|
||||
import { useRouteMatch } from 'react-router-dom';
|
||||
import styled from 'styled-components';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
@ -321,6 +321,20 @@ export const CreatePackagePolicySinglePage: CreatePackagePolicyParams = ({
|
|||
'package-policy-replace-define-step'
|
||||
);
|
||||
|
||||
// PLI auth blocks are registered to UI Extension context and are used to display upselling components.
|
||||
// Upselling components are rendered conditionally based on their availability from the PLI upselling service.
|
||||
const pliAuthBlockView = useUIExtension(packageInfo?.name ?? '', 'pli-auth-block');
|
||||
|
||||
// If an auth block view is registered to the UI Extension context, we expect the registered component to return a React component when the PLI is not sufficient,
|
||||
// or simply a wrapper returning the children if the PLI is sufficient.
|
||||
const PliAuthBlockWrapper: React.FC = useMemo(
|
||||
() =>
|
||||
pliAuthBlockView?.Component && !isPackageInfoLoading
|
||||
? pliAuthBlockView.Component
|
||||
: ({ children }) => <>{children}</>, // when no UI Extension is registered, render children
|
||||
[isPackageInfoLoading, pliAuthBlockView?.Component]
|
||||
);
|
||||
|
||||
if (replaceDefineStepView && extensionView) {
|
||||
throw new Error(
|
||||
"'package-policy-create' and 'package-policy-replace-define-step' cannot both be registered as UI extensions"
|
||||
|
@ -455,172 +469,182 @@ export const CreatePackagePolicySinglePage: CreatePackagePolicyParams = ({
|
|||
|
||||
return (
|
||||
<CreatePackagePolicySinglePageLayout {...layoutProps} data-test-subj="createPackagePolicy">
|
||||
<EuiErrorBoundary>
|
||||
{formState === 'CONFIRM' && agentPolicies.length > 0 && (
|
||||
<ConfirmDeployAgentPolicyModal
|
||||
agentCount={agentCount}
|
||||
agentPolicies={agentPolicies}
|
||||
onConfirm={onSubmit}
|
||||
onCancel={() => setFormState('VALID')}
|
||||
showUnprivilegedAgentsCallout={Boolean(
|
||||
packageInfo && isRootPrivilegesRequired(packageInfo) && unprivilegedAgentsCount > 0
|
||||
)}
|
||||
unprivilegedAgentsCount={unprivilegedAgentsCount}
|
||||
dataStreams={rootPrivilegedDataStreams}
|
||||
/>
|
||||
)}
|
||||
{formState === 'SUBMITTED_NO_AGENTS' &&
|
||||
agentPolicies.length > 0 &&
|
||||
packageInfo &&
|
||||
savedPackagePolicy && (
|
||||
<PostInstallAddAgentModal
|
||||
packageInfo={packageInfo}
|
||||
onConfirm={() => navigateAddAgent(savedPackagePolicy)}
|
||||
onCancel={() => navigateAddAgentHelp(savedPackagePolicy)}
|
||||
/>
|
||||
)}
|
||||
{formState === 'SUBMITTED_AZURE_ARM_TEMPLATE' &&
|
||||
agentPolicies.length > 0 &&
|
||||
savedPackagePolicy && (
|
||||
<PostInstallAzureArmTemplateModal
|
||||
agentPolicy={agentPolicies[0]}
|
||||
packagePolicy={savedPackagePolicy}
|
||||
onConfirm={() => navigateAddAgent(savedPackagePolicy)}
|
||||
onCancel={() => navigateAddAgentHelp(savedPackagePolicy)}
|
||||
/>
|
||||
)}
|
||||
{formState === 'SUBMITTED_CLOUD_FORMATION' &&
|
||||
agentPolicies.length > 0 &&
|
||||
savedPackagePolicy && (
|
||||
<PostInstallCloudFormationModal
|
||||
agentPolicy={agentPolicies[0]}
|
||||
packagePolicy={savedPackagePolicy}
|
||||
onConfirm={() => navigateAddAgent(savedPackagePolicy)}
|
||||
onCancel={() => navigateAddAgentHelp(savedPackagePolicy)}
|
||||
/>
|
||||
)}
|
||||
{formState === 'SUBMITTED_GOOGLE_CLOUD_SHELL' &&
|
||||
agentPolicies.length > 0 &&
|
||||
savedPackagePolicy && (
|
||||
<PostInstallGoogleCloudShellModal
|
||||
agentPolicy={agentPolicies[0]}
|
||||
packagePolicy={savedPackagePolicy}
|
||||
onConfirm={() => navigateAddAgent(savedPackagePolicy)}
|
||||
onCancel={() => navigateAddAgentHelp(savedPackagePolicy)}
|
||||
/>
|
||||
)}
|
||||
{packageInfo && (
|
||||
<IntegrationBreadcrumb
|
||||
pkgTitle={integrationInfo?.title || packageInfo.title}
|
||||
pkgkey={pkgKeyFromPackageInfo(packageInfo)}
|
||||
integration={integrationInfo?.name}
|
||||
/>
|
||||
)}
|
||||
{packageInfo && isRootPrivilegesRequired(packageInfo) ? (
|
||||
<>
|
||||
<RootPrivilegesCallout dataStreams={rootPrivilegedDataStreams} />
|
||||
<EuiSpacer size="m" />
|
||||
</>
|
||||
) : null}
|
||||
{numTransformAssets > 0 ? (
|
||||
<>
|
||||
<TransformInstallWithCurrentUserPermissionCallout count={numTransformAssets} />
|
||||
<EuiSpacer size="xl" />
|
||||
</>
|
||||
) : null}
|
||||
{showSecretsDisabledCallout && (
|
||||
<>
|
||||
<EuiCallOut
|
||||
size="m"
|
||||
color="warning"
|
||||
title={
|
||||
<FormattedMessage
|
||||
id="xpack.fleet.createPackagePolicy.secretsDisabledCalloutTitle"
|
||||
defaultMessage="Policy secrets are disabled"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.fleet.createPackagePolicy.secretsDisabledCalloutDescription"
|
||||
defaultMessage="This integration contains {policySecretsLink}, but you have a Fleet Server running on a version earlier than {minimumSecretsVersion}. Please upgrade your Fleet Server to enable policy secrets for all integrations."
|
||||
values={{
|
||||
policySecretsLink: (
|
||||
<EuiLink href={docLinks.links.fleet.policySecrets} target="_blank">
|
||||
<FormattedMessage
|
||||
id="xpack.fleet.createPackagePolicy.secretsDisabledCalloutDocsLink"
|
||||
defaultMessage="policy secrets"
|
||||
/>
|
||||
</EuiLink>
|
||||
),
|
||||
minimumSecretsVersion: <EuiCode>{SECRETS_MINIMUM_FLEET_SERVER_VERSION}</EuiCode>,
|
||||
}}
|
||||
<Suspense fallback={<Loading />}>
|
||||
<PliAuthBlockWrapper>
|
||||
<EuiErrorBoundary>
|
||||
{formState === 'CONFIRM' && agentPolicies.length > 0 && (
|
||||
<ConfirmDeployAgentPolicyModal
|
||||
agentCount={agentCount}
|
||||
agentPolicies={agentPolicies}
|
||||
onConfirm={onSubmit}
|
||||
onCancel={() => setFormState('VALID')}
|
||||
showUnprivilegedAgentsCallout={Boolean(
|
||||
packageInfo &&
|
||||
isRootPrivilegesRequired(packageInfo) &&
|
||||
unprivilegedAgentsCount > 0
|
||||
)}
|
||||
unprivilegedAgentsCount={unprivilegedAgentsCount}
|
||||
dataStreams={rootPrivilegedDataStreams}
|
||||
/>
|
||||
</EuiCallOut>
|
||||
|
||||
<EuiSpacer size="m" />
|
||||
</>
|
||||
)}
|
||||
<StepsWithLessPadding steps={steps} />
|
||||
<EuiSpacer size="xl" />
|
||||
<EuiSpacer size="xl" />
|
||||
<CustomEuiBottomBar data-test-subj="integrationsBottomBar">
|
||||
<EuiFlexGroup justifyContent="spaceBetween" alignItems="center">
|
||||
<EuiFlexItem grow={false}>
|
||||
{packageInfo && (formState === 'INVALID' || hasAgentPolicyError) ? (
|
||||
<FormattedMessage
|
||||
id="xpack.fleet.createPackagePolicy.errorOnSaveText"
|
||||
defaultMessage="Your integration policy has errors. Please fix them before saving."
|
||||
)}
|
||||
{formState === 'SUBMITTED_NO_AGENTS' &&
|
||||
agentPolicies.length > 0 &&
|
||||
packageInfo &&
|
||||
savedPackagePolicy && (
|
||||
<PostInstallAddAgentModal
|
||||
packageInfo={packageInfo}
|
||||
onConfirm={() => navigateAddAgent(savedPackagePolicy)}
|
||||
onCancel={() => navigateAddAgentHelp(savedPackagePolicy)}
|
||||
/>
|
||||
) : null}
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiFlexGroup gutterSize="s" justifyContent="flexEnd">
|
||||
<EuiFlexItem grow={false}>
|
||||
{/* eslint-disable-next-line @elastic/eui/href-or-on-click */}
|
||||
<EuiButtonEmpty
|
||||
color="text"
|
||||
href={cancelUrl}
|
||||
onClick={cancelClickHandler}
|
||||
data-test-subj="createPackagePolicyCancelButton"
|
||||
>
|
||||
)}
|
||||
{formState === 'SUBMITTED_AZURE_ARM_TEMPLATE' &&
|
||||
agentPolicies.length > 0 &&
|
||||
savedPackagePolicy && (
|
||||
<PostInstallAzureArmTemplateModal
|
||||
agentPolicy={agentPolicies[0]}
|
||||
packagePolicy={savedPackagePolicy}
|
||||
onConfirm={() => navigateAddAgent(savedPackagePolicy)}
|
||||
onCancel={() => navigateAddAgentHelp(savedPackagePolicy)}
|
||||
/>
|
||||
)}
|
||||
{formState === 'SUBMITTED_CLOUD_FORMATION' &&
|
||||
agentPolicies.length > 0 &&
|
||||
savedPackagePolicy && (
|
||||
<PostInstallCloudFormationModal
|
||||
agentPolicy={agentPolicies[0]}
|
||||
packagePolicy={savedPackagePolicy}
|
||||
onConfirm={() => navigateAddAgent(savedPackagePolicy)}
|
||||
onCancel={() => navigateAddAgentHelp(savedPackagePolicy)}
|
||||
/>
|
||||
)}
|
||||
{formState === 'SUBMITTED_GOOGLE_CLOUD_SHELL' &&
|
||||
agentPolicies.length > 0 &&
|
||||
savedPackagePolicy && (
|
||||
<PostInstallGoogleCloudShellModal
|
||||
agentPolicy={agentPolicies[0]}
|
||||
packagePolicy={savedPackagePolicy}
|
||||
onConfirm={() => navigateAddAgent(savedPackagePolicy)}
|
||||
onCancel={() => navigateAddAgentHelp(savedPackagePolicy)}
|
||||
/>
|
||||
)}
|
||||
{packageInfo && (
|
||||
<IntegrationBreadcrumb
|
||||
pkgTitle={integrationInfo?.title || packageInfo.title}
|
||||
pkgkey={pkgKeyFromPackageInfo(packageInfo)}
|
||||
integration={integrationInfo?.name}
|
||||
/>
|
||||
)}
|
||||
{packageInfo && isRootPrivilegesRequired(packageInfo) ? (
|
||||
<>
|
||||
<RootPrivilegesCallout dataStreams={rootPrivilegedDataStreams} />
|
||||
<EuiSpacer size="m" />
|
||||
</>
|
||||
) : null}
|
||||
{numTransformAssets > 0 ? (
|
||||
<>
|
||||
<TransformInstallWithCurrentUserPermissionCallout count={numTransformAssets} />
|
||||
<EuiSpacer size="xl" />
|
||||
</>
|
||||
) : null}
|
||||
{showSecretsDisabledCallout && (
|
||||
<>
|
||||
<EuiCallOut
|
||||
size="m"
|
||||
color="warning"
|
||||
title={
|
||||
<FormattedMessage
|
||||
id="xpack.fleet.createPackagePolicy.cancelButton"
|
||||
defaultMessage="Cancel"
|
||||
id="xpack.fleet.createPackagePolicy.secretsDisabledCalloutTitle"
|
||||
defaultMessage="Policy secrets are disabled"
|
||||
/>
|
||||
</EuiButtonEmpty>
|
||||
}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.fleet.createPackagePolicy.secretsDisabledCalloutDescription"
|
||||
defaultMessage="This integration contains {policySecretsLink}, but you have a Fleet Server running on a version earlier than {minimumSecretsVersion}. Please upgrade your Fleet Server to enable policy secrets for all integrations."
|
||||
values={{
|
||||
policySecretsLink: (
|
||||
<EuiLink href={docLinks.links.fleet.policySecrets} target="_blank">
|
||||
<FormattedMessage
|
||||
id="xpack.fleet.createPackagePolicy.secretsDisabledCalloutDocsLink"
|
||||
defaultMessage="policy secrets"
|
||||
/>
|
||||
</EuiLink>
|
||||
),
|
||||
minimumSecretsVersion: (
|
||||
<EuiCode>{SECRETS_MINIMUM_FLEET_SERVER_VERSION}</EuiCode>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</EuiCallOut>
|
||||
|
||||
<EuiSpacer size="m" />
|
||||
</>
|
||||
)}
|
||||
<StepsWithLessPadding steps={steps} />
|
||||
<EuiSpacer size="xl" />
|
||||
<EuiSpacer size="xl" />
|
||||
<CustomEuiBottomBar data-test-subj="integrationsBottomBar">
|
||||
<EuiFlexGroup justifyContent="spaceBetween" alignItems="center">
|
||||
<EuiFlexItem grow={false}>
|
||||
{packageInfo && (formState === 'INVALID' || hasAgentPolicyError) ? (
|
||||
<FormattedMessage
|
||||
id="xpack.fleet.createPackagePolicy.errorOnSaveText"
|
||||
defaultMessage="Your integration policy has errors. Please fix them before saving."
|
||||
/>
|
||||
) : null}
|
||||
</EuiFlexItem>
|
||||
{showDevtoolsRequest ? (
|
||||
<EuiFlexItem grow={false}>
|
||||
<DevtoolsRequestFlyoutButton
|
||||
request={devtoolRequest}
|
||||
description={devtoolRequestDescription}
|
||||
btnProps={{
|
||||
color: 'text',
|
||||
}}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
) : null}
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton
|
||||
onClick={() => onSubmit()}
|
||||
isLoading={formState === 'LOADING'}
|
||||
disabled={formState !== 'VALID' || hasAgentPolicyError || !validationResults}
|
||||
iconType="save"
|
||||
color="primary"
|
||||
fill
|
||||
data-test-subj="createPackagePolicySaveButton"
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.fleet.createPackagePolicy.saveButton"
|
||||
defaultMessage="Save and continue"
|
||||
/>
|
||||
</EuiButton>
|
||||
<EuiFlexGroup gutterSize="s" justifyContent="flexEnd">
|
||||
<EuiFlexItem grow={false}>
|
||||
{/* eslint-disable-next-line @elastic/eui/href-or-on-click */}
|
||||
<EuiButtonEmpty
|
||||
color="text"
|
||||
href={cancelUrl}
|
||||
onClick={cancelClickHandler}
|
||||
data-test-subj="createPackagePolicyCancelButton"
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.fleet.createPackagePolicy.cancelButton"
|
||||
defaultMessage="Cancel"
|
||||
/>
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
{showDevtoolsRequest ? (
|
||||
<EuiFlexItem grow={false}>
|
||||
<DevtoolsRequestFlyoutButton
|
||||
request={devtoolRequest}
|
||||
description={devtoolRequestDescription}
|
||||
btnProps={{
|
||||
color: 'text',
|
||||
}}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
) : null}
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton
|
||||
onClick={() => onSubmit()}
|
||||
isLoading={formState === 'LOADING'}
|
||||
disabled={
|
||||
formState !== 'VALID' || hasAgentPolicyError || !validationResults
|
||||
}
|
||||
iconType="save"
|
||||
color="primary"
|
||||
fill
|
||||
data-test-subj="createPackagePolicySaveButton"
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.fleet.createPackagePolicy.saveButton"
|
||||
defaultMessage="Save and continue"
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</CustomEuiBottomBar>
|
||||
</EuiErrorBoundary>
|
||||
</CustomEuiBottomBar>
|
||||
</EuiErrorBoundary>
|
||||
</PliAuthBlockWrapper>
|
||||
</Suspense>
|
||||
</CreatePackagePolicySinglePageLayout>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -119,6 +119,12 @@ export interface EndpointAgentTamperProtectionExtension {
|
|||
Component: LazyExoticComponent<ComponentType>;
|
||||
}
|
||||
|
||||
export interface PliAuthBlockExtension {
|
||||
package: string;
|
||||
view: 'pli-auth-block';
|
||||
Component: LazyExoticComponent<ComponentType>;
|
||||
}
|
||||
|
||||
export interface PackageGenericErrorsListExtension {
|
||||
package: string;
|
||||
view: 'package-generic-errors-list';
|
||||
|
@ -226,4 +232,5 @@ export type UIExtensionPoint =
|
|||
| PackageGenericErrorsListExtension
|
||||
| AgentEnrollmentFlyoutFinalStepExtension
|
||||
| PackagePolicyCreateMultiStepExtension
|
||||
| EndpointAgentTamperProtectionExtension;
|
||||
| EndpointAgentTamperProtectionExtension
|
||||
| PliAuthBlockExtension;
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* 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 type { PropsWithChildren } from 'react';
|
||||
import React, { memo } from 'react';
|
||||
import { useUpsellingComponent } from '../common/hooks/use_upselling';
|
||||
|
||||
export const CloudSecurityPosturePliAuthBlockExtension = memo<PropsWithChildren<unknown>>(
|
||||
({ children }) => {
|
||||
const Component = useUpsellingComponent('cloud_security_posture_integration_installation');
|
||||
if (!Component) {
|
||||
return <>{children}</>;
|
||||
}
|
||||
return <Component />;
|
||||
}
|
||||
);
|
||||
|
||||
CloudSecurityPosturePliAuthBlockExtension.displayName = 'CloudSecurityPosturePliAuthBlockExtension';
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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 { lazy } from 'react';
|
||||
import type { FleetUiExtensionGetterOptions } from '../common/types';
|
||||
|
||||
export const getLazyCloudSecurityPosturePliAuthBlockExtension = ({
|
||||
coreStart,
|
||||
depsStart,
|
||||
services,
|
||||
}: FleetUiExtensionGetterOptions) =>
|
||||
lazy(async () => {
|
||||
const [{ withSecurityContext }, { CloudSecurityPosturePliAuthBlockExtension }] =
|
||||
await Promise.all([
|
||||
import('../common/components/with_security_context/with_security_context'),
|
||||
import('./cloud_security_posture_pli_auth_block_extension'),
|
||||
]);
|
||||
return {
|
||||
default: withSecurityContext({
|
||||
coreStart,
|
||||
depsStart,
|
||||
services,
|
||||
WrappedComponent: CloudSecurityPosturePliAuthBlockExtension,
|
||||
}),
|
||||
};
|
||||
});
|
|
@ -11,14 +11,14 @@ import { Provider as ReduxStoreProvider } from 'react-redux';
|
|||
import type { Store } from 'redux';
|
||||
import { NavigationProvider } from '@kbn/security-solution-navigation';
|
||||
import type { UpsellingService } from '@kbn/security-solution-upselling/service';
|
||||
import { UpsellingProvider } from '../../../../../../../common/components/upselling_provider';
|
||||
import { UserPrivilegesProvider } from '../../../../../../../common/components/user_privileges/user_privileges_context';
|
||||
import type { SecuritySolutionQueryClient } from '../../../../../../../common/containers/query_client/query_client_provider';
|
||||
import { ReactQueryClientProvider } from '../../../../../../../common/containers/query_client/query_client_provider';
|
||||
import { SecuritySolutionStartDependenciesContext } from '../../../../../../../common/components/user_privileges/endpoint/security_solution_start_dependencies';
|
||||
import { CurrentLicense } from '../../../../../../../common/components/current_license';
|
||||
import type { StartPlugins } from '../../../../../../../types';
|
||||
import { useKibana } from '../../../../../../../common/lib/kibana';
|
||||
import { UpsellingProvider } from '../upselling_provider';
|
||||
import { UserPrivilegesProvider } from '../user_privileges/user_privileges_context';
|
||||
import type { SecuritySolutionQueryClient } from '../../containers/query_client/query_client_provider';
|
||||
import { ReactQueryClientProvider } from '../../containers/query_client/query_client_provider';
|
||||
import { SecuritySolutionStartDependenciesContext } from '../user_privileges/endpoint/security_solution_start_dependencies';
|
||||
import { CurrentLicense } from '../current_license';
|
||||
import type { StartPlugins } from '../../../types';
|
||||
import { useKibana } from '../../lib/kibana';
|
||||
|
||||
export type RenderContextProvidersProps = PropsWithChildren<{
|
||||
store: Store;
|
|
@ -8,14 +8,14 @@
|
|||
import type { Dispatch, Middleware, PreloadedState, ReducersMapObject } from 'redux';
|
||||
import { applyMiddleware, combineReducers, compose, createStore } from 'redux';
|
||||
import type { CoreStart } from '@kbn/core/public';
|
||||
import { managementReducer } from '../../../../../../store/reducer';
|
||||
import { appReducer } from '../../../../../../../common/store/app';
|
||||
import { ExperimentalFeaturesService } from '../../../../../../../common/experimental_features_service';
|
||||
import { managementMiddlewareFactory } from '../../../../../../store/middleware';
|
||||
import type { StartPlugins } from '../../../../../../../types';
|
||||
import type { State } from '../../../../../../../common/store';
|
||||
import type { AppAction } from '../../../../../../../common/store/actions';
|
||||
import type { Immutable } from '../../../../../../../../common/endpoint/types';
|
||||
import { managementReducer } from '../../../management/store/reducer';
|
||||
import { appReducer } from '../../store/app';
|
||||
import { ExperimentalFeaturesService } from '../../experimental_features_service';
|
||||
import { managementMiddlewareFactory } from '../../../management/store/middleware';
|
||||
import type { StartPlugins } from '../../../types';
|
||||
import type { State } from '../../store';
|
||||
import type { AppAction } from '../../store/actions';
|
||||
import type { Immutable } from '../../../../common/endpoint/types';
|
||||
|
||||
type ComposeType = typeof compose;
|
||||
declare global {
|
|
@ -8,6 +8,9 @@
|
|||
import type { ResponseErrorAttributes } from '@kbn/core/server';
|
||||
import type { DataViewBase } from '@kbn/es-query';
|
||||
import type { FieldSpec } from '@kbn/data-views-plugin/common';
|
||||
import type { CoreStart } from '@kbn/core-lifecycle-browser';
|
||||
import type { UpsellingService } from '@kbn/security-solution-upselling/service';
|
||||
import type { StartPlugins } from '../types';
|
||||
|
||||
export interface ServerApiError {
|
||||
statusCode: number;
|
||||
|
@ -32,3 +35,11 @@ export interface SecuritySolutionDataViewBase extends DataViewBase {
|
|||
|
||||
export type AlertWorkflowStatus = 'open' | 'closed' | 'acknowledged';
|
||||
export type Refetch = () => void;
|
||||
|
||||
export interface FleetUiExtensionGetterOptions {
|
||||
coreStart: CoreStart;
|
||||
depsStart: Pick<StartPlugins, 'data' | 'fleet'>;
|
||||
services: {
|
||||
upsellingService: UpsellingService;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import { lazy } from 'react';
|
||||
import type { FleetUiExtensionGetterOptions } from './types';
|
||||
import type { FleetUiExtensionGetterOptions } from '../../../../../common/types';
|
||||
|
||||
export const getLazyEndpointAgentTamperProtectionExtension = ({
|
||||
coreStart,
|
||||
|
@ -16,7 +16,7 @@ export const getLazyEndpointAgentTamperProtectionExtension = ({
|
|||
lazy(async () => {
|
||||
const [{ withSecurityContext }, { EndpointAgentTamperProtectionExtension }] = await Promise.all(
|
||||
[
|
||||
import('./components/with_security_context/with_security_context'),
|
||||
import('../../../../../common/components/with_security_context/with_security_context'),
|
||||
import('./endpoint_agent_tamper_protection_extension'),
|
||||
]
|
||||
);
|
||||
|
|
|
@ -10,7 +10,7 @@ import type {
|
|||
PackageGenericErrorsListComponent,
|
||||
PackageGenericErrorsListProps,
|
||||
} from '@kbn/fleet-plugin/public';
|
||||
import type { FleetUiExtensionGetterOptions } from './types';
|
||||
import type { FleetUiExtensionGetterOptions } from '../../../../../common/types';
|
||||
|
||||
export const getLazyEndpointGenericErrorsListExtension = ({
|
||||
coreStart,
|
||||
|
@ -19,7 +19,7 @@ export const getLazyEndpointGenericErrorsListExtension = ({
|
|||
}: FleetUiExtensionGetterOptions) => {
|
||||
return lazy<PackageGenericErrorsListComponent>(async () => {
|
||||
const [{ withSecurityContext }, { EndpointGenericErrorsList }] = await Promise.all([
|
||||
import('./components/with_security_context/with_security_context'),
|
||||
import('../../../../../common/components/with_security_context/with_security_context'),
|
||||
import('./endpoint_generic_errors_list'),
|
||||
]);
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import { lazy } from 'react';
|
||||
import type { PackageCustomExtensionComponent } from '@kbn/fleet-plugin/public';
|
||||
import type { FleetUiExtensionGetterOptions } from './types';
|
||||
import type { FleetUiExtensionGetterOptions } from '../../../../../common/types';
|
||||
|
||||
export const getLazyEndpointPackageCustomExtension = ({
|
||||
coreStart,
|
||||
|
@ -16,7 +16,7 @@ export const getLazyEndpointPackageCustomExtension = ({
|
|||
}: FleetUiExtensionGetterOptions) => {
|
||||
return lazy<PackageCustomExtensionComponent>(async () => {
|
||||
const [{ withSecurityContext }, { EndpointPackageCustomExtension }] = await Promise.all([
|
||||
import('./components/with_security_context/with_security_context'),
|
||||
import('../../../../../common/components/with_security_context/with_security_context'),
|
||||
import('./endpoint_package_custom_extension'),
|
||||
]);
|
||||
return {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import { lazy } from 'react';
|
||||
import type { PackagePolicyCreateExtensionComponent } from '@kbn/fleet-plugin/public';
|
||||
import type { FleetUiExtensionGetterOptions } from './types';
|
||||
import type { FleetUiExtensionGetterOptions } from '../../../../../common/types';
|
||||
|
||||
export const getLazyEndpointPolicyCreateExtension = ({
|
||||
coreStart,
|
||||
|
@ -16,7 +16,7 @@ export const getLazyEndpointPolicyCreateExtension = ({
|
|||
}: FleetUiExtensionGetterOptions) => {
|
||||
return lazy<PackagePolicyCreateExtensionComponent>(async () => {
|
||||
const [{ withSecurityContext }, { EndpointPolicyCreateExtension }] = await Promise.all([
|
||||
import('./components/with_security_context/with_security_context'),
|
||||
import('../../../../../common/components/with_security_context/with_security_context'),
|
||||
import('./endpoint_policy_create_extension'),
|
||||
]);
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import type {
|
|||
PackagePolicyEditExtensionComponent,
|
||||
PackagePolicyEditExtensionComponentProps,
|
||||
} from '@kbn/fleet-plugin/public';
|
||||
import type { FleetUiExtensionGetterOptions } from './types';
|
||||
import type { FleetUiExtensionGetterOptions } from '../../../../../common/types';
|
||||
|
||||
export const getLazyEndpointPolicyEditExtension = ({
|
||||
coreStart,
|
||||
|
@ -19,7 +19,7 @@ export const getLazyEndpointPolicyEditExtension = ({
|
|||
}: FleetUiExtensionGetterOptions) => {
|
||||
return lazy<PackagePolicyEditExtensionComponent>(async () => {
|
||||
const [{ withSecurityContext }, { EndpointPolicyEditExtension }] = await Promise.all([
|
||||
import('./components/with_security_context/with_security_context'),
|
||||
import('../../../../../common/components/with_security_context/with_security_context'),
|
||||
import('./endpoint_policy_edit_extension/endpoint_policy_edit_extension'),
|
||||
]);
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import type {
|
|||
PackagePolicyResponseExtensionComponent,
|
||||
PackagePolicyResponseExtensionComponentProps,
|
||||
} from '@kbn/fleet-plugin/public';
|
||||
import type { FleetUiExtensionGetterOptions } from './types';
|
||||
import type { FleetUiExtensionGetterOptions } from '../../../../../common/types';
|
||||
|
||||
export const getLazyEndpointPolicyResponseExtension = ({
|
||||
coreStart,
|
||||
|
@ -19,7 +19,7 @@ export const getLazyEndpointPolicyResponseExtension = ({
|
|||
}: FleetUiExtensionGetterOptions) => {
|
||||
return lazy<PackagePolicyResponseExtensionComponent>(async () => {
|
||||
const [{ withSecurityContext }, { EndpointPolicyResponseExtension }] = await Promise.all([
|
||||
import('./components/with_security_context/with_security_context'),
|
||||
import('../../../../../common/components/with_security_context/with_security_context'),
|
||||
import('./endpoint_policy_response_extension'),
|
||||
]);
|
||||
|
||||
|
|
|
@ -16,9 +16,9 @@ import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common';
|
|||
import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render';
|
||||
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
|
||||
import { deepFreeze } from '@kbn/std';
|
||||
import { createFleetContextReduxStore } from '../../../../../common/components/with_security_context/store';
|
||||
import type { AppContextTestRender, UiRender } from '../../../../../common/mock/endpoint';
|
||||
import { createAppRootMockRenderer } from '../../../../../common/mock/endpoint';
|
||||
import { createFleetContextReduxStore } from './components/with_security_context/store';
|
||||
import type { ExperimentalFeatures } from '../../../../../../common/experimental_features';
|
||||
import { allowedExperimentalValues } from '../../../../../../common/experimental_features';
|
||||
import type { State } from '../../../../../common/store';
|
||||
|
@ -26,7 +26,7 @@ import { mockGlobalState } from '../../../../../common/mock';
|
|||
import { managementReducer } from '../../../../store/reducer';
|
||||
import { appReducer } from '../../../../../common/store/app';
|
||||
import { ExperimentalFeaturesService } from '../../../../../common/experimental_features_service';
|
||||
import { RenderContextProviders } from './components/with_security_context/render_context_providers';
|
||||
import { RenderContextProviders } from '../../../../../common/components/with_security_context/render_context_providers';
|
||||
import type { AppAction } from '../../../../../common/store/actions';
|
||||
|
||||
// Defined a private custom reducer that reacts to an action that enables us to update the
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
/*
|
||||
* 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 type { CoreStart } from '@kbn/core-lifecycle-browser';
|
||||
import type { UpsellingService } from '@kbn/security-solution-upselling/service';
|
||||
import type { StartPlugins } from '../../../../../types';
|
||||
|
||||
export interface FleetUiExtensionGetterOptions {
|
||||
coreStart: CoreStart;
|
||||
depsStart: Pick<StartPlugins, 'data' | 'fleet'>;
|
||||
services: {
|
||||
upsellingService: UpsellingService;
|
||||
};
|
||||
}
|
|
@ -20,8 +20,8 @@ import type {
|
|||
import { DEFAULT_APP_CATEGORIES } from '@kbn/core/public';
|
||||
import { Storage } from '@kbn/kibana-utils-plugin/public';
|
||||
import type { TriggersAndActionsUIPublicPluginSetup } from '@kbn/triggers-actions-ui-plugin/public';
|
||||
import { getLazyCloudSecurityPosturePliAuthBlockExtension } from './cloud_security_posture/lazy_cloud_security_posture_pli_auth_block_extension';
|
||||
import { getLazyEndpointAgentTamperProtectionExtension } from './management/pages/policy/view/ingest_manager_integration/lazy_endpoint_agent_tamper_protection_extension';
|
||||
import type { FleetUiExtensionGetterOptions } from './management/pages/policy/view/ingest_manager_integration/types';
|
||||
import type {
|
||||
PluginSetup,
|
||||
PluginStart,
|
||||
|
@ -39,7 +39,7 @@ import { APP_ID, APP_UI_ID, APP_PATH, APP_ICON_SOLUTION } from '../common/consta
|
|||
import type { AppLinkItems } from './common/links';
|
||||
import { updateAppLinks, type LinksPermissions } from './common/links';
|
||||
import { registerDeepLinksUpdater } from './common/links/deep_links';
|
||||
import type { SecuritySolutionUiConfigType } from './common/types';
|
||||
import type { FleetUiExtensionGetterOptions, SecuritySolutionUiConfigType } from './common/types';
|
||||
|
||||
import { getLazyEndpointPolicyEditExtension } from './management/pages/policy/view/ingest_manager_integration/lazy_endpoint_policy_edit_extension';
|
||||
import { getLazyEndpointPolicyCreateExtension } from './management/pages/policy/view/ingest_manager_integration/lazy_endpoint_policy_create_extension';
|
||||
|
@ -263,6 +263,12 @@ export class Plugin implements IPlugin<PluginSetup, PluginStart, SetupPlugins, S
|
|||
Component: getLazyEndpointAgentTamperProtectionExtension(registerOptions),
|
||||
});
|
||||
|
||||
registerExtension({
|
||||
package: 'cloud_security_posture',
|
||||
view: 'pli-auth-block',
|
||||
Component: getLazyCloudSecurityPosturePliAuthBlockExtension(registerOptions),
|
||||
});
|
||||
|
||||
registerExtension({
|
||||
package: 'cribl',
|
||||
view: 'package-policy-replace-define-step',
|
||||
|
|
|
@ -44,7 +44,7 @@ export const PLI_PRODUCT_FEATURES: PliProductFeatures = {
|
|||
],
|
||||
},
|
||||
cloud: {
|
||||
essentials: [],
|
||||
essentials: [ProductFeatureKey.cloudSecurityPosture],
|
||||
complete: [],
|
||||
},
|
||||
} as const;
|
||||
|
|
|
@ -20,6 +20,13 @@ import type {
|
|||
UpsellingSectionId,
|
||||
} from '@kbn/security-solution-upselling/service/types';
|
||||
import React from 'react';
|
||||
import { CloudSecurityPostureIntegrationPliBlockLazy } from './sections/cloud_security_posture';
|
||||
import {
|
||||
EndpointAgentTamperProtectionLazy,
|
||||
EndpointPolicyProtectionsLazy,
|
||||
EndpointProtectionUpdatesLazy,
|
||||
RuleDetailsEndpointExceptionsLazy,
|
||||
} from './sections/endpoint_management';
|
||||
import type { SecurityProductTypes } from '../../common/config';
|
||||
import { getProductProductFeatures } from '../../common/pli/pli_features';
|
||||
import type { Services } from '../common/services';
|
||||
|
@ -32,12 +39,6 @@ import {
|
|||
OsqueryResponseActionsUpsellingSectionLazy,
|
||||
ThreatIntelligencePaywallLazy,
|
||||
} from './lazy_upselling';
|
||||
import {
|
||||
EndpointAgentTamperProtectionLazy,
|
||||
EndpointPolicyProtectionsLazy,
|
||||
EndpointProtectionUpdatesLazy,
|
||||
RuleDetailsEndpointExceptionsLazy,
|
||||
} from './sections/endpoint_management';
|
||||
import * as i18n from './translations';
|
||||
|
||||
interface UpsellingsConfig {
|
||||
|
@ -160,6 +161,11 @@ export const upsellingSections: UpsellingSections = [
|
|||
pli: ProductFeatureKey.endpointProtectionUpdates,
|
||||
component: EndpointProtectionUpdatesLazy,
|
||||
},
|
||||
{
|
||||
id: 'cloud_security_posture_integration_installation',
|
||||
pli: ProductFeatureKey.cloudSecurityPosture,
|
||||
component: CloudSecurityPostureIntegrationPliBlockLazy,
|
||||
},
|
||||
{
|
||||
id: 'entity_analytics_panel',
|
||||
pli: ProductFeatureKey.advancedInsights,
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* 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, { memo } from 'react';
|
||||
import { EuiCard, EuiIcon, EuiSpacer } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
/**
|
||||
* Component displayed when a given product tier is not allowed to use Cloud Security Posture Integrations installation forms.
|
||||
*/
|
||||
export const CloudSecurityPostureIntegrationPliBlock = memo(() => {
|
||||
// TODO: prefer to use getProductTypeByPLI(ProductFeatureKey.cloudSecurityPosture) after we change returned text to include "Protection"
|
||||
const requiredPLI = 'Cloud Protection Essentials';
|
||||
|
||||
return (
|
||||
<>
|
||||
<EuiSpacer size="s" />
|
||||
<EuiCard
|
||||
data-test-subj="cloud-security-posture-integration-pli-auth-block"
|
||||
isDisabled={true}
|
||||
description={false}
|
||||
icon={<EuiIcon size="xl" type="lock" />}
|
||||
betaBadgeProps={{
|
||||
label: i18n.translate(
|
||||
'xpack.securitySolutionServerless.cloudSecurityPostureIntegrationPliBlock.badgeText',
|
||||
{
|
||||
defaultMessage: 'Cloud Protection Essentials',
|
||||
}
|
||||
),
|
||||
}}
|
||||
title={
|
||||
<h3>
|
||||
<strong>
|
||||
{i18n.translate(
|
||||
'xpack.securitySolutionServerless.cloudSecurityPostureIntegrationPliBlock.cardTitle',
|
||||
{
|
||||
defaultMessage: 'Protection updates',
|
||||
}
|
||||
)}
|
||||
</strong>
|
||||
</h3>
|
||||
}
|
||||
>
|
||||
<div>
|
||||
{i18n.translate(
|
||||
'xpack.securitySolutionServerless.cloudSecurityPostureIntegrationPliBlock.cardMessage',
|
||||
{
|
||||
defaultMessage:
|
||||
'To turn on CSPM, KSPM or CNVM, view your Cloud Posture Dashboards and generate findings of misconfiguration or vulnerabilities in your cloud environment, you must add {requiredPLI} under Manage --> Project features.',
|
||||
values: {
|
||||
requiredPLI,
|
||||
},
|
||||
}
|
||||
)}
|
||||
</div>
|
||||
</EuiCard>
|
||||
</>
|
||||
);
|
||||
});
|
||||
CloudSecurityPostureIntegrationPliBlock.displayName = 'CloudSecurityPostureIntegrationPliBlock';
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* 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 { lazy } from 'react';
|
||||
|
||||
export const CloudSecurityPostureIntegrationPliBlockLazy = lazy(() =>
|
||||
import('./cloud_security_posture_integration_pli_block').then(
|
||||
({ CloudSecurityPostureIntegrationPliBlock }) => ({
|
||||
default: CloudSecurityPostureIntegrationPliBlock,
|
||||
})
|
||||
)
|
||||
);
|
|
@ -201,6 +201,10 @@ export function AddCisIntegrationFormPageProvider({
|
|||
return await testSubjects.find('confirmModalTitleText');
|
||||
};
|
||||
|
||||
const checkIntegrationPliAuthBlockExists = async () => {
|
||||
return await testSubjects.exists('cloud-security-posture-integration-pli-auth-block');
|
||||
};
|
||||
|
||||
const fillInTextField = async (selector: string, text: string) => {
|
||||
const textField = await testSubjects.find(selector);
|
||||
await textField.type(text);
|
||||
|
@ -282,5 +286,6 @@ export function AddCisIntegrationFormPageProvider({
|
|||
selectValue,
|
||||
getValueInEditPage,
|
||||
isOptionChecked,
|
||||
checkIntegrationPliAuthBlockExists,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@ import type { CreateTestConfigOptions } from '../shared/types';
|
|||
export function createTestConfig(options: CreateTestConfigOptions) {
|
||||
return async ({ readConfigFile }: FtrConfigProviderContext) => {
|
||||
const svlSharedConfig = await readConfigFile(require.resolve('../shared/config.base.ts'));
|
||||
|
||||
return {
|
||||
...svlSharedConfig.getAll(),
|
||||
|
||||
|
@ -110,6 +109,9 @@ export function createTestConfig(options: CreateTestConfigOptions) {
|
|||
maintenanceWindows: {
|
||||
pathname: '/app/management/insightsAndAlerting/maintenanceWindows',
|
||||
},
|
||||
fleet: {
|
||||
pathname: '/app/fleet',
|
||||
},
|
||||
},
|
||||
// choose where screenshots should be saved
|
||||
screenshots: {
|
||||
|
|
|
@ -16,6 +16,8 @@ export default createTestConfig({
|
|||
kbnServerArgs: [
|
||||
`--xpack.fleet.packages.0.name=cloud_security_posture`,
|
||||
`--xpack.fleet.packages.0.version=${CLOUD_SECURITY_PLUGIN_VERSION}`,
|
||||
// configs the environment to run on the basic product tier, which may include PLI block components or messages
|
||||
`--xpack.securitySolutionServerless.productTypes=${JSON.stringify([])}`,
|
||||
],
|
||||
// load tests in the index file
|
||||
testFiles: [require.resolve('./ftr/cloud_security_posture')],
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* 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 { createTestConfig } from '../../config.base';
|
||||
|
||||
export default createTestConfig({
|
||||
serverlessProject: 'security',
|
||||
junit: {
|
||||
reportName: 'Serverless Security Cloud Security Functional Tests',
|
||||
},
|
||||
kbnServerArgs: [
|
||||
`--xpack.fleet.packages.0.name=cloud_security_posture`,
|
||||
`--xpack.fleet.packages.0.version=1.5.2`,
|
||||
`--xpack.securitySolutionServerless.productTypes=${JSON.stringify([
|
||||
{ product_line: 'security', product_tier: 'essentials' },
|
||||
{ product_line: 'endpoint', product_tier: 'essentials' },
|
||||
{ product_line: 'cloud', product_tier: 'essentials' },
|
||||
])}`,
|
||||
],
|
||||
// we should only resolve files which are ending with `.essentials.ts`
|
||||
testFiles: [require.resolve('./ftr/cloud_security_posture/csp_integrations_form.essentials.ts')],
|
||||
});
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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 expect from '@kbn/expect';
|
||||
import type { FtrProviderContext } from '../../../../ftr_provider_context';
|
||||
|
||||
export default function (providerContext: FtrProviderContext) {
|
||||
const { getPageObjects } = providerContext;
|
||||
const pageObjects = getPageObjects(['cisAddIntegration', 'header', 'svlCommonPage']);
|
||||
|
||||
describe('[Essentials PLI] Test Cloud Security Posture Integrations on Serverless', function () {
|
||||
this.tags(['skipMKI']);
|
||||
let cisIntegration: typeof pageObjects.cisAddIntegration;
|
||||
|
||||
before(async () => {
|
||||
await pageObjects.svlCommonPage.login();
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
cisIntegration = pageObjects.cisAddIntegration;
|
||||
await cisIntegration.navigateToAddIntegrationCspmPage();
|
||||
});
|
||||
|
||||
it('[Essentials PLI] Integration installation form should be available with Essentials or Complete PLI', async () => {
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
const pliBlockExists = await cisIntegration.checkIntegrationPliAuthBlockExists();
|
||||
|
||||
expect(pliBlockExists).to.be(false);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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 expect from '@kbn/expect';
|
||||
import type { FtrProviderContext } from '../../../../ftr_provider_context';
|
||||
|
||||
export default function (providerContext: FtrProviderContext) {
|
||||
const { getPageObjects } = providerContext;
|
||||
const pageObjects = getPageObjects(['cisAddIntegration', 'header', 'svlCommonPage']);
|
||||
|
||||
describe('Test Cloud Security Posture Integrations on Serverless', function () {
|
||||
this.tags(['skipMKI']);
|
||||
let cisIntegration: typeof pageObjects.cisAddIntegration;
|
||||
|
||||
before(async () => {
|
||||
await pageObjects.svlCommonPage.login();
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
cisIntegration = pageObjects.cisAddIntegration;
|
||||
await cisIntegration.navigateToAddIntegrationCspmPage();
|
||||
});
|
||||
|
||||
it('Integration installation form should not be available without required PLI', async () => {
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
const pliBlockExists = await cisIntegration.checkIntegrationPliAuthBlockExists();
|
||||
|
||||
expect(pliBlockExists).to.be(true);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -10,6 +10,9 @@ import { FtrProviderContext } from '../../../../ftr_provider_context';
|
|||
export default function ({ loadTestFile }: FtrProviderContext) {
|
||||
describe('cloud_security_posture', function () {
|
||||
this.tags(['cloud_security_posture']);
|
||||
|
||||
// do not resolve files which are ending with `.essentials.ts`
|
||||
loadTestFile(require.resolve('./compliance_dashboard'));
|
||||
loadTestFile(require.resolve('./csp_integrations_form'));
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue