Skip to content

Commit 4a7ba19

Browse files
authored
feat(securitycenter): Add Resource SCC Management API Org ETD custom … (#3963)
* feat(securitycenter): Add Resource SCC Management API Org ETD custom modules * refactor cleanup logic * updated test
1 parent 4f660cd commit 4a7ba19

5 files changed

+320
-23
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright 2025 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+
/**
19+
* Retrieve an existing effective event threat detection custom module.
20+
*/
21+
function main(organizationId, customModuleId, location = 'global') {
22+
// [START securitycenter_get_effective_event_threat_detection_custom_module]
23+
// Imports the Google Cloud client library.
24+
const {SecurityCenterManagementClient} =
25+
require('@google-cloud/securitycentermanagement').v1;
26+
27+
// Create a Security Center Management client
28+
const client = new SecurityCenterManagementClient();
29+
30+
/*
31+
* Required. Resource name of effective event threat detection module.
32+
* Its format is
33+
* `organizations/[organization_id]/locations/[location_id]/effectiveEventThreatDetectionCustomModules/[custom_module]`
34+
* `folders/[folder_id]/locations/[location_id]/effectiveEventThreatDetectionCustomModules/[custom_module]`
35+
* `projects/[project_id]/locations/[location_id]/effectiveEventThreatDetectionCustomModules/[custom_module]`
36+
*/
37+
// TODO(developer): Update the following references for your own environment before running the sample.
38+
// const organizationId = 'YOUR_ORGANIZATION_ID';
39+
// const location = 'LOCATION_ID';
40+
// const customModuleId = 'CUSTOM_MODULE_ID';
41+
const name = `organizations/${organizationId}/locations/${location}/effectiveEventThreatDetectionCustomModules/${customModuleId}`;
42+
43+
// Build the request.
44+
const getEffectiveEventThreatDetectionCustomModuleRequest = {
45+
name: name,
46+
};
47+
48+
async function getEffectiveEventThreatDetectionCustomModule() {
49+
// Call the API.
50+
const [response] =
51+
await client.getEffectiveEventThreatDetectionCustomModule(
52+
getEffectiveEventThreatDetectionCustomModuleRequest
53+
);
54+
console.log(
55+
'Retrieved EffectiveEventThreatDetectionCustomModule: %j',
56+
response
57+
);
58+
}
59+
60+
getEffectiveEventThreatDetectionCustomModule();
61+
// [END securitycenter_get_effective_event_threat_detection_custom_module]
62+
}
63+
64+
main(...process.argv.slice(2));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright 2025 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+
// List all descendant event threat detection custom module under a given parent resource.
19+
function main(organizationId, location = 'global') {
20+
// [START securitycenter_list_descendant_event_threat_detection_custom_module]
21+
// Imports the Google Cloud client library.
22+
const {SecurityCenterManagementClient} =
23+
require('@google-cloud/securitycentermanagement').v1;
24+
25+
// Create a Security Center Management client
26+
const client = new SecurityCenterManagementClient();
27+
28+
/**
29+
* Required. The name of the parent resource. Its
30+
* format is "organizations/[organization_id]/locations/[location_id]",
31+
* "folders/[folder_id]/locations/[location_id]", or
32+
* "projects/[project_id]/locations/[location_id]".
33+
*/
34+
//TODO(developer): Update the following references for your own environment before running the sample.
35+
// const organizationId = 'YOUR_ORGANIZATION_ID';
36+
// const location = 'LOCATION_ID';
37+
const parent = `organizations/${organizationId}/locations/${location}`;
38+
39+
// Build the request.
40+
const listDescendantEventThreatDetectionCustomModulesRequest = {
41+
parent: parent,
42+
};
43+
44+
async function listDescendantEventThreatDetectionCustomModules() {
45+
// Call the API.
46+
const [modules] =
47+
await client.listDescendantEventThreatDetectionCustomModules(
48+
listDescendantEventThreatDetectionCustomModulesRequest
49+
);
50+
for (const module of modules) {
51+
console.log('Custom Module name:', module.name);
52+
}
53+
}
54+
55+
listDescendantEventThreatDetectionCustomModules();
56+
// [END securitycenter_list_descendant_event_threat_detection_custom_module]
57+
}
58+
59+
main(...process.argv.slice(2));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright 2025 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+
// List all effective event threat detection custom module under a given parent resource.
19+
function main(organizationId, location = 'global') {
20+
// [START securitycenter_list_effective_event_threat_detection_custom_module]
21+
// Imports the Google Cloud client library.
22+
const {SecurityCenterManagementClient} =
23+
require('@google-cloud/securitycentermanagement').v1;
24+
25+
// Create a Security Center Management client
26+
const client = new SecurityCenterManagementClient();
27+
28+
/**
29+
* Required. The name of the parent resource. Its
30+
* format is "organizations/[organization_id]/locations/[location_id]",
31+
* "folders/[folder_id]/locations/[location_id]", or
32+
* "projects/[project_id]/locations/[location_id]".
33+
*/
34+
//TODO(developer): Update the following references for your own environment before running the sample.
35+
// const organizationId = 'YOUR_ORGANIZATION_ID';
36+
// const location = 'LOCATION_ID';
37+
const parent = `organizations/${organizationId}/locations/${location}`;
38+
39+
// Build the request.
40+
const listEffectiveEventThreatDetectionCustomModulesRequest = {
41+
parent: parent,
42+
};
43+
44+
async function listEffectiveEventThreatDetectionCustomModules() {
45+
// Call the API.
46+
const [modules] =
47+
await client.listEffectiveEventThreatDetectionCustomModules(
48+
listEffectiveEventThreatDetectionCustomModulesRequest
49+
);
50+
for (const module of modules) {
51+
console.log('Custom Module name:', module.name);
52+
}
53+
}
54+
55+
listEffectiveEventThreatDetectionCustomModules();
56+
// [END securitycenter_list_effective_event_threat_detection_custom_module]
57+
}
58+
59+
main(...process.argv.slice(2));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* Copyright 2025 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+
// Validates a event threat detection custom module
19+
function main(organizationId, location = 'global') {
20+
// [START securitycenter_validate_event_threat_detection_custom_module]
21+
// Imports the Google Cloud client library.
22+
const {SecurityCenterManagementClient} =
23+
require('@google-cloud/securitycentermanagement').v1;
24+
25+
// Create a Security Center Management client
26+
const client = new SecurityCenterManagementClient();
27+
28+
/**
29+
* Required. The name of the parent resource. Its
30+
* format is "organizations/[organization_id]/locations/[location_id]",
31+
* "folders/[folder_id]/locations/[location_id]", or
32+
* "projects/[project_id]/locations/[location_id]".
33+
*/
34+
//TODO(developer): Update the following references for your own environment before running the sample.
35+
// const organizationId = 'YOUR_ORGANIZATION_ID';
36+
// const location = 'LOCATION_ID';
37+
const parent = `organizations/${organizationId}/locations/${location}`;
38+
39+
// Define the raw JSON configuration for the Event Threat Detection custom module
40+
const rawText = {
41+
ips: ['192.0.2.1'],
42+
metadata: {
43+
properties: {
44+
someProperty: 'someValue',
45+
},
46+
severity: 'MEDIUM',
47+
},
48+
};
49+
50+
// Build the request.
51+
const validateEventThreatDetectionCustomModuleRequest = {
52+
parent: parent,
53+
rawText: JSON.stringify(rawText),
54+
type: 'CONFIGURABLE_BAD_IP',
55+
};
56+
57+
async function validateEventThreatDetectionCustomModule() {
58+
// Call the API.
59+
const [response] = await client.validateEventThreatDetectionCustomModule(
60+
validateEventThreatDetectionCustomModuleRequest
61+
);
62+
// Handle the response and output validation results
63+
if (response.errors && response.errors.length > 0) {
64+
response.errors.forEach(error => {
65+
console.log(
66+
`FieldPath: ${error.fieldPath}, Description: ${error.description}`
67+
);
68+
});
69+
} else {
70+
console.log('Validation successful: No errors found.');
71+
}
72+
}
73+
74+
validateEventThreatDetectionCustomModule();
75+
// [END securitycenter_validate_event_threat_detection_custom_module]
76+
}
77+
78+
main(...process.argv.slice(2));

security-center/snippets/system-test/management_api/eventThreatDetectionCustomModule.test.js

+60-23
Original file line numberDiff line numberDiff line change
@@ -29,27 +29,6 @@ const customModuleDisplayName = `node_sample_etd_custom_module_test_${uuid()}`;
2929
// Creates a new client.
3030
const client = new SecurityCenterManagementClient();
3131

32-
// cleanupExistingCustomModules clean up all the existing custom module
33-
async function cleanupExistingCustomModules() {
34-
const [modules] = await client.listEventThreatDetectionCustomModules({
35-
parent: `organizations/${organizationId}/locations/${location}`,
36-
});
37-
// Iterate over the modules response and delete custom module one by one which start with
38-
// node_sample_etd_custom_module
39-
for (const module of modules) {
40-
try {
41-
if (module.displayName.startsWith('node_sample_etd_custom_module')) {
42-
console.log('Deleting custom module: ', module.name);
43-
// extracts the custom module ID from the full name
44-
const customModuleId = module.name.split('/')[5];
45-
await deleteCustomModule(customModuleId);
46-
}
47-
} catch (error) {
48-
console.error('Error deleting EventThreatDetectionCustomModule:', error);
49-
}
50-
}
51-
}
52-
5332
// deleteCustomModule method is for deleting the custom module
5433
async function deleteCustomModule(customModuleId) {
5534
const name = `organizations/${organizationId}/locations/${location}/eventThreatDetectionCustomModules/${customModuleId}`;
@@ -63,6 +42,7 @@ async function deleteCustomModule(customModuleId) {
6342

6443
describe('Event Threat Detection Custom module', async () => {
6544
let data;
45+
const createdCustomModuleIds = [];
6646
before(async () => {
6747
const parent = `organizations/${organizationId}/locations/${location}`;
6848

@@ -120,8 +100,21 @@ describe('Event Threat Detection Custom module', async () => {
120100
});
121101

122102
after(async () => {
123-
// Perform cleanup after running tests
124-
await cleanupExistingCustomModules();
103+
// Perform cleanup of the custom modules created by the current execution of the test, after
104+
// running tests
105+
if (createdCustomModuleIds.length > 0) {
106+
for (const customModuleId of createdCustomModuleIds) {
107+
try {
108+
console.log('Deleting custom module: ', customModuleId);
109+
await deleteCustomModule(customModuleId);
110+
} catch (error) {
111+
console.error(
112+
'Error deleting EventThreatDetectionCustomModule:',
113+
error
114+
);
115+
}
116+
}
117+
}
125118
});
126119

127120
it('should get the event threat detection custom module', done => {
@@ -160,13 +153,57 @@ describe('Event Threat Detection Custom module', async () => {
160153
const output = exec(
161154
`node management_api/createEventThreatDetectionCustomModule.js ${data.orgId} ${data.customModuleName}`
162155
);
156+
// pushing the created custom module Id to an array for cleanup after running test
157+
const jsonPart = output.substring(output.indexOf('{')).trim();
158+
const parsedOutput = JSON.parse(jsonPart);
159+
createdCustomModuleIds.push(parsedOutput.name.split('/')[5]);
163160
assert(output.includes(data.orgId));
164161
assert(output.includes(data.customModuleName));
165162
assert.match(output, /EventThreatDetectionCustomModule created/);
166163
assert.notMatch(output, /undefined/);
167164
done();
168165
});
169166

167+
it('should get the effective event threat detection custom module', done => {
168+
const output = exec(
169+
`node management_api/getEffectiveEventThreatDetectionCustomModule.js ${data.orgId} ${data.customModuleId}`
170+
);
171+
assert(output.includes(data.orgId));
172+
assert(output.includes(data.customModuleId));
173+
assert.match(output, /Retrieved EffectiveEventThreatDetectionCustomModule/);
174+
assert.notMatch(output, /undefined/);
175+
done();
176+
});
177+
178+
it('should list all the effective event threat detection custom module', done => {
179+
const output = exec(
180+
`node management_api/listEffectiveEventThreatDetectionCustomModules.js ${data.orgId}`
181+
);
182+
assert(output.includes(data.orgId));
183+
assert(output.includes(data.customModuleId));
184+
assert.notMatch(output, /undefined/);
185+
done();
186+
});
187+
188+
it('should list all the descendant event threat detection custom module', done => {
189+
const output = exec(
190+
`node management_api/listDescendantEventThreatDetectionCustomModules.js ${data.orgId}`
191+
);
192+
assert(output.includes(data.orgId));
193+
assert(output.includes(data.customModuleId));
194+
assert.notMatch(output, /undefined/);
195+
done();
196+
});
197+
198+
it('should validate the event threat detection custom module', done => {
199+
const output = exec(
200+
`node management_api/validateEventThreatDetectionCustomModule.js ${data.orgId}`
201+
);
202+
assert.match(output, /Validation successful: No errors found./);
203+
assert.notMatch(output, /undefined/);
204+
done();
205+
});
206+
170207
it('should delete the event threat detection custom module', done => {
171208
const output = exec(
172209
`node management_api/deleteEventThreatDetectionCustomModule.js ${data.orgId} ${data.customModuleId}`

0 commit comments

Comments
 (0)