Example #1
0
def _poll_switch(ip_addr, credentials, req_obj='mac', oper="SCAN"):
    """Poll switch by ip addr.


    Args:
       ip_addr: ip addr of the switch.
       credentials: credentials of the switch.

    Returns: switch attributes dict and list of machine attributes dict.
    """
    under_monitoring = 'under_monitoring'
    unreachable = 'unreachable'
    polling_error = 'error'
    hdmanager = HDManager()
    vendor, state, err_msg = hdmanager.get_vendor(ip_addr, credentials)
    if not vendor:
        logging.info("*****error_msg: %s****", err_msg)
        logging.error('no vendor found or match switch %s', ip_addr)
        return ({'vendor': vendor, 'state': state, 'err_msg': err_msg}, {})

    logging.debug('hdmanager learn switch from %s', ip_addr)
    results = []
    try:
        results = hdmanager.learn(ip_addr, credentials, vendor, req_obj, oper)
    except Exception as error:
        logging.exception(error)
        state = unreachable
        err_msg = ('SNMP walk for querying MAC addresses timedout')
        return ({'vendor': vendor, 'state': state, 'err_msg': err_msg}, {})

    logging.info("pollswitch %s result: %s", ip_addr, results)
    if not results:
        logging.error('no result learned from %s', ip_addr)
        state = polling_error
        err_msg = 'No result learned from SNMP walk'
        return ({'vendor': vendor, 'state': state, 'err_msg': err_msg}, {})

    logging.info('poll switch result: %s' % str(results))
    machine_dicts = {}
    for machine in results:
        mac = machine['mac']
        port = machine['port']
        vlan = int(machine['vlan'])
        if vlan:
            vlans = [vlan]
        else:
            vlans = []
        if mac not in machine_dicts:
            machine_dicts[mac] = {'mac': mac, 'port': port, 'vlans': vlans}
        else:
            machine_dicts[mac]['port'] = port
            machine_dicts[mac]['vlans'].extend(vlans)

    logging.debug('update switch %s state to under monitoring', ip_addr)
    state = under_monitoring
    return ({
        'vendor': vendor,
        'state': state,
        'err_msg': err_msg
    }, machine_dicts.values())
 def setUp(self):
     super(HDManagerTest, self).setUp()
     logsetting.init()
     self.manager = HDManager()
     self.correct_host = '33.33.33.1'
     self.correct_host_2 = '127.0.0.1'
     self.correct_credential = {'version': '2c', 'community': 'public'}
Example #3
0
def poll_switch(ip_addr, req_obj='mac', oper="SCAN"):
    """ Query switch and return expected result

        :param str ip_addr: switch ip address
        :param str req_obj: the object requested to query from switch
        :param str oper : the operation to query the switch(SCAN, GET, SET)
    """
    if not ip_addr:
        logging.error('No switch IP address is provided!')
        return

    #Retrieve vendor info from switch table
    session = database.current_session()
    switch = session.query(Switch).filter_by(ip=ip_addr).first()
    logging.info("pollswitch: %s", switch)
    if not switch:
        logging.error('no switch found for %s', ip_addr)
        return

    credential = switch.credential
    logging.error("pollswitch: credential %r", credential)
    vendor = switch.vendor
    hdmanager = HDManager()

    if not vendor or not hdmanager.is_valid_vendor(ip_addr,
                                                   credential, vendor):
        # No vendor found or vendor doesn't match queried switch.
        logging.debug('no vendor or vendor had been changed for switch %s',
                      switch)
        vendor = hdmanager.get_vendor(ip_addr, credential)
        logging.debug('[pollswitch] credential %r', credential)
        if not vendor:
            logging.error('no vendor found or match switch %s', switch)
            return
        switch.vendor = vendor

    # Start to poll switch's mac address.....
    logging.debug('hdmanager learn switch from %s %s %s %s %s',
                  ip_addr, credential, vendor, req_obj, oper)
    results = hdmanager.learn(ip_addr, credential, vendor, req_obj, oper)
    logging.info("pollswitch %s result: %s", switch, results)
    if not results:
        logging.error('no result learned from %s %s %s %s %s',
                      ip_addr, credential, vendor, req_obj, oper)
        return

    for entry in results:
        mac = entry['mac']
        machine = session.query(Machine).filter_by(mac=mac).first()
        if not machine:
            machine = Machine(mac=mac)
            machine.port = entry['port']
            machine.vlan = entry['vlan']
            machine.switch = switch

    logging.debug('update switch %s state to under monitoring', switch)
    switch.state = 'under_monitoring'
    def setUp(self):
        self.manager = HDManager()
        self.correct_host = '172.29.8.40'
        self.correct_credential = {'Version': 'v2c', 'Community': 'public'}

        self.ovs_host = '10.145.88.160'
        self.ovs_credential = {'username': '******', 'password': '******'}
 def setUp(self):
     super(HDManagerTest, self).setUp()
     logsetting.init()
     self.manager = HDManager()
     self.correct_host = '33.33.33.1'
     self.correct_host_2 = '127.0.0.1'
     self.correct_credential = {'version': '2c', 'community': 'public'}
