network: fix interface not found on switch Cisco SG300

This commit is contained in:
bds-congnguyen 2022-07-30 23:57:42 +07:00
commit 0f4a9ff9aa
2 changed files with 60 additions and 25 deletions

View file

@ -1,5 +1,6 @@
import logging import logging
import subprocess import subprocess
import socket
from netbox_agent.misc import is_tool from netbox_agent.misc import is_tool
@ -51,12 +52,38 @@ class LLDP():
def get_switch_ip(self, interface): def get_switch_ip(self, interface):
# lldp.eth0.chassis.mgmt-ip=100.66.7.222 # lldp.eth0.chassis.mgmt-ip=100.66.7.222
# lldp.eno1.chassis.name=G4U19 # try to conncet to chassis name instead of mgmt-ip in case ip return None
if self.data['lldp'].get(interface) is None: if self.data['lldp'].get(interface) is None:
return None return None
return self.data['lldp'][interface]['chassis'].get('mgmt-ip') if self.data['lldp'][interface]['chassis'].get('mgmt-ip') is None:
logging.debug("No switch IP found, trying to connect via switch domain name")
ip = socket.gethostbyname(self.data['lldp'][interface]['chassis'].get('name'))
return ip
else:
return self.data['lldp'][interface]['chassis'].get('mgmt-ip')
def get_switch_port(self, interface): def get_switch_port(self, interface):
# lldp.eth0.port.descr=GigabitEthernet1/0/1 # lldp.eth0.port.descr=GigabitEthernet1/0/1
# lldp.eno1.port.ifname=gi35
# Cisco SMB SG300 didn't return canonical_int in case True/False, so add an extra convert to ully expanded name
# To avoid `ERROR:root:Switch interface gi35 cannot be found`
# NAPALM result:
# "GigabitEthernet35": [
# {
# "parent_interface": "N/A",
# "remote_port": "xx:xx:xx:xx:xx:xx",
# "remote_port_description": "eno1",
# "remote_chassis_id": "yy:yy:yy:yy:yy:yy",
# "remote_system_name": "abc",
# "remote_system_description": "Debian GNU/Linux 11 (bullseye)",
# "remote_system_capab": [
# "B"
# ],
# "remote_system_enable_capab": [
# "B"
# ]
# }
# ],
if self.data['lldp'].get(interface) is None: if self.data['lldp'].get(interface) is None:
return None return None
if self.data['lldp'][interface]['port'].get('ifname'): if self.data['lldp'][interface]['port'].get('ifname'):

View file

@ -544,32 +544,40 @@ class ServerNetwork(Network):
return nb_server_interface return nb_server_interface
switch_interface = self.lldp.get_switch_port(nb_server_interface.name) switch_interface = self.lldp.get_switch_port(nb_server_interface.name)
nb_switch_interface = nb.dcim.interfaces.get( switch_interfaces = [switch_interface]
device=nb_switch, interface_match = re.match(r"([a-z]{2})(\d+)", switch_interface)
name=switch_interface, if interface_match is not None:
) logging.debug(f"Converting interface {switch_interface} to canonical name")
if nb_switch_interface is None: switch_interfaces.append(f"GigabitEthernet{interface_match.group(2)}")
logging.error('Switch interface {} cannot be found'.format(switch_interface)) logging.debug(f"switch interfaces is: {switch_interfaces}")
return nb_server_interface for switch_interface in switch_interfaces:
nb_switch_interface = nb.dcim.interfaces.get(
logging.info('Found interface {} on switch {}'.format( device=nb_switch,
switch_interface, name=switch_interface,
switch_ip, )
)) if nb_switch_interface is None:
cable = nb.dcim.cables.create( logging.error('Switch interface {} cannot be found'.format(switch_interface))
termination_a_id=nb_server_interface.id, continue
termination_a_type="dcim.interface", # return nb_server_interface
termination_b_id=nb_switch_interface.id,
termination_b_type="dcim.interface", logging.info('Found interface {} on switch {}'.format(
) switch_interface,
nb_server_interface.cable = cable switch_ip,
logging.info( ))
'Connected interface {interface} with {switch_interface} of {switch_ip}'.format( cable = nb.dcim.cables.create(
interface=nb_server_interface.name, termination_a_id=nb_server_interface.id,
switch_interface=switch_interface, termination_a_type="dcim.interface",
switch_ip=switch_ip, termination_b_id=nb_switch_interface.id,
termination_b_type="dcim.interface",
)
nb_server_interface.cable = cable
logging.info(
'Connected interface {interface} with {switch_interface} of {switch_ip}'.format(
interface=nb_server_interface.name,
switch_interface=switch_interface,
switch_ip=switch_ip,
)
) )
)
return nb_server_interface return nb_server_interface
def create_or_update_cable(self, switch_ip, switch_interface, nb_server_interface): def create_or_update_cable(self, switch_ip, switch_interface, nb_server_interface):