chef-provisioning-aws 1.4.1 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +8 -0
  3. data/README.md +26 -39
  4. data/Rakefile +13 -5
  5. data/lib/chef/provider/aws_iam_instance_profile.rb +60 -0
  6. data/lib/chef/provider/aws_iam_role.rb +98 -0
  7. data/lib/chef/provider/aws_image.rb +1 -1
  8. data/lib/chef/provider/aws_internet_gateway.rb +75 -0
  9. data/lib/chef/provider/aws_route_table.rb +3 -2
  10. data/lib/chef/provider/aws_s3_bucket.rb +4 -1
  11. data/lib/chef/provider/aws_security_group.rb +1 -1
  12. data/lib/chef/provider/aws_vpc.rb +50 -45
  13. data/lib/chef/provisioning/aws_driver.rb +22 -1
  14. data/lib/chef/provisioning/aws_driver/aws_provider.rb +13 -5
  15. data/lib/chef/provisioning/aws_driver/aws_resource.rb +173 -165
  16. data/lib/chef/provisioning/aws_driver/credentials.rb +12 -0
  17. data/lib/chef/provisioning/aws_driver/driver.rb +82 -37
  18. data/lib/chef/provisioning/aws_driver/super_lwrp.rb +56 -43
  19. data/lib/chef/provisioning/aws_driver/version.rb +1 -1
  20. data/lib/chef/resource/aws_dhcp_options.rb +1 -1
  21. data/lib/chef/resource/aws_ebs_volume.rb +1 -1
  22. data/lib/chef/resource/aws_eip_address.rb +1 -1
  23. data/lib/chef/resource/aws_iam_instance_profile.rb +33 -0
  24. data/lib/chef/resource/aws_iam_role.rb +55 -0
  25. data/lib/chef/resource/aws_image.rb +1 -1
  26. data/lib/chef/resource/aws_instance.rb +1 -1
  27. data/lib/chef/resource/aws_internet_gateway.rb +36 -6
  28. data/lib/chef/resource/aws_load_balancer.rb +1 -1
  29. data/lib/chef/resource/aws_network_acl.rb +1 -1
  30. data/lib/chef/resource/aws_network_interface.rb +1 -1
  31. data/lib/chef/resource/aws_route53_hosted_zone.rb +261 -0
  32. data/lib/chef/resource/aws_route53_record_set.rb +162 -0
  33. data/lib/chef/resource/aws_route_table.rb +1 -1
  34. data/lib/chef/resource/aws_security_group.rb +1 -1
  35. data/lib/chef/resource/aws_sns_topic.rb +1 -1
  36. data/lib/chef/resource/aws_subnet.rb +1 -1
  37. data/lib/chef/resource/aws_vpc.rb +1 -1
  38. data/lib/chef/resource/aws_vpc_peering_connection.rb +1 -1
  39. data/spec/aws_support.rb +11 -13
  40. data/spec/aws_support/matchers/create_an_aws_object.rb +7 -1
  41. data/spec/aws_support/matchers/have_aws_object_tags.rb +1 -1
  42. data/spec/aws_support/matchers/match_an_aws_object.rb +7 -1
  43. data/spec/aws_support/matchers/update_an_aws_object.rb +8 -2
  44. data/spec/integration/aws_eip_address_spec.rb +74 -0
  45. data/spec/integration/aws_iam_instance_profile_spec.rb +159 -0
  46. data/spec/integration/aws_iam_role_spec.rb +177 -0
  47. data/spec/integration/aws_internet_gateway_spec.rb +161 -0
  48. data/spec/integration/aws_network_interface_spec.rb +3 -4
  49. data/spec/integration/aws_route53_hosted_zone_spec.rb +522 -0
  50. data/spec/integration/aws_route_table_spec.rb +52 -4
  51. data/spec/integration/aws_s3_bucket_spec.rb +1 -1
  52. data/spec/integration/load_balancer_spec.rb +303 -8
  53. data/spec/integration/machine_batch_spec.rb +1 -0
  54. data/spec/integration/machine_image_spec.rb +32 -17
  55. data/spec/integration/machine_spec.rb +11 -29
  56. data/spec/unit/chef/provisioning/aws_driver/driver_spec.rb +0 -1
  57. data/spec/unit/chef/provisioning/aws_driver/route53_spec.rb +105 -0
  58. metadata +48 -6
