Skip to content

Commit b0f95bc

Browse files
gryczjsubfuzion
andauthored
feat: compute_reservation_create_template (#3811)
* feat: compute_reservation_create_template * Add create region instance template sample * Add compute_reservation_delete sample * Fix tests * Insert region instance template * Remove unneccessary samples * lint --------- Co-authored-by: Tony Pujals <[email protected]>
1 parent 38af8df commit b0f95bc

File tree

4 files changed

+250
-4
lines changed

4 files changed

+250
-4
lines changed
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(location, instanceTemplateName) {
20+
// [START compute_reservation_create_template]
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+
30+
/**
31+
* TODO(developer): Update these variables before running the sample.
32+
*/
33+
// The ID of the project where you want to reserve resources and where the instance template exists.
34+
const projectId = await reservationsClient.getProjectId();
35+
// The zone in which to reserve resources.
36+
const zone = 'us-central1-a';
37+
// The name of the reservation to create.
38+
const reservationName = 'reservation-01';
39+
// The number of VMs to reserve.
40+
const vmsNumber = 3;
41+
42+
/**
43+
* The name of an existing instance template.
44+
* TODO(developer): Uncomment and update instanceTemplateName before running the sample.
45+
*/
46+
// const instanceTemplateName = 'pernament-region-template-name';
47+
48+
/**
49+
* // The location of the instance template.
50+
* TODO(developer): Uncomment the `location` variable depending on which template you want to use.
51+
*/
52+
53+
// The location for a regional instance template: regions/{region}. Replace region with the region where the instance template is located.
54+
// If you specify a regional instance template, then you can only reserve VMs within the same region as the template's region.
55+
// const location = `regions/${zone.slice(0, -2)}`;
56+
57+
// The location for a global instance template.
58+
// const location = 'global';
59+
60+
async function callCreateComputeReservationInstanceTemplate() {
61+
// Create reservation for 3 VMs in zone us-central1-a by specifying a instance template.
62+
const specificReservation = new compute.AllocationSpecificSKUReservation({
63+
count: vmsNumber,
64+
sourceInstanceTemplate: `projects/${projectId}/${location}/instanceTemplates/${instanceTemplateName}`,
65+
});
66+
67+
// Create a reservation.
68+
const reservation = new compute.Reservation({
69+
name: reservationName,
70+
specificReservation,
71+
});
72+
73+
const [response] = await reservationsClient.insert({
74+
project: projectId,
75+
reservationResource: reservation,
76+
zone,
77+
});
78+
79+
let operation = response.latestResponse;
80+
81+
// Wait for the create reservation operation to complete.
82+
while (operation.status !== 'DONE') {
83+
[operation] = await zoneOperationsClient.wait({
84+
operation: operation.name,
85+
project: projectId,
86+
zone: operation.zone.split('/').pop(),
87+
});
88+
}
89+
90+
const createdReservation = (
91+
await reservationsClient.get({
92+
project: projectId,
93+
zone,
94+
reservation: reservationName,
95+
})
96+
)[0];
97+
98+
console.log(JSON.stringify(createdReservation));
99+
}
100+
101+
await callCreateComputeReservationInstanceTemplate();
102+
// [END compute_reservation_create_template]
103+
}
104+
105+
main(...process.argv.slice(2)).catch(err => {
106+
console.error(err.message);
107+
process.exitCode = 1;
108+
});
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
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+
const path = require('path');
20+
const assert = require('node:assert/strict');
21+
const {after, before, describe, it} = require('mocha');
22+
const cp = require('child_process');
23+
const {ReservationsClient} = require('@google-cloud/compute').v1;
24+
25+
const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
26+
const cwd = path.join(__dirname, '..');
27+
28+
describe('Create compute reservation using global instance template', async () => {
29+
const reservationName = 'reservation-01';
30+
const instanceTemplateName = 'pernament-global-template-name';
31+
const location = 'global';
32+
const reservationsClient = new ReservationsClient();
33+
let projectId;
34+
35+
before(async () => {
36+
projectId = await reservationsClient.getProjectId();
37+
// Create template
38+
execSync(
39+
`node ./create-instance-templates/createTemplate.js ${projectId} ${instanceTemplateName}`,
40+
{
41+
cwd,
42+
}
43+
);
44+
});
45+
46+
after(() => {
47+
// Delete reservation
48+
execSync('node ./reservations/deleteReservation.js', {
49+
cwd,
50+
});
51+
// Delete template
52+
execSync(
53+
`node ./create-instance-templates/deleteInstanceTemplate.js ${projectId} ${instanceTemplateName}`,
54+
{
55+
cwd,
56+
}
57+
);
58+
});
59+
60+
it('should create a new reservation', () => {
61+
const response = JSON.parse(
62+
execSync(
63+
`node ./reservations/createReservationInstanceTemplate.js ${location} ${instanceTemplateName}`,
64+
{
65+
cwd,
66+
}
67+
)
68+
);
69+
70+
assert.equal(response.name, reservationName);
71+
assert.equal(response.specificReservation.count, '3');
72+
assert.equal(
73+
response.specificReservation.sourceInstanceTemplate,
74+
`https://www.googleapis.com/compute/v1/projects/${projectId}/${location}/instanceTemplates/${instanceTemplateName}`
75+
);
76+
});
77+
});
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
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+
const path = require('path');
20+
const assert = require('node:assert/strict');
21+
const {after, before, describe, it} = require('mocha');
22+
const cp = require('child_process');
23+
const {ReservationsClient} = require('@google-cloud/compute').v1;
24+
25+
const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
26+
const cwd = path.join(__dirname, '..');
27+
28+
describe('Create compute reservation using regional instance template', async () => {
29+
const reservationName = 'reservation-01';
30+
const instanceTemplateName = 'pernament-region-template-name';
31+
const location = 'regions/us-central1';
32+
const reservationsClient = new ReservationsClient();
33+
let projectId;
34+
35+
before(async () => {
36+
projectId = await reservationsClient.getProjectId();
37+
});
38+
39+
after(() => {
40+
// Delete reservation
41+
execSync('node ./reservations/deleteReservation.js', {
42+
cwd,
43+
});
44+
});
45+
46+
it('should create a new reservation', () => {
47+
const response = JSON.parse(
48+
execSync(
49+
`node ./reservations/createReservationInstanceTemplate.js ${location} ${instanceTemplateName}`,
50+
{
51+
cwd,
52+
}
53+
)
54+
);
55+
56+
assert.equal(response.name, reservationName);
57+
assert.equal(response.specificReservation.count, '3');
58+
assert.equal(
59+
response.specificReservation.sourceInstanceTemplate,
60+
`https://www.googleapis.com/compute/v1/projects/${projectId}/${location}/instanceTemplates/${instanceTemplateName}`
61+
);
62+
});
63+
});

compute/test/reservations.test.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
const path = require('path');
2020
const assert = require('node:assert/strict');
2121
const {describe, it} = require('mocha');
22-
const {expect} = require('chai');
2322
const cp = require('child_process');
2423
const {ReservationsClient} = require('@google-cloud/compute').v1;
2524

@@ -112,9 +111,8 @@ describe('Compute reservation', async () => {
112111
throw new Error('Reservation was not deleted.');
113112
} catch (error) {
114113
// Assert that the error message indicates the reservation wasn't found
115-
expect(error.message).to.include(
116-
`The resource 'projects/${projectId}/zones/${zone}/reservations/${reservationName}' was not found`
117-
);
114+
const expected = `The resource 'projects/${projectId}/zones/${zone}/reservations/${reservationName}' was not found`;
115+
assert(error.message && error.message.includes(expected));
118116
}
119117
});
120118
});

0 commit comments

Comments
 (0)