db76af9c86
Closes-Bug: #2044793 Change-Id: I939c80bb309b22e05ba7cc93686f12bbe0d71624
97 lines
3.6 KiB
Python
97 lines
3.6 KiB
Python
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
# implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
"""LLDP Processing Hook for basic TLVs"""
|
|
|
|
import binascii
|
|
|
|
from ironic_inspector.common import lldp_parsers
|
|
from ironic_inspector.plugins import base
|
|
from ironic_inspector import utils
|
|
|
|
LOG = utils.getProcessingLogger(__name__)
|
|
|
|
|
|
class LLDPBasicProcessingHook(base.ProcessingHook):
|
|
"""Process mandatory and optional LLDP packet fields
|
|
|
|
Loop through raw LLDP TLVs and parse those from the
|
|
basic management, 802.1, and 802.3 TLV sets.
|
|
Store parsed data back to the ironic-inspector database.
|
|
"""
|
|
|
|
def _parse_lldp_tlvs(self, tlvs, node_info):
|
|
"""Parse LLDP TLVs into dictionary of name/value pairs
|
|
|
|
:param tlvs: list of raw TLVs
|
|
:param node_info: node being introspected
|
|
:returns nv: dictionary of name/value pairs. The
|
|
LLDP user-friendly names, e.g.
|
|
"switch_port_id" are the keys
|
|
"""
|
|
|
|
# Generate name/value pairs for each TLV supported by this plugin.
|
|
parser = lldp_parsers.LLDPBasicMgmtParser(node_info)
|
|
|
|
for tlv_type, tlv_value in tlvs:
|
|
try:
|
|
data = bytearray(binascii.a2b_hex(tlv_value))
|
|
except TypeError as e:
|
|
LOG.warning(
|
|
"TLV value for TLV type %(tlv_type)d not in correct "
|
|
"format, value must be in hexadecimal: %(msg)s",
|
|
{'tlv_type': tlv_type, 'msg': e}, node_info=node_info)
|
|
continue
|
|
|
|
try:
|
|
parsed_tlv = parser.parse_tlv(tlv_type, data)
|
|
except UnicodeDecodeError as e:
|
|
LOG.warning("LLDP TLV type %(tlv_type)d can't be decoded: "
|
|
"%(exc)s",
|
|
{'tlv_type': tlv_type, 'exc': e},
|
|
node_info=node_info)
|
|
continue
|
|
|
|
if parsed_tlv:
|
|
LOG.debug("Handled TLV type %d",
|
|
tlv_type, node_info=node_info)
|
|
else:
|
|
LOG.debug("LLDP TLV type %d not handled",
|
|
tlv_type, node_info=node_info)
|
|
|
|
return parser.nv_dict
|
|
|
|
def before_update(self, introspection_data, node_info, **kwargs):
|
|
"""Process LLDP data and update all_interfaces with processed data"""
|
|
|
|
inventory = utils.get_inventory(introspection_data)
|
|
lldp_raw = introspection_data.get('lldp_raw') or {}
|
|
|
|
for iface in inventory['interfaces']:
|
|
if_name = iface['name']
|
|
tlvs = lldp_raw.get(if_name) or iface.get('lldp')
|
|
if tlvs is None:
|
|
LOG.warning("No LLDP Data found for interface %s",
|
|
if_name, node_info=node_info)
|
|
continue
|
|
|
|
LOG.debug("Processing LLDP Data for interface %s",
|
|
if_name, node_info=node_info)
|
|
|
|
nv = self._parse_lldp_tlvs(tlvs, node_info)
|
|
|
|
if nv:
|
|
# Store lldp data per interface in "all_interfaces"
|
|
iface_to_update = introspection_data['all_interfaces'][if_name]
|
|
iface_to_update['lldp_processed'] = nv
|