chef-provisioning-aws 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +2 -0
  3. data/lib/chef/provider/aws_auto_scaling_group.rb +30 -41
  4. data/lib/chef/provider/aws_dhcp_options.rb +70 -0
  5. data/lib/chef/provider/aws_ebs_volume.rb +182 -34
  6. data/lib/chef/provider/aws_eip_address.rb +63 -60
  7. data/lib/chef/provider/aws_key_pair.rb +18 -27
  8. data/lib/chef/provider/aws_launch_configuration.rb +50 -0
  9. data/lib/chef/provider/aws_route_table.rb +122 -0
  10. data/lib/chef/provider/aws_s3_bucket.rb +42 -49
  11. data/lib/chef/provider/aws_security_group.rb +252 -59
  12. data/lib/chef/provider/aws_sns_topic.rb +10 -26
  13. data/lib/chef/provider/aws_sqs_queue.rb +16 -38
  14. data/lib/chef/provider/aws_subnet.rb +85 -32
  15. data/lib/chef/provider/aws_vpc.rb +163 -23
  16. data/lib/chef/provisioning/aws_driver.rb +18 -1
  17. data/lib/chef/provisioning/aws_driver/aws_provider.rb +206 -0
  18. data/lib/chef/provisioning/aws_driver/aws_resource.rb +186 -0
  19. data/lib/chef/provisioning/aws_driver/aws_resource_with_entry.rb +114 -0
  20. data/lib/chef/provisioning/aws_driver/driver.rb +317 -255
  21. data/lib/chef/provisioning/aws_driver/resources.rb +8 -5
  22. data/lib/chef/provisioning/aws_driver/super_lwrp.rb +45 -0
  23. data/lib/chef/provisioning/aws_driver/version.rb +1 -1
  24. data/lib/chef/resource/aws_auto_scaling_group.rb +15 -13
  25. data/lib/chef/resource/aws_dhcp_options.rb +57 -0
  26. data/lib/chef/resource/aws_ebs_volume.rb +20 -22
  27. data/lib/chef/resource/aws_eip_address.rb +50 -25
  28. data/lib/chef/resource/aws_image.rb +20 -0
  29. data/lib/chef/resource/aws_instance.rb +20 -0
  30. data/lib/chef/resource/aws_internet_gateway.rb +16 -0
  31. data/lib/chef/resource/aws_key_pair.rb +6 -10
  32. data/lib/chef/resource/aws_launch_configuration.rb +15 -0
  33. data/lib/chef/resource/aws_load_balancer.rb +16 -0
  34. data/lib/chef/resource/aws_network_interface.rb +16 -0
  35. data/lib/chef/resource/aws_route_table.rb +76 -0
  36. data/lib/chef/resource/aws_s3_bucket.rb +8 -18
  37. data/lib/chef/resource/aws_security_group.rb +49 -19
  38. data/lib/chef/resource/aws_sns_topic.rb +14 -15
  39. data/lib/chef/resource/aws_sqs_queue.rb +16 -14
  40. data/lib/chef/resource/aws_subnet.rb +87 -17
  41. data/lib/chef/resource/aws_vpc.rb +137 -15
  42. data/spec/integration/aws_security_group_spec.rb +55 -0
  43. data/spec/spec_helper.rb +8 -2
  44. data/spec/support/aws_support.rb +211 -0
  45. metadata +33 -10
  46. data/lib/chef/provider/aws_launch_config.rb +0 -43
  47. data/lib/chef/provider/aws_provider.rb +0 -22
  48. data/lib/chef/provisioning/aws_driver/aws_profile.rb +0 -73
  49. data/lib/chef/resource/aws_launch_config.rb +0 -14
  50. data/lib/chef/resource/aws_resource.rb +0 -10
  51. data/spec/chef_zero_rspec_helper.rb +0 -8
  52. data/spec/unit/provider/aws_subnet_spec.rb +0 -67
  53. data/spec/unit/resource/aws_subnet_spec.rb +0 -23
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3e941203fbc66689312f07ace28e6ea90413c25b
4
- data.tar.gz: fd09857eee368a41188c6c36084aacf061b31eef
3
+ metadata.gz: 1e2131f19428e227cac159a6380060b30a02b3c4
4
+ data.tar.gz: 1df8021af60fd98b0495e4f09c2d1254fd5800e5
5
5
  SHA512:
