smart_proxy_dhcp_dnsmasq 0.4 → 0.6

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
  SHA1:
3
- metadata.gz: 97a5371cbd074b39c66bd23b907b1b31730beb0b
4
- data.tar.gz: 47b63b6d25aca90f3dcf03d442efca03493084d8
3
+ metadata.gz: 64fb30133ada0a818bdf665a6488a4373f317144
4
+ data.tar.gz: 60dd83f0e023802e77b59d54ba75bdd1ec40e75c
5
5
  SHA512:
6
- metadata.gz: 5495631faaeaa74b84b6123fe2fb33f7f6bee3ec3f8b1a26e6901f70eee55bd31050b68ca50eb4afb94a46b5729ac8b636923a55c85365928280327ad8f9cf4d
7
- data.tar.gz: 54d43f53f1a2d9d6bc1026d71dd5521060161da1d4d3ed13b27c365c8d0dbad0f019e179d377a241878aecee473fc28cb77c25b14d37328639a3a9abb7cd1793
6
+ metadata.gz: 11665804f753f83922fbbabd1551b08c415b5910439f4a00319115794bbf4dd97cb472e1f75be48f5c091ab9cc3e1464c840956ecdb7bdec7da26698a4065e90
7
+ data.tar.gz: eb8ae2512a23f5924d15dd0a7b89c50b555fdbfe809f45daab0e8e3f6368a5aa8523fa85d59978c947ba3688c95cb5fe17546ed1e054001370fcc6ac5965e42e
data/README.md CHANGED
@@ -10,6 +10,14 @@ for how to install Smart Proxy plugins
10
10
 
11
11
  This plugin is compatible with Smart Proxy 1.15 or higher.
12
12
 
13
+ You need to add two lines to your dnsmasq configuration to use this plugin;
14
+ ```
15
+ dhcp-optsfile=<target_dir>/dhcpopts.conf
16
+ dhcp-hostsfile=<target_dir>/dhcphosts
17
+ ```
18
+
19
+ Dnsmasq will also require write privileges to the configuration file and folder specified.
20
+
13
21
  ## Configuration
14
22
 
15
23
  To enable this DNS provider, edit `/etc/foreman-proxy/settings.d/dhcp.yml` and set:
@@ -18,10 +26,10 @@ To enable this DNS provider, edit `/etc/foreman-proxy/settings.d/dhcp.yml` and s
18
26
 
19
27
  Configuration options for this plugin are in `/etc/foreman-proxy/settings.d/dhcp_dnsmasq.yml` and include:
20
28
 
21
- * `config_files`: The path to the configuration files to load, changes will be written to the last one unless a `write_config_file` is provided.
22
- * `lease_file`: The path to the lease file. (*optional if `dhcp-leasefile` is set in one of the config files*)
29
+ * `config`: The path to the configuration directory to load, changes will be written to host-specific configuration files inside
30
+ * `target_dir`: The path of where dhcp files should be written, must have write permissions for the proxy user.
31
+ * `lease_file`: The path to the lease file. (*optional, will be auto-discovered if `dhcp-leasefile` is set in one of the config files*)
23
32
  * `reload_cmd`: The command to use for reloading the dnsmasq configuration.
24
- * `write_config_file`: The file to write any new changes to, the smart-proxy will only be able to remove any reservations made in this file.
25
33
 
26
34
  For best results, the write config should point to a file in a dnsmasq `conf-dir` which only the smart-proxy uses.
27
35
 
@@ -3,21 +3,25 @@
3
3
  # Configuration file for 'dhcp_dnsmasq' dhcp provider
4
4
  #
5
5
 
6
- # Configuration files to parse, writing any additional entries will be done to
7
- # the last of the files unless a specific write file is provided;
8
- #
9
- #:write_config_file: /etc/dnsmasq.d/hosts.conf
10
- :config_files:
11
- - /etc/dnsmasq.conf
12
- - /etc/dnsmasq.d/foreman.conf
6
+ # This pluing requires that the following options are set in your dnsmasq
7
+ # configuration;
8
+ # dhcp-optsfile=<target_dir>/dhcpopts.conf
9
+ # dhcp-hostsfile=<target_dir>/dhcphosts # NB: this line should not end in a slash
10
+
11
+ # Configuration files and directories to parse
12
+ :config: /etc/dnsmasq.conf
13
+ # Directory to write dhcp files into
14
+ :target_dir: /var/lib/foreman-proxy/dhcp/
15
+ # Dnsmasq DHCP lease file location
13
16
  :lease_file: /var/lib/dnsmasq/dhcp.leases
