class Proxy::Dns::Powerdns::Record

Attributes

api_key[R]
url[R]

Public Class Methods

new(a_server, a_ttl, url, api_key) click to toggle source
Calls superclass method
# File lib/smart_proxy_dns_powerdns/dns_powerdns_main.rb, line 11
def initialize(a_server, a_ttl, url, api_key)
  @url = url
  @api_key = api_key

  super(a_server, a_ttl)
end

Public Instance Methods

create_record(domain_id, name, type, content) click to toggle source
# File lib/smart_proxy_dns_powerdns/dns_powerdns_main.rb, line 53
def create_record domain_id, name, type, content
  content += '.' if ['PTR', 'CNAME'].include?(type)
  rrset = {
    :name => name + '.',
    :type => type,
    :ttl => @ttl.to_i,
    :changetype => :REPLACE,
    :records => [
      {
        :content => content,
        :disabled => false
      }
    ]
  }

  patch_records domain_id, rrset
end
delete_record(domain_id, name, type) click to toggle source
# File lib/smart_proxy_dns_powerdns/dns_powerdns_main.rb, line 71
def delete_record domain_id, name, type
  rrset = {
    :name => name + '.',
    :type => type,
    :changetype => :DELETE,
    :records => []
  }

  patch_records domain_id, rrset
end
do_create(name, value, type) click to toggle source
# File lib/smart_proxy_dns_powerdns/dns_powerdns_main.rb, line 18
def do_create(name, value, type)
  zone = get_zone(name)
  unless create_record(zone['id'], name, type, value)
    raise Proxy::Dns::Error.new("Failed to insert record #{name} #{type} #{value}")
  end
  true
end
do_remove(name, type) click to toggle source
# File lib/smart_proxy_dns_powerdns/dns_powerdns_main.rb, line 26
def do_remove(name, type)
  zone = get_zone(name)
  delete_record(zone['id'], name, type)
end
get_zone(name) click to toggle source
# File lib/smart_proxy_dns_powerdns/dns_powerdns_main.rb, line 31
def get_zone name
  fqdn = Resolv::DNS::Name.create(name)
  fqdn = Resolv::DNS::Name.create(name + '.') unless fqdn.absolute?
  uri = URI("#{@url}/zones")

  result = Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
    request = Net::HTTP::Get.new uri
    request['X-API-Key'] = @api_key
    response = http.request request
    zones = JSON.parse(response.body) rescue []

    zones.select { |zone|
      domain = Resolv::DNS::Name.create(zone['name'])
      domain == fqdn or fqdn.subdomain_of?(domain)
    }.max_by { |zone| zone['name'].length }
  end

  raise Proxy::Dns::Error, "Unable to determine zone for #{name}. Zone must exist in PowerDNS." unless result

  result
end

Private Instance Methods

patch_records(domain_id, rrset) click to toggle source
# File lib/smart_proxy_dns_powerdns/dns_powerdns_main.rb, line 84
def patch_records domain_id, rrset
  uri = URI("#{@url}/zones/#{domain_id}")

  data = { :rrsets => [rrset] }

  Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
    request = Net::HTTP::Patch.new uri
    request['X-API-Key'] = @api_key
    request['Content-Type'] = 'application/json'
    request.body = data.to_json
    response = http.request request
    unless response.is_a?(Net::HTTPSuccess)
      begin
        content = JSON.parse(response.body)
      rescue
        logger.debug "Failed to pach records for #{domain_id} with '#{rrset}': #{response.body}"
        raise Proxy::Dns::Error.new("Failed to patch records")
      end
      raise Proxy::Dns::Error.new("Failed to patch records: #{content['error']}")
    end
  end

  true
end