blob: 629e01d4ec4155b4db0abf655ae511ca144c3b5b [file] [log] [blame]
Alex Savatieiev9b2f6512019-02-20 18:05:00 -06001import json
2import os
3import sys
Alex Savatieieve9613992019-02-21 18:20:35 -06004import ipaddress
Alex Savatieiev9b2f6512019-02-20 18:05:00 -06005
6from copy import deepcopy
7
Alex Savatieievf526dc02019-03-06 10:11:32 -06008from cfg_checker.reports import reporter
Alex Savatieiev9b2f6512019-02-20 18:05:00 -06009from cfg_checker.common import utils, const
10from cfg_checker.common import config, logger, logger_cli, pkg_dir
11from cfg_checker.common import salt_utils
12from cfg_checker.nodes import SaltNodes, node_tmpl
13
14
15class NetworkChecker(SaltNodes):
16 def collect_network_info(self):
17 """
18 Collects info on the network using ifs_data.py script
19
20 :return: none
21 """
22 logger_cli.info("### Collecting network data")
23 _result = self.execute_script("ifs_data.py", args=["json"])
24
25 for key in self.nodes.keys():
26 # due to much data to be passed from salt, it is happening in order
27 if key in _result:
28 _text = _result[key]
29 _dict = json.loads(_text[_text.find('{'):])
30 self.nodes[key]['networks'] = _dict
31 else:
32 self.nodes[key]['networks'] = {}
33 logger_cli.debug("# {} has {} networks".format(
34 key,
35 len(self.nodes[key]['networks'].keys())
36 ))
Alex Savatieievf808cd22019-03-01 13:17:59 -060037 logger_cli.info("-> done collecting networks data")
Alex Savatieiev9b2f6512019-02-20 18:05:00 -060038
Alex Savatieieve9613992019-02-21 18:20:35 -060039 # dump collected data to speed up coding
40 # with open('dump.json', 'w+') as ff:
41 # ff.write(json.dumps(self.nodes))
42
43 # load dump data
44 # with open('dump.json', 'r') as ff:
45 # _nodes = json.loads(ff.read())
46
47 logger_cli.info("### Building network tree")
48 # match physical interfaces by MAC addresses
49 _all_nets = {}
Alex Savatieieva05921f2019-02-21 18:21:39 -060050 for host, node_data in self.nodes.iteritems():
Alex Savatieieve9613992019-02-21 18:20:35 -060051 for net_name, net_data in node_data['networks'].iteritems():
52 # get ips and calculate subnets
53 if net_name == 'lo':
54 continue
55 _ip4s = net_data['ipv4']
56 for _ip_str in _ip4s.keys():
57 _if = ipaddress.IPv4Interface(_ip_str)
58 if not any(_if.ip in net for net in _all_nets.keys()):
59 # IP not fits into existing networks
60 if _if.network not in _all_nets.keys():
61 _all_nets[_if.network] = {}
62
63 _all_nets[_if.network][host] = {}
64 _all_nets[_if.network][host]['text'] = \
65 "{0:30}: {1:19} {2:5} {3:4}".format(
66 net_name,
67 str(_if.ip),
68 net_data['mtu'],
69 net_data['state']
70 )
71 _all_nets[_if.network][host]['if_data'] = net_data
72 else:
73 # There is a network that ip fits into
74 for _net in _all_nets.keys():
75 if _if.ip in _net:
76 if host not in _all_nets[_net]:
77 _all_nets[_net][host] = {}
78 _all_nets[_net][host]['text'] = \
79 "{0:30}: {1:19} {2:5} {3:4}".format(
80 net_name,
81 str(_if.ip),
82 net_data['mtu'],
83 net_data['state']
84 )
85 _all_nets[_net][host]['if_data'] = \
86 net_data
87
88 # save collected info
89 self.all_networks = _all_nets
Alex Savatieiev9b2f6512019-02-20 18:05:00 -060090
Alex Savatieiev9c642112019-02-26 13:55:43 -060091 # Get networks from reclass
92 # TODO:
93
94 return
95
Alex Savatieiev9b2f6512019-02-20 18:05:00 -060096 def print_network_report(self):
97 """
98 Create text report for CLI
99
100 :return: none
101 """
Alex Savatieieve9613992019-02-21 18:20:35 -0600102 for network, nodes in self.all_networks.iteritems():
103 logger_cli.info("-> {}".format(str(network)))
104 names = sorted(nodes.keys())
105
106 for hostname in names:
107 logger_cli.info(
108 "\t{0:10} {1}".format(
109 hostname.split('.')[0],
110 nodes[hostname]['text']
111 )
112 )
Alex Savatieiev9b2f6512019-02-20 18:05:00 -0600113
114 def create_html_report(self, filename):
115 """
116 Create static html showing network schema-like report
117
118 :return: none
119 """
120 logger_cli.info("### Generating report to '{}'".format(filename))
121 _report = reporter.ReportToFile(
122 reporter.HTMLNetworkReport(),
123 filename
124 )
125 _report({
126 "nodes": self.nodes,
127 "diffs": {}
128 })
129 logger_cli.info("-> Done")