From c5e7042f065ea1b26f0fec7927c5c31952ca29d4 Mon Sep 17 00:00:00 2001 From: Alexander Fenster Date: Wed, 11 Aug 2021 15:33:50 -0700 Subject: [PATCH] feat!: new generated version of compute API (#537) --- compute/.eslintrc.yml | 4 - compute/createInstance.js | 112 +++++++++++++ compute/createVM.js | 40 ----- compute/deleteInstance.js | 65 ++++++++ compute/deleteVM.js | 40 ----- compute/getUsageExportBucket.js | 61 ++++++++ compute/listAllInstances.js | 60 +++++++ compute/listImages.js | 51 ++++++ compute/listImagesByPage.js | 75 +++++++++ compute/listInstances.js | 51 ++++++ compute/listVMs.js | 35 ----- compute/mailjet.js | 6 +- compute/package.json | 19 ++- compute/quickstart.js | 47 ------ compute/sendgrid.js | 9 +- compute/setUsageExportBucket.js | 58 +++++++ compute/startupScript.js | 102 ------------ compute/test/{.eslintrc.yml => .eslintrc} | 0 compute/test/mailjet.test.js | 2 +- compute/test/samples.test.js | 183 ++++++++++++++++------ compute/test/sendgrid.test.js | 2 +- compute/vms.js | 53 ------- compute/waitForOperation.js | 53 +++++++ 23 files changed, 742 insertions(+), 386 deletions(-) delete mode 100644 compute/.eslintrc.yml create mode 100644 compute/createInstance.js delete mode 100644 compute/createVM.js create mode 100644 compute/deleteInstance.js delete mode 100644 compute/deleteVM.js create mode 100644 compute/getUsageExportBucket.js create mode 100644 compute/listAllInstances.js create mode 100644 compute/listImages.js create mode 100644 compute/listImagesByPage.js create mode 100644 compute/listInstances.js delete mode 100644 compute/listVMs.js delete mode 100644 compute/quickstart.js create mode 100644 compute/setUsageExportBucket.js delete mode 100644 compute/startupScript.js rename compute/test/{.eslintrc.yml => .eslintrc} (100%) delete mode 100644 compute/vms.js create mode 100644 compute/waitForOperation.js diff --git a/compute/.eslintrc.yml b/compute/.eslintrc.yml deleted file mode 100644 index 0aa37ac630..0000000000 --- a/compute/.eslintrc.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -rules: - no-console: off - node/no-missing-require: off diff --git a/compute/createInstance.js b/compute/createInstance.js new file mode 100644 index 0000000000..44caeb7426 --- /dev/null +++ b/compute/createInstance.js @@ -0,0 +1,112 @@ +// Copyright 2021 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. + +/** + * Sends an instance creation request to GCP and waits for it to complete. + * + * @param {string} projectId - ID or number of the project you want to use. + * @param {string} zone - Name of the zone you want to check, for example: us-west3-b + * @param {string} instanceName - Name of the new machine. + * @param {string} machineType - Machine type you want to create in following format: + * "zones/{zone}/machineTypes/{type_name}". For example: + * "zones/europe-west3-c/machineTypes/f1-micro" + * You can find the list of available machine types using: + * https://cloud.google.com/sdk/gcloud/reference/compute/machine-types/list + * @param {string} sourceImage - Path the the disk image you want to use for your boot + * disk. This can be one of the public images + * (e.g. "projects/debian-cloud/global/images/family/debian-10") + * or a private image you have access to. + * You can check the list of available public images using: + * $ gcloud compute images list + * @param {string} networkName - Name of the network you want the new instance to use. + * For example: global/networks/default - if you want to use the default network. + */ +function main( + projectId, + zone, + instanceName, + machineType = 'n1-standard-1', + sourceImage = 'projects/debian-cloud/global/images/family/debian-10', + networkName = 'global/networks/default' +) { + // [START compute_instances_create] + /** + * 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 machineType = 'n1-standard-1'; + // const sourceImage = 'projects/debian-cloud/global/images/family/debian-10'; + // const networkName = 'global/networks/default'; + + const compute = require('@google-cloud/compute'); + const compute_protos = compute.protos.google.cloud.compute.v1; + + // Create a new instance with the values provided above in the specified project and zone. + async function createInstance() { + const instancesClient = new compute.InstancesClient({fallback: 'rest'}); + + // Describe the size and source image of the boot disk to attach to the instance. + const attachedDisk = new compute_protos.AttachedDisk(); + const initializeParams = new compute_protos.AttachedDiskInitializeParams(); + + initializeParams.diskSizeGb = '10'; + initializeParams.sourceImage = sourceImage; + + attachedDisk.initializeParams = initializeParams; + attachedDisk.autoDelete = true; + attachedDisk.boot = true; + attachedDisk.type = compute_protos.AttachedDisk.Type.PERSISTENT; + + // Use the network interface provided in the networkName argument. + const networkInterface = new compute_protos.NetworkInterface(); + networkInterface.name = networkName; + + // Collect information into the Instance object. + const instance = new compute_protos.Instance(); + instance.name = instanceName; + instance.disks = [attachedDisk]; + instance.machineType = `zones/${zone}/machineTypes/${machineType}`; + instance.networkInterfaces = [networkInterface]; + + console.log(`Creating the ${instanceName} instance in ${zone}...`); + + // Wait for the create operation to complete. + const [operation] = await instancesClient.insert({ + instanceResource: instance, + project: projectId, + zone, + }); + + if (operation.status === 'RUNNING') { + const operationsClient = new compute.ZoneOperationsClient({ + fallback: 'rest', + }); + + await operationsClient.wait({ + operation: operation.name, + project: projectId, + zone: operation.zone.split('/').pop(), + }); + } + + console.log('Instance created.'); + } + + createInstance(); + // [END compute_instances_create] +} + +main(...process.argv.slice(2)); diff --git a/compute/createVM.js b/compute/createVM.js deleted file mode 100644 index dd08047e4f..0000000000 --- a/compute/createVM.js +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2017, Google, Inc. -// 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. - -// sample-metadata: -// title: Create VM -// usage: node createVM - -'use strict'; - -async function main( - vmName = 'new_virtual_machine' // VM name of your choice -) { - // [START gce_create_vm] - const Compute = require('@google-cloud/compute'); - const compute = new Compute(); - const zone = compute.zone('us-central1-c'); - - async function createVM() { - // TODO(developer): provide a name for your VM - // const vmName = 'new-virutal-machine'; - const [vm, operation] = await zone.createVM(vmName, {os: 'ubuntu'}); - console.log(vm); - await operation.promise(); - console.log('Virtual machine created!'); - } - createVM(); - // [END gce_create_vm] -} - -main(...process.argv.slice(2)); diff --git a/compute/deleteInstance.js b/compute/deleteInstance.js new file mode 100644 index 0000000000..b309926db2 --- /dev/null +++ b/compute/deleteInstance.js @@ -0,0 +1,65 @@ +// Copyright 2021 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. + +/** + * Sends a delete request to GCP and waits for it to complete. + * + * @param {string} projectId - ID or number of the project you want to use. + * @param {string} zone - Name of the zone you want to check, for example: us-west3-b + * @param {string} instanceName - Name of the instance you want to delete. + */ +function main(projectId, zone, instanceName) { + // [START compute_instances_delete] + /** + * TODO(developer): Uncomment 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'); + + // Delete the instance specified by `instanceName` if it's present in the given project and zone. + async function deleteInstance() { + const instancesClient = new compute.InstancesClient({fallback: 'rest'}); + + console.log(`Deleting ${instanceName} from ${zone}...`); + + // Wait for the delete operation to complete. + const [operation] = await instancesClient.delete({ + project: projectId, + zone, + instance: instanceName, + }); + + if (operation.status === 'RUNNING') { + const operationsClient = new compute.ZoneOperationsClient({ + fallback: 'rest', + }); + + await operationsClient.wait({ + operation: operation.name, + project: projectId, + zone: operation.zone.split('/').pop(), + }); + } + + console.log('Instance deleted.'); + } + + deleteInstance(); + // [END compute_instances_delete] +} + +main(...process.argv.slice(2)); diff --git a/compute/deleteVM.js b/compute/deleteVM.js deleted file mode 100644 index f53b96d060..0000000000 --- a/compute/deleteVM.js +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2020, Google, Inc. -// 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. - -// sample-metadata: -// title: Delete VM -// usage: node deleteVM - -'use strict'; - -async function main( - name = 'virtual_machine_name' // VM name of your choice -) { - // [START gce_delete_vm] - const Compute = require('@google-cloud/compute'); - - async function deleteVM() { - const compute = new Compute(); - const zone = compute.zone('us-central1-c'); - // TODO(developer): choose a name for the VM to delete - // const name = 'vm-name'; - const vm = zone.vm(name); - const [operation] = await vm.delete(); - await operation.promise(); - console.log('VM deleted!'); - } - deleteVM(); - // [END gce_delete_vm] -} - -main(...process.argv.slice(2)); diff --git a/compute/getUsageExportBucket.js b/compute/getUsageExportBucket.js new file mode 100644 index 0000000000..289dcba6e8 --- /dev/null +++ b/compute/getUsageExportBucket.js @@ -0,0 +1,61 @@ +// Copyright 2021 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. + +/** + * Retrieve Compute Engine usage export bucket for the Cloud project. Replaces the empty value returned by the API with the default value used to generate report file names. + * + * @param {string} projectId - ID or number of the project you want to use. + */ +function main(projectId) { + // [START compute_usage_report_get] + /** + * TODO(developer): Uncomment and replace these variables before running the sample. + */ + // const projectId = 'YOUR_PROJECT_ID'; + + const compute = require('@google-cloud/compute'); + + async function getUsageExportBucket() { + // Get the usage export location for the project from the server. + const projectsClient = new compute.ProjectsClient({fallback: 'rest'}); + const [project] = await projectsClient.get({ + project: projectId, + }); + + const usageExportLocation = project.usageExportLocation; + + if (!usageExportLocation || !usageExportLocation.bucketName) { + // The usage reports are disabled. + return; + } + + if (!usageExportLocation.reportNamePrefix) { + // Although the server explicitly sent the empty string value, the next usage report generated with these settings still has the default prefix value `usage_gce`. (see https://cloud.google.com/compute/docs/reference/rest/v1/projects/get) + console.log( + 'Report name prefix not set, replacing with default value of `usage_gce`.' + ); + usageExportLocation.reportNamePrefix = 'usage_gce'; + } + + console.log( + 'Returned reportNamePrefix:', + usageExportLocation.reportNamePrefix + ); + } + + getUsageExportBucket(); + // [END compute_usage_report_get] +} + +main(...process.argv.slice(2)); diff --git a/compute/listAllInstances.js b/compute/listAllInstances.js new file mode 100644 index 0000000000..16057b1c66 --- /dev/null +++ b/compute/listAllInstances.js @@ -0,0 +1,60 @@ +// Copyright 2021 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. + +/** + * Gets all instances present in a project, grouped by their zone. + * + * @param {string} projectId - ID or number of the project you want to use. + */ +function main(projectId) { + // [START compute_instances_list_all] + /** + * TODO(developer): Uncomment and replace these variables before running the sample. + */ + // const projectId = 'YOUR_PROJECT_ID'; + + const compute = require('@google-cloud/compute'); + + // List all instances in the specified project. + async function listAllInstances() { + const instancesClient = new compute.InstancesClient({fallback: 'rest'}); + + //Use the `maxResults` parameter to limit the number of results that the API returns per response page. + const aggListRequest = instancesClient.aggregatedListAsync({ + project: projectId, + maxResults: 5, + }); + + console.log('Instances found:'); + + // Despite using the `maxResults` parameter, you don't need to handle the pagination + // yourself. The returned object handles pagination automatically, + // requesting next pages as you iterate over the results. + for await (const [zone, instancesObject] of aggListRequest) { + const instances = instancesObject.instances; + + if (instances && instances.length > 0) { + console.log(` ${zone}`); + for (const instance of instances) { + console.log(` - ${instance.name} (${instance.machineType})`); + } + } + } + } + + listAllInstances(); + // [END compute_instances_list_all] +} + +main(...process.argv.slice(2)); diff --git a/compute/listImages.js b/compute/listImages.js new file mode 100644 index 0000000000..c6513e46e4 --- /dev/null +++ b/compute/listImages.js @@ -0,0 +1,51 @@ +// Copyright 2021 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 a list of all non-deprecated image names available in given project. + * + * @param {string} projectId - ID or number of the project you want to list images from + */ +function main(projectId) { + // [START compute_images_list] + /** + * TODO(developer): Uncomment and replace these variables before running the sample. + */ + // const projectId = 'YOUR_PROJECT_ID'; + + const compute = require('@google-cloud/compute'); + + async function listImages() { + const imagesClient = new compute.ImagesClient({fallback: 'rest'}); + + // Listing only non-deprecated images to reduce the size of the reply. + const images = imagesClient.listAsync({ + project: projectId, + maxResults: 3, + filter: 'deprecated.state != DEPRECATED', + }); + + // Although the `maxResults` parameter is specified in the request, the iterable returned + // by the `listAsync()` method hides the pagination mechanic. The library makes multiple + // requests to the API for you, so you can simply iterate over all the images. + for await (const image of images) { + console.log(` - ${image.name}`); + } + } + + listImages(); + // [END compute_images_list] +} + +main(...process.argv.slice(2)); diff --git a/compute/listImagesByPage.js b/compute/listImagesByPage.js new file mode 100644 index 0000000000..a14f2e7261 --- /dev/null +++ b/compute/listImagesByPage.js @@ -0,0 +1,75 @@ +// Copyright 2021 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 a list of all non-deprecated image names available in a given project, divided into pages as returned by the Compute Engine API. + * + * @param {string} projectId - ID or number of the project you want to list images from + * @param {number} pageSize - size of the pages you want the API to return on each call. + */ +function main(projectId, pageSize = 10) { + // [START compute_images_list_page] + /** + * TODO(developer): Uncomment and replace these variables before running the sample. + */ + // const projectId = 'YOUR_PROJECT_ID'; + // const pageSize = 10; + + const compute = require('@google-cloud/compute'); + + async function listImagesByPage() { + const imagesClient = new compute.ImagesClient({fallback: 'rest'}); + + // Listing only non-deprecated images to reduce the size of the reply. + const listRequest = { + project: projectId, + maxResults: pageSize, + filter: 'deprecated.state != DEPRECATED', + }; + + const options = { + autoPaginate: false, + }; + + let pageNum = 1; + + // Set autoPaginate option to `false` to have more granular control of + // iteration over paginated results from the API. Each time you want to access the + // next page, the library retrieves that page from the API. + const listCallback = (err, resources, nextPageRequest, response) => { + if (err) { + console.error(err); + return; + } + + console.log(`Page ${pageNum}:`); + pageNum += 1; + + for (let i = 0; i < resources.length; i++) { + console.log(resources[i].name); + } + + if (response.nextPageToken) { + imagesClient.list(nextPageRequest, options, listCallback); + } + }; + + imagesClient.list(listRequest, options, listCallback); + } + + listImagesByPage(); + // [END compute_images_list_page] +} + +main(...process.argv.slice(2)); diff --git a/compute/listInstances.js b/compute/listInstances.js new file mode 100644 index 0000000000..1e81ff2c43 --- /dev/null +++ b/compute/listInstances.js @@ -0,0 +1,51 @@ +// Copyright 2021 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. + +/** + * Gets a list of instances created in given project in given zone. + * + * @param {string} projectId - ID or number of the project you want to use. + * @param {string} zone - Name of the zone you want to check, for example: us-west3-b + */ +function main(projectId, zone) { + // [START compute_instances_list] + /** + * TODO(developer): Uncomment and replace these variables before running the sample. + */ + // const projectId = 'YOUR_PROJECT_ID'; + // const zone = 'europe-central2-b' + + const compute = require('@google-cloud/compute'); + + // List all instances in the given zone in the specified project. + async function listInstances() { + const instancesClient = new compute.InstancesClient({fallback: 'rest'}); + + const [instanceList] = await instancesClient.list({ + project: projectId, + zone, + }); + + console.log(`Instances found in zone ${zone}:`); + + for (const instance of instanceList) { + console.log(` - ${instance.name} (${instance.machineType})`); + } + } + + listInstances(); + // [END compute_instances_list] +} + +main(...process.argv.slice(2)); diff --git a/compute/listVMs.js b/compute/listVMs.js deleted file mode 100644 index d5eb248c90..0000000000 --- a/compute/listVMs.js +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2017 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. - -// sample-metadata: -// title: List VMs -// usage: node listVMs - -'use strict'; - -async function main() { - // [START gce_list_vms] - const Compute = require('@google-cloud/compute'); - const compute = new Compute(); - async function listVMs() { - const vms = await compute.getVMs({ - maxResults: 10, - }); - console.log(`Found ${vms.length} VMs!`); - vms.forEach(vm => console.log(vm)); - } - listVMs(); - // [END gce_list_vms] -} -main().catch(console.error); diff --git a/compute/mailjet.js b/compute/mailjet.js index b587faff63..5ad072be17 100644 --- a/compute/mailjet.js +++ b/compute/mailjet.js @@ -1,4 +1,4 @@ -// Copyright 2017 Google LLC +// Copyright 2021 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,7 +18,7 @@ 'use strict'; -// [START send] +// [START compute_send] const mailer = require('nodemailer'); const smtp = require('nodemailer-smtp-transport'); @@ -43,4 +43,4 @@ async function mailjet() { console.log(json); } mailjet(); -// [END send] +// [END compute_send] diff --git a/compute/package.json b/compute/package.json index cde30e0e4d..72be09d074 100644 --- a/compute/package.json +++ b/compute/package.json @@ -1,27 +1,26 @@ { - "name": "nodejs-docs-samples-computeengine", - "private": true, + "name": "nodejs-docs-samples-compute", "license": "Apache-2.0", "author": "Google Inc.", + "engines": { + "node": ">=10" + }, "repository": "googleapis/nodejs-compute", + "private": true, "files": [ - "*.js", - "!test/" + "*.js" ], - "engines": { - "node": ">=8" - }, "scripts": { - "test": "mocha --timeout 1200000" + "test": "mocha test --timeout 1200000" }, "dependencies": { - "@google-cloud/compute": "^2.6.0", + "@google-cloud/compute": "3.0.0-alpha.3", "@sendgrid/mail": "^7.0.0", - "node-fetch": "^2.3.0", "nodemailer": "^6.0.0", "nodemailer-smtp-transport": "^2.7.4" }, "devDependencies": { + "@google-cloud/storage": "^5.8.5", "chai": "^4.2.0", "mocha": "^8.0.0", "proxyquire": "^2.0.1", diff --git a/compute/quickstart.js b/compute/quickstart.js deleted file mode 100644 index f71b0ed4f3..0000000000 --- a/compute/quickstart.js +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2017, Google, Inc. -// 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'; - -async function main( - vmName = 'new_virtual_machine' // VM name of your choice -) { - // [START compute_engine_quickstart] - // Imports the Google Cloud client library - const Compute = require('@google-cloud/compute'); - - // Creates a client - const compute = new Compute(); - - async function quickstart() { - // Create a new VM using the latest OS image of your choice. - const zone = compute.zone('us-central1-c'); - - // TODO(developer): choose a name for the VM - // const vmName = 'vm-name'; - - // Start the VM create task - const [vm, operation] = await zone.createVM(vmName, {os: 'ubuntu'}); - console.log(vm); - - // `operation` lets you check the status of long-running tasks. - await operation.promise(); - - // Complete! - console.log('Virtual machine created!'); - } - quickstart(); - // [END compute_engine_quickstart] -} - -main(...process.argv.slice(2)); diff --git a/compute/sendgrid.js b/compute/sendgrid.js index 60a783bdfe..cb3b79228b 100644 --- a/compute/sendgrid.js +++ b/compute/sendgrid.js @@ -1,9 +1,10 @@ -// Copyright 2015 Google, Inc +// Copyright 2021 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 +// 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, @@ -13,7 +14,7 @@ 'use strict'; -// [START send] +// [START compute_send] // This sample is based off of: // https://github.com/sendgrid/sendgrid-nodejs/tree/master/packages/mail const sendgrid = require('@sendgrid/mail'); @@ -28,4 +29,4 @@ async function sendgridExample() { }); } sendgridExample(); -// [END send] +// [END compute_send] diff --git a/compute/setUsageExportBucket.js b/compute/setUsageExportBucket.js new file mode 100644 index 0000000000..0bbbc3033a --- /dev/null +++ b/compute/setUsageExportBucket.js @@ -0,0 +1,58 @@ +// Copyright 2021 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. + +/** + * Set Compute Engine usage export bucket for the Cloud project. This sample presents how to interpret the default value for the report name prefix parameter. + * + * @param {string} projectId - ID or number of the project you want to use. + * @param {string} bucketName - Google Cloud Storage Bucket used to store Compute Engine usage reports. An existing Google Cloud Storage bucket is required. + * @param {string} reportNamePrefix - Report Name Prefix which defaults to an empty string to showcase default values behaviour. + */ +function main(projectId, bucketName, reportNamePrefix = '') { + // [START compute_usage_report_set] + /** + * TODO(developer): Uncomment and replace these variables before running the sample. + */ + // const projectId = 'YOUR_PROJECT_ID'; + // const bucketName = 'YOUR_BUCKET_NAME'; + + const compute = require('@google-cloud/compute'); + const compute_protos = compute.protos.google.cloud.compute.v1; + + async function setUsageExportBucket() { + const usageExportLocationResource = + new compute_protos.UsageExportLocation(); + usageExportLocationResource.bucketName = bucketName; + usageExportLocationResource.reportNamePrefix = reportNamePrefix; + + if (!reportNamePrefix) { + // Sending an empty value for reportNamePrefix results in the next usage report being generated with the default prefix value "usage_gce". (see: https://cloud.google.com/compute/docs/reference/rest/v1/projects/get) + console.log( + 'Setting reportNamePrefix to empty value causes the report to have the default prefix value `usage_gce`.' + ); + } + + // Set the usage export location. + const projectsClient = new compute.ProjectsClient({fallback: 'rest'}); + projectsClient.setUsageExportBucket({ + project: projectId, + usageExportLocationResource, + }); + } + + setUsageExportBucket(); + // [END compute_usage_report_set] +} + +main(...process.argv.slice(2)); diff --git a/compute/startupScript.js b/compute/startupScript.js deleted file mode 100644 index d433560ce1..0000000000 --- a/compute/startupScript.js +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright 2018 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'; - -async function main(name = 'start-script-example') { - // [START gce_startup_script] - const Compute = require('@google-cloud/compute'); - const fetch = require('node-fetch'); - - const compute = new Compute(); - const zone = compute.zone('us-central1-c'); - - // TODO(developer): choose a name for your virtual machine - // const name = 'your-vm-name'; - - /** - * Create a new virtual machine with Ubuntu and Apache - * @param {string} name Name of the virtual machine - */ - async function createVMWithStartupScript() { - // Create a new VM, using default ubuntu image. The startup script - // installs apache and a custom homepage. - const config = { - os: 'ubuntu', - http: true, - metadata: { - items: [ - { - key: 'startup-script', - value: `#! /bin/bash - - # Installs apache and a custom homepage - apt-get update - apt-get install -y apache2 - cat < /var/www/html/index.html - -

Hello World

-

This page was created from a simple start-up script!

`, - }, - ], - }, - }; - - const vm = zone.vm(name); - - console.log(`Creating VM ${name}...`); - const [, operation] = await vm.create(config); - - console.log(`Polling operation ${operation.id}...`); - await operation.promise(); - - console.log('Acquiring VM metadata...'); - const [metadata] = await vm.getMetadata(); - - // External IP of the VM. - const ip = metadata.networkInterfaces[0].accessConfigs[0].natIP; - console.log(`Booting new VM with IP http://${ip}...`); - - // Ping the VM to determine when the HTTP server is ready. - console.log('Operation complete. Waiting for IP'); - await pingVM(ip); - - console.log(`\n${name} created successfully`); - } - - /** - * Poll a given IP address until it returns a result. - * @param {string} ip IP address to poll - */ - async function pingVM(ip) { - let exit = false; - while (!exit) { - await new Promise(r => setTimeout(r, 2000)); - try { - const res = await fetch(`http://${ip}`); - if (res.status !== 200) { - throw new Error(res.status); - } - exit = true; - } catch (err) { - process.stdout.write('.'); - } - } - } - - createVMWithStartupScript(); - // [END gce_startup_script] -} - -main(...process.argv.slice(2)); diff --git a/compute/test/.eslintrc.yml b/compute/test/.eslintrc similarity index 100% rename from compute/test/.eslintrc.yml rename to compute/test/.eslintrc diff --git a/compute/test/mailjet.test.js b/compute/test/mailjet.test.js index 6da3c8f0fc..b2de020f90 100644 --- a/compute/test/mailjet.test.js +++ b/compute/test/mailjet.test.js @@ -1,4 +1,4 @@ -// Copyright 2017 Google LLC +// Copyright 2021 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/compute/test/samples.test.js b/compute/test/samples.test.js index 879da76df6..982db6a60e 100644 --- a/compute/test/samples.test.js +++ b/compute/test/samples.test.js @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2021 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,69 +14,160 @@ 'use strict'; +const compute = require('@google-cloud/compute'); +const {Storage} = require('@google-cloud/storage'); + +const {describe, it} = require('mocha'); const uuid = require('uuid'); const cp = require('child_process'); const {assert} = require('chai'); -const Compute = require('@google-cloud/compute'); -const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'}); +const instancesClient = new compute.InstancesClient({fallback: 'rest'}); +const projectsClient = new compute.ProjectsClient({fallback: 'rest'}); -const compute = new Compute(); +const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'}); describe('samples', () => { - describe('quickstart', () => { - const name = `gcloud-ubuntu-${uuid.v4().split('-')[0]}`; - after(async () => deleteVM(name)); - it('should run the quickstart', () => { - const output = execSync(`node quickstart ${name}`); - assert.match(output, /Virtual machine created!/); - }); + const instanceName = `gcloud-test-intance-${uuid.v4().split('-')[0]}`; + const zone = 'europe-central2-b'; + const bucketName = `test-bucket-name-${uuid.v4().split('-')[0]}`; + + const storage = new Storage(); + + it('should create instance', async () => { + const projectId = await instancesClient.getProjectId(); + const output = execSync( + `node createInstance ${projectId} ${zone} ${instanceName}` + ); + assert.match(output, /Instance created./); + }); + + it('should print instances list', async () => { + const projectId = await instancesClient.getProjectId(); + const output = execSync(`node listInstances ${projectId} ${zone}`); + assert.match(output, /Instances found in zone/); + }); + + it('should print all instances list', async () => { + const projectId = await instancesClient.getProjectId(); + const output = execSync(`node listAllInstances ${projectId}`); + assert.match(output, /Instances found:/); + }); + + it('should delete instance', async () => { + const projectId = await instancesClient.getProjectId(); + const output = execSync( + `node deleteInstance ${projectId} ${zone} ${instanceName}` + ); + assert.match(output, /Instance deleted./); }); - describe('lifecycle', () => { - const name = `gcloud-ubuntu-${uuid.v4().split('-')[0]}`; + it('should wait for operation', async () => { + const projectId = await instancesClient.getProjectId(); - it('should create a VM', () => { - const output = execSync(`node createVM ${name}`); - assert.match(output, /Virtual machine created!/); + const newinstanceName = `gcloud-test-intance-${uuid.v4().split('-')[0]}`; + + execSync(`node createInstance ${projectId} ${zone} ${newinstanceName}`); + + const [operation] = await instancesClient.delete({ + project: projectId, + zone, + instance: newinstanceName, }); - it('should list the VMs', () => { - const output = execSync('node listVMs'); - assert.match(output, /Found \d+ VMs!/); + const operationString = JSON.stringify(operation); + + const output = execSync( + `node waitForOperation ${projectId} '${operationString}'` + ); + assert.match(output, /Operation finished./); + }); + + describe('usage export', () => { + before(async () => { + await storage.createBucket(bucketName); }); - it('should delete the VM', () => { - const output = execSync(`node deleteVM ${name}`); - assert.match(output, /VM deleted!/); + after(async () => { + const projectId = await instancesClient.getProjectId(); + + await projectsClient.setUsageExportBucket({ + project: projectId, + usageExportLocationResource: {}, + }); + + await storage.bucket(bucketName).delete(); }); - }); - describe('start-up script', () => { - const name = `gcloud-apache-${uuid.v4().split('-')[0]}`; - after(async () => deleteVM(name)); - it('should create vm with startup script', function (done) { - this.timeout(280000); - this.retries(3); - const {spawn} = require('child_process'); - const startupScript = spawn('node', ['startupScript', name], { - stdio: 'inherit', + it('should set empty default value in reportNamePrefix', async () => { + const projectId = await instancesClient.getProjectId(); + + const output = execSync( + `node setUsageExportBucket ${projectId} ${bucketName}` + ); + await new Promise(resolve => setTimeout(resolve, 5000)); + + assert.match( + output, + /Setting reportNamePrefix to empty value causes the report to have the default prefix value `usage_gce`./ + ); + + const [project] = await projectsClient.get({ + project: projectId, }); - startupScript.on('close', code => { - assert.strictEqual(code, 0); - return done(); + + const usageExportLocation = project.usageExportLocation; + + assert.equal(usageExportLocation.bucketName, bucketName); + assert.equal(usageExportLocation.reportNamePrefix, ''); + }); + + it('should get current default value in reportNamePrefix', async () => { + const projectId = await instancesClient.getProjectId(); + + execSync(`node setUsageExportBucket ${projectId} ${bucketName}`); + await new Promise(resolve => setTimeout(resolve, 5000)); + const output = execSync(`node getUsageExportBucket ${projectId}`); + + assert.match( + output, + /Report name prefix not set, replacing with default value of `usage_gce`./ + ); + + assert.match(output, /Returned reportNamePrefix: usage_gce/); + }); + + it('should disable usage export', async () => { + const projectId = await instancesClient.getProjectId(); + + execSync(`node setUsageExportBucket ${projectId} ${bucketName}`); + await new Promise(resolve => setTimeout(resolve, 5000)); + execSync(`node disableUsageExport ${projectId}`); + await new Promise(resolve => setTimeout(resolve, 5000)); + + const [project] = await projectsClient.get({ + project: projectId, }); + + assert.isUndefined(project.usageExportLocation); }); }); -}); -/** - * Utility function to delete a VM. - * @param {string} name - */ -async function deleteVM(name) { - const zone = compute.zone('us-central1-c'); - const vm = zone.vm(name); - const [operation] = await vm.delete(); - await operation.promise(); -} + describe('pagination', () => { + const projectId = 'windows-sql-cloud'; + + it('should automatically iterate throught the pages', async () => { + const output = execSync(`node listImages ${projectId}`); + const lines = output.split(' - '); + + assert(lines.length > 3); + }); + + it('should iterate page by page granularly', async () => { + const output = execSync(`node listImagesByPage ${projectId}`); + + assert.match(output, /Page 1/); + assert.match(output, /Page 2/); + }); + }); +}); diff --git a/compute/test/sendgrid.test.js b/compute/test/sendgrid.test.js index 217cc8a180..6b3c333959 100644 --- a/compute/test/sendgrid.test.js +++ b/compute/test/sendgrid.test.js @@ -1,4 +1,4 @@ -// Copyright 2017 Google LLC +// Copyright 2021 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/compute/vms.js b/compute/vms.js deleted file mode 100644 index b810f92c12..0000000000 --- a/compute/vms.js +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2017 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. - -// [START complete] -'use strict'; - -// [START auth] -// By default, the client will authenticate using the service account file -// specified by the GOOGLE_APPLICATION_CREDENTIALS environment variable and use -// the project specified by the GCLOUD_PROJECT environment variable. See -// https://cloud.google.com/docs/authentication/production#providing_credentials_to_your_application -const Compute = require('@google-cloud/compute'); -// [END auth] - -// [START initialize] -// Creates a client -const compute = new Compute(); -// [END initialize] - -// [START list] - -async function getVmsExample() { - // In this example we only want one VM per page - const options = { - maxResults: 1, - }; - const vms = await compute.getVMs(options); - return vms; -} -// [END list] -// [END complete] - -// Run the examples -exports.main = async () => { - const vms = await getVmsExample().catch(console.error); - if (vms) console.log('VMs:', vms); - return vms; -}; - -if (module === require.main) { - exports.main(console.log); -} diff --git a/compute/waitForOperation.js b/compute/waitForOperation.js new file mode 100644 index 0000000000..3f27c67dfa --- /dev/null +++ b/compute/waitForOperation.js @@ -0,0 +1,53 @@ +// Copyright 2021 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. + +/** + * Waits for an operation to be completed. Calling this function will block until the operation is finished. + * @param {string} projectId - ID or number of the project you want to use. + * @param {string} operationString - Operation instance you want to wait in string format. + */ +function main(projectId, operationString) { + // [START compute_instances_operation_check] + /** + * TODO(developer): Uncomment and replace these variables before running the sample. + */ + // const projectId = 'YOUR_PROJECT_ID'; + // const operationString = 'YOUR_OPERATION_STRING' + + const compute = require('@google-cloud/compute'); + + // Parse stringified operation to the object instance. + const operation = JSON.parse(operationString); + + async function waitForOperation() { + if (operation.status === 'RUNNING') { + const operationsClient = new compute.ZoneOperationsClient({ + fallback: 'rest', + }); + + await operationsClient.wait({ + operation: operation.name, + project: projectId, + zone: operation.zone.split('/').pop(), + }); + } + + console.log('Operation finished.'); + } + + waitForOperation(); + // [END compute_instances_operation_check] +} + +main(...process.argv.slice(2));