Source code for paradrop.backend.pdconfd.config.dhcp

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