smart_proxy_dns_powerdns 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  module Proxy
2
2
  module Dns
3
3
  module Powerdns
4
- VERSION = '0.2.1'
4
+ VERSION = '0.3.0'
5
5
  end
6
6
  end
7
7
  end
@@ -0,0 +1,3 @@
1
+ ---
2
+ :enabled: true
3
+ :use_provider: dns_powerdns
@@ -0,0 +1,4 @@
1
+ ---
2
+ :powerdns_backend: rest
3
+ :powerdns_rest_url: http://localhost:8081/api/v1/servers/localhost
4
+ :powerdns_rest_api_key: apikey
@@ -0,0 +1,4 @@
1
+ :settings_directory: /home/ekohl/dev/smart_proxy_dns_powerdns/test/config/smart-proxy-settings.d
2
+ :http_port: 8000
3
+ :log_file: STDOUT
4
+ :log_level: DEBUG
@@ -5,7 +5,7 @@ require 'net/http'
5
5
 
6
6
  class DnsPowerdnsIntegrationTest < Test::Unit::TestCase
7
7
 
8
- def test_forward_dns
8
+ def test_forward_dns_v4
9
9
  data = {'fqdn' => fqdn, 'value' => ip, 'type' => 'A'}
10
10
  type = Resolv::DNS::Resource::IN::A
11
11
  expected = type.new(Resolv::IPv4.create(data['value']))
@@ -13,6 +13,14 @@ class DnsPowerdnsIntegrationTest < Test::Unit::TestCase
13
13
  test_scenario(data, data['fqdn'], type, expected)
14
14
  end
15
15
 
16
+ def test_forward_dns_v6
17
+ data = {'fqdn' => fqdn, 'value' => ipv6, 'type' => 'AAAA'}
18
+ type = Resolv::DNS::Resource::IN::AAAA
19
+ expected = type.new(Resolv::IPv6.create(data['value']))
20
+
21
+ test_scenario(data, data['fqdn'], type, expected)
22
+ end
23
+
16
24
  def test_reverse_dns_v4
17
25
  data = {'fqdn' => fqdn, 'value' => IPAddr.new(ip).reverse, 'type' => 'PTR'}
18
26
  type = Resolv::DNS::Resource::IN::PTR
@@ -29,6 +37,14 @@ class DnsPowerdnsIntegrationTest < Test::Unit::TestCase
29
37
  test_scenario(data, data['value'], type, expected)
30
38
  end
31
39
 
40
+ def test_cname
41
+ data = {'fqdn' => fqdn, 'value' => 'something.example.com', 'type' => 'CNAME'}
42
+ type = Resolv::DNS::Resource::IN::CNAME
43
+ expected = type.new(Resolv::DNS::Name.create(data['value'] + '.'))
44
+
45
+ test_scenario(data, data['fqdn'], type, expected)
46
+ end
47
+
32
48
  private
33
49
 
34
50
  def test_scenario(data, name, type, expected)
@@ -40,9 +56,11 @@ class DnsPowerdnsIntegrationTest < Test::Unit::TestCase
40
56
  response = http.request request
41
57
  assert_equal(200, response.code.to_i)
42
58
 
59
+ assert(purge_cache name)
60
+
43
61
  assert_equal([expected], resolver.getresources(name, type))
44
62
 
45
- request = Net::HTTP::Delete.new(smart_proxy_url + 'dns/' + name)
63
+ request = Net::HTTP::Delete.new("#{smart_proxy_url}dns/#{name}/#{type.to_s.split("::").last}")
46
64
  response = http.request request
47
65
  assert_equal(200, response.code.to_i)
48
66
 
@@ -53,7 +71,7 @@ class DnsPowerdnsIntegrationTest < Test::Unit::TestCase
53
71
  end
54
72
 
55
73
  def resolver
56
- Resolv::DNS.new(:nameserver_port => [['127.0.0.1', 5300]])
74
+ Resolv::DNS.new(:nameserver_port => [['127.0.0.1', 53]])
57
75
  end
58
76
 
59
77
  def smart_proxy_url
@@ -75,6 +93,8 @@ class DnsPowerdnsIntegrationTest < Test::Unit::TestCase
75
93
 
76
94
  def purge_cache name