17
+ # Command to reload / SIGHUP dnsmasq
14
18
  :reload_cmd: systemctl reload dnsmasq
15
19
 
16
20
  # Example configuration for an OpenWRT router;
17
- #:config_files:
21
+ #:config:
18
22
  # - /tmp/etc/dnsmasq.conf
19
- # - /etc/dnsmasq.d/reservations.conf
23
+ # - /tmp/dnsmasq.d/
24
+ # - /etc/dnsmasq.conf
25
+ #:target_dir: /etc/foreman-proxy/dnsmasq_dhcp/
20
26
  #:lease_file: /tmp/dhcp.leases
21
27
  #:reload_cmd: /etc/init.d/dnsmasq reload
22
- #
23
- # This also requires that the conf-dir option is set in /etc/dnsmasq.conf
@@ -6,17 +6,21 @@ module ::Proxy::DHCP::Dnsmasq
6
6
  end
7
7
 
8
8
  def load_dependency_injection_wirings(container, settings)
9
- write_config = settings[:write_config_file] || settings[:config_files].last
10
-
11
9
  container.dependency :memory_store, ::Proxy::MemoryStore
10
+
12
11
  container.dependency :subnet_service, (lambda do
13
- ::Proxy::DHCP::Dnsmasq::SubnetService.new(settings[:config_files], settings[:lease_file],
12
+ ::Proxy::DHCP::Dnsmasq::SubnetService.new(
13
+ settings[:config], settings[:target_dir], settings[:lease_file],
14
14
  container.get_dependency(:memory_store),
15
15
  container.get_dependency(:memory_store), container.get_dependency(:memory_store),
16
- container.get_dependency(:memory_store), container.get_dependency(:memory_store))
16
+ container.get_dependency(:memory_store), container.get_dependency(:memory_store)
17
+ )
17
18
  end)
18
19
  container.dependency :dhcp_provider, (lambda do
19
- Proxy::DHCP::Dnsmasq::Record.new(settings[:config_files], write_config, settings[:reload_cmd], container.get_dependency(:subnet_service))
20
+ Proxy::DHCP::Dnsmasq::Record.new(
21
+ settings[:target_dir],
22
+ settings[:reload_cmd], container.get_dependency(:subnet_service)
23
+ )
20
24
  end)
21
25
  end
22
26
  end
@@ -4,62 +4,107 @@ require 'dhcp_common/server'
4
4
 
5
5
  module Proxy::DHCP::Dnsmasq
6
6
  class Record < ::Proxy::DHCP::Server
7
- attr_reader :config_files, :write_config_file, :reload_cmd, :subnet_service
7
+ attr_reader :config_dir, :reload_cmd, :subnet_service
8
8
 
9
- def initialize(config_files, write_config_file, reload_cmd, subnet_service)
10
- @config_files = config_files
11
- @write_config_file = write_config_file
9
+ def initialize(target_dir, reload_cmd, subnet_service)
10
+ @config_dir = target_dir
12
11
  @reload_cmd = reload_cmd
13
12
  @subnet_service = subnet_service
13
+ @optsfile_content = []
14
+
15
+ Dir.mkdir @config_dir unless Dir.exist? @config_dir
14
16
 
15
17
  subnet_service.load!
16
18
 
17
19
  super('localhost', nil, subnet_service)
18
20
  end
19
21
 
20
- def add_record(options={})
22
+ def add_record(options = {})
23
+ logger.debug "Adding record; #{options}"
21
24
  record = super(options)
22
25
  options = record.options
23
26
 
24
- open(@write_config_file, 'a') do |file|
25
- file.puts "dhcp-host=set:#{record.mac},#{record.mac},#{record.ip},#{record.name}"
26
- file.puts "dhcp-boot=tag:#{record.mac},#{options[:filename]},#{options[:nextServer]}" if\
27
- options[:filename] && options[:nextServer]
28
- end
29
-
30
- subnet_service.add_host(record)
27
+ tags = []
28
+ tags << ensure_bootfile(options[:filename]) if options[:filename]
29
+ tags << ensure_tftpserver(options[:nextServer]) if options[:nextServer]
30
+ tagstring = ",set:#{tags.join(',set:')}" unless tags.empty?
31
31
 
32
- raise Proxy::DHCP::Error, 'Failed to reload configuration' unless system(@reload_cmd)
32
+ hostspath = File.join(@config_dir, 'dhcphosts')
33
+ Dir.mkdir hostspath unless Dir.exist? hostspath
34
+ File.write(File.join(hostspath, "#{sanitize_string record.mac}.conf"),
35
+ "#{record.mac}#{tagstring},#{record.ip},#{record.name}\n")
36
+ subnet_service.add_host(record.subnet_address, record)
33
37
 
