From 2c7724b1068cc3265cc49692e3a4fc9c29b12805 Mon Sep 17 00:00:00 2001 From: Gaurav Aggarwal Date: Thu, 16 Jan 2025 08:20:22 +0000 Subject: [PATCH 1/7] feat(securitycenter): Add Resource SCC Management API Org SHA Custom Modules --- ...eateSecurityHealthAnalyticsCustomModule.js | 99 ++++++++++ ...tiveSecurityHealthAnalyticsCustomModule.js | 52 ++++++ .../getSecurityHealthAnalyticsCustomModule.js | 51 +++++ ...dateSecurityHealthAnalyticsCustomModule.js | 69 +++++++ security-center/snippets/package.json | 3 +- ...ecurityHealthAnalyticsCustomModule.test.js | 175 ++++++++++++++++++ 6 files changed, 448 insertions(+), 1 deletion(-) create mode 100644 security-center/snippets/management_api/createSecurityHealthAnalyticsCustomModule.js create mode 100644 security-center/snippets/management_api/getEffectiveSecurityHealthAnalyticsCustomModule.js create mode 100644 security-center/snippets/management_api/getSecurityHealthAnalyticsCustomModule.js create mode 100644 security-center/snippets/management_api/updateSecurityHealthAnalyticsCustomModule.js create mode 100644 security-center/snippets/system-test/management_api/securityHealthAnalyticsCustomModule.test.js diff --git a/security-center/snippets/management_api/createSecurityHealthAnalyticsCustomModule.js b/security-center/snippets/management_api/createSecurityHealthAnalyticsCustomModule.js new file mode 100644 index 0000000000..8bf2892c5e --- /dev/null +++ b/security-center/snippets/management_api/createSecurityHealthAnalyticsCustomModule.js @@ -0,0 +1,99 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +'use strict'; + +/** + * Create security health analytics custom module + */ +function main(organizationId, customModuleDisplayName, locationId = 'global') { + // [START securitycenter_create_security_health_analytics_custom_module] + // npm install '@google-cloud/securitycentermanagement' + const { + SecurityCenterManagementClient, + protos, + } = require('@google-cloud/securitycentermanagement'); + + const client = new SecurityCenterManagementClient(); + + const EnablementState = + protos.google.cloud.securitycentermanagement.v1 + .SecurityHealthAnalyticsCustomModule.EnablementState; + + const Severity = + protos.google.cloud.securitycentermanagement.v1.CustomConfig.Severity; + + /* + * Required. The name of the parent resource of security health analytics module + * Its format is + * `organizations/[organization_id]/locations/[location_id]` + * `folders/[folder_id]/locations/[location_id]` + * `projects/[project_id]/locations/[location_id]` + */ + const parent = `organizations/${organizationId}/locations/${locationId}`; + + /* + * Required. Resource name of security health analytics module. + * Its format is + * `organizations/[organization_id]/locations/[location_id]/securityHealthAnalyticsCustomModules/[custom_module]` + * `folders/[folder_id]/locations/[location_id]/securityHealthAnalyticsCustomModules/[custom_module]` + * `projects/[project_id]/locations/[location_id]/securityHealthAnalyticsCustomModules/[custom_module]` + */ + const name = `organizations/${organizationId}/locations/${locationId}/securityHealthAnalyticsCustomModules/custom_module`; + + // define the CEL expression here and this will scans for keys that have not been rotated in + // the last 30 days, change it according to the your requirements + const expr = { + expression: `has(resource.rotationPeriod) && (resource.rotationPeriod > duration('2592000s'))`, + }; + + // define the resource selector + const resourceSelector = { + resourceTypes: ['cloudkms.googleapis.com/CryptoKey'], + }; + + // define the custom module configuration, update the severity, description, + // recommendation below + const customConfig = { + predicate: expr, + resourceSelector: resourceSelector, + severity: Severity.MEDIUM, + description: 'add your description here', + recommendation: 'add your recommendation here', + }; + + // define the security health analytics custom module configuration, update the + // EnablementState below + const securityHealthAnalyticsCustomModule = { + name: name, + displayName: customModuleDisplayName, + enablementState: EnablementState.ENABLED, + customConfig: customConfig, + }; + + async function createSecurityHealthAnalyticsCustomModule() { + const [response] = await client.createSecurityHealthAnalyticsCustomModule({ + parent: parent, + securityHealthAnalyticsCustomModule: securityHealthAnalyticsCustomModule, + }); + console.log( + 'Security Health Analytics Custom Module creation succeeded: ', + response + ); + } + + createSecurityHealthAnalyticsCustomModule(); + // [END securitycenter_create_security_health_analytics_custom_module] +} + +main(...process.argv.slice(2)); diff --git a/security-center/snippets/management_api/getEffectiveSecurityHealthAnalyticsCustomModule.js b/security-center/snippets/management_api/getEffectiveSecurityHealthAnalyticsCustomModule.js new file mode 100644 index 0000000000..19302ac1e3 --- /dev/null +++ b/security-center/snippets/management_api/getEffectiveSecurityHealthAnalyticsCustomModule.js @@ -0,0 +1,52 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +'use strict'; + +/** + * Retrieve an existing effective security health analytics custom module + */ +function main(organizationId, customModuleId, locationId = 'global') { + // [START securitycenter_get_effective_security_health_analytics_custom_module] + // npm install '@google-cloud/securitycentermanagement' + const { + SecurityCenterManagementClient, + } = require('@google-cloud/securitycentermanagement'); + + const client = new SecurityCenterManagementClient(); + + /* + * Required. Resource name of security health analytics module. + * Its format is + * `organizations/[organization_id]/locations/[location_id]/effectiveSecurityHealthAnalyticsCustomModules/[custom_module]` + * `folders/[folder_id]/locations/[location_id]/effectiveSecurityHealthAnalyticsCustomModules/[custom_module]` + * `projects/[project_id]/locations/[location_id]/effectiveSecurityHealthAnalyticsCustomModules/[custom_module]` + */ + const name = `organizations/${organizationId}/locations/${locationId}/effectiveSecurityHealthAnalyticsCustomModules/${customModuleId}`; + + async function getEffectiveSecurityHealthAnalyticsCustomModule() { + const [response] = + await client.getEffectiveSecurityHealthAnalyticsCustomModule({ + name: name, + }); + console.log( + 'Security Health Analytics Custom Module get effective succeeded: ', + response + ); + } + + getEffectiveSecurityHealthAnalyticsCustomModule(); + // [END securitycenter_get_effective_security_health_analytics_custom_module] +} + +main(...process.argv.slice(2)); diff --git a/security-center/snippets/management_api/getSecurityHealthAnalyticsCustomModule.js b/security-center/snippets/management_api/getSecurityHealthAnalyticsCustomModule.js new file mode 100644 index 0000000000..086f95103b --- /dev/null +++ b/security-center/snippets/management_api/getSecurityHealthAnalyticsCustomModule.js @@ -0,0 +1,51 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +'use strict'; + +/** + * Retrieve an existing security health analytics custom module + */ +function main(organizationId, customModuleId, locationId = 'global') { + // [START securitycenter_get_security_health_analytics_custom_module] + // npm install '@google-cloud/securitycentermanagement' + const { + SecurityCenterManagementClient, + } = require('@google-cloud/securitycentermanagement'); + + const client = new SecurityCenterManagementClient(); + + /* + * Required. Resource name of security health analytics module. + * Its format is + * `organizations/[organization_id]/locations/[location_id]/securityHealthAnalyticsCustomModules/[custom_module]` + * `folders/[folder_id]/locations/[location_id]/securityHealthAnalyticsCustomModules/[custom_module]` + * `projects/[project_id]/locations/[location_id]/securityHealthAnalyticsCustomModules/[custom_module]` + */ + const name = `organizations/${organizationId}/locations/${locationId}/securityHealthAnalyticsCustomModules/${customModuleId}`; + + async function getSecurityHealthAnalyticsCustomModule() { + const [response] = await client.getSecurityHealthAnalyticsCustomModule({ + name: name, + }); + console.log( + 'Security Health Analytics Custom Module get succeeded: ', + response + ); + } + + getSecurityHealthAnalyticsCustomModule(); + // [END securitycenter_get_security_health_analytics_custom_module] +} + +main(...process.argv.slice(2)); diff --git a/security-center/snippets/management_api/updateSecurityHealthAnalyticsCustomModule.js b/security-center/snippets/management_api/updateSecurityHealthAnalyticsCustomModule.js new file mode 100644 index 0000000000..495c740109 --- /dev/null +++ b/security-center/snippets/management_api/updateSecurityHealthAnalyticsCustomModule.js @@ -0,0 +1,69 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +'use strict'; + +/** + * Update an existing security health analytics custom module + */ +function main(organizationId, customModuleId, locationId = 'global') { + // [START securitycenter_update_security_health_analytics_custom_module] + // npm install '@google-cloud/securitycentermanagement' + const { + SecurityCenterManagementClient, + protos, + } = require('@google-cloud/securitycentermanagement'); + + const client = new SecurityCenterManagementClient(); + + const EnablementState = + protos.google.cloud.securitycentermanagement.v1 + .SecurityHealthAnalyticsCustomModule.EnablementState; + + /* + * Required. Resource name of security health analytics module. + * Its format is + * `organizations/[organization_id]/locations/[location_id]/securityHealthAnalyticsCustomModules/[custom_module]` + * `folders/[folder_id]/locations/[location_id]/securityHealthAnalyticsCustomModules/[custom_module]` + * `projects/[project_id]/locations/[location_id]/securityHealthAnalyticsCustomModules/[custom_module]` + */ + const name = `organizations/${organizationId}/locations/${locationId}/securityHealthAnalyticsCustomModules/${customModuleId}`; + + // define the security health analytics custom module configuration, update the + // EnablementState below + const securityHealthAnalyticsCustomModule = { + name: name, + enablementState: EnablementState.DISABLED, + }; + + // Set the field mask to specify which properties should be updated. + const fieldMask = { + paths: ['enablement_state'], + }; + + async function updateSecurityHealthAnalyticsCustomModule() { + const [response] = await client.updateSecurityHealthAnalyticsCustomModule({ + updateMask: fieldMask, + securityHealthAnalyticsCustomModule: securityHealthAnalyticsCustomModule, + }); + console.log( + 'Security Health Analytics Custom Module update succeeded: ', + response + ); + } + + updateSecurityHealthAnalyticsCustomModule(); + // [END securitycenter_update_security_health_analytics_custom_module] +} + +main(...process.argv.slice(2)); diff --git a/security-center/snippets/package.json b/security-center/snippets/package.json index 6cac1054d8..6062d1a0f1 100644 --- a/security-center/snippets/package.json +++ b/security-center/snippets/package.json @@ -14,7 +14,8 @@ "license": "Apache-2.0", "dependencies": { "@google-cloud/pubsub": "^4.0.0", - "@google-cloud/security-center": "^8.7.0" + "@google-cloud/security-center": "^8.7.0", + "@google-cloud/securitycentermanagement": "^0.5.0" }, "devDependencies": { "c8": "^10.0.0", diff --git a/security-center/snippets/system-test/management_api/securityHealthAnalyticsCustomModule.test.js b/security-center/snippets/system-test/management_api/securityHealthAnalyticsCustomModule.test.js new file mode 100644 index 0000000000..b374b51680 --- /dev/null +++ b/security-center/snippets/system-test/management_api/securityHealthAnalyticsCustomModule.test.js @@ -0,0 +1,175 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +const { + SecurityCenterManagementClient, + protos, +} = require('@google-cloud/securitycentermanagement'); +const uuidv1 = require('uuid').v1; +const {assert} = require('chai'); +const {describe, it, before, after} = require('mocha'); +const {execSync} = require('child_process'); +const exec = cmd => execSync(cmd, {encoding: 'utf8'}); + +// TODO(developer): Replace with your organization ID +const organizationId = + process.env.SCC_ORGANIZATION_ID || 'YOUR_ORGANIZATION_ID'; +const locationId = 'global'; +const customModuleDisplayName = + 'security_health_analytics_test' + uuidv1().replace(/-/g, '_'); + +describe('security health analytics custom module', async () => { + let data; + + before(async () => { + const client = new SecurityCenterManagementClient(); + const EnablementState = + protos.google.cloud.securitycentermanagement.v1 + .SecurityHealthAnalyticsCustomModule.EnablementState; + const Severity = + protos.google.cloud.securitycentermanagement.v1.CustomConfig.Severity; + const parent = `organizations/${organizationId}/locations/${locationId}`; + const name = `organizations/${organizationId}/locations/${locationId}/securityHealthAnalyticsCustomModules/custom_module`; + const expr = { + expression: `has(resource.rotationPeriod) && (resource.rotationPeriod > duration('2592000s'))`, + }; + const resourceSelector = { + resourceTypes: ['cloudkms.googleapis.com/CryptoKey'], + }; + const customConfig = { + predicate: expr, + resourceSelector: resourceSelector, + severity: Severity.MEDIUM, + description: 'add your description here', + recommendation: 'add your recommendation here', + }; + const securityHealthAnalyticsCustomModule = { + name: name, + displayName: customModuleDisplayName, + enablementState: EnablementState.ENABLED, + customConfig: customConfig, + }; + + try { + const [createResponse] = + await client.createSecurityHealthAnalyticsCustomModule({ + parent: parent, + securityHealthAnalyticsCustomModule: + securityHealthAnalyticsCustomModule, + }); + // extracts the custom module ID from the full name + const customModuleId = createResponse.name.split('/').pop(); + data = { + orgId: organizationId, + customModuleId: customModuleId, + customModuleName: createResponse.displayName, + }; + console.log( + 'SecurityHealthAnalyticsCustomModule created : %j', + createResponse + ); + } catch (error) { + console.error( + 'Error creating SecurityHealthAnalyticsCustomModule:', + error + ); + } + }); + + after(async () => { + const client = new SecurityCenterManagementClient(); + + // List security health analytics custom modules + const [listResponse] = + await client.listSecurityHealthAnalyticsCustomModules({ + parent: `organizations/${organizationId}/locations/${locationId}`, + }); + + for (const module of listResponse) { + try { + if (module.displayName === customModuleDisplayName) { + const customModuleId = module.name.split('/').pop(); + // Proceed with deletion if module exist + if (customModuleId) { + await client.deleteSecurityHealthAnalyticsCustomModule({ + name: `organizations/${organizationId}/locations/${locationId}/securityHealthAnalyticsCustomModules/${customModuleId}`, + }); + console.log( + `Custom Module ${customModuleDisplayName} deleted successfully.` + ); + } + } + } catch (error) { + console.error( + 'Error deleting SecurityHealthAnalyticsCustomModule:', + error + ); + } + } + }); + + it('create security health analytics custom module', done => { + const output = exec( + `node management_api/createSecurityHealthAnalyticsCustomModule.js ${data.orgId} ${data.customModuleName} ${locationId}` + ); + assert.include(output, data.customModuleName); + assert.match( + output, + /Security Health Analytics Custom Module creation succeeded/ + ); + assert.notMatch(output, /undefined/); + done(); + }); + + it('update security health analytics custom module', done => { + const output = exec( + `node management_api/updateSecurityHealthAnalyticsCustomModule.js ${data.orgId} ${data.customModuleId} ${locationId}` + ); + assert.include(output, 'DISABLED'); + assert.match( + output, + /Security Health Analytics Custom Module update succeeded/ + ); + assert.notMatch(output, /undefined/); + done(); + }); + + it('get security health analytics custom module', done => { + const output = exec( + `node management_api/getSecurityHealthAnalyticsCustomModule.js ${data.orgId} ${data.customModuleId} ${locationId}` + ); + assert.include(output, data.customModuleName); + assert.match( + output, + /Security Health Analytics Custom Module get succeeded/ + ); + assert.notMatch(output, /undefined/); + done(); + }); + + it('get effective security health analytics custom module', done => { + const output = exec( + `node management_api/getEffectiveSecurityHealthAnalyticsCustomModule.js ${data.orgId} ${data.customModuleId} ${locationId}` + ); + assert.include(output, data.customModuleName); + assert.match( + output, + /Security Health Analytics Custom Module get effective succeeded/ + ); + assert.notMatch(output, /undefined/); + done(); + }); +}); From 8e59941c219252825137a04be9a67485d75c87ac Mon Sep 17 00:00:00 2001 From: Jennifer Davis Date: Fri, 17 Jan 2025 17:26:49 -0800 Subject: [PATCH 2/7] fix: adjust comment to remove extra word Co-authored-by: code-review-assist[bot] <182814678+code-review-assist[bot]@users.noreply.github.com> --- .../createSecurityHealthAnalyticsCustomModule.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/security-center/snippets/management_api/createSecurityHealthAnalyticsCustomModule.js b/security-center/snippets/management_api/createSecurityHealthAnalyticsCustomModule.js index 8bf2892c5e..a7eafaf344 100644 --- a/security-center/snippets/management_api/createSecurityHealthAnalyticsCustomModule.js +++ b/security-center/snippets/management_api/createSecurityHealthAnalyticsCustomModule.js @@ -51,8 +51,8 @@ function main(organizationId, customModuleDisplayName, locationId = 'global') { */ const name = `organizations/${organizationId}/locations/${locationId}/securityHealthAnalyticsCustomModules/custom_module`; - // define the CEL expression here and this will scans for keys that have not been rotated in - // the last 30 days, change it according to the your requirements +// define the CEL expression here and this will scans for keys that have not been rotated in +// the last 30 days, change it according to your requirements const expr = { expression: `has(resource.rotationPeriod) && (resource.rotationPeriod > duration('2592000s'))`, }; From 56f7fdf7aaa69319c4edfd68b3c0af0009a09704 Mon Sep 17 00:00:00 2001 From: Gaurav Aggarwal Date: Mon, 20 Jan 2025 07:59:22 +0000 Subject: [PATCH 3/7] fix: lint issue --- .../createSecurityHealthAnalyticsCustomModule.js | 4 ++-- .../securityHealthAnalyticsCustomModule.test.js | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/security-center/snippets/management_api/createSecurityHealthAnalyticsCustomModule.js b/security-center/snippets/management_api/createSecurityHealthAnalyticsCustomModule.js index a7eafaf344..a7168a2c84 100644 --- a/security-center/snippets/management_api/createSecurityHealthAnalyticsCustomModule.js +++ b/security-center/snippets/management_api/createSecurityHealthAnalyticsCustomModule.js @@ -51,8 +51,8 @@ function main(organizationId, customModuleDisplayName, locationId = 'global') { */ const name = `organizations/${organizationId}/locations/${locationId}/securityHealthAnalyticsCustomModules/custom_module`; -// define the CEL expression here and this will scans for keys that have not been rotated in -// the last 30 days, change it according to your requirements + // define the CEL expression here and this will scans for keys that have not been rotated in + // the last 30 days, change it according to your requirements const expr = { expression: `has(resource.rotationPeriod) && (resource.rotationPeriod > duration('2592000s'))`, }; diff --git a/security-center/snippets/system-test/management_api/securityHealthAnalyticsCustomModule.test.js b/security-center/snippets/system-test/management_api/securityHealthAnalyticsCustomModule.test.js index b374b51680..18e9e7cc7c 100644 --- a/security-center/snippets/system-test/management_api/securityHealthAnalyticsCustomModule.test.js +++ b/security-center/snippets/system-test/management_api/securityHealthAnalyticsCustomModule.test.js @@ -25,8 +25,7 @@ const {execSync} = require('child_process'); const exec = cmd => execSync(cmd, {encoding: 'utf8'}); // TODO(developer): Replace with your organization ID -const organizationId = - process.env.SCC_ORGANIZATION_ID || 'YOUR_ORGANIZATION_ID'; +const organizationId = process.env.GCLOUD_ORGANIZATION; const locationId = 'global'; const customModuleDisplayName = 'security_health_analytics_test' + uuidv1().replace(/-/g, '_'); From 88fb3e86c135f65950bdd3d11293e3461cd1a56c Mon Sep 17 00:00:00 2001 From: Gaurav Aggarwal Date: Wed, 29 Jan 2025 05:15:11 +0000 Subject: [PATCH 4/7] updated test --- .../securityHealthAnalyticsCustomModule.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/security-center/snippets/system-test/management_api/securityHealthAnalyticsCustomModule.test.js b/security-center/snippets/system-test/management_api/securityHealthAnalyticsCustomModule.test.js index 18e9e7cc7c..9ca7dc0f0d 100644 --- a/security-center/snippets/system-test/management_api/securityHealthAnalyticsCustomModule.test.js +++ b/security-center/snippets/system-test/management_api/securityHealthAnalyticsCustomModule.test.js @@ -24,8 +24,8 @@ const {describe, it, before, after} = require('mocha'); const {execSync} = require('child_process'); const exec = cmd => execSync(cmd, {encoding: 'utf8'}); -// TODO(developer): Replace with your organization ID -const organizationId = process.env.GCLOUD_ORGANIZATION; +// TODO(developer): update for your own environment +const organizationId = '1081635000895'; const locationId = 'global'; const customModuleDisplayName = 'security_health_analytics_test' + uuidv1().replace(/-/g, '_'); From 3dba0a5cd81a3cf8e18925bb9ccbe2f08db5e73b Mon Sep 17 00:00:00 2001 From: Gaurav Aggarwal Date: Thu, 30 Jan 2025 09:59:22 +0000 Subject: [PATCH 5/7] refactor cleanup code --- ...ecurityHealthAnalyticsCustomModule.test.js | 46 ++++++++++--------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/security-center/snippets/system-test/management_api/securityHealthAnalyticsCustomModule.test.js b/security-center/snippets/system-test/management_api/securityHealthAnalyticsCustomModule.test.js index 9ca7dc0f0d..b362f3ec29 100644 --- a/security-center/snippets/system-test/management_api/securityHealthAnalyticsCustomModule.test.js +++ b/security-center/snippets/system-test/management_api/securityHealthAnalyticsCustomModule.test.js @@ -32,6 +32,7 @@ const customModuleDisplayName = describe('security health analytics custom module', async () => { let data; + const sharedModuleIds = []; before(async () => { const client = new SecurityCenterManagementClient(); @@ -76,6 +77,7 @@ describe('security health analytics custom module', async () => { customModuleId: customModuleId, customModuleName: createResponse.displayName, }; + sharedModuleIds.push(customModuleId); console.log( 'SecurityHealthAnalyticsCustomModule created : %j', createResponse @@ -91,31 +93,29 @@ describe('security health analytics custom module', async () => { after(async () => { const client = new SecurityCenterManagementClient(); - // List security health analytics custom modules - const [listResponse] = - await client.listSecurityHealthAnalyticsCustomModules({ - parent: `organizations/${organizationId}/locations/${locationId}`, - }); - - for (const module of listResponse) { - try { - if (module.displayName === customModuleDisplayName) { - const customModuleId = module.name.split('/').pop(); - // Proceed with deletion if module exist - if (customModuleId) { + if (sharedModuleIds.length > 0) { + for (const moduleId of sharedModuleIds) { + const name = `organizations/${organizationId}/locations/${locationId}/securityHealthAnalyticsCustomModules/${moduleId}`; + + try { + //get Security Health Analytics Custom Module + const [response] = + await client.getSecurityHealthAnalyticsCustomModule({ + name: name, + }); + + if (response.displayName === customModuleDisplayName) { await client.deleteSecurityHealthAnalyticsCustomModule({ - name: `organizations/${organizationId}/locations/${locationId}/securityHealthAnalyticsCustomModules/${customModuleId}`, + name: name, }); - console.log( - `Custom Module ${customModuleDisplayName} deleted successfully.` - ); + console.log(`Custom Module ${moduleId} deleted successfully.`); } + } catch (error) { + console.error( + 'Error deleting SecurityHealthAnalyticsCustomModule:', + error + ); } - } catch (error) { - console.error( - 'Error deleting SecurityHealthAnalyticsCustomModule:', - error - ); } } }); @@ -124,6 +124,10 @@ describe('security health analytics custom module', async () => { const output = exec( `node management_api/createSecurityHealthAnalyticsCustomModule.js ${data.orgId} ${data.customModuleName} ${locationId}` ); + + const name = output.match(/name:\s*['"]([^'"]+)['"]/)[1]; + sharedModuleIds.push(name.split('/').pop()); + assert.include(output, data.customModuleName); assert.match( output, From 5168568241351337ee3eadaf64598365a9b3abff Mon Sep 17 00:00:00 2001 From: Gaurav Aggarwal Date: Fri, 31 Jan 2025 09:37:19 +0000 Subject: [PATCH 6/7] updated test --- ...ecurityHealthAnalyticsCustomModule.test.js | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/security-center/snippets/system-test/management_api/securityHealthAnalyticsCustomModule.test.js b/security-center/snippets/system-test/management_api/securityHealthAnalyticsCustomModule.test.js index b362f3ec29..60c1c60540 100644 --- a/security-center/snippets/system-test/management_api/securityHealthAnalyticsCustomModule.test.js +++ b/security-center/snippets/system-test/management_api/securityHealthAnalyticsCustomModule.test.js @@ -28,7 +28,7 @@ const exec = cmd => execSync(cmd, {encoding: 'utf8'}); const organizationId = '1081635000895'; const locationId = 'global'; const customModuleDisplayName = - 'security_health_analytics_test' + uuidv1().replace(/-/g, '_'); + 'node_security_health_analytics_test' + uuidv1().replace(/-/g, '_'); describe('security health analytics custom module', async () => { let data; @@ -64,6 +64,7 @@ describe('security health analytics custom module', async () => { }; try { + await new Promise(resolve => setTimeout(resolve, 1000)); const [createResponse] = await client.createSecurityHealthAnalyticsCustomModule({ parent: parent, @@ -98,18 +99,10 @@ describe('security health analytics custom module', async () => { const name = `organizations/${organizationId}/locations/${locationId}/securityHealthAnalyticsCustomModules/${moduleId}`; try { - //get Security Health Analytics Custom Module - const [response] = - await client.getSecurityHealthAnalyticsCustomModule({ - name: name, - }); - - if (response.displayName === customModuleDisplayName) { - await client.deleteSecurityHealthAnalyticsCustomModule({ - name: name, - }); - console.log(`Custom Module ${moduleId} deleted successfully.`); - } + await client.deleteSecurityHealthAnalyticsCustomModule({ + name: name, + }); + console.log(`SecurityHealthAnalyticsCustomModule ${moduleId} deleted successfully.`); } catch (error) { console.error( 'Error deleting SecurityHealthAnalyticsCustomModule:', From d25ad5bfe0afb6b4d483fb3ece82288590a95a2c Mon Sep 17 00:00:00 2001 From: Gaurav Aggarwal Date: Fri, 31 Jan 2025 09:49:47 +0000 Subject: [PATCH 7/7] fix lint issue --- .../securityHealthAnalyticsCustomModule.test.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/security-center/snippets/system-test/management_api/securityHealthAnalyticsCustomModule.test.js b/security-center/snippets/system-test/management_api/securityHealthAnalyticsCustomModule.test.js index 60c1c60540..6220214729 100644 --- a/security-center/snippets/system-test/management_api/securityHealthAnalyticsCustomModule.test.js +++ b/security-center/snippets/system-test/management_api/securityHealthAnalyticsCustomModule.test.js @@ -102,7 +102,9 @@ describe('security health analytics custom module', async () => { await client.deleteSecurityHealthAnalyticsCustomModule({ name: name, }); - console.log(`SecurityHealthAnalyticsCustomModule ${moduleId} deleted successfully.`); + console.log( + `SecurityHealthAnalyticsCustomModule ${moduleId} deleted successfully.` + ); } catch (error) { console.error( 'Error deleting SecurityHealthAnalyticsCustomModule:',