redzone 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.
- checksums.yaml +15 -0
- data/.gitignore +11 -0
- data/Gemfile +17 -0
- data/LICENSE.md +10 -0
- data/README.md +84 -0
- data/Rakefile +32 -0
- data/bin/redzone +7 -0
- data/lib/redzone/arpa.rb +66 -0
- data/lib/redzone/cli.rb +33 -0
- data/lib/redzone/environment.rb +20 -0
- data/lib/redzone/lifetime.rb +55 -0
- data/lib/redzone/machine.rb +70 -0
- data/lib/redzone/mail_exchange.rb +28 -0
- data/lib/redzone/name_server.rb +24 -0
- data/lib/redzone/record.rb +37 -0
- data/lib/redzone/soa.rb +64 -0
- data/lib/redzone/version.rb +6 -0
- data/lib/redzone/zone.rb +279 -0
- data/lib/redzone/zone_config.rb +28 -0
- data/lib/redzone/zonefile_writer.rb +30 -0
- data/lib/redzone.rb +2 -0
- data/redzone.gemspec +32 -0
- data/redzone.rb +279 -0
- data/spec/spec_helper.rb +30 -0
- data/spec/unit/arpa_spec.rb +40 -0
- data/spec/unit/record_spec.rb +60 -0
- data/zones.yml +74 -0
- metadata +121 -0
data/lib/redzone/zone.rb
ADDED
@@ -0,0 +1,279 @@
|
|
1
|
+
require 'redzone/record'
|
2
|
+
require 'redzone/soa'
|
3
|
+
require 'redzone/machine'
|
4
|
+
require 'redzone/mail_exchange'
|
5
|
+
require 'redzone/name_server'
|
6
|
+
require 'redzone/arpa'
|
7
|
+
|
8
|
+
module RedZone
|
9
|
+
# Represents a zone configuraton for a domain.
|
10
|
+
#
|
11
|
+
# Takes a zone configuration in the form of a hash.
|
12
|
+
# this is usually read from a yaml file. The schema
|
13
|
+
# for the yaml file can be found in the resources
|
14
|
+
#
|
15
|
+
class Zone
|
16
|
+
# Returns the domain name of the zone
|
17
|
+
# @return [String]
|
18
|
+
attr_reader :name
|
19
|
+
|
20
|
+
# Return the a list of machines
|
21
|
+
# @return [Array<Machine>]
|
22
|
+
attr_reader :machines
|
23
|
+
|
24
|
+
# Return the SOA record
|
25
|
+
# @return [SOA]
|
26
|
+
attr_reader :soa
|
27
|
+
|
28
|
+
# Returns the default machine for the domain when no subdomain is supplied
|
29
|
+
# @return [Machine]
|
30
|
+
attr_reader :default
|
31
|
+
|
32
|
+
# Returns a list of name servers that service the zone
|
33
|
+
# @return [Array<Machine>]
|
34
|
+
attr_reader :nameservers
|
35
|
+
|
36
|
+
# Returns a list of mail servers
|
37
|
+
# @return [Array<Machine>]
|
38
|
+
attr_reader :mailservers
|
39
|
+
|
40
|
+
# Returns a list of alternate names for machines.
|
41
|
+
# These are additional A/AAAA records to the same
|
42
|
+
# IP Address
|
43
|
+
# @return [Array<Machine>]
|
44
|
+
attr_reader :altnames
|
45
|
+
|
46
|
+
# Returns a list of domain-name aliases
|
47
|
+
# @return [Array<Record>]
|
48
|
+
attr_reader :cnames
|
49
|
+
|
50
|
+
# Returns the wildcard entry - the catch-all machine for dns queries
|
51
|
+
# not matching any other subdomain entry.
|
52
|
+
# @return [Machine]
|
53
|
+
attr_reader :wildcard
|
54
|
+
|
55
|
+
# Returns a list of additional zone records
|
56
|
+
# @return [Array<Record>]
|
57
|
+
attr_reader :records
|
58
|
+
|
59
|
+
# Create a new Zone config
|
60
|
+
# @param [String] name Domain name (eg: example.com)
|
61
|
+
# @param [Hash] config Zone configuration
|
62
|
+
def initialize(name,config)
|
63
|
+
@name = name
|
64
|
+
@config = config
|
65
|
+
generate_machines()
|
66
|
+
generate_aliases()
|
67
|
+
generate_nameservers()
|
68
|
+
generate_mailservers()
|
69
|
+
generate_cnames()
|
70
|
+
generate_records()
|
71
|
+
@soa = generate_soa(@name)
|
72
|
+
d = get_machine('default')
|
73
|
+
wc = get_machine('wildcard')
|
74
|
+
if d
|
75
|
+
@default = d.alias("@")
|
76
|
+
end
|
77
|
+
if wc
|
78
|
+
@wildcard = wc.alias("*")
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# Writes a given set of Records to the target IO
|
83
|
+
# @param [IO] io output IO Stream
|
84
|
+
# @param [Array<Record>] records
|
85
|
+
def write_records(io,records)
|
86
|
+
unless records.nil? or records.empty?
|
87
|
+
records.each do |r|
|
88
|
+
io << r
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Writes the list of machines to the target IO
|
94
|
+
# @param [IO] io output IO Stream
|
95
|
+
# @param [Array<#records>] machines machines
|
96
|
+
# @param [String] comment (nil) Optional comment to be prefixed to the record section
|
97
|
+
def write_machines(io,machines,comment=nil)
|
98
|
+
unless machines.nil? or machines.empty?
|
99
|
+
io << "; #{comment}\n" unless comment.nil?
|
100
|
+
machines.each do |m|
|
101
|
+
write_records(io,m.records)
|
102
|
+
end
|
103
|
+
io << "\n"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# Writes the entre zonefile to the target IO
|
108
|
+
# @param [IO] io Target IO stream
|
109
|
+
def write(io)
|
110
|
+
io << soa
|
111
|
+
unless default.nil?
|
112
|
+
write_machines(io,[default],"Default Machine")
|
113
|
+
end
|
114
|
+
write_machines(io,nameservers,"Name Servers")
|
115
|
+
write_machines(io,mailservers,"Mail Servers")
|
116
|
+
write_machines(io,machines,"Primary Machine names")
|
117
|
+
write_machines(io,altnames,"Alternate Machine Names")
|
118
|
+
unless wildcard.nil?
|
119
|
+
write_machines(io,[wildcard],"Wildcard Machine")
|
120
|
+
end
|
121
|
+
unless cnames.empty?
|
122
|
+
io << "; Canonical Names\n"
|
123
|
+
write_records(io,cnames)
|
124
|
+
io << "\n"
|
125
|
+
end
|
126
|
+
|
127
|
+
unless records.nil? or records.empty?
|
128
|
+
io << "; Extra Records\n"
|
129
|
+
write_records(io,records)
|
130
|
+
io << "\n"
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
# Generates a list of Arpas for this zone
|
135
|
+
# @return [Array<Arpa>]
|
136
|
+
def generate_arpa_list
|
137
|
+
arpas = []
|
138
|
+
if @config.has_key?('arpa')
|
139
|
+
@config['arpa'].each do |cfg|
|
140
|
+
opts = symbolize(cfg)
|
141
|
+
soa = generate_soa(opts[:name])
|
142
|
+
opts[:soa] = soa
|
143
|
+
an = Arpa.new(opts)
|
144
|
+
arpas << an
|
145
|
+
@nameservers.each do |ns|
|
146
|
+
an.add_record(Record.new(:name => '@', :type => 'NS', :data => ns.name + ".#{@name}." ))
|
147
|
+
end
|
148
|
+
@machines.each do |machine|
|
149
|
+
an.add(machine,@name)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
arpas
|
154
|
+
end
|
155
|
+
|
156
|
+
private
|
157
|
+
def sorted_each(hash,&block)
|
158
|
+
keys = hash.keys.sort
|
159
|
+
keys.each do |key|
|
160
|
+
block.call(key,hash[key])
|
161
|
+
end
|
162
|
+
end
|
163
|
+
def symbolize(hash)
|
164
|
+
hash.inject({}) do |memo,(k,v)|
|
165
|
+
memo[k.to_sym] = v
|
166
|
+
memo
|
167
|
+
end
|
168
|
+
end
|
169
|
+
def generate_soa(name)
|
170
|
+
opts = symbolize(@config['lifetimes'])
|
171
|
+
opts[:hostmaster] = @config['hostmaster'] if @config.has_key?('hostmaster')
|
172
|
+
opts[:domain] = name
|
173
|
+
opts[:ns] = @nameservers[0].name + ".#{@name}." unless @nameservers.empty?
|
174
|
+
SOA.new(opts)
|
175
|
+
end
|
176
|
+
def generate_machines
|
177
|
+
@machines = []
|
178
|
+
@allnames = []
|
179
|
+
@machines_by_name = {}
|
180
|
+
sorted_each(@config['machines']) do |n,c|
|
181
|
+
#@config['machines'].each do |n,c|
|
182
|
+
m = Machine.new(n,symbolize(c))
|
183
|
+
@allnames << n
|
184
|
+
@machines << m
|
185
|
+
@machines_by_name[n] = m
|
186
|
+
end
|
187
|
+
end
|
188
|
+
def get_machine(name)
|
189
|
+
if @machines_by_name.has_key?(name)
|
190
|
+
@machines_by_name[name]
|
191
|
+
else
|
192
|
+
nil
|
193
|
+
end
|
194
|
+
end
|
195
|
+
def generate_aliases
|
196
|
+
machines = []
|
197
|
+
if @config.has_key?('aliases')
|
198
|
+
sorted_each(@config['aliases']) do |name,ref|
|
199
|
+
#@config['aliases'].each do |name,ref|
|
200
|
+
m = get_machine(ref)
|
201
|
+
if not m.nil?
|
202
|
+
machines << m.alias(name)
|
203
|
+
@allnames << name
|
204
|
+
else
|
205
|
+
puts "ERROR: No such machine named #{ref}"
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
@altnames = machines
|
210
|
+
end
|
211
|
+
def add_alias(name,machine)
|
212
|
+
unless @allnames.include?(name)
|
213
|
+
@altnames << machine.alias(name)
|
214
|
+
@allnames << name
|
215
|
+
end
|
216
|
+
end
|
217
|
+
def generate_mailservers
|
218
|
+
machines = []
|
219
|
+
if @config.has_key?('mailservers')
|
220
|
+
sorted_each(@config['mailservers']) do |name,mx|
|
221
|
+
#@config['mailservers'].each do |name,mx|
|
222
|
+
ref = mx['machine']
|
223
|
+
m = get_machine(ref)
|
224
|
+
if not m.nil?
|
225
|
+
priority = mx['priority'] || 10
|
226
|
+
machines << MailExchange.new(name,m,priority)
|
227
|
+
add_alias(name,m)
|
228
|
+
else
|
229
|
+
puts "ERROR: No such machine named #{ref}"
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
@mailservers = machines
|
234
|
+
end
|
235
|
+
def generate_nameservers
|
236
|
+
machines = []
|
237
|
+
if @config.has_key?('nameservers')
|
238
|
+
sorted_each(@config['nameservers']) do |name,ref|
|
239
|
+
#@config['nameservers'].each do |name,ref|
|
240
|
+
m = get_machine(ref)
|
241
|
+
if not m.nil?
|
242
|
+
machines << NameServer.new(name,m)
|
243
|
+
add_alias(name,m)
|
244
|
+
else
|
245
|
+
puts "ERROR: No such machine named #{ref}"
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
@nameservers = machines
|
250
|
+
end
|
251
|
+
def generate_cnames
|
252
|
+
@cnames = []
|
253
|
+
sorted_each(@config['cnames']) do |k,v|
|
254
|
+
#@config['cnames'].each do |k,v|
|
255
|
+
data = v
|
256
|
+
# Assume absolute domain name
|
257
|
+
# if value is not a machine name
|
258
|
+
unless @allnames.include?(v)
|
259
|
+
data = "#{v}."
|
260
|
+
end
|
261
|
+
@cnames << Record.new({
|
262
|
+
:name => k,
|
263
|
+
:type => 'CNAME',
|
264
|
+
:data => data
|
265
|
+
})
|
266
|
+
end
|
267
|
+
@cnames
|
268
|
+
end
|
269
|
+
def generate_records
|
270
|
+
@records = []
|
271
|
+
if @config.has_key?('records')
|
272
|
+
@config['records'].each do |record|
|
273
|
+
@records << Record.new(symbolize(record))
|
274
|
+
end
|
275
|
+
end
|
276
|
+
@records
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'redzone/zone'
|
3
|
+
|
4
|
+
module RedZone
|
5
|
+
# Contains zone configurations
|
6
|
+
class ZoneConfig
|
7
|
+
# Return the list of Zone objects
|
8
|
+
# @return [Array<Zone>] zone
|
9
|
+
attr_reader :zones
|
10
|
+
# Return the list of ArpaNetwork objects
|
11
|
+
# @return [Array<ArpaNetwork>] arpa networks
|
12
|
+
attr_reader :arpas
|
13
|
+
def initialize(file)
|
14
|
+
config = YAML.load_file(file)
|
15
|
+
common = config['zones']['common']
|
16
|
+
@zones = []
|
17
|
+
@arpas = []
|
18
|
+
config['zones'].each do |z,c|
|
19
|
+
if z != 'common'
|
20
|
+
cfg = common.merge(c)
|
21
|
+
zone = Zone.new(z,cfg)
|
22
|
+
@zones << zone
|
23
|
+
@arpas.concat zone.generate_arpa_list()
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'redzone/zone'
|
3
|
+
|
4
|
+
module RedZone
|
5
|
+
# Writes zone configurations to files
|
6
|
+
class ZonefileWriter
|
7
|
+
# Constructs a ZonefileWriter
|
8
|
+
def initialize(zone_config)
|
9
|
+
@config = zone_config
|
10
|
+
end
|
11
|
+
# Write the zone database files to the target folder
|
12
|
+
# @param [Pathname] target Target directory
|
13
|
+
def write_zones(target)
|
14
|
+
raise ArgumentError, "Directory #{target} does not exist" unless target.exist?
|
15
|
+
@config.zones.each do |z|
|
16
|
+
with_file(target,z.name) { |io| z.write(io) }
|
17
|
+
end
|
18
|
+
@config.arpas.each do |a|
|
19
|
+
with_file(target,a.name) {|io| a.write(io)}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
private
|
23
|
+
def with_file(target,name,&block)
|
24
|
+
filename = target + "#{name}.db"
|
25
|
+
File.open(filename,"w") do |file|
|
26
|
+
block.call(file)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/redzone.rb
ADDED
data/redzone.gemspec
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'redzone/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
# Metadata
|
8
|
+
spec.name = 'redzone'
|
9
|
+
spec.version = RedZone::VERSION
|
10
|
+
spec.authors = ['Justen Walker']
|
11
|
+
spec.email = %w(justen.walker@gmail.com)
|
12
|
+
spec.homepage = "https://github.com/justenwalker/redzone"
|
13
|
+
spec.summary = 'RedZone - Automatically generate BIND zone files'
|
14
|
+
spec.description = <<-eos.gsub(/^ +/,'')
|
15
|
+
RedZone is a command-line too that can generate bind zone
|
16
|
+
files and configuration from yaml syntax.
|
17
|
+
eos
|
18
|
+
spec.license = "MIT"
|
19
|
+
|
20
|
+
|
21
|
+
spec.files = `git ls-files`.split($/)
|
22
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
23
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
24
|
+
spec.require_paths = ["lib"]
|
25
|
+
|
26
|
+
# Dependencies
|
27
|
+
spec.required_ruby_version = '>= 1.8.7'
|
28
|
+
spec.add_runtime_dependency 'thor', '~> 0.18.1'
|
29
|
+
|
30
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
31
|
+
spec.add_development_dependency "rake"
|
32
|
+
end
|
data/redzone.rb
ADDED
@@ -0,0 +1,279 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
require 'tsort'
|
5
|
+
|
6
|
+
class String
|
7
|
+
def unindent
|
8
|
+
gsub(/^#{scan(/^\s*/).min_by{|l|l.length}}/, "")
|
9
|
+
end
|
10
|
+
end
|
11
|
+
module RedZone
|
12
|
+
class ZoneConfig
|
13
|
+
include TSort
|
14
|
+
def initialize(zonefile)
|
15
|
+
@cfg = YAML.load_file(zonefile)
|
16
|
+
@zones = Hash.new {|h,k| h[k] = []}
|
17
|
+
@machines = []
|
18
|
+
@ips = []
|
19
|
+
@cfg['zones'].each do |k,v|
|
20
|
+
add(Zone.new(k,v))
|
21
|
+
end
|
22
|
+
end
|
23
|
+
def add(zone)
|
24
|
+
@zones[zone.name] = zone
|
25
|
+
end
|
26
|
+
def tsort_each_node(&block)
|
27
|
+
@zones.each_key(&block)
|
28
|
+
end
|
29
|
+
def tsort_each_child(node, &block)
|
30
|
+
@zones[node].dependencies.each(&block) if @zones.has_key?(node)
|
31
|
+
end
|
32
|
+
def domains
|
33
|
+
d = []
|
34
|
+
@zones.each do |k,v|
|
35
|
+
d << v.domains
|
36
|
+
end
|
37
|
+
d.flatten
|
38
|
+
end
|
39
|
+
def setup!
|
40
|
+
self.tsort.each do |z|
|
41
|
+
zone = @zones[z]
|
42
|
+
zone.dependencies.each do |dep|
|
43
|
+
zone.inherit!(@zones[dep])
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
def generate_domain(domain)
|
48
|
+
io = StringIO.new
|
49
|
+
@zones.each do |k,v|
|
50
|
+
if v.domains.include?(domain)
|
51
|
+
io << v.generate_zonefile(domain)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
io.string
|
55
|
+
end
|
56
|
+
end
|
57
|
+
class Zone
|
58
|
+
attr_reader :name,:dependencies,:config
|
59
|
+
def inherit!(zone)
|
60
|
+
unless @inherited.include?(zone.name)
|
61
|
+
@config = zone.config.merge(@config)
|
62
|
+
@inherited << zone.name
|
63
|
+
end
|
64
|
+
end
|
65
|
+
def initialize(name,config)
|
66
|
+
@inherited = []
|
67
|
+
@name = name
|
68
|
+
@config = config
|
69
|
+
@dependencies = []
|
70
|
+
if @config.has_key?('inherits')
|
71
|
+
@dependencies << @config['inherits']
|
72
|
+
@dependencies = @dependencies.flatten
|
73
|
+
end
|
74
|
+
end
|
75
|
+
def domains
|
76
|
+
@config['domains'] || []
|
77
|
+
end
|
78
|
+
def generate_conffile(domain,datafile,masters=[])
|
79
|
+
io = StringIO.new
|
80
|
+
write_conffile(io,domain,datafile,masters)
|
81
|
+
io.string
|
82
|
+
end
|
83
|
+
def write_conffile(io,domain,datafile,masters=[])
|
84
|
+
if not masters.empty?
|
85
|
+
masterlist = masters.join(" ; ")
|
86
|
+
io << <<-eos.unindent
|
87
|
+
zone "#{domain}" in {
|
88
|
+
type slave;
|
89
|
+
file "#{datafile}";
|
90
|
+
masters { #{masterlist} ; } ;
|
91
|
+
}
|
92
|
+
eos
|
93
|
+
else
|
94
|
+
io << <<-eos.unindent
|
95
|
+
zone "#{domain}" in {
|
96
|
+
type master;
|
97
|
+
file "#{datafile}";
|
98
|
+
}
|
99
|
+
eos
|
100
|
+
end
|
101
|
+
end
|
102
|
+
def generate_zonefile(domain)
|
103
|
+
io = StringIO.new
|
104
|
+
write_zonefile(io,domain)
|
105
|
+
io.string
|
106
|
+
end
|
107
|
+
def write_zonefile(io,domain)
|
108
|
+
io << generate_soa(domain)
|
109
|
+
io << generate_default
|
110
|
+
io << generate_dns
|
111
|
+
io << generate_mail
|
112
|
+
io << generate_machines
|
113
|
+
io << generate_names
|
114
|
+
io << generate_aliases
|
115
|
+
io << generate_wildcard
|
116
|
+
end
|
117
|
+
|
118
|
+
private
|
119
|
+
def all_machines
|
120
|
+
machines = []
|
121
|
+
@config['machines'].each do |name,cfg|
|
122
|
+
machines << Machine.new(name,cfg)
|
123
|
+
end
|
124
|
+
machines
|
125
|
+
end
|
126
|
+
def get_machine(name)
|
127
|
+
Machine.new(name,@config['machines'][name])
|
128
|
+
end
|
129
|
+
def generate_soa(domain)
|
130
|
+
lifetimes = @config['lifetimes']
|
131
|
+
ttl = lifetimes['ttl']
|
132
|
+
hostmaster = @config['hostmaster']
|
133
|
+
now = Time.now.to_i
|
134
|
+
refresh = lifetimes['refresh']
|
135
|
+
re = lifetimes['retry']
|
136
|
+
expire = lifetimes['expire']
|
137
|
+
negative = lifetimes['negative']
|
138
|
+
<<-eos.unindent
|
139
|
+
$ORIGIN #{domain}.
|
140
|
+
$TTL #{ttl} ; queries are cached for this long
|
141
|
+
@ IN SOA ns1 #{hostmaster} (
|
142
|
+
#{now} ; Date $time
|
143
|
+
#{refresh} ; slave queries for refresh this often
|
144
|
+
#{re} ; slave retries refresh this often after failure
|
145
|
+
#{expire} ; slave expires after this long if not refreshed
|
146
|
+
#{negative} ; errors are cached for this long
|
147
|
+
)
|
148
|
+
|
149
|
+
eos
|
150
|
+
end
|
151
|
+
def generate_record(name,type,detail,value,comment=nil)
|
152
|
+
suffix = " ; #{comment}" unless comment.nil?
|
153
|
+
"%-20s IN %-8s %-6s %s%s\n" % [name, type, detail, value, suffix || ""]
|
154
|
+
end
|
155
|
+
def generate_machine(name,machine)
|
156
|
+
comment = "Machine #{machine}" unless name == machine
|
157
|
+
if machine.is_a? String
|
158
|
+
machine = get_machine(machine)
|
159
|
+
end
|
160
|
+
io = StringIO.new
|
161
|
+
io << generate_record(name,"A","",machine.ipv4,comment) if machine.ipv4?
|
162
|
+
io << generate_record(name,"AAAA","",machine.ipv6,comment) if machine.ipv6?
|
163
|
+
io.string
|
164
|
+
end
|
165
|
+
def generate_default
|
166
|
+
io = StringIO.new
|
167
|
+
if @config['default']
|
168
|
+
io << "; Primary name records for unqualfied domain\n"
|
169
|
+
io << generate_machine("@",@config['default'])
|
170
|
+
io << "\n"
|
171
|
+
end
|
172
|
+
io.string
|
173
|
+
end
|
174
|
+
def generate_dns
|
175
|
+
io = StringIO.new
|
176
|
+
if @config.has_key?('dns')
|
177
|
+
io << ": DNS Server Records\n"
|
178
|
+
dns_keys = @config['dns'].keys.sort
|
179
|
+
dns_keys.each do |k|
|
180
|
+
io << generate_record("@","NS","",k)
|
181
|
+
end
|
182
|
+
dns_keys.each do |k|
|
183
|
+
machine = @config['dns'][k]
|
184
|
+
io << generate_machine(k,machine)
|
185
|
+
end
|
186
|
+
io << "\n"
|
187
|
+
end
|
188
|
+
io.string
|
189
|
+
end
|
190
|
+
def generate_mail
|
191
|
+
io = StringIO.new
|
192
|
+
if @config.has_key?('mail')
|
193
|
+
io << "; Email Servers\n"
|
194
|
+
mail_keys = @config['mail'].keys.sort
|
195
|
+
mail_keys.each do |k|
|
196
|
+
mail = @config['mail'][k]
|
197
|
+
priority = mail['priority']
|
198
|
+
io << generate_record("@","MX",priority,k)
|
199
|
+
end
|
200
|
+
mail_keys.each do |k|
|
201
|
+
mail = @config['mail'][k]
|
202
|
+
machine = mail['machine']
|
203
|
+
io << generate_machine(k,machine)
|
204
|
+
end
|
205
|
+
io << "\n"
|
206
|
+
end
|
207
|
+
io.string
|
208
|
+
end
|
209
|
+
def generate_machines
|
210
|
+
io = StringIO.new
|
211
|
+
io << "; Primary Machine Names\n"
|
212
|
+
all_machines.each do |machine|
|
213
|
+
io << generate_machine(machine.name,machine)
|
214
|
+
end
|
215
|
+
io << "\n"
|
216
|
+
io.string
|
217
|
+
end
|
218
|
+
def generate_names
|
219
|
+
io = StringIO.new
|
220
|
+
if @config.has_key?('mail')
|
221
|
+
io << "; Extra Names\n"
|
222
|
+
name_keys = @config['names'].keys.sort
|
223
|
+
name_keys.each do |name|
|
224
|
+
machine = @config['names'][name]
|
225
|
+
io << generate_machine(name,machine)
|
226
|
+
end
|
227
|
+
io << "\n"
|
228
|
+
end
|
229
|
+
io.string
|
230
|
+
end
|
231
|
+
def generate_aliases
|
232
|
+
io = StringIO.new
|
233
|
+
if @config.has_key?('mail')
|
234
|
+
io << "; Extra Names\n"
|
235
|
+
cname_keys = @config['aliases'].keys.sort
|
236
|
+
cname_keys.each do |cname|
|
237
|
+
value = @config['aliases'][cname]
|
238
|
+
io << generate_record(cname,"CNAME","",value)
|
239
|
+
end
|
240
|
+
io << "\n"
|
241
|
+
end
|
242
|
+
io.string
|
243
|
+
end
|
244
|
+
def generate_wildcard
|
245
|
+
io = StringIO.new
|
246
|
+
if @config['wildcard']
|
247
|
+
io << "; Wildcard\n"
|
248
|
+
io << generate_machine("*",@config['wildcard'])
|
249
|
+
io << "\n"
|
250
|
+
end
|
251
|
+
io.string
|
252
|
+
end
|
253
|
+
end
|
254
|
+
class Machine
|
255
|
+
attr_reader :name,:ipv4,:ipv6
|
256
|
+
def initialize(name,config)
|
257
|
+
@name = name
|
258
|
+
@ipv4 = config['ipv4']
|
259
|
+
@ipv6 = config['ipv6']
|
260
|
+
end
|
261
|
+
def ipv4?
|
262
|
+
not @ipv4.nil?
|
263
|
+
end
|
264
|
+
def ipv6?
|
265
|
+
not @ipv6.nil?
|
266
|
+
end
|
267
|
+
def to_s
|
268
|
+
@name
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
zonecfg = RedZone::ZoneConfig.new 'zones.yml'
|
274
|
+
zonecfg.setup!
|
275
|
+
zonecfg.domains.each do |d|
|
276
|
+
puts zonecfg.generate_domain(d)
|
277
|
+
end
|
278
|
+
|
279
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
dir = File.expand_path(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift File.join(dir, 'lib')
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'bundler/setup'
|
6
|
+
|
7
|
+
Bundler.require :default, :test
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
require 'tmpdir'
|
11
|
+
|
12
|
+
Pathname.glob("#{dir}/shared_behaviours/**/*.rb") do |behaviour|
|
13
|
+
require behaviour.relative_path_from(Pathname.new(dir))
|
14
|
+
end
|
15
|
+
|
16
|
+
def root_path
|
17
|
+
Pathname.new(File.expand_path(File.join(__FILE__, '..', '..')))
|
18
|
+
end
|
19
|
+
|
20
|
+
def fixture_path
|
21
|
+
root_path + 'spec' + 'fixtures'
|
22
|
+
end
|
23
|
+
|
24
|
+
def resources_path
|
25
|
+
root_path + 'resources'
|
26
|
+
end
|
27
|
+
|
28
|
+
RSpec.configure do |config|
|
29
|
+
config.mock_with :mocha
|
30
|
+
end
|