From bcac69c2616ad2017c069812e94d1df1282343c1 Mon Sep 17 00:00:00 2001
From: Anders Blomdell <anders.blomdell@control.lth.se>
Date: Tue, 13 May 2014 17:08:21 +0200
Subject: [PATCH] Version 2014-05-13 17:08

M  src/hostinfo/automount.py
M  src/hostinfo/dhcpd.py
M  src/hostinfo/dhcpd_ipv6.py
M  src/hostinfo/ifconfig.py
M  src/hostinfo/named.py
M  src/hostinfo/util.py
---
 src/hostinfo/automount.py  |  2 +-
 src/hostinfo/dhcpd.py      |  7 ++--
 src/hostinfo/dhcpd_ipv6.py | 73 +++++++++++++++++++++++++-------------
 src/hostinfo/ifconfig.py   | 16 ++++-----
 src/hostinfo/named.py      |  2 ++
 src/hostinfo/util.py       |  1 -
 6 files changed, 64 insertions(+), 37 deletions(-)

diff --git a/src/hostinfo/automount.py b/src/hostinfo/automount.py
index 4b2a24f..fb15f53 100755
--- a/src/hostinfo/automount.py
+++ b/src/hostinfo/automount.py
@@ -13,7 +13,7 @@ def auto_map(tree, map_name, auto_domain):
         if e.map[1] == map_name:
             host = e.name[2]
             key = e.key[0]
-            if auto_domain:
+            if not host.endswith('.') and auto_domain:
                 host += auto_domain
             path = '/'.join([e.root[1], e.path[0]])
             if key in where:
diff --git a/src/hostinfo/dhcpd.py b/src/hostinfo/dhcpd.py
index 766c513..492f8b9 100755
--- a/src/hostinfo/dhcpd.py
+++ b/src/hostinfo/dhcpd.py
@@ -91,9 +91,9 @@ class "pxeclient" {
     filename "pxelinux.0";
   }
 }