@@ -5,7 +5,7 @@ require 'retryable'
5
5
 
6
6
  class Chef::Provider::AwsVpc < Chef::Provisioning::AWSDriver::AWSProvider
7
7
  include Chef::Provisioning::AWSDriver::TaggingStrategy::EC2ConvergeTags
8
-
8
+
9
9
  provides :aws_vpc
10
10
 
11
11
  class NeverObtainedExistence < RuntimeError; end
@@ -134,12 +134,13 @@ class Chef::Provider::AwsVpc < Chef::Provisioning::AWSDriver::AWSProvider
134
134
  # Detach or destroy the internet gateway
135
135
  ig = vpc.internet_gateway
136
136
  if ig
137
- converge_by "detach Internet gateway #{ig.id} in #{region} from #{new_resource.to_s}" do
138
- ig.detach(vpc.id)
139
- end
140
- if ig.tags['OwnedByVPC'] == vpc.id
141
- converge_by "destroy Internet gateway #{ig.id} in #{region} (owned by #{new_resource.to_s})" do
142
- ig.delete
137
+ Cheffish.inline_resource(self, action) do
138
+ aws_internet_gateway ig do
139
+ if ig.tags['OwnedByVPC'] == vpc.id
140
+ action :purge
141
+ else
142
+ action :detach
143
+ end
143
144
  end
144
145
  end
145
146
  end
@@ -179,47 +180,49 @@ class Chef::Provider::AwsVpc < Chef::Provisioning::AWSDriver::AWSProvider
179
180
  def update_internet_gateway(vpc)
180
181
  current_ig = vpc.internet_gateway
181
182
  case new_resource.internet_gateway
182
- when String, Chef::Resource::AwsInternetGateway, AWS::EC2::InternetGateway
183
- new_ig = Chef::Resource::AwsInternetGateway.get_aws_object(new_resource.internet_gateway, resource: new_resource)
184
- if !current_ig
185
- converge_by "attach Internet gateway #{new_resource.internet_gateway} to VPC #{vpc.id}" do
186
- new_ig.attach(vpc.id)
187
- end
188
- elsif current_ig != new_ig
189
- converge_by "replace Internet gateway #{current_ig.id} on VPC #{vpc.id} with new Internet gateway #{new_ig.id}" do
190
- current_ig.detach(vpc.id)
191
- new_ig.attach(vpc.id)
192
- end
193
- if current_ig.tags['OwnedByVPC'] == vpc.id
194
- converge_by "destroy Internet gateway #{current_ig.id} in #{region} (owned by VPC #{vpc.id})" do
195
- current_ig.delete
183
+ when String, Chef::Resource::AwsInternetGateway, AWS::EC2::InternetGateway
184
+ new_ig = Chef::Resource::AwsInternetGateway.get_aws_object(new_resource.internet_gateway, resource: new_resource)
185
+ if !current_ig
186
+ Cheffish.inline_resource(self, action) do
187
+ aws_internet_gateway new_ig do
188
+ vpc vpc.id
189
+ end
196
190
  end
197
- end
198
- end
199
- when true
200
- if !current_ig
201
- converge_by "attach Internet gateway to VPC #{vpc.id}" do
202
- current_ig = AWS.ec2(config: vpc.config).internet_gateways.create
203
- retry_with_backoff(NeverObtainedExistence) do
204
- raise NeverObtainedExistence.new("Internet gateway for VPC #{vpc.id} never obtained existence") unless current_ig.exists?
191
+ elsif current_ig != new_ig
192
+ Cheffish.inline_resource(self, action) do
193
+ aws_internet_gateway current_ig do
194
+ if current_ig.tags['OwnedByVPC'] == vpc.id
195
+ action :destroy
196
+ else
197
+ action :detach
198
+ end
199
+ end
200
+ aws_internet_gateway new_ig do
201
+ vpc vpc.id
202
+ end
205
203
  end
206
- action_handler.report_progress "create Internet gateway #{current_ig.id}"
207
- current_ig.tags['OwnedByVPC'] = vpc.id
208
- action_handler.report_progress "tag Internet gateway #{current_ig.id} as OwnedByVpc: #{vpc.id}"
209
- vpc.internet_gateway = current_ig
210
204
  end