77
95
  %x{#{ENV['PDNS_CONTROL'] || "pdns_control"} purge "#{name}"}
78
- $? == 0
96
+ # Default pdns packet cache is 60 seconds, if purging failed we wait for it
97
+ sleep 60 unless $? == 0
98
+ true
79
99
  end
80
100
  end
data/test/test_helper.rb CHANGED
@@ -1,3 +1,6 @@
1
+ require 'coveralls'
2
+ Coveralls.wear!
3
+
1
4
  require 'test/unit'
2
5
  require 'mocha/setup'
3
6
  require 'json'
@@ -0,0 +1,119 @@
1
+ require 'test_helper'
2
+
3
+ require 'smart_proxy_dns_powerdns/dns_powerdns_configuration'
4
+ require 'smart_proxy_dns_powerdns/dns_powerdns_main'
5
+
6
+
7
+ class DnsPowerdnsProductionWiringTest < Test::Unit::TestCase
8
+ def setup
9
+ @container = ::Proxy::DependencyInjection::Container.new
10
+ @config = ::Proxy::Dns::Powerdns::PluginConfiguration.new
11
+ end
12
+
13
+ def test_dns_provider_initialization_mysql_backend_minimal_settings
14
+ @config.load_dependency_injection_wirings(@container, :dns_ttl => 999,
15
+ :powerdns_backend => 'mysql')
16
+
17
+ provider = @container.get_dependency(:dns_provider)
18
+
19
+ assert_not_nil provider
20
+ assert_equal 999, provider.ttl
21
+ assert_equal 'localhost', provider.hostname
22
+ assert_equal 'powerdns', provider.username
23
+ assert_equal '', provider.password
24
+ assert_equal 'pdns', provider.database
25
+ end
26
+
27
+ def test_dns_provider_initialization_mysql_backend_full_settings
28
+ @config.load_dependency_injection_wirings(@container, :dns_ttl => 999,
29
+ :powerdns_backend => 'mysql',
30
+ :powerdns_mysql_hostname => 'db.example.com',
31
+ :powerdns_mysql_username => 'user',
32
+ :powerdns_mysql_password => 'super secret',
33
+ :powerdns_mysql_database => 'the_db',
34
+ )
35
+
36
+ provider = @container.get_dependency(:dns_provider)
37
+
38
+ assert_not_nil provider
39
+ assert_equal 999, provider.ttl
40
+ assert_equal 'db.example.com', provider.hostname
41
+ assert_equal 'user', provider.username
42
+ assert_equal 'super secret', provider.password
43
+ assert_equal 'the_db', provider.database
44
+ end
45
+
46
+ def test_dns_provider_initialization_postgresql_backend_minimal_settings
47
+ @config.load_dependency_injection_wirings(@container, :dns_ttl => 999,
48
+ :powerdns_backend => 'postgresql')
49
+
50
+ provider = @container.get_dependency(:dns_provider)
51
+
52
+ assert_not_nil provider
53
+ assert_equal 999, provider.ttl
54
+ assert_equal 'dbname=pdns', provider.connection_str
55
+ end
56
+
57
+ def test_dns_provider_initialization_postgresql_backend_full_settings
58
+ @config.load_dependency_injection_wirings(@container, :dns_ttl => 999,
59
+ :powerdns_backend => 'postgresql',
60
+ :powerdns_postgresql_connection => 'dbname=powerdns')
61
+
62
+ provider = @container.get_dependency(:dns_provider)
63
+
64
+ assert_not_nil provider
65
+ assert_equal 999, provider.ttl
66
+ assert_equal 'dbname=powerdns', provider.connection_str
67
+ end
68
+
69
+ def test_dns_provider_initialization_rest_backend_invalid_settings
70
+ assert_raise Proxy::Error::ConfigurationError do
71
+ @config.load_dependency_injection_wirings(@container, :dns_ttl => 999,
72
+ :powerdns_backend => 'rest')
73
+ end
74
+ end
75
+
76
+ def test_dns_provider_initialization_rest_backend_minimal_settings
77
+ @config.load_dependency_injection_wirings(@container, :dns_ttl => 999,
78
+ :powerdns_backend => 'rest',
79
+ :powerdns_rest_api_key => 'apikey')
80
+
81
+ provider = @container.get_dependency(:dns_provider)
82
+
83
+ assert_not_nil provider
84
+ assert_equal 999, provider.ttl
85
+ assert_equal 'http://localhost:8081/api/v1/servers/localhost', provider.url
86
+ assert_equal 'apikey', provider.api_key
87
+ end
88
+
89
+ def test_dns_provider_initialization_rest_backend_full_settings
90
+ @config.load_dependency_injection_wirings(@container, :dns_ttl => 999,
91
+ :powerdns_backend => 'rest',
92
+ :powerdns_rest_url => 'http://apiserver',
93
+ :powerdns_rest_api_key => 'apikey')
94
+
95
+ provider = @container.get_dependency(:dns_provider)
96
+
97
+ assert_not_nil provider
98
+ assert_equal 999, provider.ttl
99
+ assert_equal 'http://apiserver', provider.url
100
+ assert_equal 'apikey', provider.api_key
101
+ end
102
+
103
+ def test_dns_provider_initialization_dummy_backend
104
+ @config.load_dependency_injection_wirings(@container, :dns_ttl => 999,
105
+ :powerdns_backend => 'dummy')
106
+
107
+ provider = @container.get_dependency(:dns_provider)
108
+
109
+ assert_not_nil provider
110
+ assert_equal 999, provider.ttl
111
+ end
112
+
113
+ def test_dns_provider_initialization_invalid_backend
114
+ assert_raise Proxy::Error::ConfigurationError do
115
+ @config.load_dependency_injection_wirings(@container, :dns_ttl => 999,
116
+ :powerdns_backend => 'invalid')
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,26 @@
1
+ require 'test_helper'
2
+
3
+ require 'smart_proxy_dns_powerdns/dns_powerdns_main'
4
+ require 'smart_proxy_dns_powerdns/backend/dummy'
5
+
6
+ class DnsPowerdnsBackendDummyTest < Test::Unit::TestCase
7
+ def setup
8
+ @provider = Proxy::Dns::Powerdns::Backend::Dummy.new('localhost', 86400)
9
+ end
10
+
11
+ def test_initialize
12
+ assert_equal 86400, @provider.ttl
13
+ end
14
+
15
+ def test_get_zone
16
+ assert_equal @provider.get_zone('test.example.com'), {'id' => 1, 'name' => 'example.com'}
17
+ end
18
+
19
+ def test_create_record
20
+ assert_false @provider.create_record(1, 'test.example.com', '10.1.2.3', 'A')
21
+ end
22
+
23
+ def test_delete_record
24
+ assert_false @provider.delete_record(1, 'test.example.com', 'A')
25
+ end
26
+ end
@@ -1,77 +1,57 @@
1
1
  require 'test_helper'
2
2
 
3
- require 'smart_proxy_dns_powerdns/dns_powerdns_plugin'
4
3
  require 'smart_proxy_dns_powerdns/dns_powerdns_main'
5
4
  require 'smart_proxy_dns_powerdns/backend/mysql'
6
5
 
7
6
  class DnsPowerdnsBackendMysqlTest < Test::Unit::TestCase
8
- # Test that correct initialization works
9
- def test_initialize_dummy_with_settings
10
- Proxy::Dns::Powerdns::Plugin.load_test_settings(
11
- :powerdns_mysql_hostname => 'db.example.com',
12
- :powerdns_mysql_username => 'the_user',
13
- :powerdns_mysql_password => 'something_secure',
14
- :powerdns_mysql_database => 'db_pdns'
15
- )
16
- provider = klass.new
17
- assert_equal 'db.example.com', provider.hostname
18
- assert_equal 'the_user', provider.username
19
- assert_equal 'something_secure', provider.password
20
- assert_equal 'db_pdns', provider.database
7
+ def setup
8
+ @provider = Proxy::Dns::Powerdns::Backend::Mysql.new('localhost', 86400, 'sudo pdnssec',
9
+ 'db.example.com', 'the_user',
10
+ 'something_secure', 'db_pdns')
11
+ @connection = mock()
12
+ @provider.stubs(:connection).returns(@connection)
21
13
  end
22
14
 
23
- def test_get_zone_with_existing_zone
24
- instance = klass.new
15
+ def test_initialize
16
+ assert_equal 86400, @provider.ttl
17
+ assert_equal 'sudo pdnssec', @provider.pdnssec
18
+ assert_equal 'db.example.com', @provider.hostname
19
+ assert_equal 'the_user', @provider.username
20
+ assert_equal 'something_secure', @provider.password
21
+ assert_equal 'db_pdns', @provider.database
22
+ end
25
23
 
26
- connection = mock()
27
- instance.stubs(:connection).returns(connection)
28
- connection.expects(:escape).with('test.example.com').returns('test.example.com')
29
- connection.expects(:query).with("SELECT LENGTH(name) domain_length, id, name FROM domains WHERE 'test.example.com' LIKE CONCAT('%%.', name) ORDER BY domain_length DESC LIMIT 1").returns([{'id' => 1, 'name' => 'example.com'}])
24
+ def test_get_zone_with_existing_zone
25
+ @connection.expects(:escape).with('test.example.com').returns('test.example.com')
26
+ @connection.expects(:query).with("SELECT LENGTH(name) domain_length, id, name FROM domains WHERE 'test.example.com' LIKE CONCAT('%%.', name) ORDER BY domain_length DESC LIMIT 1").returns([{'id' => 1, 'name' => 'example.com'}])
30
27
 
31
- assert_equal(instance.get_zone('test.example.com'), {'id' => 1, 'name' => 'example.com'})
28
+ assert_equal(@provider.get_zone('test.example.com'), {'id' => 1, 'name' => 'example.com'})
32
29
  end
33
30
 
34
31
  def test_get_zone_without_existing_zone
35
- instance = klass.new
36
-
37
- connection = mock()
38
- instance.stubs(:connection).returns(connection)
39
- connection.expects(:escape).with('test.example.com').returns('test.example.com')
40
- connection.expects(:query).with("SELECT LENGTH(name) domain_length, id, name FROM domains WHERE 'test.example.com' LIKE CONCAT('%%.', name) ORDER BY domain_length DESC LIMIT 1").returns([])
32
+ @connection.expects(:escape).with('test.example.com').returns('test.example.com')
33
+ @connection.expects(:query).with("SELECT LENGTH(name) domain_length, id, name FROM domains WHERE 'test.example.com' LIKE CONCAT('%%.', name) ORDER BY domain_length DESC LIMIT 1").returns([])
41
34
 
42
- assert_raise(Proxy::Dns::Error) { instance.get_zone('test.example.com') }
35
+ assert_raise(Proxy::Dns::Error) { @provider.get_zone('test.example.com') }
43
36
  end
44
37
 
45
38
  def test_create_record
46
- instance = klass.new
39
+ @connection.expects(:escape).with('test.example.com').returns('test.example.com')
40
+ @connection.expects(:escape).with('A').returns('A')
41
+ @connection.expects(:escape).with('10.1.1.1').returns('10.1.1.1')
42
+ @connection.expects(:query).with("INSERT INTO records (domain_id, name, ttl, content, type) VALUES (1, 'test.example.com', 86400, '10.1.1.1', 'A')")
43
+ @connection.expects(:affected_rows).returns(1)
47
44
 
48
- connection = mock()
49
- instance.stubs(:connection).returns(connection)
50
- connection.expects(:escape).with('test.example.com').returns('test.example.com')
51
- connection.expects(:escape).with('A').returns('A')
52
- connection.expects(:escape).with('10.1.1.1').returns('10.1.1.1')
53
- connection.expects(:query).with("INSERT INTO records (domain_id, name, ttl, content, type) VALUES (1, 'test.example.com', 86400, '10.1.1.1', 'A')")
54
- connection.expects(:affected_rows).returns(1)
55
-
56
- assert instance.create_record(1, 'test.example.com', 'A', '10.1.1.1')
45
+ assert @provider.create_record(1, 'test.example.com', 'A', '10.1.1.1')
57
46
  end
58
47
 
59
48
  def test_delete_record
60
- instance = klass.new
61
-
62
- connection = mock()
63
- instance.stubs(:connection).returns(connection)
64
- connection.expects(:escape).with('test.example.com').returns('test.example.com')
65
- connection.expects(:escape).with('A').returns('A')
66
- connection.expects(:query).with("DELETE FROM records WHERE domain_id=1 AND name='test.example.com' AND type='A'")
67
- connection.expects(:affected_rows).returns(1)
49
+ @connection.expects(:escape).with('test.example.com').returns('test.example.com')
50
+ @connection.expects(:escape).with('A').returns('A')
51
+ @connection.expects(:query).with("DELETE FROM records WHERE domain_id=1 AND name='test.example.com' AND type='A'")
52
+ @connection.expects(:affected_rows).returns(1)
68
53
 
69
- assert instance.delete_record(1, 'test.example.com', 'A')
54
+ assert @provider.delete_record(1, 'test.example.com', 'A')
70
55
  end
71
56
 
72
- private
73
-
74
- def klass
75
- Proxy::Dns::Powerdns::Backend::Mysql
76
- end
77
57
  end
@@ -1,20 +1,67 @@
1
1
  require 'test_helper'
2
2
 
3
- require 'smart_proxy_dns_powerdns/dns_powerdns_plugin'
4
3
  require 'smart_proxy_dns_powerdns/dns_powerdns_main'
5
4
  require 'smart_proxy_dns_powerdns/backend/postgresql'
6
5
 
7
6
  class DnsPowerdnsBackendPostgresqlTest < Test::Unit::TestCase
8
- # Test that correct initialization works
9
- def test_initialize_dummy_with_settings
10
- Proxy::Dns::Powerdns::Plugin.load_test_settings(:powerdns_postgresql_connection => 'dbname=powerdns')
11
- provider = klass.new
12
- assert_equal 'dbname=powerdns', provider.connection_str
7
+ def setup
8
+ @provider = Proxy::Dns::Powerdns::Backend::Postgresql.new('localhost', 86400, 'sudo pdnssec',
9
+ 'dbname=powerdns')
10
+ @connection = mock()
11
+ @provider.stubs(:connection).returns(@connection)
13
12
  end
14
13
 
15
- private
14
+ def test_initialize
15
+ assert_equal 86400, @provider.ttl
16
+ assert_equal 'sudo pdnssec', @provider.pdnssec
17
+ assert_equal 'dbname=powerdns', @provider.connection_str
18
+ end
19
+
20
+ def test_get_zone_with_existing_zone
21
+ @connection.expects(:exec_params).
22
+ with("SELECT LENGTH(name) domain_length, id, name FROM domains WHERE $1 LIKE CONCAT('%%.', name) ORDER BY domain_length DESC LIMIT 1", ['test.example.com']).
23
+ yields([{'id' => 1, 'name' => 'example.com'}])
24
+
25
+ assert_equal(@provider.get_zone('test.example.com'), {'id' => 1, 'name' => 'example.com'})
26
+ end
27
+
28
+ def test_get_zone_without_existing_zone
29
+ @connection.expects(:exec_params).
30
+ with("SELECT LENGTH(name) domain_length, id, name FROM domains WHERE $1 LIKE CONCAT('%%.', name) ORDER BY domain_length DESC LIMIT 1", ['test.example.com']).
31
+ yields([])
32
+
33
+ assert_raise(Proxy::Dns::Error) { @provider.get_zone('test.example.com') }
34
+ end
35
+
36
+ def test_create_record
37
+ @connection.expects(:exec_params).
38
+ with("INSERT INTO records (domain_id, name, ttl, content, type) VALUES ($1::int, $2, $3::int, $4, $5)", [1, 'test.example.com', 86400, '10.1.1.1', 'A']).
39
+ returns(mock(:cmdtuples => 1))
40
+
41
+ assert_true @provider.create_record(1, 'test.example.com', 'A', '10.1.1.1')
42
+ end
43
+
44
+ def test_delete_record_no_records
45
+ @connection.expects(:exec_params).
46
+ with("DELETE FROM records WHERE domain_id=$1::int AND name=$2 AND type=$3", [1, 'test.example.com', 'A']).
47
+ returns(mock(:cmdtuples => 0))
48
+
49
+ assert_false @provider.delete_record(1, 'test.example.com', 'A')
50
+ end
51
+
52
+ def test_delete_record_single_record
53
+ @connection.expects(:exec_params).
54
+ with("DELETE FROM records WHERE domain_id=$1::int AND name=$2 AND type=$3", [1, 'test.example.com', 'A']).
55
+ returns(mock(:cmdtuples => 1))
56
+
57
+ assert_true @provider.delete_record(1, 'test.example.com', 'A')
58
+ end
59
+
60
+ def test_delete_record_multiple_records
61
+ @connection.expects(:exec_params).
62
+ with("DELETE FROM records WHERE domain_id=$1::int AND name=$2 AND type=$3", [1, 'test.example.com', 'A']).
63
+ returns(mock(:cmdtuples => 2))
16
64
 
17
- def klass
18
- Proxy::Dns::Powerdns::Backend::Postgresql
65
+ assert_true @provider.delete_record(1, 'test.example.com', 'A')
19
66
  end
20
67
  end
@@ -0,0 +1,67 @@
1
+ require 'test_helper'
2
+ require 'webmock/test_unit'
3
+
4
+ require 'smart_proxy_dns_powerdns/dns_powerdns_main'
5
+ require 'smart_proxy_dns_powerdns/backend/rest'
6
+
7
+ class DnsPowerdnsBackendRestTest < Test::Unit::TestCase
8
+ def setup
9
+ @provider = Proxy::Dns::Powerdns::Backend::Rest.new('localhost', 86400,
10
+ 'http://localhost:8081/api/v1/servers/localhost',
11
+ 'apikey')
12
+ end
13
+
14
+ def test_initialize
15
+ assert_equal 86400, @provider.ttl
16
+ assert_equal 'http://localhost:8081/api/v1/servers/localhost', @provider.url
17
+ assert_equal 'apikey', @provider.api_key
18
+ end
19
+
20
+ def test_get_zone_with_existing_zone
21
+ stub_request(:get, "http://localhost:8081/api/v1/servers/localhost/zones").
22
+ with(:headers => {'X-Api-Key' => 'apikey'}).
23
+ to_return(:body => '[{"id": "example.com.", "name": "example.com."}]')
24
+ assert_equal @provider.get_zone('test.example.com'), {'id' => 'example.com.', 'name' => 'example.com.'}
25
+ end
26
+
27
+ def test_get_zone_with_existing_zone_absolute_record
28
+ stub_request(:get, "http://localhost:8081/api/v1/servers/localhost/zones").
29
+ with(:headers => {'X-Api-Key' => 'apikey'}).
30
+ to_return(:body => '[{"id": "example.com.", "name": "example.com."}]')
31
+ assert_equal @provider.get_zone('test.example.com.'), {'id' => 'example.com.', 'name' => 'example.com.'}
32
+ end
33
+
34
+ def test_get_zone_without_existing_zone
35
+ stub_request(:get, "http://localhost:8081/api/v1/servers/localhost/zones").
36
+ with(:headers => {'X-Api-Key' => 'apikey'}).
37
+ to_return(:body => '[]')
38
+ assert_raise(Proxy::Dns::Error) { @provider.get_zone('test.example.com') }
39
+ end
40
+
41
+ def test_create_a_record
42
+ stub_request(:patch, "http://localhost:8081/api/v1/servers/localhost/zones/example.com.").
43
+ with(
44
+ :headers => {'X-Api-Key' => 'apikey', 'Content-Type' => 'application/json'},
45
+ :body => '{"rrsets":[{"name":"test.example.com.","type":"A","ttl":86400,"changetype":"REPLACE","records":[{"content":"10.1.1.1","disabled":false}]}]}'
46
+ )
47
+ assert @provider.create_record('example.com.', 'test.example.com', 'A', '10.1.1.1')
48
+ end
49
+
50
+ def test_create_ptr_record
51
+ stub_request(:patch, "http://localhost:8081/api/v1/servers/localhost/zones/example.com.").
52
+ with(
53
+ :headers => {'X-Api-Key' => 'apikey', 'Content-Type' => 'application/json'},
54
+ :body => '{"rrsets":[{"name":"1.1.1.10.in-addr.arpa.","type":"PTR","ttl":86400,"changetype":"REPLACE","records":[{"content":"test.example.com.","disabled":false}]}]}'
55
+ )
56
+ assert @provider.create_record('example.com.', '1.1.1.10.in-addr.arpa', 'PTR', 'test.example.com')
57
+ end
58
+
59
+ def test_delete_record
60
+ stub_request(:patch, "http://localhost:8081/api/v1/servers/localhost/zones/example.com.").
61
+ with(
62
+ :headers => {'X-Api-Key' => 'apikey', 'Content-Type' => 'application/json'},
63
+ :body => '{"rrsets":[{"name":"test.example.com.","type":"A","changetype":"DELETE","records":[]}]}'
64
+ )
65
+ assert @provider.delete_record('example.com.', 'test.example.com', 'A')
66
+ end
67
+ end