38
+ try_reload_cmd
34
39
  record
35
40
  end
36
41
 
37
42
  def del_record(record)
38
- # TODO: Removal of leases, to prevent DHCP record collisions
43
+ logger.debug "Deleting record; #{record}"
44
+ # TODO: Removal of leases, to prevent DHCP record collisions?
39
45
  return record if record.is_a? ::Proxy::DHCP::Lease
40
46
 
41
- found = false
42
- tmppath = nil
43
- Tempfile.open('reservations') do |output|
44
- tmppath = output.path.freeze
45
- open(@write_config_file, 'r').each_line do |line|
46
- output.puts line unless line.start_with?("dhcp-host=#{record.mac}") || \
47
- line.start_with?("dhcp-host=set:#{record.mac}") || \
48
- line.start_with?("dhcp-boot=tag:#{record.mac}")
49
-
50
- found = true if line.start_with?("dhcp-host=#{record.mac}") || \
51
- line.start_with?("dhcp-host=set:#{record.mac}")
52
- end
53
- end
54
- FileUtils.mv(tmppath, @write_config_file) if found
47
+ path = File.join(@config_dir, 'dhcphosts', "#{sanitize_string record.mac}.conf")
48
+ File.unlink(path) if File.exist? path
55
49
 
56
50
  subnet_service.delete_host(record)
57
51
 
58
- raise Proxy::DHCP::Error, 'Failed to reload configuration' unless system(@reload_cmd)
59
-
52
+ try_reload_cmd
60
53
  record
61
- ensure
62
- File.unlink(tmppath) if tmppath && File.exists?(tmppath)
54
+ end
55
+
56
+ def find_record_by_mac(subnet_address, mac_address)
57
+ get_subnet(subnet_address)
58
+ service.find_host_by_mac(subnet_address, mac_address) ||
59
+ service.find_host_by_mac(subnet_address, mac_address.downcase) ||
60
+ service.find_lease_by_mac(subnet_address, mac_address) ||
61
+ service.find_lease_by_mac(subnet_address, mac_address.downcase)
62
+ end
63
+
64
+ private
65
+
66
+ def try_reload_cmd
67
+ logger.debug 'Reloading DHCP configuration...'
68
+ raise Proxy::DHCP::Error, 'Failed to reload configuration' \
69
+ unless system(@reload_cmd)
70
+ end
71
+
72
+ def optsfile_content
73
+ path = File.join(@config_dir, 'dhcpopts.conf').freeze
74
+
75
+ @optsfile_content = open(path).readlines \
76
+ if File.exist?(path) && @optsfile_content.empty?
77
+ @optsfile_content
78
+ end
79
+
80
+ def append_optsfile(line)
81
+ path = File.join(@config_dir, 'dhcpopts.conf').freeze
82
+ logger.debug "Appending #{line} to dhcpopts.conf"
83
+
84
+ optsfile_content << line
85
+ File.write(path, optsfile_content.join("\n") + "\n")
86
+ end
87
+
88
+ def sanitize_string(string)
89
+ string.downcase.gsub(/[^0-9a-z]/, '_')
90
+ end
91
+
92
+ def ensure_bootfile(filename)
93
+ tagname = "bf_#{sanitize_string(filename)}"
94
+
95
+ append_optsfile "tag:#{tagname},option:bootfile-name,#{filename}" \
96
+ unless optsfile_content.find { |l| l.start_with? "tag:#{tagname}" }
97
+
98
+ tagname
99
+ end
100
+
101
+ def ensure_tftpserver(address)
102
+ tagname = "ns_#{sanitize_string(address)}"
103
+
104
+ append_optsfile "tag:#{tagname},option:tftp-server,#{address}" \
105
+ unless optsfile_content.find { |l| l.start_with? "tag:#{tagname}" }
106
+
107
+ tagname
63
108
  end
64
109
  end
65
110
  end
@@ -6,9 +6,13 @@ module Proxy::DHCP::Dnsmasq
6
6
  plugin :dhcp_dnsmasq, ::Proxy::DHCP::Dnsmasq::VERSION
7
7
 
8
8
  requires :dhcp, '>= 1.15'
