zepplen_aws 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,7 @@
1
+ aws-tools
2
+ =========
3
+
4
+ Ruby AWS tools for common tasks
5
+
6
+ Tools
7
+ 1. Automatic Route53 DNS Creation: zepplen_dns
data/bin/zepplen_dns ADDED
@@ -0,0 +1,86 @@
1
+ #!/usr/bin/env ruby1.9.1
2
+ require 'zepplen_aws'
3
+ require 'optparse'
4
+
5
+ options = {}
6
+
7
+ OptionParser.new do |opts|
8
+ opts.banner = "Zepplen Tools: Route53 DNS Update"
9
+
10
+ options[:config_file] = nil
11
+ opts.on('--config-file FILE', 'YAML config file with options to load') do |file|
12
+ options[:config_file] = file
13
+ end
14
+
15
+ options[:aws_access_key_id] = nil
16
+ opts.on('--access-key-id AWS_ACCESS_KEY', 'AWS Access Key ID (Leave blank to use IAM Role auth)') do |key|
17
+ options[:aws_access_key_id] = key
18
+ end
19
+
20
+ options[:aws_secret_access_key] = nil
21
+ opts.on('--secret-access-key AWS_SECRET_KEY', 'AWS Secret Key (Leave blank to use IAM Role auth)') do |key|
22
+ options[:aws_secret_access_key] = key
23
+ end
24
+
25
+ #TODO: Figure out a good way to set this.... aws-sdk does not seem to have a good method at the moment
26
+ options[:aws_region] = nil
27
+ opts.on('--region REGION', 'AWS Region(s) to process') do |region|
28
+ options[:aws_region] = region
29
+ end
30
+
31
+ options[:ec2_tags] = nil
32
+ opts.on('--ec2-tags NAME-1,NAME-2', Array, 'EC2 tag name(s) to derive DNS from (name collisions resolved by order specified)') do |tag|
33
+ options[:ec2_tags] = tag
34
+ end
35
+
36
+ options[:elb] = false
37
+ opts.on('--elb', 'Enalbe ELB DNS (ELB names take precidence over EC2 tags if enabled)') do
38
+ options[:elb] = true
39
+ end
40
+
41
+ options[:public_zones] = nil
42
+ opts.on('--public-zones ZONE_ID,ZONE_NAME-2', Array, 'Rout53 zone to populate with public DNS/IP') do |zone|
43
+ options[:public_zones] = zone
44
+ end
45
+
46
+ options[:private_zones] = nil
47
+ opts.on('--private-zones ZONE_ID,ZONE_NAME-2', Array, 'Rout53 zone to populate with private DNS/IP') do |zone|
48
+ options[:private_zones] = zone
49
+ end
50
+
51
+ options[:public_zone_names] = nil
52
+ opts.on('--public-zone-names ZONE_NAME-1,ZONE_NAME-2', Array, 'Rout53 zone to populate with public DNS/IP (Use --public-zone if multiple zones exist with the same name)') do |zone|
53
+ options[:public_zone_names] = zone
54
+ end
55
+
56
+ options[:private_zone_names] = nil
57
+ opts.on('--private-zone-names ZONE_NAME,ZONE_NAME-2', Array, 'Rout53 zone to populate with private DNS/IP (Use --private-zone if multiple zones exist with the same name)') do |zone|
58
+ options[:private_zone_names] = zone
59
+ end
60
+
61
+ options[:wildcards] = false
62
+ opts.on('--wildcards', 'Also create wildcard DNS entries') do
63
+ options[:wildcards] = true
64
+ end
65
+
66
+ options[:dns_type] = 'CNAME'
67
+ opts.on('--dns-record-type [TYPE]', [:CNAME, :A], 'Type of DNS entry to create (CNAME, ARECORD). ELBs will always get CNAME records') do |type|
68
+ options[:dns_type] = type
69
+ end
70
+
71
+ options[:ttl] = 100
72
+ opts.on('--ttl SECONDS', Integer, 'DNS TTL') do |seconds|
73
+ options[:ttl] = seconds
74
+ end
75
+
76
+ options[:commit] = false
77
+ opts.on('--commit', 'Commit the changes') do
78
+ options[:commit] = true
79
+ end
80
+
81
+ end.parse!
82
+
83
+ #TODO: Add checks to validate the parameters
84
+ ZepplenAWS::Env.options = options
85
+ auto_dns = ZepplenAWS::AutoDNS.new()
86
+ auto_dns.run!
@@ -0,0 +1,236 @@
1
+ #Copyright 2013 Mark Trimmer
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module ZepplenAWS
16
+
17
+ # Utalized by the zepplen_dns script to update Route53 zones with dns entries based on
18
+ # the infrastructure.
19
+ #
20
+ # This class makes heavy use of the Env options to retrieve it's parameters.
21
+ class AutoDNS
22
+ require 'colorize'
23
+
24
+ def initialize()
25
+ @dns_precidence = 0
26
+ @dns_pool = []
27
+ @new_dns_pools = nil
28
+ @live_dns_pools = nil
29
+ @dns_entries = {}
30
+ @dns_entries[:public] = {}
31
+ @dns_entries[:private] = {}
32
+ @zones = {}
33
+ @zones[:public] = {}
34
+ @zones[:private] = {}
35
+ @options = Env::options
36
+ @ec2 = AWS::EC2.new()
37
+ @elb = AWS::ELB.new()
38
+ @route53 = AWS::Route53.new()
39
+ populate_zones()
40
+ end
41
+
42
+ # Process the existing infrusturecte as defined in the Env Options, and update
43
+ # Route 53 with the deltas.
44
+ def run!()
45
+ if(@options[:elb])
46
+ process_elbs()
47
+ end
48
+ next_precience()
49
+ if(@options[:ec2_tags])
50
+ @options[:ec2_tags].each do |tag_name|
51
+ process_ec2_tag_name(tag_name)
52
+ next_precience()
53
+ end
54
+ end
55
+ reduce_dns_pool()
56
+ process_zone_updates()
57
+ end
58
+
59
+ private
60
+
61
+ def populate_zones()
62
+ if(@options[:public_zones])
63
+ zone_id_search(@options[:public_zones], @zones[:public])
64
+ end
65
+ if(@options[:private_zones])
66
+ zone_id_search(@options[:private_zones], @zones[:private])
67
+ end
68
+ if(@options[:private_zone_names])
69
+ zone_name_search(@options[:private_zone_names], @zones[:private])
70
+ end
71
+ end
72
+
73
+ def zone_id_search(zone_ids, zone_pool)
74
+ zone_ids.each do |zone_id|
75
+ zone_pool[zone_id] = @route53.hosted_zones[zone_id]
76
+ end
77
+ end
78
+
79
+ def zone_name_search(zone_names, zone_pool)
80
+ @route53.hosted_zones.each do |hosted_zone|
81
+ zone_names.each do |zone_name|
82
+ if(hosted_zone.name == zone_name)
83
+ zone_pool[hosted_zone.id] = hosted_zone
84
+ end
85
+ end
86
+ end
87
+ end
88
+
89
+ def process_zone_updates()
90
+ @zones.each_pair do |pool_type, zones|
91
+ zones.each_pair do |zone_id, zone|
92
+ process_updates(pool_type, zone)
93
+ end
94
+ end
95
+ end
96
+
97
+ def process_updates(pool_type, zone)
98
+ if(@new_dns_pools.has_key?(pool_type))
99
+ live_zone_pool = {}
100
+ zone.resource_record_sets.each do |record|
101
+ if(record.type == 'CNAME' || record.type == 'A')
102
+ name = record.name.gsub(/^\\052/, '*')
103
+ live_zone_pool[name] = {:name => name, :type => record.type, :ttl => record.ttl , :value => record.resource_records}
104
+ end
105
+ end
106
+ to_add, to_delete = diff_zones(live_zone_pool, @new_dns_pools[pool_type], zone)
107
+ log_actions_to_take(to_add, to_delete, zone, pool_type)
108
+ if(@options[:commit])
109
+ change_batch = ::AWS::Route53::ChangeBatch.new(zone.id)
110
+ to_delete.each_pair do |key, dns_data|
111
+ change_batch << ::AWS::Route53::DeleteRequest.new(dns_data[:name], dns_data[:type], :ttl => dns_data[:ttl], :resource_records => dns_data[:value])
112
+ end
113
+ to_add.each_pair do |key, dns_data|
114
+ change_batch << ::AWS::Route53::CreateRequest.new("#{dns_data[:name]}.#{zone.name}", dns_data[:type], :ttl => dns_data[:ttl], :resource_records => dns_data[:value])
115
+ end
116
+ if(change_batch.length > 0)
117
+ change_batch.call
118
+ end
119
+ else
120
+ puts "Not in --commit mode".red
121
+ end
122
+ end
123
+ end
124
+
125
+ def log_actions_to_take(to_add, to_delete, zone, pool_type)
126
+ puts "Updating #{pool_type.to_s} #{zone.name}:#{zone.id}".green
127
+ if(to_delete.length > 0)
128
+ puts "Deleting:".yellow
129
+ to_delete.each_pair do |key, dns_data|
130
+ puts "\t#{dns_data[:name]}:".yellow
131
+ puts "\t\tType: #{dns_data[:type]}".yellow
132
+ puts "\t\tTTL: #{dns_data[:ttl]}".yellow
133
+ puts "\t\tValue: #{dns_data[:value]}".yellow
134
+ end
135
+ else
136
+ puts "Nothing To Delete".yellow
137
+ end
138
+ if(to_add.length > 0)
139
+ puts "Adding:".light_blue
140
+ to_add.each_pair do |key, dns_data|
141
+ puts "\t#{dns_data[:name]}.#{zone.name}:".light_blue
142
+ puts "\t\tType: #{dns_data[:type]}".light_blue
143
+ puts "\t\tTTL: #{dns_data[:ttl]}".light_blue
144
+ puts "\t\tValue: #{dns_data[:value]}".light_blue
145
+ end
146
+ else
147
+ puts "Nothing To Add".light_blue
148
+ end
149
+ end
150
+
151
+ def diff_zones(live_zone, new_zone, zone)
152
+ live_zone_agg = generate_zone_aggrigate(live_zone, '')
153
+ new_zone_agg = generate_zone_aggrigate(new_zone, ".#{zone.name}")
154
+ to_add_keys = new_zone_agg.keys - live_zone_agg.keys
155
+ to_del_keys = live_zone_agg.keys - new_zone_agg.keys
156
+ to_add = new_zone_agg.select{|k,v| to_add_keys.include?(k)}
157
+ to_del = live_zone_agg.select{|k,v| to_del_keys.include?(k)}
158
+ return [to_add, to_del]
159
+ end
160
+
161
+ def generate_zone_aggrigate(zone, domain)
162
+ zone_agg = {}
163
+ zone.each_pair do |name, zone_data|
164
+ key = "#{name}#{domain}|#{zone_data[:type]}|#{zone_data[:ttl]}|#{zone_data[:value].join(',')}"
165
+ zone_agg[key] = zone_data
166
+ end
167
+ return zone_agg
168
+ end
169
+
170
+ def reduce_dns_pool()
171
+ @new_dns_pools = {}
172
+ @dns_pool.each do |dns_set|
173
+ dns_set.each_pair do |key, dns_entries|
174
+ if(!@new_dns_pools.has_key?(key))
175
+ @new_dns_pools[key] = {}
176
+ end
177
+ dns_entries.each_pair do |name, dns_data|
178
+ if(!@new_dns_pools[key].has_key?(name))
179
+ @new_dns_pools[key][name] = dns_data
180
+ end
181
+ end
182
+ end
183
+ end
184
+ end
185
+
186
+ def next_precience()
187
+ @dns_precidence += 1
188
+ @dns_pool << @dns_entries
189
+ @dns_entries = {}
190
+ @dns_entries[:public] = {}
191
+ @dns_entries[:private] = {}
192
+ end
193
+
194
+ def process_ec2_tag_name(tag_name)
195
+ @ec2.instances.filter('instance-state-name', 'running').each do |instance|
196
+ if(instance.tags.has_key?(tag_name))
197
+ instance.tags[tag_name].split(',').each do |tag_value|
198
+ if(@options[:dns_type] == :CNAME)
199
+ add_dns_entry(tag_value, @options[:dns_type], @options[:ttl], instance.dns_name, instance.private_dns_name, @options[:wildcards])
200
+ else
201
+ add_dns_entry(tag_value, @options[:dns_type], @options[:ttl], instance.ip_address, instance.private_ip_address, @options[:wildcards])
202
+ end
203
+ end
204
+ end
205
+ end
206
+ end
207
+
208
+ def process_elbs()
209
+ @elb.load_balancers.each do |load_balancer|
210
+ add_dns_entry(load_balancer.name, :CNAME, @options[:ttl], load_balancer.dns_name, load_balancer.dns_name, @options[:wildcards])
211
+ end
212
+ end
213
+
214
+ def add_dns_entry(name, type, ttl, public_value, private_value, wildcards)
215
+ name = sanatize_name(name)
216
+ if(@dns_entries[:public].has_key?(name))
217
+ puts "Duplicate name found at same precidence level: #{name}"
218
+ else
219
+ @dns_entries[:public][name] = {:name => name, :type => type.to_s.upcase, :ttl => ttl , :value => [{:value => public_value}]}
220
+ @dns_entries[:private][name] = {:name => name, :type => type.to_s.upcase, :ttl => ttl , :value => [{:value => private_value}]}
221
+ if(wildcards)
222
+ name = "*.#{name}"
223
+ @dns_entries[:public][name] = {:name => name, :type => type.to_s.upcase, :ttl => ttl , :value => [{:value => public_value}]}
224
+ @dns_entries[:private][name] = {:name => name, :type => type.to_s.upcase, :ttl => ttl , :value => [{:value => private_value}]}
225
+ end
226
+ end
227
+ end
228
+
229
+ def sanatize_name(name)
230
+ name = name.gsub(/[^a-zA-Z0-9]+/, '-')
231
+ name = name.gsub(/^-*|-*$/, '')
232
+ return name.downcase
233
+ end
234
+
235
+ end
236
+ end
@@ -0,0 +1,29 @@
1
+ #Copyright 2013 Mark Trimmer
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module ZepplenAWS
16
+ module AWS
17
+ class EC2
18
+
19
+ def initialize()
20
+ @object = ::AWS::EC2.new()
21
+ end
22
+
23
+ def method_missing(method, *args)
24
+ @object.public_send(method, *args)
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,29 @@
1
+ #Copyright 2013 Mark Trimmer
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module ZepplenAWS
16
+ module AWS
17
+ class ELB
18
+
19
+ def initialize()
20
+ @object = ::AWS::ELB.new()
21
+ end
22
+
23
+ def method_missing(method, *args)
24
+ @object.public_send(method, *args)
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,29 @@
1
+ #Copyright 2013 Mark Trimmer
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module ZepplenAWS
16
+ module AWS
17
+ class Route53
18
+
19
+ def initialize()
20
+ @object = ::AWS::Route53.new()
21
+ end
22
+
23
+ def method_missing(method, *args)
24
+ @object.public_send(method, *args)
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,36 @@
1
+ #Copyright 2013 Mark Trimmer
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module ZepplenAWS
16
+
17
+ # Wrapper module for the aws-sdk Gem
18
+ #
19
+ # This module enables pasing authentication from the ENV to the AWS Libs.
20
+ # It also acts as a (very small) layer of abstraction between the 3rd party lib
21
+ # and our code.
22
+ module AWS
23
+ require 'aws-sdk'
24
+
25
+ autoload :EC2, 'zepplen_aws/aws/ec2'
26
+ autoload :ELB, 'zepplen_aws/aws/elb'
27
+ autoload :Route53, 'zepplen_aws/aws/route53'
28
+
29
+ def self.init!()
30
+ ::AWS.config(:access_key_id => Env.options[:aws_access_key_id], :secret_access_key => Env.options[:aws_secret_access_key])
31
+ end
32
+
33
+ end
34
+ end
35
+
36
+ ZepplenAWS::AWS.init!
@@ -0,0 +1,107 @@
1
+ #Copyright 2013 Mark Trimmer
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module ZepplenAWS
16
+
17
+ # = Manage Environment
18
+ #
19
+ # This is a utility class used by the code to manage bassic nessisities of the Environment.
20
+ #
21
+ # == Options
22
+ #
23
+ # This class will automatically load parameters from multiple sources. AWS Keys are attempted
24
+ # to be retrieved from Environmental Variables (AWS_ACCESS_KEY, AWS_SECRET_ACCESS_KEY).
25
+ # We can also load configuration from a YAML file. Our first attempt to locate a config file
26
+ # is by making use of the AWS_CONFIG_FILE Environmental Variable. If the varialbe points to a
27
+ # readable file, we will load configs from that. Beyond that we try to load configs from the
28
+ # following locations in order:
29
+ # 1. $HOME/.zepplen_aws.yaml
30
+ # 2. /etc/zepplen_aws/config.yaml
31
+ #
32
+ # If options are passed to us from another source
33
+ # ZepplenAWS::Env.options = options
34
+ # these options will override any configuration pulled from the ENV or config files.
35
+ #
36
+ # To use AWS IAM Roles for authentication, leave the :aws_access_key_id and :aws_secret_access_key
37
+ # parameter empty.
38
+ class Env
39
+
40
+ # Allows user to inject options into the Environment
41
+ #
42
+ # @example Injecting Options With a Hash
43
+ # ZepplenAWS::Env.options = options
44
+ #
45
+ # @param [Hash] options Options to inject into Environment
46
+ def self.options=(options)
47
+ if(options.has_key?(:config_file) && options[:config_file])
48
+ load_yaml(options[:config_file])
49
+ end
50
+ @options.merge!(options) do |key, old, new|
51
+ new == nil ? old : new
52
+ end
53
+ return nil
54
+ end
55
+
56
+ # Allows user to retrive the current option set
57
+ #
58
+ # @return [Hash] Current Options
59
+ def self.options()
60
+ return @options
61
+ end
62
+
63
+ # Allows user access to single option
64
+ #
65
+ # @param [Any] Key to retrieve
66
+ #
67
+ # @return [Any] Request option
68
+ def self.[](key)
69
+ return @options[key]
70
+ end
71
+
72
+
73
+ # Not intented for general use
74
+ #
75
+ # This function initializes the Env class, and will be called automatically uppon gem inclusion
76
+ def self.init!()
77
+ @options = {}
78
+ if(ENV.has_key?('AWS_ACCESS_KEY'))
79
+ @options[:aws_access_key_id] = ENV['AWS_ACCESS_KEY']
80
+ end
81
+ if(ENV.has_key?('AWS_SECRET_ACCESS_KEY'))
82
+ @options[:aws_secret_access_key] = ENV['AWS_SECRET_ACCESS_KEY']
83
+ end
84
+ if(ENV.has_key?('AWS_CONFIG_FILE') && File.readable?(ENV['AWS_CONFIG_FILE']))
85
+ load_yaml(ENV['AWS_CONFIG_FILE'])
86
+ elsif(File.readable?("#{ENV['HOME']}/.zepplen_aws.yaml"))
87
+ load_yaml("#{ENV['HOME']}/.zepplen_aws.yaml")
88
+ elsif(File.readable?('/etc/zepplen_aws/config.yaml'))
89
+ load_yaml('/etc/zepplen_aws/config.yaml')
90
+ end
91
+ end
92
+
93
+ # Not intended for general use
94
+ #
95
+ # This function import configuration from a YAML file
96
+ def self.load_yaml(file)
97
+ if(!File.readable?(file))
98
+ raise "Config File UnReadable: #{file}"
99
+ end
100
+ options = YAML::load_file(file)
101
+ @options.merge!(options) do |key, old, new|
102
+ new == nil ? old : new
103
+ end
104
+ end
105
+
106
+ end
107
+ end
@@ -0,0 +1,25 @@
1
+ #Copyright 2013 Mark Trimmer
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ require 'yaml'
17
+ require 'colorize'
18
+ require 'zepplen_aws/env'
19
+
20
+ module ZepplenAWS
21
+ autoload :AWS, 'zepplen_aws/aws'
22
+ autoload :AutoDNS, 'zepplen_aws/auto_dns'
23
+ end
24
+
25
+ ZepplenAWS::Env.init!
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zepplen_aws
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2013-04-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: aws-sdk
16
- requirement: &14981440 !ruby/object:Gem::Requirement
16
+ requirement: &17350880 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>'
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 1.8.0
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *14981440
24
+ version_requirements: *17350880
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: colorize
27
- requirement: &14979800 !ruby/object:Gem::Requirement
27
+ requirement: &17350200 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,14 +32,24 @@ dependencies:
32
32
  version: 0.5.8
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *14979800
35
+ version_requirements: *17350200
36
36
  description: AWS tools for common needs
37
37
  email: zepplen.aws@gmail.com
38
- executables: []
38
+ executables:
39
+ - zepplen_dns
39
40
  extensions: []
40
41
  extra_rdoc_files: []
41
- files: []
42
- homepage:
42
+ files:
43
+ - lib/zepplen_aws/env.rb
44
+ - lib/zepplen_aws/aws.rb
45
+ - lib/zepplen_aws/auto_dns.rb
46
+ - lib/zepplen_aws/aws/elb.rb
47
+ - lib/zepplen_aws/aws/ec2.rb
48
+ - lib/zepplen_aws/aws/route53.rb
49
+ - lib/zepplen_aws.rb
50
+ - bin/zepplen_dns
51
+ - README.md
52
+ homepage: https://github.com/zepplen/aws-tools
43
53
  licenses: []
44
54
  post_install_message:
45
55
  rdoc_options: []