class HDManagerTest(unittest2.TestCase):

    def setUp(self):
        self.manager = HDManager()
        self.correct_host = '172.29.8.40'
        self.correct_credential = {'Version': 'v2c', 'Community': 'public'}

        self.ovs_host = '10.145.88.160'
        self.ovs_credential = {'username': '******', 'password': '******'}

    def tearDown(self):
        del self.manager

    @patch('compass.hdsdiscovery.utils.ssh_remote_execute')
    @patch('compass.hdsdiscovery.utils.snmp_get')
    def test_GetVendor_WithIncorrectInput(self, snmp_get_mock, ovs_mock):
        snmp_get_mock.return_value = None
        ovs_mock.return_value = []

        # Incorrect ip
        self.assertIsNone(self.manager.get_vendor('1.1.1.1',
                                                  self.correct_credential))
        self.assertIsNone(self.manager.get_vendor('1.1.1.1',
                                                  self.ovs_credential))

        # Incorrect credential
        self.assertIsNone(
            self.manager.get_vendor(self.correct_host,
                                    {'Version': '1v', 'Community': 'private'}))
        self.assertIsNone(
            self.manager.get_vendor(self.ovs_host,
                                    {'username': '******', 'password': '******'}))

    def test_ValidVendor(self):
        #non-exsiting vendor
        self.assertFalse(self.manager.is_valid_vendor(self.correct_host,
                                                      self.correct_credential,
                                                      'xxxx'))

    def test_Learn(self):
        #non-exsiting plugin
        self.assertIsNone(self.manager.learn(self.correct_host,
                                             self.correct_credential,
                                             'huawei', 'xxx'))

        #non-existing vendor
        self.assertIsNone(self.manager.learn(self.correct_host,
                                             self.correct_credential,
                                             'xxxx', 'mac'))