6
- metadata.gz: 8421e20240201c3c8e66a03017d700dbdb91c669a092793b003ba5ea24234449ebe8c5c4f9517c6c943ecfd1eb5ad138279fc5548045babb004fbf2455c2ca02
7
- data.tar.gz: 08802b5ba314ce4840c4ef883164877c57291a98ae1d76720fff5c58d8e4308adfbb5bb1479d77bc46a3525fd9a5ccad99fc643db317a9b92c71806550cb889f
6
+ metadata.gz: 50f7f3d1749f8f2a95430e1d489446b40bf7b58c94d212258fbb005b0c5ffd53c2fcc355632640f362868de86a46e93b7110ce7bb31d8e7c50004e0f6dd1ce59
7
+ data.tar.gz: 5c7ae1a4bb3abfe55533b177ee02695c198ca9322b698f2869bffbdee13b49ddd6f740681c246c784e177983b1edcb0fc5aec65d33e5a191a49eb4055f3cc5c5
data/Rakefile CHANGED
@@ -7,4 +7,6 @@ task :default => :spec
7
7
  desc "Run specs"
8
8
  RSpec::Core::RakeTask.new(:spec) do |spec|
9
9
  spec.pattern = 'spec/**/*_spec.rb'
10
+ # TODO add back integration tests whenever we have strategy for keys
11
+ spec.exclude_pattern = 'spec/integration/**/*_spec.rb'
10
12
  end
@@ -1,51 +1,40 @@
1
- require 'chef/provider/aws_provider'
2
-
3
- class Chef::Provider::AwsAutoScalingGroup < Chef::Provider::AwsProvider
4
- action :create do
5
- if existing_group.nil?
6
- auto_scaling_opts = {
7
- :launch_configuration => new_resource.launch_config,
8
- :min_size => new_resource.min_size,
9
- :max_size => new_resource.max_size,
10
- :availability_zones => availability_zones
11
- }
12
-
13
- auto_scaling_opts[:desired_capacity] = new_resource.desired_capacity if new_resource.desired_capacity
14
- auto_scaling_opts[:load_balancers] = new_resource.load_balancers if new_resource.load_balancers
15
-
16
- converge_by "Creating new Auto Scaling group #{new_resource.name} in #{new_driver.aws_config.region}" do
17
- @existing_group = new_driver.auto_scaling.groups.create(
18
- new_resource.name,
19
- auto_scaling_opts
20
- )
21
-
22
- new_resource.save
23
- end
24
- end
25
- end
1
+ require 'chef/provisioning/aws_driver/aws_provider'
2
+ require 'set'
26
3
 
27
- action :delete do
28
- if existing_group
29
- converge_by "Deleting Auto Scaling group #{new_resource.name} in #{new_driver.aws_config.region}" do
30
- existing_group.delete!
31
- end
32
- end
4
+ class Chef::Provider::AwsAutoScalingGroup < Chef::Provisioning::AWSDriver::AWSProvider
5
+
6
+ protected
33
7
 
34
- new_resource.delete
8
+ def create_aws_object
9
+ converge_by "create new Auto Scaling Group #{new_resource.name} in #{region}" do
10
+ options = desired_options.dup
11
+ options[:min_size] ||= 1
12
+ options[:max_size] ||= 1
13
+
14
+ new_resource.driver.auto_scaling.groups.create( new_resource.name, options )
15
+ end
35
16
  end
36
17
 
37
- def availability_zones
38
- @availability_zones ||= new_driver.ec2.availability_zones.reduce([]) { |result, az| result << az }
18
+ def update_aws_object(group)
19
+ # TODO add updates for group
39
20
  end
40
21
 
