rubber 3.1.0 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4949f1406f5da62d1236bf1757dcf5a70e262094
4
+ data.tar.gz: 1b8dc7e8d6a18880408f5b1017d845f5ea4ef272
5
+ SHA512:
6
+ metadata.gz: b3aadb75637b09101862f6f118a37ee0c9349944416aca49fad689eacf6e6b493d98fbb2abec1a15abc593ada43239284afa7cd544f844165269c3681be08651
7
+ data.tar.gz: f61a46a4d8923082c1c4610bf6f45bba4b0ec0734657d6f8b1764b2d31b2529e8774499937bedf45b6d150035da7675f4052c5823f6b3b43e250e313a7fddd81
data/CHANGELOG CHANGED
@@ -1,9 +1,18 @@
1
+ 3.2.0 (01/09/2016)
2
+
3
+ New Features:
4
+ ============
5
+
6
+ [core] Added support for AWS VPCs.
7
+ [core] Added support for DigitalOcean v2 API.
8
+
9
+
1
10
  3.1.0 (05/31/2015)
2
11
 
3
12
  Improvements:
4
13
  ============
5
14
 
6
- [core] Removed explicit dependency on 'json' gem. <61db9cc>
15
+ [core] Removed explicit dependency on 'json' gem. <61db9cc>
7
16
  [core] Introduced env.enable_root_login_timeout parameter to configure timeout in enabling root login. <f8d1b65>
8
17
  [passenger] Updated to Passenger 5.0.8. <c4a8261>
9
18
  [passenger_nginx] Updated to Passenger 5.0.8. <c4a8261>
data/Gemfile CHANGED
@@ -4,9 +4,8 @@ gem 'jruby-openssl', :platform => :jruby
4
4
  gem 'unlimited-strength-crypto', :platform => :jruby
5
5
 
6
6
  group :development do
7
- # Need to run off master for tests until updated Digital Ocean mocking
8
- # makes it into a release
9
- gem 'fog', :git => 'https://github.com/fog/fog.git', :branch => 'master'
7
+ gem 'fog', '~> 1.36'
8
+ gem 'mime-types', '2.99'
10
9
  end
11
10
 
12
11
  # Specify your gem's dependencies in rubber.gemspec
@@ -0,0 +1,82 @@
1
+ require 'fog'
2
+ require 'fog/digitalocean/compute_v2'
3
+ require 'fog/digitalocean/requests/compute_v2/create_ssh_key'
4
+ require 'fog/digitalocean/requests/compute_v2/list_ssh_keys'
5
+ require 'fog/digitalocean/requests/compute_v2/delete_ssh_key'
6
+
7
+ module ::Fog
8
+ module Compute
9
+ class DigitalOceanV2
10
+ # Fixes an ssh key creation issue currently in fog 1.35.0
11
+ # This change currently in fog master:
12
+ # https://github.com/fog/fog/pull/3743
13
+ # However, unless it gets backported into 1.x, we'll need this patch until
14
+ # we update fog to 2.x
15
+ class Real
16
+ def create_ssh_key(name, public_key)
17
+ create_options = {
18
+ :name => name,
19
+ :public_key => public_key,
20
+ }
21
+
22
+ encoded_body = Fog::JSON.encode(create_options)
23
+
24
+ request(
25
+ :expects => [201],
26
+ :headers => {
27
+ 'Content-Type' => "application/json; charset=UTF-8",
28
+ },
29
+ :method => 'POST',
30
+ :path => '/v2/account/keys',
31
+ :body => encoded_body,
32
+ )
33
+ end
34
+ end
35
+
36
+ # These mocking improvements are not yet in fog master:
37
+ # https://github.com/fog/fog/pull/3748
38
+ class Mock
39
+ def create_ssh_key(name, public_key)
40
+ response = Excon::Response.new
41
+ response.status = 201
42
+
43
+ data[:ssh_keys] << {
44
+ "id" => Fog::Mock.random_numbers(6).to_i,
45
+ "fingerprint" => (["00"] * 16).join(':'),
46
+ "public_key" => public_key,
47
+ "name" => name
48
+ }
49
+
50
+ response.body ={
51
+ 'ssh_key' => data[:ssh_keys].last
52
+ }
53
+
54
+ response
55
+ end
56
+
57
+ def list_ssh_keys
58
+ response = Excon::Response.new
59
+ response.status = 200
60
+ response.body = {
61
+ "ssh_keys" => data[:ssh_keys],
62
+ "links" => {},
63
+ "meta" => {
64
+ "total" => data[:ssh_keys].count
65
+ }
66
+ }
67
+ response
68
+ end
69
+
70
+ def delete_ssh_key(id)
71
+ self.data[:ssh_keys].select! do |key|
72
+ key["id"] != id
73
+ end
74
+
75
+ response = Excon::Response.new
76
+ response.status = 204
77
+ response
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -5,10 +5,19 @@ module Rubber
5
5
 
