From c1643a1a3987910bd129180a13a3fdf59ba7a60d Mon Sep 17 00:00:00 2001 From: vijaykanthm Date: Wed, 2 Oct 2024 17:50:36 -0700 Subject: [PATCH] feat(security-center): Add Resource v2 API Mute Rule Samples (#3830) * Add Resource v2 Mute Rule Samples * fix lint issues * Address Comments * remove unused variable * Use the project id from env variable --------- Co-authored-by: Adam Ross --- security-center/snippets/package.json | 2 +- .../snippets/system-test/v2/muterule.test.js | 107 ++++++++++++++++++ .../system-test/v2/notifications.test.js | 4 +- security-center/snippets/v2/createMuteRule.js | 81 +++++++++++++ security-center/snippets/v2/deleteMuteRule.js | 63 +++++++++++ security-center/snippets/v2/getMuteRule.js | 63 +++++++++++ .../snippets/v2/listAllMuteRules.js | 64 +++++++++++ security-center/snippets/v2/updateMuteRule.js | 83 ++++++++++++++ 8 files changed, 464 insertions(+), 3 deletions(-) create mode 100644 security-center/snippets/system-test/v2/muterule.test.js create mode 100644 security-center/snippets/v2/createMuteRule.js create mode 100644 security-center/snippets/v2/deleteMuteRule.js create mode 100644 security-center/snippets/v2/getMuteRule.js create mode 100644 security-center/snippets/v2/listAllMuteRules.js create mode 100644 security-center/snippets/v2/updateMuteRule.js diff --git a/security-center/snippets/package.json b/security-center/snippets/package.json index a519a7f465..5ae21263cf 100644 --- a/security-center/snippets/package.json +++ b/security-center/snippets/package.json @@ -9,7 +9,7 @@ "node": ">=16.0.0" }, "scripts": { - "test": "c8 mocha -p -j 2 --recursive --timeout 6000000 system-test/v2/findings.test.js" + "test": "c8 mocha -p -j 2 --recursive --timeout 6000000 system-test/" }, "license": "Apache-2.0", "dependencies": { diff --git a/security-center/snippets/system-test/v2/muterule.test.js b/security-center/snippets/system-test/v2/muterule.test.js new file mode 100644 index 0000000000..e0d78e3af5 --- /dev/null +++ b/security-center/snippets/system-test/v2/muterule.test.js @@ -0,0 +1,107 @@ +/* + * Copyright 2024 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. + */ + +const {SecurityCenterClient} = require('@google-cloud/security-center').v2; +const {assert} = require('chai'); +const {execSync} = require('child_process'); +const exec = cmd => execSync(cmd, {encoding: 'utf8'}); +const {describe, it, before} = require('mocha'); + +// TODO(developers): update for your own environment +const organizationId = process.env.GCLOUD_ORGANIZATION; +const location = 'global'; + +describe('Client with mute rule V2', async () => { + let data; + before(async () => { + // Creates a new client. + const client = new SecurityCenterClient(); + + // Build the create mute rule request. + const muteId = 'muteid-' + Math.floor(Math.random() * 10000); + const createMuteRuleRequest = { + parent: `organizations/${organizationId}/locations/${location}`, + muteConfigId: muteId, + muteConfig: { + name: `organizations/${organizationId}/locations/${location}/muteConfigs/${muteId}`, + description: "Mute low-medium IAM grants excluding 'compute' resources", + filter: + 'severity="LOW" OR severity="MEDIUM" AND ' + + 'category="Persistence: IAM Anomalous Grant" AND ' + + '-resource.type:"compute"', + type: 'STATIC', + }, + }; + + const [muteConfigResponse] = await client + .createMuteConfig(createMuteRuleRequest) + .catch(error => console.error(error)); + + const muteConfigId = muteConfigResponse.name.split('/')[5]; + + data = { + orgId: organizationId, + muteConfigId: muteConfigId, + muteConfigName: muteConfigResponse.name, + untouchedMuteConfigName: '', + }; + console.log('My data muteConfig:: %j', data); + }); + + it('client can create mute rule V2', done => { + const output = exec(`node v2/createMuteRule.js ${data.orgId}`); + assert(output.includes(data.orgId)); + assert.match(output, /New mute rule config created/); + assert.notMatch(output, /undefined/); + done(); + }); + + it('client can list all mute rules V2', done => { + const output = exec(`node v2/listAllMuteRules.js ${data.orgId}`); + assert(output.includes(data.orgId)); + assert(output.includes(data.untouchedMuteConfigName)); + assert.notMatch(output, /undefined/); + done(); + }); + + it('client can get a mute rule V2', done => { + const output = exec( + `node v2/getMuteRule.js ${data.orgId} ${data.muteConfigId}` + ); + assert(output.includes(data.muteConfigName)); + assert.match(output, /Get mute rule config/); + assert.notMatch(output, /undefined/); + done(); + }); + + it('client can update a mute rule V2', done => { + const output = exec( + `node v2/updateMuteRule.js ${data.orgId} ${data.muteConfigId}` + ); + assert.match(output, /Update mute rule config/); + assert.notMatch(output, /undefined/); + done(); + }); + + it('client can delete a mute rule V2', done => { + const output = exec( + `node v2/deleteMuteRule.js ${data.orgId} ${data.muteConfigId}` + ); + assert.match(output, /Delete mute rule config/); + assert.notMatch(output, /undefined/); + done(); + }); +}); diff --git a/security-center/snippets/system-test/v2/notifications.test.js b/security-center/snippets/system-test/v2/notifications.test.js index 6e444f6266..215adbb063 100644 --- a/security-center/snippets/system-test/v2/notifications.test.js +++ b/security-center/snippets/system-test/v2/notifications.test.js @@ -26,8 +26,8 @@ const {PubSub} = require('@google-cloud/pubsub'); const exec = cmd => execSync(cmd, {encoding: 'utf8'}); // TODO(developers): update for your own environment -const organizationId = '1081635000895'; -const projectId = 'long-door-651'; +const organizationId = process.env.GCLOUD_ORGANIZATION; +const projectId = process.env.GOOGLE_SAMPLES_PROJECT; const location = 'global'; describe('Client with Notifications v2', async () => { diff --git a/security-center/snippets/v2/createMuteRule.js b/security-center/snippets/v2/createMuteRule.js new file mode 100644 index 0000000000..2a328c8b76 --- /dev/null +++ b/security-center/snippets/v2/createMuteRule.js @@ -0,0 +1,81 @@ +/* + * Copyright 2024 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'; + +/** + * Creates a mute configuration in a project under a given location. + */ +function main(organizationId, location = 'global') { + // [START securitycenter_create_mute_config_v2] + // Imports the Google Cloud client library. + const {SecurityCenterClient} = require('@google-cloud/security-center').v2; + + // Create a Security Center client + const client = new SecurityCenterClient(); + + /** + * Required. Resource name of the new mute configs's parent. Its format is + * "organizations/[organization_id]/locations/[location_id]", + * "folders/[folder_id]/locations/[location_id]", or + * "projects/[project_id]/locations/[location_id]". + */ + + /** + * TODO(developer): Update the following references for your own environment before running the sample. + */ + // const organizationId = 'YOUR_ORGANIZATION_ID'; + // const location = 'LOCATION_ID'; + const parent = `organizations/${organizationId}/locations/${location}`; + + /** + * Required. Unique identifier provided by the client within the parent scope. + * It must consist of only lowercase letters, numbers, and hyphens, must start + * with a letter, must end with either a letter or a number, and must be 63 + * characters or less. + */ + const muteConfigId = 'muteid-' + Math.floor(Math.random() * 10000); + + const name = `${parent}/muteConfigs/${muteConfigId}`; + + // Build the muteRuleConfig object. + const muteConfig = { + name: name, + description: "Mute low-medium IAM grants excluding 'compute' resources", + filter: + 'severity="LOW" OR severity="MEDIUM" AND ' + + 'category="Persistence: IAM Anomalous Grant" AND ' + + '-resource.type:"compute"', + type: 'STATIC', + }; + + // Build the create mute rule request. + const createMuteRuleRequest = { + parent, + muteConfig, + muteConfigId, + }; + + async function createMuteRuleConfig() { + // Call the API. + const [muteConfig] = await client.createMuteConfig(createMuteRuleRequest); + console.log('New mute rule config created: %j', muteConfig); + } + + createMuteRuleConfig(); + // [END securitycenter_create_mute_config_v2] +} + +main(...process.argv.slice(2)); diff --git a/security-center/snippets/v2/deleteMuteRule.js b/security-center/snippets/v2/deleteMuteRule.js new file mode 100644 index 0000000000..3dde715c15 --- /dev/null +++ b/security-center/snippets/v2/deleteMuteRule.js @@ -0,0 +1,63 @@ +/* + * Copyright 2024 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'; + +/** + * Deletes a mute configuration given its resource name. + */ +function main(organizationId, muteConfigId, location = 'global') { + // [START securitycenter_delete_mute_config_v2] + // Imports the Google Cloud client library. + const {SecurityCenterClient} = require('@google-cloud/security-center').v2; + + // Create a Security Center client + const client = new SecurityCenterClient(); + + /** + * Required. Name of the mute config to delete. The following list shows some + * examples of the format: + * `organizations/{organization}/muteConfigs/{config_id}` + * `organizations/{organization}/locations/{location}/muteConfigs/{config_id}` + * `folders/{folder}/muteConfigs/{config_id}` + * `folders/{folder}/locations/{location}/muteConfigs/{config_id}` + * `projects/{project}/muteConfigs/{config_id}` + * `projects/{project}/locations/{location}/muteConfigs/{config_id}` + */ + + /** + * TODO(developer): Update the following references for your own environment before running the sample. + */ + // const organizationId = 'YOUR_ORGANIZATION_ID'; + // const location = 'LOCATION_ID'; + // const muteConfigId = 'MUTE_CONFIG_ID'; + const name = `organizations/${organizationId}/locations/${location}/muteConfigs/${muteConfigId}`; + + // Build the request. + const deleteMuteRuleRequest = { + name, + }; + + async function deleteMuteConfig() { + // Call the API. + const [muteConfig] = await client.deleteMuteConfig(deleteMuteRuleRequest); + console.log('Delete mute rule config: %j', muteConfig); + } + + deleteMuteConfig(); + // [END securitycenter_delete_mute_config_v2] +} + +main(...process.argv.slice(2)); diff --git a/security-center/snippets/v2/getMuteRule.js b/security-center/snippets/v2/getMuteRule.js new file mode 100644 index 0000000000..359b48ec60 --- /dev/null +++ b/security-center/snippets/v2/getMuteRule.js @@ -0,0 +1,63 @@ +/* + * Copyright 2024 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'; + +/** + * Retrieves a mute configuration given its resource name. + */ +function main(organizationId, muteConfigId) { + // [START securitycenter_create_mute_config_v2] + // Imports the Google Cloud client library. + const {SecurityCenterClient} = require('@google-cloud/security-center').v2; + + // Create a Security Center client + const client = new SecurityCenterClient(); + + /** + * Required. Name of the mute config to retrieve. The following list shows + * some examples of the format: + * `organizations/{organization}/muteConfigs/{config_id}` + * `organizations/{organization}/locations/{location}/muteConfigs/{config_id}` + * `folders/{folder}/muteConfigs/{config_id}` + * `folders/{folder}/locations/{location}/muteConfigs/{config_id}` + * `projects/{project}/muteConfigs/{config_id}` + * `projects/{project}/locations/{location}/muteConfigs/{config_id}` + */ + + /** + * TODO(developer): Update the following references for your own environment before running the sample. + */ + // const organizationId = 'YOUR_ORGANIZATION_ID'; + // const muteConfigId = 'MUTE_CONFIG_ID'; + + const name = `organizations/${organizationId}/muteConfigs/${muteConfigId}`; + + // Build the request. + const getMuteRuleRequest = { + name, + }; + + async function createMuteRuleConfig() { + // Call the API. + const [muteConfig] = await client.getMuteConfig(getMuteRuleRequest); + console.log('Get mute rule config: %j', muteConfig); + } + + createMuteRuleConfig(); + // [END securitycenter_create_mute_config_v2] +} + +main(...process.argv.slice(2)); diff --git a/security-center/snippets/v2/listAllMuteRules.js b/security-center/snippets/v2/listAllMuteRules.js new file mode 100644 index 0000000000..36638793ea --- /dev/null +++ b/security-center/snippets/v2/listAllMuteRules.js @@ -0,0 +1,64 @@ +/* + * Copyright 2024 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'; + +/** + * Lists all mute rules present under the resource type in the given location. + */ +function main(organizationId, location = 'global') { + // [START securitycenter_list_mute_configs_v2] + // Imports the Google Cloud client library. + const {SecurityCenterClient} = require('@google-cloud/security-center').v2; + + // Creates a new client. + const client = new SecurityCenterClient(); + /** + * Required. The parent, which owns the collection of mute configs. Its format + * is "organizations/[organization_id]", "folders/[folder_id]", + * "projects/[project_id]", + * "organizations/[organization_id]/locations/[location_id]", + * "folders/[folder_id]/locations/[location_id]", + * "projects/[project_id]/locations/[location_id]". + */ + + /** + * TODO(developer): Update the following references for your own environment before running the sample. + */ + // const organizationId = 'YOUR_ORGANIZATION_ID'; + // const location = 'LOCATION_ID'; + + const parent = `organizations/${organizationId}/locations/${location}`; + + // Build the request. + const listMuteRulesRequest = { + parent, + }; + + async function listAllMuteRules() { + // Call the API. + const iterable = client.listMuteConfigsAsync(listMuteRulesRequest); + let count = 0; + + for await (const response of iterable) { + console.log(`${++count} ${response.name}: ${response.description}`); + } + } + + listAllMuteRules(); + // [END securitycenter_list_mute_configs_v2] +} + +main(...process.argv.slice(2)); diff --git a/security-center/snippets/v2/updateMuteRule.js b/security-center/snippets/v2/updateMuteRule.js new file mode 100644 index 0000000000..1a7d2342f0 --- /dev/null +++ b/security-center/snippets/v2/updateMuteRule.js @@ -0,0 +1,83 @@ +/* + * Copyright 2024 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'; + +/** + * Updates an existing mute configuration. + */ +function main(organizationId, muteConfigId, location = 'global') { + // [START securitycenter_update_mute_config_v2] + // Imports the Google Cloud client library. + const {SecurityCenterClient} = require('@google-cloud/security-center').v2; + + // Create a Security Center client + const client = new SecurityCenterClient(); + + /** + * Required. Name of the mute config to retrieve. The following list shows + * some examples of the format: + * `organizations/{organization}/muteConfigs/{config_id}` + * `organizations/{organization}/locations/{location}/muteConfigs/{config_id}` + * `folders/{folder}/muteConfigs/{config_id}` + * `folders/{folder}/locations/{location}/muteConfigs/{config_id}` + * `projects/{project}/muteConfigs/{config_id}` + * `projects/{project}/locations/{location}/muteConfigs/{config_id}` + */ + + /** + * TODO(developer): Update the following references for your own environment before running the sample. + */ + // const organizationId = 'YOUR_ORGANIZATION_ID'; + // const location = 'LOCATION_ID'; + // const muteConfigId = 'MUTE_CONFIG_ID'; + + const name = `organizations/${organizationId}/locations/${location}/muteConfigs/${muteConfigId}`; + /** + * The list of fields to be updated. + * If empty all mutable fields will be updated. + */ + const updateMask = { + paths: ['description'], + }; + + // Modify or remove the updateMask to change fields other that description. + const muteConfig = { + name, + description: 'Updated mute config description', + updateMask, + filter: + 'severity="LOW" OR severity="MEDIUM" AND ' + + 'category="Persistence: IAM Anomalous Grant" AND ' + + '-resource.type:"compute"', + type: 'STATIC', + }; + + // Build the update mute rule request. + const updateMuteConfigRequest = { + muteConfig, + }; + + async function updateMuteConfig() { + // Call the API. + const [muteConfig] = await client.updateMuteConfig(updateMuteConfigRequest); + console.log('Update mute rule config: %j', muteConfig); + } + + updateMuteConfig(); + // [END securitycenter_update_mute_config_v2] +} + +main(...process.argv.slice(2));