ruby-djbdns 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|