41
- def existing_group
42
- @existing_group ||= begin
43
- eg = new_driver.auto_scaling.groups[new_resource.name]
44
- eg.exists? ? eg : nil
45
- end
22
+ def destroy_aws_object(group)
23
+ converge_by "delete Auto Scaling Group #{new_resource.name} in #{region}" do
24
+ group.delete!
25
+ end
46
26
  end
47
27
 
48
- def id
49
- new_resource.name
28
+ def desired_options
29
+ @desired_options ||= begin
30
+ options = new_resource.options
31
+ %w(launch_configuration min_size max_size availability_zones desired_capacity load_balancers).each do |var|
32
+ var = var.to_sym
33
+ value = new_resource.public_send(var)
34
+ options[var] = value if value
35
+ end
36
+ AWSResource.lookup_options(options, resource: new_resource)
37
+ end
50
38
  end
39
+
51
40
  end
@@ -0,0 +1,70 @@
1
+ require 'chef/provisioning/aws_driver/aws_provider'
2
+
3
+ class Chef::Provider::AwsDhcpOptions < Chef::Provisioning::AWSDriver::AWSProvider
4
+ protected
5
+
6
+ def create_aws_object
7
+ options = desired_options
8
+ if options.empty?
9
+ options[:domain_name_servers] = "AmazonProvidedDNS"
10
+ end
11
+
12
+ converge_by "create new dhcp_options #{new_resource.name} in #{region}" do
13
+ dhcp_options = new_resource.driver.ec2.dhcp_options.create(options)
14
+ dhcp_options.tags['Name'] = new_resource.name
15
+ dhcp_options
16
+ end
17
+ end
18
+
19
+ def update_aws_object(dhcp_options)
20
+ # Verify unmodifiable attributes of existing dhcp_options
21
+ config = dhcp_options.configuration
22
+ differing_options = desired_options.select { |name, value| config[name] != value }
23
+ if !differing_options.empty?
24
+ old_dhcp_options = dhcp_options
25
+ # Report what we are trying to change ...
26
+ action_handler.report_progress "update #{new_resource.to_s}"
27
+ differing_options.each do |name, value|
28
+ action_handler.report_progress " set #{name} to #{value.inspect} (was #{config.has_key?(name) ? config[name].inspect : "not set"})"
29
+ end
30
+
31
+ # create new dhcp_options
32
+ if action_handler.should_perform_actions
33
+ dhcp_options = AWS.ec2(config: dhcp_options.config).dhcp_options.create(config.merge(desired_options))
34
+ end
35
+ action_handler.report_progress "create new dhcp_options #{dhcp_options.id} with new attributes in #{region}"
36
+
37
+ # attach dhcp_options to existing vpcs
38
+ old_dhcp_options.vpcs.each do |vpc|
39
+ action_handler.perform_action "attach new dhcp_options #{dhcp_options.id} to vpc #{vpc.id}" do
40
+ vpc.dhcp_options = dhcp_options
41
+ end
42
+ end
43
+
44
+ # delete old dhcp_options
45
+ action_handler.perform_action "delete old dhcp_options #{old_dhcp_options.id}" do
46
+ old_dhcp_options.delete
47
+ end
48
+
49
+ [ :replaced_aws_object, dhcp_options ]
50
+ end
51
+ end
52
+
53
+ def destroy_aws_object(dhcp_options)
54
+ converge_by "delete dhcp_options #{new_resource.name} in #{region}" do
55
+ dhcp_options.delete
56
+ end
57
+ end
58
+
59
+ private
60
+
61
+ def desired_options
62
+ desired_options = {}
63
+ %w(domain_name domain_name_servers ntp_servers netbios_name_servers netbios_node_type).each do |attr|
64
+ attr = attr.to_sym
65
+ value = new_resource.public_send(attr)
66
+ desired_options[attr] = value unless value.nil?
67
+ end
68
+ Chef::Provisioning::AWSDriver::AWSResource.lookup_options(desired_options, resource: new_resource)
69
+ end
70
+ end
@@ -1,59 +1,207 @@
1
- require 'chef/provider/aws_provider'
1
+ require 'chef/provisioning/aws_driver/aws_provider'
2
2
  require 'cheffish'
3
3
  require 'date'
4
+ require 'retryable'
4
5
 