9
- default_settings :config_files => [ '/etc/dnsmasq.d/foreman.conf' ],
9
+ default_settings :config=> '/etc/dnsmasq.conf',
10
+ :target_dir => '/var/lib/foreman-proxy/dhcp/',
11
+ :lease_file => '/var/lib/dnsmasq/dhcp.leases',
10
12
  :reload_cmd => 'systemctl reload dnsmasq'
11
13
 
14
+ validate_readable :lease_file
15
+
12
16
  load_classes ::Proxy::DHCP::Dnsmasq::PluginConfiguration
13
17
  load_dependency_injection_wirings ::Proxy::DHCP::Dnsmasq::PluginConfiguration
14
18
  end
@@ -7,10 +7,11 @@ module Proxy::DHCP::Dnsmasq
7
7
  class SubnetService < ::Proxy::DHCP::SubnetService
8
8
  include Proxy::Log
9
9
 
10
- attr_reader :config_file, :lease_file
10
+ attr_reader :config_dir, :lease_file
11
11
 
12
- def initialize(config_files, lease_file, leases_by_ip, leases_by_mac, reservations_by_ip, reservations_by_mac, reservations_by_name)
13
- @config_files = config_files
12
+ def initialize(config, target_dir, lease_file, leases_by_ip, leases_by_mac, reservations_by_ip, reservations_by_mac, reservations_by_name)
13
+ @config_paths = [config].flatten
14
+ @target_dir = target_dir
14
15
  @lease_file = lease_file
15
16
 
16
17
  super(leases_by_ip, leases_by_mac, reservations_by_ip, reservations_by_mac, reservations_by_name)
@@ -30,7 +31,7 @@ module Proxy::DHCP::Dnsmasq
30
31
  @inotify.watch(File.dirname(lease_file), :modify, :moved_to) do |ev|
31
32
  next unless ev.absolute_name == lease_file
32
33
 
33
- leases = load_leases(subnet_service)
34
+ leases = load_leases
34
35
 
35
36
  # FIXME: Proper method for this
36
37
  m.synchronize do
@@ -42,8 +43,16 @@ module Proxy::DHCP::Dnsmasq
42
43
  end
43
44
 
44
45
  def parse_config_for_subnet
45
- configuration = { }
46
- @config_files.each do |file|
46
+ configuration = {}
47
+ files = []
48
+ @config_paths.each do |path|
49
+ files << path if File.exist? path
50
+ files += Dir["#{path}/*"] if Dir.exist? path
51
+ end
52
+
53
+ logger.debug "Starting parse of DHCP subnets from #{files}"
54
+ files.each do |file|
55
+ logger.debug " Parsing #{file}..."
47
56
  open(file, 'r').each_line do |line|
48
57
  line.strip!
49
58
  next if line.empty? || line.start_with?('#') || !line.include?('=')
@@ -62,31 +71,30 @@ module Proxy::DHCP::Dnsmasq
62
71
  range_to = data.pop
63
72
  range_from = data.pop
64
73
 
65
- case ttl[-1]
66
- when 'h'
67
- ttl = ttl[0..-2].to_i * 60 * 60
68
- when 'm'
69
- ttl = ttl[0..-2].to_i * 60
70
- else
71
- ttl = ttl.to_i
72
- end
73
-
74
- configuration.merge! address: IPAddr.new("#{range_from}/#{mask}").to_s,
75
- mask: mask,
76
- range: [ range_from, range_to ],
77
- ttl: ttl
74
+ ttl = case ttl[-1]
75
+ when 'h'
76
+ ttl[0..-2].to_i * 60 * 60
77
+ when 'm'
78
+ ttl[0..-2].to_i * 60
79
+ else
80
+ ttl.to_i
81
+ end
82
+
83
+ configuration.merge! \
84
+ address: IPAddr.new("#{range_from}/#{mask}").to_s,
85
+ mask: mask,
86
+ range: [range_from, range_to],
87
+ ttl: ttl
78
88
  when 'dhcp-option'
79
89
  data = value.split(',')
80
90
 
81
91
  configuration[:options] = {} unless configuration.key? :options
82
92
 
83
- until data.empty? || /\A\d+\z/ === data.first
84
- data.shift
85
- end
93
+ data.shift until data.empty? || /\A\d+\z/ === data.first
86
94
  next if data.empty?
87
95
 
88
96
  code = data.shift.to_i
89
- option = ::Proxy::DHCP::Standard.select { |k, v| v[:code] == code }.first.first
97
+ option = ::Proxy::DHCP::Standard.select { |_k, v| v[:code] == code }.first.first
90
98
 
91
99
  data = data.first unless ::Proxy::DHCP::Standard[option][:is_list]
