class Awful::AutoScaling
Constants
- COLORS
Public Instance Methods
activities(name)
click to toggle source
# File lib/awful/auto_scaling.rb, line 382 def activities(name) autoscaling.describe_scaling_activities(auto_scaling_group_name: name).activities.output do |activities| if options[:long] print_table activities.map { |a| [color(a.status_code), a.description, a.start_time, a.end_time] } elsif options[:cause] print_table activities.map { |a| [color(a.status_code), a.description, a.start_time, a.end_time, "\n#{a.cause}\n\n"] } else puts activities.map(&:activity_id) end end end
all_matching_asgs(name)
click to toggle source
# File lib/awful/auto_scaling.rb, line 35 def all_matching_asgs(name) autoscaling.describe_auto_scaling_groups.map(&:auto_scaling_groups).flatten.select do |asg| asg.auto_scaling_group_name.match(name) or tag_name(asg, '').match(name) end end
asg_instance_details(*names)
click to toggle source
lookup ec2 details for instances in named ASGs
# File lib/awful/auto_scaling.rb, line 47 def asg_instance_details(*names) ids = asg_instances(*names).map(&:instance_id) ec2.describe_instances(instance_ids: ids).map(&:reservations).flatten.map(&:instances).flatten.sort_by(&:launch_time) end
asg_instances(*names)
click to toggle source
return instances for named ASGs
# File lib/awful/auto_scaling.rb, line 42 def asg_instances(*names) autoscaling.describe_auto_scaling_groups(auto_scaling_group_names: names).auto_scaling_groups.map(&:instances).flatten end
attach(name, *instance_ids)
click to toggle source
# File lib/awful/auto_scaling.rb, line 305 def attach(name, *instance_ids) autoscaling.attach_instances(auto_scaling_group_name: name, instance_ids: instance_ids) end
color(string)
click to toggle source
# File lib/awful/auto_scaling.rb, line 31 def color(string) set_color(string, COLORS.fetch(string.to_sym, :yellow)) end
create(file = nil)
click to toggle source
# File lib/awful/auto_scaling.rb, line 169 def create(file = nil) opt = load_cfg(options, file) whitelist = %i[auto_scaling_group_name launch_configuration_name instance_id min_size max_size desired_capacity default_cooldown availability_zones load_balancer_names health_check_type health_check_grace_period placement_group vpc_zone_identifier termination_policies tags ] opt = remove_empty_strings(opt) opt = only_keys_matching(opt, whitelist) ## scrub aws-provided keys from tags opt[:tags] = opt.has_key?(:tags) ? opt[:tags].map { |tag| only_keys_matching(tag, %i[key value propagate_at_launch]) } : [] autoscaling.create_auto_scaling_group(opt) end
delete(name)
click to toggle source
# File lib/awful/auto_scaling.rb, line 80 def delete(name) if yes? "Really delete auto-scaling group #{name}?", :yellow autoscaling.delete_auto_scaling_group(auto_scaling_group_name: name) end end
detach(name, *instance_ids)
click to toggle source
# File lib/awful/auto_scaling.rb, line 311 def detach(name, *instance_ids) autoscaling.detach_instances(auto_scaling_group_name: name, instance_ids: instance_ids, should_decrement_desired_capacity: options[:decrement]) end
dump(name)
click to toggle source
# File lib/awful/auto_scaling.rb, line 155 def dump(name) all_matching_asgs(name).map(&:to_hash).output do |asgs| asgs.each do |asg| puts YAML.dump(stringify_keys(asg)) unless options[:quiet] end end end
enter_standby(name, *instance_ids)
click to toggle source
# File lib/awful/auto_scaling.rb, line 406 def enter_standby(name, *instance_ids) autoscaling.enter_standby( auto_scaling_group_name: name, instance_ids: instance_ids, should_decrement_desired_capacity: options[:decrement] ) end
exit_standby(name, *instance_ids)
click to toggle source
# File lib/awful/auto_scaling.rb, line 415 def exit_standby(name, *instance_ids) autoscaling.exit_standby(auto_scaling_group_name: name, instance_ids: instance_ids) end
instance_lifecycle_state(*instance_ids)
click to toggle source
# File lib/awful/auto_scaling.rb, line 52 def instance_lifecycle_state(*instance_ids) autoscaling.describe_auto_scaling_instances(instance_ids: instance_ids).auto_scaling_instances.map(&:lifecycle_state) end
instances(*names)
click to toggle source
# File lib/awful/auto_scaling.rb, line 89 def instances(*names) instances = asg_instances(*names) ## make extra call to get asg name as part of object if options[:describe] instances = autoscaling.describe_auto_scaling_instances(instance_ids: instances.map(&:instance_id)).auto_scaling_instances end instances.output do |list| if options[:long] print_table list.map { |i| [ i.instance_id, options[:describe] ? i.auto_scaling_group_name : nil, i.availability_zone, color(i.lifecycle_state), color(i.health_status), i.launch_configuration_name, ].compact } else puts list.map(&:instance_id) end end end
ips(*names)
click to toggle source
# File lib/awful/auto_scaling.rb, line 117 def ips(*names) asg_instance_details(*names).output do |instances| if options[:long] print_table instances.map { |i| [ i.public_ip_address, i.private_ip_address, i.instance_id, i.image_id, i.instance_type, i.placement.availability_zone, color(i.state.name), i.launch_time ] } else puts instances.map(&:public_ip_address) end end end
launch_configuration(*names)
click to toggle source
# File lib/awful/auto_scaling.rb, line 317 def launch_configuration(*names) autoscaling.describe_auto_scaling_groups( auto_scaling_group_names: names ).map(&:auto_scaling_groups).flatten.each_with_object({}) do |asg, h| h[asg.auto_scaling_group_name] = asg.launch_configuration_name end.output do |hash| if options[:long] print_table hash else puts hash.values end end end
ls(*names)
click to toggle source
# File lib/awful/auto_scaling.rb, line 59 def ls(*names) autoscaling.describe_auto_scaling_groups(auto_scaling_group_names: names).auto_scaling_groups.output do |asgs| if options[:long] print_table asgs.map { |a| [ tag_name(a, '-')[0,40], a.auto_scaling_group_name[0,40], a.launch_configuration_name[0,40], "#{a.instances.length}/#{a.desired_capacity}", "#{a.min_size}-#{a.max_size}", a.availability_zones.map{ |az| az[-1,1] }.sort.join(','), a.created_time ] } else puts asgs.map(&:auto_scaling_group_name) end end end
newest(name)
click to toggle source
return array of instances in auto-scaling group, reverse sorted by age, newest first
# File lib/awful/auto_scaling.rb, line 232 def newest(name) oldest(name).reverse end
old_instances(*names)
click to toggle source
# File lib/awful/auto_scaling.rb, line 338 def old_instances(*names) asgs = autoscaling.describe_auto_scaling_groups(auto_scaling_group_names: names).map(&:auto_scaling_groups).flatten ## get hash of old instances by ASG name olds = asgs.each_with_object({}) do |asg, hash| outdated = asg.instances.select do |instance| instance.launch_configuration_name != asg.launch_configuration_name end hash[asg.auto_scaling_group_name] = outdated unless outdated.empty? end if olds.empty? # noop elsif options[:detach] autoscaling.detach_instances(auto_scaling_group_name: name, instance_ids: olds.values.flatten.map(&:instance_id), should_decrement_desired_capacity: options[:decrement]) elsif options[:deregister] asgs.select do |asg| olds.has_key?(asg.auto_scaling_group_name) end.each do |asg| instance_ids = olds[asg.auto_scaling_group_name].flatten.map(&:instance_id) asg.load_balancer_names.each do |elb_name| say "Deregistering #{instance_ids.join(',')} from ELB #{elb_name}", :yellow elb.deregister_instances_from_load_balancer(load_balancer_name: elb_name, instances: instance_ids.map { |id| {instance_id: id} }) end end elsif options[:terminate] olds.values.flatten.map do |instance| autoscaling.terminate_instance_in_auto_scaling_group(instance_id: instance.instance_id, should_decrement_desired_capacity: options[:decrement] && true) instance.instance_id end.output { |ids| say("Terminated: #{ids.join(',')}", :yellow) } elsif options[:groups] puts olds.keys elsif options[:long] print_table olds.map { |asg, ins| ins.map { |i| [i.instance_id, asg, i.launch_configuration_name] }.flatten } else puts olds.values.flatten.map(&:instance_id) end olds end
oldest(name)
click to toggle source
return array of instances in auto-scaling group sorted by age
# File lib/awful/auto_scaling.rb, line 220 def oldest(name) instance_ids = autoscaling.describe_auto_scaling_instances.map(&:auto_scaling_instances).flatten.select do |instance| instance.auto_scaling_group_name == name end.map(&:instance_id) if instance_ids.empty? [] else ec2.describe_instances(instance_ids: instance_ids).map(&:reservations).flatten.map(&:instances).flatten.sort_by(&:launch_time) end end
processes()
click to toggle source
# File lib/awful/auto_scaling.rb, line 273 def processes autoscaling.describe_scaling_process_types.processes.map(&:process_name).sort.output do |procs| puts procs end end
resume(name, *procs)
click to toggle source
# File lib/awful/auto_scaling.rb, line 296 def resume(name, *procs) if procs.empty? autoscaling.resume_processes(auto_scaling_group_name: name) else autoscaling.resume_processes(auto_scaling_group_name: name, scaling_processes: procs) end end
ssh(name, *args)
click to toggle source
# File lib/awful/auto_scaling.rb, line 135 def ssh(name, *args) instances = asg_instance_details(name) ## filter by list of instance id patterns if options[:instances] instances.select! do |i| options[:instances].map{ |pattern| i.instance_id.match(pattern) }.any? end end ips = instances.map(&:public_ip_address) num = options[:all] ? ips.count : options[:number].to_i login_name = options[:login_name] ? "-l #{options[:login_name]}" : '' ips.last(num).each do |ip| puts ip if options[:verbose] system "ssh #{login_name} #{ip} #{Array(args).join(' ')}" end end
stop(name, num = 1)
click to toggle source
# File lib/awful/auto_scaling.rb, line 263 def stop(name, num = 1) ins = options[:newest] ? newest(name) : oldest(name) ins.first(num.to_i).map(&:instance_id).output do |ids| if yes? "Really stop #{num} instances: #{ids.join(',')}?", :yellow ec2.stop_instances(instance_ids: ids) end end end
suspend(name, *procs)
click to toggle source
# File lib/awful/auto_scaling.rb, line 281 def suspend(name, *procs) if options[:list] autoscaling.describe_auto_scaling_groups( auto_scaling_group_names: Array(name) ).map(&:auto_scaling_groups).flatten.first.suspended_processes.output do |list| print_table list.map{ |proc| [ proc.process_name, proc.suspension_reason] } end elsif procs.empty? autoscaling.suspend_processes(auto_scaling_group_name: name) else autoscaling.suspend_processes(auto_scaling_group_name: name, scaling_processes: procs) end end
terminate(name, num = 1)
click to toggle source
# File lib/awful/auto_scaling.rb, line 242 def terminate(name, num = 1) ins = options[:newest] ? newest(name) : oldest(name) num = ins.length if options[:all] # all instances if requested if ins.empty? say 'No instances to terminate.', :green else ids = ins.first(num.to_i).map(&:instance_id) if yes? "Really terminate #{num} instances: #{ids.join(',')}?", :yellow ids.each do |id| puts "Terminating instance: #{id}" autoscaling.terminate_instance_in_auto_scaling_group(instance_id: id, should_decrement_desired_capacity: options[:decrement] && true) end else puts 'Nothing terminated' end end end
update(name, file = nil)
click to toggle source
# File lib/awful/auto_scaling.rb, line 188 def update(name, file = nil) opt = load_cfg(options, file) ## allow matching by group name or name tag, but ensure we get only one asgs = all_matching_asgs(name) if asgs.length < 1 warn "no match for #{name}" return elsif asgs.length > 1 warn "ambiguous match for #{name}:", asgs.map(&:auto_scaling_group_name) return end ## cleanup the group options opt[:auto_scaling_group_name] = asgs.first.auto_scaling_group_name opt = remove_empty_strings(opt) ## update the group whitelist = %i[auto_scaling_group_name launch_configuration_name min_size max_size desired_capacity default_cooldown availability_zones health_check_type health_check_grace_period placement_group vpc_zone_identifier termination_policies ] autoscaling.update_auto_scaling_group(only_keys_matching(opt, whitelist)) ## update any tags if opt[:tags] tags = opt[:tags].map { |tag| tag.merge(resource_id: name, resource_type: 'auto-scaling-group') } autoscaling.create_or_update_tags(tags: tags) end end
wait(*instance_ids)
click to toggle source
# File lib/awful/auto_scaling.rb, line 397 def wait(*instance_ids) until instance_lifecycle_state(*instance_ids).all?{ |s| s == options[:state] } puts "waiting for #{instance_ids.count} instances to enter state #{options[:state]}" unless options[:quiet] sleep options[:period] end end