5
- class Chef::Provider::AwsEbsVolume < Chef::Provider::AwsProvider
6
+ class Chef::Provider::AwsEbsVolume < Chef::Provisioning::AWSDriver::AWSProvider
7
+ class VolumeNotFoundError < RuntimeError
8
+ def initialize(new_resource)
9
+ super("#{new_resource} does not exist!")
10
+ end
11
+ end
6
12
 
7
- action :create do
8
- if existing_volume == nil
9
- converge_by "Creating new EBS volume #{fqn} in #{new_driver.aws_config.region}" do
13
+ class VolumeStatusTimeoutError < TimeoutError
14
+ def initialize(new_resource, initial_status, expected_status)
15
+ super("timed out waiting for #{new_resource} status to change from #{initial_status} to #{expected_status}!")
16
+ end
17
+ end
10
18
 
11
- ebs = new_driver.ec2.volumes.create(
12
- :availability_zone => new_resource.availability_zone,
13
- :size => new_resource.size.to_i
14
- )
15
- ebs.tags['Name'] = fqn
19
+ class VolumeInvalidStatusError < RuntimeError
20
+ def initialize(new_resource, status)
21
+ super("#{new_resource} is in #{status} state!")
22
+ end
23
+ end
16
24
 
17
- new_resource.created_at DateTime.now.to_s
18
- new_resource.volume_id ebs.id
25
+ def action_create
26
+ volume = super
19
27
 
20
- end
21
- else
22
- new_resource.volume_id existing_volume.id
28
+ if !new_resource.machine.nil?
29
+ update_attachment(volume)
23
30
  end
31
+ end
24
32
 
25
- new_resource.save
33
+ protected
34
+
35
+ def create_aws_object
36
+ volume = nil
37
+ converge_by "create new #{new_resource} in #{region}" do
38
+ volume = new_resource.driver.ec2.volumes.create(initial_options)
39
+ volume.tags['Name'] = new_resource.name
40
+ end
41
+
42
+ converge_by "wait for new #{new_resource} in #{region} to become available" do
43
+ wait_for_volume_status(volume, :available)
44
+ volume
45
+ end
26
46
  end
27
47
 
28
- action :delete do
29
- if existing_volume
30
- converge_by "Deleting EBS volume #{fqn} in #{new_driver.aws_config.region}" do
31
- existing_volume.delete
48
+ def update_aws_object(volume)
49
+ if initial_options.has_key?(:availability_zone)
50
+ if initial_options[:availability_zone] != volume.availability_zone_name
51
+ raise "#{new_resource}.availability_zone is #{new_resource.availability_zone}, but actual volume has availability_zone_name set to #{volume.availability_zone_name}. Cannot be modified!"
52
+ end
53
+ end
54
+ if initial_options.has_key?(:size)
55
+ if initial_options[:size] != volume.size
56
+ raise "#{new_resource}.size is #{new_resource.size}, but actual volume has size set to #{volume.size}. Cannot be modified!"
57
+ end
58
+ end
59
+ if initial_options.has_key?(:snapshot)
60
+ if initial_options[:snapshot] != volume.snapshot.id
61
+ raise "#{new_resource}.snapshot is #{new_resource.snapshot}, but actual volume has snapshot set to #{volume.snapshot.id}. Cannot be modified!"
62
+ end
63
+ end
64
+ if initial_options.has_key?(:iops)
65
+ if initial_options[:iops] != volume.iops
66
+ raise "#{new_resource}.iops is #{new_resource.iops}, but actual volume has iops set to #{volume.iops}. Cannot be modified!"
67
+ end
68
+ end
69
+ if initial_options.has_key?(:volume_type)
70
+ if initial_options[:volume_type] != volume.type
71
+ raise "#{new_resource}.volume_type is #{new_resource.volume_type}, but actual volume has type set to #{volume.type}. Cannot be modified!"
32
72
  end
33
73
  end
74
+ if initial_options.has_key?(:encrypted)
75
+ if initial_options[:encrypted] != !!volume.encrypted
76
+ raise "#{new_resource}.encrypted is #{new_resource.encrypted}, but actual volume has encrypted set to #{volume.encrypted}. Cannot be modified!"
77
+ end
78
+ end
79
+ end
34
80
 