-class "non-pxeclient" {
-  match if substring (option vendor-class-identifier, 0, 9) != "PXEClient";
-  ignore booting;
+class "anaconda" {
+  match if substring (option vendor-class-identifier, 0, 14) = "anaconda-Linux";
+  next-server %(next_server)s;
 }"""
 
 PXE_DENY="""
@@ -225,6 +225,7 @@ def emit_network(tree, options, subnet, dhcp):
                 result.append_lines("""
                   |  pool {
                   |    allow members of "pxeclient";
+                  |    allow members of "anaconda";
                   |    range %(first)s %(last)s;
                   |  }""" % dict(first=first, last=last))
                 pass
diff --git a/src/hostinfo/dhcpd_ipv6.py b/src/hostinfo/dhcpd_ipv6.py
index 3511a03..cbda7cf 100755
--- a/src/hostinfo/dhcpd_ipv6.py
+++ b/src/hostinfo/dhcpd_ipv6.py
@@ -86,10 +86,10 @@ def emit_network(tree, options, subnet, dhcp):
 def emit_subnet_info(subnet):
     result = util.StringArray()
     if subnet.domain[0]:
-        result += "option domain-name \"%s\";" % subnet.domain[0]
+        result += "option dhcp6.domain-search \"%s\";" % subnet.domain[0]
         pass
     if subnet.name_servers[0]:
-        result += "option dhcp6.domain-name-servers %s;" % (
+        result += "option dhcp6.name-servers %s;" % (
             subnet.name_servers[0])
         pass
     if subnet.ntp_servers[0]:
@@ -102,51 +102,76 @@ def emit_hosts(tree, options, net):
     result = util.StringArray()
     static = {}
     never = {}
+    def match(a):
+        return filter(lambda n: a in n, [net])
     for ip in tree._host_._interface_._ipv6_:
         # Find all hosts that associated with this network
         ethernet = ip.ethernet[0:]
         if not ethernet:
             continue
-        assert ethernet.lower() == ethernet, '%s not lower-case' % ethernet
+        if ethernet.lower() != ethernet:
+            raise util.HostinfoException('%s not lower-case' % ethernet)
         if ip.never[0]:
-            a = util.address(ip.never[0])
-            if a in net:
-                never[ip.name[0:]] =ip
+            if match(util.address(ip.never[0])):
+                if not ethernet in never:
+                    never[ethernet] = []
+                    pass
+                never[ethernet].append(ip)
                 pass
-            pass
-        else:
-            a = util.address(ip)
-            if a in net:
-                static[ip.name[0:]] = ip
+            continue
+        if match(util.address(ip)):
+            if not ethernet in static:
+                static[ethernet] = []
                 pass
+            static[ethernet].append(ip)
+            continue
+        pass
+    def by_name(ether_ip_dict):
+        result = {}
+        for e in ether_ip_dict:
+            name = set(map(lambda n: n.name[0:], ether_ip_dict[e]))
+            if len(name) != 1:
+                raise util.HostinfoException('Multiple names %s' % name,
+                                             where=ether_ip_dict[e])
+            name = name.pop()
+            key = '%s_%s' % (name, e)
+            result[key] = (name, e, ether_ip_dict[e])
+            pass
+        for key in sorted(result):
+            name, ether, ip = result[key]
+            yield name, ether, ip
             pass
         pass
+
     if static:
         result.append_lines("""
           |group { # Static hosts
           |  default-lease-time 315360000; # 10 year
           |  max-lease-time     315360000; # 10 years
           |""")
-        for h in sorted(static):
+        for name, ether, ip in by_name(static):
             result.append_lines("""
-              |  host %(name)s {
+              |  host %(id)s {
               |    hardware ethernet %(ethernet)s;
               |    fixed-address6 %(address)s;
               |    option host-name "%(name)s";
-              |  }""" % dict(name=h, 
-                             ethernet=static[h].ethernet[0:],
-                             address=util.address(static[h])))
+              |  }""" % dict(id='%s_%s' % (name, ether.replace(':','')),
+                             name=name, 
+                             ethernet=ether,
+                             address=', '.join(map(str, 
+                                                   map(util.address, ip)))))
         result += "}"
         pass
     if never:
-        result.append_lines("""
-          |group { # Disallowed hosts
-          |  ignore booting;
-          |""")
-        for h in sorted(never):
-            result.append(
-                '  host never_%(name)s { hardware ethernet %(ether)s; }' %
-                dict(name=h, ether=never[h].ethernet[0:]))
+        result += 'group { # Disallowed hosts'
+        for name, ether, ip in by_name(never):
+            if ether in never: never.pop(ether)
+            result.append_lines("""
+              |  host %(name)s { 
+              |    hardware ethernet %(ethernet)s; 
+              |    ignore booting;
+              |  }""" % dict(name='%s_never_%s' % (name, ether.replace(':','')),
+                             ethernet=ether))
         result += "}"
        
     return result
diff --git a/src/hostinfo/ifconfig.py b/src/hostinfo/ifconfig.py
index 6eb2051..0086e91 100755
--- a/src/hostinfo/ifconfig.py
+++ b/src/hostinfo/ifconfig.py
@@ -18,17 +18,17 @@ def get_uuid(device):
 
 
 def is_static(interface):
-    if not interface._dhcpserver_ and not interface._static_:
-        for ip in interface._ip_:
-            if ip.address[0] and not (ip.alias[0] or ip.vlan[0]):
-                return False
-                pass
-            pass
-        pass
-    return True
+    if interface._static_:
+        return True
+    if interface._ip_._dhcpserver_:
+        return True
+    if interface._ipv6_._dhcpserver_:
+        return True
+    return False
     
 def generate_ifcfgv4(tree, interface, search, nameservers):
     config = []
+    
     if not is_static(interface):
         config.append('BOOTPROTO=dhcp')
         pass
diff --git a/src/hostinfo/named.py b/src/hostinfo/named.py
index 2a90372..5be3abe 100755
--- a/src/hostinfo/named.py
+++ b/src/hostinfo/named.py
@@ -140,6 +140,8 @@ class DomainDict:
             pass
 
         def add_host(self, name, kind, value):
+            if not re.match('^[0-9a-zA-Z.-]+$', name):
+                raise Exception('Invalid nameserver name "%s"' % name)
             if not name in self.host:
                 self.host[name] = set()
                 pass
diff --git a/src/hostinfo/util.py b/src/hostinfo/util.py
index 908fcc5..9dc39dd 100755
--- a/src/hostinfo/util.py
+++ b/src/hostinfo/util.py
@@ -104,7 +104,6 @@ class StringArray(list, object):
             lines = other.split('\n')
             if len(lines[-1]) == 0:
                 lines.pop()
-                print '#! ', lines
                 pass
             self.extend(lines)
             pass
-- 
GitLab