Got DNS working, cleaned up some error handling

This commit is contained in:
Daniel Dayley 2019-12-04 13:00:55 -07:00
parent 4f86b7621e
commit c181e3db41
3 changed files with 62 additions and 20 deletions

40
ifxtool
View File

@ -20,7 +20,8 @@ class IFXTool():
configfilename = 'ifxtool.yml'
servicetemplate = {'hosts':[],'username':'','key':''}
configtemplate = {'bluecat':servicetemplate,'f5':servicetemplate,'paloalto':servicetemplate,'aruba':servicetemplate,'openvpn':servicetemplate}
stopinfo = ''
errorinfo = []
warninfo = []
namespace = ''
servicedelegates = []
totalconfig = {}
@ -36,8 +37,8 @@ class IFXTool():
self.totalconfig = yaml.safe_load(open(os.path.normpath(arglist.config)))
except Exception as exception :
#self.stopinfo = str(exception.__class__.__name__) + ': ' + str(exception)
self.stopinfo = "There was a problem reading your config file, aborting."
#self.errorinfo = str(exception.__class__.__name__) + ': ' + str(exception)
self.errorinfo.append("There was a problem reading your config file, aborting.")
else :
try:
self.totalconfig = yaml.safe_load(open(self.configdir + '/' + self.configfilename))
@ -47,13 +48,13 @@ class IFXTool():
if not os.path.exists(os.path.normpath(self.configdir + '/' + self.configfilename)):
with open(self.configdir + '/' + self.configfilename, 'w') as output :
yaml.dump(self.configtemplate, output)
self.stopinfo='Config file ' + self.configdir + '/' + self.configfilename + ' is empty, aborting.'
self.errorinfo.append('Config file ' + self.configdir + '/' + self.configfilename + ' is empty, aborting.')
else :
self.stopinfo = "There was a problem reading your config file, aborting."
self.errorinfo.append("There was a problem reading your config file, aborting.")
if self.totalconfig == {} :
with open(self.configdir + '/' + self.configfilename, 'w') as output :
yaml.dump(self.configtemplate, output)
self.stopinfo='Config file ' + self.configdir + '/' + self.configfilename + ' is empty, populating with a template.'
self.errorinfo.append('Config file ' + self.configdir + '/' + self.configfilename + ' is empty, populating with a template.')
def dispatch(self) :
@ -65,19 +66,18 @@ class IFXTool():
subjecttuple = socket.gethostbyname_ex(item)
else :
subjecttuple = socket.gethostbyaddr(item)
except socket.gaierror:
self.stopinfo = "Unable to resolve " + item + ", skipping."
except socket.herror:
subjecttuple = tuple(['',[],[item]])
except (socket.gaierror,socket.herror) :
self.warninfo.append("Unable to resolve " + item)
self.namespace.subjects.remove(item)
continue
# Convert mutable types to immutable (to be used as dictionary keys)
immutablesubjecttuple = tuple([subjecttuple[0],tuple(subjecttuple[1]),tuple(subjecttuple[2])])
self._dnsmaps.update({immutablesubjecttuple:item})
self._subjecttuples.append(immutablesubjecttuple)
# Stop on initialization error
if self.stopinfo != '' :
self._internal_messages['Status'] = self.stopinfo
self.print_results(self._internal_messages)
if self.errorinfo != [] :
self._internal_messages['error'] = self.errorinfo
exit(1)
# Dispatch service delegates
@ -95,6 +95,8 @@ class IFXTool():
delegatereports.update({delegatename:delegateresponse})
# Format and display results
if self.warninfo != [] :
self._internal_messages['warn'] = self.warninfo
delegatereports.update(self._internal_messages)
self.print_results(delegatereports)
@ -113,16 +115,22 @@ class IFXTool():
def print_results(self,dataset) :
"""Returns the submitted dataset"""
finalresult = {}
if 'error' in dataset or 'warn' in dataset :
finalresult['status'] = {}
if 'error' in dataset :
finalresult['status']['error'] = dataset['error']
if 'warn' in dataset :
finalresult['status']['warn'] = dataset['warn']
for subject in self._subjecttuples :
subjectname = self._dnsmaps[subject]
subjectdataset = {}
for plugin in dataset:
# for plugin in [x for x in dataset if x != 'status'] :
for plugin in [x for x in dataset if x != 'error' and x != 'warn'] :
subjectdataset.update({plugin:dataset[plugin][subject]})
finalresult.update({subjectname:subjectdataset})
if self.namespace.json :
print(json.dumps(finalresult))
else :

16
plugins/dns.py Normal file
View File

@ -0,0 +1,16 @@
from servicebase import ServiceBase
class ServiceDelegate(ServiceBase) :
def get_arguments(cls) :
"""Returns an array of information used to construct an argumentparser argument."""
return [ '-d', '--dns', 'store_true', "Return DNS resolution about the subject" ]
def perform_lookup(self,host_tuple) :
return_dict = {}
if len(host_tuple[2]) > 0 :
return_dict['IP Addresses'] = list(host_tuple[2])
if host_tuple[0] and host_tuple[0] != '' :
return_dict['Hostname'] = host_tuple[0]
if len(host_tuple[1]) > 0 :
return_dict['Associated Aliases'] = list(host_tuple[1])
return return_dict

View File

@ -6,7 +6,6 @@ class ServiceBase :
_subjects = []
def __init__(self,config,namespace,subjects,dossiercopy):
if not config or config == {} :
self.results.update({"No configuration found":"Nothing to do"})
self._status = "Error"
else :
self.config = config
@ -16,23 +15,42 @@ class ServiceBase :
pass
def _lookup_subjects(self) :
args = self.get_arguments()
if args :
args = args[1][2:]
if getattr(self.namespace,args) == False and getattr(self.namespace,'all') == False :
return None
finaldictionary = {}
self.startup()
for item in self._subjects :
finaldictionary.update({item:self.perform_lookup(item)})
self.shutdown()
return finaldictionary
def get_arguments() :
@classmethod
def get_arguments(cls) :
"""Returns an array of information used to construct an argumentparser argument."""
# [ <short flag>,<unix flag>,<arg type>,<description> ]
# Example return: [ '-n', '--net', 'store_true', "Output network information about the subject" ]
return None
def startup(self) :
"""Perform any setup that is needed to perform lookups, such as logging in or obtaining auth sessions."""
pass
def perform_lookup(self,host_tuple) :
"""Returns a JSON string with lookup information about the given IP or Hostname."""
# Host tuple is a socket triple (hostname, aliaslist, ipaddrlist) where hostname is
"""Returns a dictionary with lookup information about the given IP or Hostname."""
# host_tuple is a socket triple (hostname, aliaslist, ipaddrlist) where hostname is
# the primary host name responding to the given ip_address, aliaslist is a (possibly
# empty) tuple of alternative host names for the same address, and ipaddrlist is a tuple
# of IPv4/v6 addresses for the same interface on the same host (most likely containing
# only a single address).
# Note: You should only return arrays and dictionaries with strings as keys so the information
# serializes correctly.
return None
def shutdown(self) :
"""Perform any cleanup that is needed, such as logging out of auth sessions."""
pass