6
6
  def self.get_provider(provider, env, capistrano)
7
7
  require "rubber/cloud/#{provider}"
8
- clazz = Rubber::Cloud.const_get(Rubber::Util.camelcase(provider))
9
8
  provider_env = env.cloud_providers[provider]
10
- return clazz.new(provider_env, capistrano)
9
+
10
+ # Check to see if we have a Rubber::Cloud::Provider::Factory class. If
11
+ # not, fall back to Rubber::Cloud::Provider
12
+ begin
13
+ factory = Rubber::Cloud.const_get(Rubber::Util.camelcase(provider))::Factory
14
+ return factory.get_provider(provider_env, capistrano)
15
+ rescue NameError
16
+ clazz = Rubber::Cloud.const_get(Rubber::Util.camelcase(provider))
17
+ return clazz.new(provider_env, capistrano)
18
+ end
11
19
  end
12
20
 
13
21
  end
14
22
  end
23
+
@@ -1,545 +1,18 @@
1
- require 'rubber/cloud/fog'
2
- require 'rubber/cloud/aws_table_store'
3
-
4
1
  module Rubber
5
- module Cloud
6
-
7
- class Aws < Fog
8
-
9
- def initialize(env, capistrano)
10
-
11
- compute_credentials = {
12
- :aws_access_key_id => env.access_key,
13
- :aws_secret_access_key => env.secret_access_key
14
- }
15
-
16
- storage_credentials = {
17
- :provider => 'AWS',
18
- :aws_access_key_id => env.access_key,
19
- :aws_secret_access_key => env.secret_access_key,
20
- :path_style => true
21
- }
22
-
23
- @table_store = ::Fog::AWS::SimpleDB.new(compute_credentials)
24
-
25
- compute_credentials[:region] = env.region
26
- @elb = ::Fog::AWS::ELB.new(compute_credentials)
27
-
28
- compute_credentials[:provider] = 'AWS' # We need to set the provider after the SimpleDB init because it fails if the provider value is specified.
29
-
30
- storage_credentials[:region] = env.region
31
-
32
- env['compute_credentials'] = compute_credentials
33
- env['storage_credentials'] = storage_credentials
34
- super(env, capistrano)
35
- end
36
-
37
- def table_store(table_key)
38
- return Rubber::Cloud::AwsTableStore.new(@table_store, table_key)
39
- end
40
-
41
- def describe_instances(instance_id=nil)
42
- instances = []
43
- opts = {}
44
- opts["instance-id"] = instance_id if instance_id
45
-
46
- response = compute_provider.servers.all(opts)
47
- response.each do |item|
48
- instance = {}
49
- instance[:id] = item.id
50
- instance[:type] = item.flavor_id
51
- instance[:external_host] = item.dns_name
52
- instance[:external_ip] = item.public_ip_address
53
- instance[:internal_host] = item.private_dns_name
54
- instance[:internal_ip] = item.private_ip_address
55
- instance[:state] = item.state
56
- instance[:zone] = item.availability_zone
57
- instance[:provider] = 'aws'
58
- instance[:platform] = item.platform || Rubber::Platforms::LINUX
59
- instance[:root_device_type] = item.root_device_type
60
- instances << instance
61
- end
62
-
63
- return instances
64
- end
65
-
66
- def active_state
67
- 'running'
68
- end
69
-
70
- def stopped_state
71
- 'stopped'
72
- end
73
-
74
- def before_create_instance(instance_alias, role_names)
75
- setup_security_groups(instance_alias, role_names)
76
- end
77
-
78
- def after_create_instance(instance)
79
- # Sometimes tag creation will fail, indicating that the instance doesn't exist yet even though it does. It seems to
80
- # be a propagation delay on Amazon's end, so the best we can do is wait and try again.
81
- Rubber::Util.retry_on_failure(StandardError, :retry_sleep => 1, :retry_count => 120) do
82
- Rubber::Tag::update_instance_tags(instance.name)
83
- end
84
- end
85
-
86
- def after_refresh_instance(instance)
87
- # Sometimes tag creation will fail, indicating that the instance doesn't exist yet even though it does. It seems to
88
- # be a propagation delay on Amazon's end, so the best we can do is wait and try again.
89
- Rubber::Util.retry_on_failure(StandardError, :retry_sleep => 1, :retry_count => 120) do
90
- Rubber::Tag::update_instance_tags(instance.name)
91
- end
92
- end
93
-
94
- def before_stop_instance(instance)
95
- capistrano.fatal "Cannot stop spot instances!" if ! instance.spot_instance_request_id.nil?
96
- capistrano.fatal "Cannot stop instances with instance-store root device!" if (instance.root_device_type != 'ebs')
97
- end
98
-
99
- def before_start_instance(instance)
100
- capistrano.fatal "Cannot start spot instances!" if ! instance.spot_instance_request_id.nil?
101
- capistrano.fatal "Cannot start instances with instance-store root device!" if (instance.root_device_type != 'ebs')
102
- end
103
-
104
- def after_start_instance(instance)
105
- # Re-starting an instance will almost certainly give it a new set of IPs and DNS entries, so refresh the values.
106
- capistrano.rubber.refresh_instance(instance.name)
107
-
108
- # Static IPs, DNS, etc. need to be set up for the started instance.
109
- capistrano.rubber.post_refresh
110
- end
2
+ module Cloud
3
+ module Aws
111
4
 
