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.
Files changed (39) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.travis.yml +15 -0
  4. data/CHANGELOG.md +3 -0
  5. data/CONTRIBUTING.md +18 -0
  6. data/CONTRIBUTORS.md +27 -0
  7. data/Gemfile +4 -0
  8. data/LICENSE.md +20 -0
  9. data/README.md +58 -0
  10. data/Rakefile +8 -0
  11. data/fog-dynect.gemspec +29 -0
  12. data/gemfiles/Gemfile-1.8.7 +6 -0
  13. data/lib/fog/dynect.rb +1 -0
  14. data/lib/fog/dynect/core.rb +27 -0
  15. data/lib/fog/dynect/dns.rb +157 -0
  16. data/lib/fog/dynect/models/dns/record.rb +67 -0
  17. data/lib/fog/dynect/models/dns/records.rb +48 -0
  18. data/lib/fog/dynect/models/dns/zone.rb +56 -0
  19. data/lib/fog/dynect/models/dns/zones.rb +25 -0
  20. data/lib/fog/dynect/requests/dns/delete_record.rb +55 -0
  21. data/lib/fog/dynect/requests/dns/delete_zone.rb +41 -0
  22. data/lib/fog/dynect/requests/dns/get_all_records.rb +56 -0
  23. data/lib/fog/dynect/requests/dns/get_node_list.rb +55 -0
  24. data/lib/fog/dynect/requests/dns/get_record.rb +83 -0
  25. data/lib/fog/dynect/requests/dns/get_zone.rb +57 -0
  26. data/lib/fog/dynect/requests/dns/post_record.rb +71 -0
  27. data/lib/fog/dynect/requests/dns/post_session.rb +43 -0
  28. data/lib/fog/dynect/requests/dns/post_zone.rb +70 -0
  29. data/lib/fog/dynect/requests/dns/put_record.rb +76 -0
  30. data/lib/fog/dynect/requests/dns/put_zone.rb +76 -0
  31. data/lib/fog/dynect/version.rb +5 -0
  32. data/tests/dns/helper.rb +22 -0
  33. data/tests/dns/models/record_tests.rb +44 -0
  34. data/tests/dns/models/records_tests.rb +30 -0
  35. data/tests/dns/models/zone_tests.rb +18 -0
  36. data/tests/dns/models/zones_tests.rb +18 -0
  37. data/tests/dynect/requests/dns/dns_tests.rb +258 -0
  38. data/tests/helper.rb +13 -0
  39. 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