Skip to content

Commit a662c8b

Browse files
authored
feat(security-center): Adding SCC's BigQueryExport resource (#3847)
* feat(bigquery): Add Resource v2 API Big Query Samples * Fix lint * fix the failing test check by replacing the project * Address Suggestions * fix the test error * fix the lint error * Add dataset creation logic * fix lint error * Add cleanup for dataset * Fix lint error * Address suggestions * add the missing word in console log * Add comment variable for location
1 parent cb91d9c commit a662c8b

9 files changed

+509
-2
lines changed

security-center/snippets/package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"c8": "^10.0.0",
2121
"chai": "^4.5.0",
2222
"mocha": "^10.4.0",
23-
"uuid": "^10.0.0"
23+
"uuid": "^10.0.0",
24+
"@google-cloud/bigquery": "^7.0.0"
2425
}
2526
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
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+
const {SecurityCenterClient} = require('@google-cloud/security-center').v2;
18+
const {assert} = require('chai');
19+
const {execSync} = require('child_process');
20+
const exec = cmd => execSync(cmd, {encoding: 'utf8'});
21+
const {describe, it, before} = require('mocha');
22+
const {BigQuery} = require('@google-cloud/bigquery');
23+
24+
const organizationId = process.env.GCLOUD_ORGANIZATION;
25+
const projectId = process.env.GOOGLE_SAMPLES_PROJECT;
26+
const location = 'global';
27+
const bigquery = new BigQuery();
28+
29+
async function cleanupDatasets() {
30+
const [datasets] = await bigquery.getDatasets();
31+
for (const dataset of datasets) {
32+
if (dataset.id.startsWith('securitycenter_')) {
33+
console.log(`Deleting dataset: ${dataset.id}`);
34+
await bigquery.dataset(dataset.id).delete({force: true});
35+
}
36+
}
37+
}
38+
39+
async function cleanupBigQueryExports(client) {
40+
const [exports] = await client.listBigQueryExports({
41+
parent: client.organizationLocationPath(organizationId, location),
42+
});
43+
for (const exportData of exports) {
44+
console.log(`Deleting BigQuery export: ${exportData.name}`);
45+
await client.deleteBigQueryExport({name: exportData.name});
46+
}
47+
}
48+
49+
let dataset;
50+
51+
async function createDataset() {
52+
const randomSuffix = Math.floor(Date.now() / 1000);
53+
const datasetId = `securitycenter_dataset_${randomSuffix}`;
54+
const options = {
55+
location: 'US',
56+
};
57+
58+
try {
59+
const [createdDataset] = await bigquery.createDataset(datasetId, options);
60+
console.log(`Dataset ${createdDataset.id} created.`);
61+
return createdDataset.id;
62+
} catch (error) {
63+
if (error.code === 409) {
64+
// Dataset already exists - Fail the test instead of moving on
65+
console.log(
66+
`Dataset ${datasetId} already exists. Exiting to avoid conflict.`
67+
);
68+
throw new Error(`Dataset ${datasetId} already exists.`);
69+
}
70+
throw error;
71+
}
72+
}
73+
74+
describe('Client with bigquery export V2', async () => {
75+
let data;
76+
before(async () => {
77+
// Creates a new client.
78+
const client = new SecurityCenterClient();
79+
80+
// Clean up any existing datasets or BigQuery exports
81+
await cleanupDatasets();
82+
await cleanupBigQueryExports(client);
83+
84+
// Create a new dataset
85+
const createdDataset = await createDataset();
86+
dataset = `projects/${projectId}/datasets/${createdDataset}`;
87+
88+
// Build the create bigquery export request.
89+
const bigQueryExportId =
90+
'bigqueryexportid-' + Math.floor(Math.random() * 10000);
91+
const filter = 'severity="LOW" OR severity="MEDIUM"';
92+
const bigQueryExport = {
93+
name: 'bigQueryExport node',
94+
description:
95+
'Export low and medium findings if the compute resource has an IAM anomalous grant',
96+
filter: filter,
97+
dataset: dataset,
98+
};
99+
const createBigQueryExportRequest = {
100+
parent: client.organizationLocationPath(organizationId, location),
101+
bigQueryExport,
102+
bigQueryExportId,
103+
};
104+
105+
try {
106+
const response = await client.createBigQueryExport(
107+
createBigQueryExportRequest
108+
);
109+
const bigQueryExportResponse = response[0];
110+
data = {
111+
orgId: organizationId,
112+
bigQueryExportId: bigQueryExportId,
113+
bigQueryExportName: bigQueryExportResponse.name,
114+
untouchedbigQueryExportName: '',
115+
};
116+
console.log('Created BigQuery export %j', data);
117+
} catch (error) {
118+
console.error('Error creating BigQuery export:', error);
119+
}
120+
});
121+
122+
it('client can create bigquery export V2', done => {
123+
const output = exec(
124+
`node v2/createBigQueryExport.js ${data.orgId} ${dataset}`
125+
);
126+
assert(output.includes(data.orgId));
127+
assert.match(output, /BigQuery export request created successfully/);
128+
assert.notMatch(output, /undefined/);
129+
done();
130+
});
131+
132+
it('client can list all bigquery export V2', done => {
133+
const output = exec(`node v2/listAllBigQueryExports.js ${data.orgId}`);
134+
assert(output.includes(data.bigQueryExportName));
135+
assert.match(output, /Sources/);
136+
assert.notMatch(output, /undefined/);
137+
done();
138+
});
139+
140+
it('client can get a bigquery export V2', done => {
141+
const output = exec(
142+
`node v2/getBigQueryExport.js ${data.orgId} ${data.bigQueryExportId}`
143+
);
144+
assert(output.includes(data.bigQueryExportName));
145+
assert.match(output, /Retrieved the BigQuery export/);
146+
assert.notMatch(output, /undefined/);
147+
done();
148+
});
149+
150+
it('client can update a bigquery export V2', done => {
151+
const output = exec(
152+
`node v2/updateBigQueryExport.js ${data.orgId} ${data.bigQueryExportId} ${dataset}`
153+
);
154+
assert.match(output, /BigQueryExport updated successfully/);
155+
assert.notMatch(output, /undefined/);
156+
done();
157+
});
158+
159+
it('client can delete a bigquery export V2', done => {
160+
const output = exec(
161+
`node v2/deleteBigQueryExport.js ${data.orgId} ${data.bigQueryExportId}`
162+
);
163+
assert.match(output, /BigQuery export request deleted successfully/);
164+
assert.notMatch(output, /undefined/);
165+
done();
166+
});
167+
});

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ describe('Client with Notifications v2', async () => {
4141

4242
before(async () => {
4343
const configId = 'notif-config-test-node-create-' + uuidv1();
44-
topicName = 'test_topic';
44+
topicName = 'notifications-sample-topic';
4545
parent = `projects/${projectId}/locations/${location}`;
4646
pubsubTopic = `projects/${projectId}/topics/${topicName}`;
4747

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+
'use strict';
17+
18+
/**
19+
* Demonstrates how to create a new security finding in CSCC.
20+
*/
21+
function main(organizationId, dataset, location = 'global') {
22+
// [START securitycenter_create_bigquery_export_v2]
23+
// Imports the Google Cloud client library.
24+
const {SecurityCenterClient} = require('@google-cloud/security-center').v2;
25+
26+
// Create a Security Center client
27+
const client = new SecurityCenterClient();
28+
29+
/**
30+
* Required. The name of the parent resource of the new BigQuery export. Its
31+
* format is "organizations/[organization_id]/locations/[location_id]",
32+
* "folders/[folder_id]/locations/[location_id]", or
33+
* "projects/[project_id]/locations/[location_id]".
34+
*/
35+
const parent = client.organizationLocationPath(organizationId, location);
36+
37+
/**
38+
* Required. The BigQuery export being created.
39+
*/
40+
// filter: Expression that defines the filter to apply across create/update events of findings.
41+
const filter = 'severity="LOW" OR severity="MEDIUM"';
42+
43+
const bigQueryExport = {
44+
name: 'bigQueryExport node',
45+
description:
46+
'Export low and medium findings if the compute resource has an IAM anomalous grant',
47+
filter,
48+
dataset,
49+
};
50+
51+
/**
52+
* Required. Unique identifier provided by the client within the parent scope.
53+
* It must consist of only lowercase letters, numbers, and hyphens, must start
54+
* with a letter, must end with either a letter or a number, and must be 63
55+
* characters or less.
56+
*/
57+
const bigQueryExportId =
58+
'bigqueryexportid-' + Math.floor(Math.random() * 10000);
59+
60+
// Build the request.
61+
const createBigQueryExportRequest = {
62+
parent,
63+
bigQueryExport,
64+
bigQueryExportId,
65+
};
66+
67+
async function createBigQueryExport() {
68+
// Call the API.
69+
const [response] = await client.createBigQueryExport(
70+
createBigQueryExportRequest
71+
);
72+
console.log(
73+
`BigQuery export request created successfully: Name: ${response.name}, Dataset: ${response.dataset}, Description: ${response.description}`
74+
);
75+
}
76+
77+
createBigQueryExport();
78+
// [END securitycenter_create_bigquery_export_v2]
79+
}
80+
81+
main(...process.argv.slice(2));
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+
'use strict';
17+
18+
/**
19+
* Delete an existing BigQuery export.
20+
*/
21+
function main(organizationId, exportId, location = 'global') {
22+
// [START securitycenter_delete_bigquery_export_v2]
23+
// Imports the Google Cloud client library.
24+
const {SecurityCenterClient} = require('@google-cloud/security-center').v2;
25+
26+
// Creates a new client.
27+
const client = new SecurityCenterClient();
28+
29+
// Build the full resource path for the BigQuery export to delete.
30+
/*
31+
* TODO(developer): Update the following references for your own environment before running the sample.
32+
*/
33+
// const organizationId = 'YOUR_ORGANIZATION_ID';
34+
// const exportId = 'EXPORT_ID';
35+
const name = `organizations/${organizationId}/locations/${location}/bigQueryExports/${exportId}`;
36+
37+
// Build the request.
38+
const deleteBigQueryExportRequest = {
39+
name,
40+
};
41+
42+
async function deleteBigQueryExport() {
43+
// Call the API.
44+
const [response] = await client.deleteBigQueryExport(
45+
deleteBigQueryExportRequest
46+
);
47+
console.log('BigQuery export request deleted successfully: %j', response);
48+
}
49+
50+
deleteBigQueryExport();
51+
// [END securitycenter_delete_bigquery_export_v2]
52+
}
53+
54+
main(...process.argv.slice(2));

security-center/snippets/v2/deleteSecurityMarks.js

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ function main(
3636
*/
3737
// const organizationId = 'YOUR_ORGANIZATION_ID';
3838
// const sourceId = 'SOURCE_ID';
39+
// const location = 'LOCATION_ID';
3940
const findingName = `organizations/${organizationId}/sources/${sourceId}/locations/${location}/findings/${findingId}`;
4041

4142
// Construct the request to be sent by the client.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
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+
/**
19+
* Retrieve an existing BigQuery export.
20+
*/
21+
function main(organizationId, exportId, location = 'global') {
22+
// [START securitycenter_get_bigquery_export_v2]
23+
// Imports the Google Cloud client library.
24+
const {SecurityCenterClient} = require('@google-cloud/security-center').v2;
25+
26+
// Creates a new client.
27+
const client = new SecurityCenterClient();
28+
29+
// Build the full resource path for the BigQuery export to retrieve.
30+
/*
31+
* TODO(developer): Update the following references for your own environment before running the sample.
32+
*/
33+
// const organizationId = 'YOUR_ORGANIZATION_ID';
34+
// const exportId = 'EXPORT_ID';
35+
// const location = 'LOCATION_ID';
36+
const name = `organizations/${organizationId}/locations/${location}/bigQueryExports/${exportId}`;
37+
38+
// Build the request.
39+
const getBigQueryExportRequest = {
40+
name,
41+
};
42+
43+
async function getBigQueryExport() {
44+
// Call the API.
45+
const [response] = await client.getBigQueryExport(getBigQueryExportRequest);
46+
console.log('Retrieved the BigQuery export: %j', response);
47+
}
48+
49+
getBigQueryExport();
50+
// [END securitycenter_get_bigquery_export_v2]
51+
}
52+
53+
main(...process.argv.slice(2));

0 commit comments

Comments
 (0)