211
- end
212
- when false
213
- if current_ig
214
- converge_by "detach Internet gateway #{current_ig.id} from VPC #{vpc.id}" do
215
- current_ig.detach(vpc.id)
205
+ when true
206
+ if !current_ig
207
+ Cheffish.inline_resource(self, action) do
208
+ aws_internet_gateway "igw-managed-by-#{vpc.id}" do
209
+ vpc vpc.id
210
+ aws_tags 'OwnedByVPC' => vpc.id
211
+ end
212
+ end
216
213
  end
217
- if current_ig.tags['OwnedByVPC'] == vpc.id
218
- converge_by "destroy Internet gateway #{current_ig.id} in #{region} (owned by VPC #{vpc.id})" do
219
- current_ig.delete
214
+ when false
215
+ if current_ig
216
+ Cheffish.inline_resource(self, action) do
217
+ aws_internet_gateway current_ig.id do
218
+ if current_ig.tags['OwnedByVPC'] == vpc.id
219
+ action :destroy
220
+ else
221
+ action :detach
222
+ end
223
+ end
220
224
  end
221
225
  end
222
- end
223
226
  end
224
227
  end
225
228
 
@@ -247,9 +250,11 @@ class Chef::Provider::AwsVpc < Chef::Provisioning::AWSDriver::AWSProvider
247
250
  # creating the VPC
248
251
  main_route_table ||= vpc.route_tables.main_route_table
249
252
  main_routes = new_resource.main_routes
250
- aws_route_table main_route_table.id do
251
- vpc vpc
252
- routes main_routes
253
+ Cheffish.inline_resource(self, action) do
254
+ aws_route_table main_route_table.id do
255
+ vpc vpc
256
+ routes main_routes
257
+ end
253
258
  end
254
259
  main_route_table
255
260
  end
@@ -9,6 +9,8 @@ require "chef/resource/aws_cloudsearch_domain"
9
9
  require "chef/resource/aws_dhcp_options"
10
10
  require "chef/resource/aws_ebs_volume"
11
11
  require "chef/resource/aws_eip_address"
12
+ require "chef/resource/aws_iam_role"
13
+ require "chef/resource/aws_iam_instance_profile"
12
14
  require "chef/resource/aws_image"
13
15
  require "chef/resource/aws_instance"
14
16
  require "chef/resource/aws_internet_gateway"
@@ -17,10 +19,10 @@ require "chef/resource/aws_launch_configuration"
17
19
  require "chef/resource/aws_load_balancer"
18
20
  require "chef/resource/aws_network_acl"
19
21
  require "chef/resource/aws_network_interface"
20
- require "chef/resource/aws_route_table"
21
22
  require "chef/resource/aws_rds_instance"
22
23
  require "chef/resource/aws_rds_subnet_group"
23
24
  require "chef/resource/aws_route_table"
25
+ require "chef/resource/aws_route53_hosted_zone"
24
26
  require "chef/resource/aws_s3_bucket"
25
27
  require "chef/resource/aws_security_group"
26
28
  require "chef/resource/aws_server_certificate"
@@ -30,3 +32,22 @@ require "chef/resource/aws_subnet"
30
32
  require "chef/resource/aws_vpc"
31
33
  require "chef/resource/aws_vpc_peering_connection"
32
34
 
35
+ module NoResourceCloning
36
+ def prior_resource
37
+ if resource_class <= Chef::Provisioning::AWSDriver::AWSResource
38
+ Chef::Log.debug "Canceling resource cloning for #{resource_class}"
39
+ nil
40
+ else
41
+ super
42
+ end
43
+ end
44
+ def emit_cloned_resource_warning; end
45
+ def emit_harmless_cloning_debug; end
46
+ end
47
+
48
+ # Chef 12.2 changed `load_prior_resource` logic to be in the Chef::ResourceBuilder class
49
+ # but that class only exists in 12.2 and up
50
+ if defined? Chef::ResourceBuilder
51
+ # Ruby 2.0.0 has prepend as a protected method
52
+ Chef::ResourceBuilder.send(:prepend, NoResourceCloning)
53
+ end
@@ -269,11 +269,11 @@ class AWSProvider < Chef::Provider::LWRPBase
269
269
  sleep = opts[:sleep] || 5
