ifxlookup/plugins/bluecat.py

111 lines
4.1 KiB
Python
Raw Normal View History

from servicebase import ServiceBase
import ipaddress
2019-12-05 16:52:32 +00:00
import requests
import json
class ServiceDelegate(ServiceBase) :
2019-12-05 16:52:32 +00:00
current_auth_header = None
2020-05-26 18:26:01 +00:00
_return_payload = {}
_host = None
2019-12-05 16:52:32 +00:00
2019-12-04 19:00:50 +00:00
def get_arguments(cls) :
2020-05-22 18:28:13 +00:00
return ['-b', '--bluecat', 'store_true', 'Return network information about the subject (bluecat)']
2019-12-05 16:52:32 +00:00
def startup(self) :
for requirement in ['host','username','key'] :
if requirement not in self._config or (requirement in self._config and (self._config[requirement] == '' or type(self._config[requirement]) != str)):
2020-05-26 18:26:01 +00:00
self._error.append('Missing required config option ' + requirement)
2019-12-05 16:52:32 +00:00
return
2020-05-26 18:26:01 +00:00
self._host = self._config['host']
self._current_auth_header = self.get_bc_auth_header(self._config['host'],self._config['username'],self._config['key'])
2020-06-19 20:52:26 +00:00
self.debug('Logged into BlueCat',1)
2019-12-05 16:52:32 +00:00
def lookup(self,subject) :
2020-05-26 18:26:01 +00:00
self._return_payload = {}
if self._current_auth_header :
2020-06-19 20:52:26 +00:00
objects = self.search_bc_objects(subject)
if objects :
if type(objects) == list :
2020-06-19 20:52:26 +00:00
object_list = []
for object in objects :
result = {'object':object}
parent = self.search_bc_parent_object(object)
if parent :
result.update({'parent':parent})
object_list.append(result)
if len(object_list) > 0 :
return object_list
else :
self._return_payload.update({'object':objects})
parent = self.search_bc_parent_object(subject)
if parent :
self._return_payload.update({'parent':parent})
if len(self._return_payload) > 0 :
return self._return_payload
else :
return None
else :
2020-05-22 18:28:13 +00:00
return None
2019-12-05 16:52:32 +00:00
def shutdown(self) :
2020-05-26 18:26:01 +00:00
if self._host and self._current_auth_header :
logout = requests.get('https://' + self._host + '/Services/REST/v1/logout',headers=self._current_auth_header)
2020-05-22 18:28:13 +00:00
if not logout.text.endswith('successfully logged out.\"') :
2020-05-26 18:26:01 +00:00
self._error.append('Unable to log out of BlueCat API session')
2019-12-05 16:52:32 +00:00
def get_bc_auth_header(self,host,username,password) :
2020-05-22 18:28:13 +00:00
auth_token = requests.get('https://' + host + '/Services/REST/v1/login?username=' + username + '&password=' + password).text[17:71]
2019-12-05 16:52:32 +00:00
if auth_token.startswith('BAMAuthToken') :
2020-05-22 18:28:13 +00:00
return { 'Authorization' : auth_token }
2019-12-05 16:52:32 +00:00
else :
return None
2020-06-19 20:52:26 +00:00
def search_bc_objects(self,subject) :
2019-12-05 16:52:32 +00:00
"""Searches BC for the subject."""
# Search by IP
2020-05-26 18:26:01 +00:00
response = requests.get('https://' + self._host + '/Services/REST/v1/searchByObjectTypes?keyword=' + subject + '&types=IP4Address,IP6Address&start=0&count=10',headers=self._current_auth_header)
2019-12-05 16:52:32 +00:00
return self.clean_response(response)
2020-06-19 20:52:26 +00:00
def search_bc_parent_object(self,object) :
2019-12-05 16:52:32 +00:00
"""Search for and return information about the objects parent, if any"""
if type(object) == dict and 'id' in object :
2020-06-19 20:52:26 +00:00
response = requests.get('https://' + self._host + '/Services/REST/v1/getParent?entityId=' + str(object['id']), headers=self._current_auth_header)
2019-12-05 16:52:32 +00:00
return self.clean_response(response)
# Make a guess that it belongs to a static net that hasn't been put in bluecat
2020-06-19 20:52:26 +00:00
elif object != '' :
for net in ['/27', '/26', '/25', '/24', '/23', '/22'] :
try :
ip = ipaddress.IPv4Network(subject + net,strict=False)
network = str(ip.network_address)
2020-05-26 18:26:01 +00:00
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('[]') :
return self.clean_response(response)
except:
pass
2019-12-05 16:52:32 +00:00
def clean_response(self,response) :
2020-06-19 20:52:26 +00:00
def clean(item) :
if 'properties' in item :
item['properties'] = item['properties'][:-1]
bad_delim_props = [x for x in item['properties'].split('|') if x.count('=') > 1]
if len(bad_delim_props) > 0 :
item.update({'unknown':bad_delim_props})
attributes = dict(x.split('=') for x in item['properties'].split('|') if x.count('=') == 1)
item.pop('properties', None)
item.update(attributes)
return item
2019-12-05 16:52:32 +00:00
parsed = {}
try :
parsed = json.loads(response.text)
except Exception :
return parsed
if type(parsed) == list and len(parsed) > 0 :
2020-06-19 20:52:26 +00:00
for item in parsed:
item = clean(item)
2019-12-05 16:52:32 +00:00
return parsed
if type(parsed) == dict :
2020-06-19 20:52:26 +00:00
return clean(parsed)