[Dynect] Extract Dynect DNS provider to fog-dynect.
This commit is contained in:
parent
f99adc8907
commit
1d2700570e
|
@ -55,6 +55,7 @@ Gem::Specification.new do |s|
|
||||||
s.add_dependency("fog-atmos")
|
s.add_dependency("fog-atmos")
|
||||||
s.add_dependency("fog-aws", ">= 0.6.0")
|
s.add_dependency("fog-aws", ">= 0.6.0")
|
||||||
s.add_dependency("fog-brightbox", "~> 0.4")
|
s.add_dependency("fog-brightbox", "~> 0.4")
|
||||||
|
s.add_dependency("fog-dynect")
|
||||||
s.add_dependency("fog-ecloud", "= 0.1.1")
|
s.add_dependency("fog-ecloud", "= 0.1.1")
|
||||||
s.add_dependency("fog-google", ">= 0.0.2")
|
s.add_dependency("fog-google", ">= 0.0.2")
|
||||||
s.add_dependency("fog-local")
|
s.add_dependency("fog-local")
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
require 'fog/dynect/dns'
|
|
|
@ -1,26 +0,0 @@
|
||||||
require 'nokogiri'
|
|
||||||
|
|
||||||
require 'fog/core'
|
|
||||||
require 'fog/xml'
|
|
||||||
|
|
||||||
module Fog
|
|
||||||
module Dynect
|
|
||||||
extend Fog::Provider
|
|
||||||
|
|
||||||
service(:dns, 'DNS')
|
|
||||||
|
|
||||||
class Mock
|
|
||||||
def self.job_id
|
|
||||||
Fog::Mock.random_numbers(8).to_i
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.token
|
|
||||||
Fog::Mock.random_hex(48)
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.version
|
|
||||||
[Fog::Mock.random_numbers(1), Fog::Mock.random_numbers(1), Fog::Mock.random_numbers(1)].join('.')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,157 +0,0 @@
|
||||||
require 'fog/dynect/core'
|
|
||||||
|
|
||||||
module Fog
|
|
||||||
module DNS
|
|
||||||
class Dynect < Fog::Service
|
|
||||||
requires :dynect_customer, :dynect_username, :dynect_password
|
|
||||||
recognizes :timeout, :persistent, :job_poll_timeout
|
|
||||||
recognizes :provider # remove post deprecation
|
|
||||||
|
|
||||||
model_path 'fog/dynect/models/dns'
|
|
||||||
model :record
|
|
||||||
collection :records
|
|
||||||
model :zone
|
|
||||||
collection :zones
|
|
||||||
|
|
||||||
request_path 'fog/dynect/requests/dns'
|
|
||||||
request :delete_record
|
|
||||||
request :delete_zone
|
|
||||||
request :get_node_list
|
|
||||||
request :get_all_records
|
|
||||||
request :get_record
|
|
||||||
request :get_zone
|
|
||||||
request :post_record
|
|
||||||
request :post_session
|
|
||||||
request :post_zone
|
|
||||||
request :put_zone
|
|
||||||
request :put_record
|
|
||||||
|
|
||||||
class JobIncomplete < Error; end
|
|
||||||
|
|
||||||
class Mock
|
|
||||||
def initialize(options={})
|
|
||||||
@dynect_customer = options[:dynect_customer]
|
|
||||||
@dynect_username = options[:dynect_username]
|
|
||||||
@dynect_password = options[:dynect_password]
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.data
|
|
||||||
@data ||= {
|
|
||||||
:zones => {}
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.reset
|
|
||||||
@data = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
def auth_token
|
|
||||||
@auth_token ||= Fog::Dynect::Mock.token
|
|
||||||
end
|
|
||||||
|
|
||||||
def data
|
|
||||||
self.class.data
|
|
||||||
end
|
|
||||||
|
|
||||||
def reset_data
|
|
||||||
self.class.reset
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Real
|
|
||||||
def initialize(options={})
|
|
||||||
@dynect_customer = options[:dynect_customer]
|
|
||||||
@dynect_username = options[:dynect_username]
|
|
||||||
@dynect_password = options[:dynect_password]
|
|
||||||
|
|
||||||
@connection_options = options[:connection_options] || {}
|
|
||||||
@host = 'api-v4.dynect.net'
|
|
||||||
@port = options[:port] || 443
|
|
||||||
@path = options[:path] || '/REST'
|
|
||||||
@persistent = options[:persistent] || false
|
|
||||||
@scheme = options[:scheme] || 'https'
|
|
||||||
@version = options[:version] || '3.5.2'
|
|
||||||
@job_poll_timeout = options[:job_poll_timeout] || 10
|
|
||||||
@connection = Fog::XML::Connection.new("#{@scheme}://#{@host}:#{@port}", @persistent, @connection_options)
|
|
||||||
end
|
|
||||||
|
|
||||||
def auth_token
|
|
||||||
@auth_token ||= post_session.body['data']['token']
|
|
||||||
end
|
|
||||||
|
|
||||||
def request(params)
|
|
||||||
begin
|
|
||||||
# any request could redirect to a job
|
|
||||||
params[:expects] = Array(params[:expects]) | [307]
|
|
||||||
|
|
||||||
params[:headers] ||= {}
|
|
||||||
params[:headers]['Content-Type'] = 'application/json'
|
|
||||||
params[:headers]['API-Version'] = @version
|
|
||||||
params[:headers]['Auth-Token'] = auth_token unless params[:path] == 'Session'
|
|
||||||
params[:path] = "#{@path}/#{params[:path]}" unless params[:path] =~ %r{^#{Regexp.escape(@path)}/}
|
|
||||||
|
|
||||||
response = @connection.request(params)
|
|
||||||
|
|
||||||
if response.body.empty?
|
|
||||||
response.body = {}
|
|
||||||
elsif response.headers['Content-Type'] == 'application/json'
|
|
||||||
response.body = Fog::JSON.decode(response.body)
|
|
||||||
end
|
|
||||||
|
|
||||||
if response.body['status'] == 'failure'
|
|
||||||
raise Error, response.body['msgs'].first['INFO']
|
|
||||||
end
|
|
||||||
|
|
||||||
if params[:path] !~ %r{^/REST/Job/}
|
|
||||||
if response.status == 307
|
|
||||||
response = poll_job(response, params[:expects], @job_poll_timeout)
|
|
||||||
|
|
||||||
# Dynect intermittently returns 200 with an incomplete status. When this
|
|
||||||
# happens, the job should still be polled.
|
|
||||||
elsif response.status == 200 && response.body['status'].eql?('incomplete')
|
|
||||||
response.headers['Location'] = "/REST/Job/#{ response.body['job_id'] }"
|
|
||||||
response = poll_job(response, params[:expects], @job_poll_timeout)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
response
|
|
||||||
rescue Excon::Errors::HTTPStatusError => error
|
|
||||||
if @auth_token && error.message =~ /login: (Bad or expired credentials|inactivity logout)/
|
|
||||||
@auth_token = nil
|
|
||||||
retry
|
|
||||||
else
|
|
||||||
raise error
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
response
|
|
||||||
end
|
|
||||||
|
|
||||||
def poll_job(response, original_expects, time_to_wait)
|
|
||||||
job_location = response.headers['Location']
|
|
||||||
|
|
||||||
begin
|
|
||||||
Fog.wait_for(time_to_wait) do
|
|
||||||
response = request(
|
|
||||||
:expects => original_expects,
|
|
||||||
:idempotent => true,
|
|
||||||
:method => :get,
|
|
||||||
:path => job_location
|
|
||||||
)
|
|
||||||
response.body['status'] != 'incomplete'
|
|
||||||
end
|
|
||||||
|
|
||||||
rescue Errors::TimeoutError => error
|
|
||||||
if response.body['status'] == 'incomplete'
|
|
||||||
raise JobIncomplete.new("Job #{response.body['job_id']} is still incomplete")
|
|
||||||
else
|
|
||||||
raise error
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
response
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,67 +0,0 @@
|
||||||
require 'fog/core/model'
|
|
||||||
|
|
||||||
module Fog
|
|
||||||
module DNS
|
|
||||||
class Dynect
|
|
||||||
class Record < Fog::Model
|
|
||||||
extend Fog::Deprecation
|
|
||||||
|
|
||||||
identity :id
|
|
||||||
attribute :name, :aliases => [:fqdn, 'fqdn']
|
|
||||||
attribute :rdata
|
|
||||||
attribute :serial_style
|
|
||||||
attribute :ttl
|
|
||||||
attribute :type, :aliases => 'record_type'
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
requires :identity, :name, :type, :zone
|
|
||||||
service.delete_record(type, zone.identity, name, identity)
|
|
||||||
true
|
|
||||||
end
|
|
||||||
|
|
||||||
def save(replace=false)
|
|
||||||
requires :name, :type, :rdata, :zone
|
|
||||||
|
|
||||||
options = {
|
|
||||||
:ttl => ttl
|
|
||||||
}
|
|
||||||
options.delete_if {|key, value| value.nil?}
|
|
||||||
|
|
||||||
if replace
|
|
||||||
data = service.put_record(type, zone.identity, name, rdata, options).body['data']
|
|
||||||
else
|
|
||||||
data = service.post_record(type, zone.identity, name, rdata, options).body['data']
|
|
||||||
end
|
|
||||||
# avoid overwriting zone object with zone string
|
|
||||||
data = data.reject {|key, value| key == 'zone'}
|
|
||||||
merge_attributes(data)
|
|
||||||
|
|
||||||
zone.publish
|
|
||||||
records = service.get_record(type, zone.identity, name).body['data']
|
|
||||||
# data in format ['/REST/xRecord/domain/fqdn/identity]
|
|
||||||
records.map! do |record|
|
|
||||||
tokens = record.split('/')
|
|
||||||
{
|
|
||||||
:identity => tokens.last,
|
|
||||||
:type => tokens[2][0...-6] # everything before 'Record'
|
|
||||||
}
|
|
||||||
end
|
|
||||||
record = records.find {|record| record[:type] == type}
|
|
||||||
merge_attributes(record)
|
|
||||||
|
|
||||||
true
|
|
||||||
end
|
|
||||||
|
|
||||||
def zone
|
|
||||||
@zone
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def zone=(new_zone)
|
|
||||||
@zone = new_zone
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,48 +0,0 @@
|
||||||
require 'fog/core/collection'
|
|
||||||
require 'fog/dynect/models/dns/record'
|
|
||||||
|
|
||||||
module Fog
|
|
||||||
module DNS
|
|
||||||
class Dynect
|
|
||||||
class Records < Fog::Collection
|
|
||||||
attribute :zone
|
|
||||||
|
|
||||||
model Fog::DNS::Dynect::Record
|
|
||||||
|
|
||||||
def all(options = {})
|
|
||||||
requires :zone
|
|
||||||
data = []
|
|
||||||
service.get_all_records(zone.domain, options).body['data'].each do |records|
|
|
||||||
(type, list) = records
|
|
||||||
list.each do |record|
|
|
||||||
data << {
|
|
||||||
:identity => record['record_id'],
|
|
||||||
:fqdn => record['fqdn'],
|
|
||||||
:type => record['record_type'],
|
|
||||||
:rdata => record['rdata']
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
load(data)
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(record_id)
|
|
||||||
requires :zone
|
|
||||||
|
|
||||||
# there isn't a way to look up by just id
|
|
||||||
# must have type and domain for 'get_record' request
|
|
||||||
# so we pick it from the list returned by 'all'
|
|
||||||
|
|
||||||
list = all
|
|
||||||
list.detect {|e| e.id == record_id}
|
|
||||||
end
|
|
||||||
|
|
||||||
def new(attributes = {})
|
|
||||||
requires :zone
|
|
||||||
super({:zone => zone}.merge!(attributes))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,56 +0,0 @@
|
||||||
require 'fog/core/model'
|
|
||||||
require 'fog/dynect/models/dns/records'
|
|
||||||
|
|
||||||
module Fog
|
|
||||||
module DNS
|
|
||||||
class Dynect
|
|
||||||
class Zone < Fog::Model
|
|
||||||
identity :domain
|
|
||||||
|
|
||||||
attribute :domain, :aliases => 'zone'
|
|
||||||
attribute :email, :aliases => 'rname'
|
|
||||||
attribute :serial
|
|
||||||
attribute :serial_style
|
|
||||||
attribute :ttl
|
|
||||||
attribute :type, :aliases => 'zone_type'
|
|
||||||
|
|
||||||
def initialize(attributes={})
|
|
||||||
super
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
requires :domain
|
|
||||||
service.delete_zone(domain)
|
|
||||||
true
|
|
||||||
end
|
|
||||||
|
|
||||||
undef_method :domain=
|
|
||||||
def domain=(new_domain)
|
|
||||||
attributes[:domain] = new_domain.split('/').last
|
|
||||||
end
|
|
||||||
|
|
||||||
def publish
|
|
||||||
requires :identity
|
|
||||||
data = service.put_zone(identity, 'publish' => true)
|
|
||||||
true
|
|
||||||
end
|
|
||||||
|
|
||||||
def records
|
|
||||||
@records ||= Fog::DNS::Dynect::Records.new(:zone => self, :service => service)
|
|
||||||
end
|
|
||||||
|
|
||||||
def nameservers
|
|
||||||
raise 'nameservers Not Implemented'
|
|
||||||
end
|
|
||||||
|
|
||||||
def save
|
|
||||||
self.ttl ||= 3600
|
|
||||||
requires :domain, :email, :ttl
|
|
||||||
data = service.post_zone(email, ttl, domain).body['data']
|
|
||||||
merge_attributes(data)
|
|
||||||
true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,25 +0,0 @@
|
||||||
require 'fog/core/collection'
|
|
||||||
require 'fog/dynect/models/dns/zone'
|
|
||||||
|
|
||||||
module Fog
|
|
||||||
module DNS
|
|
||||||
class Dynect
|
|
||||||
class Zones < Fog::Collection
|
|
||||||
model Fog::DNS::Dynect::Zone
|
|
||||||
|
|
||||||
def all
|
|
||||||
data = service.get_zone.body['data'].map do |zone|
|
|
||||||
{ :domain => zone }
|
|
||||||
end
|
|
||||||
load(data)
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(zone_id)
|
|
||||||
new(service.get_zone('zone' => zone_id).body['data'])
|
|
||||||
rescue Excon::Errors::NotFound
|
|
||||||
nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,55 +0,0 @@
|
||||||
module Fog
|
|
||||||
module DNS
|
|
||||||
class Dynect
|
|
||||||
class Real
|
|
||||||
# Delete a record
|
|
||||||
#
|
|
||||||
# ==== Parameters
|
|
||||||
# * type<~String> - type of record in ['AAAA', 'ANY', 'A', 'CNAME', 'DHCID', 'DNAME', 'DNSKEY', 'DS', 'KEY', 'LOC', 'MX', 'NSA', 'NS', 'PTR', 'PX', 'RP', 'SOA', 'SPF', 'SRV', 'SSHFP', 'TXT']
|
|
||||||
# * zone<~String> - zone of record
|
|
||||||
# * fqdn<~String> - fqdn of record
|
|
||||||
# * record_id<~String> - id of record
|
|
||||||
|
|
||||||
def delete_record(type, zone, fqdn, record_id)
|
|
||||||
request(
|
|
||||||
:expects => 200,
|
|
||||||
:idempotent => true,
|
|
||||||
:method => :delete,
|
|
||||||
:path => ["#{type.to_s.upcase}Record", zone, fqdn, record_id].join('/')
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Mock
|
|
||||||
def delete_record(type, zone, fqdn, record_id)
|
|
||||||
raise Fog::DNS::Dynect::NotFound unless zone = self.data[:zones][zone]
|
|
||||||
|
|
||||||
raise Fog::DNS::Dynect::NotFound unless zone[:records][type].find { |record| record[:fqdn] == fqdn && record[:record_id] == record_id.to_i }
|
|
||||||
|
|
||||||
zone[:records_to_delete] << {
|
|
||||||
:type => type,
|
|
||||||
:fqdn => fqdn,
|
|
||||||
:record_id => record_id.to_i
|
|
||||||
}
|
|
||||||
|
|
||||||
response = Excon::Response.new
|
|
||||||
response.status = 200
|
|
||||||
|
|
||||||
response.body = {
|
|
||||||
"status" => "success",
|
|
||||||
"data" => {},
|
|
||||||
"job_id" => Fog::Dynect::Mock.job_id,
|
|
||||||
"msgs" => [{
|
|
||||||
"INFO" => "delete: Record will be deleted on zone publish",
|
|
||||||
"SOURCE" => "BLL",
|
|
||||||
"ERR_CD" => nil,
|
|
||||||
"LVL" => "INFO"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
|
|
||||||
response
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,41 +0,0 @@
|
||||||
module Fog
|
|
||||||
module DNS
|
|
||||||
class Dynect
|
|
||||||
class Real
|
|
||||||
# Delete a zone
|
|
||||||
#
|
|
||||||
# ==== Parameters
|
|
||||||
# * zone<~String> - zone to host
|
|
||||||
|
|
||||||
def delete_zone(zone)
|
|
||||||
request(
|
|
||||||
:expects => 200,
|
|
||||||
:method => :delete,
|
|
||||||
:path => "Zone/#{zone}"
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Mock
|
|
||||||
def delete_zone(zone)
|
|
||||||
self.data[:zones].delete(zone)
|
|
||||||
|
|
||||||
response = Excon::Response.new
|
|
||||||
response.status = 200
|
|
||||||
response.body = {
|
|
||||||
"status" => "success",
|
|
||||||
"data" => {},
|
|
||||||
"job_id" => Fog::Dynect::Mock.job_id,
|
|
||||||
"msgs" => [{
|
|
||||||
"ERR_CD" => '',
|
|
||||||
"INFO" => '',
|
|
||||||
"LVL" => '',
|
|
||||||
"SOURCE" => ''
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
response
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,56 +0,0 @@
|
||||||
module Fog
|
|
||||||
module DNS
|
|
||||||
class Dynect
|
|
||||||
class Real
|
|
||||||
# Get one or more node lists
|
|
||||||
#
|
|
||||||
# ==== Parameters
|
|
||||||
# * zone<~String> - zone to lookup node lists for
|
|
||||||
# * options<~Hash>
|
|
||||||
# * fqdn<~String> - fully qualified domain name of node to lookup
|
|
||||||
|
|
||||||
def get_all_records(zone, options = {})
|
|
||||||
requested_fqdn = options['fqdn'] || options[:fqdn]
|
|
||||||
request(
|
|
||||||
:expects => 200,
|
|
||||||
:idempotent => true,
|
|
||||||
:method => :get,
|
|
||||||
:path => ['AllRecord', zone, requested_fqdn].compact.join('/'),
|
|
||||||
:query => {'detail' => 'Y'} # return full records, instead of just resource URLs
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Mock
|
|
||||||
def get_all_records(zone, options = {})
|
|
||||||
raise Fog::DNS::Dynect::NotFound unless zone = self.data[:zones][zone]
|
|
||||||
|
|
||||||
response = Excon::Response.new
|
|
||||||
response.status = 200
|
|
||||||
|
|
||||||
data = [zone[:zone]]
|
|
||||||
|
|
||||||
if fqdn = options[:fqdn]
|
|
||||||
data = data | zone[:records].map { |type, records| records.select { |record| record[:fqdn] == fqdn } }.flatten.compact
|
|
||||||
else
|
|
||||||
data = data | zone[:records].map { |type, records| records.map { |record| record[:fqdn] } }.flatten
|
|
||||||
end
|
|
||||||
|
|
||||||
response.body = {
|
|
||||||
"status" => "success",
|
|
||||||
"data" => data,
|
|
||||||
"job_id" => Fog::Dynect::Mock.job_id,
|
|
||||||
"msgs" => [{
|
|
||||||
"INFO" => "get_tree: Here is your zone tree",
|
|
||||||
"SOURCE" => "BLL",
|
|
||||||
"ERR_CD" => nil,
|
|
||||||
"LVL" => "INFO"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
|
|
||||||
response
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,55 +0,0 @@
|
||||||
module Fog
|
|
||||||
module DNS
|
|
||||||
class Dynect
|
|
||||||
class Real
|
|
||||||
# Get one or more node lists
|
|
||||||
#
|
|
||||||
# ==== Parameters
|
|
||||||
# * zone<~String> - zone to lookup node lists for
|
|
||||||
# * options<~Hash>
|
|
||||||
# * fqdn<~String> - fully qualified domain name of node to lookup
|
|
||||||
|
|
||||||
def get_node_list(zone, options = {})
|
|
||||||
requested_fqdn = options['fqdn'] || options[:fqdn]
|
|
||||||
request(
|
|
||||||
:expects => 200,
|
|
||||||
:idempotent => true,
|
|
||||||
:method => :get,
|
|
||||||
:path => ['AllRecord', zone, requested_fqdn].compact.join('/')
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Mock
|
|
||||||
def get_node_list(zone, options = {})
|
|
||||||
raise Fog::DNS::Dynect::NotFound unless zone = self.data[:zones][zone]
|
|
||||||
|
|
||||||
response = Excon::Response.new
|
|
||||||
response.status = 200
|
|
||||||
|
|
||||||
data = [zone[:zone]]
|
|
||||||
|
|
||||||
if fqdn = options[:fqdn]
|
|
||||||
data = data | zone[:records].map { |type, records| records.select { |record| record[:fqdn] == fqdn } }.flatten.compact
|
|
||||||
else
|
|
||||||
data = data | zone[:records].map { |type, records| records.map { |record| record[:fqdn] } }.flatten
|
|
||||||
end
|
|
||||||
|
|
||||||
response.body = {
|
|
||||||
"status" => "success",
|
|
||||||
"data" => data,
|
|
||||||
"job_id" => Fog::Dynect::Mock.job_id,
|
|
||||||
"msgs" => [{
|
|
||||||
"INFO" => "get_tree: Here is your zone tree",
|
|
||||||
"SOURCE" => "BLL",
|
|
||||||
"ERR_CD" => nil,
|
|
||||||
"LVL" => "INFO"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
|
|
||||||
response
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,83 +0,0 @@
|
||||||
module Fog
|
|
||||||
module DNS
|
|
||||||
class Dynect
|
|
||||||
class Real
|
|
||||||
# List records of a given type
|
|
||||||
#
|
|
||||||
# ==== Parameters
|
|
||||||
# * type<~String> - type of record in ['AAAA', 'ANY', 'A', 'CNAME', 'DHCID', 'DNAME', 'DNSKEY', 'DS', 'KEY', 'LOC', 'MX', 'NSA', 'NS', 'PTR', 'PX', 'RP', 'SOA', 'SPF', 'SRV', 'SSHFP', 'TXT']
|
|
||||||
# * zone<~String> - name of zone to lookup
|
|
||||||
# * fqdn<~String> - name of fqdn to lookup
|
|
||||||
# * options<~Hash>:
|
|
||||||
# * record_id<~String> - id of record
|
|
||||||
|
|
||||||
def get_record(type, zone, fqdn, options = {})
|
|
||||||
request(
|
|
||||||
:expects => 200,
|
|
||||||
:idempotent => true,
|
|
||||||
:method => :get,
|
|
||||||
:path => ["#{type.to_s.upcase}Record", zone, fqdn, options['record_id']].compact.join('/')
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Mock
|
|
||||||
def get_record(type, zone, fqdn, options = {})
|
|
||||||
raise ArgumentError unless [
|
|
||||||
'AAAA', 'ANY', 'A', 'CNAME',
|
|
||||||
'DHCID', 'DNAME', 'DNSKEY',
|
|
||||||
'DS', 'KEY', 'LOC', 'MX',
|
|
||||||
'NSA', 'NS', 'PTR', 'PX',
|
|
||||||
'RP', 'SOA', 'SPF', 'SRV',
|
|
||||||
'SSHFP', 'TXT'
|
|
||||||
].include? type
|
|
||||||
raise Fog::DNS::Dynect::NotFound unless zone = self.data[:zones][zone]
|
|
||||||
|
|
||||||
response = Excon::Response.new
|
|
||||||
response.status = 200
|
|
||||||
|
|
||||||
if record_id = options['record_id']
|
|
||||||
raise Fog::DNS::Dynect::NotFound unless record = zone[:records][type].find { |record| record[:record_id] == record_id.to_i }
|
|
||||||
response.body = {
|
|
||||||
"status" => "success",
|
|
||||||
"data" => {
|
|
||||||
"zone" => record[:zone][:zone],
|
|
||||||
"ttl" => record[:ttl],
|
|
||||||
"fqdn" => record[:fqdn],
|
|
||||||
"record_type" => type,
|
|
||||||
"rdata" => record[:rdata],
|
|
||||||
"record_id" => record[:record_id]
|
|
||||||
},
|
|
||||||
"job_id" => Fog::Dynect::Mock.job_id,
|
|
||||||
"msgs" => [{
|
|
||||||
"INFO" => "get: Found the record",
|
|
||||||
"SOURCE" => "API-B",
|
|
||||||
"ERR_CD" => nil,
|
|
||||||
"LVL" => "INFO"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
else
|
|
||||||
records = if type == "ANY"
|
|
||||||
zone[:records].values.flatten.select { |record| record[:fqdn] == fqdn }
|
|
||||||
else
|
|
||||||
zone[:records][type].select { |record| record[:fqdn] == fqdn }
|
|
||||||
end
|
|
||||||
response.body = {
|
|
||||||
"status" => "success",
|
|
||||||
"data" => records.map { |record| "/REST/#{record[:type]}Record/#{record[:zone][:zone]}/#{record[:fqdn]}/#{record[:record_id]}" },
|
|
||||||
"job_id" => Fog::Dynect::Mock.job_id,
|
|
||||||
"msgs" => [{
|
|
||||||
"INFO" => "detail: Found #{records.size} record",
|
|
||||||
"SOURCE" => "BLL",
|
|
||||||
"ERR_CD" => nil,
|
|
||||||
"LVL" => "INFO"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
response
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,57 +0,0 @@
|
||||||
module Fog
|
|
||||||
module DNS
|
|
||||||
class Dynect
|
|
||||||
class Real
|
|
||||||
# Get one or more zones
|
|
||||||
#
|
|
||||||
# ==== Parameters
|
|
||||||
# * options<~Hash>:
|
|
||||||
# * zone<~String> - name of zone to lookup, or omit to return list of zones
|
|
||||||
|
|
||||||
def get_zone(options = {})
|
|
||||||
request(
|
|
||||||
:expects => 200,
|
|
||||||
:idempotent => true,
|
|
||||||
:method => :get,
|
|
||||||
:path => ['Zone', options['zone']].compact.join('/')
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Mock
|
|
||||||
def get_zone(options = {})
|
|
||||||
if options['zone']
|
|
||||||
raise Fog::DNS::Dynect::NotFound unless zone = self.data[:zones][options['zone']]
|
|
||||||
data = {
|
|
||||||
"zone_type" => zone[:zone_type],
|
|
||||||
"serial_style" => zone[:serial_style],
|
|
||||||
"serial" => zone[:serial],
|
|
||||||
"zone" => zone[:zone]
|
|
||||||
}
|
|
||||||
info = "get: Your zone, #{zone[:zone]}"
|
|
||||||
else
|
|
||||||
data = self.data[:zones].map { |zone, data| "/REST/Zone/#{zone}/" }
|
|
||||||
info = "get: Your #{data.size} zones"
|
|
||||||
end
|
|
||||||
|
|
||||||
response = Excon::Response.new
|
|
||||||
response.status = 200
|
|
||||||
|
|
||||||
response.body = {
|
|
||||||
"status" => "success",
|
|
||||||
"data" => data,
|
|
||||||
"job_id" => Fog::Dynect::Mock.job_id,
|
|
||||||
"msgs" => [{
|
|
||||||
"INFO" => info,
|
|
||||||
"SOURCE" => "BLL",
|
|
||||||
"ERR_CD" => nil,
|
|
||||||
"LVL" => "INFO"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
|
|
||||||
response
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,71 +0,0 @@
|
||||||
module Fog
|
|
||||||
module DNS
|
|
||||||
class Dynect
|
|
||||||
class Real
|
|
||||||
# Create a record
|
|
||||||
#
|
|
||||||
# ==== Parameters
|
|
||||||
# * type<~String> - type of record in ['AAAA', 'ANY', 'A', 'CNAME', 'DHCID', 'DNAME', 'DNSKEY', 'DS', 'KEY', 'LOC', 'MX', 'NSA', 'NS', 'PTR', 'PX', 'RP', 'SOA', 'SPF', 'SRV', 'SSHFP', 'TXT']
|
|
||||||
# * zone<~String> - zone of record
|
|
||||||
# * rdata<~Hash> - rdata for record
|
|
||||||
# * options<~Hash>: (options vary by type, listing below includes common parameters)
|
|
||||||
# * ttl<~Integer> - ttl for the record, defaults to zone ttl
|
|
||||||
|
|
||||||
def post_record(type, zone, fqdn, rdata, options = {})
|
|
||||||
options.merge!('rdata' => rdata)
|
|
||||||
request(
|
|
||||||
:body => Fog::JSON.encode(options),
|
|
||||||
:expects => 200,
|
|
||||||
:method => :post,
|
|
||||||
:path => ["#{type.to_s.upcase}Record", zone, fqdn].join('/')
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Mock
|
|
||||||
def post_record(type, zone, fqdn, rdata, options = {})
|
|
||||||
raise Fog::DNS::Dynect::NotFound unless zone = self.data[:zones][zone]
|
|
||||||
|
|
||||||
records = zone[:records]
|
|
||||||
record_id = zone[:next_record_id]
|
|
||||||
zone[:next_record_id] += 1
|
|
||||||
|
|
||||||
record = {
|
|
||||||
:type => type,
|
|
||||||
:zone => zone,
|
|
||||||
:fqdn => fqdn,
|
|
||||||
:rdata => rdata,
|
|
||||||
:ttl => options[:ttl] || zone[:ttl],
|
|
||||||
:record_id => record_id
|
|
||||||
}
|
|
||||||
|
|
||||||
records[type] << record
|
|
||||||
|
|
||||||
response = Excon::Response.new
|
|
||||||
response.status = 200
|
|
||||||
|
|
||||||
response.body = {
|
|
||||||
"status" => "success",
|
|
||||||
"data" => {
|
|
||||||
"zone" => record[:zone][:zone],
|
|
||||||
"ttl" => record[:ttl],
|
|
||||||
"fqdn" => record[:fqdn],
|
|
||||||
"record_type" => record[:type],
|
|
||||||
"rdata" => record[:rdata],
|
|
||||||
"record_id" => record[:record_id]
|
|
||||||
},
|
|
||||||
"job_id" => Fog::Dynect::Mock.job_id,
|
|
||||||
"msgs" => [{
|
|
||||||
"INFO"=>"add: Record added",
|
|
||||||
"SOURCE"=>"BLL",
|
|
||||||
"ERR_CD"=>nil,
|
|
||||||
"LVL"=>"INFO"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
|
|
||||||
response
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,43 +0,0 @@
|
||||||
module Fog
|
|
||||||
module DNS
|
|
||||||
class Dynect
|
|
||||||
class Real
|
|
||||||
def post_session
|
|
||||||
request(
|
|
||||||
:expects => 200,
|
|
||||||
:idempotent => true,
|
|
||||||
:method => :post,
|
|
||||||
:path => "Session",
|
|
||||||
:body => Fog::JSON.encode({
|
|
||||||
:customer_name => @dynect_customer,
|
|
||||||
:user_name => @dynect_username,
|
|
||||||
:password => @dynect_password
|
|
||||||
})
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Mock
|
|
||||||
def post_session
|
|
||||||
response = Excon::Response.new
|
|
||||||
response.status = 200
|
|
||||||
response.body = {
|
|
||||||
"status" => "success",
|
|
||||||
"data" => {
|
|
||||||
"token" => auth_token,
|
|
||||||
"version" => Fog::Dynect::Mock.version
|
|
||||||
},
|
|
||||||
"job_id" => Fog::Dynect::Mock.job_id,
|
|
||||||
"msgs"=>[{
|
|
||||||
"INFO"=>"login: Login successful",
|
|
||||||
"SOURCE"=>"BLL",
|
|
||||||
"ERR_CD"=>nil,
|
|
||||||
"LVL"=>"INFO"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
response
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,70 +0,0 @@
|
||||||
module Fog
|
|
||||||
module DNS
|
|
||||||
class Dynect
|
|
||||||
class Real
|
|
||||||
# Create a zone
|
|
||||||
#
|
|
||||||
# ==== Parameters
|
|
||||||
# * rname<~String> - administrative contact
|
|
||||||
# * ttl<~Integer> - time to live (in seconds) for records in this zone
|
|
||||||
# * zone<~String> - name of zone to host
|
|
||||||
# * options<~Hash>:
|
|
||||||
# * serial_style<~String> - style of serial number, in ['day', 'epoch', 'increment', 'minute']. Defaults to increment
|
|
||||||
|
|
||||||
def post_zone(rname, ttl, zone, options = {})
|
|
||||||
body = Fog::JSON.encode({
|
|
||||||
:rname => rname,
|
|
||||||
:token => auth_token,
|
|
||||||
:ttl => ttl
|
|
||||||
}.merge!(options))
|
|
||||||
|
|
||||||
request(
|
|
||||||
:body => body,
|
|
||||||
:expects => 200,
|
|
||||||
:method => :post,
|
|
||||||
:path => 'Zone/' << zone
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Mock
|
|
||||||
def post_zone(rname, ttl, zone, options = {})
|
|
||||||
new_zone = self.data[:zones][zone] = {
|
|
||||||
:next_record_id => 0,
|
|
||||||
:records => Hash.new do |records_hash, type|
|
|
||||||
records_hash[type] = []
|
|
||||||
end,
|
|
||||||
:records_to_delete => [],
|
|
||||||
:rname => rname,
|
|
||||||
:serial_style => options[:serial_style] || "increment",
|
|
||||||
:serial => 0,
|
|
||||||
:ttl => ttl,
|
|
||||||
:zone => zone,
|
|
||||||
:zone_type => "Primary"
|
|
||||||
}
|
|
||||||
|
|
||||||
response = Excon::Response.new
|
|
||||||
response.status = 200
|
|
||||||
response.body = {
|
|
||||||
"status" => "success",
|
|
||||||
"data" => {
|
|
||||||
"zone_type" => new_zone[:zone_type],
|
|
||||||
"serial_style" => new_zone[:serial_style],
|
|
||||||
"serial" => new_zone[:serial],
|
|
||||||
"zone" => zone
|
|
||||||
},
|
|
||||||
"job_id" => Fog::Dynect::Mock.job_id,
|
|
||||||
"msgs" => [{
|
|
||||||
"INFO" => "create: New zone #{zone} created. Publish it to put it on our server.",
|
|
||||||
"SOURCE" => "BLL",
|
|
||||||
"ERR_CD" => nil,
|
|
||||||
"LVL" => "INFO"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
|
|
||||||
response
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,76 +0,0 @@
|
||||||
module Fog
|
|
||||||
module DNS
|
|
||||||
class Dynect
|
|
||||||
class Real
|
|
||||||
# Update or replace a record
|
|
||||||
#
|
|
||||||
# ==== Parameters
|
|
||||||
# * type<~String> - type of record in ['AAAA', 'ANY', 'A', 'CNAME', 'DHCID', 'DNAME', 'DNSKEY', 'DS', 'KEY', 'LOC', 'MX', 'NSA', 'NS', 'PTR', 'PX', 'RP', 'SOA', 'SPF', 'SRV', 'SSHFP', 'TXT']
|
|
||||||
# * zone<~String> - zone of record
|
|
||||||
# * rdata<~Hash> - rdata for record
|
|
||||||
# * options<~Hash>: (options vary by type, listing below includes common parameters)
|
|
||||||
# * ttl<~Integer> - ttl for the record, defaults to zone ttl
|
|
||||||
|
|
||||||
def put_record(type, zone, fqdn, rdata, options = {})
|
|
||||||
options.merge!('rdata' => rdata)
|
|
||||||
type.to_s.upcase!
|
|
||||||
options = {"#{type}Records" => [options]} unless options['record_id']
|
|
||||||
path = ["#{type}Record", zone, fqdn].join('/')
|
|
||||||
path += "/#{options.delete('record_id')}" if options['record_id']
|
|
||||||
request(
|
|
||||||
:body => Fog::JSON.encode(options),
|
|
||||||
:expects => 200,
|
|
||||||
:idempotent => true,
|
|
||||||
:method => :put,
|
|
||||||
:path => path
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Mock
|
|
||||||
def put_record(type, zone, fqdn, rdata, options = {})
|
|
||||||
raise Fog::DNS::Dynect::NotFound unless zone = self.data[:zones][zone]
|
|
||||||
|
|
||||||
records = zone[:records]
|
|
||||||
record_id = zone[:next_record_id]
|
|
||||||
zone[:next_record_id] += 1
|
|
||||||
|
|
||||||
record = {
|
|
||||||
:type => type,
|
|
||||||
:zone => zone,
|
|
||||||
:fqdn => fqdn,
|
|
||||||
:rdata => rdata,
|
|
||||||
:ttl => options[:ttl] || zone[:ttl],
|
|
||||||
:record_id => record_id
|
|
||||||
}
|
|
||||||
|
|
||||||
records[type] << record
|
|
||||||
|
|
||||||
response = Excon::Response.new
|
|
||||||
response.status = 200
|
|
||||||
|
|
||||||
response.body = {
|
|
||||||
"status" => "success",
|
|
||||||
"data" => {
|
|
||||||
"zone" => record[:zone][:zone],
|
|
||||||
"ttl" => record[:ttl],
|
|
||||||
"fqdn" => record[:fqdn],
|
|
||||||
"record_type" => record[:type],
|
|
||||||
"rdata" => record[:rdata],
|
|
||||||
"record_id" => record[:record_id]
|
|
||||||
},
|
|
||||||
"job_id" => Fog::Dynect::Mock.job_id,
|
|
||||||
"msgs" => [{
|
|
||||||
"INFO"=>"add: Record added",
|
|
||||||
"SOURCE"=>"BLL",
|
|
||||||
"ERR_CD"=>nil,
|
|
||||||
"LVL"=>"INFO"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
|
|
||||||
response
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,76 +0,0 @@
|
||||||
module Fog
|
|
||||||
module DNS
|
|
||||||
class Dynect
|
|
||||||
class Real
|
|
||||||
# Update a zone
|
|
||||||
#
|
|
||||||
# ==== Parameters
|
|
||||||
# * zone<~String> - name or id of zone
|
|
||||||
# * options<~Hash>:
|
|
||||||
# * freeze<~Boolean> - causes zone to become frozen
|
|
||||||
# * publish<~Boolean> - causes all pending changes to be pushed to nameservers
|
|
||||||
# * thaw<~Boolean> - causes zone to cease being frozen
|
|
||||||
|
|
||||||
def put_zone(zone, options = {})
|
|
||||||
request(
|
|
||||||
:body => Fog::JSON.encode(options),
|
|
||||||
:expects => 200,
|
|
||||||
:idempotent => true,
|
|
||||||
:method => :put,
|
|
||||||
:path => 'Zone/' << zone
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Mock
|
|
||||||
def put_zone(zone, options = {})
|
|
||||||
raise Fog::DNS::Dynect::NotFound unless zone = self.data[:zones][zone]
|
|
||||||
|
|
||||||
raise ArgumentError unless options.size == 1
|
|
||||||
|
|
||||||
response = Excon::Response.new
|
|
||||||
response.status = 200
|
|
||||||
|
|
||||||
data = {}
|
|
||||||
|
|
||||||
if options['freeze']
|
|
||||||
zone['frozen'] = true
|
|
||||||
info = "freeze: Your zone is now frozen"
|
|
||||||
elsif options['publish']
|
|
||||||
zone[:changes] = {}
|
|
||||||
zone[:records_to_delete].each do |record|
|
|
||||||
zone[:records][record[:type]].delete_if { |r| r[:fqdn] == record[:fqdn] && r[:record_id] == record[:record_id] }
|
|
||||||
end
|
|
||||||
zone[:records_to_delete] = []
|
|
||||||
data = {
|
|
||||||
"zone_type" => zone[:zone_type],
|
|
||||||
"serial_style" => zone[:serial_style],
|
|
||||||
"serial" => zone[:serial] += 1,
|
|
||||||
"zone" => zone[:zone]
|
|
||||||
}
|
|
||||||
info = "publish: #{zone[:zone]} published"
|
|
||||||
elsif options['thaw']
|
|
||||||
zone[:frozen] = false
|
|
||||||
info = "thaw: Your zone is now thawed, you may edit normally"
|
|
||||||
else
|
|
||||||
raise ArgumentError
|
|
||||||
end
|
|
||||||
|
|
||||||
response.body = {
|
|
||||||
"status" => "success",
|
|
||||||
"data" => data,
|
|
||||||
"job_id" => Fog::Dynect::Mock.job_id,
|
|
||||||
"msgs" => [{
|
|
||||||
"INFO" => info,
|
|
||||||
"SOURCE"=>"BLL",
|
|
||||||
"ERR_CD"=>nil,
|
|
||||||
"LVL"=>"INFO"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
|
|
||||||
response
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,258 +0,0 @@
|
||||||
Shindo.tests('Dynect::dns | DNS requests', ['dynect', 'dns']) do
|
|
||||||
|
|
||||||
shared_format = {
|
|
||||||
'job_id' => Integer,
|
|
||||||
'msgs' => [{
|
|
||||||
'ERR_CD' => Fog::Nullable::String,
|
|
||||||
'INFO' => String,
|
|
||||||
'LVL' => String,
|
|
||||||
'SOURCE' => String
|
|
||||||
}],
|
|
||||||
'status' => String
|
|
||||||
}
|
|
||||||
|
|
||||||
tests "success" do
|
|
||||||
|
|
||||||
@dns = Fog::DNS[:dynect]
|
|
||||||
@domain = generate_unique_domain
|
|
||||||
@fqdn = "www.#{@domain}"
|
|
||||||
|
|
||||||
post_session_format = shared_format.merge({
|
|
||||||
'data' => {
|
|
||||||
'token' => String,
|
|
||||||
'version' => String
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
tests("post_session").formats(post_session_format) do
|
|
||||||
@dns.post_session.body
|
|
||||||
end
|
|
||||||
|
|
||||||
post_zone_format = shared_format.merge({
|
|
||||||
'data' => {
|
|
||||||
'serial' => Integer,
|
|
||||||
'zone' => String,
|
|
||||||
'zone_type' => String,
|
|
||||||
'serial_style' => String
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
tests("post_zone('netops@#{@domain}', 3600, '#{@domain}')").formats(post_zone_format) do
|
|
||||||
@dns.post_zone("netops@#{@domain}", 3600, @domain).body
|
|
||||||
end
|
|
||||||
|
|
||||||
get_zones_format = shared_format.merge({
|
|
||||||
'data' => [String]
|
|
||||||
})
|
|
||||||
|
|
||||||
tests("get_zone").formats(get_zones_format) do
|
|
||||||
@dns.get_zone.body
|
|
||||||
end
|
|
||||||
|
|
||||||
get_zone_format = shared_format.merge({
|
|
||||||
'data' => {
|
|
||||||
"serial" => Integer,
|
|
||||||
"serial_style" => String,
|
|
||||||
"zone" => String,
|
|
||||||
"zone_type" => String
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
tests("get_zone('zone' => '#{@domain}')").formats(get_zone_format) do
|
|
||||||
@dns.get_zone('zone' => @domain).body
|
|
||||||
end
|
|
||||||
|
|
||||||
post_record_format = shared_format.merge({
|
|
||||||
'data' => {
|
|
||||||
'fqdn' => String,
|
|
||||||
'rdata' => {
|
|
||||||
'address' => String
|
|
||||||
},
|
|
||||||
'record_id' => Integer,
|
|
||||||
'record_type' => String,
|
|
||||||
'ttl' => Integer,
|
|
||||||
'zone' => String
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
tests("post_record('A', '#{@domain}', '#{@fqdn}', 'address' => '1.2.3.4')").formats(post_record_format) do
|
|
||||||
@dns.post_record('A', @domain, @fqdn, {'address' => '1.2.3.4'}).body
|
|
||||||
end
|
|
||||||
|
|
||||||
put_record_format = shared_format.merge({
|
|
||||||
'data' => {
|
|
||||||
'fqdn' => String,
|
|
||||||
'ARecords' => [
|
|
||||||
{
|
|
||||||
'rdata' => {
|
|
||||||
'address' => String
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
'record_id' => Integer,
|
|
||||||
'record_type' => String,
|
|
||||||
'ttl' => Integer,
|
|
||||||
'zone' => String
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
tests("put_record('A', '#{@domain}', '#{@fqdn}', 'address' => '1.2.3.4')").formats(post_record_format) do
|
|
||||||
@dns.put_record('A', @domain, @fqdn, {'address' => '1.2.3.4'}).body
|
|
||||||
end
|
|
||||||
|
|
||||||
publish_zone_format = shared_format.merge({
|
|
||||||
'data' => {
|
|
||||||
'serial' => Integer,
|
|
||||||
'serial_style' => String,
|
|
||||||
'zone' => String,
|
|
||||||
'zone_type' => String
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
tests("put_zone('#{@domain}', 'publish' => true)").formats(publish_zone_format) do
|
|
||||||
@dns.put_zone(@domain, 'publish' => true).body
|
|
||||||
end
|
|
||||||
|
|
||||||
freeze_zone_format = shared_format.merge({
|
|
||||||
'data' => {}
|
|
||||||
})
|
|
||||||
|
|
||||||
tests("put_zone('#{@domain}', 'freeze' => true)").formats(freeze_zone_format) do
|
|
||||||
@dns.put_zone(@domain, 'freeze' => true).body
|
|
||||||
end
|
|
||||||
|
|
||||||
thaw_zone_format = shared_format.merge({
|
|
||||||
'data' => {}
|
|
||||||
})
|
|
||||||
|
|
||||||
tests("put_zone('#{@domain}', 'thaw' => true)").formats(thaw_zone_format) do
|
|
||||||
@dns.put_zone(@domain, 'thaw' => true).body
|
|
||||||
end
|
|
||||||
|
|
||||||
get_node_list_format = shared_format.merge({
|
|
||||||
'data' => [String]
|
|
||||||
})
|
|
||||||
|
|
||||||
tests("get_node_list('#{@domain}')").formats(get_node_list_format) do
|
|
||||||
@dns.get_node_list(@domain).body
|
|
||||||
end
|
|
||||||
|
|
||||||
get_all_records_format = shared_format.merge({
|
|
||||||
'data' => [String]
|
|
||||||
})
|
|
||||||
|
|
||||||
tests("get_all_records('#{@domain}')").formats(get_all_records_format) do
|
|
||||||
@dns.get_all_records(@domain).body
|
|
||||||
end
|
|
||||||
|
|
||||||
get_records_format = shared_format.merge({
|
|
||||||
'data' => [String]
|
|
||||||
})
|
|
||||||
|
|
||||||
tests("get_record('A', '#{@domain}', '#{@fqdn}')").formats(get_records_format) do
|
|
||||||
data = @dns.get_record('A', @domain, @fqdn).body
|
|
||||||
@record_id = data['data'].first.split('/').last
|
|
||||||
data
|
|
||||||
end
|
|
||||||
|
|
||||||
sleep 5 unless Fog.mocking?
|
|
||||||
|
|
||||||
@dns.post_record('CNAME', @domain, "cname.#{@fqdn}", {'cname' => "#{@fqdn}."})
|
|
||||||
|
|
||||||
tests("get_record('ANY', '#{@domain}', 'cname.#{@fqdn}')").formats(get_records_format) do
|
|
||||||
@dns.get_record('ANY', @domain, "cname.#{@fqdn}").body
|
|
||||||
end
|
|
||||||
|
|
||||||
get_record_format = shared_format.merge({
|
|
||||||
'data' => {
|
|
||||||
'zone' => String,
|
|
||||||
'ttl' => Integer,
|
|
||||||
'fqdn' => String,
|
|
||||||
'record_type' => String,
|
|
||||||
'rdata' => {
|
|
||||||
'address' => String
|
|
||||||
},
|
|
||||||
'record_id' => Integer
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
tests("get_record('A', '#{@domain}', '#{@fqdn}', 'record_id' => '#{@record_id}')").formats(get_record_format) do
|
|
||||||
@dns.get_record('A', @domain, @fqdn, 'record_id' => @record_id).body
|
|
||||||
end
|
|
||||||
|
|
||||||
delete_record_format = shared_format.merge({
|
|
||||||
'data' => {}
|
|
||||||
})
|
|
||||||
|
|
||||||
tests("delete_record('A', '#{@domain}', '#{@fqdn}', '#{@record_id}')").formats(delete_record_format) do
|
|
||||||
@dns.delete_record('A', @domain, "#{@fqdn}", @record_id).body
|
|
||||||
end
|
|
||||||
|
|
||||||
delete_zone_format = shared_format.merge({
|
|
||||||
'data' => {}
|
|
||||||
})
|
|
||||||
|
|
||||||
sleep 5 unless Fog.mocking?
|
|
||||||
|
|
||||||
tests("delete_zone('#{@domain}')").formats(delete_zone_format) do
|
|
||||||
@dns.delete_zone(@domain).body
|
|
||||||
end
|
|
||||||
|
|
||||||
tests("job handling") do
|
|
||||||
pending unless Fog.mocking?
|
|
||||||
|
|
||||||
old_mock_value = Excon.defaults[:mock]
|
|
||||||
Excon.stubs.clear
|
|
||||||
|
|
||||||
tests("returns final response from a complete job").returns({"status" => "success"}) do
|
|
||||||
begin
|
|
||||||
Excon.defaults[:mock] = true
|
|
||||||
|
|
||||||
Excon.stub({:method => :post, :path => "/REST/Session"}, {:body=>"{\"status\": \"success\", \"data\": {\"token\": \"foobar\", \"version\": \"2.3.1\"}, \"job_id\": 150583906, \"msgs\": [{\"INFO\": \"login: Login successful\", \"SOURCE\": \"BLL\", \"ERR_CD\": null, \"LVL\": \"INFO\"}]}", :headers=>{"Content-Type"=>"application/json"}, :status=>200})
|
|
||||||
|
|
||||||
Excon.stub({:method => :get, :path => "/REST/Zone/example.com"}, {:status => 307, :body => '/REST/Job/150576635', :headers => {'Content-Type' => 'text/html', 'Location' => '/REST/Job/150576635'}})
|
|
||||||
Excon.stub({:method => :get, :path => "/REST/Job/150576635"}, {:status => 307, :body => '{"status":"success"}', :headers => {'Content-Type' => 'application/json'}})
|
|
||||||
|
|
||||||
Fog::DNS::Dynect::Real.new.request(:method => :get, :path => "Zone/example.com").body
|
|
||||||
ensure
|
|
||||||
Excon.stubs.clear
|
|
||||||
Excon.defaults[:mock] = old_mock_value
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
tests("passes expects through when polling a job").returns({"status" => "success"}) do
|
|
||||||
begin
|
|
||||||
Excon.defaults[:mock] = true
|
|
||||||
|
|
||||||
Excon.stub({:method => :post, :path => "/REST/Session"}, {:body=>"{\"status\": \"success\", \"data\": {\"token\": \"foobar\", \"version\": \"2.3.1\"}, \"job_id\": 150583906, \"msgs\": [{\"INFO\": \"login: Login successful\", \"SOURCE\": \"BLL\", \"ERR_CD\": null, \"LVL\": \"INFO\"}]}", :headers=>{"Content-Type"=>"application/json"}, :status=>200})
|
|
||||||
|
|
||||||
Excon.stub({:method => :get, :path => "/REST/Zone/example.com"}, {:status => 307, :body => '/REST/Job/150576635', :headers => {'Content-Type' => 'text/html', 'Location' => '/REST/Job/150576635'}})
|
|
||||||
Excon.stub({:method => :get, :path => "/REST/Job/150576635"}, {:status => 404, :body => '{"status":"success"}', :headers => {'Content-Type' => 'application/json'}})
|
|
||||||
|
|
||||||
Fog::DNS::Dynect::Real.new.request(:method => :get, :expects => 404, :path => "Zone/example.com").body
|
|
||||||
ensure
|
|
||||||
Excon.stubs.clear
|
|
||||||
Excon.defaults[:mock] = old_mock_value
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
tests('failure') do
|
|
||||||
tests("#auth_token with expired credentials").raises(Excon::Errors::BadRequest) do
|
|
||||||
pending if Fog.mocking?
|
|
||||||
@dns = Fog::DNS[:dynect]
|
|
||||||
@dns.instance_variable_get(:@connection).stub(:request) { raise Excon::Errors::BadRequest.new('Expected(200) <=> Actual(400 Bad Request) request => {:headers=>{"Content-Type"=>"application/json", "API-Version"=>"2.3.1", "Auth-Token"=>"auth-token", "Host"=>"api2.dynect.net:443", "Content-Length"=>0}, :host=>"api2.dynect.net", :mock=>nil, :path=>"/REST/CNAMERecord/domain.com/www.domain.com", :port=>"443", :query=>nil, :scheme=>"https", :expects=>200, :method=>:get} response => #<Excon::Response:0x00000008478b98 @body="{"status": "failure", "data": {}, "job_id": 21326025, "msgs": [{"INFO": "login: Bad or expired credentials", "SOURCE": "BLL", "ERR_CD": "INVALID_DATA", "LVL": "ERROR"}, {"INFO": "login: There was a problem with your credentials", "SOURCE": "BLL", "ERR_CD": null, "LVL": "INFO"}]}", @headers={"Server"=>"nginx/0.7.67", "Date"=>"Thu, 08 Sep 2011 20:04:21 GMT", "Content-Type"=>"application/json", "Transfer-Encoding"=>"chunked", "Connection"=>"keep-alive"}, @status=400>') }
|
|
||||||
@dns.instance_variable_get(:@connection).should_receive(:request).exactly(2).times
|
|
||||||
@dns.auth_token
|
|
||||||
end
|
|
||||||
|
|
||||||
tests("#auth_token with inactivity logout").raises(Excon::Errors::BadRequest) do
|
|
||||||
pending if Fog.mocking?
|
|
||||||
@dns = Fog::DNS[:dynect]
|
|
||||||
@dns.instance_variable_get(:@connection).stub(:request) { raise Excon::Errors::BadRequest.new('Expected(200) <=> Actual(400 Bad Request) request => {:headers=>{"Content-Type"=>"application/json", "API-Version"=>"2.3.1", "Auth-Token"=>"auth-token", "Host"=>"api2.dynect.net:443", "Content-Length"=>0}, :host=>"api2.dynect.net", :mock=>nil, :path=>"/REST/CNAMERecord/domain.com/www.domain.com", :port=>"443", :query=>nil, :scheme=>"https", :expects=>200, :method=>:get} response => #<Excon::Response:0x00000008478b98 @body="{"status": "failure", "data": {}, "job_id": 21326025, "msgs": [{"INFO": "login: inactivity logout", "SOURCE": "BLL", "ERR_CD": "INVALID_DATA", "LVL": "ERROR"}, {"INFO": "login: There was a problem with your credentials", "SOURCE": "BLL", "ERR_CD": null, "LVL": "INFO"}]}", @headers={"Server"=>"nginx/0.7.67", "Date"=>"Thu, 08 Sep 2011 20:04:21 GMT", "Content-Type"=>"application/json", "Transfer-Encoding"=>"chunked", "Connection"=>"keep-alive"}, @status=400>') }
|
|
||||||
@dns.instance_variable_get(:@connection).should_receive(:request).exactly(2).times
|
|
||||||
@dns.auth_token
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
Loading…
Reference in New Issue