92
100
  configuration[:options][option] = data
@@ -94,14 +102,24 @@ module Proxy::DHCP::Dnsmasq
94
102
  end
95
103
  end
96
104
 
105
+ # TODO: Multiple subnets
106
+ logger.debug "Adding subnet with configuration; #{configuration}"
97
107
  @ttl = configuration[:ttl]
98
108
  ::Proxy::DHCP::Subnet.new(configuration[:address], configuration[:mask], configuration[:options])
99
109
  end
100
110
 
101
111
  # Expects subnet_service to have subnet data
102
- def parse_config_for_dhcp_reservations(files = @config_files)
112
+ def parse_config_for_dhcp_reservations
103
113
  to_ret = {}
114
+ files = []
115
+ @config_paths.each do |path|
116
+ files << path if File.exist? path
117
+ files += Dir[File.join(path), '*'] if Dir.exist? path
118
+ end
119
+
120
+ logger.debug "Starting parse of DHCP reservations from #{files}"
104
121
  files.each do |file|
122
+ logger.debug " Parsing #{file}..."
105
123
  open(file, 'r').each_line do |line|
106
124
  line.strip!
107
125
  next if line.empty? || line.start_with?('#') || !line.include?('=')
@@ -112,7 +130,7 @@ module Proxy::DHCP::Dnsmasq
112
130
  data = value.split(',')
113
131
  data.shift while data.first.start_with? 'set:'
114
132
 
115
- mac, ip, hostname = data[0,3]
133
+ mac, ip, hostname = data[0, 3]
116
134
 
117
135
  # TODO: Possible ttl on end
118
136
 
@@ -122,7 +140,7 @@ module Proxy::DHCP::Dnsmasq
122
140
  ip,
123
141
  mac,
124
142
  subnet,
125
- # :source_file => file # TODO: Needs to overload the comparison
143
+ # :source_file => file # TODO: Needs to overload the comparison
126
144
  )
127
145
  when 'dhcp-boot'
128
146
  data = value.split(',')
@@ -140,56 +158,104 @@ module Proxy::DHCP::Dnsmasq
140
158
  end
141
159
  end
142
160
  end
161
+ dhcpoptions = {}
162
+
163
+ dhcpopts_path = File.join(@target_dir, 'dhcpopts.conf')
164
+ logger.debug "Parsing DHCP options from #{dhcpopts_path}"
165
+ if File.exist? dhcpopts_path
166
+ open(dhcpopts_path, 'r').each_line do |line|
167
+ data = line.strip.split(',')
168
+ next if data.empty? || !data.first.start_with?('tag:')
169
+
170
+ tag = data.first[4..-1]
171
+ data.shift
172
+
173
+ dhcpoptions[tag] = data.last
174
+ end
175
+ end
176
+
177
+ logger.debug "Parsing provisioned DHCP reservations from #{@target_dir}"
178
+ Dir[File.join(@target_dir, 'dhcphosts', '*')].each do |file|
179
+ logger.debug " Parsing #{file}..."
180
+ open(file, 'r').each_line do |line|
181
+ data = line.strip.split(',')
182
+ next if data.empty? || data.first.start_with?('#')
183
+
184
+ mac = data.first
185
+ data.shift
186
+
187
+ options = { :deletable => true }
188
+ while data.first.start_with? 'set:'
189
+ tag = data.first[4..-1]
190
+ data.shift
191
+
192
+ value = dhcpoptions[tag]
193
+ next if value.nil?
194
+
195
+ options[:nextServer] = value if tag.start_with? 'ns'
196
+ options[:filename] = value if tag.start_with? 'bf'
197
+ end
198
+
199
+ ip, name = data
200
+ subnet = find_subnet(ip)
201
+
202
+ to_ret[mac] = ::Proxy::DHCP::Reservation.new(
203
+ name, ip, mac, subnet, options
204
+ )
205
+ end
206
+ end
207
+
143
208
  to_ret.values
144
- rescue Exception => e
209
+ rescue StandardError => e
145
210
  logger.error msg = "Unable to parse reservations: #{e}"
146
- raise Proxy::DHCP::Error, msg
211
+ raise Proxy::DHCP::Error, e, msg
147
212
  end
148
213
 
149
214
  def load_subnet_data
150
215
  reservations = parse_config_for_dhcp_reservations
151
216
  reservations.each do |record|
152
217
  if dupe = find_host_by_mac(record.subnet_address, record.mac)
153
- delete_host(dupe)
218
+ logger.debug "Found duplicate #{dupe} when adding record #{record}, skipping"
219
+ next
220
+ # delete_host(dupe)
154
221
  end
