Routes runtime and reclass parsing and matching
diff --git a/cfg_checker/modules/network/checker.py b/cfg_checker/modules/network/checker.py
index c3fcd82..7a654dc 100644
--- a/cfg_checker/modules/network/checker.py
+++ b/cfg_checker/modules/network/checker.py
@@ -44,30 +44,24 @@
             if key in _result:
                 _text = _result[key]
                 _dict = json.loads(_text[_text.find('{'):])
+                self.nodes[key]['routes'] = _dict.pop("routes")
                 self.nodes[key]['networks'] = _dict
             else:
                 self.nodes[key]['networks'] = {}
+                self.nodes[key]['routes'] = {}
             logger_cli.debug("... {} has {} networks".format(
                 key,
                 len(self.nodes[key]['networks'].keys())
             ))
         logger_cli.info("-> done collecting networks data")
 
-        # dump collected data to speed up coding
-        # with open('dump.json', 'w+') as ff:
-        #     ff.write(json.dumps(self.nodes))
-
-        # load dump data
-        # with open('dump.json', 'r') as ff:
-        #     _nodes = json.loads(ff.read())
-
         logger_cli.info("### Building network tree")
         # match interfaces by IP subnets
         _all_nets = {}
         for host, node_data in self.nodes.iteritems():
             for net_name, net_data in node_data['networks'].iteritems():
                 # get ips and calculate subnets
-                if net_name == 'lo':
+                if net_name in ['lo']:
                     # skip the localhost
                     continue
                 _ip4s = net_data['ipv4']
