dns-catalog_zone 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +1 -0
  4. data/.coveralls.yml +2 -0
  5. data/.gitignore +13 -0
  6. data/.rspec +1 -0
  7. data/.travis.yml +11 -0
  8. data/Gemfile +9 -0
  9. data/LICENSE.txt +21 -0
  10. data/README.jp.md +115 -0
  11. data/README.md +113 -0
  12. data/Rakefile +8 -0
  13. data/bin/catz +33 -0
  14. data/certs/mimuret.pem +21 -0
  15. data/dns-catalog_zone.gemspec +33 -0
  16. data/lib/dns/catalog_zone.rb +40 -0
  17. data/lib/dns/catalog_zone/catalog_zone.rb +125 -0
  18. data/lib/dns/catalog_zone/cli.rb +88 -0
  19. data/lib/dns/catalog_zone/config.rb +83 -0
  20. data/lib/dns/catalog_zone/errors.rb +32 -0
  21. data/lib/dns/catalog_zone/helper.rb +98 -0
  22. data/lib/dns/catalog_zone/master.rb +47 -0
  23. data/lib/dns/catalog_zone/output.rb +44 -0
  24. data/lib/dns/catalog_zone/output/base.rb +42 -0
  25. data/lib/dns/catalog_zone/output/file.rb +57 -0
  26. data/lib/dns/catalog_zone/output/stdout.rb +41 -0
  27. data/lib/dns/catalog_zone/prefixes.rb +45 -0
  28. data/lib/dns/catalog_zone/provider.rb +46 -0
  29. data/lib/dns/catalog_zone/provider/base.rb +66 -0
  30. data/lib/dns/catalog_zone/provider/knot.rb +278 -0
  31. data/lib/dns/catalog_zone/provider/nsd.rb +106 -0
  32. data/lib/dns/catalog_zone/provider/yadifa.rb +139 -0
  33. data/lib/dns/catalog_zone/source.rb +47 -0
  34. data/lib/dns/catalog_zone/source/axfr.rb +54 -0
  35. data/lib/dns/catalog_zone/source/base.rb +59 -0
  36. data/lib/dns/catalog_zone/source/file.rb +49 -0
  37. data/lib/dns/catalog_zone/version.rb +27 -0
  38. data/lib/dns/catalog_zone/zone.rb +39 -0
  39. data/share/CatalogZone +24 -0
  40. data/share/knotd-catalog.sh +32 -0
  41. data/share/nsd-catalog.sh +37 -0
  42. data/share/yadifad-catalog.sh +34 -0
  43. metadata +183 -0
  44. metadata.gz.sig +0 -0
