From ca8404abed4888ada2b0bb4b8cd361b66084bde3 Mon Sep 17 00:00:00 2001
From: Anders Blomdell <anders.blomdell@control.lth.se>
Date: Fri, 6 Aug 2021 22:11:49 +0200
Subject: [PATCH] More work on network manager

---
 src/hostinfo.py                |  6 ++-
 src/hostinfo/networkmanager.py | 91 +++++++++++++++++++++++++++++-----
 2 files changed, 84 insertions(+), 13 deletions(-)

diff --git a/src/hostinfo.py b/src/hostinfo.py
index 9f45fdc..be3ec33 100755
--- a/src/hostinfo.py
+++ b/src/hostinfo.py
@@ -8,7 +8,11 @@ import hostinfo.ifconfig
 import hostinfo.macosx_auto
 import hostinfo.mio
 import hostinfo.named
-import hostinfo.networkmanager
+try:
+    import hostinfo.networkmanager
+except Exception as e:
+    print("Ignored:", e)
+    pass
 import hostinfo.parser
 import hostinfo.pxelinux
 import hostinfo.role
diff --git a/src/hostinfo/networkmanager.py b/src/hostinfo/networkmanager.py
index b6526f1..1dfd762 100644
--- a/src/hostinfo/networkmanager.py
+++ b/src/hostinfo/networkmanager.py
@@ -1,6 +1,7 @@
 import NetworkManager
 import dbus
 import hostinfo.util as util
+import re
 from copy import deepcopy
 
 def dict_get(d, *i):
@@ -14,7 +15,7 @@ def dict_get(d, *i):
 class Network(object):
 
     def __init__(self):
-        self._networks = []
+        self._networks = {}
         self.reload()
         pass
 
@@ -71,7 +72,7 @@ class Network(object):
         
     def parse_tree(self, tree):
         for s in filter(util.network, tree._subnet_):
-            self._networks.append(util.network(s))
+            self._networks[util.network(s)] = s
             pass
         pass
 
@@ -114,6 +115,40 @@ class Network(object):
                 pass
             raise Exception("No network found for", a)
         return None
+
+    def dns(self, ip):
+        result = []
+        for i in filter(None, [ util.address(i) for i in ip ]):
+            for n in filter(None, [ v.name_servers[0]
+                                    for (k,v) in self._networks.items()
+                                    if i in k ]):
+                result.extend(re.split('[, ]+', n))
+                pass
+            pass
+        return result
+    
+    def dns_search(self, ip):
+        result = []
+        for i in filter(None, [ util.address(i) for i in ip ]):
+            for s in filter(None, [ v.domain[0]
+                                    for (k,v) in self._networks.items()
+                                    if i in k ]):
+                result.append(s)
+                pass
+            pass
+        return result
+    
+    def gateway(self, ip):
+        result = None
+        for i in filter(None, [ util.address(i) for i in ip ]):
+            for g in filter(None, [ v.gateway[0]
+                                    for (k,v) in self._networks.items()
+                                    if i in k ]):
+                result = g
+                pass
+            pass
+        return result
+    
     pass
 
 network = Network()
@@ -142,22 +177,51 @@ def update_settings(settings, update):
     return result
 
 def configure_networking(connection, interface):
-    # Construct ipv4 and ipv6 data to be set in bridge
+    # Construct ipv4 and ipv6 data to be set on interface
     update = dict()
     if not interface._static_:
         update['ipv4', 'method'] = 'auto'
         update['ipv6', 'method'] = 'auto'
         update['ipv6', 'dhcp-duid'] = ipv6_dhcp_duid(interface)
+        if interface.defroute[0] == 'no':
+            update['ipv4', 'never-default'] = True
+            update['ipv6', 'never-default'] = True
+            pass
+        else:
+            update['ipv4', 'never-default'] = None
+            update['ipv6', 'never-default'] = None
+            pass
         pass
     else:
-        ipv4 = list(filter(None,
-                           [network.address_data(i) for i in interface._ip_]))
-        ipv6 = list(filter(None,
-                           [network.address_data(i) for i in interface._ipv6_]))
-        update['ipv4', 'address-data'] = ipv4
-        update['ipv6', 'address-data'] = ipv6
-        update['ipv4', 'method'] = ('link-local','manual')[len(ipv4) > 0]
-        update['ipv6', 'method'] = ('link-local','manual')[len(ipv6) > 0]
+        ipv4a = list(filter(None, [network.address_data(i)
+                                   for i in interface._ip_]))
+        ipv6a = list(filter(None, [network.address_data(i)
+                                   for i in interface._ipv6_]))
+        update['ipv4', 'address-data'] = ipv4a
+        update['ipv4', 'dns'] = network.dns(interface._ip_)
+        update['ipv4', 'dns-search'] = network.dns_search(interface._ip_)
+        update['ipv4', 'method'] = ('disabled','manual')[len(ipv4a) > 0]
+        update['ipv6', 'address-data'] = ipv6a
+        update['ipv6', 'dns'] = network.dns(interface._ipv6_)
+        update['ipv6', 'dns-search'] = network.dns_search(interface._ipv6_)
+        update['ipv6', 'method'] = ('disabled','manual')[len(ipv6a) > 0]
+        #if interface.bridge[0] or interface.defroute[0] == 'no':
+        #    # Bridges seems to be unable to accept gateways...
+        if interface.defroute[0] == 'no':
+            # Bridges seems to be unable to accept gateways...
+            update['ipv4', 'gateway'] = None
+            update['ipv6', 'gateway'] = None
+            update['ipv4', 'never-default'] = True
+            update['ipv6', 'never-default'] = True
+            pass
+        else:
+            update['ipv4', 'gateway'] = network.gateway(interface._ip_)
+            update['ipv6', 'gateway'] = network.gateway(interface._ipv6_)
+            update['ipv4', 'never-default'] = None
+            update['ipv6', 'never-default'] = None
+            pass
+            
+        update['ipv6', 'method'] = ('disabled','manual')[len(ipv6a) > 0]
         update['ipv6', 'dhcp-duid'] = None
         pass
     if interface.bridge[0]:
@@ -166,7 +230,10 @@ def configure_networking(connection, interface):
     before = connection.GetSettings()
     after = update_settings(before, update)
     if before != after:
-        connection.Update(after)
+        x = connection.Update(after)
+        from pprint import pprint
+        pprint(before)
+        pprint(after)
         return True
     return False
     
-- 
GitLab