import ipaddress
from pdtools.lib.output import out
from .base import ConfigObject
from .command import Command
[docs]def get_all_dhcp_interfaces(allConfigs):
for key in allConfigs.keys():
if key[0] == "dhcp":
yield allConfigs[key].interface
[docs]class ConfigDhcp(ConfigObject):
typename = "dhcp"
options = [
{"name": "interface", "type": str, "required": True, "default": None},
{"name": "leasetime", "type": str, "required": True, "default": "12h"},
{"name": "limit", "type": int, "required": True, "default": 150},
{"name": "start", "type": int, "required": True, "default": 100},
{"name": "dhcp_option", "type": list, "required": False, "default": ""}
]
[docs]class ConfigDnsmasq(ConfigObject):
typename = "dnsmasq"
options = [
{"name": "interface", "type": list, "required": False, "default": None},
{"name": "noresolv", "type": bool, "required": False, "default": False},
{"name": "server", "type": list, "required": False, "default": None}
]
[docs] def commands(self, allConfigs):
commands = list()
leaseFile = "{}/dnsmasq-{}.leases".format(
self.manager.writeDir, self.name)
pidFile = "{}/dnsmasq-{}.pid".format(
self.manager.writeDir, self.name)
outputPath = "{}/dnsmasq-{}.conf".format(
self.manager.writeDir, self.name)
with open(outputPath, "w") as outputFile:
outputFile.write("#" * 80 + "\n")
outputFile.write("# dnsmasq configuration file generated by "
"pdconfd\n")
outputFile.write("# Source: {}\n".format(self.source))
outputFile.write("# Section: config {} {}\n".format(
ConfigDhcp.typename, self.name))
outputFile.write("#" * 80 + "\n")
outputFile.write("\n")
outputFile.write("dhcp-leasefile={}\n".format(leaseFile))
if self.noresolv:
outputFile.write("no-resolv\n")
if self.server:
for server in self.server:
outputFile.write("server={}\n".format(server))
if self.interface is None:
interfaces = get_all_dhcp_interfaces(allConfigs)
else:
interfaces = self.interface
# TODO: Bind interfaces allows us to have multiple instances of
# dnsmasq running, but it would probably be better to have one
# running and reconfigure it when we want to add or remove
# interfaces. It is not very disruptive to reconfigure and restart
# dnsmasq.
outputFile.write("\n")
outputFile.write("except-interface=lo\n")
outputFile.write("bind-interfaces\n")
for intfName in interfaces:
interface = self.lookup(allConfigs, "interface", intfName)
outputFile.write("\n")
outputFile.write("# Options for section interface {}\n".
format(interface.name))
outputFile.write("interface={}\n".format(interface.ifname))
network = ipaddress.IPv4Network(u"{}/{}".format(
interface.ipaddr, interface.netmask), strict=False)
dhcp = self.lookup(allConfigs, "dhcp", intfName)
# TODO: Error checking!
firstAddress = network.network_address + dhcp.start
lastAddress = firstAddress + dhcp.limit
outputFile.write("\n")
outputFile.write("# Options for section dhcp {}\n".
format(interface.name))
outputFile.write("dhcp-range={},{},{}\n".format(
str(firstAddress), str(lastAddress), dhcp.leasetime))
# Write options sections to the config file.
if dhcp.dhcp_option:
for option in dhcp.dhcp_option:
outputFile.write("dhcp-option={}\n".format(option))
cmd = ["/apps/bin/dnsmasq", "--conf-file={}".format(outputPath),
"--pid-file={}".format(pidFile)]
commands.append(Command(Command.PRIO_START_DAEMON, cmd, self))
self.pidFile = pidFile
return commands
[docs] def undoCommands(self, allConfigs):
commands = list()
try:
with open(self.pidFile, "r") as inputFile:
pid = inputFile.read().strip()
cmd = ["kill", pid]
commands.append(Command(Command.PRIO_START_DAEMON, cmd, self))
except:
# No pid file --- maybe dnsmasq was not running?
out.warn("File not found: {}\n".format(
self.pidFile))
return []
return commands