diff --git a/compute/snapshotSchedule/attachSnapshotSchedule.js b/compute/snapshotSchedule/attachSnapshotSchedule.js new file mode 100644 index 0000000000..6d41f0c62e --- /dev/null +++ b/compute/snapshotSchedule/attachSnapshotSchedule.js @@ -0,0 +1,85 @@ +/* + * 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'; + +async function main(snapshotScheduleName, diskName, region, zone) { + // [START compute_snapshot_schedule_attach] + // Import the Compute library + const computeLib = require('@google-cloud/compute'); + const compute = computeLib.protos.google.cloud.compute.v1; + + // Instantiate a disksClient + const disksClient = new computeLib.DisksClient(); + // Instantiate a zoneOperationsClient + const zoneOperationsClient = new computeLib.ZoneOperationsClient(); + + /** + * TODO(developer): Update/uncomment these variables before running the sample. + */ + // The project name. + const projectId = await disksClient.getProjectId(); + + // The region where the snapshot schedule was created. + // region = 'us-central1'; + + // The zone where the disk is located. + // zone = `${region}-f`; + + // The name of the disk. + // diskName = 'disk-name'; + + // The name of the snapshot schedule that you are applying to the disk. + // snapshotScheduleName = 'snapshot-schedule-name'; + + // Attach schedule to an existing disk. + async function callAttachSnapshotSchedule() { + const [response] = await disksClient.addResourcePolicies({ + project: projectId, + zone, + disk: diskName, + disksAddResourcePoliciesRequestResource: + new compute.DisksAddResourcePoliciesRequest({ + resourcePolicies: [ + `projects/${projectId}/regions/${region}/resourcePolicies/${snapshotScheduleName}`, + ], + }), + }); + + let operation = response.latestResponse; + + // Wait for the attach operation to complete. + while (operation.status !== 'DONE') { + [operation] = await zoneOperationsClient.wait({ + operation: operation.name, + project: projectId, + zone: operation.zone.split('/').pop(), + }); + } + + console.log( + `Snapshot schedule: ${snapshotScheduleName} attached to disk: ${diskName}.` + ); + } + + await callAttachSnapshotSchedule(); + // [END compute_snapshot_schedule_attach] +} + +main(...process.argv.slice(2)).catch(err => { + console.error(err); + process.exitCode = 1; +}); diff --git a/compute/snapshotSchedule/snapshotScheduleList.js b/compute/snapshotSchedule/snapshotScheduleList.js new file mode 100644 index 0000000000..b34ceda01f --- /dev/null +++ b/compute/snapshotSchedule/snapshotScheduleList.js @@ -0,0 +1,60 @@ +/* + * 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'; + +async function main(region) { + // [START compute_snapshot_schedule_list] + // Import the Compute library + const computeLib = require('@google-cloud/compute'); + + // Instantiate a resourcePoliciesClient + const resourcePoliciesClient = new computeLib.ResourcePoliciesClient(); + + /** + * TODO(developer): Update/uncomment these variables before running the sample. + */ + // The project name. + const projectId = await resourcePoliciesClient.getProjectId(); + + // The region of the snapshot schedules. + // region = 'us-central1'; + + async function callSnapshotScheduleList() { + const aggListRequest = resourcePoliciesClient.aggregatedListAsync({ + project: projectId, + filter: `region = "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/${region}"`, + }); + const result = []; + + for await (const [, listObject] of aggListRequest) { + const {resourcePolicies} = listObject; + if (resourcePolicies.length > 0) { + result.push(...resourcePolicies); + } + } + + console.log(JSON.stringify(result)); + } + + await callSnapshotScheduleList(); + // [END compute_snapshot_schedule_list] +} + +main(...process.argv.slice(2)).catch(err => { + console.error(err); + process.exitCode = 1; +}); diff --git a/compute/test/attachSnapshotSchedule.test.js b/compute/test/attachSnapshotSchedule.test.js new file mode 100644 index 0000000000..e91f325712 --- /dev/null +++ b/compute/test/attachSnapshotSchedule.test.js @@ -0,0 +1,113 @@ +/* + * 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'; + +const path = require('path'); +const assert = require('node:assert/strict'); +const {after, before, describe, it} = require('mocha'); +const cp = require('child_process'); +const uuid = require('uuid'); +const computeLib = require('@google-cloud/compute'); + +const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'}); +const cwd = path.join(__dirname, '..'); + +const disksClient = new computeLib.DisksClient(); + +async function createDisk(projectId, zone, diskName) { + const [response] = await disksClient.insert({ + project: projectId, + zone, + diskResource: { + name: diskName, + }, + }); + let operation = response.latestResponse; + const operationsClient = new computeLib.ZoneOperationsClient(); + + // Wait for the create operation to complete. + while (operation.status !== 'DONE') { + [operation] = await operationsClient.wait({ + operation: operation.name, + project: projectId, + zone: operation.zone.split('/').pop(), + }); + } +} + +async function deleteDisk(projectId, zone, diskName) { + const [response] = await disksClient.delete({ + project: projectId, + zone, + disk: diskName, + }); + let operation = response.latestResponse; + const operationsClient = new computeLib.ZoneOperationsClient(); + + // Wait for the delete operation to complete. + while (operation.status !== 'DONE') { + [operation] = await operationsClient.wait({ + operation: operation.name, + project: projectId, + zone: operation.zone.split('/').pop(), + }); + } +} + +describe('Attach snapshot schedule', async () => { + const snapshotScheduleName = `snapshot-schedule-name-${uuid.v4().split('-')[0]}`; + const diskName = `disk-name-with-schedule-attached-${uuid.v4().split('-')[0]}`; + const region = 'us-central1'; + const zone = `${region}-f`; + let projectId; + + before(async () => { + projectId = await disksClient.getProjectId(); + await createDisk(projectId, zone, diskName); + execSync( + `node ./snapshotSchedule/createSnapshotSchedule.js ${snapshotScheduleName} ${region}`, + { + cwd, + } + ); + }); + + after(async () => { + await deleteDisk(projectId, zone, diskName); + execSync( + `node ./snapshotSchedule/deleteSnapshotSchedule.js ${snapshotScheduleName} ${region}`, + { + cwd, + } + ); + }); + + it('should attach snapshot schedule to disk', () => { + const response = execSync( + `node ./snapshotSchedule/attachSnapshotSchedule.js ${snapshotScheduleName} ${diskName} ${region} ${zone}`, + { + cwd, + } + ); + + assert( + response.includes( + `Snapshot schedule: ${snapshotScheduleName} attached to disk: ${diskName}.` + ) + ); + }); +}); diff --git a/compute/test/snapshotScheduleList.test.js b/compute/test/snapshotScheduleList.test.js new file mode 100644 index 0000000000..d77583b4c2 --- /dev/null +++ b/compute/test/snapshotScheduleList.test.js @@ -0,0 +1,59 @@ +/* + * 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'; + +const path = require('path'); +const assert = require('node:assert/strict'); +const {after, before, describe, it} = require('mocha'); +const cp = require('child_process'); +const uuid = require('uuid'); + +const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'}); +const cwd = path.join(__dirname, '..'); + +describe('Snapshot schedule list', async () => { + const snapshotScheduleName = `snapshot-list-name-${uuid.v4().split('-')[0]}`; + const region = 'us-central1'; + + before(() => { + execSync( + `node ./snapshotSchedule/createSnapshotSchedule.js ${snapshotScheduleName} ${region}`, + { + cwd, + } + ); + }); + + after(() => { + execSync( + `node ./snapshotSchedule/deleteSnapshotSchedule.js ${snapshotScheduleName} ${region}`, + { + cwd, + } + ); + }); + + it('should return list of snapshot schedules', () => { + const response = JSON.parse( + execSync(`node ./snapshotSchedule/snapshotScheduleList.js ${region}`, { + cwd, + }) + ); + + assert(Array.isArray(response)); + }); +});