security-center/snippets/v2/groupFindings.js (86 lines of code) (raw):

// 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 // // 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'; // Group all findings under a parent type across all sources by their specified properties // (e.g category, state). async function main() { // [START securitycenter_group_all_findings_v2] // Imports the Google Cloud client library. const {SecurityCenterClient} = require('@google-cloud/security-center').v2; // Creates a new client. const client = new SecurityCenterClient(); // TODO(developer): Update the following for your own environment. const organizationId = '1081635000895'; const location = 'global'; async function createSampleFinding() { const uuid = require('uuid'); const [source] = await client.createSource({ source: { displayName: 'Customized Display Name V2', description: 'A new custom source that does X', }, parent: client.organizationPath(organizationId), }); const sourceId = source.name.split('/')[3]; // Resource name of the new finding's parent. Examples: // - `organizations/[organization_id]/sources/[source_id]` // - `organizations/[organization_id]/sources/[source_id]/locations/[location_id]` const parent = `organizations/${organizationId}/sources/${sourceId}/locations/${location}`; // The resource this finding applies to. The Cloud Security Command Center UI can link the // findings for a resource to the corresponding asset of a resource if there are matches. const resourceName = `//cloudresourcemanager.googleapis.com/organizations/${organizationId}`; // Unique identifier provided by the client within the parent scope. // It must be alphanumeric and less than or equal to 32 characters and // greater than 0 characters in length. const findingId = uuid.v4().replace(/-/g, ''); // Get the current timestamp. const eventDate = new Date(); // Finding category. const category = 'MEDIUM_RISK_ONE'; // Build the finding request object. const createFindingRequest = { parent: parent, findingId: findingId, finding: { resourceName, category, state: 'ACTIVE', // The time associated with discovering the issue. eventTime: { seconds: Math.floor(eventDate.getTime() / 1000), nanos: (eventDate.getTime() % 1000) * 1e6, }, }, }; await client.createFinding(createFindingRequest); const name = `organizations/${organizationId}/sources/${sourceId}/locations/${location}/findings/${findingId}`; // Build the request. const setMuteRequest = { name, mute: 'UNMUTED', }; const [finding] = await client.setMute(setMuteRequest); console.log('Unmute finding: %j', finding.mute); return sourceId; } const sourceId = await createSampleFinding(); // Name of the source to groupBy. If no location is specified, // finding is assumed to be in global. // // The following list shows some examples: // - `organizations/[organization_id]/sources/[source_id]` // - `organizations/[organization_id]/sources/[source_id]/locations/[location_id]` // - `folders/[folder_id]/sources/[source_id]` // - `folders/[folder_id]/sources/[source_id]/locations/[location_id]` // - `projects/[project_id]/sources/[source_id]` // - `projects/[project_id]/sources/[source_id]/locations/[location_id]` // // To groupBy across all sources provide a source_id of `-`. The following // list shows some examples: // - `organizations/{organization_id}/sources/-` // - `organizations/{organization_id}/sources/-/locations/[location_id]` // - `folders/{folder_id}/sources/-` // - `folders/{folder_id}/sources/-/locations/[location_id]` // - `projects/{project_id}/sources/-` // - `projects/{project_id}/sources/-/locations/[location_id]` const parent = `organizations/${organizationId}/sources/${sourceId}/locations/${location}`; // Supported grouping properties: resource_name/ category/ state/ parent/ severity. // Multiple properties should be separated by comma. const groupBy = 'category,state'; // Build the group findings request. const groupFindingsRequest = { parent, groupBy, }; async function groupFindings() { // Call the API. const iterable = client.groupFindingsAsync(groupFindingsRequest); let count = 0; for await (const response of iterable) { console.log( `${++count} ${response.properties.category} ${response.properties.state}` ); } } await groupFindings(); // [END securitycenter_group_all_findings_v2] } main().catch(err => { console.error(err); process.exitCode = 1; });