UNPKG

hubot-aws-cfpb

Version:

CFPB-specific Hubot aws commands. Forked from the excellent https://github.com/yoheimuta/hubot-aws/ and heavily modified for our particular usage needs

129 lines (112 loc) 4.07 kB
# Description: # Commands for reserving ec2 instances and listing existing reservations # # Commands: # hubot ec2 reserve <instance-id-nickname> <branch-name> <reservation comment> - Reserve an instance # hubot ec2 unreserve <instance-id-nickname> - Unreserve an instance # hubot ec2 reserve-ls - Displays a list of currently reserved instances # _ = require 'underscore' cson = require 'cson' ec2 = require('../../ec2.coffee') moment = require 'moment' tags = require './tags' mdTable = require('markdown-table') RESERVE_TAGS = { user: 'ReservationUser', time: 'ReservationTime', branch: 'ReservationBranch', description: 'ReservationDescription', } RESERVE_CONFIG_ENV_VAR = "HUBOT_AWS_RESERVE_CONFIG" try INSTANCE_ID_MAP = cson.parseCSONFile process.env[RESERVE_CONFIG_ENV_VAR] catch e # TODO switch to `robot.logger()` here _without_ constantly reparsing config file if e.name == "TypeError" console.log "#{RESERVE_CONFIG_ENV_VAR} is not defined" else console.log "#{RESERVE_CONFIG_ENV_VAR} could not be loaded " + "(#{process.env.HUBOT_AWS_RESERVE_CONFIG})" INSTANCE_ID_MAP = {} getReservationTags = (msg) -> args = if msg.match[1] then msg.match[1].trim().split(/\s+/).slice(1) else [] if args.length < 2 [] else [ {Key: RESERVE_TAGS.user, Value: msg.message.user.name}, {Key: RESERVE_TAGS.time, Value: Date.now().toString()}, {Key: RESERVE_TAGS.branch, Value: args[0]}, {Key: RESERVE_TAGS.description, Value: args.slice(1).join(" ")}, ] formatReservationsList = (instances) -> if not instances.length return '[None]' getTag = (_tags, tag) -> _.first(t.Value for t in _tags when t.Key is tag) || '' instanceMap = _.invert(INSTANCE_ID_MAP) rows = ( { id: instanceMap[i.InstanceId] || "UNKNOWN", resUser: getTag(i.Tags, RESERVE_TAGS.user), resTime: getTag(i.Tags, RESERVE_TAGS.time), resBranch: getTag(i.Tags, RESERVE_TAGS.branch), resDescrip: getTag(i.Tags, RESERVE_TAGS.description), state: i.State.Name, } for i in instances ).sort (a, b) -> a.id > b.id timeFmt = "MMM Do YYYY, h:mm a" tableHead = [ 'instance', 'user', 'reserved time', 'branch', 'comment', 'status' ] tableRows = ( [ r.id, r.resUser, moment(parseInt(r.resTime)).format(timeFmt), r.resBranch, r.resDescrip, r.state, ] for r in rows ) tableRows.unshift tableHead mdTable tableRows, {align: 'l'} module.exports = (robot) -> robot.respond /ec2 reserve (.*)$/i, (msg) -> instance = msg.match[1].trim().split(/\s+/)[0] if !INSTANCE_ID_MAP[instance] validInstanceIDs = Object.keys(INSTANCE_ID_MAP).join(", ") return msg.send "Unknown instance nickname. Choose from: #{validInstanceIDs}" reservationTags = getReservationTags(msg) if !reservationTags.length msg.send "Cannot reserve: please provide a branch and a comment" else tags.addReservation(msg, INSTANCE_ID_MAP[instance], reservationTags) msg.send "Reservation added to #{instance}." robot.respond /ec2 unreserve (.*)$/i, (msg) -> instance = msg.match[1].trim().split(/\s+/)[0] if !INSTANCE_ID_MAP[instance] return msg.send "Unknown instance: #{instance}" reservationTags = [ {Key: RESERVE_TAGS.user, Value: "--"}, {Key: RESERVE_TAGS.time, Value: Date.now().toString()}, {Key: RESERVE_TAGS.branch, Value: "--"}, {Key: RESERVE_TAGS.description, Value: "--"}, ] tags.addReservation(msg, INSTANCE_ID_MAP[instance], reservationTags) msg.send "Unreserved instance: #{instance}." robot.respond /ec2 reserve-ls$/i, (msg) -> params = { Filters: [ { Name: 'tag-key', Values: [RESERVE_TAGS.user] } ] } ec2.describeInstances params, (err, res) -> if err msg.send "DescribeInstancesError: #{err}" else instances = _.flatten(i for i in (r.Instances for r in res.Reservations)) msg.send(formatReservationsList(instances))