270
270
 
271
271
  Retryable.retryable(:tries => tries, :sleep => sleep) do |retries, exception|
272
- action_handler.report_progress "waited #{retries*sleep}/#{tries*sleep}s for #{aws_object.id} state to change to #{expected_responses.inspect}..."
273
- Chef::Log.debug("Current exception is #{exception.inspect}")
272
+ action_handler.report_progress "waited #{retries*sleep}/#{tries*sleep}s for <#{aws_object.class}:#{aws_object.id}>##{query_method} state to change to #{expected_responses.inspect}..."
273
+ Chef::Log.debug("Current exception in wait_for is #{exception.inspect}")
274
274
  begin
275
275
  current_response = aws_object.send(query_method)
276
- Chef::Log.debug("Current response from [#{query_method}] is #{current_response}")
276
+ Chef::Log.debug("Current response in wait_for from [#{query_method}] is #{current_response}")
277
277
  unless expected_responses.include?(current_response)
278
278
  raise StatusTimeoutError.new(aws_object, current_response, expected_responses)
279
279
  end
@@ -285,8 +285,16 @@ class AWSProvider < Chef::Provider::LWRPBase
285
285
  # Retry a block with an doubling backoff time (maximum wait of 10 seconds).
286
286
  # @param retry_on [Exception] An exception to retry on, defaults to RuntimeError
287
287
  #
288
- def retry_with_backoff(retry_on = RuntimeError, &block)
289
- Retryable.retryable(:tries => 10, :sleep => lambda { |n| [2**n, 16].min }, :on => retry_on, &block)
288
+ def self.retry_with_backoff(*retry_on)
289
+ retry_on ||= [RuntimeError]
290
+ Retryable.retryable(:tries => 10, :sleep => lambda { |n| [2**n, 16].min }, :on => retry_on) do |retries, exception|
291
+ Chef::Log.debug("Current exception in retry_with_backoff is #{exception.inspect}")
292
+ yield
293
+ end
294
+ end
295
+
296
+ def retry_with_backoff(*retry_on, &block)
297
+ self.class.retry_with_backoff(*retry_on, &block)
290
298
  end
291
299
 
292
300
  end
@@ -5,199 +5,207 @@ require 'chef/provisioning/chef_managed_entry_store'
5
5
  require 'chef/provisioning/aws_driver/aws_taggable'
6
6
 
7
7
  # Common AWS resource - contains metadata that all AWS resources will need
8
- module Chef::Provisioning::AWSDriver
9
- class AWSResource < Chef::Provisioning::AWSDriver::SuperLWRP
10
- actions :create, :destroy, :purge, :nothing
11
- default_action :create
12
-
13
- def initialize(name, run_context=nil)
14
- name = name.public_send(self.class.aws_sdk_class_id) if name.is_a?(self.class.aws_sdk_class)
15
- super
16
- if run_context
17
- driver run_context.chef_provisioning.current_driver
18
- chef_server run_context.cheffish.current_chef_server
8
+ class Chef
9
+ module Provisioning
10
+ module AWSDriver
11
+ class AWSResource < Chef::Provisioning::AWSDriver::SuperLWRP
12
+ actions :create, :destroy, :purge, :nothing
13
+ default_action :create
14
+
15
+ def initialize(name, run_context=nil)
16
+ name = name.public_send(self.class.aws_sdk_class_id) if name.is_a?(self.class.aws_sdk_class)
17
+ super
18
+ if run_context
19
+ driver run_context.chef_provisioning.current_driver
20
+ chef_server run_context.cheffish.current_chef_server
21
+ end
19
22
  end
20
- end
21
23
 
22
- # Backwards compatibility for action :destroy
23
- def action(*args)
24
- if args == [ :delete ]
25
- super(:destroy)
26
- else
27
- super
24
+ # Backwards compatibility for action :destroy
25
+ def action(*args)
26
+ if args == [ :delete ]
27
+ super(:destroy)
28
+ else
29
+ super
30
+ end
28
31
  end