35
- new_resource.delete
81
+ def destroy_aws_object(volume)
82
+ detach(volume) if volume.status == :in_use
83
+ delete(volume)
84
+ end
85
+
86
+ private
87
+
88
+ def expected_instance
89
+ if !defined?(@expected_instance)
90
+ if new_resource.machine == false
91
+ @expected_instance = nil
92
+ else
93
+ @expected_instance = Chef::Resource::AwsInstance.get_aws_object(new_resource.machine, resource: new_resource)
94
+ end
95
+ end
96
+ @expected_instance
36
97
  end
37
98
 
99
+ def initial_options
100
+ @initial_options ||= begin
101
+ options = {}
102
+ options[:availability_zone] = new_resource.availability_zone if !new_resource.availability_zone.nil?
103
+ options[:size] = new_resource.size if !new_resource.size.nil?
104
+ options[:snapshot_id] = new_resource.snapshot if !new_resource.snapshot.nil?
105
+ options[:iops] = new_resource.iops if !new_resource.iops.nil?
106
+ options[:volume_type] = new_resource.volume_type if !new_resource.volume_type.nil?
107
+ options[:encrypted] = new_resource.encrypted if !new_resource.encrypted.nil?
108
+ options[:encrypted] = !!options[:encrypted] if !options[:encrypted].nil?
38
109
 
39
- def existing_volume
40
- @existing_volume ||= new_resource.volume_id == nil ? nil : begin
41
- Chef::Log.debug("Loading volume #{new_resource.volume_id}")
42
- volume = new_driver.ec2.volumes[new_resource.volume_id]
43
- if [:deleted, :deleting, :error].include? volume.status
44
- nil
110
+ AWSResource.lookup_options(options, resource: new_resource)
111
+ end
112
+ end
113
+
114
+ def update_attachment(volume)
115
+ status = volume.status
116
+ #
117
+ # If we were told to attach the volume to a machine, do so
118
+ #
119
+ if expected_instance.is_a?(AWS::EC2::Instance)
120
+ case status
121
+ when :in_use
122
+ # We don't want to attempt to reattach to the same instance and device
123
+ attachment = current_attachment(volume)
124
+ if attachment.instance != expected_instance || attachment.device != new_resource.device
125
+ detach(volume)
126
+ attach(volume)
127
+ end
128
+ when :available
129
+ attach(volume)
130
+ when nil
131
+ raise VolumeNotFoundError.new(new_resource)
45
132
  else
46
- Chef::Log.debug("Found EBS volume #{volume.inspect}")
47
- volume
133
+ raise VolumeInvalidStatusError.new(new_resource, status)
134
+ end
135
+
136
+ #
137
+ # If we were told to set the machine to false, detach it.
138
+ #
139
+ else
140
+ case status
141
+ when nil
142
+ Chef::Log.warn VolumeNotFoundError.new(new_resource)
143
+ when :in_use
144
+ detach(volume)
48
145
  end
49
- rescue => e
50
- Chef::Log.error("Error looking for EBS volume: #{e}")
51
- nil
146
+ end
147
+ volume
148
+ end
149
+
150
+ def wait_for_volume_status(volume, expected_status)
151
+ initial_status = volume.status
152
+ log_callback = proc {
153
+ Chef::Log.info("waiting for #{new_resource} status to change to #{expected_status}...")
154
+ }
155
+
156
+ Retryable.retryable(:tries => 30, :sleep => 2, :on => VolumeStatusTimeoutError, :ensure => log_callback) do
157
+ raise VolumeStatusTimeoutError.new(new_resource, initial_status, expected_status) if volume.status != expected_status
158
+ end
159
+ end
160
+
161
+ def detach(volume)
162
+ attachment = current_attachment(volume)
163
+ instance = attachment.instance
164
+ device = attachment.device
165
+
166
+ converge_by "detach #{new_resource} from #{new_resource.machine} (#{instance.instance_id})" do
167
+ volume.detach_from(instance, device)
168
+ end
169
+
170
+ converge_by "wait for #{new_resource} to detach" do
171
+ wait_for_volume_status(volume, :available)
172
+ volume
173
+ end
174
+ end
175
+
176
+ def attach(volume)
177
+ converge_by "attach #{new_resource} to #{new_resource.machine} (#{expected_instance.instance_id}) to device #{new_resource.device}" do
178
+ volume.attach_to(expected_instance, new_resource.device)
179
+ end
180
+
181
+ converge_by "wait for #{new_resource} to attach" do
182
+ wait_for_volume_status(volume, :in_use)
183
+ volume
52
184
  end
