dns-sniper 0.0.1.pre4 → 0.0.1.pre5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0d15d70b6571fb7db1cd3b4e53c4eac7a6041c0d08072c47309d8202dc5569d3
4
- data.tar.gz: 5dadb99daabfd7896735c94ac8981a70df077f73daa3f52f4bbc50570c6efd32
3
+ metadata.gz: 61bc06052722d5ac53448692a1c4cfb8e52a86ebe41fe2ef3973b5f36a0ff1da
4
+ data.tar.gz: '058667f512cdaa447c377325a0cc17df712f05c0d1aac2d82c09337f1faa2b3b'
5
5
  SHA512:
6
- metadata.gz: 4eac165aa45a6056690e69f2a5ebe939996a8b7364d0ebecd953827c8d3c20f112e9e8fd4cf42421d16771d0084fdb23c12e52dddba50911dbd9d8e61f8797e7
7
- data.tar.gz: 6e6a4e723a92e90ce128e893172395fc3f66333aac3e9d0eda03c7f2f98fbb8f5d559cde4c25540b78b476c032e9e78af698cfc52e156b5dbabbbf5ba5697a3e
6
+ metadata.gz: a2ab89c5edd6fa0ee2be7fee4078859ee15b4af1f8598ea12cc4925103d6155d0ddc1d2da313ada9b055635ec76dcf5c6cab1a2be3d3a1a45e6bd12f2fcb53f2
7
+ data.tar.gz: 05d1dc924c958d1172da20cce2795498c60c33278db0738fbf0b1bed4539b28ab291a8f6fd7aa3b64db010b3ffa1a7f58ee872cb936705114e4c7819b43ae225
@@ -5,19 +5,16 @@ require 'optparse'
5
5
  require 'set'
6
6
  require 'dns-sniper'
7
7
 
8
- VALID_FORMATS = DNSSniper::Formatters.all.inject([]) { |arr, f| arr << f.name.to_s.sub('DNSSniper::', '').downcase }
9
- Options = Struct.new(:blacklist_urls_file, :whitelisted_hosts_file, :format)
8
+ VALID_FORMATS = DNSSniper::Exporters.all.inject([]) { |arr, f| arr << f.name.to_s.sub('DNSSniper::', '').sub('Exporter', '').downcase }
9
+ Options = Struct.new(:conf_path, :format)
10
10
 
11
11
  class Parser
12
12
  def self.parse(options)
13
13
  args = Options.new('world')
14
14
  opt_parser = OptionParser.new do |opts|
15
15
  opts.banner = "Usage: #{File.basename(__FILE__)} -f PATH -o FORMAT [options]\n#{File.basename(__FILE__)} combines online DNS blacklists and combines them into the desired configuration FORMAT.\n\n"
16
- opts.on('-f', '--blacklist=PATH', 'PATH to file with line-separated list of URL’s of blacklists') do |path|
17
- args.blacklist_urls_file = path
18
- end
19
- opts.on('-w', '--whitelist=path', 'Path to file with line-separated list of whitelisted hostnames') do |path|
20
- args.whitelisted_hosts_file = path
16
+ opts.on('-c', '--conf=PATH', 'PATH to YAML configuration file') do |path|
17
+ args.conf_path = path
21
18
  end
22
19
  opts.on('-o', '--output=FORMAT', "FORMAT to output — one of #{VALID_FORMATS.join(', ')}") do |format|
23
20
  args.format = format
@@ -34,20 +31,20 @@ end
34
31
 
35
32
  options = Parser.parse ARGV
36
33
 
37
- unless VALID_FORMATS.include?(options[:format])
38
- warn options[:format].blank? ? 'Error: Format not defined' : "Error: Invalid format \"#{options[:format]}\""
34
+ unless File.exist?(options[:conf_path])
35
+ warn "Error: Unable to access ”#{options[:conf_path]}"
39
36
  exit(-1)
40
37
  end
41
38
 
