From 4b542d462970d457fb094988d9e58718146b90bb Mon Sep 17 00:00:00 2001 From: seanrathier Date: Wed, 9 Oct 2024 08:52:03 -0400 Subject: [PATCH] [Cloud Security] Render Setup Technology Selector based on deployment mode (#194347) (cherry picked from commit 2609a533fa950b9e7974d704fa0c3f9986816dbe) --- .../common/constants.ts | 2 +- .../fleet_extensions/policy_template_form.tsx | 7 ++ .../policy_template_selectors.tsx | 6 +- .../use_setup_technology.ts | 3 +- .../single_page_layout/index.tsx | 4 +- .../edit_package_policy_page/index.tsx | 7 +- .../agentless/index.ts | 16 ++++ .../agentless/security_posture.ts | 87 +++++++++++++++++++ .../config.agentless.ts | 5 +- .../add_cis_integration_form_page.ts | 22 +++++ .../agentless/cis_integration_aws.ts | 28 ------ .../agentless/cis_integration_gcp.ts | 24 ----- 12 files changed, 150 insertions(+), 61 deletions(-) create mode 100644 x-pack/test/cloud_security_posture_functional/agentless/index.ts create mode 100644 x-pack/test/cloud_security_posture_functional/agentless/security_posture.ts diff --git a/x-pack/plugins/cloud_security_posture/common/constants.ts b/x-pack/plugins/cloud_security_posture/common/constants.ts index d415d4cfcfc69..474f29b859305 100644 --- a/x-pack/plugins/cloud_security_posture/common/constants.ts +++ b/x-pack/plugins/cloud_security_posture/common/constants.ts @@ -171,4 +171,4 @@ export const SINGLE_ACCOUNT = 'single-account'; export const CLOUD_SECURITY_PLUGIN_VERSION = '1.9.0'; // Cloud Credentials Template url was implemented in 1.10.0-preview01. See PR - https://github.com/elastic/integrations/pull/9828 -export const CLOUD_CREDENTIALS_PACKAGE_VERSION = '1.10.0-preview01'; +export const CLOUD_CREDENTIALS_PACKAGE_VERSION = '1.11.0-preview10'; diff --git a/x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/policy_template_form.tsx b/x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/policy_template_form.tsx index 721c4ca147aee..73d8ed22011dc 100644 --- a/x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/policy_template_form.tsx +++ b/x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/policy_template_form.tsx @@ -674,6 +674,7 @@ export const CspPolicyTemplateForm = memo ({ id: v, label: getPolicyTemplateLabel(v) }))} + options={Array.from(policyTemplates, (v) => ({ + id: v, + label: getPolicyTemplateLabel(v), + testId: `policy-template-radio-button-${v}`, + }))} idSelected={selectedTemplate} onChange={(id: CloudSecurityPolicyTemplate) => setPolicyTemplate(id)} disabled={disabled} diff --git a/x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/setup_technology_selector/use_setup_technology.ts b/x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/setup_technology_selector/use_setup_technology.ts index 8b6a190827f2e..e18119c3a39de 100644 --- a/x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/setup_technology_selector/use_setup_technology.ts +++ b/x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/setup_technology_selector/use_setup_technology.ts @@ -27,7 +27,8 @@ export const useSetupTechnology = ({ const isAgentlessSupportedForCloudProvider = isCspmAws || isCspmGcp || isCspmAzure; const isAgentlessAvailable = isAgentlessSupportedForCloudProvider && isAgentlessEnabled; const defaultSetupTechnology = - isEditPage && isAgentlessEnabled ? SetupTechnology.AGENTLESS : SetupTechnology.AGENT_BASED; + isEditPage && isAgentlessAvailable ? SetupTechnology.AGENTLESS : SetupTechnology.AGENT_BASED; + const [setupTechnology, setSetupTechnology] = useState(defaultSetupTechnology); const updateSetupTechnology = (value: SetupTechnology) => { diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.tsx index 3070b0961ab6d..24f8fa8a04fe5 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.tsx @@ -350,7 +350,7 @@ export const CreatePackagePolicySinglePage: CreatePackagePolicyParams = ({ "'package-policy-create' and 'package-policy-replace-define-step' cannot both be registered as UI extensions" ); } - const { isAgentlessEnabled, isAgentlessIntegration } = useAgentless(); + const { isAgentlessIntegration } = useAgentless(); const { handleSetupTechnologyChange, selectedSetupTechnology } = useSetupTechnology({ newAgentPolicy, setNewAgentPolicy, @@ -374,7 +374,7 @@ export const CreatePackagePolicySinglePage: CreatePackagePolicyParams = ({ validationResults={validationResults} isEditPage={false} handleSetupTechnologyChange={handleSetupTechnologyChange} - isAgentlessEnabled={isAgentlessEnabled} + isAgentlessEnabled={isAgentlessIntegration(packageInfo)} /> ) diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/index.tsx index e448d1376b2fe..6157f09968680 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/index.tsx @@ -103,7 +103,7 @@ export const EditPackagePolicyForm = memo<{ } = useConfig(); const { getHref } = useLink(); const { canUseMultipleAgentPolicies } = useMultipleAgentPolicies(); - const { isAgentlessAgentPolicy } = useAgentless(); + const { isAgentlessAgentPolicy, isAgentlessIntegration } = useAgentless(); const { // data agentPolicies: existingAgentPolicies, @@ -130,9 +130,10 @@ export const EditPackagePolicyForm = memo<{ const hasAgentlessAgentPolicy = useMemo( () => existingAgentPolicies.length === 1 - ? existingAgentPolicies.some((policy) => isAgentlessAgentPolicy(policy)) + ? existingAgentPolicies.some((policy) => isAgentlessAgentPolicy(policy)) && + isAgentlessIntegration(packageInfo) : false, - [existingAgentPolicies, isAgentlessAgentPolicy] + [existingAgentPolicies, isAgentlessAgentPolicy, packageInfo, isAgentlessIntegration] ); const canWriteIntegrationPolicies = useAuthz().integrations.writeIntegrationPolicies; diff --git a/x-pack/test/cloud_security_posture_functional/agentless/index.ts b/x-pack/test/cloud_security_posture_functional/agentless/index.ts new file mode 100644 index 0000000000000..02f10dc5cc348 --- /dev/null +++ b/x-pack/test/cloud_security_posture_functional/agentless/index.ts @@ -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 { FtrProviderContext } from '../ftr_provider_context'; + +// eslint-disable-next-line import/no-default-export +export default function ({ loadTestFile }: FtrProviderContext) { + describe('Cloud Security Posture', function () { + loadTestFile(require.resolve('./create_agent')); + loadTestFile(require.resolve('./security_posture')); + }); +} diff --git a/x-pack/test/cloud_security_posture_functional/agentless/security_posture.ts b/x-pack/test/cloud_security_posture_functional/agentless/security_posture.ts new file mode 100644 index 0000000000000..c7ee5ff8400e6 --- /dev/null +++ b/x-pack/test/cloud_security_posture_functional/agentless/security_posture.ts @@ -0,0 +1,87 @@ +/* + * 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 { CLOUD_CREDENTIALS_PACKAGE_VERSION } from '@kbn/cloud-security-posture-plugin/common/constants'; +import expect from '@kbn/expect'; +import type { FtrProviderContext } from '../ftr_provider_context'; +// eslint-disable-next-line import/no-default-export +export default function ({ getPageObjects, getService }: FtrProviderContext) { + const testSubjects = getService('testSubjects'); + const pageObjects = getPageObjects([ + 'common', + 'cspSecurity', + 'security', + 'header', + 'cisAddIntegration', + ]); + + const KSPM_RADIO_OPTION = 'policy-template-radio-button-kspm'; + const CSPM_RADIO_OPTION = 'policy-template-radio-button-cspm'; + const CNVM_RADIO_OPTION = 'policy-template-radio-button-vuln_mgmt'; + + const POLICY_NAME_FIELD = 'createAgentPolicyNameField'; + const SETUP_TECHNOLOGY_SELECTOR = 'setup-technology-selector-accordion'; + + describe('Agentless Security Posture Integration Options', function () { + let cisIntegration: typeof pageObjects.cisAddIntegration; + + before(async () => { + cisIntegration = pageObjects.cisAddIntegration; + }); + + after(async () => { + await pageObjects.cspSecurity.logout(); + }); + + it(`should show kspm without agentless option`, async () => { + await cisIntegration.navigateToAddIntegrationWithVersionPage( + CLOUD_CREDENTIALS_PACKAGE_VERSION + ); + + await cisIntegration.clickOptionButton(KSPM_RADIO_OPTION); + await pageObjects.header.waitUntilLoadingHasFinished(); + + const hasSetupTechnologySelector = await testSubjects.exists(SETUP_TECHNOLOGY_SELECTOR); + const hasAgentBased = await testSubjects.exists(POLICY_NAME_FIELD); + + expect(hasSetupTechnologySelector).to.be(false); + expect(hasAgentBased).to.be(true); + }); + + it(`should show cnvm without agentless option`, async () => { + // const integrationPolicyName = `cloud_security_posture-${new Date().toISOString()}`; + await cisIntegration.navigateToAddIntegrationWithVersionPage( + CLOUD_CREDENTIALS_PACKAGE_VERSION + ); + + await cisIntegration.clickOptionButton(CNVM_RADIO_OPTION); + await pageObjects.header.waitUntilLoadingHasFinished(); + + const hasSetupTechnologySelector = await testSubjects.exists(SETUP_TECHNOLOGY_SELECTOR); + const hasAgentBased = await testSubjects.exists(POLICY_NAME_FIELD); + + expect(hasSetupTechnologySelector).to.be(false); + expect(hasAgentBased).to.be(true); + }); + + it(`should show cspm with agentless option`, async () => { + // const integrationPolicyName = `cloud_security_posture-${new Date().toISOString()}`; + await cisIntegration.navigateToAddIntegrationWithVersionPage( + CLOUD_CREDENTIALS_PACKAGE_VERSION + ); + + await cisIntegration.clickOptionButton(CSPM_RADIO_OPTION); + await pageObjects.header.waitUntilLoadingHasFinished(); + + const hasSetupTechnologySelector = await testSubjects.exists(SETUP_TECHNOLOGY_SELECTOR); + const hasAgentBased = await testSubjects.exists(POLICY_NAME_FIELD); + + expect(hasSetupTechnologySelector).to.be(true); + expect(hasAgentBased).to.be(true); + }); + }); +} diff --git a/x-pack/test/cloud_security_posture_functional/config.agentless.ts b/x-pack/test/cloud_security_posture_functional/config.agentless.ts index 341ef6a9905b7..498de6d888223 100644 --- a/x-pack/test/cloud_security_posture_functional/config.agentless.ts +++ b/x-pack/test/cloud_security_posture_functional/config.agentless.ts @@ -7,6 +7,7 @@ import type { FtrConfigProviderContext } from '@kbn/test'; import { CA_CERT_PATH, KBN_CERT_PATH, KBN_KEY_PATH } from '@kbn/dev-utils'; +import { CLOUD_CREDENTIALS_PACKAGE_VERSION } from '@kbn/cloud-security-posture-plugin/common/constants'; import { pageObjects } from './page_objects'; export default async function ({ readConfigFile }: FtrConfigProviderContext) { @@ -30,9 +31,11 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { `--xpack.fleet.agentless.api.tls.key=${KBN_KEY_PATH}`, `--xpack.fleet.agentless.api.tls.ca=${CA_CERT_PATH}`, `--xpack.cloud.id=something-anything`, + `--xpack.fleet.packages.0.name=cloud_security_posture`, + `--xpack.fleet.packages.0.version=${CLOUD_CREDENTIALS_PACKAGE_VERSION}`, ], }, // load tests in the index file - testFiles: [require.resolve('./agentless/create_agent.ts')], + testFiles: [require.resolve('./agentless')], }; } diff --git a/x-pack/test/cloud_security_posture_functional/page_objects/add_cis_integration_form_page.ts b/x-pack/test/cloud_security_posture_functional/page_objects/add_cis_integration_form_page.ts index e3ef420055196..563507d705583 100644 --- a/x-pack/test/cloud_security_posture_functional/page_objects/add_cis_integration_form_page.ts +++ b/x-pack/test/cloud_security_posture_functional/page_objects/add_cis_integration_form_page.ts @@ -154,6 +154,27 @@ export function AddCisIntegrationFormPageProvider({ await PageObjects.header.waitUntilLoadingHasFinished(); }; + const navigateToAddIntegrationWithVersionPage = async ( + packageVersion: string, + space?: string + ) => { + const options = space + ? { + basePath: `/s/${space}`, + shouldUseHashForSubUrl: false, + } + : { + shouldUseHashForSubUrl: false, + }; + + await PageObjects.common.navigateToUrl( + 'fleet', + `integrations/cloud_security_posture-${packageVersion}/add-integration`, + options + ); + await PageObjects.header.waitUntilLoadingHasFinished(); + }; + const navigateToAddIntegrationCspmWithVersionPage = async ( packageVersion: string, space?: string @@ -505,6 +526,7 @@ export function AddCisIntegrationFormPageProvider({ cisAzure, cisAws, cisGcp, + navigateToAddIntegrationWithVersionPage, navigateToAddIntegrationCspmPage, navigateToAddIntegrationCspmWithVersionPage, navigateToAddIntegrationCnvmPage, diff --git a/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/cis_integration_aws.ts b/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/cis_integration_aws.ts index 90991304936ea..e669545d135f9 100644 --- a/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/cis_integration_aws.ts +++ b/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/cis_integration_aws.ts @@ -27,7 +27,6 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { let cisIntegrationAws: typeof pageObjects.cisAddIntegration.cisAws; let testSubjectIds: typeof pageObjects.cisAddIntegration.testSubjectIds; let mockApiServer: http.Server; - const previousPackageVersion = '1.9.0'; before(async () => { mockApiServer = mockAgentlessApiService.listen(8089); @@ -66,20 +65,6 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { (await cisIntegrationAws.showLaunchCloudFormationAgentlessButton()) !== undefined ).to.be(true); }); - - it(`should hide CIS_AWS Launch Cloud formation button when credentials selector is temporary keys and package version is less than ${previousPackageVersion}`, async () => { - await cisIntegration.navigateToAddIntegrationCspmWithVersionPage(previousPackageVersion); - - await cisIntegration.clickOptionButton(testSubjectIds.CIS_AWS_OPTION_TEST_ID); - await cisIntegration.clickOptionButton(testSubjectIds.AWS_SINGLE_ACCOUNT_TEST_ID); - await cisIntegration.selectSetupTechnology('agentless'); - - await cisIntegration.selectAwsCredentials('temporary'); - - await pageObjects.header.waitUntilLoadingHasFinished(); - - expect(await cisIntegrationAws.showLaunchCloudFormationAgentlessButton()).to.be(false); - }); }); describe('Serverless - Agentless CIS_AWS ORG Account Launch Cloud formation', () => { @@ -100,19 +85,6 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { expect(await cisIntegrationAws.showLaunchCloudFormationAgentlessButton()).to.be(true); }); - - it(`should hide CIS_AWS Launch Cloud formation button when credentials selector is temporary keys and package version is less than ${previousPackageVersion}`, async () => { - await cisIntegration.navigateToAddIntegrationCspmWithVersionPage(previousPackageVersion); - - await cisIntegration.clickOptionButton(testSubjectIds.CIS_AWS_OPTION_TEST_ID); - await cisIntegration.selectSetupTechnology('agentless'); - - await cisIntegration.selectAwsCredentials('temporary'); - - await pageObjects.header.waitUntilLoadingHasFinished(); - - expect(await cisIntegrationAws.showLaunchCloudFormationAgentlessButton()).to.be(false); - }); }); // TODO: Migrate test after Serverless default agentless policy is deleted. diff --git a/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/cis_integration_gcp.ts b/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/cis_integration_gcp.ts index 85a45f67bf9cc..95f855697c5bd 100644 --- a/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/cis_integration_gcp.ts +++ b/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/cis_integration_gcp.ts @@ -14,7 +14,6 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const pageObjects = getPageObjects(['common', 'svlCommonPage', 'cisAddIntegration', 'header']); const supertest = getService('supertest'); - const previousPackageVersion = '1.9.0'; describe('Agentless CIS Integration Page', function () { // TODO: we need to check if the tests are running on MKI. There is a suspicion that installing csp package via Kibana server args is not working on MKI. @@ -60,18 +59,6 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { expect(await cisIntegrationGcp.showLaunchCloudShellAgentlessButton()).to.be(true); }); - - it(`should hide CIS_GCP Launch Cloud Shell button when package version is less than ${CLOUD_CREDENTIALS_PACKAGE_VERSION}`, async () => { - await cisIntegration.navigateToAddIntegrationCspmWithVersionPage(previousPackageVersion); - - await cisIntegration.clickOptionButton(testSubjectIds.CIS_GCP_OPTION_TEST_ID); - await cisIntegration.clickOptionButton(testSubjectIds.GCP_SINGLE_ACCOUNT_TEST_ID); - await cisIntegration.selectSetupTechnology('agentless'); - - await pageObjects.header.waitUntilLoadingHasFinished(); - - expect(await cisIntegrationGcp.showLaunchCloudShellAgentlessButton()).to.be(false); - }); }); describe('Agentless CIS_GCP ORG Account Launch Cloud Shell', () => { @@ -87,17 +74,6 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { expect(await cisIntegrationGcp.showLaunchCloudShellAgentlessButton()).to.be(true); }); - - it(`should hide CIS_GCP Launch Cloud shell button when package version is ${previousPackageVersion}`, async () => { - await cisIntegration.navigateToAddIntegrationCspmWithVersionPage(previousPackageVersion); - - await cisIntegration.clickOptionButton(testSubjectIds.CIS_GCP_OPTION_TEST_ID); - await cisIntegration.selectSetupTechnology('agentless'); - - await pageObjects.header.waitUntilLoadingHasFinished(); - - expect(await cisIntegrationGcp.showLaunchCloudShellAgentlessButton()).to.be(false); - }); }); describe.skip('Serverless - Agentless CIS_GCP edit flow', () => {