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.
- checksums.yaml +4 -4
- data/Rakefile +2 -0
- data/lib/chef/provider/aws_auto_scaling_group.rb +30 -41
- data/lib/chef/provider/aws_dhcp_options.rb +70 -0
- data/lib/chef/provider/aws_ebs_volume.rb +182 -34
- data/lib/chef/provider/aws_eip_address.rb +63 -60
- data/lib/chef/provider/aws_key_pair.rb +18 -27
- data/lib/chef/provider/aws_launch_configuration.rb +50 -0
- data/lib/chef/provider/aws_route_table.rb +122 -0
- data/lib/chef/provider/aws_s3_bucket.rb +42 -49
- data/lib/chef/provider/aws_security_group.rb +252 -59
- data/lib/chef/provider/aws_sns_topic.rb +10 -26
- data/lib/chef/provider/aws_sqs_queue.rb +16 -38
- data/lib/chef/provider/aws_subnet.rb +85 -32
- data/lib/chef/provider/aws_vpc.rb +163 -23
- data/lib/chef/provisioning/aws_driver.rb +18 -1
- data/lib/chef/provisioning/aws_driver/aws_provider.rb +206 -0
- data/lib/chef/provisioning/aws_driver/aws_resource.rb +186 -0
- data/lib/chef/provisioning/aws_driver/aws_resource_with_entry.rb +114 -0
- data/lib/chef/provisioning/aws_driver/driver.rb +317 -255
- data/lib/chef/provisioning/aws_driver/resources.rb +8 -5
- data/lib/chef/provisioning/aws_driver/super_lwrp.rb +45 -0
- data/lib/chef/provisioning/aws_driver/version.rb +1 -1
- data/lib/chef/resource/aws_auto_scaling_group.rb +15 -13
- data/lib/chef/resource/aws_dhcp_options.rb +57 -0
- data/lib/chef/resource/aws_ebs_volume.rb +20 -22
- data/lib/chef/resource/aws_eip_address.rb +50 -25
- data/lib/chef/resource/aws_image.rb +20 -0
- data/lib/chef/resource/aws_instance.rb +20 -0
- data/lib/chef/resource/aws_internet_gateway.rb +16 -0
- data/lib/chef/resource/aws_key_pair.rb +6 -10
- data/lib/chef/resource/aws_launch_configuration.rb +15 -0
- data/lib/chef/resource/aws_load_balancer.rb +16 -0
- data/lib/chef/resource/aws_network_interface.rb +16 -0
- data/lib/chef/resource/aws_route_table.rb +76 -0
- data/lib/chef/resource/aws_s3_bucket.rb +8 -18
- data/lib/chef/resource/aws_security_group.rb +49 -19
- data/lib/chef/resource/aws_sns_topic.rb +14 -15
- data/lib/chef/resource/aws_sqs_queue.rb +16 -14
- data/lib/chef/resource/aws_subnet.rb +87 -17
- data/lib/chef/resource/aws_vpc.rb +137 -15
- data/spec/integration/aws_security_group_spec.rb +55 -0
- data/spec/spec_helper.rb +8 -2
- data/spec/support/aws_support.rb +211 -0
- metadata +33 -10
- data/lib/chef/provider/aws_launch_config.rb +0 -43
- data/lib/chef/provider/aws_provider.rb +0 -22
- data/lib/chef/provisioning/aws_driver/aws_profile.rb +0 -73
- data/lib/chef/resource/aws_launch_config.rb +0 -14
- data/lib/chef/resource/aws_resource.rb +0 -10
- data/spec/chef_zero_rspec_helper.rb +0 -8
- data/spec/unit/provider/aws_subnet_spec.rb +0 -67
- data/spec/unit/resource/aws_subnet_spec.rb +0 -23
@@ -1,3 +1,20 @@
|
|
1
1
|
require 'chef/provisioning'
|
2
2
|
require 'chef/provisioning/aws_driver/driver'
|
3
|
-
|
3
|
+
|
4
|
+
require "chef/resource/aws_auto_scaling_group"
|
5
|
+
require "chef/resource/aws_dhcp_options"
|
6
|
+
require "chef/resource/aws_ebs_volume"
|
7
|
+
require "chef/resource/aws_eip_address"
|
8
|
+
require "chef/resource/aws_image"
|
9
|
+
require "chef/resource/aws_instance"
|
10
|
+
require "chef/resource/aws_internet_gateway"
|
11
|
+
require "chef/resource/aws_launch_configuration"
|
12
|
+
require "chef/resource/aws_load_balancer"
|
13
|
+
require "chef/resource/aws_network_interface"
|
14
|
+
require "chef/resource/aws_route_table"
|
15
|
+
require "chef/resource/aws_s3_bucket"
|
16
|
+
require "chef/resource/aws_security_group"
|
17
|
+
require "chef/resource/aws_sns_topic"
|
18
|
+
require "chef/resource/aws_sqs_queue"
|
19
|
+
require "chef/resource/aws_subnet"
|
20
|
+
require "chef/resource/aws_vpc"
|
@@ -0,0 +1,206 @@
|
|
1
|
+
require 'chef/provider/lwrp_base'
|
2
|
+
require 'chef/provisioning/aws_driver/aws_resource'
|
3
|
+
require 'chef/provisioning/aws_driver/aws_resource_with_entry'
|
4
|
+
require 'chef/provisioning/chef_managed_entry_store'
|
5
|
+
require 'chef/provisioning/chef_provider_action_handler'
|
6
|
+
|
7
|
+
module Chef::Provisioning::AWSDriver
|
8
|
+
class AWSProvider < Chef::Provider::LWRPBase
|
9
|
+
use_inline_resources
|
10
|
+
|
11
|
+
AWSResource = Chef::Provisioning::AWSDriver::AWSResource
|
12
|
+
|
13
|
+
def action_handler
|
14
|
+
@action_handler ||= Chef::Provisioning::ChefProviderActionHandler.new(self)
|
15
|
+
end
|
16
|
+
|
17
|
+
# All these need to implement whyrun
|
18
|
+
def whyrun_supported?
|
19
|
+
true
|
20
|
+
end
|
21
|
+
|
22
|
+
def region
|
23
|
+
new_resource.driver.aws_config.region
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
# Return the damned value from the block, not whatever weirdness converge_by
|
28
|
+
# normally returns.
|
29
|
+
#
|
30
|
+
def converge_by(*args, &block)
|
31
|
+
result = nil
|
32
|
+
super(*args) do
|
33
|
+
result = block.call
|
34
|
+
end
|
35
|
+
result
|
36
|
+
end
|
37
|
+
|
38
|
+
action :create do
|
39
|
+
#
|
40
|
+
# If the user specified an ID, get the object for it, and fail if it does not exist.
|
41
|
+
#
|
42
|
+
desired_driver = new_resource.driver
|
43
|
+
desired_id = new_resource.public_send(new_resource.class.aws_id_attribute) if new_resource.class.aws_id_attribute
|
44
|
+
if desired_id
|
45
|
+
aws_object = new_resource.class.get_aws_object(desired_id, resource: new_resource)
|
46
|
+
end
|
47
|
+
|
48
|
+
#
|
49
|
+
# If Chef has already associated the object with an AWS ID, check if it's
|
50
|
+
# the same as the desired AWS ID.
|
51
|
+
#
|
52
|
+
if new_resource.is_a?(AWSResourceWithEntry)
|
53
|
+
entry_driver, entry_id, entry = new_resource.get_id_from_managed_entry
|
54
|
+
if entry_id
|
55
|
+
if desired_id
|
56
|
+
|
57
|
+
#
|
58
|
+
# We have both a desired ID and an entry ID. Find out whether they
|
59
|
+
# match and warn if they don't (because we're going to reassociate and
|
60
|
+
# update the *desired* AWS thing.).
|
61
|
+
#
|
62
|
+
if desired_driver.driver_url == entry_driver.driver_url && desired_id == entry_id
|
63
|
+
Chef::Log.debug "#{new_resource.to_s} is already associated with #{entry_id} in #{entry_driver.driver_url}"
|
64
|
+
else
|
65
|
+
Chef::Log.warn "#{new_resource.to_s} is currently associated with #{entry_id} in #{entry_driver.driver_url}, but the desired ID is #{desired_id} in #{new_resource.driver.driver_url}! Will associate with new desired ID #{desired_id}."
|
66
|
+
end
|
67
|
+
|
68
|
+
else
|
69
|
+
|
70
|
+
#
|
71
|
+
# If we don't have desired (common case), we'll update the existing
|
72
|
+
# resource or create a new one if it's been deleted.
|
73
|
+
#
|
74
|
+
aws_object = new_resource.class.get_aws_object(entry_id, driver: entry_driver, resource: new_resource, required: false)
|
75
|
+
if aws_object
|
76
|
+
Chef::Log.debug "#{new_resource.to_s} is currently associated with #{entry_id} in #{entry_driver.driver_url}."
|
77
|
+
else
|
78
|
+
Chef::Log.warn "#{new_resource.to_s} is currently associated with #{entry_id} in #{entry_driver.driver_url}, but it does not exist! We will create a new one to replace it."
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
else
|
83
|
+
|
84
|
+
#
|
85
|
+
# If we don't currently have an AWS ID associated with this resource, we
|
86
|
+
# will either associate the desired one, or create a new one.
|
87
|
+
#
|
88
|
+
if desired_id
|
89
|
+
Chef::Log.debug "#{new_resource.to_s} is not yet associated with anything. Associating with desired object #{desired_id} in #{desired_driver.driver_url}."
|
90
|
+
else
|
91
|
+
Chef::Log.debug "#{new_resource.to_s} is not yet associated with anything. Creating a new one in #{desired_driver.driver_url} ..."
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
else
|
96
|
+
|
97
|
+
#
|
98
|
+
# If it does not support storing IDs in Chef at all, just grab the existing
|
99
|
+
# object and we'll update (or not) based on that.
|
100
|
+
#
|
101
|
+
aws_object ||= new_resource.aws_object
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
#
|
106
|
+
# Actually update or create the AWS object
|
107
|
+
#
|
108
|
+
if aws_object
|
109
|
+
action, new_obj = update_aws_object(aws_object)
|
110
|
+
if action == :replaced_aws_object
|
111
|
+
aws_object = new_obj
|
112
|
+
end
|
113
|
+
else
|
114
|
+
aws_object = create_aws_object
|
115
|
+
end
|
116
|
+
|
117
|
+
#
|
118
|
+
# Associate the managed entry with the AWS object
|
119
|
+
#
|
120
|
+
if new_resource.is_a?(AWSResourceWithEntry)
|
121
|
+
new_resource.save_managed_entry(aws_object, action_handler, existing_entry: entry)
|
122
|
+
end
|
123
|
+
|
124
|
+
aws_object
|
125
|
+
end
|
126
|
+
|
127
|
+
action :destroy do
|
128
|
+
desired_driver = new_resource.driver
|
129
|
+
desired_id = new_resource.public_send(new_resource.class.aws_id_attribute) if new_resource.class.aws_id_attribute
|
130
|
+
|
131
|
+
#
|
132
|
+
# If the user specified an ID, delete THAT; do NOT delete the associated object.
|
133
|
+
#
|
134
|
+
if desired_id
|
135
|
+
aws_object = new_resource.class.get_aws_object(desired_id, resource: new_resource, required: false)
|
136
|
+
if aws_object
|
137
|
+
Chef::Log.debug "#{new_resource.to_s} provided #{new_resource.class.aws_id_attribute} #{desired_id} in #{desired_driver.driver_url}. Will delete."
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
#
|
142
|
+
# Managed entries are looked up by ID.
|
143
|
+
#
|
144
|
+
if new_resource.is_a?(AWSResourceWithEntry)
|
145
|
+
entry_driver, entry_id, entry = new_resource.get_id_from_managed_entry
|
146
|
+
if entry_id
|
147
|
+
if desired_id && (desired_id != entry_id || desired_driver.driver_url != entry_driver.driver_url)
|
148
|
+
if new_resource.class.get_aws_object(entry_id, driver: entry_driver, resource: new_resource, required: false)
|
149
|
+
# If the desired ID / driver differs from the entry, don't delete. We
|
150
|
+
# certainly can't delete the AWS object itself, and we don't *want* to
|
151
|
+
# delete the association, because the expectation is that after doing a
|
152
|
+
# delete, you should be able to create a new thing.
|
153
|
+
raise "#{new_resource.to_s} provided #{new_resource.class.aws_id_attribute} #{desired_id} in #{desired_driver.driver_url}, but is currently associated with #{entry_id} in #{entry_driver.driver_url}. Cannot delete the entry or the association until this inconsistency is resolved."
|
154
|
+
else
|
155
|
+
Chef::Log.debug "#{new_resource.to_s} provided #{new_resource.class.aws_id_attribute} #{desired_id} in #{desired_driver.driver_url}, but is currently associated with #{entry_id} in #{entry_driver.driver_url}, which does not exist. Will delete #{desired_id} and disassociate from #{entry_id}."
|
156
|
+
end
|
157
|
+
else
|
158
|
+
|
159
|
+
# Normal case: entry exists, and is the same as desired (or no desired)
|
160
|
+
aws_object = new_resource.class.get_aws_object(entry_id, driver: entry_driver, resource: new_resource, required: false)
|
161
|
+
if aws_object
|
162
|
+
Chef::Log.debug "#{new_resource.to_s} is associated with #{entry_id} in #{entry_driver.driver_url}. Will delete."
|
163
|
+
else
|
164
|
+
Chef::Log.debug "#{new_resource.to_s} is associated with #{entry_id} in #{entry_driver.driver_url}, but it does not exist. Will disassociate the entry but not delete."
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
#
|
170
|
+
# Non-managed entries all have their own way of looking it up
|
171
|
+
#
|
172
|
+
else
|
173
|
+
aws_object ||= new_resource.aws_object
|
174
|
+
end
|
175
|
+
|
176
|
+
#
|
177
|
+
# Call the delete method
|
178
|
+
#
|
179
|
+
if aws_object
|
180
|
+
destroy_aws_object(aws_object)
|
181
|
+
end
|
182
|
+
|
183
|
+
#
|
184
|
+
# Associate the managed entry with the AWS object
|
185
|
+
#
|
186
|
+
if new_resource.is_a?(AWSResourceWithEntry) && entry
|
187
|
+
new_resource.delete_managed_entry(action_handler)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
protected
|
192
|
+
|
193
|
+
def create_aws_object
|
194
|
+
raise NotImplementedError, :create_aws_object
|
195
|
+
end
|
196
|
+
|
197
|
+
def update_aws_object(obj)
|
198
|
+
raise NotImplementedError, :update_aws_object
|
199
|
+
end
|
200
|
+
|
201
|
+
def destroy_aws_object(obj)
|
202
|
+
raise NotImplementedError, :destroy_aws_object
|
203
|
+
end
|
204
|
+
|
205
|
+
end
|
206
|
+
end
|
@@ -0,0 +1,186 @@
|
|
1
|
+
require 'aws'
|
2
|
+
require 'chef/provisioning/aws_driver/super_lwrp'
|
3
|
+
require 'chef/provisioning/chef_managed_entry_store'
|
4
|
+
|
5
|
+
# Common AWS resource - contains metadata that all AWS resources will need
|
6
|
+
module Chef::Provisioning::AWSDriver
|
7
|
+
class AWSResource < Chef::Provisioning::AWSDriver::SuperLWRP
|
8
|
+
actions :create, :destroy, :nothing
|
9
|
+
default_action :create
|
10
|
+
|
11
|
+
def initialize(name, run_context=nil)
|
12
|
+
name = name.public_send(self.class.aws_sdk_class_id) if name.is_a?(self.class.aws_sdk_class)
|
13
|
+
super
|
14
|
+
if run_context
|
15
|
+
driver run_context.chef_provisioning.current_driver
|
16
|
+
chef_server run_context.cheffish.current_chef_server
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Backwards compatibility for action :destroy
|
21
|
+
def action(*args)
|
22
|
+
if args == [ :delete ]
|
23
|
+
super(:destroy)
|
24
|
+
else
|
25
|
+
super
|
26
|
+
end
|
27
|
+
end
|
28
|
+
def action=(value)
|
29
|
+
action(value)
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
# The desired driver.
|
34
|
+
#
|
35
|
+
attribute :driver, kind_of: Chef::Provisioning::Driver,
|
36
|
+
coerce: (proc do |value|
|
37
|
+
case value
|
38
|
+
when nil, Chef::Provisioning::Driver
|
39
|
+
value
|
40
|
+
else
|
41
|
+
run_context.chef_provisioning.driver_for(value)
|
42
|
+
end
|
43
|
+
end)
|
44
|
+
|
45
|
+
#
|
46
|
+
# The Chef server on which any IDs should be looked up.
|
47
|
+
#
|
48
|
+
attribute :chef_server, kind_of: Hash
|
49
|
+
|
50
|
+
#
|
51
|
+
# The managed entry store.
|
52
|
+
#
|
53
|
+
attribute :managed_entry_store, kind_of: Chef::Provisioning::ManagedEntryStore,
|
54
|
+
lazy_default: proc { Chef::Provisioning::ChefManagedEntryStore.new(chef_server) }
|
55
|
+
|
56
|
+
#
|
57
|
+
# Get the current AWS object.
|
58
|
+
#
|
59
|
+
def aws_object
|
60
|
+
raise NotImplementedError, :aws_object
|
61
|
+
end
|
62
|
+
|
63
|
+
#
|
64
|
+
# Look up an AWS options list, translating standard names using the appropriate
|
65
|
+
# classes.
|
66
|
+
#
|
67
|
+
# For example, `load_balancer_options` is passed into `lookup_options`, and if
|
68
|
+
# it looks like this: `{ subnets: `[ 'subnet1', 'subnet2' ] }`, then
|
69
|
+
# `AWSResource.lookup_options` will translate each ID with
|
70
|
+
# `AwsSubnet.get_aws_object('subnet1')`, which supports Chef names
|
71
|
+
# (`mysubnet`) as well as AWS subnet Ids (`subnet-1234abcd`) or AWS objects
|
72
|
+
# (`AWS::EC2::Subnet`).
|
73
|
+
#
|
74
|
+
# Keys that represent non-AWS-objects (such as `timeout`) are left alone.
|
75
|
+
#
|
76
|
+
def self.lookup_options(options, **handler_options)
|
77
|
+
options = options.dup
|
78
|
+
options.each do |name, value|
|
79
|
+
if name.to_s.end_with?('s')
|
80
|
+
handler_name = :"#{name[0..-2]}"
|
81
|
+
if aws_option_handlers[handler_name]
|
82
|
+
options[name] = [options[name]].flatten.map { |value| aws_option_handlers[handler_name].get_aws_object_id(value, **handler_options) }
|
83
|
+
end
|
84
|
+
else
|
85
|
+
if aws_option_handlers[name]
|
86
|
+
options[name] = aws_option_handlers[name].get_aws_object_id(value, **handler_options)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
options
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.get_aws_object(value, resource: nil, run_context: nil, driver: nil, managed_entry_store: nil, required: true)
|
94
|
+
return nil if value.nil?
|
95
|
+
|
96
|
+
if resource
|
97
|
+
run_context ||= resource.run_context
|
98
|
+
driver ||= resource.driver
|
99
|
+
managed_entry_store ||= resource.managed_entry_store
|
100
|
+
end
|
101
|
+
if value.is_a?(self)
|
102
|
+
resource = value
|
103
|
+
else
|
104
|
+
resource = new(value, run_context)
|
105
|
+
resource.driver driver if driver
|
106
|
+
resource.managed_entry_store managed_entry_store if managed_entry_store
|
107
|
+
end
|
108
|
+
result = resource.aws_object
|
109
|
+
if required && result.nil?
|
110
|
+
raise "#{self}[#{value}] does not exist!"
|
111
|
+
end
|
112
|
+
result
|
113
|
+
end
|
114
|
+
|
115
|
+
def self.get_aws_object_id(value, **options)
|
116
|
+
aws_object = get_aws_object(value, **options)
|
117
|
+
aws_object.public_send(aws_sdk_class_id) if aws_object
|
118
|
+
end
|
119
|
+
|
120
|
+
protected
|
121
|
+
|
122
|
+
NOT_PASSED = Object.new
|
123
|
+
|
124
|
+
def self.aws_sdk_type(sdk_class,
|
125
|
+
option_names: nil,
|
126
|
+
option_name: NOT_PASSED,
|
127
|
+
load_provider: true,
|
128
|
+
id: :name,
|
129
|
+
aws_id_prefix: nil)
|
130
|
+
self.resource_name = self.dsl_name
|
131
|
+
@aws_sdk_class = sdk_class
|
132
|
+
@aws_sdk_class_id = id
|
133
|
+
@aws_id_prefix = aws_id_prefix
|
134
|
+
|
135
|
+
# Go ahead and require the provider since we're here anyway ...
|
136
|
+
require "chef/provider/#{resource_name}" if load_provider
|
137
|
+
|
138
|
+
option_name = :"#{resource_name[4..-1]}" if option_name == NOT_PASSED
|
139
|
+
@aws_sdk_option_name = option_name
|
140
|
+
|
141
|
+
option_names ||= begin
|
142
|
+
option_names = []
|
143
|
+
option_names << aws_sdk_option_name
|
144
|
+
option_names << :"#{option_name}_#{aws_sdk_class_id}" if aws_sdk_class_id
|
145
|
+
option_names
|
146
|
+
end
|
147
|
+
option_names.each do |option_name|
|
148
|
+
aws_option_handlers[option_name] = self
|
149
|
+
end
|
150
|
+
|
151
|
+
name = self.name.split('::')[-1]
|
152
|
+
eval("Chef::Provisioning::AWSDriver::Resources::#{name} = self", binding, __FILE__, __LINE__)
|
153
|
+
end
|
154
|
+
|
155
|
+
def self.aws_sdk_class
|
156
|
+
@aws_sdk_class
|
157
|
+
end
|
158
|
+
|
159
|
+
def self.aws_sdk_class_id
|
160
|
+
@aws_sdk_class_id
|
161
|
+
end
|
162
|
+
|
163
|
+
def self.aws_id_prefix
|
164
|
+
@aws_id_prefix
|
165
|
+
end
|
166
|
+
|
167
|
+
def self.aws_sdk_option_name
|
168
|
+
@aws_sdk_option_name
|
169
|
+
end
|
170
|
+
|
171
|
+
@@aws_option_handlers = {}
|
172
|
+
def self.aws_option_handlers
|
173
|
+
@@aws_option_handlers
|
174
|
+
end
|
175
|
+
|
176
|
+
# Add support for aws_id_attribute: true
|
177
|
+
def self.attribute(name, aws_id_attribute: false, **validation_opts)
|
178
|
+
@aws_id_attribute = name if aws_id_attribute
|
179
|
+
super(name, validation_opts)
|
180
|
+
end
|
181
|
+
|
182
|
+
def self.aws_id_attribute
|
183
|
+
@aws_id_attribute
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'chef/provisioning/aws_driver/aws_resource'
|
2
|
+
require 'chef/provisioning/aws_driver/resources'
|
3
|
+
|
4
|
+
# Common AWS resource - contains metadata that all AWS resources will need
|
5
|
+
class Chef::Provisioning::AWSDriver::AWSResourceWithEntry < Chef::Provisioning::AWSDriver::AWSResource
|
6
|
+
#
|
7
|
+
# Dissociate the ID of this object from Chef.
|
8
|
+
#
|
9
|
+
# @param action_handler [Chef::Provisioning::ActionHandler] The action handler,
|
10
|
+
# which handles progress reporting, update reporting ("little green text")
|
11
|
+
# and dry run.
|
12
|
+
#
|
13
|
+
def delete_managed_entry(action_handler)
|
14
|
+
if should_have_managed_entry?
|
15
|
+
managed_entry_store.delete(self.class.resource_name, name, action_handler)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
#
|
20
|
+
# Save the ID of this object to Chef.
|
21
|
+
#
|
22
|
+
# @param aws_object [AWS::EC2::Core] The AWS object containing the ID.
|
23
|
+
# @param action_handler [Chef::Provisioning::ActionHandler] The action handler,
|
24
|
+
# which handles progress reporting, update reporting ("little green text")
|
25
|
+
# and dry run.
|
26
|
+
# @param existing_entry [Chef::Provisioning::ManagedEntry] The existing entry
|
27
|
+
# (if any). If this is passed in, and no values are changed, we will
|
28
|
+
# not attempt to update it (this prevents us from retrieving it twice).
|
29
|
+
#
|
30
|
+
def save_managed_entry(aws_object, action_handler, existing_entry: nil)
|
31
|
+
if should_have_managed_entry?
|
32
|
+
managed_entry = existing_entry ||
|
33
|
+
managed_entry_store.new_entry(self.class.resource_name, name)
|
34
|
+
updated = update_managed_entry(aws_object, managed_entry)
|
35
|
+
if updated || !existing_entry
|
36
|
+
managed_entry.save(action_handler)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def get_id_from_managed_entry
|
42
|
+
if should_have_managed_entry?
|
43
|
+
entry = managed_entry_store.get(self.class.managed_entry_type, name)
|
44
|
+
if entry
|
45
|
+
driver = self.driver
|
46
|
+
if entry.driver_url != driver.driver_url
|
47
|
+
# TODO some people don't send us run_context (like Drivers). We might need
|
48
|
+
# to exit early here if the driver_url doesn't match the provided driver.
|
49
|
+
driver = run_context.chef_provisioning.driver_for(entry.driver_url)
|
50
|
+
end
|
51
|
+
[ driver, entry.reference[self.class.managed_entry_id_name], entry ]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Formatted output for logging statements - contains resource type, resource name and aws object id (if available)
|
57
|
+
def to_s
|
58
|
+
id = get_driver_and_id[1]
|
59
|
+
"#{declared_type}[#{@name}] (#{ id ? id : 'no AWS object id'})"
|
60
|
+
end
|
61
|
+
|
62
|
+
protected
|
63
|
+
|
64
|
+
#
|
65
|
+
# Update an existing ManagedEntry object.
|
66
|
+
#
|
67
|
+
# @return true if the entry was changed, and false if not
|
68
|
+
#
|
69
|
+
def update_managed_entry(aws_object, managed_entry)
|
70
|
+
new_value = { self.class.managed_entry_id_name => aws_object.public_send(self.class.aws_sdk_class_id) }
|
71
|
+
if managed_entry.reference != new_value
|
72
|
+
managed_entry.reference = new_value
|
73
|
+
changed = true
|
74
|
+
end
|
75
|
+
if managed_entry.driver_url != driver.driver_url
|
76
|
+
managed_entry.driver_url = driver.driver_url
|
77
|
+
changed = true
|
78
|
+
end
|
79
|
+
changed
|
80
|
+
end
|
81
|
+
|
82
|
+
def get_driver_and_id
|
83
|
+
driver, id, entry = get_id_from_managed_entry
|
84
|
+
# If the value isn't already stored, look up the user-specified public_ip
|
85
|
+
driver, id = self.driver, self.public_send(self.class.aws_id_attribute) if !id
|
86
|
+
[ driver, id ]
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.aws_sdk_type(sdk_class,
|
90
|
+
id: :id,
|
91
|
+
managed_entry_type: nil,
|
92
|
+
managed_entry_id_name: 'id',
|
93
|
+
backcompat_data_bag_name: nil,
|
94
|
+
**options)
|
95
|
+
super(sdk_class, id: id, **options)
|
96
|
+
@managed_entry_type = managed_entry_type || resource_name.to_sym
|
97
|
+
@managed_entry_id_name = managed_entry_id_name
|
98
|
+
if backcompat_data_bag_name
|
99
|
+
Chef::Provisioning::ChefManagedEntryStore.type_names_for_backcompat[resource_name] = backcompat_data_bag_name
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def self.managed_entry_type
|
104
|
+
@managed_entry_type
|
105
|
+
end
|
106
|
+
|
107
|
+
def self.managed_entry_id_name
|
108
|
+
@managed_entry_id_name
|
109
|
+
end
|
110
|
+
|
111
|
+
def should_have_managed_entry?
|
112
|
+
name != public_send(self.class.aws_id_attribute)
|
113
|
+
end
|
114
|
+
end
|