|
| 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 | +}); |
0 commit comments