From 190141d02910ccb1c8688875c45905d0e5f5f26c Mon Sep 17 00:00:00 2001 From: Joanna Grycz Date: Thu, 3 Oct 2024 16:33:17 +0200 Subject: [PATCH 1/4] feat: compute_reservation_create_shared --- compute/package.json | 3 +- .../reservations/createSharedReservation.js | 108 ++++++++++++++++++ compute/test/sharedReservation.test.js | 68 +++++++++++ 3 files changed, 178 insertions(+), 1 deletion(-) create mode 100644 compute/reservations/createSharedReservation.js create mode 100644 compute/test/sharedReservation.test.js diff --git a/compute/package.json b/compute/package.json index 374d13e292..131aac53f3 100644 --- a/compute/package.json +++ b/compute/package.json @@ -17,7 +17,8 @@ "@google-cloud/compute": "^4.0.0", "@sendgrid/mail": "^8.0.0", "nodemailer": "^6.0.0", - "nodemailer-smtp-transport": "^2.7.4" + "nodemailer-smtp-transport": "^2.7.4", + "sinon": "^19.0.2" }, "devDependencies": { "@google-cloud/storage": "^7.0.0", diff --git a/compute/reservations/createSharedReservation.js b/compute/reservations/createSharedReservation.js new file mode 100644 index 0000000000..6c3b25350f --- /dev/null +++ b/compute/reservations/createSharedReservation.js @@ -0,0 +1,108 @@ +/* + * 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(reservationsClient, zoneOperationsClient) { + // [START compute_reservation_create_shared] + // Import the Compute library + const computeLib = require('@google-cloud/compute'); + const compute = computeLib.protos.google.cloud.compute.v1; + + /** + * TODO(developer): Uncomment reservationsClient and zoneOperationsClient before running the sample. + */ + // Instantiate a reservationsClient + // reservationsClient = new computeLib.ReservationsClient(); + // Instantiate a zoneOperationsClient + // zoneOperationsClient = new computeLib.ZoneOperationsClient(); + + /** + * TODO(developer): Update these variables before running the sample. + */ + // The ID of the project where you want to reserve resources and where the instance template exists. + const projectId = await reservationsClient.getProjectId(); + // The zone in which to reserve resources. + const zone = 'us-central1-a'; + // The name of the reservation to create. + const reservationName = 'reservation-01'; + // The number of VMs to reserve. + const vmsNumber = 3; + // The name of an existing instance template. + const instanceTemplateName = 'global-instance-template-name'; + // The location of the instance template. + const location = 'global'; + + async function callCreateComputeSharedReservation() { + // Create reservation for 3 VMs in zone us-central1-a by specifying a instance template. + const specificReservation = new compute.AllocationSpecificSKUReservation({ + count: vmsNumber, + sourceInstanceTemplate: `projects/${projectId}/${location}/instanceTemplates/${instanceTemplateName}`, + }); + + // Create share settings. Share reservation with one customer project. + const shareSettings = new compute.ShareSettings({ + shareType: 'SPECIFIC_PROJECTS', + projectMap: { + // The IDs of projects that can consume this reservation. You can include up to 100 consumer projects. + // These projects must be in the same organization as the owner project. + // Don't include the owner project. By default, it is already allowed to consume the reservation. + consumer_project_id: { + projectId: 'consumer_project_id', + }, + }, + }); + + // Create a reservation. + const reservation = new compute.Reservation({ + name: reservationName, + specificReservation, + specificReservationRequired: true, + shareSettings, + }); + + const [response] = await reservationsClient.insert({ + project: projectId, + reservationResource: reservation, + zone, + }); + + let operation = response.latestResponse; + + // Wait for the create reservation operation to complete. + while (operation.status !== 'DONE') { + [operation] = await zoneOperationsClient.wait({ + operation: operation.name, + project: projectId, + zone: operation.zone.split('/').pop(), + }); + } + + console.log(`Reservation: ${reservationName} created.`); + return response; + } + + return await callCreateComputeSharedReservation(); + // [END compute_reservation_create_shared] +} + +module.exports = main; + +// TODO(developer): Uncomment below lines before running the sample. +// main(...process.argv.slice(2)).catch(err => { +// console.error(err); +// process.exitCode = 1; +// }); diff --git a/compute/test/sharedReservation.test.js b/compute/test/sharedReservation.test.js new file mode 100644 index 0000000000..0c80687d4a --- /dev/null +++ b/compute/test/sharedReservation.test.js @@ -0,0 +1,68 @@ +/* + * 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 {beforeEach, afterEach, describe, it} = require('mocha'); +const assert = require('node:assert/strict'); +const sinon = require('sinon'); +const createSharedReservation = require('../reservations/createSharedReservation.js'); + +describe('Create compute shared reservation using global instance template', async () => { + const reservationName = 'reservation-01'; + let reservationsClientMock; + let zoneOperationsClientMock; + + beforeEach(() => { + reservationsClientMock = { + getProjectId: sinon.stub().resolves('project_id'), + insert: sinon.stub().resolves([ + { + name: reservationName, + latestResponse: { + status: 'DONE', + name: 'operation-1234567890', + zone: { + value: 'us-central1-a', + }, + }, + }, + ]), + }; + zoneOperationsClientMock = { + wait: sinon.stub().resolves([ + { + latestResponse: { + status: 'DONE', + }, + }, + ]), + }; + }); + + afterEach(() => { + sinon.restore(); + }); + + it('should create shared reservation', async () => { + const response = await createSharedReservation( + reservationsClientMock, + zoneOperationsClientMock + ); + + assert(response.name.includes(reservationName)); + }); +}); From 36677a4404ce98285b297e1e69a910599c94732d Mon Sep 17 00:00:00 2001 From: Joanna Grycz Date: Wed, 2 Oct 2024 16:52:53 +0200 Subject: [PATCH 2/4] feat: compute_reservation_create_from_vm --- .../reservations/createReservationFromVM.js | 102 ++++++++++++++++++ compute/test/createReservationFromVM.test.js | 70 ++++++++++++ 2 files changed, 172 insertions(+) create mode 100644 compute/reservations/createReservationFromVM.js create mode 100644 compute/test/createReservationFromVM.test.js diff --git a/compute/reservations/createReservationFromVM.js b/compute/reservations/createReservationFromVM.js new file mode 100644 index 0000000000..f263a8ecf1 --- /dev/null +++ b/compute/reservations/createReservationFromVM.js @@ -0,0 +1,102 @@ +/* + * 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(reservationName, vmName, zone) { + // [START compute_reservation_create_from_vm] + // Import the Compute library + const computeLib = require('@google-cloud/compute'); + const compute = computeLib.protos.google.cloud.compute.v1; + + // Instantiate a reservationsClient + const reservationsClient = new computeLib.ReservationsClient(); + // Instantiate a zoneOperationsClient + const zoneOperationsClient = new computeLib.ZoneOperationsClient(); + // Instantiate a instancesClient + const instancesClient = new computeLib.InstancesClient(); + + /** + * TODO(developer): Update/uncomment these variables before running the sample. + */ + // The ID of the project where you want to reserve resources and where the instance template exists. + const projectId = await reservationsClient.getProjectId(); + // The zone in which to reserve resources. + zone = 'us-central1-a'; + // The name of the reservation to create. + // reservationName = 'reservation-02'; + // The name of the VM which properties you want to use to create the reservation. + // vmName = 'vm-01'; + // The number of VMs to reserve. + const vmsNumber = 3; + + async function callCreateComputeReservationFromVM() { + // Get specified VM + const [vm] = await instancesClient.get({ + project: projectId, + zone, + instance: vmName, + }); + + // Create reservation for 3 VMs in zone us-central1-a by specifying directly the properties from the desired VM + const specificReservation = new compute.AllocationSpecificSKUReservation({ + count: vmsNumber, + instanceProperties: { + machineType: vm.machineType.split('/').pop(), + minCpuPlatform: vm.minCpuPlatform, + guestAccelerators: vm.guestAccelerators + ? [...vm.guestAccelerators] + : [], + localSsds: vm.localSsds ? [...vm.localSsds] : [], + }, + }); + + // Create a reservation. + const reservation = new compute.Reservation({ + name: reservationName, + zone, + specificReservation, + specificReservationRequired: true, + }); + + const [response] = await reservationsClient.insert({ + project: projectId, + reservationResource: reservation, + zone, + }); + + let operation = response.latestResponse; + + // Wait for the create reservation operation to complete. + while (operation.status !== 'DONE') { + [operation] = await zoneOperationsClient.wait({ + operation: operation.name, + project: projectId, + zone: operation.zone.split('/').pop(), + }); + } + + console.log(`Reservation: ${reservationName} created.`); + } + + await callCreateComputeReservationFromVM(); + // [END compute_reservation_create_from_vm] +} + +main(...process.argv.slice(2)).catch(err => { + console.error(err.message); + process.exitCode = 1; +}); diff --git a/compute/test/createReservationFromVM.test.js b/compute/test/createReservationFromVM.test.js new file mode 100644 index 0000000000..7a4bc91c04 --- /dev/null +++ b/compute/test/createReservationFromVM.test.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'; + +const path = require('path'); +const assert = require('node:assert/strict'); +const {before, after, describe, it} = require('mocha'); +const cp = require('child_process'); +const {ReservationsClient} = require('@google-cloud/compute').v1; + +const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'}); +const cwd = path.join(__dirname, '..'); + +describe('Compute reservation from VM', async () => { + const reservationName = `reservation-1a0bb${Math.floor(Math.random() * 1000 + 1)}`; + const vmName = `vm-1a0bb${Math.floor(Math.random() * 1000 + 1)}`; + const zone = 'us-central1-a'; + const machineType = 'e2-small'; + const reservationsClient = new ReservationsClient(); + let projectId; + + before(async () => { + projectId = await reservationsClient.getProjectId(); + + // Create VM + execSync( + `node ./createInstance.js ${projectId} ${zone} ${vmName} ${machineType}`, + { + cwd, + } + ); + }); + + after(() => { + // Delete reservation + execSync(`node ./reservations/deleteReservation.js ${reservationName}`, { + cwd, + }); + + // Delete VM + execSync(`node ./deleteInstance.js ${projectId} ${zone} ${vmName}`, { + cwd, + }); + }); + + it('should create a new reservation from vm', () => { + const response = execSync( + `node ./reservations/createReservationFromVM.js ${reservationName} ${vmName} ${zone}`, + { + cwd, + } + ); + + assert(response.includes(`Reservation: ${reservationName} created.`)); + }); +}); From 5cd6e022a9e79a19bfec980f0fb5c522050b6b16 Mon Sep 17 00:00:00 2001 From: Joanna Grycz Date: Mon, 7 Oct 2024 23:22:48 +0200 Subject: [PATCH 3/4] Cleanup resources before tests --- compute/test/consumeReservations.test.js | 2 +- compute/test/createComputeHyperdisk.test.js | 7 +- .../createComputeHyperdiskFromPool.test.js | 75 ++++------- compute/test/reservations.test.js | 2 +- compute/test/util.js | 125 +++++++++++++++++- 5 files changed, 159 insertions(+), 52 deletions(-) diff --git a/compute/test/consumeReservations.test.js b/compute/test/consumeReservations.test.js index 372c4ab063..8ca419fcc4 100644 --- a/compute/test/consumeReservations.test.js +++ b/compute/test/consumeReservations.test.js @@ -39,7 +39,7 @@ describe('Consume reservations', async () => { before(async () => { projectId = await reservationsClient.getProjectId(); - // Clean up + // Cleanup resources const instances = await getStaleVMInstances('instance-458a88aab'); await Promise.all( instances.map(instance => diff --git a/compute/test/createComputeHyperdisk.test.js b/compute/test/createComputeHyperdisk.test.js index 3c098c98e4..97dabe02c5 100644 --- a/compute/test/createComputeHyperdisk.test.js +++ b/compute/test/createComputeHyperdisk.test.js @@ -20,19 +20,24 @@ const path = require('path'); const assert = require('node:assert/strict'); const {before, after, describe, it} = require('mocha'); const cp = require('child_process'); +const {getStaleDisks, deleteDisk} = require('./util'); const {DisksClient} = require('@google-cloud/compute').v1; const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'}); const cwd = path.join(__dirname, '..'); describe('Create compute hyperdisk', async () => { - const diskName = `hyperdisk-name-941ad2d${Math.floor(Math.random() * 1000 + 1)}`; + const prefix = 'hyperdisk-name-941ad2d'; + const diskName = `${prefix}${Math.floor(Math.random() * 1000 + 1)}`; const zone = 'europe-central2-b'; const disksClient = new DisksClient(); let projectId; before(async () => { projectId = await disksClient.getProjectId(); + // Cleanup resources + const disks = await getStaleDisks(prefix); + await Promise.all(disks.map(disk => deleteDisk(disk.zone, disk.diskName))); }); after(async () => { diff --git a/compute/test/createComputeHyperdiskFromPool.test.js b/compute/test/createComputeHyperdiskFromPool.test.js index 063b22c16b..4f450cb651 100644 --- a/compute/test/createComputeHyperdiskFromPool.test.js +++ b/compute/test/createComputeHyperdiskFromPool.test.js @@ -20,64 +20,43 @@ const path = require('path'); const assert = require('node:assert/strict'); const {after, before, describe, it} = require('mocha'); const cp = require('child_process'); -const {DisksClient, StoragePoolsClient, ZoneOperationsClient} = - require('@google-cloud/compute').v1; + +const { + getStaleDisks, + deleteDisk, + getStaleStoragePools, + deleteStoragePool, +} = require('./util'); const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'}); const cwd = path.join(__dirname, '..'); -async function cleanupResources(projectId, zone, diskName, storagePoolName) { - const disksClient = new DisksClient(); - const storagePoolsClient = new StoragePoolsClient(); - const zoneOperationsClient = new ZoneOperationsClient(); - // Delete disk attached to storagePool - const [diskResponse] = await disksClient.delete({ - project: projectId, - disk: diskName, - zone, - }); - - let diskOperation = diskResponse.latestResponse; - - // Wait for the delete disk operation to complete. - while (diskOperation.status !== 'DONE') { - [diskOperation] = await zoneOperationsClient.wait({ - operation: diskOperation.name, - project: projectId, - zone: diskOperation.zone.split('/').pop(), - }); - } - - const [poolResponse] = await storagePoolsClient.delete({ - project: projectId, - storagePool: storagePoolName, - zone, - }); - let poolOperation = poolResponse.latestResponse; - - // Wait for the delete pool operation to complete. - while (poolOperation.status !== 'DONE') { - [poolOperation] = await zoneOperationsClient.wait({ - operation: poolOperation.name, - project: projectId, - zone: poolOperation.zone.split('/').pop(), - }); - } -} - describe('Create compute hyperdisk from pool', async () => { - const diskName = `disk-from-pool-name-745d98${Math.floor(Math.random() * 1000 + 1)}f`; - const zone = 'us-central1-a'; - const storagePoolName = `storage-pool-name-745d9${Math.floor(Math.random() * 1000 + 1)}5f`; - const disksClient = new DisksClient(); - let projectId; + const diskPrefix = 'disk-from-pool-name-745d98'; + const poolPrefix = 'storage-pool-name-745d9'; + const diskName = `${diskPrefix}${Math.floor(Math.random() * 1000 + 1)}f`; + const storagePoolName = `${poolPrefix}${Math.floor(Math.random() * 1000 + 1)}5f`; before(async () => { - projectId = await disksClient.getProjectId(); + // Cleanup resources + const disks = await getStaleDisks(diskPrefix); + await Promise.all(disks.map(disk => deleteDisk(disk.zone, disk.diskName))); + const storagePools = await getStaleStoragePools(poolPrefix); + await Promise.all( + storagePools.map(pool => deleteStoragePool(pool.zone, pool.diskName)) + ); }); after(async () => { - await cleanupResources(projectId, zone, diskName, storagePoolName); + // Cleanup resources + const disks = await getStaleDisks(diskPrefix); + await Promise.all(disks.map(disk => deleteDisk(disk.zone, disk.diskName))); + const storagePools = await getStaleStoragePools(poolPrefix); + await Promise.all( + storagePools.map(pool => + deleteStoragePool(pool.zone, pool.storagePoolName) + ) + ); }); it('should create a new storage pool', () => { diff --git a/compute/test/reservations.test.js b/compute/test/reservations.test.js index bb6c84ebf9..760fadc117 100644 --- a/compute/test/reservations.test.js +++ b/compute/test/reservations.test.js @@ -33,7 +33,7 @@ describe('Compute reservation', async () => { before(async () => { projectId = await reservationsClient.getProjectId(); - // Clean up + // Cleanup resorces const reservations = await getStaleReservations('reservation'); await Promise.all( reservations.map(reservation => diff --git a/compute/test/util.js b/compute/test/util.js index ffdb87332f..d7bf2fe632 100644 --- a/compute/test/util.js +++ b/compute/test/util.js @@ -97,7 +97,6 @@ async function getStaleReservations(prefix) { const aggListRequest = reservationsClient.aggregatedListAsync({ project: projectId, }); - console.log(aggListRequest); for await (const [zone, reservationsObject] of aggListRequest) { const reservations = reservationsObject.reservations; @@ -144,10 +143,134 @@ async function deleteReservation(zone, reservationName) { } } +const storagePoolsClient = new compute.StoragePoolsClient(); + +/** + * Get storage pools created more than one hour ago. + */ +async function getStaleStoragePools(prefix) { + const projectId = await storagePoolsClient.getProjectId(); + const result = []; + const currentDate = new Date(); + currentDate.setHours(currentDate.getHours() - 1); + + const aggListRequest = storagePoolsClient.aggregatedListAsync({ + project: projectId, + }); + console.log(JSON.stringify(aggListRequest)); + for await (const [zone, storagePoolsObject] of aggListRequest) { + const storagePools = storagePoolsObject.storagePools; + result.push( + ...storagePools + .filter( + storagePool => + new Date(storagePool.creationTimestamp) < currentDate && + storagePool.name.startsWith(prefix) + ) + .map(storagePool => { + return { + zone: zone.split('zones/')[1], + storagePoolName: storagePool.name, + timestamp: storagePool.creationTimestamp, + }; + }) + ); + } + + return result; +} + +async function deleteStoragePool(zone, storagePoolName) { + const projectId = await storagePoolsClient.getProjectId(); + + const [response] = await storagePoolsClient.delete({ + project: projectId, + storagePool: storagePoolName, + zone, + }); + let operation = response.latestResponse; + const operationsClient = new compute.ZoneOperationsClient(); + + console.log(`Deleting ${storagePoolName}`); + + // Wait for the delete operation to complete. + while (operation.status !== 'DONE') { + [operation] = await operationsClient.wait({ + operation: operation.name, + project: projectId, + zone, + }); + } +} + +const disksClient = new compute.DisksClient(); + +/** + * Get storage pools created more than one hour ago. + */ +async function getStaleDisks(prefix) { + const projectId = await disksClient.getProjectId(); + const result = []; + const currentDate = new Date(); + currentDate.setHours(currentDate.getHours() - 1); + + const aggListRequest = disksClient.aggregatedListAsync({ + project: projectId, + }); + console.log(JSON.stringify(aggListRequest)); + for await (const [zone, disksObject] of aggListRequest) { + const disks = disksObject.disks; + result.push( + ...disks + .filter( + disk => + new Date(disk.creationTimestamp) < currentDate && + disk.name.startsWith(prefix) + ) + .map(disk => { + return { + zone: zone.split('zones/')[1], + diskName: disk.name, + timestamp: disk.creationTimestamp, + }; + }) + ); + } + + return result; +} + +async function deleteDisk(zone, diskName) { + const projectId = await disksClient.getProjectId(); + + const [response] = await disksClient.delete({ + project: projectId, + disk: diskName, + zone, + }); + let operation = response.latestResponse; + const operationsClient = new compute.ZoneOperationsClient(); + + console.log(`Deleting ${diskName}`); + + // Wait for the delete operation to complete. + while (operation.status !== 'DONE') { + [operation] = await operationsClient.wait({ + operation: operation.name, + project: projectId, + zone, + }); + } +} + module.exports = { generateTestId, getStaleVMInstances, deleteInstance, getStaleReservations, deleteReservation, + getStaleStoragePools, + deleteStoragePool, + getStaleDisks, + deleteDisk, }; From b1b07121147d55cf73f344b395d1b6fe25a40825 Mon Sep 17 00:00:00 2001 From: Joanna Grycz Date: Tue, 8 Oct 2024 12:39:06 +0200 Subject: [PATCH 4/4] Pass zone as parameter to prevent inconsictencies between resources --- compute/disks/createComputeHyperdisk.js | 7 +++-- .../disks/createComputeHyperdiskFromPool.js | 8 ++++-- compute/test/consumeReservations.test.js | 15 ++++++----- compute/test/createComputeHyperdisk.test.js | 4 +-- .../createComputeHyperdiskFromPool.test.js | 24 +++++++---------- compute/test/createReservationFromVM.test.js | 26 ++++++++++++++++--- ...eReservationGlobalInstanceTemplate.test.js | 11 +++++++- ...eservationRegionalInstanceTemplate.test.js | 16 ++++++++++-- compute/test/reservations.test.js | 6 +++-- compute/test/util.js | 9 +++---- 10 files changed, 86 insertions(+), 40 deletions(-) diff --git a/compute/disks/createComputeHyperdisk.js b/compute/disks/createComputeHyperdisk.js index e46c04c030..9be6d4feb3 100644 --- a/compute/disks/createComputeHyperdisk.js +++ b/compute/disks/createComputeHyperdisk.js @@ -16,7 +16,7 @@ 'use strict'; -async function main(diskName) { +async function main(diskName, zone) { // [START compute_hyperdisk_create] // Import the Compute library const computeLib = require('@google-cloud/compute'); @@ -32,10 +32,13 @@ async function main(diskName) { */ // Project ID or project number of the Google Cloud project you want to use. const projectId = await disksClient.getProjectId(); + // The zone where your VM and new disk are located. - const zone = 'europe-central2-b'; + // zone = 'europe-central2-b'; + // The name of the new disk // diskName = 'disk-name'; + // The type of disk. This value uses the following format: // "zones/{zone}/diskTypes/(hyperdisk-balanced|hyperdisk-extreme|hyperdisk-ml|hyperdisk-throughput)". // For example: "zones/us-west3-b/diskTypes/hyperdisk-balanced" diff --git a/compute/disks/createComputeHyperdiskFromPool.js b/compute/disks/createComputeHyperdiskFromPool.js index 01b8aa87aa..065b885fe9 100644 --- a/compute/disks/createComputeHyperdiskFromPool.js +++ b/compute/disks/createComputeHyperdiskFromPool.js @@ -16,7 +16,7 @@ 'use strict'; -async function main(diskName, storagePoolName) { +async function main(diskName, storagePoolName, zone) { // [START compute_hyperdisk_create_from_pool] // Import the Compute library const computeLib = require('@google-cloud/compute'); @@ -32,12 +32,16 @@ async function main(diskName, storagePoolName) { */ // Project ID or project number of the Google Cloud project you want to use. const projectId = await disksClient.getProjectId(); + // The zone where your VM and new disk are located. - const zone = 'us-central1-a'; + // zone = 'us-central1-a'; + // The name of the new disk // diskName = 'disk-from-pool-name'; + // The name of the storage pool // storagePoolName = 'storage-pool-name'; + // Link to the storagePool you want to use. Use format: // https://www.googleapis.com/compute/v1/projects/{projectId}/zones/{zone}/storagePools/{storagePoolName} const storagePool = `https://www.googleapis.com/compute/v1/projects/${projectId}/zones/${zone}/storagePools/${storagePoolName}`; diff --git a/compute/test/consumeReservations.test.js b/compute/test/consumeReservations.test.js index 8ca419fcc4..1eab8b202e 100644 --- a/compute/test/consumeReservations.test.js +++ b/compute/test/consumeReservations.test.js @@ -21,7 +21,6 @@ const assert = require('node:assert/strict'); const {before, describe, it} = require('mocha'); const cp = require('child_process'); const {ReservationsClient} = require('@google-cloud/compute').v1; - const { getStaleReservations, deleteReservation, @@ -34,19 +33,21 @@ const cwd = path.join(__dirname, '..'); describe('Consume reservations', async () => { const zone = 'us-central1-a'; + const instancePrefix = 'instance-458a'; + const reservationPrefix = 'reservation-'; const reservationsClient = new ReservationsClient(); let projectId; before(async () => { projectId = await reservationsClient.getProjectId(); // Cleanup resources - const instances = await getStaleVMInstances('instance-458a88aab'); + const instances = await getStaleVMInstances(instancePrefix); await Promise.all( instances.map(instance => deleteInstance(instance.zone, instance.instanceName) ) ); - const reservations = await getStaleReservations('reservation'); + const reservations = await getStaleReservations(reservationPrefix); await Promise.all( reservations.map(reservation => deleteReservation(reservation.zone, reservation.reservationName) @@ -55,8 +56,8 @@ describe('Consume reservations', async () => { }); it('should create instance that consumes any matching reservation', () => { - const reservationName = `reservation-${Math.floor(Math.random() * 1000 + 1)}f8a31896`; - const instanceName = `instance-458a88aab${Math.floor(Math.random() * 1000 + 1)}f`; + const reservationName = `${reservationPrefix}${Math.floor(Math.random() * 1000 + 1)}f8a31896`; + const instanceName = `${instancePrefix}88aab${Math.floor(Math.random() * 1000 + 1)}f`; // Create reservation execSync( @@ -85,8 +86,8 @@ describe('Consume reservations', async () => { }); it('should create instance that consumes specific single project reservation', () => { - const reservationName = `reservation-22ab${Math.floor(Math.random() * 1000 + 1)}`; - const instanceName = `instance-458a${Math.floor(Math.random() * 1000 + 1)}`; + const reservationName = `${reservationPrefix}22ab${Math.floor(Math.random() * 1000 + 1)}`; + const instanceName = `${instancePrefix}${Math.floor(Math.random() * 1000 + 1)}`; // Create reservation execSync( diff --git a/compute/test/createComputeHyperdisk.test.js b/compute/test/createComputeHyperdisk.test.js index 97dabe02c5..0930175249 100644 --- a/compute/test/createComputeHyperdisk.test.js +++ b/compute/test/createComputeHyperdisk.test.js @@ -20,8 +20,8 @@ const path = require('path'); const assert = require('node:assert/strict'); const {before, after, describe, it} = require('mocha'); const cp = require('child_process'); -const {getStaleDisks, deleteDisk} = require('./util'); const {DisksClient} = require('@google-cloud/compute').v1; +const {getStaleDisks, deleteDisk} = require('./util'); const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'}); const cwd = path.join(__dirname, '..'); @@ -50,7 +50,7 @@ describe('Create compute hyperdisk', async () => { it('should create a new hyperdisk', () => { const response = execSync( - `node ./disks/createComputeHyperdisk.js ${diskName}`, + `node ./disks/createComputeHyperdisk.js ${diskName} ${zone}`, { cwd, } diff --git a/compute/test/createComputeHyperdiskFromPool.test.js b/compute/test/createComputeHyperdiskFromPool.test.js index 4f450cb651..3c04f27ec5 100644 --- a/compute/test/createComputeHyperdiskFromPool.test.js +++ b/compute/test/createComputeHyperdiskFromPool.test.js @@ -20,7 +20,6 @@ const path = require('path'); const assert = require('node:assert/strict'); const {after, before, describe, it} = require('mocha'); const cp = require('child_process'); - const { getStaleDisks, deleteDisk, @@ -36,6 +35,7 @@ describe('Create compute hyperdisk from pool', async () => { const poolPrefix = 'storage-pool-name-745d9'; const diskName = `${diskPrefix}${Math.floor(Math.random() * 1000 + 1)}f`; const storagePoolName = `${poolPrefix}${Math.floor(Math.random() * 1000 + 1)}5f`; + const zone = 'us-central1-a'; before(async () => { // Cleanup resources @@ -43,25 +43,21 @@ describe('Create compute hyperdisk from pool', async () => { await Promise.all(disks.map(disk => deleteDisk(disk.zone, disk.diskName))); const storagePools = await getStaleStoragePools(poolPrefix); await Promise.all( - storagePools.map(pool => deleteStoragePool(pool.zone, pool.diskName)) + storagePools.map(pool => + deleteStoragePool(pool.zone, pool.storagePoolName) + ) ); }); after(async () => { // Cleanup resources - const disks = await getStaleDisks(diskPrefix); - await Promise.all(disks.map(disk => deleteDisk(disk.zone, disk.diskName))); - const storagePools = await getStaleStoragePools(poolPrefix); - await Promise.all( - storagePools.map(pool => - deleteStoragePool(pool.zone, pool.storagePoolName) - ) - ); + await deleteDisk(zone, diskName); + await deleteStoragePool(zone, storagePoolName); }); - it('should create a new storage pool', () => { + it('should create a new storage pool', async () => { const response = execSync( - `node ./disks/createComputeHyperdiskPool.js ${storagePoolName}`, + `node ./disks/createComputeHyperdiskPool.js ${storagePoolName} ${zone}`, { cwd, } @@ -70,9 +66,9 @@ describe('Create compute hyperdisk from pool', async () => { assert(response.includes(`Storage pool: ${storagePoolName} created.`)); }); - it('should create a new hyperdisk from pool', () => { + it('should create a new hyperdisk from pool', async () => { const response = execSync( - `node ./disks/createComputeHyperdiskFromPool.js ${diskName} ${storagePoolName}`, + `node ./disks/createComputeHyperdiskFromPool.js ${diskName} ${storagePoolName} ${zone}`, { cwd, } diff --git a/compute/test/createReservationFromVM.test.js b/compute/test/createReservationFromVM.test.js index 7a4bc91c04..e16aef8c50 100644 --- a/compute/test/createReservationFromVM.test.js +++ b/compute/test/createReservationFromVM.test.js @@ -21,13 +21,21 @@ const assert = require('node:assert/strict'); const {before, after, describe, it} = require('mocha'); const cp = require('child_process'); const {ReservationsClient} = require('@google-cloud/compute').v1; +const { + getStaleReservations, + deleteReservation, + getStaleVMInstances, + deleteInstance, +} = require('./util'); const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'}); const cwd = path.join(__dirname, '..'); describe('Compute reservation from VM', async () => { - const reservationName = `reservation-1a0bb${Math.floor(Math.random() * 1000 + 1)}`; - const vmName = `vm-1a0bb${Math.floor(Math.random() * 1000 + 1)}`; + const instancePrefix = 'vm-1a0bb'; + const reservationPrefix = 'reservation-'; + const reservationName = `${reservationPrefix}1a0bb${Math.floor(Math.random() * 1000 + 1)}`; + const vmName = `${instancePrefix}${Math.floor(Math.random() * 1000 + 1)}`; const zone = 'us-central1-a'; const machineType = 'e2-small'; const reservationsClient = new ReservationsClient(); @@ -35,7 +43,19 @@ describe('Compute reservation from VM', async () => { before(async () => { projectId = await reservationsClient.getProjectId(); - + // Cleanup resources + const instances = await getStaleVMInstances(instancePrefix); + await Promise.all( + instances.map(instance => + deleteInstance(instance.zone, instance.instanceName) + ) + ); + const reservations = await getStaleReservations(reservationPrefix); + await Promise.all( + reservations.map(reservation => + deleteReservation(reservation.zone, reservation.reservationName) + ) + ); // Create VM execSync( `node ./createInstance.js ${projectId} ${zone} ${vmName} ${machineType}`, diff --git a/compute/test/createReservationGlobalInstanceTemplate.test.js b/compute/test/createReservationGlobalInstanceTemplate.test.js index aef50166c5..153830d162 100644 --- a/compute/test/createReservationGlobalInstanceTemplate.test.js +++ b/compute/test/createReservationGlobalInstanceTemplate.test.js @@ -21,12 +21,14 @@ const assert = require('node:assert/strict'); const {after, before, describe, it} = require('mocha'); const cp = require('child_process'); const {ReservationsClient} = require('@google-cloud/compute').v1; +const {getStaleReservations, deleteReservation} = require('./util'); const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'}); const cwd = path.join(__dirname, '..'); describe('Create compute reservation using global instance template', async () => { - const reservationName = `global-reservation-68ef06a${Math.floor(Math.random() * 1000 + 1)}`; + const reservationPrefix = 'global-reservation'; + const reservationName = `${reservationPrefix}-68ef06a${Math.floor(Math.random() * 1000 + 1)}`; const instanceTemplateName = `pernament-global-template-68ef06a${Math.floor(Math.random() * 1000 + 1)}`; const location = 'global'; const reservationsClient = new ReservationsClient(); @@ -34,6 +36,13 @@ describe('Create compute reservation using global instance template', async () = before(async () => { projectId = await reservationsClient.getProjectId(); + // Cleanup resources + const reservations = await getStaleReservations(reservationPrefix); + await Promise.all( + reservations.map(reservation => + deleteReservation(reservation.zone, reservation.reservationName) + ) + ); // Create template execSync( `node ./create-instance-templates/createTemplate.js ${projectId} ${instanceTemplateName}`, diff --git a/compute/test/createReservationRegionalInstanceTemplate.test.js b/compute/test/createReservationRegionalInstanceTemplate.test.js index 5eccdb4dfb..79c58c329e 100644 --- a/compute/test/createReservationRegionalInstanceTemplate.test.js +++ b/compute/test/createReservationRegionalInstanceTemplate.test.js @@ -18,17 +18,29 @@ const path = require('path'); const assert = require('node:assert/strict'); -const {after, describe, it} = require('mocha'); +const {after, before, describe, it} = require('mocha'); const cp = require('child_process'); +const {getStaleReservations, deleteReservation} = require('./util'); const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'}); const cwd = path.join(__dirname, '..'); describe('Create compute reservation using regional instance template', async () => { - const reservationName = `regional-reservation-04bf4ed${Math.floor(Math.random() * 1000 + 1)}`; + const reservationPrefix = 'regional-reservation'; + const reservationName = `${reservationPrefix}-04bf4ed${Math.floor(Math.random() * 1000 + 1)}`; const instanceTemplateName = 'pernament-region-template-name'; const location = 'regions/us-central1'; + before(async () => { + // Cleanup resources + const reservations = await getStaleReservations(reservationPrefix); + await Promise.all( + reservations.map(reservation => + deleteReservation(reservation.zone, reservation.reservationName) + ) + ); + }); + after(() => { // Delete reservation execSync(`node ./reservations/deleteReservation.js ${reservationName}`, { diff --git a/compute/test/reservations.test.js b/compute/test/reservations.test.js index 760fadc117..a81d8084e0 100644 --- a/compute/test/reservations.test.js +++ b/compute/test/reservations.test.js @@ -22,11 +22,13 @@ const {before, describe, it} = require('mocha'); const cp = require('child_process'); const {ReservationsClient} = require('@google-cloud/compute').v1; const {getStaleReservations, deleteReservation} = require('./util'); + const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'}); const cwd = path.join(__dirname, '..'); describe('Compute reservation', async () => { - const reservationName = `reservation-1a0bb${Math.floor(Math.random() * 1000 + 1)}`; + const reservationPrefix = 'reservation'; + const reservationName = `${reservationPrefix}-1a0bb${Math.floor(Math.random() * 1000 + 1)}`; const zone = 'us-central1-a'; const reservationsClient = new ReservationsClient(); let projectId; @@ -34,7 +36,7 @@ describe('Compute reservation', async () => { before(async () => { projectId = await reservationsClient.getProjectId(); // Cleanup resorces - const reservations = await getStaleReservations('reservation'); + const reservations = await getStaleReservations(reservationPrefix); await Promise.all( reservations.map(reservation => deleteReservation(reservation.zone, reservation.reservationName) diff --git a/compute/test/util.js b/compute/test/util.js index d7bf2fe632..8bc1571bda 100644 --- a/compute/test/util.js +++ b/compute/test/util.js @@ -32,7 +32,7 @@ async function getStaleVMInstances(prefix = PREFIX) { const projectId = await instancesClient.getProjectId(); const result = []; const currentDate = new Date(); - currentDate.setHours(currentDate.getHours() - 3); + currentDate.setHours(currentDate.getHours() - 1); const aggListRequest = instancesClient.aggregatedListAsync({ project: projectId, @@ -92,7 +92,7 @@ async function getStaleReservations(prefix) { const projectId = await reservationsClient.getProjectId(); const result = []; const currentDate = new Date(); - currentDate.setHours(currentDate.getHours() - 3); + currentDate.setHours(currentDate.getHours() - 1); const aggListRequest = reservationsClient.aggregatedListAsync({ project: projectId, @@ -157,7 +157,7 @@ async function getStaleStoragePools(prefix) { const aggListRequest = storagePoolsClient.aggregatedListAsync({ project: projectId, }); - console.log(JSON.stringify(aggListRequest)); + for await (const [zone, storagePoolsObject] of aggListRequest) { const storagePools = storagePoolsObject.storagePools; result.push( @@ -176,7 +176,6 @@ async function getStaleStoragePools(prefix) { }) ); } - return result; } @@ -217,7 +216,7 @@ async function getStaleDisks(prefix) { const aggListRequest = disksClient.aggregatedListAsync({ project: projectId, }); - console.log(JSON.stringify(aggListRequest)); + for await (const [zone, disksObject] of aggListRequest) { const disks = disksObject.disks; result.push(