diff --git a/fog.gemspec b/fog.gemspec index ef963f3b3..ff2ef6944 100644 --- a/fog.gemspec +++ b/fog.gemspec @@ -55,6 +55,7 @@ Gem::Specification.new do |s| s.add_dependency("fog-atmos") s.add_dependency("fog-aws", ">= 0.6.0") s.add_dependency("fog-brightbox", "~> 0.4") + s.add_dependency("fog-dynect") s.add_dependency("fog-ecloud", "= 0.1.1") s.add_dependency("fog-google", ">= 0.0.2") s.add_dependency("fog-local") diff --git a/lib/fog/dynect.rb b/lib/fog/dynect.rb deleted file mode 100644 index 16c0467a9..000000000 --- a/lib/fog/dynect.rb +++ /dev/null @@ -1 +0,0 @@ -require 'fog/dynect/dns' diff --git a/lib/fog/dynect/core.rb b/lib/fog/dynect/core.rb deleted file mode 100644 index 8a3ba55d4..000000000 --- a/lib/fog/dynect/core.rb +++ /dev/null @@ -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 diff --git a/lib/fog/dynect/dns.rb b/lib/fog/dynect/dns.rb deleted file mode 100644 index 55ece3ab4..000000000 --- a/lib/fog/dynect/dns.rb +++ /dev/null @@ -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 diff --git a/lib/fog/dynect/models/dns/record.rb b/lib/fog/dynect/models/dns/record.rb deleted file mode 100644 index 95eb59b68..000000000 --- a/lib/fog/dynect/models/dns/record.rb +++ /dev/null @@ -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 diff --git a/lib/fog/dynect/models/dns/records.rb b/lib/fog/dynect/models/dns/records.rb deleted file mode 100644 index 8abf9e8d1..000000000 --- a/lib/fog/dynect/models/dns/records.rb +++ /dev/null @@ -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 diff --git a/lib/fog/dynect/models/dns/zone.rb b/lib/fog/dynect/models/dns/zone.rb deleted file mode 100644 index e14f62292..000000000 --- a/lib/fog/dynect/models/dns/zone.rb +++ /dev/null @@ -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 diff --git a/lib/fog/dynect/models/dns/zones.rb b/lib/fog/dynect/models/dns/zones.rb deleted file mode 100644 index b0ef2c749..000000000 --- a/lib/fog/dynect/models/dns/zones.rb +++ /dev/null @@ -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 diff --git a/lib/fog/dynect/requests/dns/delete_record.rb b/lib/fog/dynect/requests/dns/delete_record.rb deleted file mode 100644 index 9cbc6f663..000000000 --- a/lib/fog/dynect/requests/dns/delete_record.rb +++ /dev/null @@ -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 diff --git a/lib/fog/dynect/requests/dns/delete_zone.rb b/lib/fog/dynect/requests/dns/delete_zone.rb deleted file mode 100644 index 1e54accae..000000000 --- a/lib/fog/dynect/requests/dns/delete_zone.rb +++ /dev/null @@ -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 diff --git a/lib/fog/dynect/requests/dns/get_all_records.rb b/lib/fog/dynect/requests/dns/get_all_records.rb deleted file mode 100644 index 13e8d7813..000000000 --- a/lib/fog/dynect/requests/dns/get_all_records.rb +++ /dev/null @@ -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 diff --git a/lib/fog/dynect/requests/dns/get_node_list.rb b/lib/fog/dynect/requests/dns/get_node_list.rb deleted file mode 100644 index d692c2d15..000000000 --- a/lib/fog/dynect/requests/dns/get_node_list.rb +++ /dev/null @@ -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 diff --git a/lib/fog/dynect/requests/dns/get_record.rb b/lib/fog/dynect/requests/dns/get_record.rb deleted file mode 100644 index e58c0366f..000000000 --- a/lib/fog/dynect/requests/dns/get_record.rb +++ /dev/null @@ -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 diff --git a/lib/fog/dynect/requests/dns/get_zone.rb b/lib/fog/dynect/requests/dns/get_zone.rb deleted file mode 100644 index 9ccc5dc38..000000000 --- a/lib/fog/dynect/requests/dns/get_zone.rb +++ /dev/null @@ -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 diff --git a/lib/fog/dynect/requests/dns/post_record.rb b/lib/fog/dynect/requests/dns/post_record.rb deleted file mode 100644 index 126bec00f..000000000 --- a/lib/fog/dynect/requests/dns/post_record.rb +++ /dev/null @@ -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 diff --git a/lib/fog/dynect/requests/dns/post_session.rb b/lib/fog/dynect/requests/dns/post_session.rb deleted file mode 100644 index 3aa3d82f3..000000000 --- a/lib/fog/dynect/requests/dns/post_session.rb +++ /dev/null @@ -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 diff --git a/lib/fog/dynect/requests/dns/post_zone.rb b/lib/fog/dynect/requests/dns/post_zone.rb deleted file mode 100644 index 579b6424a..000000000 --- a/lib/fog/dynect/requests/dns/post_zone.rb +++ /dev/null @@ -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 diff --git a/lib/fog/dynect/requests/dns/put_record.rb b/lib/fog/dynect/requests/dns/put_record.rb deleted file mode 100644 index 5f5f6a313..000000000 --- a/lib/fog/dynect/requests/dns/put_record.rb +++ /dev/null @@ -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 diff --git a/lib/fog/dynect/requests/dns/put_zone.rb b/lib/fog/dynect/requests/dns/put_zone.rb deleted file mode 100644 index c421061b9..000000000 --- a/lib/fog/dynect/requests/dns/put_zone.rb +++ /dev/null @@ -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 diff --git a/tests/dynect/requests/dns/dns_tests.rb b/tests/dynect/requests/dns/dns_tests.rb deleted file mode 100644 index 12d548c70..000000000 --- a/tests/dynect/requests/dns/dns_tests.rb +++ /dev/null @@ -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 => #"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 => #"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