@@ -122,22 +116,59 @@
         """
         _all_nets = self.all_nets.keys()
         logger_cli.info("# Reclass networks")
+        _text = "    {0:17} {1:25}: {2:19} {3:5}{4:10} {5}{6} {7}/{8}/{9}".format(
+            "Hostname",
+            "IF name",
+            "IP",
+            "Runtime MTU",
+            "Reclass MTU",
+            "Runtime State",
+            "Reclass State",
+            "Runtime gate",
+            "Runtime def. gate",
+            "Reclass gate"
+        )
+
         _reclass = [n for n in _all_nets if n in self.reclass_nets]
         for network in _reclass:
             # shortcuts
-            logger_cli.info("-> {}".format(str(network)))
+            _net = str(network)
+            logger_cli.info("-> {}".format(_net))
             names = sorted(self.all_nets[network].keys())
-
             for hostname in names:
+                # get the gateway for current net
+                _routes = self.nodes[hostname]['routes']
+                _route = _routes[_net] if _net in _routes else None
+                _gate = _route['gateway'] if _route['gateway'] else "empty"
+                
+                # get the default gateway
+                if 'default' in _routes:
+                    _d_gate = ipaddress.IPv4Address(
+                        _routes['default']['gateway']
+                    )
+                else:
+                    _d_gate = None
+                _d_gate_str = _d_gate if _d_gate else "No default gateway!"
+
                 _a = self.all_nets[network][hostname]
                 _r = self.reclass_nets[network][hostname]
-                _text = "{0:25}: {1:19} {2:5}{3:10} {4}{5}".format(
+                
+                # Take gateway parameter for this IF 
+                # from corresponding reclass record
+                _pillar = self.nodes[hostname]['pillars']
+                _rd = _pillar['linux']['network']['interface'][_a['name']]
+                _r_gate = _rd['gateway'] if 'gateway' in _rd else "empty"
+
+                _text = "{0:25}: {1:19} {2:5}{3:10} {4:4}{5:10} {6}/{7}/{8}".format(
                     _a['name'],
                     str(_a['if'].ip),
                     _a['mtu'],
                     '('+str(_r['mtu'])+')' if 'mtu' in _r else '(unset!)',
                     _a['state'],
-                    "(enabled)" if _r['enabled'] else "(disabled)"
+                    "(enabled)" if _r['enabled'] else "(disabled)",
+                    _gate,
+                    _d_gate_str,
+                    _r_gate
                 )
                 logger_cli.info(
                     "    {0:17} {1}".format(hostname.split('.')[0], _text)
diff --git a/scripts/ifs_data.py b/scripts/ifs_data.py
index 3b7a8e5..7fbba28 100644
--- a/scripts/ifs_data.py
+++ b/scripts/ifs_data.py
@@ -13,8 +13,7 @@
     return _ps
 
 
-def cut_option(_param, _options_list):
-    _option = "n/a"
+def cut_option(_param, _options_list, _option="n/a"):
     _result_list = []
     if _param in _options_list:
         _index = _options_list.index(_param)
@@ -66,14 +65,16 @@
 
 
 def get_ifs_data():
-    _ifs_raw = shell('ip a')
-
+    # Collect interface and IPs data
+    # Compile regexps for detecting IPs
     if_start = re.compile("^[0-9]+: .*: \<.*\> .*$")
     if_link = re.compile("^\s{4}link\/ether\ .*$")
     if_ipv4 = re.compile("^\s{4}inet\ .*$")
-
+    # variable prototypes
     _ifs = {}
     _if_name = None
+    # get the "ip a" output
+    _ifs_raw = shell('ip a')
     for line in _ifs_raw.splitlines():
         _if_data = {}
         if if_start.match(line):
@@ -115,7 +116,37 @@
                 _ifs[_if_name]['ipv4'][_ip] = {}
                 _ifs[_if_name]['ipv4'][_ip]['brd'] = _brd
                 _ifs[_if_name]['ipv4'][_ip]['other'] = _options
+    
+    # Collect routes data and try to match it with network
+    # Compile regexp for detecting default route
+    _routes = {
+        'raw': []
+    }
+    _ip_route_raw = shell("ip -4 r")
+    for line in _ip_route_raw.splitlines():
+        _o = line.strip().split(' ')
+        if line.startswith("default"):
+            # default gateway found, prepare options and cut word 'default'
+            _gate, _o = cut_option('via', _o, _option="0.0.0.0")
+            _dev, _o = cut_option('dev', _o)
+            _routes[_o[0]] = {
+                'gateway': _gate,
+                'device': _dev,
+                'args': " ".join(_o[1:])
+            }
+        else:
+            # network specific gateway found
+            _gate, _o = cut_option('via', _o, _option=None)
+            _dev, _o = cut_option('dev', _o)
+            _src, _o = cut_option('src', _o)
+            _routes[_o[0]] = {
+                'gateway': _gate,
+                'device': _dev,
+                'source': _src,
+                'args': " ".join(_o[1:])
+            }
 
+    _ifs["routes"] = _routes
     return _ifs
 
 
@@ -126,6 +157,7 @@
 else:
     _ifs = sorted(ifs_data.keys())
     _ifs.remove("lo")
+    _ifs.remove("routes")
     for _idx in range(len(_ifs)):
         _linked = ""
         if ifs_data[_ifs[_idx]]['lower']:
@@ -146,3 +178,32 @@
             ifs_data[_ifs[_idx]]['state'],
             _linked
         ))
+
+    print("\n")
+    # default route
+    print("default via {} on {} ({})".format(
+        ifs_data["routes"]["default"]["gateway"],
+        ifs_data["routes"]["default"]["device"],
+        ifs_data["routes"]["default"]["args"]
+    ))
+    # detected routes
+    _routes = ifs_data["routes"].keys()
+    _routes.remove("raw")
+    _routes.remove("default")
+    _rt = ifs_data["routes"]
+    for idx in range(0, len(_routes)):
+        if _rt[_routes[idx]]["gateway"]:
+            print("{0:18} <- {1:16} -> {2:18} on {3:30} ({4})".format(
+                _routes[idx],
+                _rt[_routes[idx]]["gateway"],
+                _rt[_routes[idx]]["source"],
+                _rt[_routes[idx]]["device"],
+                _rt[_routes[idx]]["args"]
+            ))
+        else:
+            print("{0:18} <- -> {1:18} on {2:30} ({3})".format(
+                _routes[idx],
+                _rt[_routes[idx]]["source"],
+                _rt[_routes[idx]]["device"],
+                _rt[_routes[idx]]["args"]
+            ))