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