class GlobodnsClient::Connection
Public Class Methods
new(options)
click to toggle source
# File lib/globodns_client/connection.rb, line 6 def initialize(options) @bearer_token = options[:bearer_token] @host = options[:host] @timeout = options[:timeout] || 30 raise ArgumentError, "You must inform the bearer token and host for GloboDNS" unless @bearer_token && @host end
Public Instance Methods
delete_record(key, kind, content = [], remove_all = true)
click to toggle source
# File lib/globodns_client/connection.rb, line 112 def delete_record(key, kind, content = [], remove_all = true) if !remove_all and content.empty? raise GlobodnsClient::MissingContent, "Record not found for (#{key}) with content (#{content})" end zone = get_zone(key, kind) if remove_all and content.empty? records = get_record(key, kind, zone) else records = get_record_matching(key, kind, zone, content) end unless records raise GlobodnsClient::NotFound, "Record not found for (#{key})" end response=[] records.each do |record| response << request('delete', 'record', nil, record[:id]) end begin schedule_export rescue Exception ensure response end end
get_domain(key)
click to toggle source
# File lib/globodns_client/connection.rb, line 17 def get_domain(key) domain = key.dup domain.chomp!('.') res = {} while domain.count('.') >= 1 res = request('get','domain', domain) if !res.empty? domain = "" else domain.gsub!(/^([a-zA-Z0-9\-_]*.)/,'') end end res unless res.empty? end
get_record(key, kind, zone)
click to toggle source
# File lib/globodns_client/connection.rb, line 65 def get_record(key, kind, zone) zone.flatten! res = [] zone = get_zone(key, kind) if zone.nil? host = get_host(key, zone, kind) response = request('get', 'record', host, zone[0][:domain][:id], kind) response.each do |r| res << r[kind.downcase.to_sym] unless r[kind.downcase.to_sym].nil? end res.empty? ? false : res end
get_record_matching(key, kind, zone, content=[])
click to toggle source
# File lib/globodns_client/connection.rb, line 77 def get_record_matching(key, kind, zone, content=[]) matching = [] records = get_record(key, kind, zone) return false unless records records.each do |record| matching << record if content.include? record[:content] end matching.empty? ? false : matching end
get_zone(key, kind = 'A')
click to toggle source
# File lib/globodns_client/connection.rb, line 32 def get_zone(key, kind = 'A') res = request('get','domain', key, nil, kind) if kind.eql?('A') && !res.empty? res else get_zone_recursive(key, kind) end end
get_zone_recursive(key, kind = 'A')
click to toggle source
# File lib/globodns_client/connection.rb, line 41 def get_zone_recursive(key, kind = 'A') if kind.eql?('A') or kind.eql?('CNAME') or kind.eql?('TXT') domain = key.split('.', 2).last elsif kind.eql?('PTR') if key.include?('in-addr.arpa') domain = key.split('.', 2).last else match = key.match(/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/) domain = (match[1..3]+["0"]).reverse.join('.')+'.in-addr.arpa' end else raise "Not implemented" end res = request('get','domain', domain, nil, kind) if res.empty? if domain.count('.') > 1 && (kind == 'A' or kind == 'CNAME') or kind.eql?('TXT') || domain.count('.') > 2 && kind == 'PTR' res = get_zone_recursive(domain, kind) else raise GlobodnsClient::NotFound, "Couldn't find a proper zone for '#{key}'" end end res end
new_record(key, kind, value)
click to toggle source
# File lib/globodns_client/connection.rb, line 90 def new_record(key, kind, value) zone = get_domain key unless zone.nil? a_records = get_record(key, 'A', zone) case kind when 'A' raise GlobodnsClient::AlreadyExists, "Item (#{key}) already exists with reference (#{a_records[0][:content]})" if (a_records and a_records.collect{|r| r[:content]}.include? value) when 'CNAME' cname_records = get_record(key, 'CNAME', zone) raise GlobodnsClient::AlreadyExists, "Item (#{key}) already exists" if a_records or cname_records end host = get_host(key, zone, kind) response = request('post', 'record', host, zone[0][:domain][:id], kind, value) end begin schedule_export rescue Exception end response['record'] end
set_token(token)
click to toggle source
# File lib/globodns_client/connection.rb, line 13 def set_token token @bearer_token = token end
Private Instance Methods
get_host(key, zone, kind)
click to toggle source
# File lib/globodns_client/connection.rb, line 143 def get_host(key, zone, kind) if kind.eql?('A') or kind.eql?('AAAA') or kind.eql?('CNAME') or kind.eql?('TXT') host = key.split('.'+zone[0][:domain][:name])[0] elsif kind.eql?('PTR') case zone[0][:domain][:name].count('.') when 4, 5 host = key.split('.').last when 3 host = key.split('.')[2..3].reverse.join('.') when 2 host = key.split('.')[1..3].reverse.join('.') else raise "Error" end else raise "Not implemented" end end
request(method,kind,value,id = nil, type = nil, addr = nil)
click to toggle source
# File lib/globodns_client/connection.rb, line 162 def request(method,kind,value,id = nil, type = nil, addr = nil) raise ArgumentError, "Invalid request. id shouldn't be nil" if kind.eql?('record') && id.nil? headers = {'Authorization' => "Bearer #{@bearer_token}", 'Content-type' => 'application/json'} case kind when 'domain' uri = 'domains.json' when 'record' uri = "domains/#{id}/records.json" when 'export' uri = 'bind9/schedule_export.json' end case method when 'get' if type.eql?('A') or type.eql?('AAAA') or type.eql?('CNAME') or type.eql?('TXT') headers[:params] = {query: value} elsif type.eql?('PTR') headers[:params] = {query: value, reverse: true} elsif kind.eql?('domain') headers[:params] = {query: value} else raise "Not implemented" end when 'post' if kind.eql?('record') payload = {kind => {'name'=> value, 'type' => type, 'content' => addr}} payload = payload.to_json end when 'delete' uri = "records/#{id}.json" end response = RestClient::Request.execute( method: method, url: "#{@host}/#{uri}", timeout: @timeout, headers: headers, payload: payload, ) if response.code < 200 || response.code > 399 raise "Couldn't get a response from GloboDNS - code (#{response.code} / message #{response.body})" end method.eql?('delete') ? "" : JSON.parse(response.body, {:symbolize_names => true, :object_class => Hash}) end