Skip to content

Commit

Permalink
Add RecordsService
Browse files Browse the repository at this point in the history
  • Loading branch information
weppos committed Dec 14, 2014
1 parent 4dcb03f commit 3210620
Show file tree
Hide file tree
Showing 12 changed files with 412 additions and 149 deletions.
20 changes: 15 additions & 5 deletions lib/dnsimple/client.rb
@@ -1,5 +1,6 @@
require 'dnsimple/version'
require 'dnsimple/compatibility'
require 'dnsimple/client/records_service'

module Dnsimple

Expand Down Expand Up @@ -96,13 +97,22 @@ def delete(path, options = {})
def request(method, path, options)
response = HTTParty.send(method, api_endpoint + path, base_options.merge(options))

if response.code == 401 && response.headers[HEADER_OTP_TOKEN] == "required"
raise TwoFactorAuthenticationRequired, response["message"]
elsif response.code == 401
raise AuthenticationFailed, response["message"]
case response.code
when 200..299
response
when 401
raise (response.headers[HEADER_OTP_TOKEN] == "required" ? TwoFactorAuthenticationRequired : AuthenticationFailed), response["message"]
when 404
raise RecordNotFound.new(response)
else
raise RequestError(response)
end
end


response
# @return [Dnsimple::Client::RecordsService] The record-related API proxy.
def records
@records_service ||= Client::RecordsService.new(self)
end


Expand Down
100 changes: 100 additions & 0 deletions lib/dnsimple/client/records_service.rb
@@ -0,0 +1,100 @@
module Dnsimple
class Client
class RecordsService < Struct.new(:client)

# Lists the domain records in the account.
#
# @see http://developer.dnsimple.com/domains/records/#list
#
# @param [#to_s] domain The domain id or domain name.
# @param [Hash] options
#
# @return [Array<Record>]
# @raise [RecordNotFound]
# @raise [RequestError] When the request fails.
def list(domain, options = {})
response = client.get("v1/domains/#{domain}/records", options)

response.map { |r| Record.new(r["record"]) }
end

# Creates the record in the account.
#
# @see http://developer.dnsimple.com/domains/records/#create
#
# @param [#to_s] domain The domain id or domain name.
# @param [Hash] attributes
#
# @return [Record]
# @raise [RecordNotFound]
# @raise [RequestError] When the request fails.
def create(domain, attributes = {})
validate_mandatory_attributes(attributes, [:name, :record_type, :content])
options = { body: { record: attributes }}
response = client.post("v1/domains/#{domain}/records", options)

Record.new(response["record"])
end

# Gets a specific record in the account.
#
# @see http://developer.dnsimple.com/domains/records/#get
#
# @param [#to_s] domain The domain id or domain name.
# @param [Fixnum] record The record id.
#
# @return [Record]
# @raise [RecordNotFound]
# @raise [RequestError] When the request fails.
def find(domain, record)
response = client.get("v1/domains/#{domain}/records/#{record}")

Record.new(response["record"])
end

# Updates the record in the account.
#
# @see http://developer.dnsimple.com/domains/records/#update
#
# @param [#to_s] domain The domain id or domain name.
# @param [Fixnum] record The record id.
# @param [Hash] attributes
#
# @return [Record]
# @raise [RecordNotFound]
# @raise [RequestError] When the request fails.
def update(domain, record, attributes = {})
options = { body: { record: attributes }}
response = client.put("v1/domains/#{domain}/records/#{record}", options)

Record.new(response["record"])
end

# Deletes a specific record from the account.
#
# WARNING: this cannot be undone.
#
# @see http://developer.dnsimple.com/domains/records/#delete
#
# @param [#to_s] domain The domain id or domain name.
# @param [Fixnum] record The record id.
#
# @return [void]
# @raise [RecordNotFound]
# @raise [RequestError] When the request fails.
def delete(domain, record)
client.delete("v1/domains/#{domain}/records/#{record}")
end


private

def validate_mandatory_attributes(attributes, required)
required.each do |name|
attributes.key?(name) or raise(ArgumentError, ":#{name} is required")
end
end

end
end
end
24 changes: 14 additions & 10 deletions lib/dnsimple/error.rb
Expand Up @@ -3,20 +3,24 @@ module Dnsimple
class Error < StandardError
end

class RecordExists < Error
end

class RecordNotFound < Error
class RequestError < Error
attr_reader :response

def initialize(*args)
if args.size == 2
message, @response = *args
super("#{message}: #{response["error"]}")
else
@response = args.first
super("#{response.code}")
end
end
end

# An exception that is raised if a method is called with missing or invalid parameter values.
class ValidationError < Error
class RecordExists < Error
end

class RequestError < Error
def initialize(description, response)
super("#{description}: #{response["error"]}")
end
class RecordNotFound < RequestError
end

class AuthenticationError < Error
Expand Down
96 changes: 11 additions & 85 deletions lib/dnsimple/record.rb
@@ -1,94 +1,20 @@
module Dnsimple

class Record < Base
Aliases = {
'priority' => 'prio',
'time-to-live' => 'ttl'
}

attr_accessor :id
attr_accessor :domain
attr_accessor :domain_id
attr_accessor :name
attr_accessor :type
attr_accessor :content
attr_accessor :ttl
attr_accessor :prio
attr_accessor :record_type


def fqdn
[name, domain.name].delete_if { |v| v !~ BLANK_REGEX }.join(".")
end

def save(options={})
record_hash = {}
%w(name content ttl prio).each do |attribute|
record_hash[Record.resolve(attribute)] = self.send(attribute)
end

options.merge!(:body => {:record => record_hash})

response = Client.put("v1/domains/#{domain.id}/records/#{id}", options)

case response.code
when 200
self
else
raise RequestError.new("Error updating record", response)
end
end

def delete(options={})
Client.delete("v1/domains/#{domain.id}/records/#{id}", options)
end
alias :destroy :delete

def self.resolve(name)
Record::Aliases[name] || name
end

def self.create(domain, name, record_type, content, options={})
record_hash = {:name => name, :record_type => record_type, :content => content}
record_hash[:ttl] = options.delete(:ttl) || 3600
record_hash[:prio] = options.delete(:priority)
record_hash[:prio] = options.delete(:prio) || ''

options.merge!({:body => {:record => record_hash}})

response = Client.post("v1/domains/#{domain.name}/records", options)

case response.code
when 201
new({:domain => domain}.merge(response["record"]))
when 406
raise RecordExists, "Record #{name}.#{domain.name} already exists"
else
raise RequestError.new("Error creating record", response)
end
end

def self.find(domain, id, options={})
response = Client.get("v1/domains/#{domain.name}/records/#{id}", options)

case response.code
when 200
new({:domain => domain}.merge(response["record"]))
when 404
raise RecordNotFound, "Could not find record #{id} for domain #{domain.name}"
else
raise RequestError.new("Error finding record", response)
end
end

def self.all(domain, options={})
response = Client.get("v1/domains/#{domain.name}/records", options)

case response.code
when 200
response.map { |r| new({:domain => domain}.merge(r["record"])) }
else
raise RequestError.new("Error listing records", response)
end
end

attr_accessor :priority
attr_accessor :created_at
attr_accessor :updated_at

alias :prio :priority
alias :prio= :priority=
alias :record_type :type
alias :record_type= :type=
end

end

0 comments on commit 3210620

Please sign in to comment.