42
- unless File.exist?(options[:blacklist_urls_file])
43
- warn "Error: Unable to access ”#{options[:blacklist_urls_file]}”"
44
- exit(-1)
45
- end
46
-
47
- if options[:whitelisted_hosts_file] && !File.exist?(options[:whitelisted_hosts_file])
48
- warn "Error: Unable to access ”#{options[:whitelisted_hosts_file]}”"
39
+ exporter = DNSSniper.const_get("#{options[:format].to_s.split('_').map(&:capitalize).join}Exporter")
40
+ if !exporter
41
+ warn "Error: Invalid format #{options[:format]}"
49
42
  exit(-1)
50
43
  end
51
44
 
52
45
  hostnames = DNSSniper::Hostnames.new
53
- puts hostnames.add_from(File.open(options[:blacklist_urls_file]).readlines).remove_from(options[:whitelisted_hosts_file]).to_format(options[:format])
46
+ hostnames.blacklist += DNSSniper::ConfigurationImporter.new(options[:conf_path], list: :reject).hostnames
47
+ hostnames.whitelist += DNSSniper::ConfigurationImporter.new(options[:conf_path], list: :allow).hostnames
48
+
49
+ exporter = exporter.new(hostnames.blocklist)
50
+ puts exporter.data
@@ -3,8 +3,8 @@
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = 'dns-sniper'
5
5
  spec.license = 'MIT'
6
- spec.version = '0.0.1.pre4'
7
- spec.date = '2020-11-01'
6
+ spec.version = '0.0.1.pre5'
7
+ spec.date = '2020-11-10'
8
8
 
9
9
  spec.authors = ['Brody Hoskins']
10
10
  spec.email = ['brody@brody.digital']
@@ -1,5 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'resolv'
4
+ require 'yaml'
5
+
6
+ require 'dns-sniper/exporter'
7
+ require 'dns-sniper/exporters'
3
8
  require 'dns-sniper/hostnames'
4
- require 'dns-sniper/formatter'
5
- require 'dns-sniper/formatters'
9
+ require 'dns-sniper/importer'
10
+ require 'dns-sniper/importers'
@@ -1,13 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DNSSniper
4
- class Formatter
4
+ class Exporter
5
+ attr_accessor :data, :hostnames
6
+
5
7
  def initialize(hostnames, options = {})
6
8
  @hostnames = hostnames
7
- @options = options
9
+ @data = output(options)
8
10
  end
9
11
 
10
- def output
12
+ def output(*)
11
13
  raise NotImplementedError, "Error: #output isn’t supported by #{self.class.name}"
12
14
  end
13
15
  end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DNSSniper
4
+ module Exporters
5
+ module_function
6
+
7
+ attr_reader :registered
8
+ @registered = []
9
+
10
+ def register(class_name, autoload_require)
11
+ DNSSniper.autoload(class_name, autoload_require)
12
+ @registered << class_name
13
+ end
14
+
15
+ def all
16
+ @registered.map { |name| DNSSniper.const_get(name) }
17
+ end
18
+
19
+ def find(name)
20
+ all.find { |c| c.name.downcase == name.to_s.downcase } or raise NameError, "Unknown exporter \"#{name}\""
21
+ end
22
+ end
23
+ end
24
+
25
+ DNSSniper::Exporters.register :Bind8Exporter, 'dns-sniper/exporters/bind8_exporter'
26
+ DNSSniper::Exporters.register :DnsmasqExporter, 'dns-sniper/exporters/dnsmasq_exporter'
27
+ DNSSniper::Exporters.register :HostsExporter, 'dns-sniper/exporters/hosts_exporter'
28
+ DNSSniper::Exporters.register :NetgearExporter, 'dns-sniper/exporters/netgear_exporter'
29
+ DNSSniper::Exporters.register :TextExporter, 'dns-sniper/exporters/text_exporter'
30
+ DNSSniper::Exporters.register :UnboundExporter, 'dns-sniper/exporters/unbound_exporter'
@@ -1,12 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DNSSniper
4
- class Bind8 < Formatter
5
- def initialize(hostnames, options = {})
6
- @hostnames = hostnames
7
- @options = options
8
- end
9
-
4
+ class Bind8Exporter < Exporter
10
5
  def output(options = {})
11
6
  raise ArgumentError, 'zone_file is required' unless defined?(options[:zone_file])
12
7
 