112
- def create_image(image_name)
5
+ class Factory
6
+ def self.get_provider(provider_env, capistrano)
7
+ require 'rubber/cloud/aws/vpc'
8
+ require 'rubber/cloud/aws/classic'
113
9
 
114
- # validate all needed config set
115
- ["key_file", "pk_file", "cert_file", "account", "secret_access_key", "image_bucket"].each do |k|
116
- raise "Set #{k} in rubber.yml" unless "#{env[k]}".strip.size > 0
10
+ klazz = provider_env.vpc_alias ? Rubber::Cloud::Aws::Vpc : Rubber::Cloud::Aws::Classic
11
+ klazz.new provider_env, capistrano
117
12
  end
118
- raise "create_image can only be called from a capistrano scope" unless capistrano
119
-
120
- ec2_key = env.key_file
121
- ec2_pk = env.pk_file
122
- ec2_cert = env.cert_file
123
-
124
- ec2_key_dest = "/mnt/#{File.basename(ec2_key)}"
125
- ec2_pk_dest = "/mnt/#{File.basename(ec2_pk)}"
126
- ec2_cert_dest = "/mnt/#{File.basename(ec2_cert)}"
127
-
128
- storage(env.image_bucket).ensure_bucket
129
-
130
- capistrano.put(File.read(ec2_key), ec2_key_dest)
131
- capistrano.put(File.read(ec2_pk), ec2_pk_dest)
132
- capistrano.put(File.read(ec2_cert), ec2_cert_dest)
133
-
134
- arch = capistrano.capture("uname -m").strip
135
- arch = case arch when /i\d86/ then "i386" else arch end
136
-
137
- capistrano.sudo_script "create_bundle", <<-CMD
138
- export RUBYLIB=/usr/lib/site_ruby/
139
- unset RUBYOPT
140
- nohup ec2-bundle-vol --batch -d /mnt -k #{ec2_pk_dest} -c #{ec2_cert_dest} -u #{env.account} -p #{image_name} -r #{arch} &> /tmp/ec2-bundle-vol.log &
141
- bg_pid=$!
142
- sleep 1
143
-
144
- echo "Creating image from instance volume..."
145
- while kill -0 $bg_pid &> /dev/null; do
146
- echo -n .
147
- sleep 5
148
- done
149
-
150
- # this returns exit code even if pid has already died, and thus triggers fail fast shell error
151
- wait $bg_pid
152
- CMD
153
-
154
- capistrano.sudo_script "register_bundle", <<-CMD
155
- export RUBYLIB=/usr/lib/site_ruby/
156
- unset RUBYOPT
157
- echo "Uploading image to S3..."
158
- ec2-upload-bundle --batch -b #{env.image_bucket} -m /mnt/#{image_name}.manifest.xml -a #{env.access_key} -s #{env.secret_access_key}
159
- CMD
160
-
161
- image_location = "#{env.image_bucket}/#{image_name}.manifest.xml"
162
- response = compute_provider.register_image(image_name,
163
- "rubber bundled image",
164
- image_location)
165
- return response.body["imageId"]
166
- end
167
-
168
- def destroy_image(image_id)
169
- image = compute_provider.images.get(image_id)
170
- raise "Could not find image: #{image_id}, aborting destroy_image" if image.nil?
171
-
172
- location_parts = image.location.split('/')
173
- bucket = location_parts.first
174
- image_name = location_parts.last.gsub(/\.manifest\.xml$/, '')
175
-
176
- image.deregister
177
-
178
- storage(bucket).walk_tree(image_name) do |f|
179
- f.destroy
180
- end
181
- end
182
-
183
- def describe_load_balancers(name=nil)
184
- lbs = []
185
- response = name.nil? ? @elb.load_balancers.all() : [@elb.load_balancers.get(name)].compact
186
- response.each do |item|
187
- lb = {}
188
- lb[:name] = item.id
189
- lb[:dns_name] = item.dns_name
190
- lb[:zones] = item.availability_zones
191
-
192
- item.listeners.each do |litem|
193
- listener = {}
194
- listener[:protocol] = litem.protocol
195
- listener[:port] = litem.lb_portPort
196
- listener[:instance_port] = litem.instance_port
197
- lb[:listeners] ||= []
198
- lb[:listeners] << listener
199
- end
200
-
201
- lbs << lb
202
- end
203
- return lbs
204
- end
205
-
206
- def describe_availability_zones
207
- zones = []
208
- response = compute_provider.describe_availability_zones()
209
- items = response.body["availabilityZoneInfo"]
210
- items.each do |item|
211
- zone = {}
212
- zone[:name] = item["zoneName"]
213
- zone[:state] =item["zoneState"]
214
- zones << zone
215
- end
216
- return zones
217
- end
218
-
219
- def create_spot_instance_request(spot_price, ami, ami_type, security_groups, availability_zone, fog_options={})
220
- response = compute_provider.spot_requests.create({:price => spot_price,
221
- :image_id => ami,
222
- :flavor_id => ami_type,
223
- :groups => security_groups,
224
- :availability_zone => availability_zone,
225
- :key_name => env.key_name}.merge(Rubber::Util.symbolize_keys(fog_options)))
226
- request_id = response.id
227
- return request_id
228
- end
229
-
230
- def describe_spot_instance_requests(request_id=nil)
231
- requests = []
232
- opts = {}
233
- opts["spot-instance-request-id"] = request_id if request_id
234
- response = compute_provider.spot_requests.all(opts)
235
- response.each do |item|
236
- request = {}
237
- request[:id] = item.id
238
- request[:spot_price] = item.price
239
- request[:state] = item.state
240
- request[:created_at] = item.created_at
241
- request[:type] = item.flavor_id
242
- request[:image_id] = item.image_id
243
- request[:instance_id] = item.instance_id
244
- requests << request
245
- end
246
- return requests
247
- end
248
-
249
- def setup_security_groups(host=nil, roles=[])
250
- rubber_cfg = Rubber::Configuration.get_configuration(Rubber.env)
251
- scoped_env = rubber_cfg.environment.bind(roles, host)
252
- security_group_defns = Hash[scoped_env.security_groups.to_a]
253
-
254
- if scoped_env.auto_security_groups
255
- sghosts = (scoped_env.rubber_instances.collect{|ic| ic.name } + [host]).uniq.compact
256
- sgroles = (scoped_env.rubber_instances.all_roles + roles).uniq.compact
257
- security_group_defns = inject_auto_security_groups(security_group_defns, sghosts, sgroles)
258
- end
259
-
260
- sync_security_groups(security_group_defns)
261
13
  end
