capify-ec2 1.7.0 → 1.8.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/Changelog.md +11 -0
- data/lib/capify-ec2.rb +19 -2
- data/lib/capify-ec2/capistrano.rb +6 -10
- data/lib/capify-ec2/cloudwatch.rb +69 -0
- data/lib/capify-ec2/version.rb +1 -1
- data/readme.md +19 -5
- metadata +6 -5
data/Changelog.md
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
## 1.8.0.pre (Nov 14, 2014)
|
2
|
+
|
3
|
+
Features:
|
4
|
+
|
5
|
+
- Support for IAM temporary security credentials (thanks jeffdevine).
|
6
|
+
- Added new `ec2:graph` command which shows an enhanced status along with instance CPU utilisation powered by CloudWatch (thanks stuartquin).
|
7
|
+
|
8
|
+
Bugfixes:
|
9
|
+
|
10
|
+
- Fixed issue with chaining multiple roles (thanks marcinc).
|
11
|
+
|
1
12
|
## 1.7.0 (Aug 26, 2014)
|
2
13
|
|
3
14
|
Bugfixes:
|
data/lib/capify-ec2.rb
CHANGED
@@ -1,9 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
1
4
|
require 'rubygems'
|
2
5
|
require 'fog'
|
3
6
|
require 'colored'
|
4
7
|
require 'net/http'
|
5
8
|
require 'net/https'
|
6
9
|
require File.expand_path(File.dirname(__FILE__) + '/capify-ec2/server')
|
10
|
+
require File.expand_path(File.dirname(__FILE__) + '/capify-ec2/cloudwatch')
|
11
|
+
|
7
12
|
|
8
13
|
class CapifyEc2
|
9
14
|
|
@@ -59,12 +64,16 @@ class CapifyEc2
|
|
59
64
|
def security_credentials
|
60
65
|
if @ec2_config[:use_iam_profile]
|
61
66
|
{ :use_iam_profile => true }
|
67
|
+
elsif aws_session_token
|
68
|
+
{ :aws_access_key_id => aws_access_key_id,
|
69
|
+
:aws_secret_access_key => aws_secret_access_key,
|
70
|
+
:aws_session_token => aws_session_token }
|
62
71
|
else
|
63
72
|
{ :aws_access_key_id => aws_access_key_id,
|
64
73
|
:aws_secret_access_key => aws_secret_access_key }
|
65
74
|
end
|
66
75
|
end
|
67
|
-
|
76
|
+
|
68
77
|
def determine_regions()
|
69
78
|
@ec2_config[:aws_params][:regions] || [@ec2_config[:aws_params][:region]]
|
70
79
|
end
|
@@ -77,12 +86,18 @@ class CapifyEc2
|
|
77
86
|
@ec2_config[:aws_secret_access_key] || Fog.credentials[:aws_secret_access_key] || ENV['AWS_SECRET_ACCESS_KEY'] || @ec2_config[:use_iam_profile] || raise("Missing AWS Secret Access Key")
|
78
87
|
end
|
79
88
|
|
80
|
-
def
|
89
|
+
def aws_session_token
|
90
|
+
@ec2_config[:aws_session_token] || Fog.credentials[:aws_session_token] || ENV['AWS_SESSION_TOKEN'] || nil
|
91
|
+
end
|
92
|
+
|
93
|
+
def display_instances(graph: false)
|
81
94
|
unless desired_instances and desired_instances.any?
|
82
95
|
puts "[Capify-EC2] No instances were found using your 'ec2.yml' configuration.".red.bold
|
83
96
|
return
|
84
97
|
end
|
85
98
|
|
99
|
+
cw = CapifyCloudwatch.new(aws_access_key_id, aws_secret_access_key) if graph
|
100
|
+
|
86
101
|
# Set minimum widths for the variable length instance attributes.
|
87
102
|
column_widths = { :name_min => 4, :type_min => 4, :dns_min => 5, :roles_min => @ec2_config[:aws_roles_tag].length, :stages_min => @ec2_config[:aws_stages_tag].length, :options_min => @ec2_config[:aws_options_tag].length }
|
88
103
|
|
@@ -114,6 +129,7 @@ class CapifyEc2
|
|
114
129
|
status_output << @ec2_config[:aws_stages_tag] .ljust( column_widths[:stages] ).bold if stages_present
|
115
130
|
status_output << @ec2_config[:aws_roles_tag] .ljust( column_widths[:roles] ).bold if roles_present
|
116
131
|
status_output << @ec2_config[:aws_options_tag].ljust( column_widths[:options] ).bold if options_present
|
132
|
+
status_output << 'CPU' .ljust( 16 ).bold if graph
|
117
133
|
puts status_output.join(" ")
|
118
134
|
|
119
135
|
desired_instances.each_with_index do |instance, i|
|
@@ -127,6 +143,7 @@ class CapifyEc2
|
|
127
143
|
status_output << (instance.tags[@ec2_config[:aws_stages_tag]] || '').ljust( column_widths[:stages] ).yellow if stages_present
|
128
144
|
status_output << (instance.tags[@ec2_config[:aws_roles_tag]] || '').ljust( column_widths[:roles] ).yellow if roles_present
|
129
145
|
status_output << (instance.tags[@ec2_config[:aws_options_tag]] || '').ljust( column_widths[:options] ).yellow if options_present
|
146
|
+
status_output << cw.get_metric(instance.id, "CPUUtilization").ljust(16) if graph
|
130
147
|
puts status_output.join(" ")
|
131
148
|
end
|
132
149
|
end
|
@@ -14,6 +14,11 @@ Capistrano::Configuration.instance(:must_exist).load do
|
|
14
14
|
capify_ec2.display_instances
|
15
15
|
end
|
16
16
|
|
17
|
+
desc "As status but with CPU usage graphs (slower due to Cloudwatch requests)"
|
18
|
+
task :graph do
|
19
|
+
capify_ec2.display_instances(graph: true)
|
20
|
+
end
|
21
|
+
|
17
22
|
desc "Prints out all ec2 load balancers"
|
18
23
|
task :elbs do
|
19
24
|
capify_ec2.display_elbs
|
@@ -225,7 +230,6 @@ Capistrano::Configuration.instance(:must_exist).load do
|
|
225
230
|
named_instance = capify_ec2.get_instance_by_name(server_name)
|
226
231
|
|
227
232
|
task named_instance.name.to_sym do
|
228
|
-
remove_default_roles
|
229
233
|
server_address = named_instance.contact_point
|
230
234
|
|
231
235
|
if named_instance.respond_to?(:roles)
|
@@ -268,7 +272,6 @@ Capistrano::Configuration.instance(:must_exist).load do
|
|
268
272
|
region_instances.each {|instance| instances << instance} unless region_instances.nil?
|
269
273
|
end
|
270
274
|
task region.to_sym do
|
271
|
-
remove_default_roles
|
272
275
|
instances.each do |instance|
|
273
276
|
define_role(role, instance)
|
274
277
|
end
|
@@ -278,7 +281,6 @@ Capistrano::Configuration.instance(:must_exist).load do
|
|
278
281
|
def define_instance_roles(role, instances)
|
279
282
|
instances.each do |instance|
|
280
283
|
task instance.name.to_sym do
|
281
|
-
remove_default_roles
|
282
284
|
define_role(role, instance)
|
283
285
|
end
|
284
286
|
end
|
@@ -286,7 +288,6 @@ Capistrano::Configuration.instance(:must_exist).load do
|
|
286
288
|
|
287
289
|
def define_role_roles(role, instances)
|
288
290
|
task role[:name].to_sym do
|
289
|
-
remove_default_roles
|
290
291
|
instances.each do |instance|
|
291
292
|
define_role(role, instance)
|
292
293
|
end
|
@@ -326,9 +327,4 @@ Capistrano::Configuration.instance(:must_exist).load do
|
|
326
327
|
"#{singular}s"
|
327
328
|
end
|
328
329
|
end
|
329
|
-
|
330
|
-
def remove_default_roles
|
331
|
-
roles.reject! { true }
|
332
|
-
end
|
333
|
-
|
334
|
-
end
|
330
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
require 'fog'
|
5
|
+
|
6
|
+
class CapifyCloudwatch
|
7
|
+
# Threshold => color
|
8
|
+
# Color is applied if metric exceeds the threshold, KEEP IN ORDER
|
9
|
+
Colors = {
|
10
|
+
0 => :green,
|
11
|
+
70 => :yellow,
|
12
|
+
90 => :red
|
13
|
+
}
|
14
|
+
|
15
|
+
def initialize(key_id, secret)
|
16
|
+
@ticks = %w[▁ ▂ ▃ ▄ ▅ ▆ ▇]
|
17
|
+
@cw = Fog::AWS::CloudWatch.new(:aws_access_key_id => key_id,
|
18
|
+
:aws_secret_access_key => secret)
|
19
|
+
end
|
20
|
+
|
21
|
+
def get_metric(instance_id, metric, hours = 1)
|
22
|
+
range = hours * (60 * 60)
|
23
|
+
time = Time.new
|
24
|
+
start = DateTime.parse((time - range).to_s)
|
25
|
+
finish = DateTime.parse(time.to_s)
|
26
|
+
|
27
|
+
dimensions = [{
|
28
|
+
"Name" => "InstanceId",
|
29
|
+
"Value" => instance_id
|
30
|
+
}]
|
31
|
+
|
32
|
+
result = @cw.get_metric_statistics({'Namespace' => 'AWS/EC2',
|
33
|
+
'MetricName' => metric,
|
34
|
+
'Period' => 120,
|
35
|
+
'Statistics' => ['Average'],
|
36
|
+
'StartTime' => start,
|
37
|
+
'EndTime' => finish,
|
38
|
+
'Dimensions' => dimensions})
|
39
|
+
|
40
|
+
dp = result.body.fetch("GetMetricStatisticsResult", {})["Datapoints"]
|
41
|
+
|
42
|
+
if dp
|
43
|
+
return get_spark_line(dp.map {|x| x["Average"]})
|
44
|
+
end
|
45
|
+
return ""
|
46
|
+
end
|
47
|
+
|
48
|
+
def colorize_output(output, value)
|
49
|
+
colored = output
|
50
|
+
Colors.each do |threshold, color|
|
51
|
+
if value >= threshold
|
52
|
+
colored = output.send(color)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
colored
|
56
|
+
end
|
57
|
+
|
58
|
+
def get_spark_line(values)
|
59
|
+
scale = @ticks.length - 1
|
60
|
+
|
61
|
+
if values and values.count > 0
|
62
|
+
final = values.last.round
|
63
|
+
bar = values.map { |x| @ticks[(x / 100.0 * scale).floor] }.join
|
64
|
+
return colorize_output(bar.rjust(13, @ticks.first) + " #{final}%", final)
|
65
|
+
else
|
66
|
+
""
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/lib/capify-ec2/version.rb
CHANGED
data/readme.md
CHANGED
@@ -72,6 +72,10 @@ Note: `:aws_access_key_id` and `:aws_secret_access_key` are required, unless you
|
|
72
72
|
|
73
73
|
Use this option to use IAM roles for authentication, rather than an access key id and secret access key.
|
74
74
|
|
75
|
+
* :aws_session_token
|
76
|
+
|
77
|
+
If you are an IAM user that only has access to temporary credentials, you can provide your session token here to authenticate.
|
78
|
+
|
75
79
|
|
76
80
|
##### AWS Credentials
|
77
81
|
|
@@ -81,16 +85,18 @@ By default, Capify-EC2 will attempt to use the credentials found in your `ec2.ym
|
|
81
85
|
|
82
86
|
###### Via Fog Configuration
|
83
87
|
|
84
|
-
If you wish, you can have Capify-EC2 use the AWS credentials found in your Fog configuration, instead of instead of specifying `:aws_access_key_id` and `:aws_secret_access_key` in the YML configuration file. Refer to the Fog documentation for details on specifying AWS credentials.
|
88
|
+
If you wish, you can have Capify-EC2 use the AWS credentials found in your Fog configuration, instead of instead of specifying `:aws_access_key_id` and `:aws_secret_access_key` in the YML configuration file. Optionally, if you requires session tokens or federated users, you can set ` :aws_session_token `. Refer to the Fog documentation for details on specifying AWS credentials.
|
85
89
|
|
86
90
|
###### Via Environment Variables
|
87
91
|
|
88
|
-
If you wish, you can define AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY as environment variables, instead of specifying `:aws_access_key_id` and `:aws_secret_access_key` in the YML configuration file.
|
92
|
+
If you wish, you can define AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY as environment variables, instead of specifying `:aws_access_key_id` and `:aws_secret_access_key` in the YML configuration file. Optionally, if you requires session tokens or federated users, you can set the environment variable AWS_SESSION_TOKEN.
|
89
93
|
|
90
94
|
###### Via AWS IAM Roles
|
91
95
|
|
92
96
|
If you have IAM roles set up on your box to allow querying EC2 information you tell Fog to use IAM roles and you will not need to provide any credentials at runtime. For more information on IAM roles read Amazon's [IAM documentation](http://aws.amazon.com/iam/).
|
93
97
|
|
98
|
+
If you are an IAM user that only has access to temporary credentials, you can use `:aws_session_token: "YOUR TOKEN HERE"` to authenticate.
|
99
|
+
|
94
100
|
###### Ordering
|
95
101
|
|
96
102
|
Capify-EC2 will attempt to load your AWS credentials first from the `ec2.yml` configuration file, then from your Fog configuration file, and finally from environment variables. It will display an error if no credentials are found by any of these methods.
|
@@ -550,6 +556,14 @@ The following command will generate a listing of all instances that match your c
|
|
550
556
|
cap ec2:status
|
551
557
|
```
|
552
558
|
|
559
|
+
##### Viewing CPU Utilisation
|
560
|
+
|
561
|
+
The following command will generate an enhanced listing of all instances that match your configuration (projects and roles) as with `ec2:status`, with the addition of CPU utilisation graphs powered by CloudWatch. You will need to ensure your IAM permissions allow this.
|
562
|
+
|
563
|
+
```ruby
|
564
|
+
cap ec2:graph
|
565
|
+
```
|
566
|
+
|
553
567
|
|
554
568
|
#### Viewing ELBs
|
555
569
|
|
@@ -768,10 +782,10 @@ Report Issues/Feature requests on [GitHub Issues](http://github.com/forward/capi
|
|
768
782
|
* Make your feature addition or bug fix.
|
769
783
|
* Add tests for it. This is important so I don't break it in a
|
770
784
|
future version unintentionally.
|
771
|
-
* Commit, do not
|
772
|
-
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
785
|
+
* Commit, do not change the version, or changelog.
|
786
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself so I can ignore it when I pull)
|
773
787
|
* Send me a pull request. Bonus points for topic branches.
|
774
788
|
|
775
789
|
### Copyright
|
776
790
|
|
777
|
-
Copyright (c) 2011, 2012, 2013 Forward. See [LICENSE](https://github.com/forward/capify-ec2/blob/master/LICENSE) for details.
|
791
|
+
Copyright (c) 2011, 2012, 2013, 2014 Forward. See [LICENSE](https://github.com/forward/capify-ec2/blob/master/LICENSE) for details.
|
metadata
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capify-ec2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
5
|
-
prerelease:
|
4
|
+
version: 1.8.0.pre
|
5
|
+
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Noah Cantor
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2014-
|
15
|
+
date: 2014-11-14 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: fog
|
@@ -78,6 +78,7 @@ files:
|
|
78
78
|
- capify-ec2.gemspec
|
79
79
|
- lib/capify-ec2.rb
|
80
80
|
- lib/capify-ec2/capistrano.rb
|
81
|
+
- lib/capify-ec2/cloudwatch.rb
|
81
82
|
- lib/capify-ec2/server.rb
|
82
83
|
- lib/capify-ec2/version.rb
|
83
84
|
- readme.md
|
@@ -97,9 +98,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
97
98
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
99
|
none: false
|
99
100
|
requirements:
|
100
|
-
- - ! '
|
101
|
+
- - ! '>'
|
101
102
|
- !ruby/object:Gem::Version
|
102
|
-
version:
|
103
|
+
version: 1.3.1
|
103
104
|
requirements: []
|
104
105
|
rubyforge_project: capify-ec2
|
105
106
|
rubygems_version: 1.8.23
|