Example #7
0
def poll_switch(ip_addr, req_obj='mac', oper="SCAN"):
    """Query switch and return expected result

    .. note::
       When polling switch succeeds, for each mac it got from polling switch,
       A Machine record associated with the switch is added to the database.

    :param ip_addr: switch ip address.
    :type ip_addr: str
    :param req_obj: the object requested to query from switch.
    :type req_obj: str
    :param oper: the operation to query the switch.
    :type oper: str, should be one of ['SCAN', 'GET', 'SET']

    .. note::
       The function should be called out of database session scope.

    """
    under_monitoring = 'under_monitoring'
    unreachable = 'unreachable'

    if not ip_addr:
        logging.error('No switch IP address is provided!')
        return

    with database.session() as session:
        #Retrieve vendor info from switch table
        switch = session.query(Switch).filter_by(ip=ip_addr).first()
        logging.info("pollswitch: %s", switch)
        if not switch:
            logging.error('no switch found for %s', ip_addr)
            return

        credential = switch.credential
        logging.info("pollswitch: credential %r", credential)
        vendor = switch.vendor
        prev_state = switch.state
        hdmanager = HDManager()

        vendor, vstate, err_msg = hdmanager.get_vendor(ip_addr, credential)
        if not vendor:
            switch.state = vstate
            switch.err_msg = err_msg
            logging.info("*****error_msg: %s****", switch.err_msg)
            logging.error('no vendor found or match switch %s', switch)
            return

        switch.vendor = vendor

        # Start to poll switch's mac address.....
        logging.debug('hdmanager learn switch from %s %s %s %s %s',
                      ip_addr, credential, vendor, req_obj, oper)
        results = []

        try:
            results = hdmanager.learn(
                ip_addr, credential, vendor, req_obj, oper)
        except Exception as error:
            logging.exception(error)
            switch.state = unreachable
            switch.err_msg = "SNMP walk for querying MAC addresses timedout"
            return

        logging.info("pollswitch %s result: %s", switch, results)
        if not results:
            logging.error('no result learned from %s %s %s %s %s',
                          ip_addr, credential, vendor, req_obj, oper)
            return

        switch_id = switch.id
        filter_ports = session.query(
            SwitchConfig.filter_port
        ).filter(
            SwitchConfig.ip == Switch.ip
        ).filter(
            Switch.id == switch_id
        ).all()
        logging.info("***********filter posts are %s********", filter_ports)
        if filter_ports:
            #Get all ports from tuples into list
            filter_ports = [i[0] for i in filter_ports]

        for entry in results:
            mac = entry['mac']
            port = entry['port']
            vlan = entry['vlan']
            if port in filter_ports:
                continue

            machine = session.query(Machine).filter_by(
                mac=mac, port=port, switch_id=switch_id).first()
            if not machine:
                machine = Machine(mac=mac, port=port, vlan=vlan)
                session.add(machine)
                machine.switch = switch

        logging.debug('update switch %s state to under monitoring', switch)
        if prev_state != under_monitoring:
            #Update error message in db
            switch.err_msg = ""

        switch.state = under_monitoring
Example #8
0
def _poll_switch(ip_addr, credentials, req_obj='mac', oper="SCAN"):
    """Poll switch by ip addr.


    Args:
       ip_addr: ip addr of the switch.
       credentials: credentials of the switch.

    Returns: switch attributes dict and list of machine attributes dict.
    """
    under_monitoring = 'under_monitoring'
    unreachable = 'unreachable'
    polling_error = 'error'
    hdmanager = HDManager()
    vendor, state, err_msg = hdmanager.get_vendor(ip_addr, credentials)
    if not vendor:
        logging.info("*****error_msg: %s****", err_msg)
        logging.error('no vendor found or match switch %s', ip_addr)
        return (
            {
                'vendor': vendor, 'state': state, 'err_msg': err_msg
            }, {
            }
        )

    logging.debug(
        'hdmanager learn switch from %s', ip_addr
    )
    results = []
    try:
        results = hdmanager.learn(
            ip_addr, credentials, vendor, req_obj, oper
        )
    except Exception as error:
        logging.exception(error)
        state = unreachable
        err_msg = (
            'SNMP walk for querying MAC addresses timedout'
        )
        return (
            {
                'vendor': vendor, 'state': state, 'err_msg': err_msg
            }, {
            }
        )

    logging.info("pollswitch %s result: %s", ip_addr, results)
    if not results:
        logging.error(
            'no result learned from %s', ip_addr
        )
        state = polling_error
        err_msg = 'No result learned from SNMP walk'
        return (
            {'vendor': vendor, 'state': state, 'err_msg': err_msg},
            {}
        )

    logging.info('poll switch result: %s' % str(results))
    machine_dicts = {}
    for machine in results:
        mac = machine['mac']
        port = machine['port']
        vlan = int(machine['vlan'])
        if vlan:
            vlans = [vlan]
        else:
            vlans = []
        if mac not in machine_dicts:
            machine_dicts[mac] = {'mac': mac, 'port': port, 'vlans': vlans}
        else:
            machine_dicts[mac]['port'] = port
            machine_dicts[mac]['vlans'].extend(vlans)

    logging.debug('update switch %s state to under monitoring', ip_addr)
    state = under_monitoring
    return (
        {'vendor': vendor, 'state': state, 'err_msg': err_msg},
        machine_dicts.values()
    )