262
14
 
263
- def describe_security_groups(group_name=nil)
264
- groups = []
265
-
266
- opts = {}
267
- opts["group-name"] = group_name if group_name
268
- response = compute_provider.security_groups.all(opts)
269
-
270
- response.each do |item|
271
- group = {}
272
- group[:name] = item.name
273
- group[:description] = item.description
274
-
275
- item.ip_permissions.each do |ip_item|
276
- group[:permissions] ||= []
277
- rule = {}
278
-
279
- rule[:protocol] = ip_item["ipProtocol"]
280
- rule[:from_port] = ip_item["fromPort"]
281
- rule[:to_port] = ip_item["toPort"]
282
-
283
- ip_item["groups"].each do |rule_group|
284
- rule[:source_groups] ||= []
285
- source_group = {}
286
- source_group[:account] = rule_group["userId"]
287
-
288
- # Amazon doesn't appear to be returning the groupName value when running in a default VPC. It's possible
289
- # it's only returned for EC2 Classic. This is distinctly in conflict with the API documents and thus
290
- # appears to be a bug on Amazon's end. Nonetheless, we need to handle it because otherwise our security
291
- # group rule matching logic will fail and it messes up our users.
292
- #
293
- # Since every top-level item has both an ID and a name, if we're lacking the groupName we can search
294
- # through the items for the one matching the groupId we have and then use its name value. This should
295
- # represent precisely the same data.
296
- source_group[:name] = if rule_group["groupName"]
297
- rule_group["groupName"]
298
- elsif rule_group["groupId"]
299
- matching_security_group = response.find { |item| item.group_id == rule_group["groupId"] }
300
- matching_security_group ? matching_security_group.name : nil
301
- else
302
- nil
303
- end
304
-
305
- rule[:source_groups] << source_group
306
- end if ip_item["groups"]
307
-
308
- ip_item["ipRanges"].each do |ip_range|
309
- rule[:source_ips] ||= []
310
- rule[:source_ips] << ip_range["cidrIp"]
311
- end if ip_item["ipRanges"]
312
-
313
- group[:permissions] << rule
314
- end
315
-
316
- groups << group
317
- end
318
-
319
- groups
320
- end
321
-
322
- def create_volume(instance, volume_spec)
323
- fog_options = Rubber::Util.symbolize_keys(volume_spec['fog_options'] || {})
324
- volume_data = {
325
- :size => volume_spec['size'], :availability_zone => volume_spec['zone']
326
- }.merge(fog_options)
327
- volume = compute_provider.volumes.create(volume_data)
328
- volume.id
329
- end
330
-
331
- def after_create_volume(instance, volume_id, volume_spec)
332
- # After we create an EBS volume, we need to attach it to the instance.
333
- volume = compute_provider.volumes.get(volume_id)
334
- server = compute_provider.servers.get(instance.instance_id)
335
- volume.device = volume_spec['device']
336
- volume.server = server
337
- end
338
-
339
- def before_destroy_volume(volume_id)
340
- # Before we can destroy an EBS volume, we must detach it from any running instances.
341
- volume = compute_provider.volumes.get(volume_id)
342
- volume.force_detach
343
- end
344
-
345
- def destroy_volume(volume_id)
346
- compute_provider.volumes.get(volume_id).destroy
347
- end
348
-
349
- def describe_volumes(volume_id=nil)
350
- volumes = []
351
- opts = {}
352
- opts[:'volume-id'] = volume_id if volume_id
353
- response = compute_provider.volumes.all(opts)
354
-
355
- response.each do |item|
356
- volume = {}
357
- volume[:id] = item.id
358
- volume[:status] = item.state
359
-
360
- if item.server_id
361
- volume[:attachment_instance_id] = item.server_id
362
- volume[:attachment_status] = item.attached_at ? "attached" : "waiting"
363
- end
364
-
365
- volumes << volume
366
- end
367
-
368
- volumes
369
- end
370
-
371
- # resource_id is any Amazon resource ID (e.g., instance ID or volume ID)
372
- # tags is a hash of tag_name => tag_value pairs
373
- def create_tags(resource_id, tags)
374
- # Tags need to be created individually in fog
375
- tags.each do |k, v|
376
- compute_provider.tags.create(:resource_id => resource_id,
377
- :key => k.to_s, :value => v.to_s)
378
- end
379
- end
380
-
381
- private
382
-
383
- def create_security_group(group_name, group_description)
384
- compute_provider.security_groups.create(:name => group_name, :description => group_description)
385
- end
386
-
387
- def destroy_security_group(group_name)
388
- compute_provider.security_groups.get(group_name).destroy
389
- end
390
-
391
- def add_security_group_rule(group_name, protocol, from_port, to_port, source)
392
- group = compute_provider.security_groups.get(group_name)
393
- opts = {:ip_protocol => protocol || 'tcp'}
394
-
395
- if source.instance_of? Hash
396
- opts[:group] = {source[:account] => source[:name]}
397
- else
398
- opts[:cidr_ip] = source
399
- end
400
-
401
- group.authorize_port_range(from_port.to_i..to_port.to_i, opts)
402
- end
403
-
404
- def remove_security_group_rule(group_name, protocol, from_port, to_port, source)
405
- group = compute_provider.security_groups.get(group_name)
406
- opts = {:ip_protocol => protocol || 'tcp'}
407
-
408
- if source.instance_of? Hash
409
- opts[:group] = {source[:account] => source[:name]}
410
- else
411
- opts[:cidr_ip] = source
412
- end
413
-
414
- group.revoke_port_range(from_port.to_i..to_port.to_i, opts)
415
- end
416
-
417
- def sync_security_groups(groups)
418
- return unless groups
419
-
420
- groups = Rubber::Util::stringify(groups)
421
- groups = isolate_groups(groups)
422
- group_keys = groups.keys.clone()
423
-
424
- # For each group that does already exist in cloud
425
- cloud_groups = describe_security_groups()
426
- cloud_groups.each do |cloud_group|
427
- group_name = cloud_group[:name]
428
-
429
- # skip those groups that don't belong to this project/env
430
- next if env.isolate_security_groups && group_name !~ /^#{isolate_prefix}/
431
-
432
- if group_keys.delete(group_name)
433
- # sync rules
434
- capistrano.logger.debug "Security Group already in cloud, syncing rules: #{group_name}"
435
- group = groups[group_name]
436
-
437
- # convert the special case default rule into what it actually looks like when
438
- # we query ec2 so that we can match things up when syncing
439
- rules = group['rules'].clone
440
- group['rules'].each do |rule|
441
- if [2, 3].include?(rule.size) && rule['source_group_name'] && rule['source_group_account']
442
- rules << rule.merge({'protocol' => 'tcp', 'from_port' => '1', 'to_port' => '65535' })
443
- rules << rule.merge({'protocol' => 'udp', 'from_port' => '1', 'to_port' => '65535' })
444
- rules << rule.merge({'protocol' => 'icmp', 'from_port' => '-1', 'to_port' => '-1' })
445
- rules.delete(rule)
446
- end
447
- end
448
-
449
- rule_maps = []
450
-
451
- # first collect the rule maps from the request (group/user pairs are duplicated for tcp/udp/icmp,
452
- # so we need to do this up frnot and remove duplicates before checking against the local rubber rules)
453
- cloud_group[:permissions].each do |rule|
454
- source_groups = rule.delete(:source_groups)
455
- if source_groups
456
- source_groups.each do |source_group|
457
- rule_map = rule.clone
458
- rule_map.delete(:source_ips)
459
- rule_map[:source_group_name] = source_group[:name]
460
- rule_map[:source_group_account] = source_group[:account]
461
- rule_map = Rubber::Util::stringify(rule_map)
462
- rule_maps << rule_map unless rule_maps.include?(rule_map)
463
- end
464
- else
465
- rule_map = Rubber::Util::stringify(rule)
466
- rule_maps << rule_map unless rule_maps.include?(rule_map)
467
- end
468
- end if cloud_group[:permissions]
469
- # For each rule, if it exists, do nothing, otherwise remove it as its no longer defined locally
470
- rule_maps.each do |rule_map|
471
- if rules.delete(rule_map)
472
- # rules match, don't need to do anything
473
- # logger.debug "Rule in sync: #{rule_map.inspect}"
474
- else
475
- # rules don't match, remove them from cloud and re-add below
476
- answer = nil
477
- msg = "Rule '#{rule_map.inspect}' exists in cloud, but not locally"
478
- if env.prompt_for_security_group_sync
479
- answer = Capistrano::CLI.ui.ask("#{msg}, remove from cloud? [y/N]: ")
480
- else
481
- capistrano.logger.info(msg)
482
- end
483
-
484
- if answer =~ /^y/
485
- rule_map = Rubber::Util::symbolize_keys(rule_map)
486
- if rule_map[:source_group_name]
487
- remove_security_group_rule(group_name, rule_map[:protocol], rule_map[:from_port], rule_map[:to_port], {:name => rule_map[:source_group_name], :account => rule_map[:source_group_account]})
488
- else
489
- rule_map[:source_ips].each do |source_ip|
490
- remove_security_group_rule(group_name, rule_map[:protocol], rule_map[:from_port], rule_map[:to_port], source_ip)
491
- end if rule_map[:source_ips]
492
- end
493
- end
494
- end
495
- end
496
-
497
- rules.each do |rule_map|
498
- # create non-existing rules
499
- capistrano.logger.debug "Missing rule, creating: #{rule_map.inspect}"
500
- rule_map = Rubber::Util::symbolize_keys(rule_map)
501
- if rule_map[:source_group_name]
502
- add_security_group_rule(group_name, rule_map[:protocol], rule_map[:from_port], rule_map[:to_port], {:name => rule_map[:source_group_name], :account => rule_map[:source_group_account]})
503
- else
504
- rule_map[:source_ips].each do |source_ip|
505
- add_security_group_rule(group_name, rule_map[:protocol], rule_map[:from_port], rule_map[:to_port], source_ip)
506
- end if rule_map[:source_ips]
507
- end
508
- end
509
- else
510
- # delete group
511
- answer = nil
512
- msg = "Security group '#{group_name}' exists in cloud but not locally"
513
- if env.prompt_for_security_group_sync
514
- answer = Capistrano::CLI.ui.ask("#{msg}, remove from cloud? [y/N]: ")
515
- else
516
- capistrano.logger.debug(msg)
517
- end
518
- destroy_security_group(group_name) if answer =~ /^y/
519
- end
520
- end
521
-
522
- # For each group that didnt already exist in cloud
523
- group_keys.each do |group_name|
524
- group = groups[group_name]
525
- capistrano.logger.debug "Creating new security group: #{group_name}"
526
- # create each group
527
- create_security_group(group_name, group['description'])
528
- # create rules for group
529
- group['rules'].each do |rule_map|
530
- capistrano.logger.debug "Creating new rule: #{rule_map.inspect}"
531
- rule_map = Rubber::Util::symbolize_keys(rule_map)
532
- if rule_map[:source_group_name]
533
- add_security_group_rule(group_name, rule_map[:protocol], rule_map[:from_port], rule_map[:to_port], {:name => rule_map[:source_group_name], :account => rule_map[:source_group_account]})
534
- else
535
- rule_map[:source_ips].each do |source_ip|
536
- add_security_group_rule(group_name, rule_map[:protocol], rule_map[:from_port], rule_map[:to_port], source_ip)
537
- end if rule_map[:source_ips]
538
- end
539
- end
540
- end
541
- end
542
15
  end
543
-
544
16
  end
545
17
  end
18
+