1717import re
1818import socket
1919
20- from first import first
2120from napalm import get_network_driver
2221from napalm .base .exceptions import ConnectionException , CommandErrorException
2322
@@ -196,7 +195,11 @@ def get_platform_object_from_netbox(platform_slug):
196195
197196 return platform
198197
199- def get_required_info (self ):
198+ def get_required_info (
199+ self ,
200+ default_mgmt_if = PLUGIN_SETTINGS ["default_management_interface" ],
201+ default_mgmt_pfxlen = PLUGIN_SETTINGS ["default_management_prefix_length" ],
202+ ):
200203 """Gather information from the network device that is needed to onboard the device into the NetBox system.
201204
202205 Raises:
@@ -217,6 +220,9 @@ def get_required_info(self):
217220 try :
218221 platform_slug = self .get_platform_slug ()
219222 platform_object = self .get_platform_object_from_netbox (platform_slug = platform_slug )
223+ if self .ot .platform != platform_object :
224+ self .ot .platform = platform_object
225+ self .ot .save ()
220226
221227 driver_name = platform_object .napalm_driver
222228
@@ -248,17 +254,18 @@ def get_required_info(self):
248254 # locate the interface assigned with the mgmt_ipaddr value and retain
249255 # the interface name and IP prefix-length so that we can use it later
250256 # when creating the IPAM IP-Address instance.
257+ # Note that in some cases (e.g., NAT) the mgmt_ipaddr may differ than
258+ # the interface addresses present on the device. We need to handle this.
251259
252- try :
253- mgmt_ifname , mgmt_pflen = first (
254- ( if_name , if_addr_data [ "prefix_length" ])
255- for if_name , if_data in ip_ifs .items ()
256- for if_addr , if_addr_data in if_data [ "ipv4" ]. items ()
257- if if_addr == mgmt_ipaddr
258- )
260+ def get_mgmt_info () :
261+ """Get the interface name and prefix length for the management interface."""
262+ for if_name , if_data in ip_ifs . items ():
263+ for if_addr , if_addr_data in if_data [ "ipv4" ] .items ():
264+ if if_addr == mgmt_ipaddr :
265+ return ( if_name , if_addr_data [ "prefix_length" ])
266+ return ( default_mgmt_if , default_mgmt_pfxlen )
259267
260- except Exception as exc :
261- raise OnboardException (reason = "fail-general" , message = str (exc ))
268+ mgmt_ifname , mgmt_pflen = get_mgmt_info ()
262269
263270 # retain the attributes that will be later used by NetBox processing.
264271
@@ -322,14 +329,14 @@ def ensure_device_type(
322329 # instance.
323330
324331 try :
325- self .manufacturer = Manufacturer .objects .get (slug = self .netdev .vendor )
332+ self .manufacturer = Manufacturer .objects .get (slug = self .netdev .vendor . lower () )
326333 except Manufacturer .DoesNotExist :
327334 if not create_manufacturer :
328335 raise OnboardException (
329336 reason = "fail-config" , message = f"ERROR manufacturer not found: { self .netdev .vendor } "
330337 )
331338
332- self .manufacturer = Manufacturer .objects .create (name = self .netdev .vendor , slug = self .netdev .vendor )
339+ self .manufacturer = Manufacturer .objects .create (name = self .netdev .vendor , slug = self .netdev .vendor . lower () )
333340 self .manufacturer .save ()
334341
335342 # Now see if the device type (slug) already exists,
@@ -343,7 +350,9 @@ def ensure_device_type(
343350 logging .warning ("device model is now: %s" , self .netdev .model )
344351
345352 try :
346- self .device_type = DeviceType .objects .get (slug = self .netdev .model )
353+ self .device_type = DeviceType .objects .get (slug = self .netdev .model .lower ())
354+ self .netdev .ot .device_type = self .device_type .slug
355+ self .netdev .ot .save ()
347356 except DeviceType .DoesNotExist :
348357 if not create_device_type :
349358 raise OnboardException (
@@ -352,9 +361,11 @@ def ensure_device_type(
352361
353362 logging .info ("CREATE: device-type: %s" , self .netdev .model )
354363 self .device_type = DeviceType .objects .create (
355- slug = self .netdev .model , model = self .netdev .model .upper (), manufacturer = self .manufacturer
364+ slug = self .netdev .model . lower () , model = self .netdev .model .upper (), manufacturer = self .manufacturer
356365 )
357366 self .device_type .save ()
367+ self .netdev .ot .device_type = self .device_type .slug
368+ self .netdev .ot .save ()
358369 return
359370
360371 if self .device_type .manufacturer .id != self .manufacturer .id :
@@ -398,6 +409,7 @@ def ensure_device_role(
398409
399410 def ensure_device_instance (self ):
400411 """Ensure that the device instance exists in NetBox and is assigned the provided device role or DEFAULT_ROLE."""
412+ # TODO: this can create duplicate entries in NetBox...
401413 device , _ = Device .objects .get_or_create (
402414 name = self .netdev .hostname ,
403415 device_type = self .device_type ,
@@ -409,7 +421,7 @@ def ensure_device_instance(self):
409421 device .serial = self .netdev .serial_number
410422 device .save ()
411423
412- self .netdev .ot .device = device
424+ self .netdev .ot .created_device = device
413425 self .netdev .ot .save ()
414426
415427 self .device = device
0 commit comments