Example #9
0
def poll_switch(ip_addr, req_obj='mac', oper="SCAN"):
    """Query switch and return expected result

    .. note::
       When polling switch succeeds, for each mac it got from polling switch,
       A Machine record associated with the switch is added to the database.

    :param ip_addr: switch ip address.
    :type ip_addr: str
    :param req_obj: the object requested to query from switch.
    :type req_obj: str
    :param oper: the operation to query the switch.
    :type oper: str, should be one of ['SCAN', 'GET', 'SET']

    .. note::
       The function should be called out of database session scope.

    """
    under_monitoring = 'under_monitoring'
    unreachable = 'unreachable'

    if not ip_addr:
        logging.error('No switch IP address is provided!')
        return

    with database.session() as session:
        #Retrieve vendor info from switch table
        switch = session.query(Switch).filter_by(ip=ip_addr).first()
        logging.info("pollswitch: %s", switch)
        if not switch:
            logging.error('no switch found for %s', ip_addr)
            return

        credential = switch.credential
        logging.info("pollswitch: credential %r", credential)
        vendor = switch.vendor
        prev_state = switch.state
        hdmanager = HDManager()

        vendor, vstate, err_msg = hdmanager.get_vendor(ip_addr, credential)
        if not vendor:
            switch.state = vstate
            switch.err_msg = err_msg
            logging.info("*****error_msg: %s****", switch.err_msg)
            logging.error('no vendor found or match switch %s', switch)
            return

        switch.vendor = vendor

        # Start to poll switch's mac address.....
        logging.debug('hdmanager learn switch from %s %s %s %s %s', ip_addr,
                      credential, vendor, req_obj, oper)
        results = []

        try:
            results = hdmanager.learn(ip_addr, credential, vendor, req_obj,
                                      oper)
        except Exception as error:
            logging.exception(error)
            switch.state = unreachable
            switch.err_msg = "SNMP walk for querying MAC addresses timedout"
            return

        logging.info("pollswitch %s result: %s", switch, results)
        if not results:
            logging.error('no result learned from %s %s %s %s %s', ip_addr,
                          credential, vendor, req_obj, oper)
            return

        switch_id = switch.id
        filter_ports = session.query(SwitchConfig.filter_port).filter(
            SwitchConfig.ip == Switch.ip).filter(Switch.id == switch_id).all()
        logging.info("***********filter posts are %s********", filter_ports)
        if filter_ports:
            #Get all ports from tuples into list
            filter_ports = [i[0] for i in filter_ports]

        for entry in results:
            mac = entry['mac']
            port = entry['port']
            vlan = entry['vlan']
            if port in filter_ports:
                continue

            machine = session.query(Machine).filter_by(
                mac=mac, switch_id=switch_id).first()
            if not machine:
                machine = Machine(mac=mac,
                                  port=port,
                                  vlan=vlan,
                                  switch_id=switch_id)
                session.add(machine)
            else:
                machine.port = port
                machine.vlan = vlan

        logging.debug('update switch %s state to under monitoring', switch)
        if prev_state != under_monitoring:
            #Update error message in db
            switch.err_msg = ""

        switch.state = under_monitoring
