Skip to content

Commit 9af3f5d

Browse files
rafaelMurataRafael Rodriguesiennaegraysidesubfuzion
authored
feat: Adding API v2 IAM+Notifications samples (#3717)
* feat: Adding API v2 Source Finding sample * feat: Adding API v2 Source Finding Mute sample * improving readability * add workflow scc * add notifications samples * add IAM samples * feat: Adding API v2 IAM Notifications samples * improve lint * trying to get projectId * trying to get projectId v2 * fix security error and remove IAM samples * fix: add missing test topic * fix: ensure topic doesn't exist before trying to create it * chore: update project vars * refactor: clean up async code, catch unhandled promise * refactor: security center project vars * debug: test v1 only * debug: test v2 only * debug: resume testing v1 and v2 * chore: roll up updates for v1 and v2 --------- Co-authored-by: Rafael Rodrigues <[email protected]> Co-authored-by: Jennifer Davis <[email protected]> Co-authored-by: Adam Ross <[email protected]> Co-authored-by: Tony Pujals <[email protected]> Co-authored-by: Tony Pujals <[email protected]>
1 parent 30e988e commit 9af3f5d

16 files changed

+539
-13
lines changed

.github/workflows/utils/workflows.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,5 +94,6 @@
9494
"video-intelligence",
9595
"vision/productSearch",
9696
"workflows",
97-
"workflows/invoke-private-endpoint"
97+
"workflows/invoke-private-endpoint",
98+
"security-center/snippets/v2"
9899
]

security-center/snippets/system-test/v1/assetSecurityMarks.test.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ const {describe, it, before} = require('mocha');
2020
const {execSync} = require('child_process');
2121
const exec = cmd => execSync(cmd, {encoding: 'utf8'});
2222

23-
const organizationId = process.env['GCLOUD_ORGANIZATION'];
23+
// TODO(developers): update for your own environment
24+
const organizationId = '1081635000895';
2425

