Skip to content

Commit 9383872

Browse files
authored
feat: compute_reservation_create_shared, compute_reservation_create_from_vm (#3894)
* feat: compute_reservation_create_shared * feat: compute_reservation_create_from_vm * Cleanup resources before tests * Pass zone as parameter to prevent inconsictencies between resources
1 parent 53350c0 commit 9383872

14 files changed

+577
-75
lines changed

compute/disks/createComputeHyperdisk.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
'use strict';
1818

19-
async function main(diskName) {
19+
async function main(diskName, zone) {
2020
// [START compute_hyperdisk_create]
2121
// Import the Compute library
2222
const computeLib = require('@google-cloud/compute');
@@ -32,10 +32,13 @@ async function main(diskName) {
3232
*/
3333
// Project ID or project number of the Google Cloud project you want to use.
3434
const projectId = await disksClient.getProjectId();
35+
3536
// The zone where your VM and new disk are located.
36-
const zone = 'europe-central2-b';
37+
// zone = 'europe-central2-b';
38+
3739
// The name of the new disk
3840
// diskName = 'disk-name';
41+
3942
// The type of disk. This value uses the following format:
4043
// "zones/{zone}/diskTypes/(hyperdisk-balanced|hyperdisk-extreme|hyperdisk-ml|hyperdisk-throughput)".
4144
// For example: "zones/us-west3-b/diskTypes/hyperdisk-balanced"

compute/disks/createComputeHyperdiskFromPool.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
'use strict';
1818

19-
async function main(diskName, storagePoolName) {
19+
async function main(diskName, storagePoolName, zone) {
2020
// [START compute_hyperdisk_create_from_pool]
2121
// Import the Compute library
2222
const computeLib = require('@google-cloud/compute');
@@ -32,12 +32,16 @@ async function main(diskName, storagePoolName) {
3232
*/
3333
// Project ID or project number of the Google Cloud project you want to use.
3434
const projectId = await disksClient.getProjectId();
35+
3536
// The zone where your VM and new disk are located.
36-
const zone = 'us-central1-a';
37+
// zone = 'us-central1-a';
38+
3739
// The name of the new disk
3840
// diskName = 'disk-from-pool-name';
41+
3942
// The name of the storage pool
4043
// storagePoolName = 'storage-pool-name';
44+
4145
// Link to the storagePool you want to use. Use format:
4246
// https://www.googleapis.com/compute/v1/projects/{projectId}/zones/{zone}/storagePools/{storagePoolName}
4347
const storagePool = `https://www.googleapis.com/compute/v1/projects/${projectId}/zones/${zone}/storagePools/${storagePoolName}`;

compute/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
"@google-cloud/compute": "^4.0.0",
1818
"@sendgrid/mail": "^8.0.0",
1919
"nodemailer": "^6.0.0",
20-
"nodemailer-smtp-transport": "^2.7.4"
20+
"nodemailer-smtp-transport": "^2.7.4",
21+
"sinon": "^19.0.2"
2122
},
2223
"devDependencies": {
2324
"@google-cloud/storage": "^7.0.0",
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
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+
* https://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+
'use strict';
18+
19+
async function main(reservationName, vmName, zone) {
20+
// [START compute_reservation_create_from_vm]
21+
// Import the Compute library
22+
const computeLib = require('@google-cloud/compute');
23+
const compute = computeLib.protos.google.cloud.compute.v1;
24+
25+
// Instantiate a reservationsClient
26+
const reservationsClient = new computeLib.ReservationsClient();
27+
// Instantiate a zoneOperationsClient
28+
const zoneOperationsClient = new computeLib.ZoneOperationsClient();
29+
// Instantiate a instancesClient
30+
const instancesClient = new computeLib.InstancesClient();
31+
32+
/**
33+
* TODO(developer): Update/uncomment these variables before running the sample.
34+
*/
35+
// The ID of the project where you want to reserve resources and where the instance template exists.
36+
const projectId = await reservationsClient.getProjectId();
37+
// The zone in which to reserve resources.
38+
zone = 'us-central1-a';
39+
// The name of the reservation to create.
40+
// reservationName = 'reservation-02';
41+
// The name of the VM which properties you want to use to create the reservation.
42+
// vmName = 'vm-01';
43+
// The number of VMs to reserve.
44+
const vmsNumber = 3;
45+
46+
async function callCreateComputeReservationFromVM() {
47+
// Get specified VM
48+
const [vm] = await instancesClient.get({
49+
project: projectId,
50+
zone,
51+
instance: vmName,
52+
});
53+
54+
// Create reservation for 3 VMs in zone us-central1-a by specifying directly the properties from the desired VM
55+
const specificReservation = new compute.AllocationSpecificSKUReservation({
56+
count: vmsNumber,
57+
instanceProperties: {
58+
machineType: vm.machineType.split('/').pop(),
59+
minCpuPlatform: vm.minCpuPlatform,
60+
guestAccelerators: vm.guestAccelerators
61+
? [...vm.guestAccelerators]
62+
: [],
63+
localSsds: vm.localSsds ? [...vm.localSsds] : [],
64+
},
65+
});
66+
67+
// Create a reservation.
68+
const reservation = new compute.Reservation({
69+
name: reservationName,
70+
zone,
71+
specificReservation,
72+
specificReservationRequired: true,
73+
});
74+
75+
const [response] = await reservationsClient.insert({
76+
project: projectId,
77+
reservationResource: reservation,
78+
zone,
79+
});
80+
81+
let operation = response.latestResponse;
82+
83+
// Wait for the create reservation operation to complete.
84+
while (operation.status !== 'DONE') {
85+
[operation] = await zoneOperationsClient.wait({
86+
operation: operation.name,
87+
project: projectId,
88+
zone: operation.zone.split('/').pop(),
89+
});
90+
}
91+
92+
console.log(`Reservation: ${reservationName} created.`);
93+
}
94+
95+
await callCreateComputeReservationFromVM();
96+
// [END compute_reservation_create_from_vm]
97+
}
98+
99+
main(...process.argv.slice(2)).catch(err => {
100+
console.error(err.message);
101+
process.exitCode = 1;
102+
});
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
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+
* https://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+
'use strict';
18+
19+
async function main(reservationsClient, zoneOperationsClient) {
20+
// [START compute_reservation_create_shared]
21+
// Import the Compute library
22+
const computeLib = require('@google-cloud/compute');
23+
const compute = computeLib.protos.google.cloud.compute.v1;
24+
25+
/**
26+
* TODO(developer): Uncomment reservationsClient and zoneOperationsClient before running the sample.
27+
*/
28+
// Instantiate a reservationsClient
29+
// reservationsClient = new computeLib.ReservationsClient();
30+
// Instantiate a zoneOperationsClient
31+
// zoneOperationsClient = new computeLib.ZoneOperationsClient();
32+
33+
/**
34+
* TODO(developer): Update these variables before running the sample.
35+
*/
36+
// The ID of the project where you want to reserve resources and where the instance template exists.
37+
const projectId = await reservationsClient.getProjectId();
38+
// The zone in which to reserve resources.
39+
const zone = 'us-central1-a';
40+
// The name of the reservation to create.
41+
const reservationName = 'reservation-01';
42+
// The number of VMs to reserve.
43+
const vmsNumber = 3;
44+
// The name of an existing instance template.
45+
const instanceTemplateName = 'global-instance-template-name';
46+
// The location of the instance template.
47+
const location = 'global';
48+
49+
async function callCreateComputeSharedReservation() {
50+
// Create reservation for 3 VMs in zone us-central1-a by specifying a instance template.
51+
const specificReservation = new compute.AllocationSpecificSKUReservation({
52+
count: vmsNumber,
53+
sourceInstanceTemplate: `projects/${projectId}/${location}/instanceTemplates/${instanceTemplateName}`,
54+
});
55+
56+
// Create share settings. Share reservation with one customer project.
57+
const shareSettings = new compute.ShareSettings({
58+
shareType: 'SPECIFIC_PROJECTS',
59+
projectMap: {
60+
// The IDs of projects that can consume this reservation. You can include up to 100 consumer projects.
61+
// These projects must be in the same organization as the owner project.
62+
// Don't include the owner project. By default, it is already allowed to consume the reservation.
63+
consumer_project_id: {
64+
projectId: 'consumer_project_id',
65+
},
66+
},
67+
});
68+
69+
// Create a reservation.
70+
const reservation = new compute.Reservation({
71+
name: reservationName,
72+
specificReservation,
73+
specificReservationRequired: true,
74+
shareSettings,
75+
});
76+
77+
const [response] = await reservationsClient.insert({
78+
project: projectId,
79+
reservationResource: reservation,
80+
zone,
81+
});
82+
83+
let operation = response.latestResponse;
84+
85+
// Wait for the create reservation operation to complete.
86+
while (operation.status !== 'DONE') {
87+
[operation] = await zoneOperationsClient.wait({
88+
operation: operation.name,
89+
project: projectId,
90+
zone: operation.zone.split('/').pop(),
91+
});
92+
}
93+
94+
console.log(`Reservation: ${reservationName} created.`);
95+
return response;
96+
}
97+
98+
return await callCreateComputeSharedReservation();
99+
// [END compute_reservation_create_shared]
100+
}
101+
102+
module.exports = main;
103+
104+
// TODO(developer): Uncomment below lines before running the sample.
105+
// main(...process.argv.slice(2)).catch(err => {
106+
// console.error(err);
107+
// process.exitCode = 1;
108+
// });

compute/test/consumeReservations.test.js

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ const assert = require('node:assert/strict');
2121
const {before, describe, it} = require('mocha');
2222
const cp = require('child_process');
2323
const {ReservationsClient} = require('@google-cloud/compute').v1;
24-
2524
const {
2625
getStaleReservations,
2726
deleteReservation,
@@ -34,19 +33,21 @@ const cwd = path.join(__dirname, '..');
3433

3534
describe('Consume reservations', async () => {
3635
const zone = 'us-central1-a';
36+
const instancePrefix = 'instance-458a';
37+
const reservationPrefix = 'reservation-';
3738
const reservationsClient = new ReservationsClient();
3839
let projectId;
3940

4041
before(async () => {
4142
projectId = await reservationsClient.getProjectId();
42-
// Clean up
43-
const instances = await getStaleVMInstances('instance-458a88aab');
43+
// Cleanup resources
44+
const instances = await getStaleVMInstances(instancePrefix);
4445
await Promise.all(
4546
instances.map(instance =>
4647
deleteInstance(instance.zone, instance.instanceName)
4748
)
4849
);
49-
const reservations = await getStaleReservations('reservation');
50+
const reservations = await getStaleReservations(reservationPrefix);
5051
await Promise.all(
5152
reservations.map(reservation =>
5253
deleteReservation(reservation.zone, reservation.reservationName)
@@ -55,8 +56,8 @@ describe('Consume reservations', async () => {
5556
});
5657

5758
it('should create instance that consumes any matching reservation', () => {
58-
const reservationName = `reservation-${Math.floor(Math.random() * 1000 + 1)}f8a31896`;
59-
const instanceName = `instance-458a88aab${Math.floor(Math.random() * 1000 + 1)}f`;
59+
const reservationName = `${reservationPrefix}${Math.floor(Math.random() * 1000 + 1)}f8a31896`;
60+
const instanceName = `${instancePrefix}88aab${Math.floor(Math.random() * 1000 + 1)}f`;
6061

6162
// Create reservation
6263
execSync(
@@ -85,8 +86,8 @@ describe('Consume reservations', async () => {
8586
});
8687

8788
it('should create instance that consumes specific single project reservation', () => {
88-
const reservationName = `reservation-22ab${Math.floor(Math.random() * 1000 + 1)}`;
89-
const instanceName = `instance-458a${Math.floor(Math.random() * 1000 + 1)}`;
89+
const reservationName = `${reservationPrefix}22ab${Math.floor(Math.random() * 1000 + 1)}`;
90+
const instanceName = `${instancePrefix}${Math.floor(Math.random() * 1000 + 1)}`;
9091

9192
// Create reservation
9293
execSync(

compute/test/createComputeHyperdisk.test.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,23 @@ const assert = require('node:assert/strict');
2121
const {before, after, describe, it} = require('mocha');
2222
const cp = require('child_process');
2323
const {DisksClient} = require('@google-cloud/compute').v1;
24+
const {getStaleDisks, deleteDisk} = require('./util');
2425

2526
const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
2627
const cwd = path.join(__dirname, '..');
2728

2829
describe('Create compute hyperdisk', async () => {
29-
const diskName = `hyperdisk-name-941ad2d${Math.floor(Math.random() * 1000 + 1)}`;
30+
const prefix = 'hyperdisk-name-941ad2d';
31+
const diskName = `${prefix}${Math.floor(Math.random() * 1000 + 1)}`;
3032
const zone = 'europe-central2-b';
3133
const disksClient = new DisksClient();
3234
let projectId;
3335

3436
before(async () => {
3537
projectId = await disksClient.getProjectId();
38+
// Cleanup resources
39+
const disks = await getStaleDisks(prefix);
40+
await Promise.all(disks.map(disk => deleteDisk(disk.zone, disk.diskName)));
3641
});
3742

3843
after(async () => {
@@ -45,7 +50,7 @@ describe('Create compute hyperdisk', async () => {
4550

4651
it('should create a new hyperdisk', () => {
4752
const response = execSync(
48-
`node ./disks/createComputeHyperdisk.js ${diskName}`,
53+
`node ./disks/createComputeHyperdisk.js ${diskName} ${zone}`,
4954
{
5055
cwd,
5156
}

0 commit comments

Comments
 (0)