Example #10
0
class HDManagerTest(unittest2.TestCase):
    """test HDManager."""

    def setUp(self):
        super(HDManagerTest, self).setUp()
        logsetting.init()
        self.manager = HDManager()
        self.correct_host = '33.33.33.1'
        self.correct_host_2 = '127.0.0.1'
        self.correct_credential = {'version': '2c', 'community': 'public'}

    def tearDown(self):
        del self.manager
        super(HDManagerTest, self).tearDown()

    @patch('compass.hdsdiscovery.hdmanager.HDManager.get_sys_info')
    def test_get_vendor(self, sys_info_mock):
        """test get_vendor."""
        # Incorrect ip
        vendor, state, err = self.manager.get_vendor('1234.1.1.1',
                                                     self.correct_credential)
        self.assertIsNone(vendor)
        self.assertEqual('error', state)

        # Incorrect credential
        incorr_cred = {'version': '1v', 'community': 'private'}
        vendor, state, err = self.manager.get_vendor(self.correct_host,
                                                     incorr_cred)
        self.assertIsNone(vendor)
        self.assertEqual('error', state)

        # SNMP get system description Timeout
        excepted_err_msg = 'Timeout: No Response from 127.0.0.1.'
        sys_info_mock.return_value = (None, excepted_err_msg)
        result, state, err = self.manager.get_vendor(self.correct_host,
                                                     self.correct_credential)
        self.assertIsNone(result)
        self.assertEqual(state, 'unreachable')
        self.assertEqual(err, excepted_err_msg)

        # No vendor plugin supported
        excepted_err_msg = 'Not supported switch vendor!'
        sys_info_mock.return_value = ('xxxxxx', excepted_err_msg)
        result, state, err = self.manager.get_vendor(self.correct_host,
                                                     self.correct_credential)
        self.assertIsNone(result)
        self.assertEqual(state, 'notsupported')
        self.assertEqual(err, excepted_err_msg)

        # Found the correct vendor
        sys_info = ['Huawei Versatile Routing Platform Software',
                    'ProCurve J9089A Switch 2610-48-PWR, revision R.11.25',
                    'Pica8 XorPlus Platform Software']
        expected_vendor_names = ['huawei', 'hp', 'pica8', 'appliance']
        for info, expected_vendor in zip(sys_info, expected_vendor_names):
            sys_info_mock.return_value = (info, '')
            # the result is a tuple ($vendor, $state, $error_message)
            result = self.manager.get_vendor(self.correct_host,
                                             self.correct_credential)
            self.assertEqual(result[0], expected_vendor)

    @patch('compass.hdsdiscovery.hdmanager.HDManager.get_sys_info')
    def test_is_valid_vendor(self, sys_info_mock):
        """test is_valid_vendor."""
        # non-exsiting vendor under vendors directory
        self.assertFalse(
            self.manager.is_valid_vendor(self.correct_host,
                                         self.correct_credential,
                                         'xxxx')
        )

        # No system description retrieved
        sys_info_mock.return_value = (None, 'TIMEOUT')
        self.assertFalse(
            self.manager.is_valid_vendor(self.correct_host,
                                         self.correct_credential,
                                         'pica8')
        )

        # Incorrect vendor name
        sys_info = 'Pica8 XorPlus Platform Software'
        sys_info_mock.return_value = (sys_info, '')
        self.assertFalse(
            self.manager.is_valid_vendor(self.correct_host,
                                         self.correct_credential,
                                         'huawei')
        )

        # Correct vendor name
        self.assertTrue(
            self.manager.is_valid_vendor(self.correct_host,
                                         self.correct_credential,
                                         'pica8')
        )

    def test_learn(self):
        """test learn."""
        # non-exsiting plugin
        self.assertIsNone(self.manager.learn(self.correct_host,
                                             self.correct_credential,
                                             'huawei', 'xxx'))

        # non-existing vendor
        self.assertIsNone(self.manager.learn(self.correct_host,
                                             self.correct_credential,
                                             'xxxx', 'mac'))
