From c685a08c77cb83b0dbe84497edf8c0fcbbce00f6 Mon Sep 17 00:00:00 2001 From: Dylan Egan Date: Mon, 29 Aug 2011 16:04:13 -0700 Subject: [PATCH] Beginning of Dynect::DNS mocking support. --- lib/fog/dynect.rb | 14 +++++- lib/fog/dynect/dns.rb | 22 ++++++++- lib/fog/dynect/requests/dns/delete_record.rb | 31 +++++++++++++ lib/fog/dynect/requests/dns/delete_zone.rb | 21 +++++++++ lib/fog/dynect/requests/dns/get_node_list.rb | 31 +++++++++++++ lib/fog/dynect/requests/dns/get_record.rb | 37 +++++++++++++++ lib/fog/dynect/requests/dns/get_zone.rb | 34 ++++++++++++++ lib/fog/dynect/requests/dns/post_record.rb | 48 ++++++++++++++++++++ lib/fog/dynect/requests/dns/post_session.rb | 17 +++++-- lib/fog/dynect/requests/dns/post_zone.rb | 38 ++++++++++++++++ lib/fog/dynect/requests/dns/put_zone.rb | 43 ++++++++++++++++++ tests/dns/requests/dynect/dns_tests.rb | 3 -- 12 files changed, 329 insertions(+), 10 deletions(-) diff --git a/lib/fog/dynect.rb b/lib/fog/dynect.rb index 8b6dbcd4f..a306dcc0d 100644 --- a/lib/fog/dynect.rb +++ b/lib/fog/dynect.rb @@ -5,10 +5,22 @@ require 'fog/core/parser' module Fog module Dynect - extend Fog::Provider service(:dns, 'dynect/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 index 9ca6fa284..cd1b1f8e5 100644 --- a/lib/fog/dynect/dns.rb +++ b/lib/fog/dynect/dns.rb @@ -24,13 +24,33 @@ module Fog request :put_zone 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 diff --git a/lib/fog/dynect/requests/dns/delete_record.rb b/lib/fog/dynect/requests/dns/delete_record.rb index 824e35d7c..3e307b356 100644 --- a/lib/fog/dynect/requests/dns/delete_record.rb +++ b/lib/fog/dynect/requests/dns/delete_record.rb @@ -19,6 +19,37 @@ module Fog ) 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 index 8a8968d99..6f1f237c5 100644 --- a/lib/fog/dynect/requests/dns/delete_zone.rb +++ b/lib/fog/dynect/requests/dns/delete_zone.rb @@ -16,6 +16,27 @@ module Fog ) 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_node_list.rb b/lib/fog/dynect/requests/dns/get_node_list.rb index 07192dc3d..7c04c02c5 100644 --- a/lib/fog/dynect/requests/dns/get_node_list.rb +++ b/lib/fog/dynect/requests/dns/get_node_list.rb @@ -18,6 +18,37 @@ module Fog ) end end + + class Mock + def get_node_list(zone, options = {}) + raise Fog::Dynect::DNS::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].collect { |type, records| records.select { |record| record[:fqdn] == fqdn } }.flatten.compact + else + data = data | zone[:records].collect { |type, records| records.collect { |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 index e4dc932a8..4db37a751 100644 --- a/lib/fog/dynect/requests/dns/get_record.rb +++ b/lib/fog/dynect/requests/dns/get_record.rb @@ -20,6 +20,43 @@ module Fog ) 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::Dynect::DNS::NotFound unless zone = self.data[:zones][zone] + + response = Excon::Response.new + response.status = 200 + + if record_id = options[:record_id] + raise Fog::Dynect::DNS::NotFound unless record = zone[:records][type].first { |record| record[:record_id] == record_id } + response.body = {} + else + records = zone[:records][type].select { |record| record[:fqdn] == fqdn } + response.body = { + "status" => "success", + "data" => records.collect { |record| "/REST/ARecord/#{record[: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 index 282201820..ce636687a 100644 --- a/lib/fog/dynect/requests/dns/get_zone.rb +++ b/lib/fog/dynect/requests/dns/get_zone.rb @@ -17,6 +17,40 @@ module Fog ) end end + + class Mock + def get_zone(options = {}) + if options['zone'] && 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].collect { |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 index b234e31f3..8b355db5f 100644 --- a/lib/fog/dynect/requests/dns/post_record.rb +++ b/lib/fog/dynect/requests/dns/post_record.rb @@ -22,6 +22,54 @@ module Fog ) end end + + class Mock + def post_record(type, zone, fqdn, rdata, options = {}) + raise Fog::Dynect::DNS::NotFound unless zone = self.data[:zones][zone] + + records = zone[:records] ||= Hash.new do |hash, type| + hash[type] = [] + end + + 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 index 828ddf947..dcd96558b 100644 --- a/lib/fog/dynect/requests/dns/post_session.rb +++ b/lib/fog/dynect/requests/dns/post_session.rb @@ -18,19 +18,26 @@ module Fog end class Mock - def post_session response = Excon::Response.new response.status = 200 response.body = { - 'API-Version' => '2.3.1', - 'Auth-Token' => 'thetoken==' + "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 index b8090721c..01ac23bda 100644 --- a/lib/fog/dynect/requests/dns/post_zone.rb +++ b/lib/fog/dynect/requests/dns/post_zone.rb @@ -27,6 +27,44 @@ module Fog ) end end + + class Mock + def post_zone(rname, ttl, zone, options = {}) + new_zone = { + :next_record_id => 0, + :records_to_delete => [], + :rname => rname, + :serial_style => options[:serial_style] || "increment", + :serial => 0, + :ttl => ttl, + :zone => zone, + :zone_type => "Primary" + } + + self.data[:zones][zone] = new_zone + + 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_zone.rb b/lib/fog/dynect/requests/dns/put_zone.rb index 78ff7aefe..e8184836c 100644 --- a/lib/fog/dynect/requests/dns/put_zone.rb +++ b/lib/fog/dynect/requests/dns/put_zone.rb @@ -21,6 +21,49 @@ module Fog ) end end + + class Mock + def put_zone(zone, options = {}) + raise Fog::Dynect::DNS::NotFound unless zone = self.data[:zones][zone] + + raise ArgumentError unless options.size == 1 + + response = Excon::Response.new + response.status = 200 + + if options[:freeze] + zone[:frozen] = true + 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] = [] + response.body = { + "status" => "success", + "data" => { + "zone_type" => zone[:zone_type], + "serial_style" => zone[:serial_style], + "serial" => zone[:serial] += 1, + "zone" => zone[:zone] + }, + "job_id" => Fog::Dynect::Mock.job_id, + "msgs" => [{ + "INFO" => "publish: #{zone[:zone]} published", + "SOURCE"=>"BLL", + "ERR_CD"=>nil, + "LVL"=>"INFO" + }] + } + elsif options[:thaw] + zone[:frozen] = false + else + raise ArgumentError + end + + response + end + end end end end diff --git a/tests/dns/requests/dynect/dns_tests.rb b/tests/dns/requests/dynect/dns_tests.rb index 7dddea85d..b91f2f3dd 100644 --- a/tests/dns/requests/dynect/dns_tests.rb +++ b/tests/dns/requests/dynect/dns_tests.rb @@ -1,7 +1,5 @@ Shindo.tests('Dynect::dns | DNS requests', ['dynect', 'dns']) do - pending if Fog.mocking? - shared_format = { 'job_id' => Integer, 'msgs' => [{ @@ -127,6 +125,5 @@ Shindo.tests('Dynect::dns | DNS requests', ['dynect', 'dns']) do tests("delete_zone('#{@domain}')").formats(delete_zone_format) do @dns.delete_zone(@domain).body end - end end