chef-provisioning-aws 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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