Example #11
0
def poll_switch(ip_addr, req_obj='mac', oper="SCAN"):
    """Query switch and return expected result

    .. note::
       When polling switch succeeds, for each mac it got from polling switch,
       A Machine record associated with the switch is added to the database.

    :param ip_addr: switch ip address.
    :type ip_addr: str
    :param req_obj: the object requested to query from switch.
    :type req_obj: str
    :param oper: the operation to query the switch.
    :type oper: str, should be one of ['SCAN', 'GET', 'SET']

    .. note::
       The function should be called inside database session scope.

    """
    if not ip_addr:
        logging.error('No switch IP address is provided!')
        return

    #Retrieve vendor info from switch table
    session = database.current_session()
    switch = session.query(Switch).filter_by(ip=ip_addr).first()
    logging.info("pollswitch: %s", switch)
    if not switch:
        logging.error('no switch found for %s', ip_addr)
        return

    credential = switch.credential
    logging.error("pollswitch: credential %r", credential)
    vendor = switch.vendor
    hdmanager = HDManager()

    if not vendor or not hdmanager.is_valid_vendor(ip_addr, credential,
                                                   vendor):
        # No vendor found or vendor doesn't match queried switch.
        logging.debug('no vendor or vendor had been changed for switch %s',
                      switch)
        vendor = hdmanager.get_vendor(ip_addr, credential)
        logging.debug('[pollswitch] credential %r', credential)
        if not vendor:
            logging.error('no vendor found or match switch %s', switch)
            return
        switch.vendor = vendor

    # Start to poll switch's mac address.....
    logging.debug('hdmanager learn switch from %s %s %s %s %s', ip_addr,
                  credential, vendor, req_obj, oper)
    results = hdmanager.learn(ip_addr, credential, vendor, req_obj, oper)
    logging.info("pollswitch %s result: %s", switch, results)
    if not results:
        logging.error('no result learned from %s %s %s %s %s', ip_addr,
                      credential, vendor, req_obj, oper)
        return

    for entry in results:
        mac = entry['mac']
        machine = session.query(Machine).filter_by(mac=mac).first()
        if not machine:
            machine = Machine(mac=mac)
            machine.port = entry['port']
            machine.vlan = entry['vlan']
            machine.switch = switch

    logging.debug('update switch %s state to under monitoring', switch)
    switch.state = 'under_monitoring'
class HDManagerTest(unittest2.TestCase):
    """test HDManager."""
    def setUp(self):
        super(HDManagerTest, self).setUp()
        logsetting.init()
        self.manager = HDManager()
        self.correct_host = '33.33.33.1'
        self.correct_host_2 = '127.0.0.1'
        self.correct_credential = {'version': '2c', 'community': 'public'}

    def tearDown(self):
        del self.manager
        super(HDManagerTest, self).tearDown()

    @patch('compass.hdsdiscovery.hdmanager.HDManager.get_sys_info')
    def test_get_vendor(self, sys_info_mock):
        """test get_vendor."""
        # Incorrect ip
        vendor, state, err = self.manager.get_vendor('1234.1.1.1',
                                                     self.correct_credential)
        self.assertIsNone(vendor)
        self.assertEqual('error', state)

        # Incorrect credential
        incorr_cred = {'version': '1v', 'community': 'private'}
        vendor, state, err = self.manager.get_vendor(self.correct_host,
                                                     incorr_cred)
        self.assertIsNone(vendor)
        self.assertEqual('error', state)

        # SNMP get system description Timeout
        excepted_err_msg = 'Timeout: No Response from 127.0.0.1.'
        sys_info_mock.return_value = (None, excepted_err_msg)
        result, state, err = self.manager.get_vendor(self.correct_host,
                                                     self.correct_credential)
        self.assertIsNone(result)
        self.assertEqual(state, 'unreachable')
        self.assertEqual(err, excepted_err_msg)

        # No vendor plugin supported
        excepted_err_msg = 'Not supported switch vendor!'
        sys_info_mock.return_value = ('xxxxxx', excepted_err_msg)
        result, state, err = self.manager.get_vendor(self.correct_host,
                                                     self.correct_credential)
        self.assertIsNone(result)
        self.assertEqual(state, 'notsupported')
        self.assertEqual(err, excepted_err_msg)

        # Found the correct vendor
        sys_info = [
            'Huawei Versatile Routing Platform Software',
            'ProCurve J9089A Switch 2610-48-PWR, revision R.11.25',
            'Pica8 XorPlus Platform Software'
        ]
        expected_vendor_names = ['huawei', 'hp', 'pica8', 'appliance']
        for info, expected_vendor in zip(sys_info, expected_vendor_names):
            sys_info_mock.return_value = (info, '')
            # the result is a tuple ($vendor, $state, $error_message)
            result = self.manager.get_vendor(self.correct_host,
                                             self.correct_credential)
            self.assertEqual(result[0], expected_vendor)

    @patch('compass.hdsdiscovery.hdmanager.HDManager.get_sys_info')
    def test_is_valid_vendor(self, sys_info_mock):
        """test is_valid_vendor."""
        # non-exsiting vendor under vendors directory
        self.assertFalse(
            self.manager.is_valid_vendor(self.correct_host,
                                         self.correct_credential, 'xxxx'))

        # No system description retrieved
        sys_info_mock.return_value = (None, 'TIMEOUT')
        self.assertFalse(
            self.manager.is_valid_vendor(self.correct_host,
                                         self.correct_credential, 'pica8'))

        # Incorrect vendor name
        sys_info = 'Pica8 XorPlus Platform Software'
        sys_info_mock.return_value = (sys_info, '')
        self.assertFalse(
            self.manager.is_valid_vendor(self.correct_host,
                                         self.correct_credential, 'huawei'))

        # Correct vendor name
        self.assertTrue(
            self.manager.is_valid_vendor(self.correct_host,
                                         self.correct_credential, 'pica8'))

    def test_learn(self):
        """test learn."""
        # non-exsiting plugin
        self.assertIsNone(
            self.manager.learn(self.correct_host, self.correct_credential,
                               'huawei', 'xxx'))

        # non-existing vendor
        self.assertIsNone(
            self.manager.learn(self.correct_host, self.correct_credential,
                               'xxxx', 'mac'))