29
- end
30
32
 
31
- # In Chef < 12.4 we need to define this method. In > 12.4 this method is
32
- # already defined for us so we don't need to overwrite it.
33
- unless defined?(:action=)
34
- def action=(value)
35
- action(value)
33
+ # In Chef < 12.4 we need to define this method. In > 12.4 this method is
34
+ # already defined for us so we don't need to overwrite it.
35
+ unless defined?(:action=)
36
+ def action=(value)
37
+ action(value)
38
+ end
36
39
  end
37
- end
38
40
 
39
- #
40
- # The desired driver.
41
- #
42
- attribute :driver, kind_of: Chef::Provisioning::Driver,
43
- coerce: (proc do |value|
44
- case value
45
- when nil, Chef::Provisioning::Driver
46
- value
47
- else
48
- run_context.chef_provisioning.driver_for(value)
49
- end
50
- end)
51
-
52
- #
53
- # The Chef server on which any IDs should be looked up.
54
- #
55
- attribute :chef_server, kind_of: Hash
56
-
57
- #
58
- # The managed entry store.
59
- #
60
- attribute :managed_entry_store, kind_of: Chef::Provisioning::ManagedEntryStore,
61
- lazy_default: proc { Chef::Provisioning::ChefManagedEntryStore.new(chef_server) }
62
-
63
- #
64
- # Get the current AWS object. This should return the aws_object even if it has
65
- # a status like 'deleted' or 'inactive'. If there is an aws_object, we return it.
66
- # Callers will need to check the status if they care.
67
- #
68
- def aws_object
69
- raise NotImplementedError, :aws_object
70
- end
41
+ #
42
+ # The desired driver.
43
+ #
44
+ attribute :driver, kind_of: Chef::Provisioning::Driver,
45
+ coerce: (proc do |value|
46
+ case value
47
+ when nil, Chef::Provisioning::Driver
48
+ value
49
+ else
50
+ run_context.chef_provisioning.driver_for(value)
51
+ end
52
+ end)
53
+
54
+ #
55
+ # The Chef server on which any IDs should be looked up.
56
+ #
57
+ attribute :chef_server, kind_of: Hash
58
+
59
+ #
60
+ # The managed entry store.
61
+ #
62
+ attribute :managed_entry_store, kind_of: Chef::Provisioning::ManagedEntryStore,
63
+ default: lazy { Chef::Provisioning::ChefManagedEntryStore.new(chef_server) }
64
+
65
+ #
66
+ # Get the current AWS object. This should return the aws_object even if it has
67
+ # a status like 'deleted' or 'inactive'. If there is an aws_object, we return it.
68
+ # Callers will need to check the status if they care.
69
+ #
70
+ def aws_object
71
+ raise NotImplementedError, :aws_object
72
+ end
71
73
 
72
- def aws_object_id
73
- @aws_object_id ||= begin
74
- o = aws_object
75
- o.public_send(self.class.aws_sdk_class_id) if o
74
+ def aws_object_id
75
+ @aws_object_id ||= begin
76
+ o = aws_object
77
+ o.public_send(self.class.aws_sdk_class_id) if o
78
+ end
76
79
  end
77
- end
78
80
 
