More code cleanup
This commit is contained in:
parent
89a643f218
commit
4f4b7f2bdc
@ -107,8 +107,10 @@ class IFXLookup():
|
|||||||
"""Returns a map of plugins configured to use in the lookup."""
|
"""Returns a map of plugins configured to use in the lookup."""
|
||||||
return self._delegate_map
|
return self._delegate_map
|
||||||
|
|
||||||
def search_plugins(self,directory='/'.join(os.path.realpath(__file__).split('/')[:-1]) + '/' + 'plugins') :
|
def search_plugins(self,directory=None) :
|
||||||
"""Searches a given directory for compatible plugins and returns a map of available plugin names and classes"""
|
"""Searches a given directory for compatible plugins and returns a map of available plugin names and classes"""
|
||||||
|
if not directory :
|
||||||
|
directory = '/'.join(os.path.realpath(__file__).split('/')[:-1]) + '/' + 'plugins'
|
||||||
directory = os.path.normpath(os.path.expanduser(os.path.expandvars(directory)))
|
directory = os.path.normpath(os.path.expanduser(os.path.expandvars(directory)))
|
||||||
name_map = {}
|
name_map = {}
|
||||||
candidates = {x.split('.')[0]:x for x in os.listdir(directory) if x.endswith('.py') and x != 'servicebase.py'}
|
candidates = {x.split('.')[0]:x for x in os.listdir(directory) if x.endswith('.py') and x != 'servicebase.py'}
|
||||||
@ -126,18 +128,6 @@ class IFXLookup():
|
|||||||
raise TypeError('argument \'config\' should be of type dict')
|
raise TypeError('argument \'config\' should be of type dict')
|
||||||
self._config.update(config)
|
self._config.update(config)
|
||||||
|
|
||||||
def load_config_from_file(self,config=DEFAULT_CONFIG) :
|
|
||||||
"""Loads a JSON or YAML file containing a configuration map for plugins. Used to configure several plugins at once."""
|
|
||||||
if config :
|
|
||||||
file_descriptor = open(os.path.normpath(os.path.expanduser(os.path.expandvars(config))))
|
|
||||||
try :
|
|
||||||
file_descriptor = open(os.path.normpath(os.path.expanduser(os.path.expandvars(config))))
|
|
||||||
total_config = json.load(file_descriptor)
|
|
||||||
except json.decoder.JSONDecodeError as exception :
|
|
||||||
file_descriptor = open(os.path.normpath(os.path.expanduser(os.path.expandvars(config))))
|
|
||||||
total_config = yaml.safe_load(file_descriptor)
|
|
||||||
self._config.update(total_config)
|
|
||||||
|
|
||||||
def dump_config(self) :
|
def dump_config(self) :
|
||||||
"""Returns the current configuration state. This likely contains sensitive information such as API keys."""
|
"""Returns the current configuration state. This likely contains sensitive information such as API keys."""
|
||||||
return self._config
|
return self._config
|
||||||
@ -206,15 +196,19 @@ class IFXLookup():
|
|||||||
report = {}
|
report = {}
|
||||||
for subject in subjects :
|
for subject in subjects :
|
||||||
report.update({subject:delegate.lookup(subject)})
|
report.update({subject:delegate.lookup(subject)})
|
||||||
if delegate.error != [] :
|
if delegate._error != [] :
|
||||||
error_info.update({delegatename:delegate.error})
|
error_info.update({delegatename:delegate._error})
|
||||||
if delegate.warn != [] :
|
if delegate._warn != [] :
|
||||||
warn_info.update({delegatename:delegate.warn})
|
warn_info.update({delegatename:delegate._warn})
|
||||||
report.update(error_info)
|
report.update(error_info)
|
||||||
report.update(warn_info)
|
report.update(warn_info)
|
||||||
if report and report != {}:
|
if report and report != {}:
|
||||||
final_report.update({delegatename:report})
|
final_report.update({delegatename:report})
|
||||||
|
|
||||||
|
if len(error_info) > 0 :
|
||||||
|
final_report.update({'error':error_info})
|
||||||
|
if len(warn_info) > 0 :
|
||||||
|
final_report.update({'warning':warn_info})
|
||||||
# If caching is enabled prevent shutdown. Otherwise shutdown.
|
# If caching is enabled prevent shutdown. Otherwise shutdown.
|
||||||
if not self._caching :
|
if not self._caching :
|
||||||
self.__shutdown_plugins()
|
self.__shutdown_plugins()
|
@ -6,15 +6,15 @@ import xml.etree.ElementTree as ElementTree
|
|||||||
|
|
||||||
class ServiceDelegate(ServiceBase) :
|
class ServiceDelegate(ServiceBase) :
|
||||||
|
|
||||||
host = None
|
_host = None
|
||||||
api_session = requests.session()
|
_api_session = requests.session()
|
||||||
session_key = None
|
_session_key = None
|
||||||
query_page_size = 200
|
_query_page_size = 200
|
||||||
clients_fields = ['sta_mac_address', 'client_ht_phy_type', 'openflow_state', 'client_ip_address', 'client_user_name', 'client_dev_type', 'client_ap_location', 'client_conn_port', 'client_conn_type', 'client_timestamp', 'client_role_name', 'client_active_uac', 'client_standby_uac', 'ap_cluster_name', 'client_health', 'total_moves', 'successful_moves', 'steer_capability', 'ssid', 'ap_name', 'channel', 'channel_str', 'channel_busy', 'tx_time', 'rx_time', 'channel_free', 'channel_interference', 'current_channel_utilization', 'radio_band', 'bssid', 'speed', 'max_negotiated_rate', 'noise_floor', 'radio_ht_phy_type', 'snr', 'total_data_frames', 'total_data_bytes', 'avg_data_rate', 'tx_avg_data_rate', 'rx_avg_data_rate', 'tx_frames_transmitted', 'tx_frames_dropped', 'tx_bytes_transmitted', 'tx_bytes_dropped', 'tx_time_transmitted', 'tx_time_dropped', 'tx_data_transmitted', 'tx_data_dropped', 'tx_data_retried', 'tx_data_transmitted_retried', 'tx_data_bytes_transmitted', 'tx_abs_data_bytes', 'tx_data_bytes_dropped', 'tx_time_data_transmitted', 'tx_time_data_dropped', 'tx_mgmt', 'rx_frames', 'rx_bytes', 'rx_data', 'rx_data_bytes', 'rx_abs_data_bytes', 'rx_data_retried', 'tx_data_frame_rate_dist', 'rx_data_frame_rate_dist', 'tx_data_bytes_rate_dist', 'rx_data_bytes_rate_dist', 'connection_type_classification', 'total_data_throughput', 'tx_data_throughput', 'rx_data_throughput', 'client_auth_type', 'client_auth_subtype', 'client_encrypt_type', 'client_fwd_mode']
|
_clients_fields = ['sta_mac_address', 'client_ht_phy_type', 'openflow_state', 'client_ip_address', 'client_user_name', 'client_dev_type', 'client_ap_location', 'client_conn_port', 'client_conn_type', 'client_timestamp', 'client_role_name', 'client_active_uac', 'client_standby_uac', 'ap_cluster_name', 'client_health', 'total_moves', 'successful_moves', 'steer_capability', 'ssid', 'ap_name', 'channel', 'channel_str', 'channel_busy', 'tx_time', 'rx_time', 'channel_free', 'channel_interference', 'current_channel_utilization', 'radio_band', 'bssid', 'speed', 'max_negotiated_rate', 'noise_floor', 'radio_ht_phy_type', 'snr', 'total_data_frames', 'total_data_bytes', 'avg_data_rate', 'tx_avg_data_rate', 'rx_avg_data_rate', 'tx_frames_transmitted', 'tx_frames_dropped', 'tx_bytes_transmitted', 'tx_bytes_dropped', 'tx_time_transmitted', 'tx_time_dropped', 'tx_data_transmitted', 'tx_data_dropped', 'tx_data_retried', 'tx_data_transmitted_retried', 'tx_data_bytes_transmitted', 'tx_abs_data_bytes', 'tx_data_bytes_dropped', 'tx_time_data_transmitted', 'tx_time_data_dropped', 'tx_mgmt', 'rx_frames', 'rx_bytes', 'rx_data', 'rx_data_bytes', 'rx_abs_data_bytes', 'rx_data_retried', 'tx_data_frame_rate_dist', 'rx_data_frame_rate_dist', 'tx_data_bytes_rate_dist', 'rx_data_bytes_rate_dist', 'connection_type_classification', 'total_data_throughput', 'tx_data_throughput', 'rx_data_throughput', 'client_auth_type', 'client_auth_subtype', 'client_encrypt_type', 'client_fwd_mode']
|
||||||
aps_fields = ['mon_ap', 'mon_bssid', 'mon_radio_phy_type', 'mon_ssid', 'mon_radio_band', 'mon_ap_current_channel', 'mon_ht_sec_channel', 'mon_sta_count', 'mon_ap_classification', 'mon_ap_match_conf_level', 'mon_ap_encr', 'mon_ap_encr_auth', 'mon_ap_encr_cipher', 'mon_ap_is_dos', 'mon_ap_type', 'mon_ap_status', 'mon_is_ibss', 'mon_ap_create_time', 'mon_ap_match_type', 'mon_ap_match_method', 'mon_ap_match_name', 'mon_ap_match_time', 'wms_event_count']
|
_aps_fields = ['mon_ap', 'mon_bssid', 'mon_radio_phy_type', 'mon_ssid', 'mon_radio_band', 'mon_ap_current_channel', 'mon_ht_sec_channel', 'mon_sta_count', 'mon_ap_classification', 'mon_ap_match_conf_level', 'mon_ap_encr', 'mon_ap_encr_auth', 'mon_ap_encr_cipher', 'mon_ap_is_dos', 'mon_ap_type', 'mon_ap_status', 'mon_is_ibss', 'mon_ap_create_time', 'mon_ap_match_type', 'mon_ap_match_method', 'mon_ap_match_name', 'mon_ap_match_time', 'wms_event_count']
|
||||||
justip_fields = ['client_ip_address']
|
_justip_fields = ['client_ip_address']
|
||||||
aruba_hosts = []
|
_aruba_hosts = []
|
||||||
aruba_basestations = []
|
_aruba_basestations = []
|
||||||
|
|
||||||
def get_arguments(cls) :
|
def get_arguments(cls) :
|
||||||
"""Returns an array of information used to construct an argumentparser argument."""
|
"""Returns an array of information used to construct an argumentparser argument."""
|
||||||
@ -22,11 +22,11 @@ class ServiceDelegate(ServiceBase) :
|
|||||||
|
|
||||||
def startup(self) :
|
def startup(self) :
|
||||||
for requirement in ['host','username','key'] :
|
for requirement in ['host','username','key'] :
|
||||||
if requirement not in self.config or (requirement in self.config and (self.config[requirement] is '' or type(self.config[requirement]) is not str)):
|
if requirement not in self._config or (requirement in self._config and (self._config[requirement] is '' or type(self._config[requirement]) is not str)):
|
||||||
self.error.append('Missing required config option ' + requirement)
|
self._error.append('Missing required config option ' + requirement)
|
||||||
return
|
return
|
||||||
self.host = self.config['host']
|
self._host = self._config['host']
|
||||||
self.start_session(self.config['host'],self.config['username'],self.config['key'])
|
self.start_session(self._config['host'],self._config['username'],self._config['key'])
|
||||||
clientsquery = 'backend-observer-sta-19'
|
clientsquery = 'backend-observer-sta-19'
|
||||||
clientssortfield = 'client_user_name'
|
clientssortfield = 'client_user_name'
|
||||||
clientsfilter = 'client_conn_type not_equals 0'
|
clientsfilter = 'client_conn_type not_equals 0'
|
||||||
@ -36,9 +36,9 @@ class ServiceDelegate(ServiceBase) :
|
|||||||
apsfilter = 'mon_ap_status equals 1'
|
apsfilter = 'mon_ap_status equals 1'
|
||||||
apsdevicetype = 'mon_bssid'
|
apsdevicetype = 'mon_bssid'
|
||||||
self.debug('Retrieving list of Aruba\'s detected basestations...',1)
|
self.debug('Retrieving list of Aruba\'s detected basestations...',1)
|
||||||
self.aruba_basestations = self.perform_list_query(apsquery,self.aps_fields,apssortfield,apsfilter,apsdevicetype)
|
self._aruba_basestations = self.perform_list_query(apsquery,self._aps_fields,apssortfield,apsfilter,apsdevicetype)
|
||||||
self.debug('Retrieving list of Aruba connected clients...',1)
|
self.debug('Retrieving list of Aruba connected clients...',1)
|
||||||
self.aruba_hosts = self.perform_list_query(clientsquery,self.clients_fields,clientssortfield,clientsfilter,clientsdevicetype)
|
self._aruba_hosts = self.perform_list_query(clientsquery,self._clients_fields,clientssortfield,clientsfilter,clientsdevicetype)
|
||||||
self.debug('Searching Aruba information...',1)
|
self.debug('Searching Aruba information...',1)
|
||||||
|
|
||||||
def lookup(self,subject) :
|
def lookup(self,subject) :
|
||||||
@ -50,11 +50,11 @@ class ServiceDelegate(ServiceBase) :
|
|||||||
# By IP
|
# By IP
|
||||||
if 'dns' in self.hints and subject in self.hints['dns'] and self.hints['dns'][subject]['addresses'] :
|
if 'dns' in self.hints and subject in self.hints['dns'] and self.hints['dns'][subject]['addresses'] :
|
||||||
for ip in self.hints['dns'][subject]['addresses'] :
|
for ip in self.hints['dns'][subject]['addresses'] :
|
||||||
for entry in self.aruba_basestations :
|
for entry in self._aruba_basestations :
|
||||||
if ip in entry.values() :
|
if ip in entry.values() :
|
||||||
return entry
|
return entry
|
||||||
# By value
|
# By value
|
||||||
for entry in self.aruba_basestations :
|
for entry in self._aruba_basestations :
|
||||||
lowercase_values = [x.lower() for x in entry.values() if type(x) is str]
|
lowercase_values = [x.lower() for x in entry.values() if type(x) is str]
|
||||||
all_values = lowercase_values + [x for x in entry.values() if type(x) is not str]
|
all_values = lowercase_values + [x for x in entry.values() if type(x) is not str]
|
||||||
for value in all_values :
|
for value in all_values :
|
||||||
@ -64,11 +64,11 @@ class ServiceDelegate(ServiceBase) :
|
|||||||
# By IP
|
# By IP
|
||||||
if 'dns' in self.hints and subject in self.hints['dns'] and self.hints['dns'][subject]['addresses'] :
|
if 'dns' in self.hints and subject in self.hints['dns'] and self.hints['dns'][subject]['addresses'] :
|
||||||
for ip in self.hints['dns'][subject]['addresses'] :
|
for ip in self.hints['dns'][subject]['addresses'] :
|
||||||
for entry in self.aruba_hosts :
|
for entry in self._aruba_hosts :
|
||||||
if ip in entry.values() :
|
if ip in entry.values() :
|
||||||
return entry
|
return entry
|
||||||
# By value
|
# By value
|
||||||
for entry in self.aruba_hosts :
|
for entry in self._aruba_hosts :
|
||||||
lowercase_values = [x.lower() for x in entry.values() if type(x) is str]
|
lowercase_values = [x.lower() for x in entry.values() if type(x) is str]
|
||||||
all_values = lowercase_values + [x for x in entry.values() if type(x) is not str]
|
all_values = lowercase_values + [x for x in entry.values() if type(x) is not str]
|
||||||
for value in all_values :
|
for value in all_values :
|
||||||
@ -80,9 +80,9 @@ class ServiceDelegate(ServiceBase) :
|
|||||||
def start_session(self,host,username,key) :
|
def start_session(self,host,username,key) :
|
||||||
headers = { 'Content-Type': 'application/x-www-form-urlencoded' }
|
headers = { 'Content-Type': 'application/x-www-form-urlencoded' }
|
||||||
data = 'opcode=login&uid=' + username + '&passwd=' + key
|
data = 'opcode=login&uid=' + username + '&passwd=' + key
|
||||||
self.api_session.post('https://' + host + '/screens/wms/wms.login',verify=False,headers=headers,data=data)
|
self._api_session.post('https://' + host + '/screens/wms/wms.login',verify=False,headers=headers,data=data)
|
||||||
if 'SESSION' in self.api_session.cookies.get_dict() :
|
if 'SESSION' in self._api_session.cookies.get_dict() :
|
||||||
self.session_key = self.api_session.cookies.get_dict()['SESSION']
|
self._session_key = self._api_session.cookies.get_dict()['SESSION']
|
||||||
|
|
||||||
def perform_list_query(self,queryname,columnlist,sortfield,queryfilter,devicetype) :
|
def perform_list_query(self,queryname,columnlist,sortfield,queryfilter,devicetype) :
|
||||||
""""Performs a list-type XML query against the Aruba UI API"""
|
""""Performs a list-type XML query against the Aruba UI API"""
|
||||||
@ -128,9 +128,9 @@ class ServiceDelegate(ServiceBase) :
|
|||||||
allitems = []
|
allitems = []
|
||||||
while not finished :
|
while not finished :
|
||||||
start_row.text = str(nextstart)
|
start_row.text = str(nextstart)
|
||||||
num_rows.text = str(self.query_page_size)
|
num_rows.text = str(self._query_page_size)
|
||||||
datapayload = ''.join(['query=',tostring(aruba_queries).decode(),'&UIDARUBA=',self.session_key])
|
datapayload = ''.join(['query=',tostring(aruba_queries).decode(),'&UIDARUBA=',self._session_key])
|
||||||
page = self.api_session.post('https://' + self.host + '/screens/cmnutil/execUiQuery.xml',verify=False,timeout=1,data=datapayload)
|
page = self._api_session.post('https://' + self._host + '/screens/cmnutil/execUiQuery.xml',verify=False,timeout=1,data=datapayload)
|
||||||
self.debug('Got a page of results from Aruba host...',3)
|
self.debug('Got a page of results from Aruba host...',3)
|
||||||
if page.status_code == 100 or page.status_code == 200 :
|
if page.status_code == 100 or page.status_code == 200 :
|
||||||
pagecontents = ElementTree.fromstring(page.text)
|
pagecontents = ElementTree.fromstring(page.text)
|
||||||
@ -151,7 +151,7 @@ class ServiceDelegate(ServiceBase) :
|
|||||||
finished = True
|
finished = True
|
||||||
if page.status_code != 100 and page.status_code !=200 :
|
if page.status_code != 100 and page.status_code !=200 :
|
||||||
finished = True
|
finished = True
|
||||||
nextstart = nextstart + self.query_page_size
|
nextstart = nextstart + self._query_page_size
|
||||||
else :
|
else :
|
||||||
finished = True
|
finished = True
|
||||||
self.debug('Retrieved ' + str((len(allitems))) + ' results from query',2)
|
self.debug('Retrieved ' + str((len(allitems))) + ' results from query',2)
|
||||||
|
@ -6,42 +6,42 @@ import json
|
|||||||
class ServiceDelegate(ServiceBase) :
|
class ServiceDelegate(ServiceBase) :
|
||||||
|
|
||||||
current_auth_header = None
|
current_auth_header = None
|
||||||
return_payload = {}
|
_return_payload = {}
|
||||||
host = None
|
_host = None
|
||||||
|
|
||||||
def get_arguments(cls) :
|
def get_arguments(cls) :
|
||||||
return ['-b', '--bluecat', 'store_true', 'Return network information about the subject (bluecat)']
|
return ['-b', '--bluecat', 'store_true', 'Return network information about the subject (bluecat)']
|
||||||
|
|
||||||
def startup(self) :
|
def startup(self) :
|
||||||
for requirement in ['host','username','key'] :
|
for requirement in ['host','username','key'] :
|
||||||
if requirement not in self.config or (requirement in self.config and (self.config[requirement] is '' or type(self.config[requirement]) is not str)):
|
if requirement not in self._config or (requirement in self._config and (self._config[requirement] is '' or type(self._config[requirement]) is not str)):
|
||||||
self.error.append('Missing required config option ' + requirement)
|
self._error.append('Missing required config option ' + requirement)
|
||||||
return
|
return
|
||||||
self.host = self.config['host']
|
self._host = self._config['host']
|
||||||
self.current_auth_header = self.get_bc_auth_header(self.config['host'],self.config['username'],self.config['key'])
|
self._current_auth_header = self.get_bc_auth_header(self._config['host'],self._config['username'],self._config['key'])
|
||||||
self.debug('Searching BlueCat for hosts...',1)
|
self.debug('Searching BlueCat for hosts...',1)
|
||||||
|
|
||||||
def lookup(self,subject) :
|
def lookup(self,subject) :
|
||||||
self.return_payload = {}
|
self._return_payload = {}
|
||||||
if self.current_auth_header :
|
if self._current_auth_header :
|
||||||
object = self.search_bc_object(subject)
|
object = self.search_bc_object(subject)
|
||||||
if object :
|
if object :
|
||||||
self.return_payload.update({'object':object})
|
self._return_payload.update({'object':object})
|
||||||
parent = self.search_bc_parent_object(subject)
|
parent = self.search_bc_parent_object(subject)
|
||||||
if parent :
|
if parent :
|
||||||
self.return_payload.update({'parent':parent})
|
self._return_payload.update({'parent':parent})
|
||||||
if len(self.return_payload) > 0 :
|
if len(self._return_payload) > 0 :
|
||||||
return self.return_payload
|
return self._return_payload
|
||||||
else :
|
else :
|
||||||
return None
|
return None
|
||||||
else :
|
else :
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def shutdown(self) :
|
def shutdown(self) :
|
||||||
if self.host and self.current_auth_header :
|
if self._host and self._current_auth_header :
|
||||||
logout = requests.get('https://' + self.host + '/Services/REST/v1/logout',headers=self.current_auth_header)
|
logout = requests.get('https://' + self._host + '/Services/REST/v1/logout',headers=self._current_auth_header)
|
||||||
if not logout.text.endswith('successfully logged out.\"') :
|
if not logout.text.endswith('successfully logged out.\"') :
|
||||||
self.error.append('Unable to log out of BlueCat API session')
|
self._error.append('Unable to log out of BlueCat API session')
|
||||||
|
|
||||||
|
|
||||||
def get_bc_auth_header(self,host,username,password) :
|
def get_bc_auth_header(self,host,username,password) :
|
||||||
@ -54,13 +54,13 @@ class ServiceDelegate(ServiceBase) :
|
|||||||
def search_bc_object(self,subject) :
|
def search_bc_object(self,subject) :
|
||||||
"""Searches BC for the subject."""
|
"""Searches BC for the subject."""
|
||||||
# Search by IP
|
# Search by IP
|
||||||
response = requests.get('https://' + self.host + '/Services/REST/v1/searchByObjectTypes?keyword=' + subject + '&types=IP4Address,IP6Address&start=0&count=10',headers=self.current_auth_header)
|
response = requests.get('https://' + self._host + '/Services/REST/v1/searchByObjectTypes?keyword=' + subject + '&types=IP4Address,IP6Address&start=0&count=10',headers=self._current_auth_header)
|
||||||
return self.clean_response(response)
|
return self.clean_response(response)
|
||||||
|
|
||||||
def search_bc_parent_object(self,subject) :
|
def search_bc_parent_object(self,subject) :
|
||||||
"""Search for and return information about the objects parent, if any"""
|
"""Search for and return information about the objects parent, if any"""
|
||||||
if 'object' in self.return_payload and type(self.return_payload['object']) is dict and 'id' in self.return_payload['object'] :
|
if 'object' in self._return_payload and type(self._return_payload['object']) is dict and 'id' in self._return_payload['object'] :
|
||||||
response = requests.get('https://' + self.host + '/Services/REST/v1/getParent?entityId=' + str(self.return_payload['object']['id']), headers=self.current_auth_header)
|
response = requests.get('https://' + self._host + '/Services/REST/v1/getParent?entityId=' + str(self._return_payload['object']['id']), headers=self._current_auth_header)
|
||||||
return self.clean_response(response)
|
return self.clean_response(response)
|
||||||
# Make a guess that it belongs to a static net that hasn't been put in bluecat
|
# Make a guess that it belongs to a static net that hasn't been put in bluecat
|
||||||
elif subject != '' :
|
elif subject != '' :
|
||||||
@ -68,7 +68,7 @@ class ServiceDelegate(ServiceBase) :
|
|||||||
try :
|
try :
|
||||||
ip = ipaddress.IPv4Network(subject + net,strict=False)
|
ip = ipaddress.IPv4Network(subject + net,strict=False)
|
||||||
network = str(ip.network_address)
|
network = str(ip.network_address)
|
||||||
response = requests.get('https://' + self.host + '/Services/REST/v1/searchByObjectTypes?keyword=' + network + '&types=IP4Network,IP4Block&start=0&count=10',headers=self.current_auth_header)
|
response = requests.get('https://' + self._host + '/Services/REST/v1/searchByObjectTypes?keyword=' + network + '&types=IP4Network,IP4Block&start=0&count=10',headers=self._current_auth_header)
|
||||||
if not response.text.startswith('[]') :
|
if not response.text.startswith('[]') :
|
||||||
return self.clean_response(response)
|
return self.clean_response(response)
|
||||||
except:
|
except:
|
||||||
|
@ -12,8 +12,8 @@ class ServiceDelegate(ServiceBase) :
|
|||||||
|
|
||||||
def startup(self) :
|
def startup(self) :
|
||||||
self.resolver = dns.resolver.Resolver()
|
self.resolver = dns.resolver.Resolver()
|
||||||
if 'resolver' in self.config :
|
if 'resolver' in self._config :
|
||||||
self.resolver.nameservers.append(self.config['resolver'])
|
self.resolver.nameservers.append(self._config['resolver'])
|
||||||
|
|
||||||
def lookup(self,subject) :
|
def lookup(self,subject) :
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ class ServiceDelegate(ServiceBase) :
|
|||||||
subjecttuple = socket.gethostbyname_ex(subject)
|
subjecttuple = socket.gethostbyname_ex(subject)
|
||||||
except socket.gaierror :
|
except socket.gaierror :
|
||||||
# Not a valid host or IP
|
# Not a valid host or IP
|
||||||
self.error.append('Unable to resolve ' + subject)
|
self._error.append('Unable to resolve ' + subject)
|
||||||
subjecttuple = [subject,[],['']]
|
subjecttuple = [subject,[],['']]
|
||||||
# Can't make IPv4 out of it
|
# Can't make IPv4 out of it
|
||||||
except socket.gaierror :
|
except socket.gaierror :
|
||||||
|
@ -8,8 +8,8 @@ urllib3.disable_warnings()
|
|||||||
|
|
||||||
class ServiceDelegate(ServiceBase) :
|
class ServiceDelegate(ServiceBase) :
|
||||||
|
|
||||||
return_payload = {}
|
_return_payload = {}
|
||||||
hosts = None
|
_hosts = None
|
||||||
_partition = 'Common'
|
_partition = 'Common'
|
||||||
|
|
||||||
def get_arguments(cls) :
|
def get_arguments(cls) :
|
||||||
@ -17,28 +17,28 @@ class ServiceDelegate(ServiceBase) :
|
|||||||
|
|
||||||
def startup(self) :
|
def startup(self) :
|
||||||
for requirement in ['hosts','username','key'] :
|
for requirement in ['hosts','username','key'] :
|
||||||
if requirement not in self.config or (requirement in self.config and self.config[requirement] is ''):
|
if requirement not in self._config or (requirement in self._config and self._config[requirement] is ''):
|
||||||
self.error.append('Missing required config option ' + requirement)
|
self._error.append('Missing required config option ' + requirement)
|
||||||
return
|
return
|
||||||
self.hosts = self.config['hosts']
|
self._hosts = self._config['hosts']
|
||||||
self.debug('Logging into F5\'s and searching for hosts, this make take some time.',1)
|
self.debug('Logging into F5\'s and searching for hosts, this make take some time.',1)
|
||||||
|
|
||||||
def lookup(self,subject) :
|
def lookup(self,subject) :
|
||||||
self.return_payload = {}
|
self._return_payload = {}
|
||||||
|
|
||||||
logincandidates = self.choose_host(subject)
|
logincandidates = self.choose_host(subject)
|
||||||
if logincandidates == {} :
|
if logincandidates == {} :
|
||||||
# Idk what to do here, do we give up or do we log in to all of them?
|
# Idk what to do here, do we give up or do we log in to all of them?
|
||||||
self.error.append('Unable to find an LB to log into to check host ' + str(subject))
|
self._error.append('Unable to find an LB to log into to check host ' + str(subject))
|
||||||
return None
|
return None
|
||||||
|
|
||||||
for host in logincandidates.keys() :
|
for host in logincandidates.keys() :
|
||||||
auth_header = self.get_iq_auth_header(host,self.config['username'],self.config['key'])
|
auth_header = self.get_iq_auth_header(host,self._config['username'],self._config['key'])
|
||||||
if not auth_header :
|
if not auth_header :
|
||||||
self.error.append('Unable to log in to ' + host)
|
self._error.append('Unable to log in to ' + host)
|
||||||
continue
|
continue
|
||||||
# Get all VIPs
|
# Get all VIPs
|
||||||
if 'vip' not in self.return_payload :
|
if 'vip' not in self._return_payload :
|
||||||
vips = self.get_vip(host,auth_header);
|
vips = self.get_vip(host,auth_header);
|
||||||
# If it's a VIP, return it and the host and let's be done
|
# If it's a VIP, return it and the host and let's be done
|
||||||
if vips :
|
if vips :
|
||||||
@ -47,11 +47,11 @@ class ServiceDelegate(ServiceBase) :
|
|||||||
all_vips = [ x['destination'] for x in vips ]
|
all_vips = [ x['destination'] for x in vips ]
|
||||||
if len(vip_match) > 0 :
|
if len(vip_match) > 0 :
|
||||||
selected_vip = vip_match[0]
|
selected_vip = vip_match[0]
|
||||||
self.return_payload.update({'vip': selected_vip})
|
self._return_payload.update({'vip': selected_vip})
|
||||||
pool_name = selected_vip['pool'].split('/' + self._partition + '/')[1]
|
pool_name = selected_vip['pool'].split('/' + self._partition + '/')[1]
|
||||||
pool_info = self.get_pool(host,auth_header,pool_name)
|
pool_info = self.get_pool(host,auth_header,pool_name)
|
||||||
if pool_info :
|
if pool_info :
|
||||||
self.return_payload.update(pool_info)
|
self._return_payload.update(pool_info)
|
||||||
break
|
break
|
||||||
else :
|
else :
|
||||||
self.debug('Unable to find VIP in VIPs from host ' + host,2)
|
self.debug('Unable to find VIP in VIPs from host ' + host,2)
|
||||||
@ -62,9 +62,9 @@ class ServiceDelegate(ServiceBase) :
|
|||||||
# Check if address is in the pool. If it is, return the node, pool, vip, and host.
|
# Check if address is in the pool. If it is, return the node, pool, vip, and host.
|
||||||
# Naw, I'll just give up.
|
# Naw, I'll just give up.
|
||||||
self.debug('Unable to get VIPs from ' + host,2)
|
self.debug('Unable to get VIPs from ' + host,2)
|
||||||
if len(self.return_payload) is 0 :
|
if len(self._return_payload) is 0 :
|
||||||
self.return_payload = None
|
self._return_payload = None
|
||||||
return self.return_payload
|
return self._return_payload
|
||||||
|
|
||||||
def shutdown(self) :
|
def shutdown(self) :
|
||||||
return
|
return
|
||||||
@ -127,9 +127,9 @@ class ServiceDelegate(ServiceBase) :
|
|||||||
else :
|
else :
|
||||||
potentialdc = None
|
potentialdc = None
|
||||||
if potentialdc :
|
if potentialdc :
|
||||||
for host in self.hosts.keys() :
|
for host in self._hosts.keys() :
|
||||||
if potentialdc.lower() in host.lower() :
|
if potentialdc.lower() in host.lower() :
|
||||||
hosts.update({host:self.hosts[host]})
|
hosts.update({host:self._hosts[host]})
|
||||||
if hosts != {} :
|
if hosts != {} :
|
||||||
return hosts
|
return hosts
|
||||||
self.debug('Unable to determine DC from subject name: ' + subject,3)
|
self.debug('Unable to determine DC from subject name: ' + subject,3)
|
||||||
@ -139,9 +139,9 @@ class ServiceDelegate(ServiceBase) :
|
|||||||
potentialdc = self.hints['bluecat'][subject]['object']['locationCode'].split(' ')[-1]
|
potentialdc = self.hints['bluecat'][subject]['object']['locationCode'].split(' ')[-1]
|
||||||
elif 'parent' in self.hints['bluecat'][subject] and 'name' in self.hints['bluecat'][subject]['parent'] :
|
elif 'parent' in self.hints['bluecat'][subject] and 'name' in self.hints['bluecat'][subject]['parent'] :
|
||||||
potentialdc = self.hints['bluecat'][subject]['parent']['name'].split(' ')[0]
|
potentialdc = self.hints['bluecat'][subject]['parent']['name'].split(' ')[0]
|
||||||
for host in self.hosts.keys() :
|
for host in self._hosts.keys() :
|
||||||
if potentialdc.lower() in host.lower() :
|
if potentialdc.lower() in host.lower() :
|
||||||
hosts.update({host:self.hosts[host]})
|
hosts.update({host:self._hosts[host]})
|
||||||
self.debug('Got additional host info from the BlueCat plugin!',3)
|
self.debug('Got additional host info from the BlueCat plugin!',3)
|
||||||
return hosts
|
return hosts
|
||||||
return hosts
|
return hosts
|
||||||
|
File diff suppressed because one or more lines are too long
@ -1,10 +1,11 @@
|
|||||||
from servicebase import ServiceBase
|
from servicebase import ServiceBase
|
||||||
import paramiko
|
import paramiko
|
||||||
|
import datetime
|
||||||
import re
|
import re
|
||||||
|
|
||||||
class ServiceDelegate(ServiceBase) :
|
class ServiceDelegate(ServiceBase) :
|
||||||
|
|
||||||
connections = None
|
_connections = None
|
||||||
|
|
||||||
def get_arguments(cls) :
|
def get_arguments(cls) :
|
||||||
"""Returns an array of information used to construct an argumentparser argument."""
|
"""Returns an array of information used to construct an argumentparser argument."""
|
||||||
@ -12,37 +13,38 @@ class ServiceDelegate(ServiceBase) :
|
|||||||
|
|
||||||
def startup(self) :
|
def startup(self) :
|
||||||
for requirement in ['hosts','username','key'] :
|
for requirement in ['hosts','username','key'] :
|
||||||
if requirement not in self.config or (requirement in self.config and self.config[requirement] is ''):
|
if requirement not in self._config or (requirement in self._config and self._config[requirement] is ''):
|
||||||
self.error.append('Missing required config option ' + requirement)
|
self._error.append('Missing required config option ' + requirement)
|
||||||
return
|
rself._error
|
||||||
self.hosts = self.config['hosts']
|
self.hosts = self._config['hosts']
|
||||||
self.debug('Logging into OpenVPN servers...',1)
|
self.debug('Logging into OpenVPN servers...',1)
|
||||||
connections = {}
|
connections = {}
|
||||||
for host in self.config['hosts'] :
|
for host in self._config['hosts'] :
|
||||||
try :
|
try :
|
||||||
sshclient = paramiko.SSHClient()
|
sshclient = paramiko.SSHClient()
|
||||||
sshclient.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
sshclient.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||||
sshclient.connect(host,22,username=self.config['username'],password=self.config['key'])
|
sshclient.connect(host,22,username=self._config['username'],password=self._config['key'])
|
||||||
connections.update({host:sshclient})
|
connections.update({host:sshclient})
|
||||||
except Exception as exception :
|
except Exception as exception :
|
||||||
self.error.append('Unable to ssh into ' + host + ': ' + str(exception))
|
self._error.append('Unable to ssh into ' + host + ': ' + str(exception))
|
||||||
self.connections = connections
|
self._connections = connections
|
||||||
|
|
||||||
|
|
||||||
def shutdown(self) :
|
def shutdown(self) :
|
||||||
for connection in self.connections.values() :
|
for connection in self._connections.values() :
|
||||||
connection.close()
|
connection.close()
|
||||||
|
|
||||||
def lookup(self,subject) :
|
def lookup(self,subject) :
|
||||||
search_command = 'sudo -S cat /var/log/openvpn/openvpn.log | grep \'primary virtual IP for\' | grep \'' + subject + '\' | tail -n 1'
|
search_command = 'sudo -S cat /var/log/openvpn/openvpn.log | grep \'primary virtual IP for\' | grep \'' + subject + '\' | tail -n 1'
|
||||||
for host,connection in self.connections.items() :
|
final_dictionary = {}
|
||||||
|
for host,connection in self._connections.items() :
|
||||||
try:
|
try:
|
||||||
stdin,stdout,stderr=connection.exec_command(search_command)
|
stdin,stdout,stderr=connection.exec_command(search_command)
|
||||||
stdin.write(self.config['key'] + '\n')
|
stdin.write(self._config['key'] + '\n')
|
||||||
stdin.flush()
|
stdin.flush()
|
||||||
result = stdout.readlines()
|
result = stdout.readlines()
|
||||||
if len(result) > 0 :
|
if len(result) > 0 :
|
||||||
self.debug('Retrieved line from ssh session: \n' + result[0],2)
|
self.debug('Retrieved line from ssh session: \n' + result[0].strip(),2)
|
||||||
result = result[0]
|
result = result[0]
|
||||||
else :
|
else :
|
||||||
result = ''
|
result = ''
|
||||||
@ -54,9 +56,23 @@ class ServiceDelegate(ServiceBase) :
|
|||||||
return_dictionary.update({item: matches[1]})
|
return_dictionary.update({item: matches[1]})
|
||||||
if len(return_dictionary) > 0 :
|
if len(return_dictionary) > 0 :
|
||||||
return_dictionary.update({'host':host})
|
return_dictionary.update({'host':host})
|
||||||
return return_dictionary
|
|
||||||
|
epoch = None
|
||||||
|
if 'timestamp' in final_dictionary.keys() and 'timestamp' in return_dictionary.keys() :
|
||||||
|
epoch = int(datetime.datetime.strptime(return_dictionary['timestamp'] + ' ' + str(datetime.datetime.now().year), '%b %d %H:%M:%S %Y').strftime('%s'))
|
||||||
|
if len(return_dictionary) > 0 :
|
||||||
|
if epoch :
|
||||||
|
if epoch > int(datetime.datetime.strptime(final_dictionary['timestamp'] + ' ' + str(datetime.datetime.now().year), '%b %d %H:%M:%S %Y').strftime('%s')) :
|
||||||
|
final_dictionary = {}
|
||||||
|
final_dictionary.update(return_dictionary)
|
||||||
|
else :
|
||||||
|
final_dictionary = return_dictionary
|
||||||
else :
|
else :
|
||||||
return None
|
self.debug('No results for ' + subject + ' on host ' + host,2)
|
||||||
except Exception as exception :
|
except Exception as exception :
|
||||||
self.error.append('Unable to get results from ssh: ' + str(exception))
|
raise exception
|
||||||
pass
|
self._error.append('Unable to get results from ssh: ' + str(exception))
|
||||||
|
if len(final_dictionary) > 0 :
|
||||||
|
return final_dictionary
|
||||||
|
else :
|
||||||
|
return None
|
||||||
|
@ -15,10 +15,10 @@ class ServiceDelegate(ServiceBase) :
|
|||||||
|
|
||||||
def startup(self) :
|
def startup(self) :
|
||||||
for requirement in ['keys'] :
|
for requirement in ['keys'] :
|
||||||
if requirement not in self.config or (requirement in self.config and self.config[requirement] is ''):
|
if requirement not in self._config or (requirement in self._config and self._config[requirement] is ''):
|
||||||
self.error.append('Missing required config option ' + requirement)
|
self._error.append('Missing required config option ' + requirement)
|
||||||
return
|
return
|
||||||
keys = self.config['keys']
|
keys = self._config['keys']
|
||||||
self._api_sessions = [shodan.Shodan(x) for x in keys]
|
self._api_sessions = [shodan.Shodan(x) for x in keys]
|
||||||
self.debug('Searching Shodan for hosts...',1)
|
self.debug('Searching Shodan for hosts...',1)
|
||||||
|
|
||||||
|
@ -10,14 +10,12 @@ class ServiceDelegate(ServiceBase) :
|
|||||||
|
|
||||||
def startup(self) :
|
def startup(self) :
|
||||||
self.resolver = dns.resolver.Resolver()
|
self.resolver = dns.resolver.Resolver()
|
||||||
if 'resolver' in self.config :
|
if 'resolver' in self._config :
|
||||||
self.resolver.nameservers.append(self.config['resolver'])
|
self.resolver.nameservers.append(self._config['resolver'])
|
||||||
|
|
||||||
def lookup(self,subject) :
|
def lookup(self,subject) :
|
||||||
|
|
||||||
# Note : hostname lookups always use system resolver.
|
# Note : hostname lookups always use system resolver.
|
||||||
# TODO: Make host lookups use the config-sepcified resolver.
|
|
||||||
|
|
||||||
try :
|
try :
|
||||||
subjecttuple = socket.gethostbyname_ex(subject)
|
subjecttuple = socket.gethostbyname_ex(subject)
|
||||||
# Can't make an IP of the subject
|
# Can't make an IP of the subject
|
||||||
@ -27,11 +25,11 @@ class ServiceDelegate(ServiceBase) :
|
|||||||
subjecttuple = socket.gethostbyname_ex(subject)
|
subjecttuple = socket.gethostbyname_ex(subject)
|
||||||
except socket.gaierror :
|
except socket.gaierror :
|
||||||
# Not a valid host or IP
|
# Not a valid host or IP
|
||||||
self.error.append("Unable to resolve " + subject)
|
self._error.append("Unable to resolve " + subject)
|
||||||
subjecttuple = [subject,[],['']]
|
subjecttuple = [subject,[],['']]
|
||||||
# Can't make IPv4 out of it
|
# Can't make IPv4 out of it
|
||||||
except socket.gaierror :
|
except socket.gaierror :
|
||||||
self.error.append("Unable to resolve " + subject)
|
self._error.append("Unable to resolve " + subject)
|
||||||
subjecttuple = [subject,[],['']]
|
subjecttuple = [subject,[],['']]
|
||||||
# Get additional records
|
# Get additional records
|
||||||
return_dict = {}
|
return_dict = {}
|
||||||
|
@ -1,22 +1,20 @@
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
class ServiceBase :
|
class ServiceBase :
|
||||||
config = {}
|
_config = {}
|
||||||
namespace = {}
|
|
||||||
data = {}
|
|
||||||
error = []
|
error = []
|
||||||
warn = []
|
warn = []
|
||||||
_status = "Ready"
|
_status = "Ready"
|
||||||
def __init__(self,hints={},config={}):
|
def __init__(self,hints={},config={}):
|
||||||
self.config = config
|
self._config = config
|
||||||
self.error = []
|
self._error = []
|
||||||
self.warn = []
|
self._warn = []
|
||||||
self.hints = hints
|
self.hints = hints
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _set_config(self,config) :
|
def _set_config(self,config) :
|
||||||
"""Allows for post-initialization configuration"""
|
"""Allows for post-initialization configuration"""
|
||||||
self.config = config
|
self._config = config
|
||||||
|
|
||||||
def _set_hints(self,hints) :
|
def _set_hints(self,hints) :
|
||||||
"""Allows for post-initialization configuration of hint data"""
|
"""Allows for post-initialization configuration of hint data"""
|
||||||
@ -28,7 +26,7 @@ class ServiceBase :
|
|||||||
|
|
||||||
def debug(self,message,verbosity_level) :
|
def debug(self,message,verbosity_level) :
|
||||||
"""Prints the submitted message if the environment's verbosity level matches or is surpassed by the submitted level."""
|
"""Prints the submitted message if the environment's verbosity level matches or is surpassed by the submitted level."""
|
||||||
if self.config['_namespace']['debug'] and self.config['_namespace']['debug'] >= verbosity_level :
|
if self._config['_namespace']['debug'] and self._config['_namespace']['debug'] >= verbosity_level :
|
||||||
print(message,file=sys.stderr)
|
print(message,file=sys.stderr)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
Loading…
Reference in New Issue
Block a user