Example #13
0
def poll_switch(ip_addr, req_obj='mac', oper="SCAN"):
    """Query switch and return expected result

    .. note::
       When polling switch succeeds, for each mac it got from polling switch,
       A Machine record associated with the switch is added to the database.

    :param ip_addr: switch ip address.
    :type ip_addr: str
    :param req_obj: the object requested to query from switch.
    :type req_obj: str
    :param oper: the operation to query the switch.
    :type oper: str, should be one of ['SCAN', 'GET', 'SET']

    .. note::
       The function should be called inside database session scope.

    """
    if not ip_addr:
        logging.error('No switch IP address is provided!')
        return

    #Retrieve vendor info from switch table
    session = database.current_session()
    switch = session.query(Switch).filter_by(ip=ip_addr).first()
    logging.info("pollswitch: %s", switch)
    if not switch:
        logging.error('no switch found for %s', ip_addr)
        return

    credential = switch.credential
    logging.error("pollswitch: credential %r", credential)
    vendor = switch.vendor
    hdmanager = HDManager()

    if not vendor or not hdmanager.is_valid_vendor(ip_addr,
                                                   credential, vendor):
        # No vendor found or vendor doesn't match queried switch.
        logging.debug('no vendor or vendor had been changed for switch %s',
                      switch)
        vendor = hdmanager.get_vendor(ip_addr, credential)
        logging.debug('[pollswitch] credential %r', credential)
        if not vendor:
            logging.error('no vendor found or match switch %s', switch)
            return
        switch.vendor = vendor

    # Start to poll switch's mac address.....
    logging.debug('hdmanager learn switch from %s %s %s %s %s',
                  ip_addr, credential, vendor, req_obj, oper)
    results = hdmanager.learn(ip_addr, credential, vendor, req_obj, oper)
    logging.info("pollswitch %s result: %s", switch, results)
    if not results:
        logging.error('no result learned from %s %s %s %s %s',
                      ip_addr, credential, vendor, req_obj, oper)
        return

    for entry in results:
        mac = entry['mac']
        machine = session.query(Machine).filter_by(mac=mac).first()
        if not machine:
            machine = Machine(mac=mac)
            machine.port = entry['port']
            machine.vlan = entry['vlan']
            machine.switch = switch

    logging.debug('update switch %s state to under monitoring', switch)
    switch.state = 'under_monitoring'