155
222
 
223
+ logger.debug "Adding host #{record}"
156
224
  add_host(record.subnet_address, record)
157
225
  end
158
226
 
159
227
  leases = [] # load_leases # FIXME: Will cause collisions if added
160
228
  leases.each do |lease|
161
229
  if dupe = find_lease_by_mac(lease.subnet_address, lease.mac)
162
- delete_lease(dupe)
230
+ logger.debug "Removing duplicate #{dupe} when adding lease #{lease}, skipping"
231
+ next
232
+ # delete_lease(dupe)
163
233
  end
164
234
  if dupe = find_lease_by_ip(lease.subnet_address, lease.ip)
165
- delete_lease(dupe)
235
+ logger.debug "Removing duplicate #{dupe} when adding lease #{lease}, skipping"
236
+ next
237
+ # delete_lease(dupe)
166
238
  end
167
239
 
240
+ logger.debug "Adding lease #{lease}"
168
241
  add_lease(lease.subnet_address, lease)
169
242
  end
170
243
  end
171
244
 
172
245
  # Expects subnet_service to have subnet data
173
246
  def load_leases
174
- leases = []
175
- open(@lease_file, 'r').each_line do |line|
176
- timestamp, mac, ip, hostname, client_id = line.split
177
-
247
+ open(@lease_file, 'r').readlines.map do |line|
248
+ timestamp, mac, ip, _hostname, _client_id = line.split
178
249
  timestamp = timestamp.to_i
179
250
 
180
251
  subnet = find_subnet(ip)
