lib/rubber/dns/zerigo.rb in rubber-2.0.5 vs lib/rubber/dns/zerigo.rb in rubber-2.0.6
- old
+ new
@@ -1,17 +1,123 @@
require 'rubygems'
require 'fog'
-require 'rubber/dns/fog'
module Rubber
module Dns
- class Zerigo < Fog
+ class Zerigo < Base
+ attr_accessor :client
+
def initialize(env)
- super(env.merge({"credentials" => { "provider" => 'zerigo', "zerigo_email" => env.email, "zerigo_token" => env.token }}))
+ super(env)
+ creds = { :provider => 'zerigo', :zerigo_email => env.email, :zerigo_token => env.token }
+ @client = ::Fog::DNS.new(creds)
end
-
+
+ # multiple hosts with same name/type convert to a single rubber-dns.yml opts format
+ def hosts_to_opts(hosts)
+ opts = {}
+
+ hosts.each do |host|
+ opts[:host] ||= host.name || ''
+ opts[:domain] ||= host.zone.domain
+ opts[:type] ||= host.type
+ opts[:ttl] ||= host.ttl.to_i if host.ttl
+
+ opts[:data] ||= []
+ if host.type =~ /MX/i
+ opts[:data] << {:priority => host.priority, :value => host.value}
+ else
+ opts[:data] << host.value
+ end
+ end
+
+ return opts
+ end
+
+ # a single rubber-dns.yml opts format converts to multiple hosts with same name/type
+ def opts_to_hosts(opts)
+ hosts = []
+
+ opts[:data].each do |o|
+ host = {}
+ host[:name] = opts[:host]
+ host[:type] = opts[:type]
+ host[:ttl] = opts[:ttl] if opts[:ttl]
+ if o.kind_of?(Hash) && o[:priority]
+ host[:priority] = o[:priority]
+ host[:value] = o[:value]
+ else
+ host[:value] = o
+ end
+ hosts << host
+ end
+
+ return hosts
+ end
+
+ def find_or_create_zone(domain)
+ zone = @client.zones.all.find {|z| z.domain =~ /^#{domain}\.?/}
+ if ! zone
+ zone = @client.zones.create(:domain => domain)
+ end
+ return zone
+ end
+
+ def find_hosts(opts = {})
+ opts = setup_opts(opts, [:host, :domain])
+ result = []
+ zone = find_or_create_zone(opts[:domain])
+
+ # TODO: revert this when zerigo fog gets fixed to allow parameters
+ # hosts = fqdn ? (zone.records.all(:name => fqdn) rescue []) : zone.records.all
+ hosts = zone.records.all
+ hosts = hosts.select {|h| name = h.name || ''; name == opts[:host] } if opts.has_key?(:host) && opts[:host] != '*'
+ hosts = hosts.select {|h| h.type == opts[:type] } if opts.has_key?(:type) && opts[:type] != '*'
+
+ return hosts
+ end
+
+ def find_host_records(opts = {})
+ hosts = find_hosts(opts)
+ group = {}
+ hosts.each do |h|
+ key = "#{h.name}.#{h.domain} #{h.type}"
+ group[key] ||= []
+ group[key] << h
+ end
+ result = group.values.collect {|h| hosts_to_opts(h).merge(:domain => opts[:domain])}
+ return result
+ end
+
+ def create_host_record(opts = {})
+ opts = setup_opts(opts, [:host, :data, :domain, :type, :ttl])
+ zone = find_or_create_zone(opts[:domain])
+ opts_to_hosts(opts).each do |host|
+ zone.records.create(host)
+ end
+ end
+
+ def destroy_host_record(opts = {})
+ opts = setup_opts(opts, [:host, :domain])
+
+ find_hosts(opts).each do |h|
+ h.destroy || raise("Failed to destroy #{h.hostname}")
+ end
+ end
+
+ def update_host_record(old_opts={}, new_opts={})
+ old_opts = setup_opts(old_opts, [:host, :domain, :type])
+ new_opts = setup_opts(new_opts, [:host, :domain, :type, :data])
+
+ # Tricky to update existing hosts since zerigo needs a separate host
+ # entry for multiple records of same type (MX, etc), so take the easy
+ # way out and destroy/create instead of update
+ destroy_host_record(old_opts)
+ create_host_record(new_opts)
+ end
+
end
end
end