dns-zonefile 1.1.6 → 1.1.10
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 +5 -5
- data/.github/dependabot.yml +7 -0
- data/.github/workflows/ci.yml +31 -0
- data/CONTRIBUTING.md +4 -0
- data/Gemfile +1 -1
- data/README.md +21 -17
- data/Rakefile +1 -1
- data/dns-zonefile.gemspec +24 -25
- data/examples/basic.rb +2 -2
- data/examples/basic_origin.rb +3 -3
- data/lib/dns/zonefile/version.rb +1 -1
- data/lib/dns/zonefile.rb +179 -166
- data/lib/dns/zonefile.treetop +69 -13
- metadata +12 -13
- data/.travis.yml +0 -4
- data/circle.yml +0 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e88aecfb00a572044b1e71d5c3bfc9f4fd4fa88d1ee7a2ae85d2127230d483d8
|
4
|
+
data.tar.gz: f121b1c044894597fd2c3b9d1e12892efa444179834ec307001060bf650bd302
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 871370b42902039616ed6a2fd7d6fc3556f99abe54cb53fa17b3989ac47735c8e4be82a41ff9b2ba551da4352886607d686137018859a87be575407d4ebd1386
|
7
|
+
data.tar.gz: 8933e2220b5aa111d6b54e3870c1cbb67c02b213e78faaa328d05339aa367be3837c84e7054c70b7bd08f44c3b0b21a3efeb30edd22afda56968add0697cdb94
|
@@ -0,0 +1,31 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on:
|
4
|
+
pull_request:
|
5
|
+
types:
|
6
|
+
- opened
|
7
|
+
- reopened
|
8
|
+
- synchronize
|
9
|
+
- ready_for_review
|
10
|
+
push:
|
11
|
+
branches: [ main ]
|
12
|
+
|
13
|
+
concurrency:
|
14
|
+
group: '${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}'
|
15
|
+
cancel-in-progress: true
|
16
|
+
|
17
|
+
jobs:
|
18
|
+
test:
|
19
|
+
strategy:
|
20
|
+
fail-fast: false
|
21
|
+
matrix:
|
22
|
+
os: [ubuntu-20.04, ubuntu-latest]
|
23
|
+
ruby: ['2.7', '3.0', '3.1', head, jruby, truffleruby]
|
24
|
+
runs-on: ${{ matrix.os }}
|
25
|
+
steps:
|
26
|
+
- uses: actions/checkout@v3
|
27
|
+
- uses: ruby/setup-ruby@v1
|
28
|
+
with:
|
29
|
+
ruby-version: ${{ matrix.ruby }}
|
30
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
31
|
+
- run: bundle exec rake
|
data/CONTRIBUTING.md
CHANGED
@@ -30,3 +30,7 @@ $ rake
|
|
30
30
|
## Tests
|
31
31
|
|
32
32
|
Submit unit tests for your changes. You can test your changes on your machine by [running the test suite](#testing).
|
33
|
+
|
34
|
+
## Publishing
|
35
|
+
|
36
|
+
Once a PR is merged into master, bump the version in `lib/dns/zonefile/version.rb` and commit that change. Next, add a new tag with that version number and push the tag to GitHub. Finally, if you are a maintainer with access rights for rubygems.org, run `gem build dnsimple-zonefile.gemspec` followed by `gem push dnsimple-zonefile-x.x.x.gem` where x.x.x is the version number you just set.
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -24,28 +24,32 @@ Okay, you're ready to move onto the examples now.
|
|
24
24
|
Using raw data from the parser. Note that "@" isn't translated in this mode.
|
25
25
|
Nor are inherited TTLs interpreted.
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
|
27
|
+
```ruby
|
28
|
+
zonefile = "/path/to/file.zone"
|
29
|
+
zone_string = File.read(zonefile)
|
30
|
+
zone = DNS::Zonefile.parse(zone_string)
|
30
31
|
|
31
|
-
|
32
|
-
|
33
|
-
|
32
|
+
puts zone.soa.origin.to_s
|
33
|
+
puts zone.soa.ns.to_s
|
34
|
+
puts zone.rr[0].to_s
|
35
|
+
```
|
34
36
|
|
35
37
|
Using more structure data. @, TTLs, and empty hostname inheritance are all
|
36
38
|
handled in this mode.
|
37
39
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
40
|
+
```ruby
|
41
|
+
zonefile = "/path/to/file.zone"
|
42
|
+
zone_string = File.read(zonefile)
|
43
|
+
zone = DNS::Zonefile.load(zone_string)
|
44
|
+
# or, if no $origin is in the zone file
|
45
|
+
zone = DNS::Zonefile.load(zone_string, 'example.com.')
|
43
46
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
47
|
+
puts zone.soa.origin
|
48
|
+
puts zone.soa.nameserver
|
49
|
+
puts zone.records[1]
|
50
|
+
# get all MX records
|
51
|
+
puts zone.records_of(DNS::Zonefile::MX)
|
52
|
+
```
|
49
53
|
|
50
54
|
Open the examples in the `./examples` directory to see more examples.
|
51
55
|
|
@@ -65,4 +69,4 @@ Craig R Webster <http://barkingiguana.com/>
|
|
65
69
|
|
66
70
|
See the TODO. Read CONTRIBUTING.md for more details on how to contribute to this project.
|
67
71
|
|
68
|
-
[](http://travis-ci.org/craigw/dns-zonefile)
|
data/Rakefile
CHANGED
data/dns-zonefile.gemspec
CHANGED
@@ -1,42 +1,41 @@
|
|
1
|
-
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
1
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
3
|
+
require "dns/zonefile/version"
|
5
4
|
|
6
5
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name
|
8
|
-
spec.version
|
9
|
-
spec.authors
|
10
|
-
spec.email
|
6
|
+
spec.name = "dns-zonefile"
|
7
|
+
spec.version = DNS::Zonefile::VERSION
|
8
|
+
spec.authors = ["Craig R Webster", "Anthony Eden"]
|
9
|
+
spec.email = ["craig@barkingiguana.com", "anthonyeden@gmail.com"]
|
11
10
|
|
12
|
-
spec.summary
|
13
|
-
spec.description =
|
14
|
-
The format of a DNS Zonefile is defined in RFC 1035 section 5 and RFC
|
15
|
-
1034 section 3.6.1. To anyone who's using BIND they'll look very
|
16
|
-
familiar.
|
17
|
-
|
18
|
-
This is an attempt to use Ruby parse them into an object graph which can
|
19
|
-
be investigated programatically, manipulated, validated or printed into
|
20
|
-
some canonical form.
|
11
|
+
spec.summary = "Work with zonefiles (RFC 1035 section 5 and RFC 1034 section 3.6.1)"
|
12
|
+
spec.description = <<~EOD
|
13
|
+
The format of a DNS Zonefile is defined in RFC 1035 section 5 and RFC
|
14
|
+
1034 section 3.6.1. To anyone who's using BIND they'll look very
|
15
|
+
familiar.
|
16
|
+
|
17
|
+
This is an attempt to use Ruby parse them into an object graph which can
|
18
|
+
be investigated programatically, manipulated, validated or printed into
|
19
|
+
some canonical form.
|
21
20
|
EOD
|
22
|
-
spec.homepage
|
21
|
+
spec.homepage = "https://github.com/craigw/dns-zonefile"
|
23
22
|
|
24
23
|
# Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
|
25
24
|
# delete this section to allow pushing this gem to any host.
|
26
25
|
if spec.respond_to?(:metadata)
|
27
|
-
spec.metadata[
|
26
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
28
27
|
else
|
29
28
|
raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
|
30
29
|
end
|
31
30
|
|
32
|
-
spec.files
|
33
|
-
spec.bindir
|
34
|
-
spec.executables
|
31
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
32
|
+
spec.bindir = "exe"
|
33
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
35
34
|
spec.require_paths = ["lib"]
|
36
35
|
|
37
|
-
spec.add_dependency "treetop",
|
38
|
-
spec.add_dependency "polyglot",
|
39
|
-
spec.add_development_dependency "bundler", "~> 1
|
40
|
-
spec.add_development_dependency "rake", "~>
|
36
|
+
spec.add_dependency "treetop", "~> 1.6"
|
37
|
+
spec.add_dependency "polyglot", "~> 0.3"
|
38
|
+
spec.add_development_dependency "bundler", "~> 2.1"
|
39
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
41
40
|
spec.add_development_dependency "rspec", "~> 3.0"
|
42
41
|
end
|
data/examples/basic.rb
CHANGED
data/examples/basic_origin.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# First make sure you have installed the `dns-zonefile` gem.
|
2
|
-
#
|
2
|
+
#
|
3
3
|
# Run this script with `ruby basic.rb`
|
4
4
|
|
5
|
-
require
|
5
|
+
require "dns/zonefile"
|
6
6
|
|
7
7
|
zonefile = "example.com.zonefile"
|
8
|
-
zone = DNS::Zonefile.load(File.read(zonefile),
|
8
|
+
zone = DNS::Zonefile.load(File.read(zonefile), "example.com.")
|
9
9
|
|
10
10
|
puts zone.soa.origin
|
11
11
|
puts zone.soa.nameserver
|
data/lib/dns/zonefile/version.rb
CHANGED
data/lib/dns/zonefile.rb
CHANGED
@@ -1,86 +1,84 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
Treetop.load File.expand_path(
|
1
|
+
require "dns/zonefile/version"
|
2
|
+
require "treetop"
|
3
|
+
Treetop.load File.expand_path("../zonefile", __FILE__)
|
4
4
|
|
5
5
|
module DNS
|
6
6
|
module Zonefile
|
7
7
|
class << self
|
8
8
|
def parse(zone_string)
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
raise ParsingError, parser.failure_reason
|
14
|
-
end
|
9
|
+
parser = ZonefileParser.new
|
10
|
+
result = parser.parse(zone_string)
|
11
|
+
return result if result
|
12
|
+
raise ParsingError, parser.failure_reason
|
15
13
|
end
|
16
14
|
|
17
|
-
def load(zone_string, alternate_origin=nil)
|
18
|
-
|
15
|
+
def load(zone_string, alternate_origin = nil)
|
16
|
+
Zone.new(parse(zone_string).entries, alternate_origin)
|
19
17
|
end
|
20
18
|
end
|
21
19
|
|
22
|
-
class ParsingError < RuntimeError
|
23
|
-
class UnknownRecordType < RuntimeError
|
20
|
+
class ParsingError < RuntimeError; end
|
21
|
+
class UnknownRecordType < RuntimeError; end
|
24
22
|
class Zone
|
25
|
-
attr_reader :origin
|
23
|
+
attr_reader :origin
|
26
24
|
attr_reader :records
|
27
25
|
|
28
|
-
def initialize(entries, alternate_origin=nil)
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
when
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
26
|
+
def initialize(entries, alternate_origin = nil)
|
27
|
+
alternate_origin ||= "."
|
28
|
+
@records = []
|
29
|
+
@vars = {"origin" => alternate_origin, :last_host => "."}
|
30
|
+
entries.each do |e|
|
31
|
+
case e.parse_type
|
32
|
+
when :variable
|
33
|
+
key = e.name.text_value.downcase
|
34
|
+
@vars[key] = case key
|
35
|
+
when "ttl"
|
36
|
+
e.value.text_value.to_i
|
37
|
+
else
|
38
|
+
e.value.text_value
|
39
|
+
end
|
40
|
+
when :soa
|
41
|
+
@records << SOA.new(@vars, e)
|
42
|
+
when :record
|
43
|
+
case e.record_type
|
44
|
+
when "A" then @records << A.new(@vars, e)
|
45
|
+
when "AAAA" then @records << AAAA.new(@vars, e)
|
46
|
+
when "CAA" then @records << CAA.new(@vars, e)
|
47
|
+
when "CNAME" then @records << CNAME.new(@vars, e)
|
48
|
+
when "MX" then @records << MX.new(@vars, e)
|
49
|
+
when "NAPTR" then @records << NAPTR.new(@vars, e)
|
50
|
+
when "NS" then @records << NS.new(@vars, e)
|
51
|
+
when "PTR" then @records << PTR.new(@vars, e)
|
52
|
+
when "SRV" then @records << SRV.new(@vars, e)
|
53
|
+
when "SPF" then @records << SPF.new(@vars, e)
|
54
|
+
when "SSHFP" then @records << SSHFP.new(@vars, e)
|
55
|
+
when "TXT" then @records << TXT.new(@vars, e)
|
56
|
+
when "SOA" then
|
57
|
+
# No-op
|
58
|
+
else
|
59
|
+
raise UnknownRecordType, "Unknown record type: #{e.record_type}"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
62
63
|
end
|
63
64
|
|
64
65
|
def soa
|
65
|
-
|
66
|
+
records_of(SOA).first
|
66
67
|
end
|
67
68
|
|
68
69
|
def records_of(kl)
|
69
|
-
|
70
|
+
@records.select { |r| r.instance_of? kl }
|
70
71
|
end
|
71
72
|
end
|
72
73
|
|
73
74
|
class Record
|
74
75
|
# assign, with handling for global TTL
|
75
76
|
def self.writer_for_ttl(*attribs)
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
MTH
|
82
|
-
class_eval c, __FILE__, __LINE__
|
83
|
-
end
|
77
|
+
attribs.each do |attrib|
|
78
|
+
define_method "#{attrib}=" do |val|
|
79
|
+
instance_variable_set("@#{attrib}", val || @vars["ttl"])
|
80
|
+
end
|
81
|
+
end
|
84
82
|
end
|
85
83
|
|
86
84
|
attr_reader :ttl
|
@@ -88,47 +86,45 @@ module DNS
|
|
88
86
|
writer_for_ttl :ttl
|
89
87
|
|
90
88
|
def klass
|
91
|
-
|
92
|
-
|
89
|
+
@klass = nil if @klass == ""
|
90
|
+
@klass ||= "IN"
|
93
91
|
end
|
94
92
|
|
95
93
|
private
|
94
|
+
|
96
95
|
def qualify_host(host)
|
97
|
-
origin = vars[
|
98
|
-
host = vars[:last_host] if
|
96
|
+
origin = vars["origin"]
|
97
|
+
host = vars[:last_host] if /^\s*$/.match?(host)
|
99
98
|
host = host.gsub(/@/, origin)
|
100
|
-
if host
|
99
|
+
if /\.$/.match?(host)
|
101
100
|
host
|
101
|
+
elsif /^\./.match?(origin)
|
102
|
+
host + origin
|
102
103
|
else
|
103
|
-
|
104
|
-
host + origin
|
105
|
-
else
|
106
|
-
host + "." + origin
|
107
|
-
end
|
104
|
+
host + "." + origin
|
108
105
|
end
|
109
106
|
end
|
110
107
|
attr_accessor :vars
|
111
|
-
|
112
108
|
end
|
113
109
|
|
114
110
|
class SOA < Record
|
115
111
|
attr_accessor :origin, :nameserver, :responsible_party, :serial, :refresh_time, :retry_time, :expiry_time, :nxttl
|
116
112
|
|
117
|
-
def initialize(vars, zonefile_soa=nil)
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
self.nameserver
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
113
|
+
def initialize(vars, zonefile_soa = nil)
|
114
|
+
@vars = vars
|
115
|
+
if zonefile_soa
|
116
|
+
self.origin = qualify_host(zonefile_soa.origin.to_s)
|
117
|
+
@vars[:last_host] = origin
|
118
|
+
self.ttl = zonefile_soa.ttl.to_i
|
119
|
+
self.klass = zonefile_soa.klass.to_s
|
120
|
+
self.nameserver = qualify_host(zonefile_soa.ns.to_s)
|
121
|
+
self.responsible_party = qualify_host(zonefile_soa.rp.to_s)
|
122
|
+
self.serial = zonefile_soa.serial.to_i
|
123
|
+
self.refresh_time = zonefile_soa.refresh.to_i
|
124
|
+
self.retry_time = zonefile_soa.reretry.to_i
|
125
|
+
self.expiry_time = zonefile_soa.expiry.to_i
|
126
|
+
self.nxttl = zonefile_soa.nxttl.to_i
|
127
|
+
end
|
132
128
|
end
|
133
129
|
end
|
134
130
|
|
@@ -136,69 +132,86 @@ module DNS
|
|
136
132
|
attr_accessor :host, :address
|
137
133
|
|
138
134
|
def initialize(vars, zonefile_record)
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
135
|
+
@vars = vars
|
136
|
+
if zonefile_record
|
137
|
+
self.host = qualify_host(zonefile_record.host.to_s)
|
138
|
+
@vars[:last_host] = host
|
139
|
+
self.ttl = zonefile_record.ttl.to_i
|
140
|
+
self.klass = zonefile_record.klass.to_s
|
141
|
+
self.address = zonefile_record.ip_address.to_s
|
142
|
+
end
|
147
143
|
end
|
148
144
|
end
|
149
145
|
|
150
146
|
class AAAA < A
|
151
147
|
end
|
152
148
|
|
149
|
+
class CAA < Record
|
150
|
+
attr_accessor :host, :flags, :tag, :value
|
151
|
+
|
152
|
+
def initialize(vars, zonefile_record)
|
153
|
+
@vars = vars
|
154
|
+
if zonefile_record
|
155
|
+
self.host = qualify_host(zonefile_record.host.to_s)
|
156
|
+
@vars[:last_host] = host
|
157
|
+
self.ttl = zonefile_record.ttl.to_i
|
158
|
+
self.klass = zonefile_record.klass.to_s
|
159
|
+
self.flags = zonefile_record.flags.to_i
|
160
|
+
self.tag = zonefile_record.tag.to_s
|
161
|
+
self.value = zonefile_record.value.to_s
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
153
166
|
class CNAME < Record
|
154
167
|
attr_accessor :host, :domainname
|
155
168
|
|
156
169
|
def initialize(vars, zonefile_record)
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
170
|
+
@vars = vars
|
171
|
+
if zonefile_record
|
172
|
+
self.host = qualify_host(zonefile_record.host.to_s)
|
173
|
+
@vars[:last_host] = host
|
174
|
+
self.ttl = zonefile_record.ttl.to_i
|
175
|
+
self.klass = zonefile_record.klass.to_s
|
176
|
+
self.domainname = qualify_host(zonefile_record.target.to_s)
|
177
|
+
end
|
165
178
|
end
|
166
179
|
|
167
|
-
alias
|
168
|
-
alias
|
180
|
+
alias target domainname
|
181
|
+
alias alias host
|
169
182
|
end
|
170
183
|
|
171
184
|
class MX < Record
|
172
185
|
attr_accessor :host, :priority, :domainname
|
173
186
|
|
174
187
|
def initialize(vars, zonefile_record)
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
188
|
+
@vars = vars
|
189
|
+
if zonefile_record
|
190
|
+
self.host = qualify_host(zonefile_record.host.to_s)
|
191
|
+
@vars[:last_host] = host
|
192
|
+
self.ttl = zonefile_record.ttl.to_i
|
193
|
+
self.klass = zonefile_record.klass.to_s
|
194
|
+
self.priority = zonefile_record.priority.to_i
|
195
|
+
self.domainname = qualify_host(zonefile_record.exchanger.to_s)
|
196
|
+
end
|
184
197
|
end
|
185
198
|
|
186
|
-
alias
|
187
|
-
alias
|
199
|
+
alias exchange domainname
|
200
|
+
alias exchanger domainname
|
188
201
|
end
|
189
202
|
|
190
203
|
class NAPTR < Record
|
191
204
|
attr_accessor :host, :data
|
192
205
|
|
193
206
|
def initialize(vars, zonefile_record)
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
207
|
+
@vars = vars
|
208
|
+
if zonefile_record
|
209
|
+
self.host = qualify_host(zonefile_record.host.to_s)
|
210
|
+
@vars[:last_host] = host
|
211
|
+
self.ttl = zonefile_record.ttl.to_i
|
212
|
+
self.klass = zonefile_record.klass.to_s
|
213
|
+
self.data = zonefile_record.data.to_s
|
214
|
+
end
|
202
215
|
end
|
203
216
|
end
|
204
217
|
|
@@ -206,54 +219,54 @@ module DNS
|
|
206
219
|
attr_accessor :host, :domainname
|
207
220
|
|
208
221
|
def initialize(vars, zonefile_record)
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
222
|
+
@vars = vars
|
223
|
+
if zonefile_record
|
224
|
+
self.host = qualify_host(zonefile_record.host.to_s)
|
225
|
+
@vars[:last_host] = host
|
226
|
+
self.ttl = zonefile_record.ttl.to_i
|
227
|
+
self.klass = zonefile_record.klass.to_s
|
228
|
+
self.domainname = qualify_host(zonefile_record.nameserver.to_s)
|
229
|
+
end
|
217
230
|
end
|
218
231
|
|
219
|
-
alias
|
232
|
+
alias nameserver domainname
|
220
233
|
end
|
221
234
|
|
222
235
|
class PTR < Record
|
223
236
|
attr_accessor :host, :domainname
|
224
237
|
|
225
238
|
def initialize(vars, zonefile_record)
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
239
|
+
@vars = vars
|
240
|
+
if zonefile_record
|
241
|
+
self.host = qualify_host(zonefile_record.host.to_s)
|
242
|
+
@vars[:last_host] = host
|
243
|
+
self.ttl = zonefile_record.ttl.to_i
|
244
|
+
self.klass = zonefile_record.klass.to_s
|
245
|
+
self.domainname = qualify_host(zonefile_record.target.to_s)
|
246
|
+
end
|
234
247
|
end
|
235
248
|
|
236
|
-
alias
|
249
|
+
alias target domainname
|
237
250
|
end
|
238
251
|
|
239
252
|
class SRV < Record
|
240
253
|
attr_accessor :host, :priority, :weight, :port, :domainname
|
241
254
|
|
242
255
|
def initialize(vars, zonefile_record)
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
256
|
+
@vars = vars
|
257
|
+
if zonefile_record
|
258
|
+
self.host = qualify_host(zonefile_record.host.to_s)
|
259
|
+
@vars[:last_host] = host
|
260
|
+
self.ttl = zonefile_record.ttl.to_i
|
261
|
+
self.klass = zonefile_record.klass.to_s
|
262
|
+
self.priority = zonefile_record.priority.to_i
|
263
|
+
self.weight = zonefile_record.weight.to_i
|
264
|
+
self.port = zonefile_record.port.to_i
|
265
|
+
self.domainname = qualify_host(zonefile_record.target.to_s)
|
266
|
+
end
|
254
267
|
end
|
255
268
|
|
256
|
-
alias
|
269
|
+
alias target domainname
|
257
270
|
end
|
258
271
|
|
259
272
|
class SSHFP < Record
|
@@ -262,13 +275,13 @@ module DNS
|
|
262
275
|
def initialize(vars, zonefile_record)
|
263
276
|
@vars = vars
|
264
277
|
if zonefile_record
|
265
|
-
self.host
|
266
|
-
@vars[:last_host] =
|
267
|
-
self.ttl
|
268
|
-
self.klass
|
269
|
-
self.alg
|
270
|
-
self.fptype
|
271
|
-
self.fp
|
278
|
+
self.host = qualify_host(zonefile_record.host.to_s)
|
279
|
+
@vars[:last_host] = host
|
280
|
+
self.ttl = zonefile_record.ttl.to_i
|
281
|
+
self.klass = zonefile_record.klass.to_s
|
282
|
+
self.alg = zonefile_record.alg.to_i
|
283
|
+
self.fptype = zonefile_record.fptype.to_i
|
284
|
+
self.fp = zonefile_record.fp.to_s
|
272
285
|
end
|
273
286
|
end
|
274
287
|
end
|
@@ -277,14 +290,14 @@ module DNS
|
|
277
290
|
attr_accessor :host, :data
|
278
291
|
|
279
292
|
def initialize(vars, zonefile_record)
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
293
|
+
@vars = vars
|
294
|
+
if zonefile_record
|
295
|
+
self.host = qualify_host(zonefile_record.host.to_s)
|
296
|
+
@vars[:last_host] = host
|
297
|
+
self.ttl = zonefile_record.ttl.to_i
|
298
|
+
self.klass = zonefile_record.klass.to_s
|
299
|
+
self.data = zonefile_record.data.to_s
|
300
|
+
end
|
288
301
|
end
|
289
302
|
end
|
290
303
|
|
data/lib/dns/zonefile.treetop
CHANGED
@@ -43,7 +43,10 @@ grammar Zonefile
|
|
43
43
|
end
|
44
44
|
|
45
45
|
rule soa
|
46
|
-
|
46
|
+
(
|
47
|
+
origin space ttl klass "SOA" space ns space rp space "("? multiline_comment* space_or_break* serial multiline_comment* space_or_break refresh multiline_comment* space_or_break reretry multiline_comment* space_or_break expiry multiline_comment* space_or_break nxttl multiline_comment* space_or_break* ")"? /
|
48
|
+
origin space klass ttl "SOA" space ns space rp space "("? multiline_comment* space_or_break* serial multiline_comment* space_or_break refresh multiline_comment* space_or_break reretry multiline_comment* space_or_break expiry multiline_comment* space_or_break nxttl multiline_comment* space_or_break* ")"?
|
49
|
+
) {
|
47
50
|
def to_s
|
48
51
|
"#{origin} #{ttl} #{klass} SOA #{ns} #{rp} (#{serial} #{refresh} #{reretry} #{expiry} #{nxttl})"
|
49
52
|
end
|
@@ -53,7 +56,7 @@ grammar Zonefile
|
|
53
56
|
end
|
54
57
|
|
55
58
|
rule resource_record
|
56
|
-
record:(a_record / aaaa_record / cname_record / mx_record / naptr_record / ns_record / ptr_record / srv_record / spf_record / sshfp_record / txt_record / soa_record) space* comment? linebreak {
|
59
|
+
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
60
|
def zone
|
58
61
|
p = parent
|
59
62
|
while p.respond_to?(:parent) && p.parent
|
@@ -89,7 +92,10 @@ grammar Zonefile
|
|
89
92
|
end
|
90
93
|
|
91
94
|
rule a_record
|
92
|
-
|
95
|
+
(
|
96
|
+
host space ms_age ttl klass "A" space ip_address /
|
97
|
+
host space ms_age klass ttl "A" space ip_address
|
98
|
+
) {
|
93
99
|
def to_s
|
94
100
|
"#{host} #{ms_age} #{ttl} #{klass} A #{ip_address}"
|
95
101
|
end
|
@@ -109,7 +115,10 @@ grammar Zonefile
|
|
109
115
|
end
|
110
116
|
|
111
117
|
rule aaaa_record
|
112
|
-
|
118
|
+
(
|
119
|
+
host space ms_age ttl klass "AAAA" space ip_address:ip6_address /
|
120
|
+
host space ms_age klass ttl "AAAA" space ip_address:ip6_address
|
121
|
+
) {
|
113
122
|
def to_s
|
114
123
|
"#{host} #{ttl} #{klass} AAAA #{ip_address}"
|
115
124
|
end
|
@@ -128,6 +137,29 @@ grammar Zonefile
|
|
128
137
|
}
|
129
138
|
end
|
130
139
|
|
140
|
+
rule caa_record
|
141
|
+
(
|
142
|
+
host space ms_age ttl klass "CAA" space flags:integer space tag:unquoted_string space value:caa_value /
|
143
|
+
host space ms_age klass ttl "CAA" space flags:integer space tag:unquoted_string space value:caa_value
|
144
|
+
) {
|
145
|
+
def to_s
|
146
|
+
"#{host} #{ttl} #{klass} CAA #{flags} #{tag} #{value}"
|
147
|
+
end
|
148
|
+
|
149
|
+
def record_type
|
150
|
+
"CAA"
|
151
|
+
end
|
152
|
+
}
|
153
|
+
end
|
154
|
+
|
155
|
+
rule caa_value
|
156
|
+
(quoted_string / unquoted_string) {
|
157
|
+
def to_s
|
158
|
+
text_value
|
159
|
+
end
|
160
|
+
}
|
161
|
+
end
|
162
|
+
|
131
163
|
rule cname_record
|
132
164
|
(
|
133
165
|
host space ms_age ttl klass "CNAME" space target:host /
|
@@ -146,7 +178,10 @@ grammar Zonefile
|
|
146
178
|
end
|
147
179
|
|
148
180
|
rule mx_record
|
149
|
-
|
181
|
+
(
|
182
|
+
host space ttl klass "MX" space priority:integer space exchanger:host /
|
183
|
+
host space klass ttl "MX" space priority:integer space exchanger:host
|
184
|
+
) {
|
150
185
|
def to_s
|
151
186
|
"#{host} #{ttl} #{klass} MX #{priority} #{exchanger}"
|
152
187
|
end
|
@@ -158,7 +193,10 @@ grammar Zonefile
|
|
158
193
|
end
|
159
194
|
|
160
195
|
rule naptr_record
|
161
|
-
|
196
|
+
(
|
197
|
+
host space ms_age ttl klass "NAPTR" space data /
|
198
|
+
host space ms_age klass ttl "NAPTR" space data
|
199
|
+
) {
|
162
200
|
def to_s
|
163
201
|
"#{host} #{ttl} #{klass} NAPTR #{data}"
|
164
202
|
end
|
@@ -170,7 +208,10 @@ grammar Zonefile
|
|
170
208
|
end
|
171
209
|
|
172
210
|
rule ns_record
|
173
|
-
|
211
|
+
(
|
212
|
+
host space ms_age ttl klass "NS" space nameserver:host /
|
213
|
+
host space ms_age klass ttl "NS" space nameserver:host
|
214
|
+
) {
|
174
215
|
def to_s
|
175
216
|
"#{host} #{ttl} #{klass} NS #{nameserver}"
|
176
217
|
end
|
@@ -182,7 +223,10 @@ grammar Zonefile
|
|
182
223
|
end
|
183
224
|
|
184
225
|
rule ptr_record
|
185
|
-
|
226
|
+
(
|
227
|
+
host space ms_age ttl klass "PTR" space target:host /
|
228
|
+
host space ms_age klass ttl "PTR" space target:host
|
229
|
+
) {
|
186
230
|
def to_s
|
187
231
|
"#{host} #{ttl} #{klass} PTR #{target}"
|
188
232
|
end
|
@@ -194,7 +238,10 @@ grammar Zonefile
|
|
194
238
|
end
|
195
239
|
|
196
240
|
rule soa_record
|
197
|
-
|
241
|
+
(
|
242
|
+
origin space ms_age ttl klass "SOA" space ns space rp space data /
|
243
|
+
origin space ms_age klass ttl "SOA" space ns space rp space data
|
244
|
+
) {
|
198
245
|
def to_s
|
199
246
|
"#{origin} #{ttl} #{klass} SOA #{ns} #{rp} (#{space})"
|
200
247
|
end
|
@@ -223,7 +270,10 @@ grammar Zonefile
|
|
223
270
|
end
|
224
271
|
|
225
272
|
rule spf_record
|
226
|
-
|
273
|
+
(
|
274
|
+
host space ms_age ttl klass "SPF" space data:txt_data /
|
275
|
+
host space ms_age klass ttl "SPF" space data:txt_data
|
276
|
+
) {
|
227
277
|
def to_s
|
228
278
|
"#{host} #{ttl} #{klass} SPF #{data}"
|
229
279
|
end
|
@@ -235,7 +285,10 @@ grammar Zonefile
|
|
235
285
|
end
|
236
286
|
|
237
287
|
rule sshfp_record
|
238
|
-
|
288
|
+
(
|
289
|
+
host space ms_age ttl klass "SSHFP" space alg:integer space fptype:integer space fp:fingerprint /
|
290
|
+
host space ms_age klass ttl "SSHFP" space alg:integer space fptype:integer space fp:fingerprint
|
291
|
+
) {
|
239
292
|
def to_s
|
240
293
|
"#{host} #{ttl} #{klass} SSHFP #{alg} #{fptype} #{fp}"
|
241
294
|
end
|
@@ -247,7 +300,10 @@ grammar Zonefile
|
|
247
300
|
end
|
248
301
|
|
249
302
|
rule txt_record
|
250
|
-
|
303
|
+
(
|
304
|
+
host space ms_age ttl klass "TXT" space data:ms_txt_data /
|
305
|
+
host space ms_age klass ttl "TXT" space data:ms_txt_data
|
306
|
+
) {
|
251
307
|
def to_s
|
252
308
|
"#{host} #{ttl} #{klass} TXT #{data}"
|
253
309
|
end
|
@@ -505,7 +561,7 @@ grammar Zonefile
|
|
505
561
|
end
|
506
562
|
|
507
563
|
rule unquoted_string
|
508
|
-
[a-zA-Z0-9=_]+ {
|
564
|
+
'[a-zA-Z0-9=_\.\-\@\:]+'r {
|
509
565
|
def to_s
|
510
566
|
text_value
|
511
567
|
end
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dns-zonefile
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Craig R Webster
|
8
8
|
- Anthony Eden
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2022-11-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: treetop
|
@@ -45,28 +45,28 @@ dependencies:
|
|
45
45
|
requirements:
|
46
46
|
- - "~>"
|
47
47
|
- !ruby/object:Gem::Version
|
48
|
-
version: '1
|
48
|
+
version: '2.1'
|
49
49
|
type: :development
|
50
50
|
prerelease: false
|
51
51
|
version_requirements: !ruby/object:Gem::Requirement
|
52
52
|
requirements:
|
53
53
|
- - "~>"
|
54
54
|
- !ruby/object:Gem::Version
|
55
|
-
version: '1
|
55
|
+
version: '2.1'
|
56
56
|
- !ruby/object:Gem::Dependency
|
57
57
|
name: rake
|
58
58
|
requirement: !ruby/object:Gem::Requirement
|
59
59
|
requirements:
|
60
60
|
- - "~>"
|
61
61
|
- !ruby/object:Gem::Version
|
62
|
-
version: '
|
62
|
+
version: '13.0'
|
63
63
|
type: :development
|
64
64
|
prerelease: false
|
65
65
|
version_requirements: !ruby/object:Gem::Requirement
|
66
66
|
requirements:
|
67
67
|
- - "~>"
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
version: '
|
69
|
+
version: '13.0'
|
70
70
|
- !ruby/object:Gem::Dependency
|
71
71
|
name: rspec
|
72
72
|
requirement: !ruby/object:Gem::Requirement
|
@@ -96,9 +96,10 @@ executables: []
|
|
96
96
|
extensions: []
|
97
97
|
extra_rdoc_files: []
|
98
98
|
files:
|
99
|
+
- ".github/dependabot.yml"
|
100
|
+
- ".github/workflows/ci.yml"
|
99
101
|
- ".gitignore"
|
100
102
|
- ".rspec"
|
101
|
-
- ".travis.yml"
|
102
103
|
- CONTRIBUTING.md
|
103
104
|
- Dockerfile
|
104
105
|
- Gemfile
|
@@ -108,7 +109,6 @@ files:
|
|
108
109
|
- TODO
|
109
110
|
- bin/console
|
110
111
|
- bin/setup
|
111
|
-
- circle.yml
|
112
112
|
- dns-zonefile.gemspec
|
113
113
|
- doc/example.com.zone
|
114
114
|
- doc/example2.com.zone
|
@@ -126,7 +126,7 @@ homepage: https://github.com/craigw/dns-zonefile
|
|
126
126
|
licenses: []
|
127
127
|
metadata:
|
128
128
|
allowed_push_host: https://rubygems.org
|
129
|
-
post_install_message:
|
129
|
+
post_install_message:
|
130
130
|
rdoc_options: []
|
131
131
|
require_paths:
|
132
132
|
- lib
|
@@ -141,9 +141,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
141
141
|
- !ruby/object:Gem::Version
|
142
142
|
version: '0'
|
143
143
|
requirements: []
|
144
|
-
|
145
|
-
|
146
|
-
signing_key:
|
144
|
+
rubygems_version: 3.3.7
|
145
|
+
signing_key:
|
147
146
|
specification_version: 4
|
148
147
|
summary: Work with zonefiles (RFC 1035 section 5 and RFC 1034 section 3.6.1)
|
149
148
|
test_files: []
|
data/.travis.yml
DELETED