dns-zonefile 1.1.0 → 1.1.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -53,7 +53,7 @@ grammar Zonefile
53
53
  end
54
54
 
55
55
  rule resource_record
56
- record:(a_record / aaaa_record / cname_record / mx_record / naptr_record / ns_record / ptr_record / srv_record / spf_record / txt_record / soa_record) space* comment? linebreak {
56
+ record:(a_record / aaaa_record / caa_record / cname_record / mx_record / naptr_record / ns_record / ptr_record / srv_record / spf_record / sshfp_record / txt_record / soa_record) space* comment? linebreak {
57
57
  def zone
58
58
  p = parent
59
59
  while p.respond_to?(:parent) && p.parent
@@ -128,6 +128,28 @@ grammar Zonefile
128
128
  }
129
129
  end
130
130
 
131
+ rule caa_record
132
+ (
133
+ host space ms_age ttl klass "CAA" space flags:integer space tag:unquoted_string space value:caa_value
134
+ ) {
135
+ def to_s
136
+ "#{host} #{ttl} #{klass} CAA #{flags} #{tag} #{value}"
137
+ end
138
+
139
+ def record_type
140
+ "CAA"
141
+ end
142
+ }
143
+ end
144
+
145
+ rule caa_value
146
+ (quoted_string / unquoted_string) {
147
+ def to_s
148
+ text_value
149
+ end
150
+ }
151
+ end
152
+
131
153
  rule cname_record
132
154
  (
133
155
  host space ms_age ttl klass "CNAME" space target:host /
@@ -221,7 +243,7 @@ grammar Zonefile
221
243
  end
222
244
  }
223
245
  end
224
-
246
+
225
247
  rule spf_record
226
248
  host space ms_age ttl klass "SPF" space data:txt_data {
227
249
  def to_s
@@ -233,7 +255,19 @@ grammar Zonefile
233
255
  end
234
256
  }
235
257
  end
236
-
258
+
259
+ rule sshfp_record
260
+ host space ms_age ttl klass "SSHFP" space alg:integer space fptype:integer space fp:fingerprint {
261
+ def to_s
262
+ "#{host} #{ttl} #{klass} SSHFP #{alg} #{fptype} #{fp}"
263
+ end
264
+
265
+ def record_type
266
+ "SSHFP"
267
+ end
268
+ }
269
+ end
270
+
237
271
  rule txt_record
238
272
  host space ms_age ttl klass "TXT" space data:ms_txt_data {
239
273
  def to_s
@@ -436,14 +470,15 @@ grammar Zonefile
436
470
  rule host
437
471
  ( ([*a-zA-Z0-9\-\._]+) / "@" / ' ' / "\t" ) {
438
472
  def to_s
439
- case text_value
440
- when /\.$/
441
- text_value
442
- when "@", /\s/
443
- text_value
444
- else
445
- text_value + '.@'
446
- end
473
+ text_value
474
+ end
475
+ }
476
+ end
477
+
478
+ rule fingerprint
479
+ [a-fA-Z0-9:]+ {
480
+ def to_s
481
+ text_value.strip
447
482
  end
448
483
  }
449
484
  end
@@ -492,7 +527,7 @@ grammar Zonefile
492
527
  end
493
528
 
494
529
  rule unquoted_string
495
- [a-zA-Z0-9]+ {
530
+ [a-zA-Z0-9=_]+ {
496
531
  def to_s
497
532
  text_value
498
533
  end
@@ -1,5 +1,5 @@
1
1
  module DNS
2
2
  module Zonefile
3
- VERSION = "1.1.0"
3
+ VERSION = "1.1.9"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,72 +1,87 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dns-zonefile
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Craig R Webster
8
+ - Anthony Eden
8
9
  autorequire:
9
- bindir: bin
10
+ bindir: exe
10
11
  cert_chain: []
11
- date: 2016-06-01 00:00:00.000000000 Z
12
+ date: 2020-09-10 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
- name: rspec
15
+ name: treetop
15
16
  requirement: !ruby/object:Gem::Requirement
16
17
  requirements:
17
- - - ">="
18
+ - - "~>"
18
19
  - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :development
20
+ version: '1.6'
21
+ type: :runtime
21
22
  prerelease: false
22
23
  version_requirements: !ruby/object:Gem::Requirement
23
24
  requirements:
24
- - - ">="
25
+ - - "~>"
25
26
  - !ruby/object:Gem::Version
26
- version: '0'
27
+ version: '1.6'
27
28
  - !ruby/object:Gem::Dependency
28
- name: rake
29
+ name: polyglot
29
30
  requirement: !ruby/object:Gem::Requirement
30
31
  requirements:
31
- - - ">="
32
+ - - "~>"
32
33
  - !ruby/object:Gem::Version
33
- version: '0'
34
+ version: '0.3'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '0.3'
42
+ - !ruby/object:Gem::Dependency
43
+ name: bundler
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '2.1'
34
49
  type: :development
35
50
  prerelease: false
36
51
  version_requirements: !ruby/object:Gem::Requirement
37
52
  requirements:
38
- - - ">="
53
+ - - "~>"
39
54
  - !ruby/object:Gem::Version
40
- version: '0'
55
+ version: '2.1'
41
56
  - !ruby/object:Gem::Dependency
42
- name: treetop
57
+ name: rake
43
58
  requirement: !ruby/object:Gem::Requirement
44
59
  requirements:
45
- - - ">="
60
+ - - "~>"
46
61
  - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :runtime
62
+ version: '13.0'
63
+ type: :development
49
64
  prerelease: false
50
65
  version_requirements: !ruby/object:Gem::Requirement
51
66
  requirements:
52
- - - ">="
67
+ - - "~>"
53
68
  - !ruby/object:Gem::Version
54
- version: '0'
69
+ version: '13.0'
55
70
  - !ruby/object:Gem::Dependency
56
- name: polyglot
71
+ name: rspec
57
72
  requirement: !ruby/object:Gem::Requirement
58
73
  requirements:
59
- - - ">="
74
+ - - "~>"
60
75
  - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :runtime
76
+ version: '3.0'
77
+ type: :development
63
78
  prerelease: false
64
79
  version_requirements: !ruby/object:Gem::Requirement
65
80
  requirements:
66
- - - ">="
81
+ - - "~>"
67
82
  - !ruby/object:Gem::Version
68
- version: '0'
69
- description: |-
83
+ version: '3.0'
84
+ description: |
70
85
  The format of a DNS Zonefile is defined in RFC 1035 section 5 and RFC
71
86
  1034 section 3.6.1. To anyone who's using BIND they'll look very
72
87
  familiar.
@@ -76,32 +91,41 @@ description: |-
76
91
  some canonical form.
77
92
  email:
78
93
  - craig@barkingiguana.com
94
+ - anthonyeden@gmail.com
79
95
  executables: []
80
96
  extensions: []
81
97
  extra_rdoc_files: []
82
98
  files:
83
99
  - ".gitignore"
100
+ - ".rspec"
84
101
  - ".travis.yml"
102
+ - CONTRIBUTING.md
85
103
  - Dockerfile
86
104
  - Gemfile
87
105
  - LICENCE
88
106
  - README.md
89
107
  - Rakefile
90
108
  - TODO
109
+ - bin/console
110
+ - bin/setup
111
+ - circle.yml
91
112
  - dns-zonefile.gemspec
92
113
  - doc/example.com.zone
93
114
  - doc/example2.com.zone
94
115
  - doc/example3.com.zone
95
116
  - doc/zonefile.example
96
117
  - docker-compose.yml
118
+ - examples/basic.rb
119
+ - examples/basic_origin.rb
120
+ - examples/example.com.no-origin.zonefile
121
+ - examples/example.com.zonefile
97
122
  - lib/dns/zonefile.rb
98
123
  - lib/dns/zonefile.treetop
99
124
  - lib/dns/zonefile/version.rb
100
- - spec/dns/zonefile_spec.rb
101
- - spec/spec_helper.rb
102
- homepage: ''
125
+ homepage: https://github.com/craigw/dns-zonefile
103
126
  licenses: []
104
- metadata: {}
127
+ metadata:
128
+ allowed_push_host: https://rubygems.org
105
129
  post_install_message:
106
130
  rdoc_options: []
107
131
  require_paths:
@@ -117,11 +141,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
117
141
  - !ruby/object:Gem::Version
118
142
  version: '0'
119
143
  requirements: []
120
- rubyforge_project: dns-zonefile
121
- rubygems_version: 2.4.5.1
144
+ rubygems_version: 3.1.2
122
145
  signing_key:
123
146
  specification_version: 4
124
147
  summary: Work with zonefiles (RFC 1035 section 5 and RFC 1034 section 3.6.1)
125
- test_files:
126
- - spec/dns/zonefile_spec.rb
127
- - spec/spec_helper.rb
148
+ test_files: []
@@ -1,435 +0,0 @@
1
- require 'spec_helper'
2
- require 'dns/zonefile'
3
-
4
- RSpec.describe "DNS::Zonefile" do
5
- it "should be versioned" do
6
- expect { DNS::Zonefile.const_get(:VERSION) }.to_not raise_error
7
- end
8
-
9
- it "should provide a way of parsing a string" do
10
- expect(DNS::Zonefile).to respond_to(:parse)
11
- end
12
-
13
- describe "parsing a zonefile string" do
14
- before(:each) do
15
- @zonefile =<<-ZONE
16
- ; Hi! I'm an example zonefile.
17
- $ORIGIN example.com.
18
- $TTL 86400; expire in 1 day.
19
- $OTHER abc
20
- ; line above has spaces at the end, but no comment
21
- @ IN SOA ns.example.com. hostmaster\\.awesome.example.com. (
22
- ;
23
- 2007120710 ; serial number of this zone file
24
- ;two
25
- ;comments
26
- 1d ; slave refresh (1 day)
27
- 1d ; slave retry time in case of a problem (1 day)
28
- 4W ; slave expiration time (4 weeks)
29
- 3600 ; minimum caching time in case of failed lookups (1 hour)
30
- )
31
- ; That's the SOA part done.
32
-
33
- ; Next comment line has nothing after the semi-colon.
34
- ;
35
-
36
- ; Let's start the resource records.
37
- example.com. NS ns ; ns.example.com is the nameserver for example.com
38
- example.com. NS ns.somewhere.com. ; ns.somewhere.com is a backup nameserver for example.com
39
- example.com. A 10.0.0.1 ; ip address for "example.com". next line has spaces after the IP, but no actual comment.
40
- @ A 10.0.0.11
41
- A 10.0.0.12 ; tertiary ip for "example.com"
42
- ns A 10.0.0.2 ; ip address for "ns.example.com"
43
- 60 A 10.0.0.21 ; secondary ip for "ns.example.com" with TTL
44
- * A 10.0.0.100 ; wildcard
45
- *.sub A 10.0.0.101 ; subdomain wildcard
46
- with-class IN A 10.0.0.3 ; record that includes the class type of IN
47
- with-ttl 60 A 10.0.0.5 ; with a specified TTL
48
- ttl-class 60 IN A 10.0.0.6 ; with TTL and class type
49
- www CNAME ns ; "www.example.com" is an alias for "ns.example.com"
50
- wwwtest CNAME www ; "wwwtest.example.com" is another alias for "www.example.com"
51
- www2 CNAME ns.example.com. ; yet another alias, with FQDN target
52
-
53
- ; Email... that'll be fun then
54
- example.com. MX 10 mail.example.com. ; mail.example.com is the mailserver for example.com
55
- @ MX 20 mail2.example.com. ; Similar to above line, but using "@" to say "use $ORIGIN"
56
- @ MX 50 mail3 ; Similar to above line, but using a host within this domain
57
-
58
- @ AAAA 2001:db8:a::1 ; IPv6, lowercase
59
- ns AAAA 2001:DB8:B::1 ; IPv6, uppercase
60
- mail AAAA 2001:db8:c::10.0.0.4 ; IPv6, with trailing IPv4-type address
61
-
62
- sip NAPTR 100 10 "U" "E2U+sip" "!^.*$!sip:cs@example.com!i" . ; NAPTR record
63
- sip2 NAPTR 100 10 "" "" "/urn:cid:.+@([^\\.]+\\.)(.*)$/\\2/i" . ; another one
64
-
65
- _xmpp-server._tcp SRV 5 0 5269 xmpp-server.l.google.com. ; SRV record
66
-
67
- ; TXT record, with embedded semicolons
68
- _domainkey TXT "v=DKIM1\\;g=*\\;k=rsa\\; p=4tkw1bbkfa0ahfjgnbewr2ttkvahvfmfizowl9s4g0h28io76ndow25snl9iumpcv0jwxr2k"
69
- with_ms_txt TXT ( "Some text" )
70
-
71
- @ TXT "some other \\"message\\" goes here" ; embedded quotes
72
- long TXT "a multi-segment TXT record" "usually used for really long TXT records" "since each segment can only span 255 chars"
73
- unquoted TXT some text data
74
-
75
- multiline TXT "A TXT record
76
- split across multiple lines
77
- with LF and CRLF line endings"
78
-
79
- ; Microsoft AD DNS Examples with Aging.
80
- with-age [AGE:999992222] 60 A 10.0.0.7 ; with a specified AGE
81
- with-age-aaaa [AGE:999992222] 60 AAAA 10.0.0.8 ; with a specified AGE
82
- _ldap._tcp.pupy._sites.dc._msdcs [AGE:3636525] 600 SRV 0 100 389 host01.ad
83
- P229392922 [AGE:3636449] 172800 CNAME printer01.ad
84
-
85
- @ SPF "v=spf1 a a:other.domain.com ~all"
86
-
87
- 45 IN PTR @
88
-
89
-
90
- eam 900 IN SRV 5 0 5269 www
91
- eam IN 900 SRV 5 0 5269 www
92
- eam IN SRV 5 0 5269 www
93
- eam 900 SRV 5 0 5269 www
94
- eam SRV 5 0 5269 www
95
-
96
- eam 900 IN CNAME www
97
- eam IN 900 CNAME www
98
- eam IN CNAME www
99
- eam 900 CNAME www
100
- eam CNAME www
101
-
102
- $ORIGIN test.example.com.
103
- $TTL 3600; expire in 1 day.
104
- @ A 10.1.0.1 ; Test with alternate origin
105
- MX 10 mail.example.com.
106
- www A 10.1.0.2 ; www.test.example.com.
107
-
108
- ZONE
109
- end
110
-
111
- it "should set the origin correctly" do
112
- zone = DNS::Zonefile.parse(@zonefile)
113
- expect(zone.origin).to eq('@')
114
- end
115
-
116
- it "should interpret the origin correctly" do
117
- zone = DNS::Zonefile.load(@zonefile)
118
- expect(zone.soa.origin).to eq('example.com.')
119
- end
120
-
121
- it "should set the zone variables correctly" do
122
- zone = DNS::Zonefile.parse(@zonefile)
123
- expect(zone.variables['TTL']).to eq('86400')
124
- expect(zone.variables['ORIGIN']).to eq('example.com.')
125
- end
126
-
127
- it "should interpret the SOA correctly" do
128
- zone = DNS::Zonefile.load(@zonefile)
129
- soa = zone.soa
130
- expect(soa.klass).to eq('IN')
131
- expect(soa.ttl).to eq(86400)
132
- expect(soa.nameserver).to eq('ns.example.com.')
133
- expect(soa.responsible_party).to eq('hostmaster\.awesome.example.com.')
134
- expect(soa.serial).to eq(2007120710)
135
- expect(soa.refresh_time).to eq(86400)
136
- expect(soa.retry_time).to eq(86400)
137
- expect(soa.expiry_time).to eq(2419200)
138
- expect(soa.nxttl).to eq(3600)
139
- end
140
-
141
- it "should build the correct number of resource records" do
142
- zone = DNS::Zonefile.parse(@zonefile)
143
- expect(zone.rr.size).to eq(49)
144
- end
145
-
146
- it "should build the correct NS records" do
147
- zone = DNS::Zonefile.load(@zonefile)
148
- ns_records = zone.records_of DNS::Zonefile::NS
149
- expect(ns_records.size).to eq(2)
150
-
151
- expect(ns_records.detect { |ns|
152
- ns.host == "example.com." && ns.nameserver == "ns.example.com."
153
- }).to_not be_nil
154
-
155
- expect(ns_records.detect { |ns|
156
- ns.host == "example.com." && ns.nameserver == "ns.somewhere.com." && ns.ttl == 86400
157
- }).to_not be_nil
158
- end
159
-
160
- it "should build the correct A records" do
161
- zone = DNS::Zonefile.load(@zonefile)
162
- a_records = zone.records_of DNS::Zonefile::A
163
- expect(a_records.size).to eq(13)
164
-
165
- expect(a_records.detect { |a|
166
- a.host == "example.com." && a.address == "10.0.0.1"
167
- }).to_not be_nil
168
-
169
- expect(a_records.detect { |a|
170
- a.host == "example.com." && a.address == "10.0.0.11"
171
- }).to_not be_nil
172
-
173
- expect(a_records.detect { |a|
174
- a.host == "example.com." && a.address == "10.0.0.12"
175
- }).to_not be_nil
176
-
177
- expect(a_records.detect { |a|
178
- a.host == "ns.example.com." && a.address == "10.0.0.2" && a.ttl == 86400
179
- }).to_not be_nil
180
-
181
- expect(a_records.detect { |a|
182
- a.host == "ns.example.com." && a.address == "10.0.0.21" && a.ttl == 60
183
- }).to_not be_nil
184
-
185
- expect(a_records.detect { |a|
186
- a.host == "*.example.com." && a.address == "10.0.0.100"
187
- }).to_not be_nil
188
-
189
- expect(a_records.detect { |a|
190
- a.host == "*.sub.example.com." && a.address == "10.0.0.101"
191
- }).to_not be_nil
192
-
193
- expect(a_records.detect { |a|
194
- a.host == "with-class.example.com." && a.address == "10.0.0.3" && a.ttl == 86400
195
- }).to_not be_nil
196
-
197
- expect(a_records.detect { |a|
198
- a.host == "with-ttl.example.com." && a.address == "10.0.0.5" && a.ttl == 60
199
- }).to_not be_nil
200
-
201
- expect(a_records.detect { |a|
202
- a.host == "with-age.example.com." && a.address == "10.0.0.7" && a.ttl == 60
203
- }).to_not be_nil
204
-
205
- expect(a_records.detect { |a|
206
- a.host == "ttl-class.example.com." && a.address == "10.0.0.6" && a.ttl == 60
207
- }).to_not be_nil
208
-
209
- expect(a_records.detect { |a|
210
- a.host == "test.example.com." && a.address == "10.1.0.1" && a.ttl == 3600
211
- }).to_not be_nil
212
-
213
- expect(a_records.detect { |a|
214
- a.host == "www.test.example.com." && a.address == "10.1.0.2" && a.ttl == 3600
215
- }).to_not be_nil
216
- end
217
-
218
- it "should build the correct CNAME records" do
219
- zone = DNS::Zonefile.load(@zonefile)
220
- cname_records = zone.records_of DNS::Zonefile::CNAME
221
- expect(cname_records.size).to eq(9)
222
-
223
- expect(cname_records.detect { |cname|
224
- cname.host == "www.example.com." && cname.target == "ns.example.com."
225
- }).to_not be_nil
226
-
227
- expect(cname_records.detect { |cname|
228
- cname.host == "wwwtest.example.com." && cname.domainname == "www.example.com."
229
- }).to_not be_nil
230
-
231
- expect(cname_records.detect { |cname|
232
- cname.host == "www2.example.com." && cname.domainname == "ns.example.com." && cname.ttl == 86400
233
- }).to_not be_nil
234
-
235
- expect(cname_records.detect { |cname|
236
- cname.host == "P229392922.example.com." && cname.domainname == "printer01.ad.example.com." && cname.ttl == 172800
237
- }).to_not be_nil
238
-
239
- eam_records = cname_records.select { |c| c.host =~ /eam\./ }
240
-
241
- expect(eam_records.length).to eq(5)
242
-
243
- eam_records.each { |cname|
244
- expect(cname.target).to eq("www.example.com.")
245
- }
246
-
247
- r = eam_records.group_by { |c| c.ttl }
248
- expect(r[900].length).to eq(3)
249
- expect(r[86400].length).to eq(2)
250
- end
251
-
252
- it "should build the correct MX records" do
253
- zone = DNS::Zonefile.load(@zonefile)
254
- mx_records = zone.records_of DNS::Zonefile::MX
255
- expect(mx_records.length).to eq(4)
256
-
257
- expect(mx_records.detect { |mx|
258
- mx.host == "example.com." && mx.priority == 10 && mx.exchanger == 'mail.example.com.'
259
- }).to_not be_nil
260
-
261
- expect(mx_records.detect { |mx|
262
- mx.host == "example.com." && mx.priority == 20 && mx.exchange == 'mail2.example.com.'
263
- }).to_not be_nil
264
-
265
- expect(mx_records.detect { |mx|
266
- mx.host == "example.com." && mx.priority == 50 && mx.domainname == 'mail3.example.com.' && mx.ttl == 86400
267
- }).to_not be_nil
268
-
269
- expect(mx_records.detect { |mx|
270
- mx.host == "test.example.com." && mx.priority == 10 && mx.domainname == 'mail.example.com.' && mx.ttl == 3600
271
- }).to_not be_nil
272
- end
273
-
274
- it "should build the correct AAAA records" do
275
- zone = DNS::Zonefile.load(@zonefile)
276
- aaaa_records = zone.records_of DNS::Zonefile::AAAA
277
- expect(aaaa_records.length).to eq(4)
278
-
279
- expect(aaaa_records.detect { |a|
280
- a.host == "example.com." && a.address == "2001:db8:a::1"
281
- }).to_not be_nil
282
-
283
- expect(aaaa_records.detect { |a|
284
- a.host == "ns.example.com." && a.address == "2001:db8:b::1"
285
- }).to_not be_nil
286
-
287
- expect(aaaa_records.detect { |a|
288
- a.host == "mail.example.com." && a.address == "2001:db8:c::10.0.0.4" && a.ttl == 86400
289
- }).to_not be_nil
290
-
291
- expect(aaaa_records.detect { |a|
292
- a.host == "with-age-aaaa.example.com." && a.address == "10.0.0.8" && a.ttl == 60
293
- }).to_not be_nil
294
-
295
- end
296
-
297
- it "should build the correct NAPTR records" do
298
- zone = DNS::Zonefile.load(@zonefile)
299
- naptr_records = zone.records_of DNS::Zonefile::NAPTR
300
- expect(naptr_records.length).to eq(2)
301
-
302
- expect(naptr_records.detect { |r|
303
- r.host == "sip.example.com." && r.data == '100 10 "U" "E2U+sip" "!^.*$!sip:cs@example.com!i" .'
304
- }).to_not be_nil
305
-
306
- expect(naptr_records.detect { |r|
307
- r.host == "sip2.example.com." && r.data == %q{100 10 "" "" "/urn:cid:.+@([^\\.]+\\.)(.*)$/\\2/i" .} && r.ttl == 86400
308
- }).to_not be_nil
309
- end
310
-
311
- it "should build the correct SRV records" do
312
- zone = DNS::Zonefile.load(@zonefile)
313
- srv_records = zone.records_of DNS::Zonefile::SRV
314
- expect(srv_records.length).to eq(7)
315
-
316
- expect(srv_records.detect { |r|
317
- r.host == "_xmpp-server._tcp.example.com." && r.priority == 5 && r.weight == 0 && r.port == 5269 && r.target == 'xmpp-server.l.google.com.' && r.ttl == 86400
318
- }).to_not be_nil
319
-
320
- expect(srv_records.detect { |r|
321
- r.host == "_ldap._tcp.pupy._sites.dc._msdcs.example.com." && r.priority == 0 && r.weight == 100 && r.port == 389 && r.target == 'host01.ad.example.com.' && r.ttl == 600
322
- }).to_not be_nil
323
-
324
- eam_records = srv_records.select { |s| s.host =~ /eam\./ }
325
- expect(eam_records.length).to eq(5)
326
- eam_records.each { |srv|
327
- expect(srv.target).to eq("www.example.com.")
328
- expect(srv.priority).to eq(5)
329
- expect(srv.port).to eq(5269)
330
- expect(srv.weight).to eq(0)
331
- }
332
-
333
- r = eam_records.group_by { |c| c.ttl }
334
- expect(r[900].length).to eq(3)
335
- expect(r[86400].length).to eq(2)
336
- end
337
-
338
- it "should build the correct TXT records" do
339
- zone = DNS::Zonefile.load(@zonefile)
340
- txt_records = zone.records_of DNS::Zonefile::TXT
341
- expect(txt_records.size).to eq(6)
342
-
343
- expect(txt_records.detect { |r|
344
- r.host == "_domainkey.example.com." && r.data == '"v=DKIM1\;g=*\;k=rsa\; p=4tkw1bbkfa0ahfjgnbewr2ttkvahvfmfizowl9s4g0h28io76ndow25snl9iumpcv0jwxr2k"'
345
- }).to_not be_nil
346
-
347
- expect(txt_records.detect { |r|
348
- r.host == "with_ms_txt.example.com." && r.data == '"Some text"'
349
- }).to_not be_nil
350
-
351
- expect(txt_records.detect { |r|
352
- r.host == "example.com." && r.data == '"some other \"message\" goes here"' && r.ttl == 86400
353
- }).to_not be_nil
354
-
355
- expect(txt_records.detect { |r|
356
- r.host == "long.example.com." && r.data == '"a multi-segment TXT record" "usually used for really long TXT records" "since each segment can only span 255 chars"'
357
- }).to_not be_nil
358
-
359
- expect(txt_records.detect { |r|
360
- r.host == "unquoted.example.com." && r.data == 'some text data'
361
- }).to_not be_nil
362
-
363
- expect(txt_records.detect { |r|
364
- r.host == "multiline.example.com." && r.data == "\"A TXT record\nsplit across multiple lines\nwith LF and CRLF line endings\""
365
- }).to_not be_nil
366
- end
367
-
368
- it "should build the correct SPF records" do
369
- zone = DNS::Zonefile.load(@zonefile)
370
- spf_records = zone.records_of DNS::Zonefile::SPF
371
- expect(spf_records.length).to eq(1)
372
-
373
- expect(spf_records.detect { |r|
374
- r.host == "example.com." && r.data == '"v=spf1 a a:other.domain.com ~all"' && r.ttl == 86400
375
- }).to_not be_nil
376
- end
377
-
378
- it "should build the correct PTR records" do
379
- zone = DNS::Zonefile.load(@zonefile)
380
- ptr_records = zone.records_of DNS::Zonefile::PTR
381
- expect(ptr_records.length).to eq(1)
382
-
383
- expect(ptr_records.detect { |r|
384
- r.host == "45.example.com." && r.target == 'example.com.' && r.ttl == 86400
385
- }).to_not be_nil
386
- end
387
- end
388
-
389
- describe "parsing an SOA without parens" do
390
- before(:each) do
391
- @zonefile =<<-ZONE
392
- example.com. 86400 IN SOA ns0.example.com. hostmaster.example.com. 2006010558 43200 3600 1209600 180
393
- example.com. 3600 IN A 1.2.3.4
394
- example.com. 86400 IN SOA ns0.example.com. hostmaster.example.com. 2006010558 43200 3600 1209600 180
395
-
396
- ZONE
397
- end
398
-
399
- it "should parse the SOA record correctly" do
400
- zone = DNS::Zonefile.load(@zonefile)
401
- soa = zone.soa
402
- expect(soa.klass).to eql('IN')
403
- expect(soa.ttl).to eql(86400)
404
- expect(soa.nameserver).to eql('ns0.example.com.')
405
- expect(soa.responsible_party).to eql('hostmaster.example.com.')
406
- expect(soa.serial).to eql(2006010558)
407
- expect(soa.refresh_time).to eql(43200)
408
- expect(soa.retry_time).to eql(3600)
409
- expect(soa.expiry_time).to eql(1209600)
410
- expect(soa.nxttl).to eql(180)
411
- end
412
- end
413
-
414
- describe "parsing an SOA with just . for responsible party" do
415
- before(:each) do
416
- @zonefile =<<-ZONE
417
- @ IN SOA ns.domain.example.com. . (
418
- 2007120710 ; serial number of this zone file
419
- 1d ; slave refresh (1 day)
420
- 1d ; slave retry time in case of a problem (1 day)
421
- 4W ; slave expiration time (4 weeks)
422
- 3600 ; minimum caching time in case of failed lookups (1 hour)
423
- )
424
- ZONE
425
- end
426
-
427
- it "should parse the SOA record correctly" do
428
- zone = DNS::Zonefile.load(@zonefile)
429
- soa = zone.soa
430
- expect(soa.klass).to eql('IN')
431
- expect(soa.nameserver).to eql('ns.domain.example.com.')
432
- expect(soa.responsible_party).to eql('.')
433
- end
434
- end
435
- end