@@ -1,13 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DNSSniper
4
- class Dnsmasq < Formatter
5
- def initialize(hostnames, options = {})
6
- @hostnames = hostnames
7
- @options = options
8
- end
9
-
10
- def output(_options = {})
4
+ class DnsmasqExporter < Exporter
5
+ def output(*)
11
6
  str = ''.dup
12
7
  @hostnames.each do |hostname|
13
8
  str << "server=/#{hostname}/#{$/}"
@@ -1,13 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DNSSniper
4
- class Hosts < Formatter
5
- def initialize(hostnames, options = {})
6
- @hostnames = hostnames
7
- @options = options
8
- end
9
-
10
- def output(_options = {})
4
+ class HostsExporter < Exporter
5
+ def output(*)
11
6
  str = ''.dup
12
7
  @hostnames.each do |hostname|
13
8
  str << "127.0.0.1\t#{hostname}#{$/}"
@@ -1,13 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DNSSniper
4
- class Netgear < Formatter
5
- def initialize(hostnames, options = {})
6
- @hostnames = hostnames
7
- @options = options
8
- end
9
-
10
- def output(_options = {})
4
+ class NetgearExporter < Exporter
5
+ def output(*)
11
6
  str = ''.dup
12
7
  @hostnames.each_with_index do |hostname, i|
13
8
  str << "[517003_e]: #{i + 1}) #{hostname}\n"
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DNSSniper
4
+ class TextExporter < Exporter
5
+ def output(_options = {})
6
+ @hostnames.to_a.join($/)
7
+ end
8
+ end
9
+ end
@@ -1,13 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DNSSniper
4
- class Unbound < Formatter
5
- def initialize(hostnames, options = {})
6
- @hostnames = hostnames
7
- @options = options
8
- end
9
-
10
- def output(_options = {})
4
+ class UnboundExporter < Exporter
5
+ def output(*)
11
6
  str = ''.dup
12
7
  str << "server:#{$/}"
13
8
  @hostnames.each do |hostname|
@@ -7,152 +7,28 @@ require 'resolv'
7
7
 
8
8
  module DNSSniper
9
9
  class Hostnames
10
- def initialize(_options = {})
11
- @hostnames = [].to_set
12
- self
13
- end
10
+ attr_accessor :blacklist
11
+ attr_accessor :whitelist
14
12
 
15
- def add(hostnames)
16
- hostnames = clean(hostnames.class == String ? [hostnames] : hostnames)
17
- @hostnames += hostnames unless hostnames.empty?
13
+ def initialize
14
+ @blacklist = [].to_set
15
+ @whitelist = [].to_set
18
16
  self
19
17
  end
20
18
 
21
- def add_from(paths_or_urls)
22
- return self unless paths_or_urls
23
-
24
- paths_or_urls = [paths_or_urls] if paths_or_urls.class == String
25
-
26
- paths_or_urls.each do |path_or_url|
27
- path_or_url.chomp!
28
-
29
- if File.exist?(path_or_url)
30
- contents = File.open(path_or_url).readlines(chomp: true)
31
- else
32
- begin
33
- down = Down.download(path_or_url)
34
- path_or_url = down.path
35
- contents = down.readlines(chomp: true)
36
- rescue Down::InvalidUrl
37
- warn "\"#{path_or_url}\" does not exist, nor is it a valid URL"
38
- rescue Down::NotFound
39
- warn "\"#{path_or_url}\" does not exist"
40
- return self
41
- rescue Down::ResponseError
42
- warn "\"#{path_or_url}\": No data from server"
43
- return self
44
- end
45
- end
19
+ def blocklist
20
+ blacklist = @blacklist
21
+ whitelist = @whitelist
46
22
 
47
- case syntax(path_or_url, contents)
48
- when nil
49
- warn "Error: Syntax: Syntax of \"#{path_or_url}\" not recognized, ignored"
50
- return self
51
- when 'hosts'
52
- add from_hosts_file(path_or_url)
53
- when 'hostnames'
54
- add from_hostnames_file(contents)
23
+ whitelist.each do |domain|
24
+ domain_parts = domain.split('.')
25
+ domain_parts.count.times do |count|
26
+ next if count == 1
27
+ whitelist += [domain_parts[count - 1, domain_parts.length].join('.')]
55
28
  end
