diff --git a/src/hostinfo/dhcpd.py b/src/hostinfo/dhcpd.py index a315a7309a0042ea9c2a81fd334209539af86adf..c255d7db507289725b29777b8ee6b4a55df1294a 100755 --- a/src/hostinfo/dhcpd.py +++ b/src/hostinfo/dhcpd.py @@ -48,105 +48,142 @@ class "AppleNBI-ppc" { def conf(tree, dhcphost): # - # A. Check if host is a dhcpserver + # A. Get interfaces to serve # - emit = False + interface = [] for ds in tree._host_._interface_._dhcpserver_: if dhcphost in ds.name[0::1]: - # Given host is a dhcpserver - dhcphost = ds.name[0:] + # Host is dhcpserver for this interface dhcpip = ds.ip[0:] - emit = True - - if not emit: + interface.append(ds._parent) + if not interface: raise Exception("%s is not a dhcpserver" % dhcphost) + # + # B. Emit header + # result = "ddns-update-style none;\n" result += "authoritative;\n" result += MacOS_NETBOOT(dhcpip) - for n in tree._subnet_: - if not n.network[0]: - continue - netmask = aton(n.netmask[0]) - subnet = aton(n.network[0]) & netmask - static = {} - dynamic = {} - emit = None - for i in tree._host_._interface_: - # Find all hosts that belong to this network - if i.ip[0]: - net = aton(i.ip[0]) & netmask - if net == subnet: - if i.name[0:] == dhcphost: - emit = i._dhcpserver_ - if i.dynamic[0] == dhcphost: - # Dynamic address served by this host - dynamic[aton(i.ip[0])] = i - else: - static[i.name[0:]] = i - if not emit: - continue - result += "subnet %s netmask %s {\n" % (n.network[0], n.netmask[0]) - result += " option subnet-mask %s;\n" % n.netmask[0] - if n.broadcast[0]: - result += " option broadcast-address %s;\n" % n.broadcast[0] - if n.gateway[0]: - result += " option routers %s;\n" % n.gateway[0] - if n.domain[0]: - result += " option domain-name \"%s\";\n" % n.domain[0] - if n.name_servers[0]: - result += " option domain-name-servers %s;\n" % n.name_servers[0] + # + # C. Emit subnet declarations for each interface + # + for i in interface: + address = [] + if i.ip[0]: + # Main address + address.append(i.ip[0]) + for ip in i._ip_: + # Alias addresses + if ip.address[0]: + address.append(ip.address[0]) - # - # Emit dynamic hosts - # - result += " default-lease-time 604800; # One week\n" - result += " max-lease-time 604800;\n" - dk = dynamic.keys() - dk.sort() - min = 0 - max = 0 - for d in dk: - if d == max + 1: - max = d - else: - if min: - result += " range %s %s;\n" % (ntoa(min), ntoa(max)) - min = d - max = d - if min: - result += " range %s %s;\n" % (ntoa(min), ntoa(max)) - result += " get-lease-hostnames true;\n" - result += " use-host-decl-names on;\n" + # Collect subnets for this interface + network = {} + for n in tree._subnet_: + if not n.network[0]: + continue + netmask = aton(n.netmask[0]) + subnet = aton(n.network[0]) & netmask + for a in address: + if aton(a) & netmask == subnet: + network[ntoa(subnet)] = n - # - # Emit static hosts - # - result += "\n group {\n" - result += " default-lease-time 315360000; # 10 year\n" - result += " max-lease-time 315360000; # 10 years\n\n" - - sk = static.keys() - sk.sort() - for i in [static[x] for x in sk]: - ether = i.ethernet[0] - ip = i.ip[0] - if ether: - result += " host %s.%s {\n"% (i.name[0:], n.domain[0]) - result += " hardware ethernet %s;\n" % ether - result += " fixed-address %s;\n" % ip - result += " option host-name \"%s\";\n" % i.name[0:] - if i._kickstart_: - kf = i._kickstart_[0].file[0] - result += " server-name \"%s\";\n" % dhcphost - result += " next-server %s;\n" % dhcphost - result += " filename \"/local/kickstart/%s\";\n" % kf - for d in i._dhcp_: - result += " %s\n" % d.value[0] - result += " }\n" - + # Emit subnet declarations + if len(network.keys()) > 1: + # Multiple networks served on this interface + result += 'shared-network "MAC(%s)" {\n\n' % i.ethernet[0] + for n in network.values(): + for l in emit_subnet(tree, n, dhcphost).split("\n"): + result += " %s\n" % l + result += "}\n" + else: + result += emit_subnet(tree, network.values()[0], dhcphost) + + return result + +def emit_subnet(tree, n, dhcphost): + result = "" + + netmask = aton(n.netmask[0]) + subnet = aton(n.network[0]) & netmask + static = {} + dynamic = {} + + for i in tree._host_._interface_: + # Find all hosts that belong to this network + if i.ip[0]: + net = aton(i.ip[0]) & netmask + if net == subnet: + if i.dynamic[0] == dhcphost: + # Dynamic address served by this host + dynamic[aton(i.ip[0])] = i + else: + static[i.name[0:]] = i - result += " }\n" - result += "}\n\n" + result += "subnet %s netmask %s {\n" % (n.network[0], n.netmask[0]) + result += " option subnet-mask %s;\n" % n.netmask[0] + if n.broadcast[0]: + result += " option broadcast-address %s;\n" % n.broadcast[0] + if n.gateway[0]: + result += " option routers %s;\n" % n.gateway[0] + if n.domain[0]: + result += " option domain-name \"%s\";\n" % n.domain[0] + if n.name_servers[0]: + result += " option domain-name-servers %s;\n" % ( + n.name_servers[0]) + + # + # Emit dynamic hosts + # + result += " default-lease-time 604800; # One week\n" + result += " max-lease-time 604800;\n" + dk = dynamic.keys() + dk.sort() + min = 0 + max = 0 + for d in dk: + if d == max + 1: + max = d + else: + if min: + result += " range %s %s;\n" % (ntoa(min), ntoa(max)) + min = d + max = d + if min: + result += " range %s %s;\n" % (ntoa(min), ntoa(max)) + result += " get-lease-hostnames true;\n" + result += " use-host-decl-names on;\n" + + # + # Emit static hosts + # + result += "\n group {\n" + result += " default-lease-time 315360000; # 10 year\n" + result += " max-lease-time 315360000; # 10 years\n\n" + + sk = static.keys() + sk.sort() + for i in [static[x] for x in sk]: + ether = i.ethernet[0] + ip = i.ip[0] + if ether: + result += " host %s.%s {\n"% (i.name[0:], n.domain[0]) + result += " hardware ethernet %s;\n" % ether + result += " fixed-address %s;\n" % ip + result += " option host-name \"%s\";\n" % i.name[0:] + if i._kickstart_: + kf = i._kickstart_[0].file[0] + result += " server-name \"%s\";\n" % dhcphost + result += " next-server %s;\n" % dhcphost + result += " filename \"/local/kickstart/%s\";\n" % kf + for d in i._dhcp_: + result += " %s\n" % d.value[0] + result += " }\n" + + + result += " }\n" + result += "}\n" + return result