smart_proxy_dns_route53 2.0.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +52 -1
- data/lib/smart_proxy_dns_route53/dns_route53_configuration.rb +16 -0
- data/lib/smart_proxy_dns_route53/dns_route53_main.rb +54 -15
- data/lib/smart_proxy_dns_route53/dns_route53_plugin.rb +5 -6
- data/lib/smart_proxy_dns_route53/dns_route53_version.rb +1 -1
- data/test/dns_route53_integration_test.rb +158 -0
- data/test/dns_route53_record_test.rb +78 -74
- metadata +21 -5
- data/lib/smart_proxy_dns_route53/route53_dependencies.rb +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cc34b8b1e28f0d113bc0ded31929bd925d863c70
|
4
|
+
data.tar.gz: 5ebc3509ec21c98e544e41cb577086deb13bf99a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c6bada1d5fca8a12dcdb9b7370ba933db54ac3b7a0cbb3d0d3f28f411066a312edfcba097806d9712a95ba20c9a89bfa3f0a3e458ce1ccd54e68a862d5006c52
|
7
|
+
data.tar.gz: f596aef91a3b5d0f858076ddcdba44beb539db647c9fdfa90435021279fc094c3ac91f7363957f51fc826ca957450b9a7558db6b5fd7cf5565a3a646758090a5
|
data/README.md
CHANGED
@@ -12,7 +12,8 @@ for how to install Smart Proxy plugins
|
|
12
12
|
| Smart Proxy Version | Plugin Version |
|
13
13
|
| ------------------- | --------------:|
|
14
14
|
| >= 1.10, < 1.11 | ~> 1.0 |
|
15
|
-
| >= 1.11
|
15
|
+
| >= 1.11, < 1.13 | ~> 2.0 |
|
16
|
+
| >= 1.13, < 1.15 | ~> 3.0 |
|
16
17
|
|
17
18
|
## Configuration
|
18
19
|
|
@@ -27,10 +28,60 @@ Configuration options for this plugin are in `/etc/foreman-proxy/settings.d/dns_
|
|
27
28
|
* `:aws_access_key: "ABCDEF123456"` - set to be the Access Key ID of the IAM account
|
28
29
|
* `:aws_secret_key: "ABCDEF123456!@#$"` - set to be the Secret Access Key of the IAM account
|
29
30
|
|
31
|
+
### IAM policy
|
32
|
+
|
33
|
+
The IAM account must have the following actions associated via a policy:
|
34
|
+
|
35
|
+
* `route53:ListHostedZones` (all resources)
|
36
|
+
* `route53:ChangeResourceRecordSets` (on all zones being managed)
|
37
|
+
* `route53:ListResourceRecordSets` (on all zones being managed)
|
38
|
+
|
39
|
+
An example policy document follows:
|
40
|
+
|
41
|
+
```json
|
42
|
+
{
|
43
|
+
"Version": "2012-10-17",
|
44
|
+
"Statement": [
|
45
|
+
{
|
46
|
+
"Sid": "Stmt1485852222000",
|
47
|
+
"Effect": "Allow",
|
48
|
+
"Action": [
|
49
|
+
"route53:ListHostedZones"
|
50
|
+
],
|
51
|
+
"Resource": "*"
|
52
|
+
},
|
53
|
+
{
|
54
|
+
"Sid": "Stmt1485852222001",
|
55
|
+
"Effect": "Allow",
|
56
|
+
"Action": [
|
57
|
+
"route53:ChangeResourceRecordSets",
|
58
|
+
"route53:ListResourceRecordSets"
|
59
|
+
],
|
60
|
+
"Resource": [
|
61
|
+
"arn:aws:route53:::hostedzone/Z1HNC9XBMDGFH9",
|
62
|
+
"arn:aws:route53:::hostedzone/Z2MCBLVJI24XOO",
|
63
|
+
"arn:aws:route53:::hostedzone/Z5H8WZ62ARI5V"
|
64
|
+
]
|
65
|
+
}
|
66
|
+
]
|
67
|
+
}
|
68
|
+
```
|
69
|
+
|
30
70
|
## Contributing
|
31
71
|
|
32
72
|
Fork and send a Pull Request. Thanks!
|
33
73
|
|
74
|
+
### Integration test
|
75
|
+
|
76
|
+
The integration test runs against the AWS Route 53 API, so requires IAM credentials. To run it locally, set up an IAM policy with actions described above, _plus_ the `route53:GetHostedZone` action.
|
77
|
+
|
78
|
+
Three zones must also be set up - a forward, reverse IPv4 and reverse IPv6 zone. The names do not matter. *All records will be deleted* in these zones when running the test, so do not use the zones for any other purpose.
|
79
|
+
|
80
|
+
Export the following environment variables:
|
81
|
+
|
82
|
+
* `AWS_ACCESS_KEY`, `AWS_SECRET_KEY` - per regular plugin configuration
|
83
|
+
* `AWS_FORWARD_ZONE`, `AWS_REVERSE_V4_ZONE`, `AWS_REVERSE_V6_ZONE` - zone names that will be under complete control of the test suite
|
84
|
+
|
34
85
|
## Copyright
|
35
86
|
|
36
87
|
Copyright (c) 2015 Daniel Maraio, Sol Cates, Red Hat Inc. and other contributors
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module ::Proxy::Dns::Route53
|
2
|
+
class PluginConfiguration
|
3
|
+
def load_classes
|
4
|
+
require 'smart_proxy_dns_plugin_template/dns_plugin_template_main'
|
5
|
+
end
|
6
|
+
|
7
|
+
def load_dependency_injection_wirings(container_instance, settings)
|
8
|
+
container_instance.dependency :dns_provider, (lambda do
|
9
|
+
::Proxy::Dns::Route53::Record.new(
|
10
|
+
settings[:aws_access_key],
|
11
|
+
settings[:aws_secret_key],
|
12
|
+
settings[:dns_ttl])
|
13
|
+
end)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -10,15 +10,18 @@ module Proxy::Dns::Route53
|
|
10
10
|
|
11
11
|
attr_reader :aws_access_key, :aws_secret_key
|
12
12
|
|
13
|
-
def initialize(
|
14
|
-
@aws_access_key =
|
15
|
-
@aws_secret_key =
|
16
|
-
super(
|
13
|
+
def initialize(aws_access_key, aws_secret_key, ttl = nil)
|
14
|
+
@aws_access_key = aws_access_key
|
15
|
+
@aws_secret_key = aws_secret_key
|
16
|
+
super(nil, ttl)
|
17
17
|
end
|
18
18
|
|
19
19
|
def create_a_record(fqdn, ip)
|
20
|
-
|
21
|
-
|
20
|
+
case a_record_conflicts(fqdn, ip) #returns -1, 0, 1
|
21
|
+
when 1 then
|
22
|
+
raise(Proxy::Dns::Collision, "#{fqdn} is already used by #{ip}")
|
23
|
+
when 0 then
|
24
|
+
return nil
|
22
25
|
else
|
23
26
|
zone = get_zone(fqdn)
|
24
27
|
new_record = Route53::DNSRecord.new(fqdn, 'A', ttl, [ip], zone)
|
@@ -28,12 +31,30 @@ module Proxy::Dns::Route53
|
|
28
31
|
end
|
29
32
|
end
|
30
33
|
|
31
|
-
def
|
32
|
-
|
33
|
-
|
34
|
+
def create_aaaa_record(fqdn, ip)
|
35
|
+
case aaaa_record_conflicts(fqdn, ip) #returns -1, 0, 1
|
36
|
+
when 1 then
|
37
|
+
raise(Proxy::Dns::Collision, "#{fqdn} is already used by #{ip}")
|
38
|
+
when 0 then
|
39
|
+
return nil
|
34
40
|
else
|
35
|
-
zone = get_zone(
|
36
|
-
new_record = Route53::DNSRecord.new(
|
41
|
+
zone = get_zone(fqdn)
|
42
|
+
new_record = Route53::DNSRecord.new(fqdn, 'AAAA', ttl, [ip], zone)
|
43
|
+
resp = new_record.create
|
44
|
+
raise "AWS Response Error: #{resp}" if resp.error?
|
45
|
+
true
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def create_ptr_record(fqdn, ptr)
|
50
|
+
case ptr_record_conflicts(fqdn, ptr_to_ip(ptr)) #returns -1, 0, 1
|
51
|
+
when 1 then
|
52
|
+
raise(Proxy::Dns::Collision, "#{ptr} is already in use")
|
53
|
+
when 0 then
|
54
|
+
return nil
|
55
|
+
else
|
56
|
+
zone = get_zone(ptr)
|
57
|
+
new_record = Route53::DNSRecord.new(ptr, 'PTR', ttl, [fqdn], zone)
|
37
58
|
resp = new_record.create
|
38
59
|
raise "AWS Response Error: #{resp}" if resp.error?
|
39
60
|
true
|
@@ -44,7 +65,20 @@ module Proxy::Dns::Route53
|
|
44
65
|
zone = get_zone(fqdn)
|
45
66
|
recordset = zone.get_records
|
46
67
|
recordset.each do |rec|
|
47
|
-
if rec.name == fqdn + '.'
|
68
|
+
if rec.name == fqdn + '.' && rec.type == 'A'
|
69
|
+
resp = rec.delete
|
70
|
+
raise "AWS Response Error: #{resp}" if resp.error?
|
71
|
+
return true
|
72
|
+
end
|
73
|
+
end
|
74
|
+
raise Proxy::Dns::NotFound, "Could not find forward record #{fqdn}"
|
75
|
+
end
|
76
|
+
|
77
|
+
def remove_aaaa_record(fqdn)
|
78
|
+
zone = get_zone(fqdn)
|
79
|
+
recordset = zone.get_records
|
80
|
+
recordset.each do |rec|
|
81
|
+
if rec.name == fqdn + '.' && rec.type == 'AAAA'
|
48
82
|
resp = rec.delete
|
49
83
|
raise "AWS Response Error: #{resp}" if resp.error?
|
50
84
|
return true
|
@@ -76,9 +110,14 @@ module Proxy::Dns::Route53
|
|
76
110
|
@resolver ||= Resolv::DNS.new
|
77
111
|
end
|
78
112
|
|
79
|
-
def get_zone(
|
80
|
-
|
81
|
-
|
113
|
+
def get_zone(name)
|
114
|
+
zones = conn.get_zones
|
115
|
+
name_arr = name.split('.')
|
116
|
+
(1 ... name_arr.size).each do |i|
|
117
|
+
search_domain = name_arr.last(name_arr.size - i).join('.') + "."
|
118
|
+
zone_select = zones.select { |z| z.name == search_domain }
|
119
|
+
return zone_select.first if zone_select.any?
|
120
|
+
end
|
82
121
|
end
|
83
122
|
end
|
84
123
|
end
|
@@ -1,16 +1,15 @@
|
|
1
1
|
require 'smart_proxy_dns_route53/dns_route53_version'
|
2
|
+
require 'smart_proxy_dns_route53/dns_route53_configuration'
|
2
3
|
|
3
4
|
module Proxy::Dns::Route53
|
4
5
|
class Plugin < ::Proxy::Provider
|
5
6
|
plugin :dns_route53, ::Proxy::Dns::Route53::VERSION
|
6
7
|
|
7
|
-
requires :dns, '>= 1.
|
8
|
+
requires :dns, '>= 1.13'
|
8
9
|
|
9
|
-
|
10
|
+
default_settings :aws_access_key => nil, :aws_secret_key => nil
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
require 'smart_proxy_dns_route53/route53_dependencies'
|
14
|
-
end
|
12
|
+
load_classes ::Proxy::Dns::Route53::PluginConfiguration
|
13
|
+
load_dependency_injection_wirings ::Proxy::Dns::Route53::PluginConfiguration
|
15
14
|
end
|
16
15
|
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
require 'smart_proxy_dns_route53/dns_route53_plugin'
|
4
|
+
require 'smart_proxy_dns_route53/dns_route53_main'
|
5
|
+
|
6
|
+
require 'dns/dependency_injection'
|
7
|
+
|
8
|
+
module Proxy::Dns
|
9
|
+
module DependencyInjection
|
10
|
+
include Proxy::DependencyInjection::Accessors
|
11
|
+
def container_instance
|
12
|
+
Proxy::DependencyInjection::Container.new do |c|
|
13
|
+
c.dependency :dns_provider, (lambda do
|
14
|
+
::Proxy::Dns::Route53::Record.new(
|
15
|
+
ENV['AWS_ACCESS_KEY'],
|
16
|
+
ENV['AWS_SECRET_KEY'])
|
17
|
+
end)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
require 'dns/dns_api'
|
24
|
+
require 'rack/test'
|
25
|
+
require 'resolv'
|
26
|
+
|
27
|
+
TestRecord = Struct.new(:ip, :type) do
|
28
|
+
alias_method :fqdn, :ip
|
29
|
+
end
|
30
|
+
|
31
|
+
class DnsRoute53IntegrationTest < Test::Unit::TestCase
|
32
|
+
include Rack::Test::Methods
|
33
|
+
|
34
|
+
def app
|
35
|
+
@app = Proxy::Dns::Api.new
|
36
|
+
end
|
37
|
+
|
38
|
+
def setup
|
39
|
+
omit_if(%w[AWS_ACCESS_KEY AWS_SECRET_KEY AWS_FORWARD_ZONE AWS_REVERSE_V4_ZONE AWS_REVERSE_V6_ZONE].any? { |e| !ENV.has_key?(e) })
|
40
|
+
clean_zones
|
41
|
+
@record = nil
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_create_a_record
|
45
|
+
post '/', :fqdn => "test.#{forward_zone}", :value => '192.168.33.33', :type => 'A'
|
46
|
+
assert_equal 200, last_response.status
|
47
|
+
assert_equal '192.168.33.33', record(forward_zone, "test.#{forward_zone}.", 'A').ip
|
48
|
+
assert_equal 'A', @record.type
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_create_ptr_v4_record
|
52
|
+
post '/', :fqdn => "test.#{forward_zone}.", :value => "33.#{reverse_v4_zone}", :type => 'PTR'
|
53
|
+
assert_equal 200, last_response.status
|
54
|
+
assert_equal "test.#{forward_zone}.", record(reverse_v4_zone, "33.#{reverse_v4_zone}.", 'PTR').fqdn
|
55
|
+
assert_equal 'PTR', @record.type
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_create_ptr_v6_record
|
59
|
+
post '/', :fqdn => "test.#{forward_zone}.", :value => "1.#{reverse_v6_zone(true)}", :type => 'PTR'
|
60
|
+
assert_equal 200, last_response.status
|
61
|
+
assert_equal "test.#{forward_zone}.", record(reverse_v6_zone, "1.#{reverse_v6_zone(true)}.", 'PTR').fqdn
|
62
|
+
assert_equal 'PTR', @record.type
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_create_aaaa_record
|
66
|
+
post '/', :fqdn => "test.#{forward_zone}", :value => '2001:db8::1', :type => 'AAAA'
|
67
|
+
assert_equal 200, last_response.status
|
68
|
+
assert_equal '2001:db8::1', record(forward_zone, "test.#{forward_zone}.", 'AAAA').ip
|
69
|
+
assert_equal 'AAAA', @record.type
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_create_cname_record
|
73
|
+
omit 'CNAME support not implemented'
|
74
|
+
post '/', :fqdn => "test.#{forward_zone}", :value => 'test1.com', :type => 'CNAME'
|
75
|
+
assert_equal 200, last_response.status
|
76
|
+
assert_equal 'test1.com.', record(forward_zone, "test.#{forward_zone}.", 'CNAME').fqdn
|
77
|
+
assert_equal 'CNAME', @record.type
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_delete_a_record
|
81
|
+
create_record forward_zone, "test.#{forward_zone}.", 'A', '3600', ['1.2.3.4']
|
82
|
+
delete "/test.#{forward_zone}"
|
83
|
+
assert_equal 200, last_response.status
|
84
|
+
assert_nil record(forward_zone, "test.#{forward_zone}.", 'A')
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_delete_ptr_record
|
88
|
+
create_record reverse_v4_zone, "33.#{reverse_v4_zone}.", 'PTR', '3600', ['test.example.com.']
|
89
|
+
delete "/33.#{reverse_v4_zone}"
|
90
|
+
assert_equal 200, last_response.status
|
91
|
+
assert_nil record(reverse_v4_zone, "33.#{reverse_v4_zone}.", 'PTR')
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_delete_aaaa_record
|
95
|
+
create_record forward_zone, "test.#{forward_zone}.", 'AAAA', '3600', ['2001:db8::1']
|
96
|
+
delete "/test.#{forward_zone}/AAAA"
|
97
|
+
assert_equal 200, last_response.status
|
98
|
+
assert_nil record(forward_zone, "test.#{forward_zone}.", 'AAAA')
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_delete_explicit_cname_record
|
102
|
+
omit 'CNAME support not implemented'
|
103
|
+
create_record forward_zone, "test.#{forward_zone}.", 'CNAME', '3600', ['test.example.com.']
|
104
|
+
delete "/test.#{forward_zone}/CNAME"
|
105
|
+
assert_equal 200, last_response.status
|
106
|
+
assert_nil record(forward_zone, "test.#{forward_zone}.", 'CNAME')
|
107
|
+
end
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
def forward_zone
|
112
|
+
ENV['AWS_FORWARD_ZONE'].chomp('.')
|
113
|
+
end
|
114
|
+
|
115
|
+
def reverse_v4_zone
|
116
|
+
ENV['AWS_REVERSE_V4_ZONE'].chomp('.')
|
117
|
+
end
|
118
|
+
|
119
|
+
def reverse_v6_zone(pad = false)
|
120
|
+
zone = ENV['AWS_REVERSE_V6_ZONE'].chomp('.')
|
121
|
+
if pad
|
122
|
+
zeros = '0.' * ((62 - (reverse_v6_zone.length - 'ip6.arpa'.length)) / 2)
|
123
|
+
"#{zeros}#{zone}"
|
124
|
+
else
|
125
|
+
zone
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def conn
|
130
|
+
@conn ||= Route53::Connection.new(ENV['AWS_ACCESS_KEY'], ENV['AWS_SECRET_KEY'])
|
131
|
+
end
|
132
|
+
|
133
|
+
def clean_zones
|
134
|
+
[forward_zone, reverse_v4_zone, reverse_v6_zone].each do |zone_name|
|
135
|
+
zone = conn.get_zones(zone_name)
|
136
|
+
raise "Cannot find AWS zone #{zone_name}" if zone.nil?
|
137
|
+
zone.first.get_records.each do |record|
|
138
|
+
next if %w[SOA NS].include?(record.type)
|
139
|
+
raise "AWS error while deleting #{record}: #{response}" if (response = record.delete).error?
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def record(zone_name, name, type)
|
145
|
+
zone = conn.get_zones(zone_name)
|
146
|
+
raise "Cannot find AWS zone #{zone_name}" if zone.nil?
|
147
|
+
record = zone.first.get_records.find { |rec| rec.name == name && rec.type == type }
|
148
|
+
@record = record.nil? ? nil : TestRecord.new(record.values.first, record.type)
|
149
|
+
end
|
150
|
+
|
151
|
+
def create_record(zone_name, *record)
|
152
|
+
zone = conn.get_zones(zone_name)
|
153
|
+
raise "Cannot find AWS zone #{zone_name}" if zone.nil?
|
154
|
+
response = Route53::DNSRecord.new(*(record.push(zone.first))).create
|
155
|
+
raise "Failed to create test record #{record}: #{response}" if response.error?
|
156
|
+
record
|
157
|
+
end
|
158
|
+
end
|
@@ -4,141 +4,145 @@ require 'smart_proxy_dns_route53/dns_route53_plugin'
|
|
4
4
|
require 'smart_proxy_dns_route53/dns_route53_main'
|
5
5
|
|
6
6
|
class DnsRoute53RecordTest < Test::Unit::TestCase
|
7
|
+
def setup
|
8
|
+
@provider = Proxy::Dns::Route53::Record.new('foo', 'bar', 86400)
|
9
|
+
end
|
10
|
+
|
7
11
|
# Test that correct initialization works
|
8
12
|
def test_provider_initialization
|
9
|
-
|
10
|
-
|
11
|
-
assert_equal
|
12
|
-
assert_equal 'bar', provider.aws_secret_key
|
13
|
+
assert_equal 'foo', @provider.aws_access_key
|
14
|
+
assert_equal 'bar', @provider.aws_secret_key
|
15
|
+
assert_equal 86400, @provider.ttl
|
13
16
|
end
|
14
17
|
|
15
18
|
# Test A record creation
|
16
19
|
def test_create_a
|
17
|
-
|
18
|
-
record.expects(:dns_find).returns(false)
|
20
|
+
@provider.expects(:a_record_conflicts).with('test.example.com', '10.1.1.1').returns(-1)
|
19
21
|
|
20
22
|
zone = mock()
|
21
|
-
|
23
|
+
@provider.expects(:get_zone).with('test.example.com').returns(zone)
|
22
24
|
|
23
25
|
dnsrecord = mock(:create => mock(:error? => false))
|
24
26
|
Route53::DNSRecord.expects(:new).with('test.example.com', 'A', 86400, ['10.1.1.1'], zone).returns(dnsrecord)
|
25
27
|
|
26
|
-
assert
|
28
|
+
assert @provider.create_a_record(fqdn, ip)
|
27
29
|
end
|
28
30
|
|
29
31
|
# Test A record creation fails if the record exists
|
30
32
|
def test_create_a_conflict
|
31
|
-
|
32
|
-
|
33
|
-
|
33
|
+
@provider.expects(:a_record_conflicts).with(fqdn, ip).returns(1)
|
34
|
+
assert_raise(Proxy::Dns::Collision) { @provider.create_a_record(fqdn, ip) }
|
35
|
+
end
|
36
|
+
|
37
|
+
# Test AAAA record creation
|
38
|
+
def test_create_aaaaa
|
39
|
+
@provider.expects(:aaaa_record_conflicts).with('test.example.com', '2001:db8::1').returns(-1)
|
40
|
+
|
41
|
+
zone = mock()
|
42
|
+
@provider.expects(:get_zone).with('test.example.com').returns(zone)
|
43
|
+
|
44
|
+
dnsrecord = mock(:create => mock(:error? => false))
|
45
|
+
Route53::DNSRecord.expects(:new).with('test.example.com', 'AAAA', 86400, ['2001:db8::1'], zone).returns(dnsrecord)
|
46
|
+
|
47
|
+
assert @provider.create_aaaa_record(fqdn, '2001:db8::1')
|
48
|
+
end
|
49
|
+
|
50
|
+
# Test AAAA record creation fails if the record exists
|
51
|
+
def test_create_aaaa_conflict
|
52
|
+
@provider.expects(:aaaa_record_conflicts).with(fqdn, '2001:db8::1').returns(1)
|
53
|
+
assert_raise(Proxy::Dns::Collision) { @provider.create_aaaa_record(fqdn, '2001:db8::1') }
|
34
54
|
end
|
35
55
|
|
36
56
|
# Test PTR record creation
|
37
57
|
def test_create_ptr
|
38
|
-
|
39
|
-
record.expects(:dns_find).returns(false)
|
58
|
+
@provider.expects(:ptr_record_conflicts).with('test.example.com', '10.1.1.1').returns(false)
|
40
59
|
|
41
60
|
zone = mock()
|
42
|
-
|
61
|
+
@provider.expects(:get_zone).with('1.1.1.10.in-addr.arpa').returns(zone)
|
43
62
|
|
44
63
|
dnsrecord = mock(:create => mock(:error? => false))
|
45
|
-
Route53::DNSRecord.expects(:new).with('
|
64
|
+
Route53::DNSRecord.expects(:new).with('1.1.1.10.in-addr.arpa', 'PTR', 86400, ['test.example.com'], zone).returns(dnsrecord)
|
46
65
|
|
47
|
-
assert
|
66
|
+
assert @provider.create_ptr_record(fqdn, '1.1.1.10.in-addr.arpa')
|
48
67
|
end
|
49
68
|
|
50
69
|
# Test PTR record creation fails if the record exists
|
51
70
|
def test_create_ptr_conflict
|
52
|
-
|
53
|
-
|
54
|
-
assert_raise(Proxy::Dns::Collision) { record.create_ptr_record(fqdn, ip) }
|
71
|
+
@provider.expects(:ptr_record_conflicts).with('test.example.com', '10.1.1.1').returns(1)
|
72
|
+
assert_raise(Proxy::Dns::Collision) { @provider.create_ptr_record(fqdn, '1.1.1.10.in-addr.arpa') }
|
55
73
|
end
|
56
74
|
|
57
75
|
# Test A record removal
|
58
76
|
def test_remove_a
|
59
|
-
zone = mock(:get_records => [mock(:name => 'test.example.com.', :delete => mock(:error? => false))])
|
60
|
-
|
61
|
-
|
62
|
-
assert record.remove_a_record(fqdn)
|
77
|
+
zone = mock(:get_records => [mock(:name => 'test.example.com.', :type => 'A', :delete => mock(:error? => false))])
|
78
|
+
@provider.expects(:get_zone).with('test.example.com').returns(zone)
|
79
|
+
assert @provider.remove_a_record(fqdn)
|
63
80
|
end
|
64
81
|
|
65
82
|
# Test A record removal fails if the record doesn't exist
|
66
83
|
def test_remove_a_not_found
|
67
|
-
|
68
|
-
|
69
|
-
|
84
|
+
@provider.expects(:get_zone).with('test.example.com').returns(mock(:get_records => []))
|
85
|
+
assert_raise(Proxy::Dns::NotFound) { assert @provider.remove_a_record(fqdn) }
|
86
|
+
end
|
87
|
+
|
88
|
+
# Test AAAA record removal
|
89
|
+
def test_remove_aaaa
|
90
|
+
zone = mock(:get_records => [mock(:name => 'test.example.com.', :type => 'AAAA', :delete => mock(:error? => false))])
|
91
|
+
@provider.expects(:get_zone).with('test.example.com').returns(zone)
|
92
|
+
assert @provider.remove_aaaa_record(fqdn)
|
93
|
+
end
|
94
|
+
|
95
|
+
# Test A record removal fails if the record doesn't exist
|
96
|
+
def test_remove_a_not_found
|
97
|
+
@provider.expects(:get_zone).with('test.example.com').returns(mock(:get_records => []))
|
98
|
+
assert_raise(Proxy::Dns::NotFound) { assert @provider.remove_a_record(fqdn) }
|
70
99
|
end
|
71
100
|
|
72
101
|
# Test PTR record removal
|
73
102
|
def test_remove_ptr
|
74
103
|
# FIXME: record name seems incorrect for rDNS
|
75
104
|
zone = mock(:get_records => [mock(:name => '10.1.1.1.', :delete => mock(:error? => false))])
|
76
|
-
|
77
|
-
|
78
|
-
assert record.remove_ptr_record(ip)
|
105
|
+
@provider.expects(:get_zone).with('10.1.1.1').returns(zone)
|
106
|
+
assert @provider.remove_ptr_record(ip)
|
79
107
|
end
|
80
108
|
|
81
109
|
# Test PTR record removal fails if the record doesn't exist
|
82
110
|
def test_remove_ptr_not_found
|
83
|
-
|
84
|
-
|
85
|
-
assert_raise(Proxy::Dns::NotFound) { assert record.remove_ptr_record(ip) }
|
111
|
+
@provider.expects(:get_zone).with('10.1.1.1').returns(mock(:get_records => []))
|
112
|
+
assert_raise(Proxy::Dns::NotFound) { assert @provider.remove_ptr_record(ip) }
|
86
113
|
end
|
87
114
|
|
88
115
|
def test_get_zone_forward
|
89
|
-
|
90
|
-
conn = mock()
|
91
|
-
|
92
|
-
|
93
|
-
assert_equal :zone, record.send(:get_zone, 'test.example.com')
|
116
|
+
zone = stub(:name => 'example.com.')
|
117
|
+
conn = mock(:get_zones => [zone])
|
118
|
+
@provider.expects(:conn).returns(conn)
|
119
|
+
assert_equal zone, @provider.send(:get_zone, 'test.example.com.')
|
94
120
|
end
|
95
121
|
|
96
122
|
def test_get_zone_reverse
|
97
|
-
|
98
|
-
conn = mock()
|
99
|
-
|
100
|
-
|
101
|
-
assert_equal :zone, record.send(:get_zone, '10.1.1.1')
|
123
|
+
zone = stub(:name => '2.1.10.in-addr.arpa.')
|
124
|
+
conn = mock(:get_zones => [zone])
|
125
|
+
@provider.expects(:conn).returns(conn)
|
126
|
+
assert_equal zone, @provider.send(:get_zone, '3.2.1.10.in-addr.arpa.')
|
102
127
|
end
|
103
128
|
|
104
|
-
def
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
assert_equal '10.1.1.1', record.send(:dns_find, 'test.example.com')
|
129
|
+
def test_get_zone_reverse_v6
|
130
|
+
zone = stub(:name => '8.b.d.0.1.0.0.2.ip6.arpa.')
|
131
|
+
conn = mock(:get_zones => [zone])
|
132
|
+
@provider.expects(:conn).returns(conn)
|
133
|
+
assert_equal zone, @provider.send(:get_zone, '1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.')
|
110
134
|
end
|
111
135
|
|
112
|
-
def
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
end
|
119
|
-
|
120
|
-
def test_dns_find_reverse
|
121
|
-
record = klass.new
|
122
|
-
resolver = mock()
|
123
|
-
resolver.expects(:getname).with('3.2.1.10').returns('test.example.com')
|
124
|
-
record.expects(:resolver).returns(resolver)
|
125
|
-
assert_equal 'test.example.com', record.send(:dns_find, '10.1.2.3')
|
126
|
-
end
|
127
|
-
|
128
|
-
def test_dns_find_reverse_not_found
|
129
|
-
record = klass.new
|
130
|
-
resolver = mock()
|
131
|
-
resolver.expects(:getname).with('3.2.1.10').raises(Resolv::ResolvError)
|
132
|
-
record.expects(:resolver).returns(resolver)
|
133
|
-
refute record.send(:dns_find, '10.1.2.3')
|
136
|
+
def test_get_zone_longest_match
|
137
|
+
zone = stub(:name => 'sub.example.com.')
|
138
|
+
other = stub(:name => 'example.com.')
|
139
|
+
conn = mock(:get_zones => [other, zone])
|
140
|
+
@provider.expects(:conn).returns(conn)
|
141
|
+
assert_equal zone, @provider.send(:get_zone, 'host.sub.example.com.')
|
134
142
|
end
|
135
143
|
|
136
144
|
private
|
137
145
|
|
138
|
-
def klass
|
139
|
-
Proxy::Dns::Route53::Record
|
140
|
-
end
|
141
|
-
|
142
146
|
def fqdn
|
143
147
|
'test.example.com'
|
144
148
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: smart_proxy_dns_route53
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Foreman developers
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-02-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: route53
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rack-test
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
69
83
|
description: Route 53 DNS provider plugin for Foreman's smart proxy
|
70
84
|
email:
|
71
85
|
- foreman-dev@googlegroups.com
|
@@ -78,15 +92,16 @@ files:
|
|
78
92
|
- bundler.d/dns_route53.rb
|
79
93
|
- config/dns_route53.yml
|
80
94
|
- lib/smart_proxy_dns_route53.rb
|
95
|
+
- lib/smart_proxy_dns_route53/dns_route53_configuration.rb
|
81
96
|
- lib/smart_proxy_dns_route53/dns_route53_main.rb
|
82
97
|
- lib/smart_proxy_dns_route53/dns_route53_plugin.rb
|
83
98
|
- lib/smart_proxy_dns_route53/dns_route53_version.rb
|
84
|
-
-
|
99
|
+
- test/dns_route53_integration_test.rb
|
85
100
|
- test/dns_route53_record_test.rb
|
86
101
|
- test/test_helper.rb
|
87
102
|
homepage: https://github.com/theforeman/smart_proxy_dns_route53
|
88
103
|
licenses:
|
89
|
-
-
|
104
|
+
- GPL-3.0
|
90
105
|
metadata: {}
|
91
106
|
post_install_message:
|
92
107
|
rdoc_options: []
|
@@ -104,10 +119,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
104
119
|
version: '0'
|
105
120
|
requirements: []
|
106
121
|
rubyforge_project:
|
107
|
-
rubygems_version: 2.
|
122
|
+
rubygems_version: 2.6.8
|
108
123
|
signing_key:
|
109
124
|
specification_version: 4
|
110
125
|
summary: Route 53 DNS provider plugin for Foreman's smart proxy
|
111
126
|
test_files:
|
127
|
+
- test/dns_route53_integration_test.rb
|
112
128
|
- test/dns_route53_record_test.rb
|
113
129
|
- test/test_helper.rb
|