56
29
  end
57
30
 
58
- self
59
- end
60
-
61
- def remove(hostnames)
62
- hostnames = clean(hostnames.class == String ? [hostnames] : hostnames)
63
- @hostnames -= hostnames unless hostnames.empty?
64
- self
65
- end
66
-
67
- def remove_from(paths_or_urls)
68
- return self unless paths_or_urls
69
-
70
- paths_or_urls = [paths_or_urls] if paths_or_urls.class == String
71
-
72
- paths_or_urls.each do |path_or_url|
73
- path_or_url = path_or_url.strip
74
-
75
- if File.exist?(path_or_url)
76
- contents = File.open(path_or_url).readlines
77
- else
78
- begin
79
- down = Down.download(path_or_url)
80
- path_or_url = down.path
81
- contents = down.readlines
82
- rescue Down::NotFound
83
- warn "\"#{path_or_url}\" does not exist"
84
- return self
85
- rescue Down::ResponseError
86
- warn "\"#{path_or_url}\": No data from server"
87
- return self
88
- end
89
- end
90
-
91
- case syntax(path_or_url, contents)
92
- when nil
93
- warn "Error: Syntax: Syntax of \"#{path_or_url}\" not recognized, ignored"
94
- return self
95
- when 'hosts'
96
- remove from_hosts_file(path_or_url)
97
- when 'hostnames'
98
- remove from_hostnames_file(contents)
99
- end
100
- end
101
-
102
- self
103
- end
104
-
105
- def to_format(format, options = {})
106
- format = format.capitalize
107
- begin
108
- klass = DNSSniper.const_get(format)
109
- klass.new(@hostnames.to_a).output(options)
110
- rescue NameError
111
- false
112
- end
113
- end
114
-
115
- def to_a
116
- @hostnames.to_a
117
- end
118
-
119
- private
120
-
121
- def clean(hostnames)
122
- cleaned_hostnames = []
123
- hostnames.each do |hostname|
124
- hostname = hostname.downcase.strip
125
- hostname = hostname.sub('www.', '')
126
- hostname_top_domain = "#{hostname.split('.')[-2]}.#{hostname.split('.')[-1]}"
127
-
128
- if !hostname.include?('#') && !['broadcasthost', 'localhost', ''].include?(hostname) && !@hostnames.include?(hostname_top_domain)
129
- cleaned_hostnames << hostname
130
- end
131
- end
132
- cleaned_hostnames
133
- end
134
-
135
- def syntax(path_or_url, contents)
136
- contents.each do |line|
137
- next if line.include?('#')
138
-
139
- line = line.downcase
140
- if line.strip.split(/\s/).first =~ Regexp.union([Resolv::IPv4::Regex, Resolv::IPv6::Regex])
141
- return 'hosts'
142
- elsif line.include?('.') && !URI.parse(line).is_a?(URI::HTTP)
143
- return 'hostnames'
144
- end
145
- end
146
- nil
147
- end
148
-
149
- def from_hosts_file(path_or_url)
150
- # TODO: Remove downloading file twice
151
- HostsFile.load(path_or_url).map(&:name)
152
- end
153
-
154
- def from_hostnames_file(contents)
155
- contents.each { |line| add(line) }
31
+ blacklist - whitelist
156
32
  end
157
33
  end
158
34
  end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DNSSniper