181
- leases << ::Proxy::DHCP::Lease.new(
182
- hostname,
183
- ip,
184
- mac,
185
- subnet,
186
- timestamp - (@ttl or 24*60*60),
252
+ ::Proxy::DHCP::Lease.new(
253
+ nil, ip, mac, subnet,
254
+ timestamp - (@ttl || 24 * 60 * 60),
187
255
  timestamp,
188
- 'active',
189
- deleteable: false,
256
+ 'active'
190
257
  )
191
258
  end
192
- leases
193
259
  end
194
260
  end
195
261
  end
@@ -1,7 +1,7 @@
1
1
  module Proxy
2
2
  module DHCP
3
3
  module Dnsmasq
4
- VERSION = '0.4'
4
+ VERSION = '0.6'.freeze
5
5
  end
6
6
  end
7
7
  end
@@ -5,7 +5,9 @@ require 'smart_proxy_dhcp_dnsmasq/dhcp_dnsmasq_plugin'
5
5
  class DnsDnsmasqDefaultSettingsTest < Test::Unit::TestCase
6
6
  def test_default_settings
7
7
  Proxy::DHCP::Dnsmasq::Plugin.load_test_settings({})
8
- assert_equal ["/etc/dnsmasq.d/foreman.conf"], Proxy::DHCP::Dnsmasq::Plugin.settings.config_files
9
- assert_equal "systemctl reload dnsmasq", Proxy::DHCP::Dnsmasq::Plugin.settings.reload_cmd
8
+ assert_equal '/etc/dnsmasq.conf', Proxy::DHCP::Dnsmasq::Plugin.settings.config
9
+ assert_equal '/var/lib/foreman-proxy/dhcp/', Proxy::DHCP::Dnsmasq::Plugin.settings.target_dir
10
+ assert_equal '/var/lib/dnsmasq/dhcp.leases', Proxy::DHCP::Dnsmasq::Plugin.settings.lease_file
11
+ assert_equal 'systemctl reload dnsmasq', Proxy::DHCP::Dnsmasq::Plugin.settings.reload_cmd
10
12
  end
11
13
  end
@@ -10,17 +10,20 @@ class DHCPDnsmasqProductionWiringTest < Test::Unit::TestCase
10
10
 
11
11
  def test_dns_provider_initialization_default
12
12
  Proxy::DHCP::Dnsmasq::SubnetService.any_instance.expects(:load!).returns(true)
13
+ Dir.expects(:exist?).with('/etc/dnsmasq.d/dhcp').returns(true)
13
14
 
14
- @config.load_dependency_injection_wirings(@container,
15
- :config_files => ['/etc/dnsmasq.conf'],
16
- :lease_file => '/tmp/dhcp.leases',
17
- :reload_cmd => 'systemctl reload dnsmasq')
15
+ @config.load_dependency_injection_wirings(
16
+ @container,
17
+ :config => '/etc/dnsmasq.conf',
18
+ :target_dir => '/etc/dnsmasq.d/dhcp',
19
+ :lease_file => '/tmp/dhcp.leases',
20
+ :reload_cmd => 'systemctl reload dnsmasq'
21
+ )
18
22
 
19
23
  provider = @container.get_dependency(:dhcp_provider)
20
24
 
21
25
  assert_not_nil provider
22
- assert_equal ['/etc/dnsmasq.conf'], provider.config_files
23
- assert_equal '/etc/dnsmasq.conf', provider.write_config_file
26
+ assert_equal '/etc/dnsmasq.d/dhcp', provider.config_dir
24
27
  assert_equal 'systemctl reload dnsmasq', provider.reload_cmd
25
28
  end
26
29
  end
@@ -0,0 +1,54 @@
1
+ require 'test_helper'
2
+ require 'smart_proxy_dhcp_dnsmasq/dhcp_dnsmasq_main'
3
+
4
+ class DHCPDnsmasqRecordHandlingTest < Test::Unit::TestCase
5
+ def setup
6
+ @subnet_service = mock
7
+ @subnet_service.expects(:load!).returns(true)
8
+ Dir.stubs(:exist?).returns(true)
9
+
10
+ @server = ::Proxy::DHCP::Dnsmasq::Record.new('/etc/dnsmasq.d/', '/bin/true', @subnet_service)
11
+ @server.instance_eval('@optsfile_content = []')
12
+ end
13
+
14
+ def test_add_record
15
+ subnet = ::Proxy::DHCP::Subnet.new('10.0.0.0', '255.0.0.0')
16
+ @subnet_service.stubs(:find_subnet).with('10.0.0.0').returns(subnet)
17
+ @subnet_service.stubs(:find_hosts_by_ip).returns(nil)
18
+ @subnet_service.stubs(:find_host_by_mac).returns(nil)
19
+ @subnet_service.stubs(:find_lease_by_ip).returns(nil)
20
+ @subnet_service.stubs(:find_lease_by_mac).returns(nil)
21
+
22
+ File.expects(:write).with(
23
+ '/etc/dnsmasq.d/dhcphosts/00_01_02_03_04_05.conf',
24
+ "00:01:02:03:04:05,set:bf_bootfile,set:ns_10_0_0_2,10.0.0.1,hostname\n"
25
+ )
26
+ @server.expects(:append_optsfile)
27
+ .with('tag:bf_bootfile,option:bootfile-name,bootfile').returns(true)
28
+ @server.expects(:append_optsfile)
29
+ .with('tag:ns_10_0_0_2,option:tftp-server,10.0.0.2').returns(true)
30
+ @subnet_service.expects(:add_host).returns(true)
31
+ @server.expects(:try_reload_cmd).returns(nil)
32
+
33
+ @server.add_record(
34
+ 'hostname' => 'hostname',
35
+ 'ip' => '10.0.0.1',
36
+ 'network' => '10.0.0.0',
37
+ 'mac' => '00:01:02:03:04:05',
38
+ filename: 'bootfile',
39
+ nextServer: '10.0.0.2'
40
+ )
41
+ end
42
+
43
+ def test_del_record
44
+ subnet = ::Proxy::DHCP::Subnet.new('10.0.0.0', '255.0.0.0')
45
+ host = ::Proxy::DHCP::Reservation.new('10.0.0.0', '255.0.0.0', '00:01:02:03:04:05', subnet)
46
+ @subnet_service.expects(:delete_host).with(host).returns(true)
47
+
48
+ File.expects(:exist?).with('/etc/dnsmasq.d/dhcphosts/00_01_02_03_04_05.conf').returns(true)
49
+ File.expects(:unlink).with('/etc/dnsmasq.d/dhcphosts/00_01_02_03_04_05.conf').returns(true)
50
+ @server.expects(:try_reload_cmd).returns(nil)
51
+
52
+ @server.del_record(host)
53
+ end
54
+ end
@@ -0,0 +1,33 @@
1
+ require 'test_helper'
2
+ require 'smart_proxy_dhcp_dnsmasq/dhcp_dnsmasq_subnet_service'
3
+
4
+ class DHCPDnsmasqSubnetServiceTest < Test::Unit::TestCase
5
+ def setup
6
+ @subnet_service = mock()
7
+ Dir.stubs(:exist?).returns(true)
8
+ end
9
+
10
+ def test_initialize
11
+ subnet = ::Proxy::DHCP::Subnet.new('10.0.0.0', '255.255.255.0')
12
+ host = ::Proxy::DHCP::Reservation.new('test', '10.0.0.10', 'ba:be:fa:ce:ca:fe', subnet)
13
+ lease = ::Proxy::DHCP::Lease.new('test', '10.0.0.10', 'ba:be:fa:ce:ca:fe', subnet, Time.now, Time.now + 1000, 'active')
14
+
15
+ initializer = Proxy::DHCP::Dnsmasq::SubnetService.new(
16
+ 'config/file', 'config/dir', 'lease/file',
17
+ ::Proxy::MemoryStore.new, ::Proxy::MemoryStore.new,
18
+ ::Proxy::MemoryStore.new, ::Proxy::MemoryStore.new,
19
+ ::Proxy::MemoryStore.new
20
+ )
21
+
22
+ initializer.expects(:add_subnet).with(subnet)
23
+ initializer.expects(:add_host)
24
+ # initializer.expects(:add_lease)
25
+
26
+ initializer.expects(:parse_config_for_subnet).returns(subnet)
27
+ initializer.expects(:parse_config_for_dhcp_reservations).returns([host])
28
+ # initializer.expects(:load_leases).returns([lease])
29
+ # initializer.expects(:add_watch)
30
+
31
+ initializer.load!
32
+ end
33
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smart_proxy_dhcp_dnsmasq
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.4'
4
+ version: '0.6'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Olofsson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-17 00:00:00.000000000 Z
11
+ date: 2017-08-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -71,7 +71,8 @@ files:
71
71
  - lib/smart_proxy_dhcp_dnsmasq/dhcp_dnsmasq_version.rb
72
72
  - test/dhcp_dnsmasq_default_settings_test.rb
73
73
  - test/dhcp_dnsmasq_production_wiring_test.rb
74
- - test/dhcp_dnsmasq_record_default_test.rb
74
+ - test/dhcp_dnsmasq_record_handling_test.rb
75
+ - test/dhcp_dnsmasq_subnet_service_test.rb
75
76
  - test/test_helper.rb
76
77
  homepage: https://github.com/ace13/smart_proxy_dhcp_dnsmasq
77
78
  licenses:
@@ -93,7 +94,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
93
94
  version: '0'
94
95
  requirements: []
95
96
  rubyforge_project:
96
- rubygems_version: 2.6.8
97
+ rubygems_version: 2.6.12
97
98
  signing_key:
98
99
  specification_version: 4
99
100
  summary: dnsmasq DHCP provider plugin for Foreman's smart proxy
@@ -101,4 +102,5 @@ test_files:
101
102
  - test/test_helper.rb
102
103
  - test/dhcp_dnsmasq_default_settings_test.rb
103
104
  - test/dhcp_dnsmasq_production_wiring_test.rb
104
- - test/dhcp_dnsmasq_record_default_test.rb
105
+ - test/dhcp_dnsmasq_record_handling_test.rb
106
+ - test/dhcp_dnsmasq_subnet_service_test.rb
@@ -1,26 +0,0 @@
1
- require 'test_helper'
2
- require 'smart_proxy_dhcp_dnsmasq/dhcp_dnsmasq_subnet_service'
3
-
4
- class DHCPDnsmasqSubnetServiceTest < Test::Unit::TestCase
5
- def setup
6
- @subnet_service = mock()
7
- end
8
-
9
- def test_initialize
10
- subnet = ::Proxy::DHCP::Subnet.new('10.0.0.0','255.255.255.0')
11
- host = ::Proxy::DHCP::Reservation.new('test','10.0.0.10','ba:be:fa:ce:ca:fe',subnet)
12
- lease = ::Proxy::DHCP::Lease.new('test','10.0.0.10','ba:be:fa:ce:ca:fe',subnet,Time.now,Time.now + 1000,'active')
13
-
14
- initializer = Proxy::DHCP::Dnsmasq::SubnetService.new('config/file', 'lease/file', ::Proxy::MemoryStore.new, ::Proxy::MemoryStore.new, ::Proxy::MemoryStore.new, ::Proxy::MemoryStore.new, ::Proxy::MemoryStore.new)
15
-
16
- initializer.expects(:add_subnet).with(subnet)
17
- initializer.expects(:add_host)
18
- initializer.expects(:add_lease)
19
-
20
- initializer.expects(:parse_config_for_subnet).returns(subnet)
21
- initializer.expects(:parse_config_for_dhcp_reservations).returns([ host ])
22
- initializer.expects(:load_leases).returns([ lease ])
23
- initializer.expects(:add_watch)
24
- initializer.load!
25
- end
26
- end