ruby-djbdns 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.
- data/COPYING +19 -0
- data/FILES +10 -0
- data/README +27 -0
- data/VERSION +1 -0
- data/lib/djb/tinydns.rb +410 -0
- data/lib/djb.rb +116 -0
- data/sample/axfr.rb +26 -0
- data/sample/resolver.rb +44 -0
- data/test/axfr.rb +41 -0
- data/test/resolver.rb +97 -0
- data/test/runner.rb +19 -0
- metadata +60 -0
data/COPYING
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2006 Christopher Boumenot
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
4
|
+
this software and associated documentation files (the "Software"), to deal in
|
5
|
+
the Software without restriction, including without limitation the rights to
|
6
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
7
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
8
|
+
so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
11
|
+
copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
|
+
SOFTWARE.
|
data/FILES
ADDED
data/README
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
=============
|
2
|
+
ruby-djbdns
|
3
|
+
=============
|
4
|
+
|
5
|
+
This package provides an interface to configure, and manage a djbdns
|
6
|
+
installation. For more information about djbdns see
|
7
|
+
http://cr.yp.to/djbdns.html, and http://tinydns.org.
|
8
|
+
|
9
|
+
ruby-djbdns makes it easy to manage a tinydns installation. It currently
|
10
|
+
assists in the management of resolver, and axfrdns installations. Support for
|
11
|
+
dnscache, rbldns, and walldns are planned. ruby-djbdns provides an object
|
12
|
+
oriented system around the configuration of tinydns. Classes are used to
|
13
|
+
control the configuration of DNS records, and locations. Classes are also
|
14
|
+
provided that support common DNS types using tinydns's generic mechanism.
|
15
|
+
|
16
|
+
Installation Process
|
17
|
+
======================
|
18
|
+
|
19
|
+
Reporting Bugs
|
20
|
+
================
|
21
|
+
|
22
|
+
If you find bugs please contact <boumenot@gmail.com>.
|
23
|
+
|
24
|
+
Usage
|
25
|
+
=======
|
26
|
+
|
27
|
+
Examples of usage may be found in the samples directory.
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
data/lib/djb/tinydns.rb
ADDED
@@ -0,0 +1,410 @@
|
|
1
|
+
# $Id: tinydns.rb 49 2006-12-12 21:01:29Z boumenot $
|
2
|
+
require 'djb'
|
3
|
+
|
4
|
+
module DJB
|
5
|
+
|
6
|
+
module TinyDNS
|
7
|
+
|
8
|
+
##################################################
|
9
|
+
|
10
|
+
class Cache < DJB::Service
|
11
|
+
def initialize(*args)
|
12
|
+
super(*args)
|
13
|
+
end
|
14
|
+
|
15
|
+
def fn
|
16
|
+
raise RuntimeError, 'DJB::TinyDNS::Cache does not have a configuraton file!'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
##################################################
|
21
|
+
|
22
|
+
class RBL < DJB::Service
|
23
|
+
def initialize(*args)
|
24
|
+
super(*args)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
##################################################
|
29
|
+
|
30
|
+
class Resolver < DJB::Service
|
31
|
+
attr_reader :root
|
32
|
+
|
33
|
+
def initialize(*args)
|
34
|
+
super(*args)
|
35
|
+
@lines = Array.new
|
36
|
+
end
|
37
|
+
|
38
|
+
def fn
|
39
|
+
return @root + "/root/data"
|
40
|
+
end
|
41
|
+
|
42
|
+
def add(entry)
|
43
|
+
@lines << entry.to_s
|
44
|
+
end
|
45
|
+
|
46
|
+
def add_reverse(args)
|
47
|
+
fqdn = args['ip'].split('.').reverse[1..3].join(".")
|
48
|
+
fqdn += '.in-addr.arpa'
|
49
|
+
|
50
|
+
args['fqdn'] = fqdn
|
51
|
+
|
52
|
+
add(DJB::TinyDNS::NS::DelegateFrom.new(args))
|
53
|
+
end
|
54
|
+
|
55
|
+
def to_s
|
56
|
+
return @lines.join("\n")
|
57
|
+
end
|
58
|
+
|
59
|
+
def to_f
|
60
|
+
File.write(fn(), self.to_s)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
#------------------------------------------------#
|
65
|
+
|
66
|
+
class Location
|
67
|
+
attr_reader :name, :addr
|
68
|
+
def initialize(name, addr)
|
69
|
+
@name, @addr = name, addr
|
70
|
+
@resources = Array.new
|
71
|
+
@resources << "%#{@name}:#{@addr}"
|
72
|
+
end
|
73
|
+
|
74
|
+
def add(res)
|
75
|
+
@resources << res.to_s + ":#{@name}"
|
76
|
+
end
|
77
|
+
|
78
|
+
def to_s
|
79
|
+
return @resources.join("\n")
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
class Resource
|
84
|
+
attr :ttl
|
85
|
+
attr :timestamp
|
86
|
+
attr_reader :fqdn
|
87
|
+
|
88
|
+
def initialize(args)
|
89
|
+
@args = { 'timestamp' => '', 'ttl' => '' }
|
90
|
+
@args.update(args)
|
91
|
+
@args.default('')
|
92
|
+
|
93
|
+
@fields = Array.new
|
94
|
+
@fqdn = args['fqdn']
|
95
|
+
end
|
96
|
+
|
97
|
+
def encode(s)
|
98
|
+
s.gsub(/[^0-9a-zA-Z]/) { |m| sprintf("\\%.3o", m[0]) }
|
99
|
+
end
|
100
|
+
|
101
|
+
def to_s
|
102
|
+
return self.class::Sigil + @fields.join(":")
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# A + PTR
|
107
|
+
# fqdn, ip, ttl, timestamp
|
108
|
+
class Host < Resource
|
109
|
+
Sigil = '='
|
110
|
+
def initialize(args)
|
111
|
+
super(args)
|
112
|
+
|
113
|
+
@ip = @args['ip']
|
114
|
+
|
115
|
+
@fields << @fqdn
|
116
|
+
@fields << @ip
|
117
|
+
@fields << @ttl
|
118
|
+
@fields << @timestamp
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# fqdn, data, ttl, timestamp
|
123
|
+
class Generic < Resource
|
124
|
+
Sigil = ':'
|
125
|
+
attr_reader :data
|
126
|
+
|
127
|
+
def initialize(args)
|
128
|
+
super(args)
|
129
|
+
@data = @args['data']
|
130
|
+
|
131
|
+
@fields << @fqdn
|
132
|
+
@fields << (args.has_key?('TypeValue') ? args['TypeValue'] : self.class::TypeValue)
|
133
|
+
@fields << encode(@data)
|
134
|
+
@fields << @ttl
|
135
|
+
@fields << @timestamp
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
##################################################
|
140
|
+
|
141
|
+
# fqdn, ip, ttl, timestamp
|
142
|
+
class A < Resource
|
143
|
+
Sigil = '+'
|
144
|
+
TypeValue = 1
|
145
|
+
|
146
|
+
attr_reader :ip
|
147
|
+
|
148
|
+
def initialize(args)
|
149
|
+
super(args)
|
150
|
+
@ip = @args['ip']
|
151
|
+
|
152
|
+
@fields << @fqdn
|
153
|
+
@fields << @ip
|
154
|
+
@fields << @ttl
|
155
|
+
@fields << @timestamp
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
# fqdn, ip, ttl, timestamp
|
160
|
+
module NS
|
161
|
+
class Base < DJB::TinyDNS::Resource
|
162
|
+
TypeValue = 2
|
163
|
+
attr_reader :ip, :host
|
164
|
+
|
165
|
+
def initialize(args)
|
166
|
+
super(args)
|
167
|
+
@ip = @args['ip']
|
168
|
+
@host = @args['host']
|
169
|
+
|
170
|
+
@fields << @fqdn
|
171
|
+
@fields << @ip
|
172
|
+
@fields << @host
|
173
|
+
@fields << @ttl
|
174
|
+
@fields << @timestamp
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
class DelegateFrom < Base
|
179
|
+
Sigil = '.'
|
180
|
+
end
|
181
|
+
|
182
|
+
class DelegateTo < Base
|
183
|
+
Sigil = '&'
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
|
188
|
+
# fqdn, p, ttl, timestamp
|
189
|
+
class CNAME < Resource
|
190
|
+
Sigil = 'C'
|
191
|
+
TypeValue = 5
|
192
|
+
|
193
|
+
attr_reader :alias
|
194
|
+
|
195
|
+
def initialize(args)
|
196
|
+
super(args)
|
197
|
+
@alias = @args['alias']
|
198
|
+
|
199
|
+
@fields << @alias
|
200
|
+
@fields << @fqdn
|
201
|
+
@fields << @ttl
|
202
|
+
@fields << @timestamp
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
# fqdn, mname, rname, ser, ref, ret, exp, min, ttl, timestamp
|
207
|
+
class SOA < Resource
|
208
|
+
Sigil = 'Z'
|
209
|
+
TypeValue = 6
|
210
|
+
|
211
|
+
attr_reader :mname, :rname
|
212
|
+
|
213
|
+
def initialize(args)
|
214
|
+
super(args)
|
215
|
+
|
216
|
+
@mname = @args['mname']
|
217
|
+
@rname = @args['rname']
|
218
|
+
|
219
|
+
@fields << @fqdn
|
220
|
+
@fields << @mname
|
221
|
+
@fields << @rname
|
222
|
+
@fields << @args['serial']
|
223
|
+
@fields << @args['refresh']
|
224
|
+
@fields << @args['retry']
|
225
|
+
@fields << @args['expire']
|
226
|
+
@fields << @args['minimum']
|
227
|
+
@fields << @ttl
|
228
|
+
@fields << @timestamp
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
class NULL < Generic
|
233
|
+
TypeValue = 10
|
234
|
+
end
|
235
|
+
|
236
|
+
class WKS < Generic
|
237
|
+
TypeValue = 11
|
238
|
+
end
|
239
|
+
|
240
|
+
# fqdn, p, ttl, timestamp
|
241
|
+
class PTR < Resource
|
242
|
+
Sigil = '^'
|
243
|
+
TypeValue = 12
|
244
|
+
|
245
|
+
attr_reader :host
|
246
|
+
|
247
|
+
def initialize(args)
|
248
|
+
super(args)
|
249
|
+
|
250
|
+
@host = @args['host']
|
251
|
+
|
252
|
+
@fields << @fqdn
|
253
|
+
@fields << @host
|
254
|
+
@fields << @ttl
|
255
|
+
@fields << @timestamp
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
class HINFO < Generic
|
260
|
+
TypeValue = 13
|
261
|
+
end
|
262
|
+
|
263
|
+
class MINFO < Generic
|
264
|
+
TypeValue = 14
|
265
|
+
end
|
266
|
+
|
267
|
+
# fqdn, ip, x, dist, ttl, timestamp
|
268
|
+
class MX < Resource
|
269
|
+
Sigil ='@'
|
270
|
+
TypeValue = 15
|
271
|
+
|
272
|
+
attr_reader :host, :distance
|
273
|
+
|
274
|
+
def initialize(args)
|
275
|
+
super(args)
|
276
|
+
|
277
|
+
@ip = @args['ip']
|
278
|
+
@host = @args['host']
|
279
|
+
@distance = @args['distance']
|
280
|
+
|
281
|
+
@fields << @fqdn
|
282
|
+
@fields << @ip
|
283
|
+
@fields << @host
|
284
|
+
@fields << @distance
|
285
|
+
@fields << @ttl
|
286
|
+
@fields << @timestamp
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
# fqdn, s, ttl, timestamp
|
291
|
+
class TXT < Resource
|
292
|
+
Sigil = '\''
|
293
|
+
TypeValue = 16
|
294
|
+
|
295
|
+
attr_reader :data
|
296
|
+
|
297
|
+
def initialize(args)
|
298
|
+
super(args)
|
299
|
+
|
300
|
+
@data = @args['data']
|
301
|
+
|
302
|
+
@fields << @fqdn
|
303
|
+
@fields << encode(data)
|
304
|
+
@fields << @ttl
|
305
|
+
@fields << @timestamp
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
class RP
|
310
|
+
TypeValue = 17
|
311
|
+
end
|
312
|
+
|
313
|
+
class ISDN < Generic
|
314
|
+
TypeValue = 20
|
315
|
+
end
|
316
|
+
|
317
|
+
class NSAP < Generic
|
318
|
+
TypeValue = 22
|
319
|
+
end
|
320
|
+
|
321
|
+
class AAAA < Generic
|
322
|
+
TypeValue = 28
|
323
|
+
end
|
324
|
+
|
325
|
+
class LOC < Generic
|
326
|
+
TypeValue = 29
|
327
|
+
end
|
328
|
+
|
329
|
+
class SRV < Generic
|
330
|
+
TypeValue = 33
|
331
|
+
end
|
332
|
+
|
333
|
+
class NAPTR < Generic
|
334
|
+
TypeValue = 35
|
335
|
+
end
|
336
|
+
|
337
|
+
class DNAME < Generic
|
338
|
+
TypeValue = 39
|
339
|
+
end
|
340
|
+
|
341
|
+
class ANY < Generic
|
342
|
+
TypeValue = 255
|
343
|
+
end
|
344
|
+
|
345
|
+
##################################################
|
346
|
+
|
347
|
+
class Transfer < DJB::Service
|
348
|
+
def initialize(*args)
|
349
|
+
super(*args)
|
350
|
+
@allow = Hash.new
|
351
|
+
@deny = Hash.new
|
352
|
+
end
|
353
|
+
|
354
|
+
def fn
|
355
|
+
return @root + '/tcp'
|
356
|
+
end
|
357
|
+
|
358
|
+
def allow(*args)
|
359
|
+
ip = args.shift
|
360
|
+
|
361
|
+
@allow[ip] ||= Array.new
|
362
|
+
args.inject(@allow[ip]) { |arr,ip| arr << ip}
|
363
|
+
end
|
364
|
+
|
365
|
+
def deny(*args)
|
366
|
+
ip = args.shift
|
367
|
+
|
368
|
+
@deny[ip] ||= Array.new
|
369
|
+
args.inject(@deny[ip]) { |arr,ip| arr << ip}
|
370
|
+
end
|
371
|
+
|
372
|
+
def to_s
|
373
|
+
s = ''
|
374
|
+
|
375
|
+
@allow.each do |k,v|
|
376
|
+
s += k + ':allow'
|
377
|
+
s += ",AXFR=\"#{v.join("/")}\"" if v.size() > 0
|
378
|
+
s += "\n"
|
379
|
+
end
|
380
|
+
|
381
|
+
@deny.each do |k,v|
|
382
|
+
s += k + ':deny'
|
383
|
+
s += ",AXFR=\"#{v.join("/")}\"" if v.size() > 0
|
384
|
+
s += "\n"
|
385
|
+
end
|
386
|
+
|
387
|
+
s += ":deny\n"
|
388
|
+
return s
|
389
|
+
end
|
390
|
+
|
391
|
+
def to_f
|
392
|
+
File.write(fn(), to_s())
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
396
|
+
##################################################
|
397
|
+
|
398
|
+
class Wall < DJB::Service
|
399
|
+
def initialize(*args)
|
400
|
+
super(*args)
|
401
|
+
end
|
402
|
+
end
|
403
|
+
|
404
|
+
end # module TinyDNS
|
405
|
+
end # module DJB
|
406
|
+
|
407
|
+
# Local Variables:
|
408
|
+
# mode: ruby
|
409
|
+
# ruby-indent-level: 4
|
410
|
+
# End:
|
data/lib/djb.rb
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
# $Id: djb.rb 50 2006-12-21 02:41:47Z boumenot $
|
2
|
+
|
3
|
+
class File
|
4
|
+
def File.write(filename, string, offset=0)
|
5
|
+
File.open(filename, 'w') do |outf|
|
6
|
+
outf.seek(offset)
|
7
|
+
outf.write(string)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module DJB
|
13
|
+
# see http://cr.yp.to/daemontools/svc.html
|
14
|
+
class Service
|
15
|
+
attr_reader :root
|
16
|
+
attr :svc
|
17
|
+
def initialize(root, svc="/command/svc")
|
18
|
+
@root, @svc = root, svc
|
19
|
+
end
|
20
|
+
|
21
|
+
#------------------------------------------------#
|
22
|
+
|
23
|
+
def env(name, *args)
|
24
|
+
fn = "#{@root}/env/#{name}"
|
25
|
+
if args.size == 0
|
26
|
+
return File.open(fn).read()
|
27
|
+
else
|
28
|
+
File.write(fn, args.join(""))
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Implemented in the base class.
|
33
|
+
# def fn() end
|
34
|
+
|
35
|
+
def make
|
36
|
+
Dir.chdir(File.dirname(fn())) do |d|
|
37
|
+
system("make")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
#------------------------------------------------#
|
42
|
+
|
43
|
+
def restart
|
44
|
+
terminate()
|
45
|
+
end
|
46
|
+
|
47
|
+
def start
|
48
|
+
up()
|
49
|
+
end
|
50
|
+
|
51
|
+
def stop
|
52
|
+
down()
|
53
|
+
end
|
54
|
+
|
55
|
+
#------------------------------------------------#
|
56
|
+
|
57
|
+
def up
|
58
|
+
_svc('-u')
|
59
|
+
end
|
60
|
+
|
61
|
+
def down
|
62
|
+
_svc('-d')
|
63
|
+
end
|
64
|
+
|
65
|
+
def once
|
66
|
+
_svc('-o')
|
67
|
+
end
|
68
|
+
|
69
|
+
def pause
|
70
|
+
_svc('-p')
|
71
|
+
end
|
72
|
+
|
73
|
+
def continue
|
74
|
+
_svc('-c')
|
75
|
+
end
|
76
|
+
|
77
|
+
def hangup
|
78
|
+
_svc('-h')
|
79
|
+
end
|
80
|
+
|
81
|
+
def alarm
|
82
|
+
_svc('-a')
|
83
|
+
end
|
84
|
+
|
85
|
+
def interrupt
|
86
|
+
_svc('-i')
|
87
|
+
end
|
88
|
+
|
89
|
+
def terminate
|
90
|
+
_svc('-t')
|
91
|
+
end
|
92
|
+
|
93
|
+
def kill
|
94
|
+
_svc('-k')
|
95
|
+
end
|
96
|
+
|
97
|
+
def exit
|
98
|
+
_svc('-x')
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
def _svc(options)
|
104
|
+
err = ''
|
105
|
+
IO.popen("#{@svc} #{options} #{@root} 2>&1") { |f| err = f.read() }
|
106
|
+
if $? != 0
|
107
|
+
raise "%Error(#{$?}): #{err}!"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# Local Variables:
|
114
|
+
# mode: ruby
|
115
|
+
# ruby-indent-level: 4
|
116
|
+
# End:
|
data/sample/axfr.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'djb/tinydns'
|
4
|
+
|
5
|
+
axfr = DJB::TinyDNS::Transfer.new('/etc/axfrdns', '/usr/local/bin/svc')
|
6
|
+
|
7
|
+
axfr.allow('172.16.100.1')
|
8
|
+
axfr.allow('172.16.100.2', '1.16.172.in-addr.arpa', 'example.net')
|
9
|
+
axfr.allow('172.16.100.2', 'example.org')
|
10
|
+
axfr.allow('172.16.100.3', '1.16.172.in-addr.arpa')
|
11
|
+
|
12
|
+
axfr.deny('172.16.100.4')
|
13
|
+
axfr.deny('172.16.100.5', '1.16.172.in-addr.arpa')
|
14
|
+
|
15
|
+
# print the tinydns file to the screen
|
16
|
+
puts axfr
|
17
|
+
|
18
|
+
# print the axfr files to the _tcp_ file
|
19
|
+
# axfr.to_f
|
20
|
+
|
21
|
+
|
22
|
+
# Local Variables:
|
23
|
+
# mode: ruby
|
24
|
+
# ruby-indent-level: 4
|
25
|
+
# End:
|
26
|
+
|
data/sample/resolver.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'djb/tinydns'
|
4
|
+
|
5
|
+
tinydns = DJB::TinyDNS::Resolver.new('/etc/tinydns', '/usr/local/bin/svc')
|
6
|
+
|
7
|
+
tinydns.add(DJB::TinyDNS::NS::DelegateFrom.new({'fqdn' => 'example.net', 'ip' => '172.16.1.1'}))
|
8
|
+
tinydns.add(DJB::TinyDNS::NS::DelegateFrom.new({'fqdn' => '1.16.172.in-addr.arpa', 'ip' => '172.16.1.1'}))
|
9
|
+
# -or-
|
10
|
+
# tinydns.add_reverse({'ip' => '172.16.1.1'})
|
11
|
+
|
12
|
+
tinydns.add(DJB::TinyDNS::Host.new( {'fqdn' => 'ace.example.net', 'ip' => '172.16.1.1'}))
|
13
|
+
tinydns.add(DJB::TinyDNS::Host.new( {'fqdn' => 'gary.example.net', 'ip' => '172.16.1.2'}))
|
14
|
+
tinydns.add(DJB::TinyDNS::A.new( {'fqdn' => 'www.example.net', 'ip' => '172.16.1.1'}))
|
15
|
+
tinydns.add(DJB::TinyDNS::A.new( {'fqdn' => 'ftp.example.net', 'ip' => '172.16.1.1'}))
|
16
|
+
tinydns.add(DJB::TinyDNS::A.new( {'fqdn' => 'ssh.example.net', 'ip' => '172.16.1.1'}))
|
17
|
+
tinydns.add(DJB::TinyDNS::A.new( {'fqdn' => 'tftp.example.net', 'ip' => '172.16.1.2'}))
|
18
|
+
tinydns.add(DJB::TinyDNS::CNAME.new({'fqdn' => 'gary.example.net', 'alias' => 'rsh.example.net'}))
|
19
|
+
tinydns.add(DJB::TinyDNS::CNAME.new({'fqdn' => 'gary.example.net', 'alias' => 'telnet.example.net'}))
|
20
|
+
tinydns.add(DJB::TinyDNS::CNAME.new({'fqdn' => 'gary.example.net', 'alias' => 'ntp.example.net'}))
|
21
|
+
tinydns.add(DJB::TinyDNS::MX.new( {'fqdn' => 'example.net', 'host' => 'gary.example.net', 'distance' => 10}))
|
22
|
+
|
23
|
+
intranet = DJB::TinyDNS::Location.new('intranet', '10.0.0')
|
24
|
+
intranet.add(DJB::TinyDNS::Host.new({'fqdn' => 'ace.example.net', 'ip' => '10.0.0.1'}))
|
25
|
+
intranet.add(DJB::TinyDNS::Host.new({'fqdn' => 'gary.example.net', 'ip' => '10.0.0.2'}))
|
26
|
+
tinydns.add(intranet)
|
27
|
+
|
28
|
+
vpn = DJB::TinyDNS::Location.new('vpn', '192.168')
|
29
|
+
vpn.add(DJB::TinyDNS::Host.new({'fqdn' => 'ace.example.net', 'ip' => '192.168.1.1'}))
|
30
|
+
vpn.add(DJB::TinyDNS::Host.new({'fqdn' => 'gary.example.net', 'ip' => '192.168.1.2'}))
|
31
|
+
tinydns.add(vpn)
|
32
|
+
|
33
|
+
# print the tinydns file to the screen
|
34
|
+
puts tinydns
|
35
|
+
|
36
|
+
# print the tinydns files to the _data_ file
|
37
|
+
# tinydns.to_f
|
38
|
+
|
39
|
+
|
40
|
+
# Local Variables:
|
41
|
+
# mode: ruby
|
42
|
+
# ruby-indent-level: 4
|
43
|
+
# End:
|
44
|
+
|
data/test/axfr.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# $Id: axfr.rb 50 2006-12-21 02:41:47Z boumenot $
|
3
|
+
|
4
|
+
require 'test/unit'
|
5
|
+
require 'djb/tinydns'
|
6
|
+
|
7
|
+
class TC_Transfer < Test::Unit::TestCase
|
8
|
+
def test_allow_addr
|
9
|
+
transfer = DJB::TinyDNS::Transfer.new('/etc/axfrdns', '/usr/local/bin/svc')
|
10
|
+
transfer.allow('172.16.1.1')
|
11
|
+
assert(/^172.16.1.1:allow$/.match(transfer.to_s.split("\n")[0]), 'transfer: allow_addr')
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_allow_zone
|
15
|
+
transfer = DJB::TinyDNS::Transfer.new('/etc/axfrdns', '/usr/local/bin/svc')
|
16
|
+
transfer.allow('172.16.1.1', 'example.org')
|
17
|
+
assert(/^172.16.1.1:allow,AXFR="example.org"$/.match(transfer.to_s.split("\n")[0]), 'transfer: allow_zone')
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_allow_multi_zone
|
21
|
+
transfer = DJB::TinyDNS::Transfer.new('/etc/axfrdns', '/usr/local/bin/svc')
|
22
|
+
transfer.allow('172.16.1.1', %w(example.org example.net))
|
23
|
+
assert(/^172.16.1.1:allow,AXFR=\"example.org\/example.net\"$/.match(transfer.to_s.split("\n")[0]), 'transfer: allow_multi_zone')
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_deny_addr
|
27
|
+
transfer = DJB::TinyDNS::Transfer.new('/etc/axfrdns', '/usr/local/bin/svc')
|
28
|
+
transfer.deny('172.16.1.1')
|
29
|
+
assert(/^172.16.1.1:deny$/.match(transfer.to_s.split("\n")[0]), 'transfer: deny_addr')
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_default_deny
|
33
|
+
transfer = DJB::TinyDNS::Transfer.new('/etc/axfrdns', '/usr/local/bin/svc')
|
34
|
+
assert(/^:deny$/.match(transfer.to_s.split("\n")[-1]), 'transfer: default_deny')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Local Variables:
|
39
|
+
# mode: ruby
|
40
|
+
# ruby-indent-level: 4
|
41
|
+
# End:
|
data/test/resolver.rb
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# $Id: resolver.rb 50 2006-12-21 02:41:47Z boumenot $
|
3
|
+
|
4
|
+
require 'test/unit'
|
5
|
+
require 'djb/tinydns'
|
6
|
+
|
7
|
+
EVERYTHING = {
|
8
|
+
'fqdn' => 'ace.example.net',
|
9
|
+
'ip' => '172.16.1.100',
|
10
|
+
'host' => 'gary.example.net',
|
11
|
+
'alias' => 'agd.example.net',
|
12
|
+
'mname' => 'dns.example.net',
|
13
|
+
'rname' => 'admin.example.net',
|
14
|
+
'distance' => 10,
|
15
|
+
'data' => 'Robert Smigel',
|
16
|
+
'TypeValue' => 1001,
|
17
|
+
}
|
18
|
+
|
19
|
+
def module_walk(clss)
|
20
|
+
top = Object
|
21
|
+
clss.split('::')[0..-1].each do |m|
|
22
|
+
top = top.const_get(m)
|
23
|
+
end
|
24
|
+
return top
|
25
|
+
end
|
26
|
+
|
27
|
+
class TC_Prefix < Test::Unit::TestCase
|
28
|
+
def test_prefix
|
29
|
+
e = {
|
30
|
+
'Host' => '=',
|
31
|
+
'Generic' => ':',
|
32
|
+
'A' => '+',
|
33
|
+
'NS::DelegateTo' => '&',
|
34
|
+
'NS::DelegateFrom' => '.',
|
35
|
+
'CNAME' => 'C',
|
36
|
+
'SOA' => 'Z',
|
37
|
+
'PTR' => '^',
|
38
|
+
'MX' => '@',
|
39
|
+
'TXT' => '\'',
|
40
|
+
|
41
|
+
'AAAA' => ':',
|
42
|
+
'WKS' => ':',
|
43
|
+
'SRV' => ':',
|
44
|
+
'NULL' => ':',
|
45
|
+
'HINFO' => ':',
|
46
|
+
'MINFO' => ':',
|
47
|
+
}
|
48
|
+
|
49
|
+
e.each do |k,expected|
|
50
|
+
mod = module_walk("DJB::TinyDNS::#{k}")
|
51
|
+
actual = mod.new(EVERYTHING).to_s[0].chr
|
52
|
+
assert(actual == expected, "prefix: expected=#{expected}, actual=#{actual}")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class TC_Accessor < Test::Unit::TestCase
|
58
|
+
def test_accessor
|
59
|
+
e = {
|
60
|
+
:ttl => %w{Host Generic A NS::DelegateTo NS::DelegateFrom CNAME SOA PTR MX TXT},
|
61
|
+
:timestamp => %w{Host Generic A NS::DelegateTo NS::DelegateFrom CNAME SOA PTR MX TXT},
|
62
|
+
:alias => %w{CNAME},
|
63
|
+
:mname => %w{SOA},
|
64
|
+
:rname => %w{SOA},
|
65
|
+
:host => %w{NS::DelegateTo NS::DelegateFrom PTR MX},
|
66
|
+
:distance => %w{MX},
|
67
|
+
:data => %w{Generic TXT},
|
68
|
+
:ip => %w{A NS::DelegateTo NS::DelegateFrom},
|
69
|
+
}
|
70
|
+
|
71
|
+
e.each do |k,v|
|
72
|
+
v.each do |c|
|
73
|
+
mod = module_walk("DJB::TinyDNS::#{c}")
|
74
|
+
assert(mod.new(EVERYTHING).respond_to?(k), "DJB::TinyDNS::#{c} does not respond to #{k}")
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
class TC_Location < Test::Unit::TestCase
|
80
|
+
def test_location
|
81
|
+
loc = DJB::TinyDNS::Location.new('intranet', '192.168')
|
82
|
+
loc.add(DJB::TinyDNS::Host.new(EVERYTHING))
|
83
|
+
|
84
|
+
first, second = loc.to_s.split("\n")
|
85
|
+
|
86
|
+
assert(/^%intranet/.match(first), "location: expected /^%intranet/, actual=#{first}")
|
87
|
+
assert(/^\=/.match(second), "location: expected /^=.*/, actual #{second}")
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
# Local Variables:
|
95
|
+
# mode: ruby
|
96
|
+
# ruby-indent-level: 4
|
97
|
+
# End:
|
data/test/runner.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# $Id: runner.rb 50 2006-12-21 02:41:47Z boumenot $
|
3
|
+
|
4
|
+
$: << File.dirname(__FILE__) + '/../lib'
|
5
|
+
require 'test/unit'
|
6
|
+
|
7
|
+
if not (File.exists?('resolver.rb'))
|
8
|
+
raise 'The test suite should only be run from the test directory.'
|
9
|
+
end
|
10
|
+
|
11
|
+
Dir.glob("#{File.dirname(__FILE__)}/*.rb").each() { |filename|
|
12
|
+
next if filename == 'runner.rb'
|
13
|
+
require(filename)
|
14
|
+
}
|
15
|
+
|
16
|
+
# Local Variables:
|
17
|
+
# mode: ruby
|
18
|
+
# ruby-indent-level: 4
|
19
|
+
# End:
|
metadata
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.8.11
|
3
|
+
specification_version: 1
|
4
|
+
name: ruby-djbdns
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.0.1
|
7
|
+
date: 2006-12-30 00:00:00 -05:00
|
8
|
+
summary: Ruby module to manage TinyDNS
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: boumenot@gmail.com
|
12
|
+
homepage:
|
13
|
+
rubyforge_project:
|
14
|
+
description:
|
15
|
+
autorequire:
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: false
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
authors:
|
29
|
+
- Christopher Boumenot
|
30
|
+
files:
|
31
|
+
- sample
|
32
|
+
- lib
|
33
|
+
- VERSION
|
34
|
+
- README
|
35
|
+
- test
|
36
|
+
- FILES
|
37
|
+
- COPYING
|
38
|
+
- sample/axfr.rb
|
39
|
+
- sample/resolver.rb
|
40
|
+
- lib/djb.rb
|
41
|
+
- lib/djb/tinydns.rb
|
42
|
+
- test/resolver.rb
|
43
|
+
- test/axfr.rb
|
44
|
+
- test/runner.rb
|
45
|
+
test_files:
|
46
|
+
- test/resolver.rb
|
47
|
+
- test/axfr.rb
|
48
|
+
- test/runner.rb
|
49
|
+
rdoc_options: []
|
50
|
+
|
51
|
+
extra_rdoc_files: []
|
52
|
+
|
53
|
+
executables: []
|
54
|
+
|
55
|
+
extensions: []
|
56
|
+
|
57
|
+
requirements: []
|
58
|
+
|
59
|
+
dependencies: []
|
60
|
+
|