4
+ class Importer
5
+ attr_accessor :uri, :hostnames
6
+
7
+ def initialize(uri, *)
8
+ @uri = uri
9
+ @hostnames = File.exist?(uri) ? import_file(uri) : import_uri(uri)
10
+ end
11
+
12
+ def import_file(*)
13
+ raise NotImplementedError, "#{self.class.name}: #import_file not supported"
14
+ end
15
+
16
+ def import_uri(*)
17
+ raise NotImplementedError, "#{self.class.name}: #import_uri not supported"
18
+ end
19
+
20
+ # Helper methods
21
+
22
+ def clean(domain)
23
+ domain = domain.split('#')[0] if domain[0] != '#' && domain.include?('#')
24
+ domain = domain.split(':')[0] if domain.include?(':') && !ip_addr?(domain)
25
+ domain = domain.sub('www.', '') if domain.start_with?('www.') && domain.scan('www.').count == 1
26
+
27
+ domain.chomp.gsub(/\s+/, '').downcase
28
+ end
29
+
30
+ def rejector(domain)
31
+ !domain?(domain)
32
+ end
33
+
34
+ def domain?(domain)
35
+ return false if domain == ''
36
+ return false if domain.gsub('#', '').gsub(/\s+/, '').empty?
37
+ return false if domain[0] == '#'
38
+ return false unless domain.include?('.')
39
+ return false if domain.include?(':')
40
+ return false if ip_addr?(domain)
41
+ return false unless /\b((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\b/.match?(domain)
42
+
43
+ begin
44
+ return false if URI.parse(domain).is_a?(URI::HTTP)
45
+ rescue URI::InvalidURIError; end
46
+ true
47
+ end
48
+
49
+ def ip_addr?(domain)
50
+ domain =~ Regexp.union([Resolv::IPv4::Regex, Resolv::IPv6::Regex])
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DNSSniper
4
+ module Importers
5
+ module_function
6
+
7
+ attr_reader :registered
8
+ @registered = []
9
+
10
+ def register(class_name, autoload_require)
11
+ DNSSniper.autoload(class_name, autoload_require)
12
+ @registered << class_name
13
+ end
14
+
15
+ def all
16
+ @registered.map { |name| DNSSniper.const_get(name) }
17
+ end
18
+
19
+ def find(name)
20
+ all.find { |c| c.name.downcase == name.to_s.downcase } or raise NameError, "Unknown Importer \"#{name}\""
21
+ end
22
+ end
23
+ end
24
+
25
+ DNSSniper::Importers.register :ConfigurationImporter, 'dns-sniper/importers/configuration_importer'
26
+ DNSSniper::Importers.register :DomainsImporter, 'dns-sniper/importers/domains_importer'
27
+ DNSSniper::Importers.register :HostsImporter, 'dns-sniper/importers/hosts_importer'
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DNSSniper
4
+ class ConfigurationImporter < Importer
5
+ def initialize(uri, list:)
6
+ @uri = uri
7
+ @hostnames = File.exist?(uri) ? import_file(uri, list: list) : import_uri(uri, list: list)
8
+ end
9
+
10
+ def import_file(path, list:)
11
+ raise ArgumentError, "#{self.class.name}: #from_path requies list to be defined" unless list
12
+ return [].to_set unless File.exist?(path)
13
+
14
+ yaml = YAML.safe_load(File.read(path), permitted_classes: [Symbol])
15
+ return [].to_set unless yaml.dig(:sources)&.dig(list.to_sym)
16
+
17
+ hostnames = [].to_set
18
+ yaml.dig(:sources).dig(list.to_sym).each do |source|
19
+ return [].to_set unless source.dig(:importer)
20
+ return [].to_set unless source.dig(:uri)
21
+
22
+ importer = DNSSniper.const_get("#{source.dig(:importer).to_s.split('_').map(&:capitalize).join}Importer")
23
+ if !importer
24
+ next
25
+ else
26
+ importer = importer.new(source.dig(:uri))
27
+ hostnames += importer.hostnames
28
+ end
29
+ end
30
+
31
+ hostnames
32
+ end
33
+
34
+ def import_uri(_uri, list:)
35
+ raise NotImplementedError, "#{self.class.name}: #from_uri not supported"
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DNSSniper
4
+ class DomainsImporter < Importer
5
+ def import_file(path)
6
+ return [].to_set unless File.exist?(path)
7
+
8
+ File.open(path).readlines(chomp: true).map { |hostname| clean(hostname) }.reject { |hostname| rejector(hostname) }.to_set
9
+ end
10
+
11
+ def import_uri(uri)
12
+ begin
13
+ down = Down.download(uri)
14
+ return down.readlines(chomp: true).map { |hostname| clean(hostname) }.reject { |hostname| rejector(hostname) }.to_set
15
+ rescue Down::InvalidUrl => e
16
+ warn "#{self.class.name}: #{e}"
17
+ end
18
+
19
+ [].to_set
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DNSSniper
4
+ class HostsImporter < Importer
5
+ def import_file(path, *)
6
+ return [].to_set unless File.exist?(path)
7
+
8
+ HostsFile.load(path).map(&:name).map { |hostname| clean(hostname) }.reject { |hostname| rejector(hostname) }.to_set
9
+ end
10
+
11
+ def import_uri(uri, *)
12
+ begin
13
+ down = Down.download(uri)
14
+ path = down.path
15
+ rescue Down::InvalidUrl => e
16
+ warn "#{self.class.name}: #{e}"
17
+ end
18
+
19
+ if path
20
+ return HostsFile.load(path).map(&:name).map { |hostname| clean(hostname) }.reject { |hostname| rejector(hostname) }.to_set
21
+ end
22
+
23
+ [].to_set
24
+ end
25
+ end
26
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dns-sniper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.pre4
4
+ version: 0.0.1.pre5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brody Hoskins
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-01 00:00:00.000000000 Z
11
+ date: 2020-11-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: down
@@ -56,15 +56,20 @@ files:
56
56
  - bin/dns-sniper
57
57
  - dns-sniper.gemspec
58
58
  - lib/dns-sniper.rb
59
- - lib/dns-sniper/formatter.rb
60
- - lib/dns-sniper/formatters.rb
61
- - lib/dns-sniper/formatters/bind8.rb
62
- - lib/dns-sniper/formatters/dnsmasq.rb
63
- - lib/dns-sniper/formatters/hosts.rb
64
- - lib/dns-sniper/formatters/netgear.rb
65
- - lib/dns-sniper/formatters/text.rb
66
- - lib/dns-sniper/formatters/unbound.rb
59
+ - lib/dns-sniper/exporter.rb
60
+ - lib/dns-sniper/exporters.rb
61
+ - lib/dns-sniper/exporters/bind8_exporter.rb
62
+ - lib/dns-sniper/exporters/dnsmasq_exporter.rb
63
+ - lib/dns-sniper/exporters/hosts_exporter.rb
64
+ - lib/dns-sniper/exporters/netgear_exporter.rb
65
+ - lib/dns-sniper/exporters/text_exporter.rb
66
+ - lib/dns-sniper/exporters/unbound_exporter.rb
67
67
  - lib/dns-sniper/hostnames.rb
68
+ - lib/dns-sniper/importer.rb
69
+ - lib/dns-sniper/importers.rb
70
+ - lib/dns-sniper/importers/configuration_importer.rb
71
+ - lib/dns-sniper/importers/domains_importer.rb
72
+ - lib/dns-sniper/importers/hosts_importer.rb
68
73
  homepage: https://github.com/brodyhoskins/dns-sniper
69
74
  licenses:
70
75
  - MIT
@@ -1,30 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module DNSSniper
4
- module Formatters
5
- extend self
6
-
7
- attr_reader :registered
8
- @registered = []
9
-
10
- def register(class_name, autoload_require)
11
- DNSSniper.autoload(class_name, autoload_require)
12
- @registered << class_name
13
- end
14
-
15
- def all
16
- @registered.map { |name| DNSSniper.const_get(name) }
17
- end
18
-
19
- def find(name)
20
- all.find { |c| c.name.downcase == name.to_s.downcase } or raise NameError, "Unknown formatter \"#{name}\""
21
- end
22
- end
23
- end
24
-
25
- DNSSniper::Formatters.register :Bind8, 'dns-sniper/formatters/bind8'
26
- DNSSniper::Formatters.register :Dnsmasq, 'dns-sniper/formatters/dnsmasq'
27
- DNSSniper::Formatters.register :Hosts, 'dns-sniper/formatters/hosts'
28
- DNSSniper::Formatters.register :Netgear, 'dns-sniper/formatters/netgear'
29
- DNSSniper::Formatters.register :Text, 'dns-sniper/formatters/text'
30
- DNSSniper::Formatters.register :Unbound, 'dns-sniper/formatters/unbound'
@@ -1,14 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module DNSSniper
4
- class Text < Formatter
5
- def initialize(hostnames, options = {})
6
- @hostnames = hostnames
7
- @options = options
8
- end
9
-
10
- def output(_options = {})
11
- @hostnames.to_a.join($/)
12
- end
13
- end
14
- end