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

198 lines (157 loc) 7.45 kB
# Description: # Run ec2 instance # # Configurations: # HUBOT_AWS_DEFAULT_CREATOR_EMAIL: [required] An email address to be used for tagging the new instance # HUBOT_AWS_EC2_RUN_CONFIG: [optional] Path to csonfile to be performs service operation based on. Required a config_path argument or this. # HUBOT_AWS_EC2_RUN_USERDATA_PATH: [optional] Path to userdata file. # HUBOT_AWS_EC2_REQUIRE_SSH_KEY: [optional] Require that a user have a public SSH key saved to their chat account. See https://github.com/catops/catops-keys # # Commands: # hubot ec2 run - Run an Instance # # Notes: # --image_id=*** : [optional] The ID of the AMI. If omit it, the ImageId of config is used # --config_path=*** : [optional] Config file path. If omit it, HUBOT_AWS_EC2_RUN_CONFIG is referred to. # --userdata_path=*** : [optional] Userdata file path to be not encoded yet. If omit it, HUBOT_AWS_EC2_RUN_USERDATA_PATH is referred to. # --squad=*** : [optional] Name of squad the instance belongs to. The public keys of everyone on the squad will be added to the instance. Requires `hubot-squads`. # --dry-run : [optional] Checks whether the api request is right. Recommend to set before applying to real asset. fs = require 'fs' cson = require 'cson' util = require 'util' tags_ = require './tags' getArgParams = (arg) -> dry_run = if arg.match(/--dry-run/) then true else false image_id_capture = /--image_id=(.*?)( |$)/.exec(arg) image_id = if image_id_capture then image_id_capture[1] else null config_path_capture = /--config_path=(.*?)( |$)/.exec(arg) config_path = if config_path_capture then config_path_capture[1] else null userdata_path_capture = /--userdata_path=(.*?)( |$)/.exec(arg) userdata_path = if userdata_path_capture then userdata_path_capture[1] else null squad_capture = /--(squad|team)=(.*?)( |$)/.exec(arg) squad = if squad_capture then squad_capture[2] else null return {dry_run: dry_run, image_id: image_id, config_path: config_path, userdata_path: userdata_path, squad: squad} module.exports = (robot) -> robot.respond /ec2 run(.*)$/i, (msg) -> unless require('../../auth.coffee').canAccess(robot, msg.envelope.user) msg.send "You cannot access this feature. Please contact with admin" return arg_value = msg.match[1] arg_params = getArgParams(arg_value) dry_run = arg_params.dry_run image_id = arg_params.image_id config_path = arg_params.config_path userdata_path = arg_params.userdata_path squad = arg_params.squad config_path ||= process.env.HUBOT_AWS_EC2_RUN_CONFIG unless fs.existsSync config_path msg.send "NOT FOUND HUBOT_AWS_EC2_RUN_CONFIG" return params = cson.parseCSONFile config_path params.ImageId = image_id if image_id ssh_key = '' # Check if a squad was specified and if squads exist in the brain if squad and robot.brain.data.squads and robot.brain.data.squads[squad] robot.brain.data.squads[squad].members.forEach (member) -> member = robot.brain.userForName(member) if member and member.key ssh_key += member.key + '\n' return # If we're not using squads, check for the user's key else if robot.brain.userForId(msg.envelope.user.id).key ssh_key = robot.brain.userForId(msg.envelope.user.id).key # If a key is required and we didn't find one, abort if !!process.env.HUBOT_AWS_EC2_REQUIRE_SSH_KEY and !ssh_key.length return msg.send "You need to set your SSH *public* key first. To do so, copy your ~/.ssh/id_rsa.pub into your clipboard, and then in chat say `#{robot.name} my public key is [your_ssh_key]`" userData = """ #!/bin/bash echo 'UserData inside of run.coffee' echo 'Copying user public key into authorized_keys' echo '#{ssh_key}' >> /home/ec2-user/.ssh/authorized_keys """ init_file = "" userdata_path ||= process.env.HUBOT_AWS_EC2_RUN_USERDATA_PATH if fs.existsSync userdata_path init_file = fs.readFileSync userdata_path, 'utf-8' # params.UserData = new Buffer(init_file).toString('base64') userData += "\n" + init_file console.log "UserData is " + userData buf = new Buffer(userData) params.UserData = buf.toString('base64') msg.send "Requesting image_id=#{image_id}, config_path=#{config_path}, userdata_path=#{userdata_path}, dry-run=#{dry_run}..." curr_value = 0 aws_instance_name = "" aws_instance_desc = "" arg_values = arg_value.split /\s+/ for av in arg_values if not av.match(/^--/) if (curr_value == 1) aws_instance_name = av else if (curr_value > 1) aws_instance_desc += (av + " ") curr_value += 1 if (aws_instance_name.length == 0) msg.send "An AWS instance name is required" msg.send "Example usage: ec2 run test_instance this is my description" return # TODO: yank this out into functions; replace with moment.js goodness today = new Date dd = today.getDate() mm = today.getMonth() + 1 yyyy = today.getFullYear() if dd < 10 dd = '0' + dd if mm < 10 mm = '0' + mm expireDate = new Date expireDate.setDate(expireDate.getDate() + 14) expdd = expireDate.getDate() expmm = expireDate.getMonth() + 1 expyyyy = expireDate.getFullYear() if expdd < 10 expdd = '0' + expdd if expmm < 10 expmm = '0' + expmm user_email = msg.message.user["email_address"] || process.env.HUBOT_AWS_DEFAULT_CREATOR_EMAIL || "unknown" tags = [ { Key: 'Name', Value: aws_instance_name }, { Key: 'Description', Value: aws_instance_desc }, { Key: 'Application', Value: '' }, { Key: 'Creator', Value: user_email}, { Key: 'Software', Value: '' }, { Key: 'BusinessOwner', Value: process.env.HUBOT_AWS_DEFAULT_CREATOR_EMAIL || "unknown" }, { Key: 'SysAdmin', Value: user_email }, { Key: tags_.SCHEDULE_TAG, Value: tags_.formatSchedule(tags_.DEFAULT_SCHEDULE) }, { Key: 'CreatedByApplication', Value: 'chat' }, { Key: 'CreateDate', Value: "#{yyyy}-#{mm}-#{dd}"}, { Key: 'ExpireDate', Value: "#{expyyyy}-#{expmm}-#{expdd}"} ] for t in tags msg.send "Adding new tag: tag_key=#{t['Key']}, tag_value=#{t['Value']}" if dry_run msg.send util.inspect(params, false, null) return ec2 = require('../../ec2.coffee') ec2.runInstances params, (err, res) -> if err msg.send "Error: #{err}" else messages = [] for ins in res.Instances state = ins.State.Name id = ins.InstanceId type = ins.InstanceType for network in ins.NetworkInterfaces ip = network.PrivateIpAddress messages.push("#{state}\t#{id}\t#{type}\t#{ip}\t#{aws_instance_name}") messages.push("\nIn about 10 minutes, you should be able to ssh in with ssh ec2-user@#{ip}\n") messages.push("\nThis instance defaults to running between 8 AM and 6 PM. You can change that schedule with the `ec2 schedule` command. See `bot help ec2 schedule` for details\n") messages.sort() message = messages.join "\n" msg.send message params = Resources: [id] Tags: tags ec2.createTags params, (err, res) -> if err msg.send "Error creating tags: #{err}"