79
- #
80
- # Look up an AWS options list, translating standard names using the appropriate
81
- # classes.
82
- #
83
- # For example, `load_balancer_options` is passed into `lookup_options`, and if
84
- # it looks like this: `{ subnets: `[ 'subnet1', 'subnet2' ] }`, then
85
- # `AWSResource.lookup_options` will translate each ID with
86
- # `AwsSubnet.get_aws_object('subnet1')`, which supports Chef names
87
- # (`mysubnet`) as well as AWS subnet Ids (`subnet-1234abcd`) or AWS objects
88
- # (`AWS::EC2::Subnet`).
89
- #
90
- # Keys that represent non-AWS-objects (such as `timeout`) are left alone.
91
- #
92
- def self.lookup_options(options, **handler_options)
93
- options = options.dup
94
- options.each do |name, value|
95
- if name.to_s.end_with?('s')
96
- handler_name = :"#{name[0..-2]}"
97
- if aws_option_handlers[handler_name]
98
- options[name] = [options[name]].flatten.map { |value| aws_option_handlers[handler_name].get_aws_object_id(value, **handler_options) }
99
- end
100
- else
101
- if aws_option_handlers[name]
102
- options[name] = aws_option_handlers[name].get_aws_object_id(value, **handler_options)
81
+ #
82
+ # Look up an AWS options list, translating standard names using the appropriate
83
+ # classes.
84
+ #
85
+ # For example, `load_balancer_options` is passed into `lookup_options`, and if
86
+ # it looks like this: `{ subnets: `[ 'subnet1', 'subnet2' ] }`, then
87
+ # `AWSResource.lookup_options` will translate each ID with
88
+ # `AwsSubnet.get_aws_object('subnet1')`, which supports Chef names
89
+ # (`mysubnet`) as well as AWS subnet Ids (`subnet-1234abcd`) or AWS objects
90
+ # (`AWS::EC2::Subnet`).
91
+ #
92
+ # Keys that represent non-AWS-objects (such as `timeout`) are left alone.
93
+ #
94
+ def self.lookup_options(options = Hash.new, **handler_options)
95
+ options = options.dup
96
+ options.each do |name, value|
97
+ if name.to_s.end_with?('s')
98
+ handler_name = :"#{name[0..-2]}"
99
+ if aws_option_handlers[handler_name]
100
+ options[name] = [options[name]].flatten.map { |value| aws_option_handlers[handler_name].get_aws_object_id(value, **handler_options) }
101
+ end
102
+ else
103
+ if aws_option_handlers[name]
104
+ options[name] = aws_option_handlers[name].get_aws_object_id(value, **handler_options)
105
+ end
103
106
  end
104
107
  end
108
+ options
105
109
  end
106
- options
107
- end
108
110
 
109
- def self.get_aws_object(value, resource: nil, run_context: nil, driver: nil, managed_entry_store: nil, required: true)
110
- return nil if value.nil?
111
+ def self.get_aws_object(value, resource: nil, run_context: nil, driver: nil, managed_entry_store: nil, required: true)
112
+ return nil if value.nil?
111
113
 
112
- if resource
113
- run_context ||= resource.run_context
114
- driver ||= resource.driver
115
- managed_entry_store ||= resource.managed_entry_store
116
- end
117
- if value.is_a?(self)
118
- resource = value
119
- else
120
- resource = new(value, run_context)
121
- resource.driver driver if driver
122
- resource.managed_entry_store managed_entry_store if managed_entry_store
123
- end
114
+ if resource
115
+ run_context ||= resource.run_context
116
+ driver ||= resource.driver
117
+ managed_entry_store ||= resource.managed_entry_store
118
+ end
119
+ if value.is_a?(self)
120
+ resource = value
121
+ else
122
+ resource = new(value, run_context)
123
+ resource.driver driver if driver
124
+ resource.managed_entry_store managed_entry_store if managed_entry_store
125
+ end
124
126
 
125
- result = resource.aws_object
126
- if required && result.nil?
127
- raise "#{self}[#{value}] does not exist!"
127
+ result = resource.aws_object
128
+ if required && result.nil?
129
+ raise "#{self}[#{value}] does not exist!"
130
+ end
131
+ result
128
132
  end
129
- result
130
- end
131
133
 
132
- def self.get_aws_object_id(value, **options)
133
- aws_object = get_aws_object(value, **options)
134
- aws_object.public_send(aws_sdk_class_id) if aws_object
135
- end
136
-
137
- protected
138
-
139
- NOT_PASSED = Object.new
140
-
141
- def self.aws_sdk_type(sdk_class,
142
- option_names: nil,
143
- option_name: NOT_PASSED,
144
- load_provider: true,
145
- id: :name,
146
- aws_id_prefix: nil)
147
- self.resource_name = convert_to_snake_case(self.name.split('::')[-1])
148
- @aws_sdk_class = sdk_class
149
- @aws_sdk_class_id = id
150
- @aws_id_prefix = aws_id_prefix
151
-
152
- # Go ahead and require the provider since we're here anyway ...
153
- require "chef/provider/#{resource_name}" if load_provider
134
+ def self.get_aws_object_id(value, **options)
135
+ aws_object = get_aws_object(value, **options)
136
+ aws_object.public_send(aws_sdk_class_id) if aws_object
137
+ end
154
138
 
