Skip to content
This repository has been archived by the owner on Jun 28, 2019. It is now read-only.

EC2 instance tags are available as parameters #68

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Cap-EC2 changelog

## 1.0.1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can release this separately.


Added the possibility to get any tags defined on EC2 instance as parameters in Capistrano.
Updated AWS-SDK to Ver 2.

## 1.0.0

Cap-EC2 is pretty stable, and the rate of PRs has decreased, so I've
Expand Down Expand Up @@ -28,7 +33,7 @@ decided to bump the version to 1.0.0.

## 0.0.15

* Add `ec2_filter_by_status_ok?` to filter out instances that aren't returning `OK`
* Add `ec2_filter_by_status_ok?` to filter out instances that aren't returning `OK`
for their EC2 status checks. [@tomconroy](https://github.com/tomconroy)

## 0.0.14
Expand Down
2 changes: 2 additions & 0 deletions cap-ec2.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ Gem::Specification.new do |spec|
spec.add_development_dependency "bundler", "~> 1.3"
spec.add_development_dependency "rake"

spec.add_dependency "aws-sdk"
spec.add_dependency "aws-sdk-v1"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We require v2 now in the new versions.

spec.add_dependency "aws-sdk-resources"
spec.add_dependency "capistrano", ">= 3.0"
spec.add_dependency "terminal-table"
spec.add_dependency "colorize"
Expand Down
12 changes: 9 additions & 3 deletions lib/cap-ec2/capistrano.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@ def ec2_handler

def ec2_role(name, options={})
ec2_handler.get_servers_for_role(name).each do |server|
env.role(name, CapEC2::Utils.contact_point(server),
options_with_instance_id(options, server))
env.role(
name,
CapEC2::Utils.contact_point(server),
options_with_instance_id(options, server)
)
end
end

Expand All @@ -32,7 +35,10 @@ def env
private

def options_with_instance_id(options, server)
options.merge({aws_instance_id: server.instance_id})
tags = server[:tag_set].map{ |t| Hash[t[0].downcase.to_sym, t[1]] }.reduce({}, :merge)
options.merge({
aws_instance_id: server[:instance_id],
}).merge(tags)
end

end
Expand Down
51 changes: 35 additions & 16 deletions lib/cap-ec2/ec2-handler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def initialize

def ec2_connect(region=nil)
AWS.start_memoizing
AWS::EC2.new(
AWS::EC2::Client.new(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you change this to be compatible with v2?

access_key_id: fetch(:ec2_access_key_id),
secret_access_key: fetch(:ec2_secret_access_key),
region: region
Expand All @@ -22,23 +22,23 @@ def ec2_connect(region=nil)

def status_table
CapEC2::StatusTable.new(
defined_roles.map {|r| get_servers_for_role(r)}.flatten.uniq {|i| i.instance_id}
defined_roles.map {|r| get_servers_for_role(r)}.flatten.uniq {|i| i[:instance_id]}
)
end

def server_names
puts defined_roles.map {|r| get_servers_for_role(r)}
.flatten
.uniq {|i| i.instance_id}
.map {|i| i.tags["Name"]}
.uniq {|i| i[:instance_id]}
.map {|i| i[:tag_set]["Name"] || i[:instance_id] + ' (Server name not specified)'}
.join("\n")
end

def instance_ids
puts defined_roles.map {|r| get_servers_for_role(r)}
.flatten
.uniq {|i| i.instance_id}
.map {|i| i.instance_id}
.uniq {|i| i[:instance_id]}
.map {|i| i[:instance_id]}
.join("\n")
end

Expand All @@ -60,18 +60,32 @@ def tag(tag_name)

def get_servers_for_role(role)
servers = []
instances = []

@ec2.each do |_, ec2|
instances = ec2.instances
.filter(tag(project_tag), "*#{application}*")
.filter('instance-state-name', 'running')
servers << instances.select do |i|
query = ec2.describe_instances(filters:[
{ name: 'instance-state-name', values: ["running"] },
{ name: "#{tag(project_tag)}", values: ["#{application}"] }
])
query[:reservation_set].each do |reservations|
reservations[:instances_set].each do |instance|
if instance[:tag_set][0]
instance[:tag_set].map!{|sm_h| Hash[sm_h[:key], sm_h[:value]]}
instance[:tag_set] = instance[:tag_set].reduce({}, :merge)
end
instances << instance
end
end

servers = instances.select do |i|
instance_has_tag?(i, roles_tag, role) &&
instance_has_tag?(i, stages_tag, stage) &&
instance_has_tag?(i, project_tag, application) &&
(fetch(:ec2_filter_by_status_ok?) ? instance_status_ok?(i) : true)
end
end
servers.flatten.sort_by {|s| s.tags["Name"] || ''}

servers
end

def get_server(instance_id)
Expand All @@ -83,15 +97,20 @@ def get_server(instance_id)
private

def instance_has_tag?(instance, key, value)
(instance.tags[key] || '').split(',').map(&:strip).include?(value.to_s)
(instance[:tag_set][key] || '').split(',').map(&:strip).include?(value.to_s)
end

def instance_status_ok?(instance)
@ec2.any? do |_, ec2|
response = ec2.client.describe_instance_status(
instance_ids: [instance.id],
filters: [{ name: 'instance-status.status', values: %w(ok) }]
)
response = ec2.describe_instance_status({
instance_ids: [instance[:instance_id]],
filters: [
{
name: 'instance-status.status',
values: %w(ok)
}
]
})
response.data.has_key?(:instance_status_set) && response.data[:instance_status_set].any?
end
end
Expand Down
18 changes: 9 additions & 9 deletions lib/cap-ec2/status-table.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
module CapEC2
class StatusTable
include CapEC2::Utils

def initialize(instances)
@instances = instances
output
end

def header_row
[
bold("Num"),
Expand All @@ -19,7 +19,7 @@ def header_row
bold("Stages")
]
end

def output
table = Terminal::Table.new(
:style => {
Expand All @@ -38,13 +38,13 @@ def output
def instance_to_row(instance, index)
[
sprintf("%02d:", index),
green(instance.tags["Name"] || ''),
red(instance.id),
cyan(instance.instance_type),
green(instance[:tag_set]["Name"] || ''),
red(instance[:instance_id]),
cyan(instance[:instance_type]),
bold(blue(CapEC2::Utils.contact_point(instance))),
magenta(instance.availability_zone),
yellow(instance.tags[roles_tag]),
yellow(instance.tags[stages_tag])
magenta(instance[:placement][:availability_zone]),
yellow(instance[:tag_set][roles_tag]),
yellow(instance[:tag_set][stages_tag])
]
end

Expand Down
3 changes: 1 addition & 2 deletions lib/cap-ec2/utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ def self.contact_point_mapping
def self.contact_point(instance)
ec2_interface = contact_point_mapping[fetch(:ec2_contact_point)]
return instance.send(ec2_interface) if ec2_interface

instance.public_dns_name || instance.public_ip_address || instance.private_ip_address
instance[:dns_name] || instance[:ip_address] || instance[:private_ip_address]
end

def load_config
Expand Down