53
185
  end
54
186
 
55
- def id
56
- new_resource.volume_name
187
+ def current_attachment(volume)
188
+ volume.attachments.first
57
189
  end
58
190
 
191
+ def delete(volume)
192
+ converge_by "delete #{new_resource} in #{region}" do
193
+ volume.delete
194
+ end
195
+
196
+ converge_by "wait for #{new_resource} in #{region} to delete" do
197
+ log_callback = proc {
198
+ Chef::Log.info('waiting for volume to delete...')
199
+ }
200
+
201
+ Retryable.retryable(:tries => 30, :sleep => 2, :on => VolumeStatusTimeoutError, :ensure => log_callback) do
202
+ raise VolumeStatusTimeoutError.new(new_resource, 'exists', 'deleted') if volume.exists?
203
+ end
204
+ volume
205
+ end
206
+ end
59
207
  end
@@ -1,85 +1,88 @@
1
- require 'chef/provider/aws_provider'
1
+ require 'chef/provisioning/aws_driver/aws_provider'
2
+ require 'chef/resource/aws_instance'
2
3
  require 'chef/provisioning/machine_spec'
3
4
  require 'cheffish'
4
5
 
5
- class Chef::Provider::AwsEipAddress < Chef::Provider::AwsProvider
6
+ class Chef::Provider::AwsEipAddress < Chef::Provisioning::AWSDriver::AWSProvider
6
7
 
7
- action :create do
8
- if existing_ip == nil
9
- converge_by "Creating new EIP address in #{new_driver.aws_config.region}" do
10
- eip = new_driver.ec2.elastic_ips.create :vpc => new_resource.associate_to_vpc
11
- new_resource.public_ip eip.public_ip
12
- new_resource.domain eip.domain
13
- new_resource.instance_id eip.instance_id
14
- end
15
- else
16
- new_resource.public_ip existing_ip.public_ip
17
- new_resource.domain existing_ip.domain
18
- new_resource.instance_id existing_ip.instance_id
8
+ def action_create
9
+ elastic_ip = super
10
+
11
+ if !new_resource.machine.nil?
12
+ update_association(elastic_ip)
19
13
  end
20
- new_resource.save
21
14
  end
22
15
 
23
- action :delete do
24
- if existing_ip
25
- converge_by "Deleting EIP Address #{new_resource.name} in #{new_driver.aws_config.region}" do
26
- #if it's attached to something in a vpc, disassociate first
27
- if existing_ip.instance_id != nil && existing_ip.domain == 'vpc'
28
- existing_ip.disassociate
16
+ protected
17
+
18
+ def create_aws_object
19
+ converge_by "create new EIP address in #{region}" do
20
+ associate_to_vpc = new_resource.associate_to_vpc
21
+ if associate_to_vpc.nil?
22
+ if desired_instance.is_a?(AWS::EC2::Instance)
23
+ associate_to_vpc = !!desired_instance.vpc_id
24
+ Chef::Log.debug "Since associate_to_vpc is not specified and instance #{new_resource.machine} (#{desired_instance.id}) and #{associate_to_vpc ? "is" : "is not"} in a VPC, setting associate_to_vpc to #{associate_to_vpc}."
29
25
  end
30
- existing_ip.delete
31
- new_resource.delete
32
26
  end
27
+ new_resource.driver.ec2.elastic_ips.create vpc: new_resource.associate_to_vpc
33
28
  end
34
29
  end
35
30
 