@@ -0,0 +1,125 @@
1
+ # The MIT License (MIT)
2
+ #
3
+ # Copyright (c) 2016 Manabu Sonoda
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ require 'digest/sha1'
24
+
25
+ module Dns
26
+ module CatalogZone
27
+ # for catalog zone
28
+ class CatalogZone
29
+ include Dns::CatalogZone
30
+ include Dns::CatalogZone::ZoneHelper
31
+
32
+ attr_reader :masters, :notifies, :allow_transfers
33
+ attr_reader :zones
34
+
35
+ # initialize zone
36
+ def initialize(zonename, rrsets)
37
+ @rrsets = rrsets
38
+ @zonename = Dnsruby::Name.create(zonename).to_s + '.'
39
+ @zones = {}
40
+ @templates = {}
41
+ @masters = {}
42
+ @notifies = {}
43
+ @allow_transfers = {}
44
+
45
+ version_name = Dnsruby::Name.create("version.#{@zonename}")
46
+ masters_name = Dnsruby::Name.create("masters.#{@zonename}")
47
+ notifies_name = Dnsruby::Name.create("notifies.#{@zonename}")
48
+ transfer_name = Dnsruby::Name.create("allow-transfer.#{@zonename}")
49
+
50
+ @rrsets.each do |rr|
51
+ # version
52
+ if rr.name == version_name && rr.type == Dnsruby::Types::TXT
53
+ @version = rr.strings.join('')
54
+ end
55
+ # global master option
56
+ add_masters(rr, '.') if rr.name == masters_name
57
+ add_masters(rr, rr.name.labels[0]) if rr.name.subdomain_of?(masters_name)
58
+
59
+ # global notify option
60
+ add_notifies(rr, '.') if rr.name == notifies_name
61
+ add_notifies(rr, rr.name.labels[0]) if rr.name.subdomain_of?(notifies_name)
62
+
63
+ # global allow-transfer option
64
+ add_allow_transfers(rr, '.') if rr.name == transfer_name
65
+ add_allow_transfers(rr, rr.name.labels[0]) if rr.name.subdomain_of?(transfer_name)
66
+ end
67
+ case @version
68
+ when '1'
69
+ parse_v1
70
+ else
71
+ raise ValidateError, "#{@version} is unknown Catalog zone schema version"
72
+ end
73
+ end
74
+
75
+ private
76
+
77
+ def parse_zones
78
+ zones_str = Dnsruby::Name.create("zones.#{@zonename}")
79
+ # step 1 load zones
80
+ @rrsets.each do |rr|
81
+ next unless rr.name.subdomain_of?(zones_str)
82
+ next unless rr.type == Dnsruby::Types::PTR
83
+ mhash = Digest::SHA1.hexdigest(rr.domainname.canonical)
84
+ if mhash != rr.name.labels[0].to_s
85
+ raise ValidateError, "#{rr.name.labels[0]} PTR #{mhash} is not equal hash."
86
+ end
87
+ @zones[rr.name.labels[0].to_s] = Dns::CatalogZone::Zone.new(rr.domainname)
88
+ end
89
+ end
90
+
91
+ def parse_zones_options
92
+ zones_name = Dnsruby::Name.create("zones.#{@zonename}")
93
+ @rrsets.each do |rr|
94
+ next unless rr.name.subdomain_of?(zones_name)
95
+ label = type = mhash = nil
96
+ if @zones[rr.name.labels[1].to_s]
97
+ label = '.'
98
+ type = rr.name.labels[0].to_s
99
+ mhash = rr.name.labels[1].to_s
100
+ elsif @zones[rr.name.labels[2].to_s]
101
+ label = rr.name.labels[0].to_s
102
+ type = rr.name.labels[1].to_s
103
+ mhash = rr.name.labels[2].to_s
104
+ end
105
+
106
+ case type
107
+ when 'masters'
108
+ @zones[mhash].add_masters(rr, label)
109
+ when 'notifies'
110
+ @zones[mhash].add_notifies(rr, label)
111
+ when 'allow-transfer'
112
+ @zones[mhash].add_allow_transfers(rr, label)
113
+ end
114
+ end
115
+ end
116
+
117
+ def parse_v1
118
+ # step 1 load zones
119
+ parse_zones
120
+ # step 2 load options
121
+ parse_zones_options
122
+ end
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,88 @@
1
+ # The MIT License (MIT)
2
+ #
3
+ # Copyright (c) 2016 Manabu Sonoda
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ require 'dns/catalog_zone'
24
+ require 'thor'
25
+
26
+ # The Cli class is used to catz cli application
27
+ module Dns
28
+ module CatalogZone
29
+ class Cli < Thor
30
+ desc 'init', 'initializes a new environment by creating a CatalogZone'
31
+ def init(_zonename = 'catalog.example', _type = 'file')
32
+ unless File.exist? 'CatalogZone'
33
+ FileUtils.cp Dns::CatalogZone.root_path + '/share/CatalogZone', 'CatalogZone'
34
+ end
35
+ end
36
+ desc 'list', 'list setting'
37
+ def list
38
+ read_config
39
+ puts "name\tsource\tsoftware\tzonename\n"
40
+ @config.settings.each do |setting|
41
+ puts "#{setting.name}\t#{setting.source}\t" \
42
+ "#{setting.software}\t\t#{setting.zonename}\n"
43
+ end
44
+ end
45
+ desc 'checkconf [setting]', 'check config'
46
+ def checkconf(name = nil)
47
+ read_config
48
+ @config.settings.each do |setting|
49
+ next unless name == setting.name || name.nil?
50
+ setting.validate
51
+ end
52
+ end
53
+ desc 'make [setting]', 'make config file'
54
+ def make(name = nil)
55
+ read_config
56
+ @config.settings.each do |setting|
57
+ next unless name == setting.name || name.nil?
58
+ setting.validate
59
+ catalog_zone = make_CatalogZone(setting)
60
+ provider = make_config(setting, catalog_zone)
61
+ output(setting, provider)
62
+ end
63
+ end
64
+
65
+ private
66
+
67
+ def read_config
68
+ @config = Dns::CatalogZone::Config.read
69
+ end
70
+
71
+ def make_CatalogZone(setting)
72
+ source = Dns::CatalogZone::Source.create(setting)
73
+ Dns::CatalogZone::CatalogZone.new(setting.zonename, source.get)
74
+ end
75
+
76
+ def make_config(setting, catalog_zone)
77
+ provider = Dns::CatalogZone::Provider.create(setting)
78
+ provider.make(catalog_zone)
79
+ provider
80
+ end
81
+
82
+ def output(setting, provider)
83
+ output = Dns::CatalogZone::Output.create(setting)
84
+ output.output(provider.write)
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,83 @@
1
+ # The MIT License (MIT)
2
+ #
3
+ # Copyright (c) 2016 Manabu Sonoda
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ module Dns
24
+ module CatalogZone
25
+ # The Setting class is basic config class
26
+ class Setting
27
+ def initialize(name)
28
+ @attributes = { 'name' => name, 'software' => 'nsd',
29
+ 'source' => 'file', 'output' => 'stdout',
30
+ 'zonename' => 'catalog.example', 'zonepath' => '%s',
31
+ 'output_path' => 'catalog.conf', 'port' => 53,
32
+ 'timeout' => 30 }
33
+ end
34
+
35
+ def method_missing(method_name, *params)
36
+ name = method_name.to_s
37
+ if (md = name.to_s.match(/([a-zA-Z0-9][a-zA-Z0-9_-]*[a-zA-Z0-9])=$/))
38
+ @attributes[md[1]] = params[0]
39
+ elsif name.to_s =~ /([a-zA-Z0-9][a-zA-Z0-9_-]*[a-zA-Z0-9])$/
40
+ @attributes[name]
41
+ else
42
+ raise ValidateError
43
+ end
44
+ end
45
+
46
+ def validate
47
+ Source.create(self).validate
48
+ Provider.create(self).validate
49
+ Output.create(self).validate
50
+ end
51
+ end
52
+
53
+ # The Config class is aggregative config class
54
+ class Config
55
+ attr_reader :settings
56
+ class << self
57
+ def read(filename = 'CatalogZone')
58
+ raise ConfigNotFound unless File.exist?(filename)
59
+ config = Config.new
60
+ config_str = ''
61
+ File.open(filename) do |file|
62
+ config_str = file.read
63
+ end
64
+ config.instance_eval config_str, filename
65
+ config
66
+ end
67
+ end
68
+ def initialize
69
+ @settings = []
70
+ end
71
+
72
+ def setting(name)
73
+ setting = Setting.new(name)
74
+ yield(setting)
75
+ @settings.push(setting)
76
+ end
77
+
78
+ def validate
79
+ @settings.each(&:validate)
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,32 @@
1
+ # The MIT License (MIT)
2
+ #
3
+ # Copyright (c) 2016 Manabu Sonoda
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ module Dns
24
+ module CatalogZone
25
+ class ConfigNotFound < RuntimeError; end
26
+ class ValidateError < RuntimeError; end
27
+ class CantOutput < RuntimeError; end
28
+ class AxfrError < RuntimeError; end
29
+ class TimeoutError < RuntimeError; end
30
+ class ZonePraseError < RuntimeError; end
31
+ end
32
+ end
@@ -0,0 +1,98 @@
1
+ # The MIT License (MIT)
2
+ #
3
+ # Copyright (c) 2016 Manabu Sonoda
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ require 'camelizable'
24
+ require 'digest/sha1'
25
+
26
+ # add camelizable
27
+ class String
28
+ include Camelizable
29
+ end
30
+
31
+ module Dns
32
+ # CatalogZone module
33
+ module CatalogZone
34
+ class << self
35
+ def root_path
36
+ File.expand_path('../../../../', __FILE__)
37
+ end
38
+
39
+ # %s zone name
40
+ # %h zone hash
41
+ # %S(1) first character %S(2) second character %S(3) third character
42
+ # %L(1) top label %L(2) second label
43
+ # %H(1) zone name hash 1 character
44
+ # %H(2) zone name hash 2 character
45
+ def convert_path(format, zonename)
46
+ mhash = Digest::SHA1.hexdigest(zonename.canonical)
47
+ path = format.clone
48
+ path.gsub!(/%S\(1\)/, zonename.to_s[0])
49
+ path.gsub!(/%S\(2\)/, zonename.to_s[1])
50
+ path.gsub!(/%S\(3\)/, zonename.to_s[2])
51
+ path.gsub!(/%L\(1\)/, zonename.labels[zonename.labels.size - 1].to_s)
52
+ path.gsub!(/%L\(2\)/, zonename.labels[zonename.labels.size - 2].to_s)
53
+ path.gsub!(/%H\(1\)/, mhash[0])
54
+ path.gsub!(/%H\(2\)/, mhash[1])
55
+ path.gsub!(/%s/, zonename.to_s)
56
+ path.gsub!(/%h/, mhash)
57
+ path
58
+ end
59
+ end
60
+ def host_rr?(rr)
61
+ rr.type == Dnsruby::Types.A || rr.type == Dnsruby::Types.AAAA
62
+ end
63
+
64
+ def txt_rr?(rr)
65
+ rr.type == Dnsruby::Types.TXT
66
+ end
67
+
68
+ def ptr_rr?(rr)
69
+ rr.type == Dnsruby::Types.PTR
70
+ end
71
+
72
+ def apl_rr?(rr)
73
+ rr.type == Dnsruby::Types.APL
74
+ end
75
+ end
76
+ end
77
+
78
+ module Dns
79
+ module CatalogZone
80
+ # ZoneHelper module
81
+ module ZoneHelper
82
+ def add_masters(rr, label)
83
+ @masters[label] = Dns::CatalogZone::Master.new unless @masters[label]
84
+ @masters[label].parse_master(rr)
85
+ end
86
+
87
+ def add_notifies(rr, label)
88
+ @notifies[label] = Dns::CatalogZone::Master.new unless @notifies[label]
89
+ @notifies[label].parse_master(rr)
90
+ end
91
+
92
+ def add_allow_transfers(rr, label)
93
+ @allow_transfers[label] = Dns::CatalogZone::Prefixes.new unless @allow_transfers[label]
94
+ @allow_transfers[label].parse_apl(rr)
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,47 @@
1
+ # The MIT License (MIT)
2
+ #
3
+ # Copyright (c) 2016 Manabu Sonoda
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ module Dns
24
+ module CatalogZone
25
+ # Master class
26
+ class Master
27
+ include Dns::CatalogZone
28
+ attr_accessor :tsig, :port
29
+ attr_reader :addresses
30
+ def initialize(addresses = [], port = 53, tsig = nil)
31
+ @addresses = addresses
32
+ @port = port
33
+ @tsig = tsig
34
+ end
35
+
36
+ def add_address(address)
37
+ @addresses.push(address)
38
+ self
39
+ end
40
+
41
+ def parse_master(rr)
42
+ add_address(rr.rdata_to_string) if host_rr?(rr)
43
+ self.tsig = rr.strings.join('') if txt_rr?(rr)
44
+ end
45
+ end
46
+ end
47
+ end