fog-dynect 0.0.1
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 +7 -0
- data/.gitignore +18 -0
- data/.travis.yml +15 -0
- data/CHANGELOG.md +3 -0
- data/CONTRIBUTING.md +18 -0
- data/CONTRIBUTORS.md +27 -0
- data/Gemfile +4 -0
- data/LICENSE.md +20 -0
- data/README.md +58 -0
- data/Rakefile +8 -0
- data/fog-dynect.gemspec +29 -0
- data/gemfiles/Gemfile-1.8.7 +6 -0
- data/lib/fog/dynect.rb +1 -0
- data/lib/fog/dynect/core.rb +27 -0
- data/lib/fog/dynect/dns.rb +157 -0
- data/lib/fog/dynect/models/dns/record.rb +67 -0
- data/lib/fog/dynect/models/dns/records.rb +48 -0
- data/lib/fog/dynect/models/dns/zone.rb +56 -0
- data/lib/fog/dynect/models/dns/zones.rb +25 -0
- data/lib/fog/dynect/requests/dns/delete_record.rb +55 -0
- data/lib/fog/dynect/requests/dns/delete_zone.rb +41 -0
- data/lib/fog/dynect/requests/dns/get_all_records.rb +56 -0
- data/lib/fog/dynect/requests/dns/get_node_list.rb +55 -0
- data/lib/fog/dynect/requests/dns/get_record.rb +83 -0
- data/lib/fog/dynect/requests/dns/get_zone.rb +57 -0
- data/lib/fog/dynect/requests/dns/post_record.rb +71 -0
- data/lib/fog/dynect/requests/dns/post_session.rb +43 -0
- data/lib/fog/dynect/requests/dns/post_zone.rb +70 -0
- data/lib/fog/dynect/requests/dns/put_record.rb +76 -0
- data/lib/fog/dynect/requests/dns/put_zone.rb +76 -0
- data/lib/fog/dynect/version.rb +5 -0
- data/tests/dns/helper.rb +22 -0
- data/tests/dns/models/record_tests.rb +44 -0
- data/tests/dns/models/records_tests.rb +30 -0
- data/tests/dns/models/zone_tests.rb +18 -0
- data/tests/dns/models/zones_tests.rb +18 -0
- data/tests/dynect/requests/dns/dns_tests.rb +258 -0
- data/tests/helper.rb +13 -0
- metadata +168 -0
@@ -0,0 +1,71 @@
|
|
1
|
+
module Fog
|
2
|
+
module DNS
|
3
|
+
class Dynect
|
4
|
+
class Real
|
5
|
+
# Create a record
|
6
|
+
#
|
7
|
+
# ==== Parameters
|
8
|
+
# * 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']
|
9
|
+
# * zone<~String> - zone of record
|
10
|
+
# * rdata<~Hash> - rdata for record
|
11
|
+
# * options<~Hash>: (options vary by type, listing below includes common parameters)
|
12
|
+
# * ttl<~Integer> - ttl for the record, defaults to zone ttl
|
13
|
+
|
14
|
+
def post_record(type, zone, fqdn, rdata, options = {})
|
15
|
+
options.merge!('rdata' => rdata)
|
16
|
+
request(
|
17
|
+
:body => Fog::JSON.encode(options),
|
18
|
+
:expects => 200,
|
19
|
+
:method => :post,
|
20
|
+
:path => ["#{type.to_s.upcase}Record", zone, fqdn].join('/')
|
21
|
+
)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class Mock
|
26
|
+
def post_record(type, zone, fqdn, rdata, options = {})
|
27
|
+
raise Fog::DNS::Dynect::NotFound unless zone = self.data[:zones][zone]
|
28
|
+
|
29
|
+
records = zone[:records]
|
30
|
+
record_id = zone[:next_record_id]
|
31
|
+
zone[:next_record_id] += 1
|
32
|
+
|
33
|
+
record = {
|
34
|
+
:type => type,
|
35
|
+
:zone => zone,
|
36
|
+
:fqdn => fqdn,
|
37
|
+
:rdata => rdata,
|
38
|
+
:ttl => options[:ttl] || zone[:ttl],
|
39
|
+
:record_id => record_id
|
40
|
+
}
|
41
|
+
|
42
|
+
records[type] << record
|
43
|
+
|
44
|
+
response = Excon::Response.new
|
45
|
+
response.status = 200
|
46
|
+
|
47
|
+
response.body = {
|
48
|
+
"status" => "success",
|
49
|
+
"data" => {
|
50
|
+
"zone" => record[:zone][:zone],
|
51
|
+
"ttl" => record[:ttl],
|
52
|
+
"fqdn" => record[:fqdn],
|
53
|
+
"record_type" => record[:type],
|
54
|
+
"rdata" => record[:rdata],
|
55
|
+
"record_id" => record[:record_id]
|
56
|
+
},
|
57
|
+
"job_id" => Fog::Dynect::Mock.job_id,
|
58
|
+
"msgs" => [{
|
59
|
+
"INFO"=>"add: Record added",
|
60
|
+
"SOURCE"=>"BLL",
|
61
|
+
"ERR_CD"=>nil,
|
62
|
+
"LVL"=>"INFO"
|
63
|
+
}]
|
64
|
+
}
|
65
|
+
|
66
|
+
response
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Fog
|
2
|
+
module DNS
|
3
|
+
class Dynect
|
4
|
+
class Real
|
5
|
+
def post_session
|
6
|
+
request(
|
7
|
+
:expects => 200,
|
8
|
+
:idempotent => true,
|
9
|
+
:method => :post,
|
10
|
+
:path => "Session",
|
11
|
+
:body => Fog::JSON.encode({
|
12
|
+
:customer_name => @dynect_customer,
|
13
|
+
:user_name => @dynect_username,
|
14
|
+
:password => @dynect_password
|
15
|
+
})
|
16
|
+
)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class Mock
|
21
|
+
def post_session
|
22
|
+
response = Excon::Response.new
|
23
|
+
response.status = 200
|
24
|
+
response.body = {
|
25
|
+
"status" => "success",
|
26
|
+
"data" => {
|
27
|
+
"token" => auth_token,
|
28
|
+
"version" => Fog::Dynect::Mock.version
|
29
|
+
},
|
30
|
+
"job_id" => Fog::Dynect::Mock.job_id,
|
31
|
+
"msgs"=>[{
|
32
|
+
"INFO"=>"login: Login successful",
|
33
|
+
"SOURCE"=>"BLL",
|
34
|
+
"ERR_CD"=>nil,
|
35
|
+
"LVL"=>"INFO"
|
36
|
+
}]
|
37
|
+
}
|
38
|
+
response
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Fog
|
2
|
+
module DNS
|
3
|
+
class Dynect
|
4
|
+
class Real
|
5
|
+
# Create a zone
|
6
|
+
#
|
7
|
+
# ==== Parameters
|
8
|
+
# * rname<~String> - administrative contact
|
9
|
+
# * ttl<~Integer> - time to live (in seconds) for records in this zone
|
10
|
+
# * zone<~String> - name of zone to host
|
11
|
+
# * options<~Hash>:
|
12
|
+
# * serial_style<~String> - style of serial number, in ['day', 'epoch', 'increment', 'minute']. Defaults to increment
|
13
|
+
|
14
|
+
def post_zone(rname, ttl, zone, options = {})
|
15
|
+
body = Fog::JSON.encode({
|
16
|
+
:rname => rname,
|
17
|
+
:token => auth_token,
|
18
|
+
:ttl => ttl
|
19
|
+
}.merge!(options))
|
20
|
+
|
21
|
+
request(
|
22
|
+
:body => body,
|
23
|
+
:expects => 200,
|
24
|
+
:method => :post,
|
25
|
+
:path => 'Zone/' << zone
|
26
|
+
)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class Mock
|
31
|
+
def post_zone(rname, ttl, zone, options = {})
|
32
|
+
new_zone = self.data[:zones][zone] = {
|
33
|
+
:next_record_id => 0,
|
34
|
+
:records => Hash.new do |records_hash, type|
|
35
|
+
records_hash[type] = []
|
36
|
+
end,
|
37
|
+
:records_to_delete => [],
|
38
|
+
:rname => rname,
|
39
|
+
:serial_style => options[:serial_style] || "increment",
|
40
|
+
:serial => 0,
|
41
|
+
:ttl => ttl,
|
42
|
+
:zone => zone,
|
43
|
+
:zone_type => "Primary"
|
44
|
+
}
|
45
|
+
|
46
|
+
response = Excon::Response.new
|
47
|
+
response.status = 200
|
48
|
+
response.body = {
|
49
|
+
"status" => "success",
|
50
|
+
"data" => {
|
51
|
+
"zone_type" => new_zone[:zone_type],
|
52
|
+
"serial_style" => new_zone[:serial_style],
|
53
|
+
"serial" => new_zone[:serial],
|
54
|
+
"zone" => zone
|
55
|
+
},
|
56
|
+
"job_id" => Fog::Dynect::Mock.job_id,
|
57
|
+
"msgs" => [{
|
58
|
+
"INFO" => "create: New zone #{zone} created. Publish it to put it on our server.",
|
59
|
+
"SOURCE" => "BLL",
|
60
|
+
"ERR_CD" => nil,
|
61
|
+
"LVL" => "INFO"
|
62
|
+
}]
|
63
|
+
}
|
64
|
+
|
65
|
+
response
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Fog
|
2
|
+
module DNS
|
3
|
+
class Dynect
|
4
|
+
class Real
|
5
|
+
# Update or replace a record
|
6
|
+
#
|
7
|
+
# ==== Parameters
|
8
|
+
# * 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']
|
9
|
+
# * zone<~String> - zone of record
|
10
|
+
# * rdata<~Hash> - rdata for record
|
11
|
+
# * options<~Hash>: (options vary by type, listing below includes common parameters)
|
12
|
+
# * ttl<~Integer> - ttl for the record, defaults to zone ttl
|
13
|
+
|
14
|
+
def put_record(type, zone, fqdn, rdata, options = {})
|
15
|
+
options.merge!('rdata' => rdata)
|
16
|
+
type.to_s.upcase!
|
17
|
+
options = {"#{type}Records" => [options]} unless options['record_id']
|
18
|
+
path = ["#{type}Record", zone, fqdn].join('/')
|
19
|
+
path += "/#{options.delete('record_id')}" if options['record_id']
|
20
|
+
request(
|
21
|
+
:body => Fog::JSON.encode(options),
|
22
|
+
:expects => 200,
|
23
|
+
:idempotent => true,
|
24
|
+
:method => :put,
|
25
|
+
:path => path
|
26
|
+
)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class Mock
|
31
|
+
def put_record(type, zone, fqdn, rdata, options = {})
|
32
|
+
raise Fog::DNS::Dynect::NotFound unless zone = self.data[:zones][zone]
|
33
|
+
|
34
|
+
records = zone[:records]
|
35
|
+
record_id = zone[:next_record_id]
|
36
|
+
zone[:next_record_id] += 1
|
37
|
+
|
38
|
+
record = {
|
39
|
+
:type => type,
|
40
|
+
:zone => zone,
|
41
|
+
:fqdn => fqdn,
|
42
|
+
:rdata => rdata,
|
43
|
+
:ttl => options[:ttl] || zone[:ttl],
|
44
|
+
:record_id => record_id
|
45
|
+
}
|
46
|
+
|
47
|
+
records[type] << record
|
48
|
+
|
49
|
+
response = Excon::Response.new
|
50
|
+
response.status = 200
|
51
|
+
|
52
|
+
response.body = {
|
53
|
+
"status" => "success",
|
54
|
+
"data" => {
|
55
|
+
"zone" => record[:zone][:zone],
|
56
|
+
"ttl" => record[:ttl],
|
57
|
+
"fqdn" => record[:fqdn],
|
58
|
+
"record_type" => record[:type],
|
59
|
+
"rdata" => record[:rdata],
|
60
|
+
"record_id" => record[:record_id]
|
61
|
+
},
|
62
|
+
"job_id" => Fog::Dynect::Mock.job_id,
|
63
|
+
"msgs" => [{
|
64
|
+
"INFO"=>"add: Record added",
|
65
|
+
"SOURCE"=>"BLL",
|
66
|
+
"ERR_CD"=>nil,
|
67
|
+
"LVL"=>"INFO"
|
68
|
+
}]
|
69
|
+
}
|
70
|
+
|
71
|
+
response
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Fog
|
2
|
+
module DNS
|
3
|
+
class Dynect
|
4
|
+
class Real
|
5
|
+
# Update a zone
|
6
|
+
#
|
7
|
+
# ==== Parameters
|
8
|
+
# * zone<~String> - name or id of zone
|
9
|
+
# * options<~Hash>:
|
10
|
+
# * freeze<~Boolean> - causes zone to become frozen
|
11
|
+
# * publish<~Boolean> - causes all pending changes to be pushed to nameservers
|
12
|
+
# * thaw<~Boolean> - causes zone to cease being frozen
|
13
|
+
|
14
|
+
def put_zone(zone, options = {})
|
15
|
+
request(
|
16
|
+
:body => Fog::JSON.encode(options),
|
17
|
+
:expects => 200,
|
18
|
+
:idempotent => true,
|
19
|
+
:method => :put,
|
20
|
+
:path => 'Zone/' << zone
|
21
|
+
)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class Mock
|
26
|
+
def put_zone(zone, options = {})
|
27
|
+
raise Fog::DNS::Dynect::NotFound unless zone = self.data[:zones][zone]
|
28
|
+
|
29
|
+
raise ArgumentError unless options.size == 1
|
30
|
+
|
31
|
+
response = Excon::Response.new
|
32
|
+
response.status = 200
|
33
|
+
|
34
|
+
data = {}
|
35
|
+
|
36
|
+
if options['freeze']
|
37
|
+
zone['frozen'] = true
|
38
|
+
info = "freeze: Your zone is now frozen"
|
39
|
+
elsif options['publish']
|
40
|
+
zone[:changes] = {}
|
41
|
+
zone[:records_to_delete].each do |record|
|
42
|
+
zone[:records][record[:type]].delete_if { |r| r[:fqdn] == record[:fqdn] && r[:record_id] == record[:record_id] }
|
43
|
+
end
|
44
|
+
zone[:records_to_delete] = []
|
45
|
+
data = {
|
46
|
+
"zone_type" => zone[:zone_type],
|
47
|
+
"serial_style" => zone[:serial_style],
|
48
|
+
"serial" => zone[:serial] += 1,
|
49
|
+
"zone" => zone[:zone]
|
50
|
+
}
|
51
|
+
info = "publish: #{zone[:zone]} published"
|
52
|
+
elsif options['thaw']
|
53
|
+
zone[:frozen] = false
|
54
|
+
info = "thaw: Your zone is now thawed, you may edit normally"
|
55
|
+
else
|
56
|
+
raise ArgumentError
|
57
|
+
end
|
58
|
+
|
59
|
+
response.body = {
|
60
|
+
"status" => "success",
|
61
|
+
"data" => data,
|
62
|
+
"job_id" => Fog::Dynect::Mock.job_id,
|
63
|
+
"msgs" => [{
|
64
|
+
"INFO" => info,
|
65
|
+
"SOURCE"=>"BLL",
|
66
|
+
"ERR_CD"=>nil,
|
67
|
+
"LVL"=>"INFO"
|
68
|
+
}]
|
69
|
+
}
|
70
|
+
|
71
|
+
response
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/tests/dns/helper.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
def dns_providers
|
2
|
+
{
|
3
|
+
:dynect => {
|
4
|
+
:mocked => false,
|
5
|
+
:zone_attributes => {
|
6
|
+
:email => 'fog@example.com'
|
7
|
+
}
|
8
|
+
}
|
9
|
+
}
|
10
|
+
end
|
11
|
+
|
12
|
+
def generate_unique_domain( with_trailing_dot = false)
|
13
|
+
#get time (with 1/100th of sec accuracy)
|
14
|
+
#want unique domain name and if provider is fast, this can be called more than once per second
|
15
|
+
time= (Time.now.to_f * 100).to_i
|
16
|
+
domain = 'test-' + time.to_s + '.com'
|
17
|
+
if with_trailing_dot
|
18
|
+
domain+= '.'
|
19
|
+
end
|
20
|
+
|
21
|
+
domain
|
22
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
for provider, config in dns_providers
|
2
|
+
|
3
|
+
# FIXME: delay/timing breaks things :(
|
4
|
+
next if [:dnsmadeeasy, :rage4].include?(provider)
|
5
|
+
|
6
|
+
domain_name = uniq_id + '.com'
|
7
|
+
|
8
|
+
Shindo.tests("Fog::DNS[:#{provider}] | record", [provider.to_s]) do
|
9
|
+
|
10
|
+
a_record_attributes = {
|
11
|
+
:name => 'a.' + domain_name,
|
12
|
+
:type => 'A',
|
13
|
+
:value => '1.2.3.4'
|
14
|
+
}.merge!(config[:record_attributes] || {})
|
15
|
+
|
16
|
+
aaaa_record_attributes = {
|
17
|
+
:name => 'aaaa.' + domain_name,
|
18
|
+
:type => 'AAAA',
|
19
|
+
:value => '2001:0db8:0000:0000:0000:ff00:0042:8329'
|
20
|
+
}.merge!(config[:record_attributes] || {})
|
21
|
+
|
22
|
+
cname_record_attributes = {
|
23
|
+
:name => 'cname.' + domain_name,
|
24
|
+
:type => 'CNAME',
|
25
|
+
:value => 'real.' + domain_name
|
26
|
+
}.merge!(config[:record_attributes] || {})
|
27
|
+
|
28
|
+
if !Fog.mocking? || config[:mocked]
|
29
|
+
zone_attributes = {
|
30
|
+
:domain => domain_name
|
31
|
+
}.merge(config[:zone_attributes] || {})
|
32
|
+
|
33
|
+
@zone = Fog::DNS[provider].zones.create(zone_attributes)
|
34
|
+
|
35
|
+
model_tests(@zone.records, a_record_attributes, config[:mocked])
|
36
|
+
model_tests(@zone.records, aaaa_record_attributes, config[:mocked])
|
37
|
+
model_tests(@zone.records, cname_record_attributes, config[:mocked])
|
38
|
+
|
39
|
+
@zone.destroy
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
for provider, config in dns_providers
|
2
|
+
|
3
|
+
# FIXME: delay/timing breaks things :(
|
4
|
+
next if [:dnsmadeeasy, :rage4].include?(provider)
|
5
|
+
|
6
|
+
domain_name = uniq_id + '.com'
|
7
|
+
|
8
|
+
Shindo.tests("Fog::DNS[:#{provider}] | records", [provider.to_s]) do
|
9
|
+
|
10
|
+
record_attributes = {
|
11
|
+
:name => 'www.' + domain_name,
|
12
|
+
:type => 'A',
|
13
|
+
:value => '1.2.3.4'
|
14
|
+
}.merge!(config[:record_attributes] || {})
|
15
|
+
|
16
|
+
if !Fog.mocking? || config[:mocked]
|
17
|
+
zone_attributes = {
|
18
|
+
:domain => domain_name
|
19
|
+
}.merge(config[:zone_attributes] || {})
|
20
|
+
|
21
|
+
@zone = Fog::DNS[provider].zones.create(zone_attributes)
|
22
|
+
|
23
|
+
collection_tests(@zone.records, record_attributes, config[:mocked])
|
24
|
+
|
25
|
+
@zone.destroy
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|