def test_shutdown_ip(): class MockBcfProxy(BcfProxy): def __init__(self): self.endpoints = None def get_endpoints(self): return self.endpoints def shutdown_endpoint(self, tenant, segment, name, mac, shutdown): pass bcf = MockBcfProxy() filemap = { '/data/controller/applications/bcf/info/fabric/switch': 'sample_switches.json', '/data/controller/applications/bcf/info/endpoint-manager/tenant': 'sample_tenants.json', '/data/controller/applications/bcf/info/endpoint-manager/segment': 'sample_segments.json', '/data/controller/applications/bcf/info/endpoint-manager/endpoint': 'sample_endpoints.json', '/data/controller/applications/bcf/span-fabric': 'sample_span_fabric.json', # %22 = url-encoded double quotes '/data/controller/applications/bcf/span-fabric[name=%22vent%22]': 'sample_span_fabric.json', } proxy = None endpoints = None with HTTMock(mock_factory(r'.*', filemap)): proxy = BcfProxy('http://localhost', 'login', { 'username': username, 'password': password }) endpoints = proxy.get_endpoints() bcf.endpoints = endpoints ret_val = bcf.shutdown_ip('10.0.0.1') answer = list([{ 'ip-address': '10.0.0.1', 'ip-state': 'learned', 'mac': '00:00:00:00:00:01', 'segment': 'poseidon', 'tenant': 'poseidon', 'name': None }]) assert str(answer) == str(ret_val) ret_val = bcf.shutdown_ip('10.0.0.1', mac_addr='00:00:00:00:00:01') answer = list([{ 'mac': '00:00:00:00:00:01', 'name': None, 'tenant': 'poseidon', 'segment': 'poseidon' }]) assert str(answer) == str(ret_val)
def test_unmirror_ip(): class MockBcfProxy(BcfProxy): def __init__(self): self.endpoints = None self.span_fabric = None def get_endpoints(self): return self.endpoints def mirror_traffic(self, seq, mirror=True, span_name='vent', s_dict=None, fabric_span_endpoint='', **target_kwargs): pass def get_span_fabric(self): return self.span_fabric def shutdown_endpoint(self, tenant, segment, name, mac, shutdown): pass bcf = MockBcfProxy() filemap = { '/data/controller/applications/bcf/info/fabric/switch': 'sample_switches.json', '/data/controller/applications/bcf/info/endpoint-manager/tenant': 'sample_tenants.json', '/data/controller/applications/bcf/info/endpoint-manager/segment': 'sample_segments.json', '/data/controller/applications/bcf/info/endpoint-manager/endpoint': 'sample_endpoints.json', '/data/controller/applications/bcf/span-fabric': 'sample_span_fabric.json', # %22 = url-encoded double quotes '/data/controller/applications/bcf/span-fabric[name=%22vent%22]': 'sample_span_fabric.json', } proxy = None endpoints = None span_fabric = None with HTTMock(mock_factory(r'.*', filemap)): proxy = BcfProxy('http://localhost', 'login', { 'username': username, 'password': password }) endpoints = proxy.get_endpoints() span_fabric = proxy.get_span_fabric() bcf.endpoints = endpoints bcf.span_fabric = span_fabric ret_val = bcf.unmirror_ip('10.0.0.2')
def test_get_highest(): class MockBcfProxy(BcfProxy): def __init__(self): self.endpoints = None self.span_fabric = None # def get_endpoints(self): # return self.endpoints # def get_span_fabric(self): # return self.span_fabric # def shutdown_endpoint(self, tenant, segment, name, mac, shutdown): # pass bcf = MockBcfProxy() filemap = { '/data/controller/applications/bcf/info/fabric/switch': 'sample_switches.json', '/data/controller/applications/bcf/info/endpoint-manager/tenant': 'sample_tenants.json', '/data/controller/applications/bcf/info/endpoint-manager/segment': 'sample_segments.json', '/data/controller/applications/bcf/info/endpoint-manager/endpoint': 'sample_endpoints.json', '/data/controller/applications/bcf/span-fabric[name=%22SPAN_FABRIC%22]': 'sample_span_fabric.json', # %22 = url-encoded double quotes '/data/controller/applications/bcf/span-fabric[name=%22SPAN_FABRIC%22][dest-interface-group=%22INTERFACE_GROUP%22]': 'sample_span_fabric.json', } proxy = None endpoints = None span_fabric = None with HTTMock(mock_factory(r'.*', filemap)): proxy = BcfProxy('http://localhost', 'login', { 'username': username, 'password': password }, span_fabric_name='SPAN_FABRIC', interface_group='INTERFACE_GROUP') endpoints = proxy.get_endpoints() span_fabric = proxy.get_span_fabric() bcf.endpoints = endpoints bcf.span_fabric = span_fabric ret_val = bcf.get_highest(span_fabric) answer = 3 assert answer == ret_val
def test_get_byip(): class MockBcfProxy(BcfProxy): def __init__(self): self.endpoints = None self.logger = MockLogger().logger self.poseidon_logger = MockLogger().poseidon_logger def get_endpoints(self): return self.endpoints bcf = MockBcfProxy() filemap = { '/data/controller/applications/bcf/info/fabric/switch': 'sample_switches.json', '/data/controller/applications/bcf/info/endpoint-manager/tenant': 'sample_tenants.json', '/data/controller/applications/bcf/info/endpoint-manager/segment': 'sample_segments.json', '/data/controller/applications/bcf/info/endpoint-manager/endpoint': 'sample_endpoints.json', '/data/controller/applications/bcf/span-fabric[name=%22SPAN_FABRIC%22]': 'sample_span_fabric.json', # %22 = url-encoded double quotes '/data/controller/applications/bcf/span-fabric[name=%22SPAN_FABRIC%22][dest-interface-group=%22INTERFACE_GROUP%22]': 'sample_span_fabric.json', } proxy = None endpoints = None with HTTMock(mock_factory(r'.*', filemap)): proxy = BcfProxy('http://localhost', 'login', { 'username': username, 'password': password }, span_fabric_name='SPAN_FABRIC', interface_group='INTERFACE_GROUP') endpoints = proxy.get_endpoints() bcf.endpoints = endpoints ret_val = bcf.get_byip('10.0.0.1') answer = list([{ 'ip-address': '10.0.0.1', 'ip-state': 'learned', 'mac': '00:00:00:00:00:01', 'segment': 'poseidon', 'tenant': 'poseidon', 'name': None }]) assert str(answer) == str(ret_val)
def test_get_seq_by_ip(): class MockBcfProxy(BcfProxy): def __init__(self): self.endpoints = None self.span_fabric = None # def get_endpoints(self): # return self.endpoints def get_span_fabric(self): return self.span_fabric # def shutdown_endpoint(self, tenant, segment, name, mac, shutdown): # pass bcf = MockBcfProxy() filemap = { '/data/controller/applications/bcf/info/fabric/switch': 'sample_switches.json', '/data/controller/applications/bcf/info/endpoint-manager/tenant': 'sample_tenants.json', '/data/controller/applications/bcf/info/endpoint-manager/segment': 'sample_segments.json', '/data/controller/applications/bcf/info/endpoint-manager/endpoint': 'sample_endpoints.json', '/data/controller/applications/bcf/span-fabric': 'sample_span_fabric.json', # %22 = url-encoded double quotes '/data/controller/applications/bcf/span-fabric[name=%22vent%22]': 'sample_span_fabric.json', } proxy = None endpoints = None span_fabric = None with HTTMock(mock_factory(r'.*', filemap)): proxy = BcfProxy('http://localhost', 'login', { 'username': username, 'password': password }) endpoints = proxy.get_endpoints() span_fabric = proxy.get_span_fabric() bcf.endpoints = endpoints bcf.span_fabric = span_fabric ret_val = bcf.get_seq_by_ip('10.0.0.2') answer = list() assert answer == ret_val
def test_unmirror_mac(): class MockBcfProxy(BcfProxy): def __init__(self): self.endpoints = None self.span_fabric = None self.logger = MockLogger().logger self.poseidon_logger = MockLogger().poseidon_logger def get_span_fabric(self): return self.span_fabric bcf = MockBcfProxy() filemap = { '/data/controller/applications/bcf/info/fabric/switch': 'sample_switches.json', '/data/controller/applications/bcf/info/endpoint-manager/tenant': 'sample_tenants.json', '/data/controller/applications/bcf/info/endpoint-manager/segment': 'sample_segments.json', '/data/controller/applications/bcf/info/endpoint-manager/endpoint': 'sample_endpoints.json', '/data/controller/applications/bcf/span-fabric[name=%22SPAN_FABRIC%22]': 'sample_span_fabric.json', # %22 = url-encoded double quotes '/data/controller/applications/bcf/span-fabric[name=%22SPAN_FABRIC%22][dest-interface-group=%22INTERFACE_GROUP%22]': 'sample_span_fabric.json', } proxy = None endpoints = None span_fabric = None with HTTMock(mock_factory(r'.*', filemap)): proxy = BcfProxy('http://localhost', 'login', { 'username': username, 'password': password }, span_fabric_name='SPAN_FABRIC', interface_group='INTERFACE_GROUP') endpoints = proxy.get_endpoints() span_fabric = proxy.get_span_fabric() bcf.endpoints = endpoints bcf.span_fabric = span_fabric ret_val = bcf.unmirror_mac('00:00:00:00:00:01')
def first_run(self): ''' do some pre-run setup/configuration ''' if self.configured: self.controller['TYPE'] = str( self.mod_configuration['controller_type']) if self.controller['TYPE'] == 'bcf': self.controller['URI'] = str( self.mod_configuration['controller_uri']) self.controller['USER'] = str( self.mod_configuration['controller_user']) self.controller['PASS'] = str( self.mod_configuration['controller_pass']) myauth = {} myauth['password'] = self.controller['PASS'] myauth['user'] = self.controller['USER'] try: self.sdnc = BcfProxy(self.controller['URI'], auth=myauth) except BaseException: self.logger.error( 'BcfProxy could not connect to {0}'.format( self.controller['URI'])) elif self.controller['TYPE'] == 'faucet': try: if 'controller_uri' in self.mod_configuration: self.controller['URI'] = str( self.mod_configuration['controller_uri']) if 'controller_user' in self.mod_configuration: self.controller['USER'] = str( self.mod_configuration['controller_user']) if 'controller_pass' in self.mod_configuration: self.controller['PASS'] = str( self.mod_configuration['controller_pass']) if 'controller_config_file' in self.mod_configuration: self.controller['CONFIG_FILE'] = str( self.mod_configuration['controller_config_file']) if 'controller_log_file' in self.mod_configuration: self.controller['LOG_FILE'] = str( self.mod_configuration['controller_log_file']) if 'controller_mirror_ports' in self.mod_configuration: self.controller['MIRROR_PORTS'] = ast.literal_eval( self.mod_configuration['controller_mirror_ports']) self.sdnc = FaucetProxy( host=self.controller['URI'], user=self.controller['USER'], pw=self.controller['PASS'], config_file=self.controller['CONFIG_FILE'], log_file=self.controller['LOG_FILE'], mirror_ports=self.controller['MIRROR_PORTS']) except BaseException as e: # pragma: no cover self.logger.error( 'FaucetProxy could not connect to {0} because {1}'. format(self.controller['URI'], e)) else: self.logger.error('Unknown SDN controller type {0}'.format( self.controller['TYPE'])) else: pass
def first_run(self): ''' do some pre-run setup/configuration ''' if self.configured: self.controller['URI'] = str( self.mod_configuration['controller_uri']) self.controller['USER'] = str( self.mod_configuration['controller_user']) self.controller['PASS'] = str( self.mod_configuration['controller_pass']) myauth = {} myauth['password'] = self.controller['PASS'] myauth['user'] = self.controller['USER'] try: self.bcf = BcfProxy(self.controller['URI'], auth=myauth) except BaseException: self.logger.error('BcfProxy coult not connect to {0}'.format( self.controller['URI'])) else: pass
def test_format_endpoints(): input_data = list([{'attachment-point': {'switch-interface': {'interface': 'ethernet16', 'switch': 'leaf02'}, 'type': 'switch-interface'}, 'attachment-point-state': 'learned', 'created-since': '2017-09-18T16:28:34.694Z', 'detail': 'true', 'interface': 'ethernet16', 'ip-address': [{'ip-address': '10.0.0.101', 'ip-state': 'learned', 'mac': 'f8:b1:56:fe:f2:de', 'segment': 'prod', 'tenant': 'FLOORPLATE'}], 'leaf-group': '00:00:f4:8e:38:16:a3:73', 'mac': 'f8:b1:56:fe:f2:de', 'nat-endpoint': False, 'remote': False, 'segment': 'prod', 'state': 'Active', 'switch': 'leaf02', 'tenant': 'FLOORPLATE', 'vlan': -1}, {'attachment-point': {'switch-interface': {'interface': 'ethernet42', 'switch': 'leaf01'}, 'type': 'switch-interface'}, 'attachment-point-state': 'learned', 'created-since': '2017-07-11T23:56:23.888Z', 'detail': 'true', 'interface': 'ethernet42', 'leaf-group': '00:00:f4:8e:38:16:b3:73', 'mac': '20:4c:9e:5f:e3:a3', 'nat-endpoint': False, 'remote': False, 'segment': 'to-core-router', 'state': 'Active', 'switch': 'leaf01', 'tenant': 'EXTERNAL', 'vlan': -1}]) output = BcfProxy.format_endpoints(input_data) answer = list([{'ip-address': '10.0.0.101', 'mac': 'f8:b1:56:fe:f2:de', 'segment': 'prod', 'tenant': 'FLOORPLATE', 'name': None}]) assert str(answer) == str(output)
class Update_Switch_State(Monitor_Helper_Base): ''' handle periodic process, determine if switch state updated ''' def __init__(self): super(Update_Switch_State, self).__init__() self.logger = module_logger.logger self.mod_name = self.__class__.__name__ self.retval = {} self.times = 0 self.owner = None self.controller = {} self.controller['URI'] = None self.controller['USER'] = None self.controller['PASS'] = None self.bcf = None self.first_time = True self.endpoint_states = defaultdict(dict) self.m_queue = Queue.Queue() def return_endpoint_state(self): return self.endpoint_states def first_run(self): ''' do some pre-run setup/configuration ''' if self.configured: self.controller['URI'] = str( self.mod_configuration['controller_uri']) self.controller['USER'] = str( self.mod_configuration['controller_user']) self.controller['PASS'] = str( self.mod_configuration['controller_pass']) myauth = {} myauth['password'] = self.controller['PASS'] myauth['user'] = self.controller['USER'] try: self.bcf = BcfProxy(self.controller['URI'], auth=myauth) except BaseException: self.logger.error('BcfProxy coult not connect to {0}'.format( self.controller['URI'])) else: pass @staticmethod def make_hash(item): ''' hash the metadata in a sane way''' h = hashlib.new('ripemd160') pre_h = str() post_h = None # nodhcp -> dhcp withname makes different hashes # {u'tenant': u'FLOORPLATE', u'mac': u'ac:87:a3:2b:7f:12', u'segment': u'prod', u'name': None, u'ip-address': u'10.179.0.100'}}^ # {u'tenant': u'FLOORPLATE', u'mac': u'ac:87:a3:2b:7f:12', u'segment': u'prod', u'name': u'demo-laptop', u'ip-address': u'10.179.0.100'}} # ^^^ make different hashes if name is included # for word in ['tenant', 'mac', 'segment', 'name', 'ip-address']: for word in ['tenant', 'mac', 'segment', 'ip-address']: pre_h = pre_h + str(item.get(str(word), 'missing')) h.update(pre_h) post_h = h.hexdigest() return post_h def get_endpoint_state(self, my_hash): if my_hash in self.endpoint_states: return self.endpoint_states[my_hash]['state'] return None def get_endpoint_ip(self, my_hash): if my_hash in self.endpoint_states: return self.endpoint_states[my_hash]['endpoint']['ip-address'] return None def shutdown_endpoint(self, my_hash, next_state='SHUTDOWN'): if my_hash in self.endpoint_states: if self.get_endpoint_state(my_hash) != next_state: my_ip = self.get_endpoint_ip(my_hash) self.bcf.shutdown_ip(my_ip) self.change_endpoint_state(my_hash) self.logger.debug('endpoint:{0}:{1}:{2}'.format( my_hash, my_ip, next_state)) return True return False def mirror_endpoint(self, my_hash, next_state='MIRRORING'): if my_hash in self.endpoint_states: if self.get_endpoint_state(my_hash) != next_state: my_ip = self.get_endpoint_ip(my_hash) self.bcf.mirror_ip(my_ip) self.change_endpoint_state(my_hash) self.logger.debug('endpoint:{0}:{1}:{2}'.format( my_hash, my_ip, next_state)) return True return False def make_known_endpoint(self, my_hash, next_state='KNOWN'): if my_hash in self.endpoint_states: if self.get_endpoint_state(my_hash) != next_state: my_ip = self.get_endpoint_ip(my_hash) self.bcf.unmirror_ip(my_ip) self.change_endpoint_state(my_hash, 'KNOWN') self.logger.debug('endpoint:{0}:{1}:{2}'.format( my_hash, my_ip, next_state)) return True return False def make_endpoint_dict(self, my_hash, state, data): self.endpoint_states[my_hash]['state'] = state self.endpoint_states[my_hash]['next-state'] = 'NONE' self.endpoint_states[my_hash]['endpoint'] = data def change_endpoint_state(self, my_hash, new_state=None): self.endpoint_states[my_hash][ 'state'] = new_state or self.endpoint_states[my_hash]['next-state'] self.endpoint_states[my_hash]['next-state'] = 'NONE' def find_new_machines(self, machines): '''parse switch structure to find new machines added to network since last call''' if self.first_time: self.first_time = False # TODO db call to see if really need to run things for machine in machines: h = self.make_hash(machine) self.logger.critical( 'adding address to known systems {0}'.format(machine)) self.make_endpoint_dict(h, 'KNOWN', machine) else: for machine in machines: h = self.make_hash(machine) if h not in self.endpoint_states: self.logger.critical( '***** detected new address {0}'.format(machine)) self.make_endpoint_dict(h, 'UNKNOWN', machine) def print_endpoint_state(self): def same_old(logger, state, letter, endpoint_states): logger.debug('*******{0}*********'.format(state)) out_flag = False for my_hash in endpoint_states.keys(): my_dict = endpoint_states[my_hash] if my_dict['state'] == state: out_flag = True logger.debug('{0}:{1}:{2}->{3}:{4}'.format( letter, my_hash, my_dict['state'], my_dict['next-state'], my_dict['endpoint'])) if not out_flag: logger.debug('None') states = [('K', 'KNOWN'), ('U', 'UNKNOWN'), ('M', 'MIRRORING'), ('S', 'SHUTDOWN'), ('R', 'REINVESTIGATING')] for l, s in states: same_old(self.logger, s, l, self.endpoint_states) self.logger.debug('****************') def update_endpoint_state(self): '''Handles Get requests''' self.retval['service'] = self.owner.mod_name + ':' + self.mod_name self.retval['times'] = self.times self.retval['machines'] = None self.retval['resp'] = 'bad' current = None parsed = None machines = {} try: current = self.bcf.get_endpoints() parsed = self.bcf.format_endpoints(current) machines = parsed except BaseException: self.logger.error('Could not establish connection to {0}.'.format( self.controller['URI'])) self.retval[ 'controller'] = 'Could not establish connection to {0}.'.format( self.controller['URI']) self.logger.debug('MACHINES:{0}'.format(machines)) self.find_new_machines(machines) self.print_endpoint_state() self.retval['machines'] = parsed self.retval['resp'] = 'ok' self.times = self.times + 1 return json.dumps(self.retval)
def test_BcfProxy(): """ Tests bcf """ filemap = { '/data/controller/applications/bcf/info/fabric/switch': 'sample_switches.json', '/data/controller/applications/bcf/info/endpoint-manager/tenant': 'sample_tenants.json', '/data/controller/applications/bcf/info/endpoint-manager/segment': 'sample_segments.json', '/data/controller/applications/bcf/info/endpoint-manager/endpoint': 'sample_endpoints.json', '/data/controller/applications/bcf/span-fabric': 'sample_span_fabric.json', # %22 = url-encoded double quotes '/data/controller/applications/bcf/span-fabric[name=%22vent%22]': 'sample_span_fabric.json', } proxy = None with HTTMock(mock_factory(r'.*', filemap)): proxy = BcfProxy('http://localhost', 'login', { 'username': username, 'password': password }) endpoints = proxy.get_endpoints() assert endpoints switches = proxy.get_switches() assert switches tenants = proxy.get_tenants() assert tenants segments = proxy.get_segments() assert segments span_fabric = proxy.get_span_fabric() assert span_fabric span_fabric = proxy.get_span_fabric(span_name="vent") assert span_fabric with HTTMock(mock_factory2(r'.*')): # Normally shutdown_endpoint does not return a value. # You should call get_endpoint() afterwards to verify that a shutdown request went through. # In addition, the mock endpoint generated does not check for duplicates. # TODO: ***This code below is temporary.*** r = proxy.shutdown_endpoint(tenant="TENANT", segment="SEGMENT", endpoint_name="test", mac="00:00:00:00:00:00", shutdown=True) assert r r = proxy.shutdown_endpoint(tenant="TENANT", segment="SEGMENT", endpoint_name="test", mac="00:00:00:00:00:00", shutdown=False) assert r r = proxy.mirror_traffic(seq=2, mirror=True, tenant="TENANT", segment="SEGMENT") assert r r = proxy.mirror_traffic(seq=2, mirror=False) assert r def r(): return None r.text = "" BcfProxy.parse_json(r) proxy.session.cookies.clear_session_cookies() proxy.base_uri = "http://jsonplaceholder.typicode.com" r = proxy.post_resource('posts') r.raise_for_status() r = proxy.request_resource( method="PUT", url="http://jsonplaceholder.typicode.com/posts/1") r.raise_for_status()
class Handle_Periodic(Monitor_Helper_Base): ''' handle periodic process, determine if switch state updated ''' def __init__(self): super(Handle_Periodic, self).__init__() self.logger = module_logger self.mod_name = self.__class__.__name__ self.retval = {} self.times = 0 self.owner = None self.controller = {} self.controller['URI'] = None self.controller['USER'] = None self.controller['PASS'] = None self.bcf = None self.first_time = True self.prev_endpoints = {} self.new_endpoints = {} self.mirroring = {} self.shutdown = {} self.do_rabbit = True self.m_queue = Queue.Queue() self.rabbit_connection_local = None self.rabbit_channel_local = None if getenv('SKIPRABBIT') is None: module_logger.critical('handle_periodic skipping rabbit') self.do_rabbit = False else: module_logger.critical('handle_periodic starting rabbit') self.start_rabbit() # TODO init the rabbitmq # rabbit def start_rabbit(self): ''' start the rabbit negotiations ''' self.init_rabbit() if self.do_rabbit: self.start_channel(self.rabbit_channel_local, callback, 'poseidon_NBCA') def make_rabbit_connection(self, host, exchange, queue_name, keys): # pragma: no cover ''' Continuously loops trying to connect to rabbitmq, once connected declares the exchange and queue for processing algorithm results. ''' wait = True channel = None connection = None total_sleep = 30 while wait and total_sleep > 0: try: connection = pika.BlockingConnection( pika.ConnectionParameters(host=host)) channel = connection.channel() channel.exchange_declare(exchange=exchange, type='topic') channel.queue_declare(queue=queue_name, exclusive=True) self.logger.debug( '************* connected to {0} rabbitMQ'.format(host)) wait = False except Exception as e: self.logger.debug( '************* waiting for {0} rabbitQM'.format(host)) self.logger.debug(str(e)) time.sleep(2) total_sleep -= 2 wait = True if wait: self.do_rabbit = False if isinstance(keys, types.ListType) and not wait: for key in keys: self.logger.debug( 'array adding key:{0} to rabbitmq channel'.format(key)) channel.queue_bind(exchange=exchange, queue=queue_name, routing_key=key) if isinstance(keys, types.StringType) and not wait: self.logger.debug( 'string adding key:{0} to rabbitmq channel'.format(keys)) channel.queue_bind(exchange=exchange, queue=queue_name, routing_key=keys) return channel, connection def init_rabbit(self): # pragma: no cover ''' init_rabbit ''' host = 'poseidon-rabbit' exchange = 'topic-poseidon-internal' queue_name = 'poseidon_NBCA' # binding_key = ['poseidon.algos.#', 'poseidon.action.#'] binding_key = ['poseidon.action.#'] retval = self.make_rabbit_connection( host, exchange, queue_name, binding_key) self.rabbit_channel_local = retval[0] self.rabbit_connection_local = retval[1] def start_channel(self, channel, mycallback, queue): ''' handle threading for a messagetype ''' self.logger.debug('about to start channel {0}'.format(channel)) channel.basic_consume( partial(mycallback, q=self.m_queue), queue=queue, no_ack=True) mq_recv_thread = threading.Thread(target=channel.start_consuming) mq_recv_thread.start() def first_run(self): ''' do some pre-run setup/configuration ''' if self.configured: self.controller['URI'] = str( self.mod_configuration['controller_uri']) self.controller['USER'] = str( self.mod_configuration['controller_user']) self.controller['PASS'] = str( self.mod_configuration['controller_pass']) myauth = {} myauth['password'] = self.controller['PASS'] myauth['user'] = self.controller['USER'] try: self.bcf = BcfProxy(self.controller['URI'], auth=myauth) except: self.logger.error( 'BcfProxy coult not connect to {0}'.format(self.controller['URI'])) else: pass @staticmethod def make_hash(item): ''' hash the metadata in a sane way''' h = hashlib.new('ripemd160') pre_h = str() post_h = None for word in ['tenant', 'mac', 'segment', 'name', 'ip-address']: pre_h = pre_h + str(item.get(str(word), 'missing')) h.update(pre_h) post_h = h.hexdigest() return post_h def handle_item(self, item): ''' perform an action based on rabbit item''' self.logger.debug('handle_item: {0}:{1}'.format(item, type(item))) itype = item[0] ivalue = item[1] ivalue = json.loads(ivalue) self.logger.debug( 'handle_item: ivalue json: {0}:{1}'.format(ivalue, type(ivalue))) if itype == 'poseidon.action.start_monitor': for my_hash, my_dict in ivalue.iteritems(): if my_hash in self.new_endpoints: v = self.new_endpoints.pop(my_hash) self.logger.debug( 'removed {0} from new_endpoints'.format(v)) else: self.logger.debug('could not find {0} in {1}'.format( my_hash, self.new_endpoints)) self.logger.debug( 'mirroring :{0}'.format(my_dict['ip-address'])) self.logger.debug( 'mirroring[{0}]={1}'.format(my_hash, my_dict)) self.bcf.mirror_ip(my_dict['ip-address']) self.mirroring[my_hash] = my_dict if itype == 'poseidon.action.endpoint_shutdown': self.logger.debug( 'endpoint_shutdown:{0}:{1}'.format(ivalue, type(ivalue))) for my_hash, my_dict in ivalue.iteritems(): bad_ip = my_dict.get('ip-address') if bad_ip is not None: self.logger.debug( '****** shutdown {0}:{1}'.format(bad_ip, ivalue)) self.bcf.shutdown_ip(bad_ip) self.shutdown[my_hash] = my_dict if itype == 'poseidon.action.stop_monitor': self.logger.debug('stop_monitor:{0}:{1}'.format(itype, ivalue)) for my_hash, my_dict in ivalue.iteritems(): self.logger.debug('stop_monitor_dict:{0}'.format(my_dict)) my_ip = my_dict.get('ip-address') if my_ip is not None: self.logger.debug('***** shutting down {0}'.format(my_ip)) self.bcf.unmirror_ip(my_ip) if my_hash in self.mirroring: self.mirroring.pop(my_hash) def get_rabbit_work(self): '''get work item from queue if exists''' # type , value workfound = False item = None self.logger.debug('about to look for work') try: item = self.m_queue.get(False) self.logger.debug('item:{0}'.format(item)) self.logger.debug('work found') workfound = True except Queue.Empty: pass self.logger.debug('done looking for work!') if workfound: self.handle_item(item) return item def find_new_machines(self, machines): '''parse switch structure to find new machines added to network since last call''' if self.first_time: self.first_time = False # TODO db call to see if really need to run things for machine in machines: h = self.make_hash(machine) module_logger.critical( 'adding address to known systems {0}'.format(machine)) self.prev_endpoints[h] = machine else: for machine in machines: h = self.make_hash(machine) if h not in self.prev_endpoints and h not in self.mirroring: module_logger.critical( '***** detected new address {0}'.format(machine)) self.new_endpoints[h] = machine def print_state(self): self.logger.debug('**************PREV*****************') for my_hash, my_dict in self.prev_endpoints.iteritems(): self.logger.debug('P:{0}:{1}'.format(my_hash, my_dict)) self.logger.debug('**************NEW******************') for my_hash, my_dict in self.new_endpoints.iteritems(): self.logger.debug('N:{0}:{1}'.format(my_hash, my_dict)) self.logger.debug('***********MIRRORING***************') for my_hash, my_dict in self.mirroring.iteritems(): self.logger.debug('M:{0}:{1}'.format(my_hash, my_dict)) self.logger.debug('***********SHUTDOWN****************') for my_hash, my_dict in self.shutdown.iteritems(): self.logger.debug('M:{0}:{1}'.format(my_hash, my_dict)) def send_new_machines(self): '''send listing of new machines to main for decisions''' for hashed, machine in self.new_endpoints.iteritems(): # TODO write findings to main r_exchange = 'topic-poseidon-internal' r_key = 'poseidon.action.new_machine' r_msg = json.dumps({hashed: machine}) self.rabbit_channel_local.basic_publish(exchange=r_exchange, routing_key=r_key, body=r_msg) def on_get(self, req, resp): '''Handles Get requests''' self.retval['service'] = self.owner.mod_name + ':' + self.mod_name self.retval['times'] = self.times self.retval['machines'] = None self.retval['resp'] = 'bad' current = None parsed = None machines = {} try: current = self.bcf.get_endpoints() parsed = self.bcf.format_endpoints(current) machines = parsed except: self.logger.error( 'Could not establish connection to {0}.'.format(self.controller['URI'])) self.retval['controller'] = 'Could not establish connection to {0}.'.format( self.controller['URI']) self.get_rabbit_work() self.logger.debug('MACHINES:{0}'.format(machines)) self.find_new_machines(machines) self.send_new_machines() self.print_state() self.retval['machines'] = parsed self.retval['resp'] = 'ok' # TODO change response to something reflecting success of traversal self.times = self.times + 1 resp.body = json.dumps(self.retval)
def first_run(self): ''' do some pre-run setup/configuration ''' if self.configured: self.controller['TYPE'] = str( self.mod_configuration['controller_type']) if self.controller['TYPE'] == 'bcf': self.controller['URI'] = str( self.mod_configuration['controller_uri']) self.controller['USER'] = str( self.mod_configuration['controller_user']) self.controller['PASS'] = str( self.mod_configuration['controller_pass']) if 'controller_span_fabric_name' in self.mod_configuration: self.controller['SPAN_FABRIC_NAME'] = str( self.mod_configuration['controller_span_fabric_name']) if 'controller_interface_group' in self.mod_configuration: self.controller['INTERFACE_GROUP'] = str( self.mod_configuration['controller_interface_group']) myauth = {} myauth['password'] = self.controller['PASS'] myauth['user'] = self.controller['USER'] try: self.sdnc = BcfProxy( self.controller['URI'], auth=myauth, span_fabric_name=self.controller['SPAN_FABRIC_NAME'], interface_group=self.controller['INTERFACE_GROUP']) except BaseException as e: # pragma: no cover self.logger.error( 'BcfProxy could not connect to {0} because {1}'.format( self.controller['URI'], e)) elif self.controller['TYPE'] == 'faucet': try: if 'learn_public_addresses' in self.mod_configuration: if self.mod_configuration[ 'learn_public_addresses'] == 'Yes': self.controller['LEARN_PUBLIC_ADDRESSES'] = True else: self.controller['LEARN_PUBLIC_ADDRESSES'] = False if 'controller_uri' in self.mod_configuration: self.controller['URI'] = str( self.mod_configuration['controller_uri']) if 'controller_user' in self.mod_configuration: self.controller['USER'] = str( self.mod_configuration['controller_user']) if 'controller_pass' in self.mod_configuration: self.controller['PASS'] = str( self.mod_configuration['controller_pass']) if 'controller_config_file' in self.mod_configuration: self.controller['CONFIG_FILE'] = str( self.mod_configuration['controller_config_file']) if 'controller_log_file' in self.mod_configuration: self.controller['LOG_FILE'] = str( self.mod_configuration['controller_log_file']) if 'controller_mirror_ports' in self.mod_configuration: self.controller['MIRROR_PORTS'] = ast.literal_eval( self.mod_configuration['controller_mirror_ports']) if 'rabbit_enabled' in self.mod_configuration: self.controller['RABBIT_ENABLED'] = ast.literal_eval( self.mod_configuration['rabbit_enabled']) self.sdnc = FaucetProxy( host=self.controller['URI'], user=self.controller['USER'], pw=self.controller['PASS'], config_file=self.controller['CONFIG_FILE'], log_file=self.controller['LOG_FILE'], mirror_ports=self.controller['MIRROR_PORTS'], rabbit_enabled=self.controller['RABBIT_ENABLED'], learn_pub_adds=self. controller['LEARN_PUBLIC_ADDRESSES'], reinvestigation_frequency=self. reinvestigation_frequency, max_concurrent_reinvestigations=self. max_concurrent_reinvestigations) except BaseException as e: # pragma: no cover self.logger.error( 'FaucetProxy could not connect to {0} because {1}'. format(self.controller['URI'], e)) else: self.logger.error('Unknown SDN controller type {0}'.format( self.controller['TYPE']))
def test_BcfProxy(): """ Tests bcf """ filemap = { '/data/controller/applications/bcf/info/fabric/switch': 'sample_switches.json', '/data/controller/applications/bcf/info/endpoint-manager/tenant': 'sample_tenants.json', '/data/controller/applications/bcf/info/endpoint-manager/segment': 'sample_segments.json', '/data/controller/applications/bcf/info/endpoint-manager/endpoint': 'sample_endpoints.json', '/data/controller/applications/bcf/span-fabric[name=%22SPAN_FABRIC%22]': 'sample_span_fabric.json', # %22 = url-encoded double quotes '/data/controller/applications/bcf/span-fabric[name=%22SPAN_FABRIC%22][dest-interface-group=%22INTERFACE_GROUP%22]': 'sample_span_fabric.json', '/data/controller/applications/bcf/span-fabric[name=%22empty%22][dest-interface-group=%22empty%22]': 'sample_span_fabric_empty.json', } proxy = None with HTTMock(mock_factory(r'.*', filemap)): proxy = BcfProxy('http://localhost', 'login', { 'username': username, 'password': password }, span_fabric_name='SPAN_FABRIC', interface_group='INTERFACE_GROUP') endpoints = proxy.get_endpoints() assert endpoints switches = proxy.get_switches() assert switches tenants = proxy.get_tenants() assert tenants segments = proxy.get_segments() assert segments span_fabric = proxy.get_span_fabric() assert span_fabric span_fabric = proxy.get_span_fabric(span_name='SPAN_FABRIC') assert span_fabric span_fabric = proxy.get_span_fabric(span_name='empty', interface_group='empty') assert not span_fabric with HTTMock(mock_factory2(r'.*')): # Normally shutdown_endpoint does not return a value. # You should call get_endpoint() afterwards to verify that a shutdown request went through. # In addition, the mock endpoint generated does not check for duplicates. # TODO: ***This code below is temporary.*** r = proxy.shutdown_endpoint(tenant='TENANT', segment='SEGMENT', endpoint_name='test', mac='00:00:00:00:00:00', shutdown=True) assert r r = proxy.shutdown_endpoint(tenant='TENANT', segment='SEGMENT', endpoint_name='test', mac='00:00:00:00:00:00', shutdown=False) assert r r = proxy.mirror_traffic(seq=2, mirror=True, tenant='TENANT', segment='SEGMENT') assert r r = proxy.mirror_traffic(seq=2, mirror=False) assert r def r(): return True r.text = '' # cover object assert r() BcfProxy.parse_json(r) proxy.session.cookies.clear_session_cookies() proxy.base_uri = 'http://jsonplaceholder.typicode.com' r = proxy.post_resource('posts') r.raise_for_status() r = proxy.request_resource( method='PUT', url='http://jsonplaceholder.typicode.com/posts/1') r.raise_for_status()