diff --git a/README.md b/README.md index 1585ed67..38afb948 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,7 @@ Samples are in the [`samples/`](https://github.com/googleapis/nodejs-compute/tre | Create Instance From Template With Overrides | [source code](https://github.com/googleapis/nodejs-compute/blob/main/samples/createInstanceFromTemplateWithOverrides.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-compute&page=editor&open_in_editor=samples/createInstanceFromTemplateWithOverrides.js,samples/README.md) | | Delete Instance | [source code](https://github.com/googleapis/nodejs-compute/blob/main/samples/deleteInstance.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-compute&page=editor&open_in_editor=samples/deleteInstance.js,samples/README.md) | | Disable Usage Export | [source code](https://github.com/googleapis/nodejs-compute/blob/main/samples/disableUsageExport.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-compute&page=editor&open_in_editor=samples/disableUsageExport.js,samples/README.md) | +| Get Instance | [source code](https://github.com/googleapis/nodejs-compute/blob/main/samples/getInstance.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-compute&page=editor&open_in_editor=samples/getInstance.js,samples/README.md) | | Get Usage Export Bucket | [source code](https://github.com/googleapis/nodejs-compute/blob/main/samples/getUsageExportBucket.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-compute&page=editor&open_in_editor=samples/getUsageExportBucket.js,samples/README.md) | | List All Instances | [source code](https://github.com/googleapis/nodejs-compute/blob/main/samples/listAllInstances.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-compute&page=editor&open_in_editor=samples/listAllInstances.js,samples/README.md) | | List Images | [source code](https://github.com/googleapis/nodejs-compute/blob/main/samples/listImages.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-compute&page=editor&open_in_editor=samples/listImages.js,samples/README.md) | diff --git a/samples/README.md b/samples/README.md index dce687d9..e2322a52 100644 --- a/samples/README.md +++ b/samples/README.md @@ -28,6 +28,7 @@ and 3.0.y. * [Create Instance From Template With Overrides](#create-instance-from-template-with-overrides) * [Delete Instance](#delete-instance) * [Disable Usage Export](#disable-usage-export) + * [Get Instance](#get-instance) * [Get Usage Export Bucket](#get-usage-export-bucket) * [List All Instances](#list-all-instances) * [List Images](#list-images) @@ -142,6 +143,23 @@ __Usage:__ +### Get Instance + +View the [source code](https://github.com/googleapis/nodejs-compute/blob/main/samples/getInstance.js). + +[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-compute&page=editor&open_in_editor=samples/getInstance.js,samples/README.md) + +__Usage:__ + + +`node samples/getInstance.js` + + +----- + + + + ### Get Usage Export Bucket View the [source code](https://github.com/googleapis/nodejs-compute/blob/main/samples/getUsageExportBucket.js). diff --git a/samples/disks/createDiskFromSnapshot.js b/samples/disks/createDiskFromSnapshot.js new file mode 100644 index 00000000..7ebd365b --- /dev/null +++ b/samples/disks/createDiskFromSnapshot.js @@ -0,0 +1,83 @@ +// Copyright 2022 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 +// +// http://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. + +/** + * Creates a new disk in a project in given zone. + * + * @param {string} projectId - Project ID or project number of the Cloud project you want to use. + * @param {string} zone - Name of the zone to create the instance in. For example: "us-west3-b". + * @param {string} diskName - Name of the disk you want to create. + * @param {string} diskType - The type of disk you want to create. This value uses the following format: + * "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)". + * For example: "zones/us-west3-b/diskTypes/pd-ssd". + * @param {int} diskSizeGb - Size of the new disk in gigabytes. + * @param {string} snapshotLink - A link to the snapshot you want to use as a source for the new disk. + * This value uses the following format: "projects/{project_name}/global/snapshots/{snapshot_name}" + */ + +function main(projectId, zone, diskName, diskType, diskSizeGb, snapshotLink) { + // [START compute_disk_create_from_snapshot] + /** + * TODO(developer): Uncomment and replace these variables before running the sample. + */ + // const projectId = 'YOUR_PROJECT_ID'; + // const zone = 'europe-central2-b'; + // const diskName = 'YOUR_DISK_NAME'; + // const diskType = 'zones/us-west3-b/diskTypes/pd-ssd'; + // const diskSizeGb = 10; + // const snapshotLink = 'projects/project_name/global/snapshots/snapshot_name'; + + const compute = require('@google-cloud/compute'); + + async function createDiskFromSnapshot() { + const disksClient = new compute.DisksClient(); + + const [response] = await disksClient.insert({ + project: projectId, + zone, + diskResource: { + sizeGb: diskSizeGb, + name: diskName, + zone, + type: diskType, + sourceSnapshot: snapshotLink, + }, + }); + let operation = response.latestResponse; + const operationsClient = new compute.ZoneOperationsClient(); + + // Wait for the create disk operation to complete. + while (operation.status !== 'DONE') { + [operation] = await operationsClient.wait({ + operation: operation.name, + project: projectId, + zone: operation.zone.split('/').pop(), + }); + } + + console.log('Disk created.'); + } + + createDiskFromSnapshot(); + // [END compute_disk_create_from_snapshot] +} + +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); + +const args = process.argv.slice(2); +args[4] = parseInt(args[4]); +main(...args); diff --git a/samples/disks/createEmptyDisk.js b/samples/disks/createEmptyDisk.js new file mode 100644 index 00000000..cff1923e --- /dev/null +++ b/samples/disks/createEmptyDisk.js @@ -0,0 +1,78 @@ +// Copyright 2022 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 +// +// http://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. + +/** + * Creates a new empty disk in a project in given zone. + * + * @param {string} projectId - Project ID or project number of the Cloud project you want to use. + * @param {string} zone - Name of the zone to create the instance in. For example: "us-west3-b". + * @param {string} diskName - Name of the disk you want to create. + * @param {string} diskType - The type of disk you want to create. This value uses the following format: + * "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)". + * For example: "zones/us-west3-b/diskTypes/pd-ssd". + * @param {int} diskSizeGb - Size of the new disk in gigabytes. + */ +function main(projectId, zone, diskName, diskType, diskSizeGb) { + // [START compute_disk_create_empty_disk] + /** + * TODO(developer): Uncomment and replace these variables before running the sample. + */ + // const projectId = 'YOUR_PROJECT_ID'; + // const zone = 'europe-central2-b'; + // const diskName = 'YOUR_DISK_NAME'; + // const diskType = 'zones/us-west3-b/diskTypes/pd-ssd'; + // const diskSizeGb = 10; + + const compute = require('@google-cloud/compute'); + + async function createEmptyDisk() { + const disksClient = new compute.DisksClient(); + + const [response] = await disksClient.insert({ + project: projectId, + zone, + diskResource: { + sizeGb: diskSizeGb, + name: diskName, + zone, + type: diskType, + }, + }); + let operation = response.latestResponse; + const operationsClient = new compute.ZoneOperationsClient(); + + // Wait for the create disk operation to complete. + while (operation.status !== 'DONE') { + [operation] = await operationsClient.wait({ + operation: operation.name, + project: projectId, + zone: operation.zone.split('/').pop(), + }); + } + + console.log('Disk created.'); + } + + createEmptyDisk(); + // [END compute_disk_create_empty_disk] +} + +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); + +const args = process.argv.slice(2); +args[4] = parseInt(args[4]); +main(...args); diff --git a/samples/disks/deleteDisk.js b/samples/disks/deleteDisk.js new file mode 100644 index 00000000..1233f142 --- /dev/null +++ b/samples/disks/deleteDisk.js @@ -0,0 +1,65 @@ +// Copyright 2022 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 +// +// http://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. + +/** + * Deletes a disk from a project. + * + * @param {string} projectId - Project ID or project number of the Cloud project you want to use. + * @param {string} zone - Name of the zone in which is the disk you want to delete. + * @param {string} diskName - Name of the disk you want to delete. + */ +function main(projectId, zone, diskName) { + // [START compute_disk_delete] + /** + * TODO(developer): Uncomment and replace these variables before running the sample. + */ + // const projectId = 'YOUR_PROJECT_ID'; + // const zone = 'europe-central2-b'; + // const diskName = 'YOUR_DISK_NAME'; + + const compute = require('@google-cloud/compute'); + + async function deleteDisk() { + const disksClient = new compute.DisksClient(); + + const [response] = await disksClient.delete({ + project: projectId, + zone, + disk: diskName, + }); + let operation = response.latestResponse; + const operationsClient = new compute.ZoneOperationsClient(); + + // Wait for the create disk operation to complete. + while (operation.status !== 'DONE') { + [operation] = await operationsClient.wait({ + operation: operation.name, + project: projectId, + zone: operation.zone.split('/').pop(), + }); + } + + console.log('Disk deleted.'); + } + + deleteDisk(); + // [END compute_disk_delete] +} + +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); + +main(...process.argv.slice(2)); diff --git a/samples/disks/setDiskAutodelete.js b/samples/disks/setDiskAutodelete.js new file mode 100644 index 00000000..b7b331e0 --- /dev/null +++ b/samples/disks/setDiskAutodelete.js @@ -0,0 +1,85 @@ +// Copyright 2022 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 +// +// http://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. + +/** + * Sets the autodelete flag of a disk to given value. + * + * @param {string} projectId - Project ID or project number of the Cloud project you want to use. + * @param {string} zone - Name of the zone in which is the disk you want to modify. + * @param {string} instanceName - Name of the instance the disk is attached to. + * @param {string} diskName - The name of the disk which flag you want to modify. + * @param {boolean} autoDelete - The new value of the autodelete flag. + */ +function main(projectId, zone, instanceName, diskName, autoDelete) { + // [START compute_disk_autodelete_change] + /** + * TODO(developer): Uncomment and replace these variables before running the sample. + */ + // const projectId = 'YOUR_PROJECT_ID'; + // const zone = 'europe-central2-b'; + // const instanceName = 'YOUR_INSTANCE_NAME'; + // const diskName = 'YOUR_DISK_NAME'; + // const autoDelete = true; + + const compute = require('@google-cloud/compute'); + + async function setDiskAutodelete() { + const instancesClient = new compute.InstancesClient(); + + const [instance] = await instancesClient.get({ + project: projectId, + zone, + instance: instanceName, + }); + + if (!instance.disks.some(disk => disk.deviceName === diskName)) { + throw new Error( + `Instance ${instanceName} doesn't have a disk named ${diskName} attached.` + ); + } + + const [response] = await instancesClient.setDiskAutoDelete({ + project: projectId, + zone, + instance: instanceName, + deviceName: diskName, + autoDelete, + }); + let operation = response.latestResponse; + const operationsClient = new compute.ZoneOperationsClient(); + + // Wait for the update instance operation to complete. + while (operation.status !== 'DONE') { + [operation] = await operationsClient.wait({ + operation: operation.name, + project: projectId, + zone: operation.zone.split('/').pop(), + }); + } + + console.log('Disk autoDelete field updated.'); + } + + setDiskAutodelete(); + // [END compute_disk_autodelete_change] +} + +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); + +const args = process.argv.slice(2); +args[4] = args[4] === 'true'; +main(...args); diff --git a/samples/getInstance.js b/samples/getInstance.js new file mode 100644 index 00000000..5cb86db5 --- /dev/null +++ b/samples/getInstance.js @@ -0,0 +1,55 @@ +// Copyright 2022 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 +// +// http://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. + +/** + * Prints information about a VM instance in the given zone in the specified project. + * + * @param {string} projectId - Project ID or project number of the Cloud project you want to use. + * @param {string} zone - Name of the zone you want to use. For example: 'us-west3-b'. + * @param {string} instanceName - Name of the VM instance you want to query. + */ +function main(projectId, zone, instanceName) { + // [START compute_instances_get] + /** + * TODO(developer): Uncomment and replace these variables before running the sample. + */ + // const projectId = 'YOUR_PROJECT_ID'; + // const zone = 'europe-central2-b' + // const instanceName = 'YOUR_INSTANCE_NAME' + + const compute = require('@google-cloud/compute'); + + async function getInstance() { + const instancesClient = new compute.InstancesClient(); + + const [instance] = await instancesClient.get({ + project: projectId, + zone, + instance: instanceName, + }); + + console.log( + `Instance ${instanceName} data:\n${JSON.stringify(instance, null, 4)}` + ); + } + getInstance(); + // [END compute_instances_get] +} + +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); + +main(...process.argv.slice(2)); diff --git a/samples/instances/create-start-instance/createInstanceWithExistingDisks.js b/samples/instances/create-start-instance/createInstanceWithExistingDisks.js new file mode 100644 index 00000000..e0daeded --- /dev/null +++ b/samples/instances/create-start-instance/createInstanceWithExistingDisks.js @@ -0,0 +1,104 @@ +// Copyright 2022 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 +// +// http://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. + +/** + * Create a new VM instance using selected disks. The first disk in diskNames will be used as boot disk. + * + * @param {string} projectId - Project ID or project number of the Cloud project you want to use. + * @param {string} zone - Name of the zone to create the instance in. For example: "us-west3-b" + * @param {string} instanceName - Name of the new virtual machine (VM) instance. + * @param {Array} diskNames - Array of disk names to be attached to the new virtual machine. + * First disk in this list will be used as the boot device. + */ +function main(projectId, zone, instanceName, diskNames) { + // [START compute_instances_create_with_existing_disks] + /** + * TODO(developer): Uncomment and replace these variables before running the sample. + */ + // const projectId = 'YOUR_PROJECT_ID'; + // const zone = 'europe-central2-b'; + // const instanceName = 'YOUR_INSTANCE_NAME'; + // const diskNames = ['boot_disk', 'disk1', 'disk2']; + + const compute = require('@google-cloud/compute'); + + async function createWithExistingDisks() { + const instancesClient = new compute.InstancesClient(); + const disksClient = new compute.DisksClient(); + + if (diskNames.length < 1) { + throw new Error('At least one disk should be provided'); + } + + const disks = []; + for (const diskName of diskNames) { + const [disk] = await disksClient.get({ + project: projectId, + zone, + disk: diskName, + }); + disks.push(disk); + } + + const attachedDisks = []; + + for (const disk of disks) { + attachedDisks.push({ + source: disk.selfLink, + }); + } + + attachedDisks[0].boot = true; + + const [response] = await instancesClient.insert({ + project: projectId, + zone, + instanceResource: { + name: instanceName, + disks: attachedDisks, + machineType: `zones/${zone}/machineTypes/n1-standard-1`, + networkInterfaces: [ + { + name: 'global/networks/default', + }, + ], + }, + }); + let operation = response.latestResponse; + const operationsClient = new compute.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(), + }); + } + + console.log('Instance created.'); + } + + createWithExistingDisks(); + // [END compute_instances_create_with_existing_disks] +} + +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); + +const args = process.argv.slice(2); +args[3] = args[3].split(','); +main(...args); diff --git a/samples/snapshots/createSnapshot.js b/samples/snapshots/createSnapshot.js new file mode 100644 index 00000000..a3360641 --- /dev/null +++ b/samples/snapshots/createSnapshot.js @@ -0,0 +1,130 @@ +// Copyright 2022 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 +// +// http://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. + +/** + * Creates a snapshot of a disk. + * + * You need to pass `zone` or `region` parameter relevant to the disk you want to + * snapshot, but not both. Pass `zone` parameter for zonal disks and `region` for + * regional disks. + * + * @param {string} projectId - Project ID or project number of the Cloud project you want to use. + * @param {string} diskName - Name of the disk you want to snapshot. + * @param {string} snapshotName - Name of the snapshot to be created. + * @param {string} zone - Name of the zone in which is the disk you want to snapshot (for zonal disks). + * @param {string} region - Name of the region in which is the disk you want to snapshot (for regional disks). + * @param {string} location - The Cloud Storage multi-region or the Cloud Storage region where you + * want to store your snapshot. + * You can specify only one storage location. Available locations: + * https://cloud.google.com/storage/docs/locations#available-locations + * @param {string} diskProjectId - project ID or project number of the Cloud project that + * hosts the disk you want to snapshot. If not provided, will look for + * the disk in the `project_id` project. + */ + +function main( + projectId, + diskName, + snapshotName, + zone, + region, + location, + diskProjectId +) { + // [START compute_snapshot_create] + /** + * TODO(developer): Uncomment and replace these variables before running the sample. + */ + // const projectId = 'YOUR_PROJECT_ID'; + // const diskName = 'YOUR_DISK_NAME'; + // const snapshotName = 'YOUR_SNAPSHOT_NAME'; + // const zone = 'europe-central2-b'; + // const region = ''; + // const location = 'europe-central2'; + // let diskProjectId = 'YOUR_DISK_PROJECT_ID'; + + const compute = require('@google-cloud/compute'); + + async function createSnapshot() { + const snapshotsClient = new compute.SnapshotsClient(); + + let disk; + + if (!zone && !region) { + throw new Error( + 'You need to specify `zone` or `region` for this function to work.' + ); + } + + if (zone && region) { + throw new Error("You can't set both `zone` and `region` parameters"); + } + + if (!diskProjectId) { + diskProjectId = projectId; + } + + if (zone) { + const disksClient = new compute.DisksClient(); + [disk] = await disksClient.get({ + project: diskProjectId, + zone, + disk: diskName, + }); + } else { + const regionDisksClient = new compute.RegionDisksClient(); + [disk] = await regionDisksClient.get({ + project: diskProjectId, + region, + disk: diskName, + }); + } + + const snapshotResource = { + name: snapshotName, + sourceDisk: disk.selfLink, + }; + + if (location) { + snapshotResource.storageLocations = [location]; + } + + const [response] = await snapshotsClient.insert({ + project: projectId, + snapshotResource, + }); + let operation = response.latestResponse; + const operationsClient = new compute.GlobalOperationsClient(); + + // Wait for the create snapshot operation to complete. + while (operation.status !== 'DONE') { + [operation] = await operationsClient.wait({ + operation: operation.name, + project: projectId, + }); + } + + console.log('Snapshot created.'); + } + + createSnapshot(); + // [END compute_snapshot_create] +} + +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); + +main(...process.argv.slice(2)); diff --git a/samples/snapshots/deleteSnapshot.js b/samples/snapshots/deleteSnapshot.js new file mode 100644 index 00000000..8aa9fc1f --- /dev/null +++ b/samples/snapshots/deleteSnapshot.js @@ -0,0 +1,61 @@ +// Copyright 2022 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 +// +// http://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. + +/** + * Delete a snapshot of a disk. + * + * @param {string} projectId - Project ID or project number of the Cloud project you want to use. + * @param {string} snapshotName - Name of the snapshot to delete. + */ +function main(projectId, snapshotName) { + // [START compute_snapshot_delete] + /** + * TODO(developer): Uncomment and replace these variables before running the sample. + */ + // const projectId = 'YOUR_PROJECT_ID'; + // const snapshotName = 'YOUR_SNAPSHOT_NAME'; + + const compute = require('@google-cloud/compute'); + + async function deleteSnapshot() { + const snapshotsClient = new compute.SnapshotsClient(); + + const [response] = await snapshotsClient.delete({ + project: projectId, + snapshot: snapshotName, + }); + let operation = response.latestResponse; + const operationsClient = new compute.GlobalOperationsClient(); + + // Wait for the create disk operation to complete. + while (operation.status !== 'DONE') { + [operation] = await operationsClient.wait({ + operation: operation.name, + project: projectId, + }); + } + + console.log('Snapshot deleted.'); + } + + deleteSnapshot(); + // [END compute_snapshot_delete] +} + +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); + +main(...process.argv.slice(2)); diff --git a/samples/test/createStartInstance.test.js b/samples/test/createStartInstance.test.js index b8f6486f..0e0f2825 100644 --- a/samples/test/createStartInstance.test.js +++ b/samples/test/createStartInstance.test.js @@ -267,4 +267,29 @@ describe('create start instance tests', () => { assert.match(output, /Instance created./); execSync(`node deleteInstance ${projectId} ${zone} ${instanceName}`); }); + + it('should create instance with existing disks', async () => { + const projectId = await instancesClient.getProjectId(); + + const [newestDebian] = await imagesClient.getFromFamily({ + project: 'debian-cloud', + family: 'debian-11', + }); + + const bootDiskName = `gcloud-test-disk-${uuid.v4().split('-')[0]}`; + const diskName2 = `gcloud-test-disk-${uuid.v4().split('-')[0]}`; + + await createDisk(projectId, zone, bootDiskName, newestDebian.selfLink); + await createDisk(projectId, zone, diskName2, newestDebian.selfLink); + + const output = execSync( + `node instances/create-start-instance/createInstanceWithExistingDisks ${projectId} ${zone} ${instanceName} ${bootDiskName},${diskName2}` + ); + assert.match(output, /Instance created./); + + execSync(`node deleteInstance ${projectId} ${zone} ${instanceName}`); + + await deleteDisk(projectId, zone, diskName2); + await deleteDisk(projectId, zone, bootDiskName); + }); }); diff --git a/samples/test/disks.test.js b/samples/test/disks.test.js new file mode 100644 index 00000000..77ccf35b --- /dev/null +++ b/samples/test/disks.test.js @@ -0,0 +1,229 @@ +// Copyright 2022 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 +// +// http://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 compute = require('@google-cloud/compute'); + +const {describe, it} = require('mocha'); +const uuid = require('uuid'); +const cp = require('child_process'); +const {assert} = require('chai'); + +const {generateTestId, getStaleVMInstances, deleteInstance} = require('./util'); + +const instancesClient = new compute.InstancesClient(); +const imagesClient = new compute.ImagesClient(); +const snapshotsClient = new compute.SnapshotsClient(); +const disksClient = new compute.DisksClient(); + +const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'}); + +const createDisk = async (projectId, zone, diskName, sourceImage) => { + const [response] = await disksClient.insert({ + project: projectId, + zone, + diskResource: { + sourceImage, + name: diskName, + }, + }); + let operation = response.latestResponse; + const operationsClient = new compute.ZoneOperationsClient(); + + while (operation.status !== 'DONE') { + [operation] = await operationsClient.wait({ + operation: operation.name, + project: projectId, + zone: operation.zone.split('/').pop(), + }); + } +}; + +const getInstance = async (projectId, zone, instanceName) => { + const [instance] = await instancesClient.get({ + project: projectId, + zone, + instance: instanceName, + }); + + return instance; +}; + +const deleteDisk = async (projectId, zone, diskName) => { + const [response] = await disksClient.delete({ + project: projectId, + zone, + disk: diskName, + }); + let operation = response.latestResponse; + const operationsClient = new compute.ZoneOperationsClient(); + + while (operation.status !== 'DONE') { + [operation] = await operationsClient.wait({ + operation: operation.name, + project: projectId, + zone: operation.zone.split('/').pop(), + }); + } +}; + +const createDiskSnapshot = async (projectId, zone, diskName, snapshotName) => { + const [response] = await disksClient.createSnapshot({ + project: projectId, + zone, + disk: diskName, + snapshotResource: { + name: snapshotName, + }, + }); + let operation = response.latestResponse; + const operationsClient = new compute.ZoneOperationsClient(); + + while (operation.status !== 'DONE') { + [operation] = await operationsClient.wait({ + operation: operation.name, + project: projectId, + zone: operation.zone.split('/').pop(), + }); + } +}; + +const deleteDiskSnapshot = async (projectId, snapshotName) => { + const [response] = await snapshotsClient.delete({ + project: projectId, + snapshot: snapshotName, + }); + let operation = response.latestResponse; + const operationsClient = new compute.GlobalOperationsClient(); + + while (operation.status !== 'DONE') { + [operation] = await operationsClient.wait({ + operation: operation.name, + project: projectId, + }); + } +}; + +describe('disks tests', () => { + const instanceName = generateTestId(); + const diskName = `gcloud-test-disk-${uuid.v4().split('-')[0]}`; + const diskName2 = `gcloud-test-disk-${uuid.v4().split('-')[0]}`; + const snapshotName = `gcloud-test-snapshot-${uuid.v4().split('-')[0]}`; + const zone = 'europe-central2-b'; + const diskType = `zones/${zone}/diskTypes/pd-ssd`; + + after(async () => { + const instances = await getStaleVMInstances(); + await Promise.all( + instances.map(instance => + deleteInstance(instance.zone, instance.instanceName) + ) + ); + }); + + it('should create disk from snapshot and remove', async () => { + const projectId = await instancesClient.getProjectId(); + + const [newestDebian] = await imagesClient.getFromFamily({ + project: 'debian-cloud', + family: 'debian-11', + }); + + await createDisk(projectId, zone, diskName, newestDebian.selfLink); + await createDiskSnapshot(projectId, zone, diskName, snapshotName); + + const diskSnapshotLink = `projects/${projectId}/global/snapshots/${snapshotName}`; + + let output = execSync( + `node disks/createDiskFromSnapshot ${projectId} ${zone} ${diskName2} ${diskType} 10 ${diskSnapshotLink}` + ); + assert.match(output, /Disk created./); + + output = execSync( + `node disks/deleteDisk ${projectId} ${zone} ${diskName2}` + ); + assert.match(output, /Disk deleted./); + + await deleteDiskSnapshot(projectId, snapshotName); + await deleteDisk(projectId, zone, diskName); + }); + + it('should create empty disk', async () => { + const projectId = await instancesClient.getProjectId(); + + const output = execSync( + `node disks/createEmptyDisk ${projectId} ${zone} ${diskName} ${diskType} 10` + ); + assert.match(output, /Disk created./); + + await deleteDisk(projectId, zone, diskName); + }); + + it('should set autodelete field', async () => { + const projectId = await instancesClient.getProjectId(); + + const [newestDebian] = await imagesClient.getFromFamily({ + project: 'debian-cloud', + family: 'debian-11', + }); + + const [response] = await instancesClient.insert({ + instanceResource: { + name: instanceName, + disks: [ + { + initializeParams: { + diskSizeGb: '10', + sourceImage: newestDebian.selfLink, + diskName, + }, + deviceName: diskName, + autoDelete: false, + boot: true, + }, + ], + machineType: `zones/${zone}/machineTypes/n1-standard-1`, + networkInterfaces: [ + { + name: 'global/networks/default', + }, + ], + }, + project: projectId, + zone, + }); + let operation = response.latestResponse; + const operationsClient = new compute.ZoneOperationsClient(); + + while (operation.status !== 'DONE') { + [operation] = await operationsClient.wait({ + operation: operation.name, + project: projectId, + zone: operation.zone.split('/').pop(), + }); + } + + const output = execSync( + `node disks/setDiskAutodelete ${projectId} ${zone} ${instanceName} ${diskName} true` + ); + assert.match(output, /Disk autoDelete field updated./); + + const instance = await getInstance(projectId, zone, instanceName); + + assert.equal(instance.disks[0].autoDelete, true); + + execSync(`node deleteInstance ${projectId} ${zone} ${instanceName}`); + }); +}); diff --git a/samples/test/samples.test.js b/samples/test/samples.test.js index 197c3c6a..e1192d5e 100644 --- a/samples/test/samples.test.js +++ b/samples/test/samples.test.js @@ -79,6 +79,14 @@ describe('samples', () => { assert.match(output, /Instance created./); }); + it('should print instance data', async () => { + const projectId = await instancesClient.getProjectId(); + const output = execSync( + `node getInstance ${projectId} ${zone} ${instanceName}` + ); + assert.include(output, `"name": "${instanceName}"`); + }); + it('should print instances list', async () => { const projectId = await instancesClient.getProjectId(); const output = execSync(`node listInstances ${projectId} ${zone}`); diff --git a/samples/test/snapshots.test.js b/samples/test/snapshots.test.js new file mode 100644 index 00000000..4c2faea2 --- /dev/null +++ b/samples/test/snapshots.test.js @@ -0,0 +1,172 @@ +// Copyright 2022 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 +// +// http://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 compute = require('@google-cloud/compute'); + +const {describe, it} = require('mocha'); +const uuid = require('uuid'); +const cp = require('child_process'); +const {assert} = require('chai'); + +const {getStaleVMInstances, deleteInstance} = require('./util'); + +const instancesClient = new compute.InstancesClient(); +const imagesClient = new compute.ImagesClient(); +const disksClient = new compute.DisksClient(); +const regionDisksClient = new compute.RegionDisksClient(); + +const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'}); + +const createRegionDisk = async (projectId, region, diskName) => { + const [response] = await regionDisksClient.insert({ + project: projectId, + region, + diskResource: { + sizeGb: 200, + name: diskName, + replicaZones: [ + `projects/${projectId}/zones/europe-central2-a`, + `projects/${projectId}/zones/europe-central2-b`, + ], + }, + }); + let operation = response.latestResponse; + const operationsClient = new compute.RegionOperationsClient(); + + while (operation.status !== 'DONE') { + [operation] = await operationsClient.wait({ + operation: operation.name, + project: projectId, + region: operation.region.split('/').pop(), + }); + } +}; + +const createDisk = async (projectId, zone, diskName, sourceImage) => { + const [response] = await disksClient.insert({ + project: projectId, + zone, + diskResource: { + sourceImage, + name: diskName, + }, + }); + let operation = response.latestResponse; + const operationsClient = new compute.ZoneOperationsClient(); + + while (operation.status !== 'DONE') { + [operation] = await operationsClient.wait({ + operation: operation.name, + project: projectId, + zone: operation.zone.split('/').pop(), + }); + } +}; + +const deleteDisk = async (projectId, zone, diskName) => { + const [response] = await disksClient.delete({ + project: projectId, + zone, + disk: diskName, + }); + let operation = response.latestResponse; + const operationsClient = new compute.ZoneOperationsClient(); + + while (operation.status !== 'DONE') { + [operation] = await operationsClient.wait({ + operation: operation.name, + project: projectId, + zone: operation.zone.split('/').pop(), + }); + } +}; + +const deleteRegionDisk = async (projectId, region, diskName) => { + const [response] = await regionDisksClient.delete({ + project: projectId, + region, + disk: diskName, + }); + let operation = response.latestResponse; + const operationsClient = new compute.RegionOperationsClient(); + + while (operation.status !== 'DONE') { + [operation] = await operationsClient.wait({ + operation: operation.name, + project: projectId, + region: operation.region.split('/').pop(), + }); + } +}; + +describe('snapshots tests', () => { + const diskName = `gcloud-test-disk-${uuid.v4().split('-')[0]}`; + const snapshotName = `gcloud-test-snapshot-${uuid.v4().split('-')[0]}`; + const zone = 'europe-central2-b'; + const location = 'europe-central2'; + + after(async () => { + const instances = await getStaleVMInstances(); + await Promise.all( + instances.map(instance => + deleteInstance(instance.zone, instance.instanceName) + ) + ); + }); + + it('should create zonal snapshot and remove', async () => { + const projectId = await instancesClient.getProjectId(); + + const [newestDebian] = await imagesClient.getFromFamily({ + project: 'debian-cloud', + family: 'debian-11', + }); + + await createDisk(projectId, zone, diskName, newestDebian.selfLink); + + let output = execSync( + `node snapshots/createSnapshot ${projectId} ${diskName} ${snapshotName} ${zone} '' ${location} ''` + ); + + assert.match(output, /Snapshot created./); + + output = execSync( + `node snapshots/deleteSnapshot ${projectId} ${snapshotName}` + ); + assert.match(output, /Snapshot deleted./); + + await deleteDisk(projectId, zone, diskName); + }); + + it('should create regional snapshot and remove', async () => { + const projectId = await instancesClient.getProjectId(); + + await createRegionDisk(projectId, location, diskName); + + let output = execSync( + `node snapshots/createSnapshot ${projectId} ${diskName} ${snapshotName} '' ${location} ${location} ''` + ); + + assert.match(output, /Snapshot created./); + + output = execSync( + `node snapshots/deleteSnapshot ${projectId} ${snapshotName}` + ); + assert.match(output, /Snapshot deleted./); + + await deleteRegionDisk(projectId, location, diskName); + }); +});