Skip to content

Instantly share code, notes, and snippets.

@prabowomurti
Created October 15, 2020 05:59
Show Gist options
  • Select an option

  • Save prabowomurti/3b0b2c5800b8f28e9e5515805be1e33f to your computer and use it in GitHub Desktop.

Select an option

Save prabowomurti/3b0b2c5800b8f28e9e5515805be1e33f to your computer and use it in GitHub Desktop.

Revisions

  1. prabowomurti created this gist Oct 15, 2020.
    139 changes: 139 additions & 0 deletions index.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,139 @@
    /**
    * Copyright 2018, 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.
    */

    // [START functions_start_instance_pubsub]
    // [START functions_stop_instance_pubsub]
    const Buffer = require('safe-buffer').Buffer;
    const Compute = require('@google-cloud/compute');
    const compute = new Compute();
    // [END functions_stop_instance_pubsub]

    /**
    * Starts a Compute Engine instance.
    *
    * Expects a PubSub message with JSON-formatted event data containing the
    * following attributes:
    * zone - the GCP zone the instances are located in.
    * label - the label of instances to start.
    *
    * @param {!object} event Cloud Function PubSub message event.
    * @param {!object} callback Cloud Function PubSub callback indicating
    * completion.
    */
    exports.startInstancePubSub = (event, context, callback) => {
    try {
    const payload = _validatePayload(
    JSON.parse(Buffer.from(event.data, 'base64').toString())
    );
    const options = {filter: `labels.${payload.label}`};
    compute.getVMs(options).then(vms => {
    vms[0].forEach(instance => {
    compute
    .zone(instance.zone.id)
    .vm(instance.name)
    .start()
    .then(data => {
    // Operation pending.
    const operation = data[0];
    return operation.promise();
    })
    .then(() => {
    // Operation complete. Instance successfully started.
    const message = 'Successfully started instance ' + instance.name;
    console.log(message);
    callback(null, message);
    })
    .catch(err => {
    console.log(err);
    callback(err);
    });
    });
    });
    } catch (err) {
    console.log(err);
    callback(err);
    }
    };
    // [END functions_start_instance_pubsub]
    // [START functions_stop_instance_pubsub]

    /**
    * Stops a Compute Engine instance.
    *
    * Expects a PubSub message with JSON-formatted event data containing the
    * following attributes:
    * zone - the GCP zone the instances are located in.
    * instance - the name of a single instance.
    * label - the label of instances to start.
    *
    * Exactly one of instance or label must be specified.
    *
    * @param {!object} event Cloud Function PubSub message event.
    * @param {!object} callback Cloud Function PubSub callback indicating completion.
    */
    exports.stopInstancePubSub = (event, context, callback) => {
    try {
    const payload = _validatePayload(
    JSON.parse(Buffer.from(event.data, 'base64').toString())
    );
    const options = {filter: `labels.${payload.label}`};
    compute.getVMs(options).then(vms => {
    vms[0].forEach(instance => {
    compute
    .zone(instance.zone.id)
    .vm(instance.name)
    .stop()
    .then(data => {
    // Operation pending.
    const operation = data[0];
    return operation.promise();
    })
    .then(() => {
    // Operation complete. Instance successfully stopped.
    const message = 'Successfully stopped instance ' + instance.name;
    console.log(message);
    callback(null, message);
    })
    .catch(err => {
    console.log(err);
    callback(err);
    });
    });
    });
    } catch (err) {
    console.log(err);
    callback(err);
    }
    };
    // [START functions_start_instance_pubsub]

    /**
    * Validates that a request payload contains the expected fields.
    *
    * @param {!object} payload the request payload to validate.
    * @return {!object} the payload object.
    */
    function _validatePayload(payload) {
    // ignore the zone
    // if (!payload.zone) {
    // throw new Error(`Attribute 'zone' missing from payload`);
    // } else
    if (!payload.label) {
    throw new Error(`Attribute 'label' missing from payload`);
    }
    return payload;
    }
    // [END functions_start_instance_pubsub]
    // [END functions_stop_instance_pubsub]
    27 changes: 27 additions & 0 deletions package.json
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,27 @@
    {
    "name": "cloud-functions-schedule-instance",
    "version": "0.0.2",
    "private": true,
    "license": "Apache-2.0",
    "author": "Google Inc.",
    "repository": {
    "type": "git",
    "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git"
    },
    "engines": {
    "node": ">=8.13.0"
    },
    "scripts": {
    "test": "mocha test/*.test.js --timeout=20000"
    },
    "devDependencies": {
    "@google-cloud/nodejs-repo-tools": "^3.3.0",
    "mocha": "^6.0.0",
    "proxyquire": "^2.0.0",
    "sinon": "^7.0.0"
    },
    "dependencies": {
    "@google-cloud/compute": "^0.12.0",
    "safe-buffer": "^5.1.2"
    }
    }