36
- action :associate do
37
- converge_by "Associating EIP Address #{new_resource.name} in #{new_driver.aws_config.region}" do
38
- if existing_ip == nil
39
- action_create
40
- end
41
- eip = new_driver.ec2.elastic_ips[new_resource.public_ip]
42
- begin
43
- spec = Chef::Provisioning::ChefMachineSpec.get(new_resource.machine)
44
- if spec == nil
45
- Chef::Application.fatal!("Could not find machine #{new_resource.machine}")
46
- else
47
- eip.associate :instance => spec.location['instance_id']
48
- end
49
- new_resource.instance_id eip.instance_id
50
- rescue => e
51
- Chef::Application.fatal!("Error Associating EIP: #{e}")
31
+ def update_aws_object(elastic_ip)
32
+ if !new_resource.associate_to_vpc.nil?
33
+ if !!new_resource.associate_to_vpc != !!elastic_ip.vpc?
34
+ raise "#{new_resource.to_s}.associate_to_vpc = #{new_resource.associate_to_vpc}, but actual IP address has vpc? set to #{elastic_ip.vpc?}. Cannot be modified!"
52
35
  end
53
- new_resource.save
54
36
  end
55
37
  end
56
38
 
57
- action :disassociate do
58
- converge_by "Disassociating EIP Address #{new_resource.name} in #{new_driver.aws_config.region}" do
59
- begin
60
- if existing_ip != nil
61
- existing_ip.disassociate
62
- new_resource.instance_id nil
63
- new_resource.save
64
- else
65
- Chef::Log.warn("No EIP found to disassociate")
66
- end
67
- rescue => e
68
- Chef::Application.fatal!("Error Disassociating EIP: #{e}")
39
+ def destroy_aws_object(elastic_ip)
40
+ #if it's attached to something in a vpc, disassociate first
41
+ if elastic_ip.instance_id != nil && elastic_ip.domain == 'vpc'
42
+ converge_by "dissociate Elastic IP Address #{new_resource.name} (#{elastic_ip.public_ip}) from #{elastic_ip.instance_id}" do
43
+ elastic_ip.disassociate
69
44
  end
70
45
  end
46
+ converge_by "delete Elastic IP Address #{new_resource.name} (#{elastic_ip.public_ip}) in #{region}" do
47
+ elastic_ip.delete
48
+ end
71
49
  end
72
50
 
73
- def existing_ip
74
- new_resource.hydrate
75
- @existing_ip ||= new_resource.public_ip == nil ? nil : begin
76
- eip = new_driver.ec2.elastic_ips[new_resource.public_ip]
77
- eip
78
- rescue => e
79
- Chef::Application.fatal!("Error looking for EIP Address: #{e}")
80
- nil
51
+ private
52
+
53
+ def desired_instance
54
+ if !defined?(@desired_instance)
55
+ if new_resource.machine == false
56
+ @desired_instance = false
57
+ else
58
+ @desired_instance = Chef::Resource::AwsInstance.get_aws_object(new_resource.machine, resource: new_resource)
59
+ end
81
60
  end
61
+ @desired_instance
82
62
  end
83
63
 
64
+ def update_association(elastic_ip)
65
+ #
66
+ # If we were told to associate the IP to a machine, do so
67
+ #
68
+ if desired_instance.is_a?(AWS::EC2::Instance)
69
+ if desired_instance.id != elastic_ip.instance_id
70
+ converge_by "associate Elastic IP Address #{new_resource.name} (#{elastic_ip.public_ip}) with #{new_resource.machine} (#{desired_instance.id})" do
71
+ elastic_ip.associate instance: desired_instance.id
72
+ end
73
+ end
74
+
75
+ #
76
+ # If we were told to set the association to false, disassociate it.
77
+ #
78
+ else
79
+ if elastic_ip.associated?
80
+ converge_by "disassociate Elastic IP Address #{new_resource.name} (#{elastic_ip.public_ip}) from #{elastic_ip.instance_id} in #{region}" do
81
+ aws_object.disassociate
82
+ end
83
+ end
84
+ end
85
+
86
+ end
84
87
 
85
88
  end