From d9523da19edb66fae3409bda748d4b2d4f1731af Mon Sep 17 00:00:00 2001 From: Joanna Grycz Date: Mon, 2 Dec 2024 16:08:45 +0100 Subject: [PATCH 1/2] feat: compute_snapshot_schedule_attach --- .../attachSnapshotSchedule.js | 85 +++++++++++++ .../createSnapshotSchedule.js | 103 ++++++++++++++++ .../deleteSnapshotSchedule.js | 70 +++++++++++ compute/test/attachSnapshotSchedule.test.js | 113 ++++++++++++++++++ 4 files changed, 371 insertions(+) create mode 100644 compute/snapshotSchedule/attachSnapshotSchedule.js create mode 100644 compute/snapshotSchedule/createSnapshotSchedule.js create mode 100644 compute/snapshotSchedule/deleteSnapshotSchedule.js create mode 100644 compute/test/attachSnapshotSchedule.test.js diff --git a/compute/snapshotSchedule/attachSnapshotSchedule.js b/compute/snapshotSchedule/attachSnapshotSchedule.js new file mode 100644 index 0000000000..352d0f5e0b --- /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 zone where the disk is located. + // zone = 'europe-central2-a'; + + // The region where the snapshot schedule was created. + // region = 'europe-central2'; + + // 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/createSnapshotSchedule.js b/compute/snapshotSchedule/createSnapshotSchedule.js new file mode 100644 index 0000000000..3fb6db1852 --- /dev/null +++ b/compute/snapshotSchedule/createSnapshotSchedule.js @@ -0,0 +1,103 @@ +/* + * 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, region) { + // [START compute_snapshot_schedule_create] + // Import the Compute library + const computeLib = require('@google-cloud/compute'); + const compute = computeLib.protos.google.cloud.compute.v1; + + // Instantiate a resourcePoliciesClient + const resourcePoliciesClient = new computeLib.ResourcePoliciesClient(); + // Instantiate a regionOperationsClient + const regionOperationsClient = new computeLib.RegionOperationsClient(); + + /** + * TODO(developer): Update/uncomment these variables before running the sample. + */ + // The project name. + const projectId = await resourcePoliciesClient.getProjectId(); + + // The location of the snapshot schedule resource policy. + // region = 'europe-central2'; + + // The name of the snapshot schedule. + // snapshotScheduleName = 'snapshot-schedule-name'; + + // The description of the snapshot schedule. + const snapshotScheduleDescription = 'snapshot schedule description...'; + + async function callCreateSnapshotSchedule() { + const [response] = await resourcePoliciesClient.insert({ + project: projectId, + region, + resourcePolicyResource: new compute.ResourcePolicy({ + name: snapshotScheduleName, + description: snapshotScheduleDescription, + snapshotSchedulePolicy: + new compute.ResourcePolicyInstanceSchedulePolicySchedule({ + retentionPolicy: + new compute.ResourcePolicySnapshotSchedulePolicyRetentionPolicy({ + maxRetentionDays: 5, + }), + schedule: new compute.ResourcePolicySnapshotSchedulePolicySchedule({ + // Similarly, you can create a weekly or monthly schedule. + // Review the resourcePolicies.insert method for details specific to setting a weekly or monthly schedule. + dailySchedule: new compute.ResourcePolicyDailyCycle({ + startTime: '12:00', + daysInCycle: 1, + }), + }), + snapshotProperties: + new compute.ResourcePolicySnapshotSchedulePolicySnapshotProperties( + { + guestFlush: false, + labels: { + env: 'dev', + media: 'images', + }, + // OPTIONAL: the storage location. If you omit this flag, the default storage location is used. + // storageLocations: 'storage-location', + } + ), + }), + }), + }); + + let operation = response.latestResponse; + + // Wait for the create operation to complete. + while (operation.status !== 'DONE') { + [operation] = await regionOperationsClient.wait({ + operation: operation.name, + project: projectId, + region, + }); + } + + console.log(`Snapshot schedule: ${snapshotScheduleName} created.`); + } + + await callCreateSnapshotSchedule(); + // [END compute_snapshot_schedule_create] +} + +main(...process.argv.slice(2)).catch(err => { + console.error(err); + process.exitCode = 1; +}); diff --git a/compute/snapshotSchedule/deleteSnapshotSchedule.js b/compute/snapshotSchedule/deleteSnapshotSchedule.js new file mode 100644 index 0000000000..06089cbb52 --- /dev/null +++ b/compute/snapshotSchedule/deleteSnapshotSchedule.js @@ -0,0 +1,70 @@ +/* + * 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, region) { + // [START compute_snapshot_schedule_delete] + // Import the Compute library + const computeLib = require('@google-cloud/compute'); + + // Instantiate a resourcePoliciesClient + const resourcePoliciesClient = new computeLib.ResourcePoliciesClient(); + // Instantiate a regionOperationsClient + const regionOperationsClient = new computeLib.RegionOperationsClient(); + + /** + * TODO(developer): Update/uncomment these variables before running the sample. + */ + // The project name. + const projectId = await resourcePoliciesClient.getProjectId(); + + // The location of the snapshot schedule resource policy. + // region = 'europe-central2'; + + // The name of the snapshot schedule. + // snapshotScheduleName = 'snapshot-schedule-name' + + async function callDeleteSnapshotSchedule() { + // If the snapshot schedule is already attached to a disk, you will receive an error. + const [response] = await resourcePoliciesClient.delete({ + project: projectId, + region, + resourcePolicy: snapshotScheduleName, + }); + + let operation = response.latestResponse; + + // Wait for the delete operation to complete. + while (operation.status !== 'DONE') { + [operation] = await regionOperationsClient.wait({ + operation: operation.name, + project: projectId, + region, + }); + } + + console.log(`Snapshot schedule: ${snapshotScheduleName} deleted.`); + } + + await callDeleteSnapshotSchedule(); + // [END compute_snapshot_schedule_delete] +} + +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..4d9158adba --- /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 = 'europe-central2'; + const zone = 'europe-central2-a'; + 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}.` + ) + ); + }); +}); From 0397137ea0be680a9120179d3f8ecdd6ac7dab48 Mon Sep 17 00:00:00 2001 From: Joanna Grycz Date: Tue, 3 Dec 2024 09:22:21 +0100 Subject: [PATCH 2/2] feat: compute_snapshot_schedule_list --- .../attachSnapshotSchedule.js | 8 +-- .../createSnapshotSchedule.js | 2 +- .../deleteSnapshotSchedule.js | 2 +- .../snapshotSchedule/snapshotScheduleList.js | 60 +++++++++++++++++++ compute/test/attachSnapshotSchedule.test.js | 4 +- compute/test/snapshotScheduleList.test.js | 59 ++++++++++++++++++ 6 files changed, 127 insertions(+), 8 deletions(-) create mode 100644 compute/snapshotSchedule/snapshotScheduleList.js create mode 100644 compute/test/snapshotScheduleList.test.js diff --git a/compute/snapshotSchedule/attachSnapshotSchedule.js b/compute/snapshotSchedule/attachSnapshotSchedule.js index 352d0f5e0b..6d41f0c62e 100644 --- a/compute/snapshotSchedule/attachSnapshotSchedule.js +++ b/compute/snapshotSchedule/attachSnapshotSchedule.js @@ -33,11 +33,11 @@ async function main(snapshotScheduleName, diskName, region, zone) { // The project name. const projectId = await disksClient.getProjectId(); - // The zone where the disk is located. - // zone = 'europe-central2-a'; - // The region where the snapshot schedule was created. - // region = 'europe-central2'; + // region = 'us-central1'; + + // The zone where the disk is located. + // zone = `${region}-f`; // The name of the disk. // diskName = 'disk-name'; diff --git a/compute/snapshotSchedule/createSnapshotSchedule.js b/compute/snapshotSchedule/createSnapshotSchedule.js index 3fb6db1852..321c6f8d53 100644 --- a/compute/snapshotSchedule/createSnapshotSchedule.js +++ b/compute/snapshotSchedule/createSnapshotSchedule.js @@ -34,7 +34,7 @@ async function main(snapshotScheduleName, region) { const projectId = await resourcePoliciesClient.getProjectId(); // The location of the snapshot schedule resource policy. - // region = 'europe-central2'; + // region = 'us-central1'; // The name of the snapshot schedule. // snapshotScheduleName = 'snapshot-schedule-name'; diff --git a/compute/snapshotSchedule/deleteSnapshotSchedule.js b/compute/snapshotSchedule/deleteSnapshotSchedule.js index 06089cbb52..aee5a13853 100644 --- a/compute/snapshotSchedule/deleteSnapshotSchedule.js +++ b/compute/snapshotSchedule/deleteSnapshotSchedule.js @@ -33,7 +33,7 @@ async function main(snapshotScheduleName, region) { const projectId = await resourcePoliciesClient.getProjectId(); // The location of the snapshot schedule resource policy. - // region = 'europe-central2'; + // region = 'us-central1'; // The name of the snapshot schedule. // snapshotScheduleName = 'snapshot-schedule-name' 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 index 4d9158adba..e91f325712 100644 --- a/compute/test/attachSnapshotSchedule.test.js +++ b/compute/test/attachSnapshotSchedule.test.js @@ -71,8 +71,8 @@ async function deleteDisk(projectId, zone, diskName) { 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 = 'europe-central2'; - const zone = 'europe-central2-a'; + const region = 'us-central1'; + const zone = `${region}-f`; let projectId; before(async () => { 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)); + }); +});