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,48 @@
|
|
1
|
+
require 'fog/core/collection'
|
2
|
+
require 'fog/dynect/models/dns/record'
|
3
|
+
|
4
|
+
module Fog
|
5
|
+
module DNS
|
6
|
+
class Dynect
|
7
|
+
class Records < Fog::Collection
|
8
|
+
attribute :zone
|
9
|
+
|
10
|
+
model Fog::DNS::Dynect::Record
|
11
|
+
|
12
|
+
def all(options = {})
|
13
|
+
requires :zone
|
14
|
+
data = []
|
15
|
+
service.get_all_records(zone.domain, options).body['data'].each do |records|
|
16
|
+
(type, list) = records
|
17
|
+
list.each do |record|
|
18
|
+
data << {
|
19
|
+
:identity => record['record_id'],
|
20
|
+
:fqdn => record['fqdn'],
|
21
|
+
:type => record['record_type'],
|
22
|
+
:rdata => record['rdata']
|
23
|
+
}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
load(data)
|
28
|
+
end
|
29
|
+
|
30
|
+
def get(record_id)
|
31
|
+
requires :zone
|
32
|
+
|
33
|
+
# there isn't a way to look up by just id
|
34
|
+
# must have type and domain for 'get_record' request
|
35
|
+
# so we pick it from the list returned by 'all'
|
36
|
+
|
37
|
+
list = all
|
38
|
+
list.detect {|e| e.id == record_id}
|
39
|
+
end
|
40
|
+
|
41
|
+
def new(attributes = {})
|
42
|
+
requires :zone
|
43
|
+
super({:zone => zone}.merge!(attributes))
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'fog/core/model'
|
2
|
+
require 'fog/dynect/models/dns/records'
|
3
|
+
|
4
|
+
module Fog
|
5
|
+
module DNS
|
6
|
+
class Dynect
|
7
|
+
class Zone < Fog::Model
|
8
|
+
identity :domain
|
9
|
+
|
10
|
+
attribute :domain, :aliases => 'zone'
|
11
|
+
attribute :email, :aliases => 'rname'
|
12
|
+
attribute :serial
|
13
|
+
attribute :serial_style
|
14
|
+
attribute :ttl
|
15
|
+
attribute :type, :aliases => 'zone_type'
|
16
|
+
|
17
|
+
def initialize(attributes={})
|
18
|
+
super
|
19
|
+
end
|
20
|
+
|
21
|
+
def destroy
|
22
|
+
requires :domain
|
23
|
+
service.delete_zone(domain)
|
24
|
+
true
|
25
|
+
end
|
26
|
+
|
27
|
+
undef_method :domain=
|
28
|
+
def domain=(new_domain)
|
29
|
+
attributes[:domain] = new_domain.split('/').last
|
30
|
+
end
|
31
|
+
|
32
|
+
def publish
|
33
|
+
requires :identity
|
34
|
+
data = service.put_zone(identity, 'publish' => true)
|
35
|
+
true
|
36
|
+
end
|
37
|
+
|
38
|
+
def records
|
39
|
+
@records ||= Fog::DNS::Dynect::Records.new(:zone => self, :service => service)
|
40
|
+
end
|
41
|
+
|
42
|
+
def nameservers
|
43
|
+
raise 'nameservers Not Implemented'
|
44
|
+
end
|
45
|
+
|
46
|
+
def save
|
47
|
+
self.ttl ||= 3600
|
48
|
+
requires :domain, :email, :ttl
|
49
|
+
data = service.post_zone(email, ttl, domain).body['data']
|
50
|
+
merge_attributes(data)
|
51
|
+
true
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'fog/core/collection'
|
2
|
+
require 'fog/dynect/models/dns/zone'
|
3
|
+
|
4
|
+
module Fog
|
5
|
+
module DNS
|
6
|
+
class Dynect
|
7
|
+
class Zones < Fog::Collection
|
8
|
+
model Fog::DNS::Dynect::Zone
|
9
|
+
|
10
|
+
def all
|
11
|
+
data = service.get_zone.body['data'].map do |zone|
|
12
|
+
{ :domain => zone }
|
13
|
+
end
|
14
|
+
load(data)
|
15
|
+
end
|
16
|
+
|
17
|
+
def get(zone_id)
|
18
|
+
new(service.get_zone('zone' => zone_id).body['data'])
|
19
|
+
rescue Excon::Errors::NotFound
|
20
|
+
nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Fog
|
2
|
+
module DNS
|
3
|
+
class Dynect
|
4
|
+
class Real
|
5
|
+
# Delete 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
|
+
# * fqdn<~String> - fqdn of record
|
11
|
+
# * record_id<~String> - id of record
|
12
|
+
|
13
|
+
def delete_record(type, zone, fqdn, record_id)
|
14
|
+
request(
|
15
|
+
:expects => 200,
|
16
|
+
:idempotent => true,
|
17
|
+
:method => :delete,
|
18
|
+
:path => ["#{type.to_s.upcase}Record", zone, fqdn, record_id].join('/')
|
19
|
+
)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class Mock
|
24
|
+
def delete_record(type, zone, fqdn, record_id)
|
25
|
+
raise Fog::DNS::Dynect::NotFound unless zone = self.data[:zones][zone]
|
26
|
+
|
27
|
+
raise Fog::DNS::Dynect::NotFound unless zone[:records][type].find { |record| record[:fqdn] == fqdn && record[:record_id] == record_id.to_i }
|
28
|
+
|
29
|
+
zone[:records_to_delete] << {
|
30
|
+
:type => type,
|
31
|
+
:fqdn => fqdn,
|
32
|
+
:record_id => record_id.to_i
|
33
|
+
}
|
34
|
+
|
35
|
+
response = Excon::Response.new
|
36
|
+
response.status = 200
|
37
|
+
|
38
|
+
response.body = {
|
39
|
+
"status" => "success",
|
40
|
+
"data" => {},
|
41
|
+
"job_id" => Fog::Dynect::Mock.job_id,
|
42
|
+
"msgs" => [{
|
43
|
+
"INFO" => "delete: Record will be deleted on zone publish",
|
44
|
+
"SOURCE" => "BLL",
|
45
|
+
"ERR_CD" => nil,
|
46
|
+
"LVL" => "INFO"
|
47
|
+
}]
|
48
|
+
}
|
49
|
+
|
50
|
+
response
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Fog
|
2
|
+
module DNS
|
3
|
+
class Dynect
|
4
|
+
class Real
|
5
|
+
# Delete a zone
|
6
|
+
#
|
7
|
+
# ==== Parameters
|
8
|
+
# * zone<~String> - zone to host
|
9
|
+
|
10
|
+
def delete_zone(zone)
|
11
|
+
request(
|
12
|
+
:expects => 200,
|
13
|
+
:method => :delete,
|
14
|
+
:path => "Zone/#{zone}"
|
15
|
+
)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class Mock
|
20
|
+
def delete_zone(zone)
|
21
|
+
self.data[:zones].delete(zone)
|
22
|
+
|
23
|
+
response = Excon::Response.new
|
24
|
+
response.status = 200
|
25
|
+
response.body = {
|
26
|
+
"status" => "success",
|
27
|
+
"data" => {},
|
28
|
+
"job_id" => Fog::Dynect::Mock.job_id,
|
29
|
+
"msgs" => [{
|
30
|
+
"ERR_CD" => '',
|
31
|
+
"INFO" => '',
|
32
|
+
"LVL" => '',
|
33
|
+
"SOURCE" => ''
|
34
|
+
}]
|
35
|
+
}
|
36
|
+
response
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Fog
|
2
|
+
module DNS
|
3
|
+
class Dynect
|
4
|
+
class Real
|
5
|
+
# Get one or more node lists
|
6
|
+
#
|
7
|
+
# ==== Parameters
|
8
|
+
# * zone<~String> - zone to lookup node lists for
|
9
|
+
# * options<~Hash>
|
10
|
+
# * fqdn<~String> - fully qualified domain name of node to lookup
|
11
|
+
|
12
|
+
def get_all_records(zone, options = {})
|
13
|
+
requested_fqdn = options['fqdn'] || options[:fqdn]
|
14
|
+
request(
|
15
|
+
:expects => 200,
|
16
|
+
:idempotent => true,
|
17
|
+
:method => :get,
|
18
|
+
:path => ['AllRecord', zone, requested_fqdn].compact.join('/'),
|
19
|
+
:query => {'detail' => 'Y'} # return full records, instead of just resource URLs
|
20
|
+
)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class Mock
|
25
|
+
def get_all_records(zone, options = {})
|
26
|
+
raise Fog::DNS::Dynect::NotFound unless zone = self.data[:zones][zone]
|
27
|
+
|
28
|
+
response = Excon::Response.new
|
29
|
+
response.status = 200
|
30
|
+
|
31
|
+
data = [zone[:zone]]
|
32
|
+
|
33
|
+
if fqdn = options[:fqdn]
|
34
|
+
data = data | zone[:records].map { |type, records| records.select { |record| record[:fqdn] == fqdn } }.flatten.compact
|
35
|
+
else
|
36
|
+
data = data | zone[:records].map { |type, records| records.map { |record| record[:fqdn] } }.flatten
|
37
|
+
end
|
38
|
+
|
39
|
+
response.body = {
|
40
|
+
"status" => "success",
|
41
|
+
"data" => data,
|
42
|
+
"job_id" => Fog::Dynect::Mock.job_id,
|
43
|
+
"msgs" => [{
|
44
|
+
"INFO" => "get_tree: Here is your zone tree",
|
45
|
+
"SOURCE" => "BLL",
|
46
|
+
"ERR_CD" => nil,
|
47
|
+
"LVL" => "INFO"
|
48
|
+
}]
|
49
|
+
}
|
50
|
+
|
51
|
+
response
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Fog
|
2
|
+
module DNS
|
3
|
+
class Dynect
|
4
|
+
class Real
|
5
|
+
# Get one or more node lists
|
6
|
+
#
|
7
|
+
# ==== Parameters
|
8
|
+
# * zone<~String> - zone to lookup node lists for
|
9
|
+
# * options<~Hash>
|
10
|
+
# * fqdn<~String> - fully qualified domain name of node to lookup
|
11
|
+
|
12
|
+
def get_node_list(zone, options = {})
|
13
|
+
requested_fqdn = options['fqdn'] || options[:fqdn]
|
14
|
+
request(
|
15
|
+
:expects => 200,
|
16
|
+
:idempotent => true,
|
17
|
+
:method => :get,
|
18
|
+
:path => ['AllRecord', zone, requested_fqdn].compact.join('/')
|
19
|
+
)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class Mock
|
24
|
+
def get_node_list(zone, options = {})
|
25
|
+
raise Fog::DNS::Dynect::NotFound unless zone = self.data[:zones][zone]
|
26
|
+
|
27
|
+
response = Excon::Response.new
|
28
|
+
response.status = 200
|
29
|
+
|
30
|
+
data = [zone[:zone]]
|
31
|
+
|
32
|
+
if fqdn = options[:fqdn]
|
33
|
+
data = data | zone[:records].map { |type, records| records.select { |record| record[:fqdn] == fqdn } }.flatten.compact
|
34
|
+
else
|
35
|
+
data = data | zone[:records].map { |type, records| records.map { |record| record[:fqdn] } }.flatten
|
36
|
+
end
|
37
|
+
|
38
|
+
response.body = {
|
39
|
+
"status" => "success",
|
40
|
+
"data" => data,
|
41
|
+
"job_id" => Fog::Dynect::Mock.job_id,
|
42
|
+
"msgs" => [{
|
43
|
+
"INFO" => "get_tree: Here is your zone tree",
|
44
|
+
"SOURCE" => "BLL",
|
45
|
+
"ERR_CD" => nil,
|
46
|
+
"LVL" => "INFO"
|
47
|
+
}]
|
48
|
+
}
|
49
|
+
|
50
|
+
response
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module Fog
|
2
|
+
module DNS
|
3
|
+
class Dynect
|
4
|
+
class Real
|
5
|
+
# List records of a given type
|
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> - name of zone to lookup
|
10
|
+
# * fqdn<~String> - name of fqdn to lookup
|
11
|
+
# * options<~Hash>:
|
12
|
+
# * record_id<~String> - id of record
|
13
|
+
|
14
|
+
def get_record(type, zone, fqdn, options = {})
|
15
|
+
request(
|
16
|
+
:expects => 200,
|
17
|
+
:idempotent => true,
|
18
|
+
:method => :get,
|
19
|
+
:path => ["#{type.to_s.upcase}Record", zone, fqdn, options['record_id']].compact.join('/')
|
20
|
+
)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class Mock
|
25
|
+
def get_record(type, zone, fqdn, options = {})
|
26
|
+
raise ArgumentError unless [
|
27
|
+
'AAAA', 'ANY', 'A', 'CNAME',
|
28
|
+
'DHCID', 'DNAME', 'DNSKEY',
|
29
|
+
'DS', 'KEY', 'LOC', 'MX',
|
30
|
+
'NSA', 'NS', 'PTR', 'PX',
|
31
|
+
'RP', 'SOA', 'SPF', 'SRV',
|
32
|
+
'SSHFP', 'TXT'
|
33
|
+
].include? type
|
34
|
+
raise Fog::DNS::Dynect::NotFound unless zone = self.data[:zones][zone]
|
35
|
+
|
36
|
+
response = Excon::Response.new
|
37
|
+
response.status = 200
|
38
|
+
|
39
|
+
if record_id = options['record_id']
|
40
|
+
raise Fog::DNS::Dynect::NotFound unless record = zone[:records][type].find { |record| record[:record_id] == record_id.to_i }
|
41
|
+
response.body = {
|
42
|
+
"status" => "success",
|
43
|
+
"data" => {
|
44
|
+
"zone" => record[:zone][:zone],
|
45
|
+
"ttl" => record[:ttl],
|
46
|
+
"fqdn" => record[:fqdn],
|
47
|
+
"record_type" => type,
|
48
|
+
"rdata" => record[:rdata],
|
49
|
+
"record_id" => record[:record_id]
|
50
|
+
},
|
51
|
+
"job_id" => Fog::Dynect::Mock.job_id,
|
52
|
+
"msgs" => [{
|
53
|
+
"INFO" => "get: Found the record",
|
54
|
+
"SOURCE" => "API-B",
|
55
|
+
"ERR_CD" => nil,
|
56
|
+
"LVL" => "INFO"
|
57
|
+
}]
|
58
|
+
}
|
59
|
+
else
|
60
|
+
records = if type == "ANY"
|
61
|
+
zone[:records].values.flatten.select { |record| record[:fqdn] == fqdn }
|
62
|
+
else
|
63
|
+
zone[:records][type].select { |record| record[:fqdn] == fqdn }
|
64
|
+
end
|
65
|
+
response.body = {
|
66
|
+
"status" => "success",
|
67
|
+
"data" => records.map { |record| "/REST/#{record[:type]}Record/#{record[:zone][:zone]}/#{record[:fqdn]}/#{record[:record_id]}" },
|
68
|
+
"job_id" => Fog::Dynect::Mock.job_id,
|
69
|
+
"msgs" => [{
|
70
|
+
"INFO" => "detail: Found #{records.size} record",
|
71
|
+
"SOURCE" => "BLL",
|
72
|
+
"ERR_CD" => nil,
|
73
|
+
"LVL" => "INFO"
|
74
|
+
}]
|
75
|
+
}
|
76
|
+
end
|
77
|
+
|
78
|
+
response
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Fog
|
2
|
+
module DNS
|
3
|
+
class Dynect
|
4
|
+
class Real
|
5
|
+
# Get one or more zones
|
6
|
+
#
|
7
|
+
# ==== Parameters
|
8
|
+
# * options<~Hash>:
|
9
|
+
# * zone<~String> - name of zone to lookup, or omit to return list of zones
|
10
|
+
|
11
|
+
def get_zone(options = {})
|
12
|
+
request(
|
13
|
+
:expects => 200,
|
14
|
+
:idempotent => true,
|
15
|
+
:method => :get,
|
16
|
+
:path => ['Zone', options['zone']].compact.join('/')
|
17
|
+
)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class Mock
|
22
|
+
def get_zone(options = {})
|
23
|
+
if options['zone']
|
24
|
+
raise Fog::DNS::Dynect::NotFound unless zone = self.data[:zones][options['zone']]
|
25
|
+
data = {
|
26
|
+
"zone_type" => zone[:zone_type],
|
27
|
+
"serial_style" => zone[:serial_style],
|
28
|
+
"serial" => zone[:serial],
|
29
|
+
"zone" => zone[:zone]
|
30
|
+
}
|
31
|
+
info = "get: Your zone, #{zone[:zone]}"
|
32
|
+
else
|
33
|
+
data = self.data[:zones].map { |zone, data| "/REST/Zone/#{zone}/" }
|
34
|
+
info = "get: Your #{data.size} zones"
|
35
|
+
end
|
36
|
+
|
37
|
+
response = Excon::Response.new
|
38
|
+
response.status = 200
|
39
|
+
|
40
|
+
response.body = {
|
41
|
+
"status" => "success",
|
42
|
+
"data" => data,
|
43
|
+
"job_id" => Fog::Dynect::Mock.job_id,
|
44
|
+
"msgs" => [{
|
45
|
+
"INFO" => info,
|
46
|
+
"SOURCE" => "BLL",
|
47
|
+
"ERR_CD" => nil,
|
48
|
+
"LVL" => "INFO"
|
49
|
+
}]
|
50
|
+
}
|
51
|
+
|
52
|
+
response
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|