lib/rubber/dns/fog.rb in rubber-2.0.2 vs lib/rubber/dns/fog.rb in rubber-2.0.3
- old
+ new
@@ -10,12 +10,14 @@
def initialize(env)
super(env)
creds = Rubber::Util.symbolize_keys(env.credentials)
@client = ::Fog::DNS.new(creds)
- @name_includes_domain = env.name_includes_domain
- @name_includes_trailing_period = env.name_includes_trailing_period
+ if creds[:provider] == 'aws'
+ @name_includes_domain = true
+ @name_includes_trailing_period = true
+ end
end
def normalize_name(name, domain)
domain = domain.gsub(/\.$/, "") if @name_includes_trailing_period
@@ -42,32 +44,65 @@
return name, domain
end
def host_to_opts(host)
name, domain = normalize_name(host.name || '', host.zone.domain)
-
opts = {}
opts[:id] = host.id if host.respond_to?(:id) && host.id
- opts[:host] = name
+ opts[:host] = fix_hostname(name)
opts[:domain] = domain
opts[:type] = host.type
- opts[:data] = Array(host.value).first if host.value
opts[:ttl] = host.ttl.to_i if host.ttl
opts[:priority] = host.priority if host.respond_to?(:priority) && host.priority
-
+
+ if host.respond_to?(:alias_target) && ! host.alias_target.nil?
+
+ # Convert from camel-case to snake-case for Route 53 ALIAS records so the match the rubber config format.
+ opts[:data] = {
+ 'hosted_zone_id' => host.alias_target['HostedZoneId'],
+ 'dns_name' => host.alias_target['DNSName'].split('.')[0..-1].join('.')
+ }
+
+ # Route 53 ALIAS records do not have a TTL, so delete the rubber-supplied default value.
+ opts.delete(:ttl)
+ else
+ opts[:data] = Array(host.value).first if host.value
+ end
+
return opts
end
def opts_to_host(opts, host={})
name, domain = denormalize_name(opts[:host], opts[:domain])
-
- host[:name] = name
+
+ host[:name] = name
host[:type] = opts[:type]
- host[:value] = opts[:data] if opts[:data]
host[:ttl] = opts[:ttl] if opts[:ttl]
host[:priority] = opts[:priority] if opts[:priority]
-
+
+ if opts[:data]
+ creds = Rubber::Util.symbolize_keys(env.credentials)
+
+ if creds[:provider] == 'aws'
+ # Route 53 requires the priority to be munged with the data value.
+ if opts[:type] =~ /MX/i
+ host[:value] = "#{opts[:priority]} #{opts[:data]}"
+ else
+ # Route 53 allows creation of ALIAS records, which will always be a Hash in the DNS config. ALIAS records
+ # cannot have a TTL.
+ if opts[:data].is_a?(Hash)
+ host[:alias_target] = opts[:data]
+ host.delete(:ttl)
+ else
+ host[:value] = opts[:data]
+ end
+ end
+ else
+ host[:value] = opts[:data]
+ end
+ end
+
return host
end
def find_or_create_zone(domain)
zone = @client.zones.all.find {|z| z.domain =~ /^#{domain}\.?/}
@@ -99,11 +134,13 @@
# hosts = fqdn ? (zone.records.all(:name => fqdn) rescue []) : zone.records.all
hosts = zone.records.all
if fqdn
hosts = hosts.find_all do |r|
attributes = host_to_opts(r)
- host, domain = attributes[:host], attributes[:domain]
+
+ # Route 53 encodes the asterisk character ('*') as octal. Translate it here so rubber is consistent.
+ host, domain = fix_hostname(attributes[:host]), attributes[:domain]
fog_fqdn = ""
fog_fqdn << "#{host}." if host && ! host.strip.empty?
fog_fqdn << "#{domain}"
@@ -167,9 +204,14 @@
result = h.save
end
result || raise("Failed to update host #{h.hostname}, #{h.errors.full_messages.join(', ')}")
end
+ end
+
+ def fix_hostname(host)
+ # Route 53 encodes asterisks in their ASCII octal representation.
+ host.gsub("\\052", "*")
end
end
end