2526
describe('client with security marks for assets', async () => {
2627
let data;

security-center/snippets/system-test/v1/findings.test.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ const {describe, it, before} = require('mocha');
2020
const {execSync} = require('child_process');
2121
const exec = cmd => execSync(cmd, {encoding: 'utf8'});
2222

23-
const organizationId = process.env['GCLOUD_ORGANIZATION'];
23+
// TODO(developers): update for your own environment
24+
const organizationId = '1081635000895';
2425

2526
describe('Client with SourcesAndFindings', async () => {
2627
let data;

security-center/snippets/system-test/v1/listAllAssets.test.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,12 @@ const {describe, it} = require('mocha');
1919
const {execSync} = require('child_process');
2020
const exec = cmd => execSync(cmd, {encoding: 'utf8'});
2121

22-
const organization_id = process.env['GCLOUD_ORGANIZATION'];
22+
// TODO(developers): update for your own environment
23+
const organizationId = '1081635000895';
2324

2425
describe('listAllAssets', () => {
2526
it('should print all assets in org', () => {
26-
const output = exec(`node v1/listAllAssets.js ${organization_id}`);
27+
const output = exec(`node v1/listAllAssets.js ${organizationId}`);
2728
assert.isAtLeast(output.match(/\n/g).length + 1, 62);
2829
assert.notMatch(output, /undefined/);
2930
});

security-center/snippets/system-test/v1/listAssetsAndChanges.test.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,12 @@ const {describe, it} = require('mocha');
1919
const {execSync} = require('child_process');
2020
const exec = cmd => execSync(cmd, {encoding: 'utf8'});
2121

22-
const organization_id = process.env['GCLOUD_ORGANIZATION'];
22+
// TODO(developers): update for your own environment
23+
const organizationId = '1081635000895';
2324

2425
describe('listAssetsandChanges', () => {
2526
it('should print projects with state changes', () => {
26-
const output = exec(`node v1/listAssetsAndChanges.js ${organization_id}`);
27+
const output = exec(`node v1/listAssetsAndChanges.js ${organizationId}`);
2728
assert.match(output, /(ADDED|ACTIVE)/);
2829
assert.equal(4, output.match(/\n/g).length + 1, '== number of projects');
2930
assert.notMatch(output, /undefined/);

security-center/snippets/system-test/v1/listAssetsAtTime.test.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,12 @@ const {describe, it} = require('mocha');
1919
const {execSync} = require('child_process');
2020
const exec = cmd => execSync(cmd, {encoding: 'utf8'});
2121

22-
const organization_id = process.env['GCLOUD_ORGANIZATION'];
22+
// TODO(developers): update for your own environment
23+
const organizationId = '1081635000895';
2324

2425
describe('listAssetsAttime', () => {
2526
it('should print projects', () => {
26-
const output = exec(`node v1/listAssetsAtTime.js ${organization_id}`);
27+
const output = exec(`node v1/listAssetsAtTime.js ${organizationId}`);
2728
assert.equal(4, output.match(/\n/g).length + 1, '== number of projects');
2829
assert.notMatch(output, /undefined/);
2930
});

security-center/snippets/system-test/v1/listFilteredAssets.test.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,12 @@ const {describe, it} = require('mocha');
1919
const {execSync} = require('child_process');
2020
const exec = cmd => execSync(cmd, {encoding: 'utf8'});
2121

22-
const organization_id = process.env['GCLOUD_ORGANIZATION'];
22+
// TODO(developers): update for your own environment
23+
const organizationId = '1081635000895';
2324

2425
describe('listAllAssets', () => {
2526
it('should print all assets in org', () => {
26-
const output = exec(`node v1/listFilteredAssets.js ${organization_id}`);
27+
const output = exec(`node v1/listFilteredAssets.js ${organizationId}`);
2728
assert.isAtLeast(4, output.match(/\n/g).length + 1);
2829
assert.notMatch(output, /undefined/);
2930
});

security-center/snippets/system-test/v1/notifications.test.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ const {describe, it, before, after} = require('mocha');
2121
const {execSync} = require('child_process');
2222
const exec = cmd => execSync(cmd, {encoding: 'utf8'});
2323

24-
const organizationId = process.env['GCLOUD_ORGANIZATION'];
24+
// TODO(developers): update for your own environment
25+
const organizationId = '1081635000895';
2526
const orgName = 'organizations/' + organizationId;
2627
const pubsubTopic = 'projects/project-a-id/topics/notifications-sample-topic';
2728

security-center/snippets/system-test/v1/orgSettings.test.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ const {describe, it} = require('mocha');
1919
const {execSync} = require('child_process');
2020
const exec = cmd => execSync(cmd, {encoding: 'utf8'});
2121

22-
const organizationId = process.env['GCLOUD_ORGANIZATION'];
22+
// TODO(developers): update for your own environment
23+
const organizationId = '1081635000895';
2324

2425
describe('client with organization settings', () => {
2526
it('client can enable asset discovery', () => {
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
/*
2+
* Copyright 2024 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
'use strict';
17+
18+
const {execSync} = require('node:child_process');
19+
20+
const {assert} = require('chai');
21+
const {describe, it, before, after} = require('mocha');
22+
const uuidv1 = require('uuid').v1;
23+
24+
const {SecurityCenterClient} = require('@google-cloud/security-center').v2;
25+
const {PubSub} = require('@google-cloud/pubsub');
26+
27+
const exec = cmd => execSync(cmd, {encoding: 'utf8'});
28+
29+
// TODO(developers): update for your own environment
30+
const organizationId = '1081635000895';
31+
const projectId = 'long-door-651';
32+
const location = 'global';
33+
34+
describe('Client with Notifications v2', async () => {
35+
let client;
36+
let pubSubClient;
37+
let topicName;
38+
let parent;
39+
let pubsubTopic;
40+
41+
let data;
42+
43+
before(async () => {
44+
const configId = 'notif-config-test-node-create-' + uuidv1();
45+
topicName = 'test_topic';
46+
parent = `projects/${projectId}/locations/${location}`;
47+
pubsubTopic = `projects/${projectId}/topics/${topicName}`;
48+
49+
client = new SecurityCenterClient();
50+
51+
pubSubClient = new PubSub();
52+
// A previous test failure can result the topic hanging around
53+
try {
54+
await pubSubClient.topic(topicName).delete();
55+
} catch {
56+
// Ignore if the topic doesn't already exist
57+
}
58+
await pubSubClient.createTopic(topicName);
59+
60+
const notificationConfig = {
61+
description: 'Sample config for node v2',
62+
pubsubTopic: pubsubTopic,
63+
streamingConfig: {filter: 'state = "ACTIVE"'},
64+
};
65+
66+
const [notificationResponse] = await client.createNotificationConfig({
67+
parent: parent,
68+
configId: configId,
69+
notificationConfig: notificationConfig,
70+
});
71+
72+
const notificationConfigs = notificationResponse.name.split('/')[5];
73+
data = {
74+
orgId: organizationId,
75+
projectId: projectId,
76+
notificationName: notificationResponse.name,
77+
notificationConfigs: notificationConfigs,
78+
topicName: topicName,
79+
};
80+
console.log('my data notification %j', data);
81+
});
82+
83+
after(async () => {
84+
try {
85+
await pubSubClient.topic(topicName).delete();
86+
} catch {
87+
// Ignore if the topic doesn't exist
88+
}
89+
});
90+
91+
it('client can create config v2', () => {
92+
const output = exec(
93+
`node v2/createNotificationConfig.js ${data.projectId} ${data.topicName}`
94+
);
95+
assert(output.includes(data.projectId));
96+
assert.match(output, /Notification configuration creation successful/);
97+
assert.notMatch(output, /undefined/);
98+
});
99+
100+
it('client can get config v2', () => {
101+
const output = exec(
102+
`node v2/getNotificationConfig.js ${data.projectId} ${data.notificationConfigs}`
103+
);
104+
assert(output.includes(data.notificationName));
105+
assert.match(output, /Notification config/);
106+
assert.notMatch(output, /undefined/);
107+
});
108+
109+
it('client can list configs v2', () => {
110+
const output = exec(`node v2/listNotificationConfigs.js ${data.projectId}`);
111+
assert(output.includes(data.projectId));
112+
assert.notMatch(output, /undefined/);
113+
});
114+
115+
it('client can update configs v2', () => {
116+
const output = exec(
117+
`node v2/updateNotificationConfig.js ${data.projectId} ${data.notificationConfigs} ${data.topicName}`
118+
);
119+
assert(output.includes(data.notificationName));
120+
assert.match(output, /Notification configuration update successful/);
121+
assert.notMatch(output, /undefined/);
122+
});
123+
124+
it('client can delete config v2', () => {
125+
const output = exec(
126+
`node v2/deleteNotificationConfig.js ${data.projectId} ${data.notificationConfigs}`
127+
);
128+
assert.include(output, 'Deleted Notification config');
129+
assert.notMatch(output, /undefined/);
130+
});
131+
});
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
* Copyright 2024 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
'use strict';
18+
19+
/**
20+
* Creates a notification config in a project under a given location.
21+
* Ensure the ServiceAccount has the "pubsub.topics.setIamPolicy" permission on the new topic.
22+
*/
23+
async function main(projectId, topicName, location = 'global') {
24+
// [START securitycenter_create_notification_config_v2]
25+
// npm install '@google-cloud/security-center'
26+
const {SecurityCenterClient} = require('@google-cloud/security-center').v2;
27+
const uuidv1 = require('uuid').v1;
28+
29+
const client = new SecurityCenterClient();
30+
/*
31+
* Required. Resource name of the new notification config's parent. Its format
32+
* is "organizations/[organization_id]/locations/[location_id]",
33+
* "folders/[folder_id]/locations/[location_id]", or
34+
* "projects/[project_id]/locations/[location_id]".
35+
*/
36+
const parent = `projects/${projectId}/locations/${location}`;
37+
38+
/**
39+
* Required.
40+
* Unique identifier provided by the client within the parent scope.
41+
* It must be between 1 and 128 characters and contain alphanumeric
42+
* characters, underscores, or hyphens only.
43+
*/
44+
const configId = 'notif-config-test-node-create-' + uuidv1();
45+
46+
// pubsubTopic = "projects/{your-project}/topics/{your-topic}";
47+
const pubsubTopic = `projects/${projectId}/topics/${topicName}`;
48+
49+
/**
50+
* Required. The notification config being created. The name and the service
51+
* account will be ignored as they are both output only fields on this
52+
* resource.
53+
*/
54+
const notificationConfig = {
55+
description: 'Sample config for node v2',
56+
pubsubTopic: pubsubTopic,
57+
streamingConfig: {filter: 'state = "ACTIVE"'},
58+
};
59+
60+
// Build the request.
61+
const createNotificationRequest = {
62+
parent: parent,
63+
configId: configId,
64+
notificationConfig: notificationConfig,
65+
};
66+
67+
async function createNotificationConfig() {
68+
const [response] = await client.createNotificationConfig(
69+
createNotificationRequest
70+
);
71+
console.log('Notification configuration creation successful: %j', response);
72+
}
73+
74+
await createNotificationConfig();
75+
// [END securitycenter_create_notification_config_v2]
76+
}
77+
78+
main(...process.argv.slice(2)).catch(err => {
79+
console.error(err);
80+
process.exitCode = 1;
81+
});
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright 2024 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
'use strict';
18+
19+
//Delete a notification config.
20+
async function main(projectId, notificationId, location = 'global') {
21+
// [START securitycenter_delete_notification_config_v2]
22+
// npm install '@google-cloud/security-center'
23+
const {SecurityCenterClient} = require('@google-cloud/security-center').v2;
24+
25+
const client = new SecurityCenterClient();
26+
/**
27+
* Required. Name of the notification config to delete. The following list
28+
* shows some examples of the format:
29+
* `organizations/[organization_id]/locations/[location_id]/notificationConfigs/[config_id]`
30+
* `folders/[folder_id]/locations/[location_id]notificationConfigs/[config_id]`
31+
* `projects/[project_id]/locations/[location_id]notificationConfigs/[config_id]`
32+
*/
33+
const name = `projects/${projectId}/locations/${location}/notificationConfigs/${notificationId}`;
34+
35+
// Build the request.
36+
const deleteNotificationConfigRequest = {
37+
name: name,
38+
};
39+
40+
async function deleteNotificationConfig() {
41+
const [response] = await client.deleteNotificationConfig(
42+
deleteNotificationConfigRequest
43+
);
44+
console.log('Deleted Notification config: %j', response);
45+
}
46+
47+
await deleteNotificationConfig();
48+
// [END securitycenter_delete_notification_config_v2]
49+
}
50+
51+
main(...process.argv.slice(2)).catch(err => {
52+
console.error(err);
53+
process.exitCode = 1;
54+
});

0 commit comments

Comments
 (0)