Added info module for generating info files about nodes, links, graphs and domains. Currently there is offline node info available only. Furthermore there is a attribute to append filters to info module

This commit is contained in:
Simon Wüllhorst 2016-07-19 23:28:01 +02:00
commit f617f3b2be
5 changed files with 169 additions and 4 deletions

18
info/Info.py Normal file
View file

@ -0,0 +1,18 @@
from info.OfflineInfo import OfflineInfo
class Info(object):
def __init__(self, infoTypes, infoOutFolder, infoOutType, infoFilters, nodes, globalGraph, domains):
self.__infoTypes__ = infoTypes
self.__infoOutFolder__ = infoOutFolder
self.__infoOutType__ = infoOutType
self.__infoFilters__ = infoFilters
self.__nodes__ = nodes
self.__globalGraph__ = globalGraph
self.__domains__ = domains
if self.__infoTypes__ != None:
if 'get_offline_nodes' in self.__infoTypes__:
self.__offlineNodes__ = OfflineInfo(self.__infoFilters__, self.__nodes__, self.__domains__)
print(self.__infoOutType__)
if 'csv' in self.__infoOutType__:
self.__offlineNodes__.writeCSVtoFile(self.__infoOutFolder__+'/offline_nodes.csv')
if 'json' in self.__infoOutType__:
self.__offlineNodes__.writeJsonToFile(self.__infoOutFolder__+'/offline_nodes.json')

75
info/InfoMeta.py Normal file
View file

@ -0,0 +1,75 @@
import json
class InfoMeta(object):
def __init__(self):
self.resultNodes = None
self.resultGraph = None
def __generateNodesJson__(self):
if self.resultNodes == None:
return []
result = []
for node in self.resultNodes:
result.append(node.__jsonObject__)
return result
def __generateNodesCSV__(self):
if self.resultNodes == None:
return ''
result = '"hostname","site","nodeid","ipv6addresses","status","lastseen","firstseen","autoupdater","branch","firmware","hardware"\n'
for node in self.resultNodes:
nodeData = node.__jsonObject__
nodeinfo = nodeData['nodeinfo']
result += '"'+nodeinfo['hostname']+'",'
try:
result +='"'+nodeinfo['system']['site_code']+'",'
except:
result += '"none",'
result += '"'+nodeinfo['node_id']+'","'
#add array of public IPv6 Addresses
addresses = node.__getPublicAddresses__()
for i, address in enumerate(addresses):
if i == len(addresses)-1:
result += address
else:
result += address + ','
result += '",'
if nodeData['flags']['online'] == True:
result += '"online",'
else:
result += '"offline",'
result += '"'+nodeData['lastseen']+'","'+nodeData['firstseen']+'",'
try:
if nodeinfo['software']['autoupdater']['enabled'] == True:
result += '"enabled",'
else:
result += '"disabled",'
except:
result += '"none",'
try:
result += '"'+nodeinfo['software']['autoupdater']['branch']+'",'
except:
result += '"none",'
result += '"'+nodeinfo['software']['firmware']['release']+'",'
try:
result += '"'+nodeinfo['hardware']['model']+'"'
except:
result += '"none"'
result += '\n'
return result
def writeCSVtoFile(self, filename):
with open(filename, 'w') as out:
out.write(self.__generateNodesCSV__())
def writeJsonToFile(self, filename):
with open(filename, 'w') as out:
out.write(json.dumps(self.__generateNodesJson__(), sort_keys=True, indent=4, ensure_ascii=False))

68
info/OfflineInfo.py Normal file
View file

@ -0,0 +1,68 @@
from info.InfoMeta import InfoMeta
from shapely.geometry import Point
import datetime, re
from datetime import timedelta
class OfflineInfo(InfoMeta):
def __init__(self, filters, nodes, domains):
super().__init__()
self.__filters__ = filters
self.__nodes__ = nodes
self.__domains__ = domains
self.__minAge__, self.__maxAge__ = self.__parseFilters__()
self.resultNodes = self.__filterNodes__()
def __filterNodes__(self):
offlineNodes = []
for k,v in self.__nodes__.items():
if v.isOnline == False:
if v.geo != None:
for dk, dv in self.__domains__.items():
if dv.isPointInDomaene(Point((v.geo['lon'], v.geo['lat']))) == True:
nodeLastSeen = datetime.datetime.strptime(v.__jsonObject__['lastseen'],'%Y-%m-%dT%H:%M:%S')
if self.__minAge__ != None:
if self.__minAge__ < nodeLastSeen:
continue
if self.__maxAge__ != None:
if self.__maxAge__ > nodeLastSeen:
continue
offlineNodes.append(v)
return offlineNodes
def __parseFilters__(self):
if self.__filters__ == None:
return None, None
regX = re.compile("([0-9]+)([a-zA-Z]+)")
minAge = None
maxAge = None
for filter in self.__filters__:
attr = filter.split(':')
if len(attr) == 2:
if attr[0] == 'min_age' or attr[0] == 'max_age':
d = regX.match(attr[1])
if d != None:
val = int(d.group(1))
unit = d.group(2)
date = datetime.datetime.now()
if unit == 'd' or unit == 'day' or unit == 'days':
date = date - timedelta(days=val)
elif unit == 'w' or unit == 'week' or unit == 'weeks':
date = date - timedelta(days=val*7)
elif unit == 'm' or unit == 'month' or unit == 'months':
date = date - timedelta(days=val*30)
elif unit == 'y' or unit == 'year' or unit == 'years':
date = date - timedelta(days=val*365)
else:
date = None
if attr[0] == 'min_age':
minAge = date
elif attr[0] == 'max_age':
maxAge = date
return minAge, maxAge

0
info/__init__.py Normal file
View file