Skip to content

Instantly share code, notes, and snippets.

@zomglings
Created April 22, 2018 15:26
Show Gist options
  • Save zomglings/45af143b0449e3f52c33dc7869745f58 to your computer and use it in GitHub Desktop.
Save zomglings/45af143b0449e3f52c33dc7869745f58 to your computer and use it in GitHub Desktop.
Poll GCE instance to make sure it hasn't died (or been pre-empted)...
var Compute = require('@google-cloud/compute');
var {poll} = require('@nkashy1/pollster');
var twilio = require('twilio');
// START gcp-related setup
const gcpProject = process.env.GOOGLE_CLOUD_PROJECT
const gcpSacred = process.env.GOOGLE_APPLICATION_CREDENTIALS
const gceZone = process.env.GOOGLE_COMPUTE_ZONE;
const gceInstance = process.env.GOOGLE_COMPUTE_INSTANCE;
if (!gcpProject || !gcpSacred || !gceZone || !gceInstance) {
let message = (
'One of these environment variables is undefined:\n' +
`GOOGLE_CLOUD_PROJECT: ${!!gcpProject}\n` +
`GOOGLE_APPLICATION_CREDENTIALS: ${!!gcpSacred}\n` +
`GOOGLE_COMPUTE_ZONE: ${!!gceZone}\n` +
`GOOGLE_COMPUTE_INSTANCE: ${!!gceInstance}\n`
);
throw new Error(message);
}
var gce = new Compute({
projectId: gcpProject,
keyFilename: gcpSacred
});
// END gcp-related setup
// START twilio-related setup
var twilioAccountSid = process.env.TWILIO_ACCOUNT_SID;
var twilioAuthToken = process.env.TWILIO_AUTH_TOKEN;
var twilioPhoneNumber = process.env.TWILIO_PHONE_NUMBER;
var notificationPhoneNumber = process.env.NOTIFICATION_PHONE_NUMBER;
if (!twilioAccountSid || !twilioAuthToken || !twilioPhoneNumber || !notificationPhoneNumber) {
let message = (
'The following environment variables should be defined:\n' +
`TWILIO_ACCOUNT_SID: ${!!twilioAccountSid}\n` +
`TWILIO_AUTH_TOKEN: ${!!twilioAuthToken}\n` +
`TWILIO_PHONE_NUMBER: ${!!twilioPhoneNumber}\n` +
`NOTIFICATION_PHONE_NUMBER: ${notificationPhoneNumber}\n`
);
throw new Error(message);
}
var twilioClient = new twilio(twilioAccountSid, twilioAuthToken);
// END twilio-related setup
function smsSignaller(twilioClient, twilioPhoneNumber, notificationPhoneNumber, message) {
function sendSignal(err) {
if (!!err) {
console.error(err);
process.exit(1);
}
return twilioClient.messages.create({
body: message,
to: notificationPhoneNumber,
from: twilioPhoneNumber
}, function(err, message) {
if (!!err) {
console.error(err);
process.exit(1);
}
console.log(
`Message sent: ${message.sid}`);
process.exit(0);
});
}
return sendSignal;
}
function vmStatusPredicate(alarmingStatuses) {
function predicate(cb) {
console.log(`${Date.now()} - polling status of ${gceInstance}...`);
let vm = gce.zone(gceZone).vm(gceInstance);
return vm.exists((err, existsp) => {
if (!!err) {
return cb(err);
}
if (!existsp) {
console.log(`${gceInstance} non-existent`);
return cb(null, true)
}
return vm.getMetadata((err, metadata, apiResponse) => {
if (!!err) {
return cb(err);
}
let vmStatus = apiResponse.status;
console.log(`Status: ${vmStatus}`);
if (alarmingStatuses[vmStatus]) {
return cb(null, true);
}
return cb(null, false);
});
});
}
return predicate;
}
let watchStatuses = {
STOPPING: true,
TERMINATED: true
};
console.log(`Watching instance ${gceInstance} in zone ${gceZone} for the following statuses: ${Object.keys(watchStatuses).join(', ')}`);
poll(
vmStatusPredicate(watchStatuses),
5000,
Infinity,
smsSignaller(
twilioClient,
twilioPhoneNumber,
notificationPhoneNumber,
`Instance down: ${gceInstance}`)
);
{
"name": "@nkashy1/gce-monitor",
"version": "0.0.1",
"description": "Monitor state of GCE resources",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "nkashy1",
"license": "Apache-2.0",
"dependencies": {
"@google-cloud/compute": "^0.10.0",
"@nkashy1/pollster": "0.0.3",
"twilio": "^3.15.1"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment