diff --git a/src/lldp_syncd/daemon.py b/src/lldp_syncd/daemon.py index e949ad1..40be2b2 100644 --- a/src/lldp_syncd/daemon.py +++ b/src/lldp_syncd/daemon.py @@ -296,25 +296,36 @@ def parse_update(self, lldp_json): logger.exception("Failed to parse LLDPd JSON. \n{}\n -- ".format(lldp_json)) def parse_chassis(self, chassis_attributes): + + chassis_id_subtype = chassis_id = sys_name = descr = mgmt_ip = '' + try: if 'id' in chassis_attributes and 'id' not in chassis_attributes['id']: - sys_name = '' attributes = chassis_attributes - id_attributes = chassis_attributes['id'] + id_attributes = chassis_attributes.get('id') or {} else: (sys_name, attributes) = list(chassis_attributes.items())[0] - id_attributes = attributes.get('id', '') + id_attributes = attributes.get('id') or {} + + id_type = id_attributes.get('type') + + if id_type not in self.ChassisIdSubtypeMap.__members__: + logger.warning( + "lldp-syncd: unsupported chassis id subtype: %s", + id_type, + ) + else: + chassis_id_subtype = str(self.ChassisIdSubtypeMap[id_type].value) + chassis_id = id_attributes.get('value', '') + - chassis_id_subtype = str(self.ChassisIdSubtypeMap[id_attributes['type']].value) - chassis_id = id_attributes.get('value', '') descr = attributes.get('descr', '') mgmt_ip = attributes.get('mgmt-ip', '') if isinstance(mgmt_ip, list): mgmt_ip = ','.join(mgmt_ip) - except (KeyError, ValueError): - logger.exception("Could not infer system information from: {}" - .format(chassis_attributes)) - chassis_id_subtype = chassis_id = sys_name = descr = mgmt_ip = '' + + except (KeyError, AttributeError, TypeError): + logger.error("Could not infer system information from: %s", chassis_attributes) return (chassis_id_subtype, chassis_id, @@ -324,19 +335,27 @@ def parse_chassis(self, chassis_attributes): ) def parse_port(self, port_attributes): - port_identifiers = port_attributes.get('id') - try: - subtype = str(self.PortIdSubtypeMap[port_identifiers['type']].value) - value = port_identifiers['value'] - - except ValueError: - logger.exception("Could not infer chassis subtype from: {}".format(port_attributes)) - subtype, value = None - - return (subtype, - value, - port_attributes.get('descr', ''), - ) + port_identifiers = port_attributes.get('id') or {} + + subtype = None + value = None + + id_type = port_identifiers.get('type') + + if id_type not in self.PortIdSubtypeMap.__members__: + logger.warning( + "lldp-syncd: unsupported port id subtype: %s", + id_type, + ) + else: + subtype = str(self.PortIdSubtypeMap[id_type].value) + value = port_identifiers.get('value', '') + + return ( + subtype, + value, + port_attributes.get('descr', ''), + ) def cache_diff(self, cache, update): """ diff --git a/tests/test_lldpSyncDaemon.py b/tests/test_lldpSyncDaemon.py index 8dd0df7..3a2ff5c 100644 --- a/tests/test_lldpSyncDaemon.py +++ b/tests/test_lldpSyncDaemon.py @@ -218,6 +218,62 @@ def test_invalid_chassis_name(self, mock_check_output): ''' result = self.daemon.source_update() self.assertIsNone(result) + + def test_unsupported_port_subtype(self): + bad_json = { + "lldp": { + "interface": [ + { + "Ethernet1": { + "via": "LLDP", + "rid": "1", + "age": "0 day, 00:00:10", + "chassis": { + "id": {"type": "mac", "value": "aa:bb:cc:dd:ee:ff"} + }, + "port": { + "id": {"type": "unhandled", "value": "garbage"}, + "ttl": "120" + } + } + } + ] + } + } + + parsed = self.daemon.parse_update(bad_json) + + self.assertIn("Ethernet1", parsed) + self.assertIsNone(parsed["Ethernet1"]["lldp_rem_port_id_subtype"]) + self.assertEqual(parsed["Ethernet1"]["lldp_rem_port_id"], None) + + def test_unsupported_chassis_subtype(self): + bad_json = { + "lldp": { + "interface": [ + { + "Ethernet2": { + "via": "LLDP", + "rid": "1", + "age": "0 day, 00:00:10", + "chassis": { + "id": {"type": "unhandled", "value": "garbage"} + }, + "port": { + "id": {"type": "ifname", "value": "Ethernet2"}, + "ttl": "120" + } + } + } + ] + } + } + + parsed = self.daemon.parse_update(bad_json) + + self.assertIn("Ethernet2", parsed) + self.assertEqual(parsed["Ethernet2"]["lldp_rem_chassis_id_subtype"], "") + self.assertEqual(parsed["Ethernet2"]["lldp_rem_chassis_id"], "") def test_changed_interface(self):