Class: Chef::Provider::AwsRoute53HostedZone
- Inherits:
-
Chef::Provisioning::AWSDriver::AWSProvider
- Object
- LWRPBase
- Chef::Provisioning::AWSDriver::AWSProvider
- Chef::Provider::AwsRoute53HostedZone
- Defined in:
- lib/chef/resource/aws_route53_hosted_zone.rb
Constant Summary collapse
- CREATE =
"CREATE".freeze
- UPDATE =
UPSERT = "UPSERT".freeze
- DELETE =
"DELETE".freeze
- RRS_COMMENT =
"Managed by chef-provisioning-aws".freeze
Constants inherited from Chef::Provisioning::AWSDriver::AWSProvider
Chef::Provisioning::AWSDriver::AWSProvider::AWSResource
Instance Attribute Summary collapse
-
#record_set_list ⇒ Object
Returns the value of attribute record_set_list.
Attributes inherited from Chef::Provisioning::AWSDriver::AWSProvider
Instance Method Summary collapse
- #create_aws_object ⇒ Object
- #destroy_aws_object(hosted_zone) ⇒ Object
-
#get_record_sets_from_resource(new_resource) ⇒ Object
‘record_sets` is defined on the `aws_route53_hosted_zone` resource as a block attribute, so compile that, validate it, and return a list of AWSRoute53RecordSet resource objects.
- #make_hosted_zone_config(new_resource) ⇒ Object
-
#populate_zone_info(record_set_resources, hosted_zone) ⇒ Object
this happens at a slightly different time in the lifecycle from #get_record_sets_from_resource.
- #update_aws_object(hosted_zone) ⇒ Object
Methods inherited from Chef::Provisioning::AWSDriver::AWSProvider
#action_handler, #converge_by, #region, #whyrun_supported?
Instance Attribute Details
#record_set_list ⇒ Object
Returns the value of attribute record_set_list.
88 89 90 |
# File 'lib/chef/resource/aws_route53_hosted_zone.rb', line 88 def record_set_list @record_set_list end |
Instance Method Details
#create_aws_object ⇒ Object
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/chef/resource/aws_route53_hosted_zone.rb', line 107 def create_aws_object converge_by "create new Route 53 zone #{new_resource}" do # AWS stores some attributes off to the side here. hosted_zone_config = make_hosted_zone_config(new_resource) values = { name: new_resource.name, hosted_zone_config: hosted_zone_config, caller_reference: "chef-provisioning-aws-#{SecureRandom.uuid.upcase}", # required, unique each call } # this will validate the record_set resources prior to making any AWS calls. record_set_resources = get_record_sets_from_resource(new_resource) zone = new_resource.driver.route53_client.create_hosted_zone(values).hosted_zone new_resource.aws_route53_zone_id(zone.id) if record_set_resources populate_zone_info(record_set_resources, zone) change_list = record_set_resources.map { |rs| rs.to_aws_change_struct(UPDATE) } new_resource.driver.route53_client.change_resource_record_sets(hosted_zone_id: new_resource.aws_route53_zone_id, change_batch: { comment: RRS_COMMENT, changes: change_list }) end zone end end |
#destroy_aws_object(hosted_zone) ⇒ Object
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/chef/resource/aws_route53_hosted_zone.rb', line 198 def destroy_aws_object(hosted_zone) converge_by "delete Route53 zone #{new_resource}" do Chef::Log.info("Deleting all non-SOA/NS records for #{hosted_zone.name}") rr_changes = hosted_zone.resource_record_sets.reject do |aws_rr| %w{SOA NS}.include?(aws_rr.type) end.map do |aws_rr| { action: DELETE, resource_record_set: aws_rr.to_change_struct } end unless rr_changes.empty? aws_struct = { hosted_zone_id: hosted_zone.id, change_batch: { comment: "Purging RRs prior to deleting resource", changes: rr_changes } } new_resource.driver.route53_client.change_resource_record_sets(aws_struct) end result = new_resource.driver.route53_client.delete_hosted_zone(id: hosted_zone.id) end end |
#get_record_sets_from_resource(new_resource) ⇒ Object
‘record_sets` is defined on the `aws_route53_hosted_zone` resource as a block attribute, so compile that, validate it, and return a list of AWSRoute53RecordSet resource objects.
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 |
# File 'lib/chef/resource/aws_route53_hosted_zone.rb', line 229 def get_record_sets_from_resource(new_resource) return nil unless new_resource.record_sets instance_eval(&new_resource.record_sets) # because we're in the provider, the RecordSet resources happen in their own mini Chef run, and they're the # only things in the resource_collection. record_set_resources = run_context.resource_collection.to_a return nil unless record_set_resources record_set_resources.each do |rs| rs.aws_route53_hosted_zone(new_resource) rs.aws_route53_zone_name(new_resource.name) if new_resource.defaults new_resource.class::DEFAULTABLE_ATTRS.each do |att| # check if the RecordSet has its own value, without triggering validation. in Chef >= 12.5, there is # #property_is_set?. if rs.instance_variable_get("@#{att}").nil? && !new_resource.defaults[att].nil? rs.send(att, new_resource.defaults[att]) end end end rs.validate! end Chef::Resource::AwsRoute53RecordSet.verify_unique!(record_set_resources) record_set_resources end |
#make_hosted_zone_config(new_resource) ⇒ Object
90 91 92 93 94 95 96 97 98 |
# File 'lib/chef/resource/aws_route53_hosted_zone.rb', line 90 def make_hosted_zone_config(new_resource) config = {} # add :private_zone here once VPC validation is enabled. [:comment].each do |attr| value = new_resource.send(attr) config[attr] = value if value end config end |
#populate_zone_info(record_set_resources, hosted_zone) ⇒ Object
this happens at a slightly different time in the lifecycle from #get_record_sets_from_resource.
101 102 103 104 105 |
# File 'lib/chef/resource/aws_route53_hosted_zone.rb', line 101 def populate_zone_info(record_set_resources, hosted_zone) record_set_resources.each do |rs| rs.aws_route53_zone_id(hosted_zone.id) end end |
#update_aws_object(hosted_zone) ⇒ Object
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/chef/resource/aws_route53_hosted_zone.rb', line 139 def update_aws_object(hosted_zone) new_resource.aws_route53_zone_id(hosted_zone.id) # this will validate the record_set resources prior to making any AWS calls. record_set_resources = get_record_sets_from_resource(new_resource) if new_resource.comment != hosted_zone.config.comment new_resource.driver.route53_client.update_hosted_zone_comment(id: hosted_zone.id, comment: new_resource.comment) end if record_set_resources populate_zone_info(record_set_resources, hosted_zone) aws_record_sets = hosted_zone.resource_record_sets change_list = [] # TODO: the SOA and NS records have identical :name properties (the zone name), so one of them will # be overwritten in the `keyed_aws_objects` hash. mostly we're declining to operate on SOA and NS, # so it probably doesn't matter, but bears investigating. # we already checked for duplicate Chef RR resources in #get_record_sets_from_resource. keyed_chef_resources = record_set_resources.each_with_object({}) { |rs, coll| (coll[rs.aws_key] ||= []) << rs; } keyed_aws_objects = aws_record_sets.each_with_object({}) { |rs, coll| coll[rs.aws_key] = rs; } # because DNS is important, we're going to err on the side of caution and only operate on records for # which we have a Chef resource. "total management" might be a nice resource option to have. keyed_chef_resources.each do |key, chef_resource_ary| chef_resource_ary.each do |chef_resource| # RR already exists... if keyed_aws_objects.key?(key) # ... do we want to delete it? if chef_resource.action.first == :destroy change_list << chef_resource.to_aws_change_struct(DELETE) # ... update it, then, only if the fields differ. elsif chef_resource.to_aws_struct != keyed_aws_objects[key] change_list << chef_resource.to_aws_change_struct(UPDATE) end # otherwise, RR does not already exist... else # using UPSERT instead of CREATE; there are merits to both. change_list << chef_resource.to_aws_change_struct(UPSERT) end end end Chef::Log.debug("RecordSet changes: #{change_list.inspect}") if !change_list.empty? new_resource.driver.route53_client.change_resource_record_sets(hosted_zone_id: new_resource.aws_route53_zone_id, change_batch: { comment: RRS_COMMENT, changes: change_list }) else Chef::Log.info("All aws_route53_record_set resources up to date (nothing to do).") end end end |