Skip to content

Commit

Permalink
feat: compute_reservation_create_shared, compute_reservation_create_f…
Browse files Browse the repository at this point in the history
…rom_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
  • Loading branch information
gryczj authored Oct 9, 2024
1 parent 53350c0 commit 9383872
Show file tree
Hide file tree
Showing 14 changed files with 577 additions and 75 deletions.
7 changes: 5 additions & 2 deletions compute/disks/createComputeHyperdisk.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand All @@ -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"
Expand Down
8 changes: 6 additions & 2 deletions compute/disks/createComputeHyperdiskFromPool.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand All @@ -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}`;
Expand Down
3 changes: 2 additions & 1 deletion compute/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
102 changes: 102 additions & 0 deletions compute/reservations/createReservationFromVM.js
Original file line number Diff line number Diff line change
@@ -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;
});
108 changes: 108 additions & 0 deletions compute/reservations/createSharedReservation.js
Original file line number Diff line number Diff line change
@@ -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;
// });
17 changes: 9 additions & 8 deletions compute/test/consumeReservations.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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();
// Clean up
const instances = await getStaleVMInstances('instance-458a88aab');
// Cleanup resources
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)
Expand All @@ -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(
Expand Down Expand Up @@ -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(
Expand Down
9 changes: 7 additions & 2 deletions compute/test/createComputeHyperdisk.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,23 @@ const assert = require('node:assert/strict');
const {before, after, describe, it} = require('mocha');
const cp = require('child_process');
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, '..');

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 () => {
Expand All @@ -45,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,
}
Expand Down
Loading

0 comments on commit 9383872

Please sign in to comment.