smart_proxy_dhcp_dnsmasq 0.4 → 0.6

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