Пример #1
0
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)
Пример #2
0
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')
Пример #3
0
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
Пример #4
0
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)
Пример #5
0
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
Пример #6
0
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')
Пример #7
0
    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
Пример #9
0
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)
Пример #11
0
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)
Пример #13
0
    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']))
Пример #14
0
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()