155
- option_name = :"#{resource_name[4..-1]}" if option_name == NOT_PASSED
156
- @aws_sdk_option_name = option_name
139
+ protected
140
+
141
+ # This supports the introduction of the NOT_PASSED chef constant
142
+ # in chef 12.5
143
+ # TODO remove when we make 12.5 and higher a dependency
144
+ NOT_PASSED = Object.new unless defined?(NOT_PASSED)
145
+
146
+ def self.aws_sdk_type(sdk_class,
147
+ option_names: nil,
148
+ option_name: NOT_PASSED,
149
+ load_provider: true,
150
+ id: :name,
151
+ aws_id_prefix: nil)
152
+ self.resource_name = convert_to_snake_case(self.name.split('::')[-1])
153
+ @aws_sdk_class = sdk_class
154
+ @aws_sdk_class_id = id
155
+ @aws_id_prefix = aws_id_prefix
156
+
157
+ # Go ahead and require the provider since we're here anyway ...
158
+ require "chef/provider/#{resource_name}" if load_provider
159
+
160
+ option_name = :"#{resource_name[4..-1]}" if option_name == NOT_PASSED
161
+ @aws_sdk_option_name = option_name
162
+
163
+ option_names ||= begin
164
+ option_names = []
165
+ option_names << aws_sdk_option_name
166
+ option_names << :"#{option_name}_#{aws_sdk_class_id}" if aws_sdk_class_id
167
+ option_names
168
+ end
169
+ option_names.each do |option_name|
170
+ aws_option_handlers[option_name] = self
171
+ end
157
172
 
158
- option_names ||= begin
159
- option_names = []
160
- option_names << aws_sdk_option_name
161
- option_names << :"#{option_name}_#{aws_sdk_class_id}" if aws_sdk_class_id
162
- option_names
163
- end
164
- option_names.each do |option_name|
165
- aws_option_handlers[option_name] = self
173
+ name = self.name.split('::')[-1]
174
+ eval("Chef::Provisioning::AWSDriver::Resources::#{name} = self", binding, __FILE__, __LINE__)
166
175
  end
167
176
 
168
- name = self.name.split('::')[-1]
169
- eval("Chef::Provisioning::AWSDriver::Resources::#{name} = self", binding, __FILE__, __LINE__)
170
- end
177
+ def self.aws_sdk_class
178
+ @aws_sdk_class
179
+ end
171
180
 
172
- def self.aws_sdk_class
173
- @aws_sdk_class
174
- end
181
+ def self.aws_sdk_class_id
182
+ @aws_sdk_class_id
183
+ end
175
184
 
176
- def self.aws_sdk_class_id
177
- @aws_sdk_class_id
178
- end
185
+ def self.aws_id_prefix
186
+ @aws_id_prefix
187
+ end
179
188
 
180
- def self.aws_id_prefix
181
- @aws_id_prefix
182
- end
189
+ def self.aws_sdk_option_name
190
+ @aws_sdk_option_name
191
+ end
183
192
 
184
- def self.aws_sdk_option_name
185
- @aws_sdk_option_name
186
- end
193
+ @@aws_option_handlers = {}
194
+ def self.aws_option_handlers
195
+ @@aws_option_handlers
196
+ end
187
197
 
188
- @@aws_option_handlers = {}
189
- def self.aws_option_handlers
190
- @@aws_option_handlers
191
- end
198
+ # Add support for aws_id_attribute: true
199
+ def self.attribute(name, aws_id_attribute: false, **validation_opts)
200
+ @aws_id_attribute = name if aws_id_attribute
201
+ super(name, validation_opts)
202
+ end
192
203
 
193
- # Add support for aws_id_attribute: true
194
- def self.attribute(name, aws_id_attribute: false, **validation_opts)
195
- @aws_id_attribute = name if aws_id_attribute
196
- super(name, validation_opts)
204
+ def self.aws_id_attribute
205
+ @aws_id_attribute
206
+ end
197
207
  end
198
208
 
199
- def self.aws_id_attribute
200
- @aws_id_attribute
201
- end
209
+ end
202
210
  end
203
211
  end