How to link a custom field with a many2one relationship to ip address and devices

41 views
Skip to first unread message

Anesu Mukanya

unread,
Aug 5, 2021, 11:11:49 AM8/5/21
to NetBox
I am working on a plugin.I have a custom field customer_id that is can be linked to multiple ip addresses or devices. I want to create a model in netbox that links the customer_id to the ip address and a device, a many2one relationship. How do i create this relation. Thank you.

Brian Candler

unread,
Aug 5, 2021, 1:19:45 PM8/5/21
to NetBox
That's a Django question, not a Netbox one, so a Django mailing list would be the right place to ask.

Brian Candler

unread,
Aug 5, 2021, 1:22:18 PM8/5/21
to NetBox
Possibly also useful is
if you want a single relation which can link to arbitrary objects.

(Normally you would model "many2one" by adding an extra field on device or IP which links to the foreign model, but with plugins you're not allowed to modify the built-in Netbox data models)

Message has been deleted
Message has been deleted

Anesu Mukanya

unread,
Aug 6, 2021, 6:15:11 AM8/6/21
to NetBox
Thanks Brian for responding. You mentioned that this is a django question. Yes because netbox is build on django and no because we are dealing with netbox built in methods. Linking two methods to create a many2one relationship like so 

class CustomerID(models.Model):
name = models.CharField(max_length=32)

def __str__(self):
return self.name

class IPAddress(models.Model):
name = models.CharField(max_length=32)
ipaddress= models.ForeignKey(
to='CustomerID',
on_delete=models.CASCADE,
blank=True,
null = True
)
that is doable.

CustomerID is a custom field already defined in netbox with existing values and what i want do is to link the customer_id(custom field) and the related IPAddress for the ipam resource. The Ipam resources are both the Ip address and a device. What i want is to be able to connect to those device and try and extract the device information so that i can now create a device that is linked to those resources. So how do i create a model that relates a customer_id to an IPAddress resource and a device resource.

Brian Candler

unread,
Aug 6, 2021, 8:02:35 AM8/6/21
to NetBox
If you are writing a plugin, then presumably you are using a recent version of Netbox.  In Netbox v2.10 onwards, custom fields are not held in their own models.  There is a single JSON field "custom_field_data" on each model, containg an object of {"cfname":"cfvalue"}

I am confused by what you're saying.  On the one hand you're saying "CustomerID is a custom field", but then you are showing "CustomerID" as a model.  I can only assume you mean that "CustomerID" is a custom field which *refers to* the CustomerID model in some way (e.g. it contains the value of CustomerID.name)

Unfortunately, custom fields don't have a way to enforce referential integrity - not to standard netbox models, and certainly not to plugin models.  This field would be just plain text or a number.  That is, it's easy to have a CustomerID custom field on both Device and IPAddress, but no way to ensure that the data entered is valid.  Having said that, it might be possible using the validation feature in the upcoming Netbox 3.x to write a custom validator which looks up the CustomerID and gives an error if there's no corresponding plugin model.  I haven't tested this myself.

In your code you also show a class "IPAddress"; does this mean that your plugin also creates a model "IPAddress", separately from Netbox's "IPAddress"? That seems confusing to me, but I don't really know what you're trying to achieve.  If you want to model IP addresses separately from Netbox's IP addresses, then I suggest you at least call the model something else.  You can of course have custom fields on IPAddress, just as you can on Device.  But you cannot modify the core Netbox models in any way.

There's another way to do this in a plugin, avoiding custom fields altogether:
1. make a model "Customer" (which has a "name" field containing the customerID, and also has a database-assigned ID like other Netbox models)
2. make a model which links Customer to Device (i.e. it has customer_id and device_id)
3. make a model which links Customer to IPAddress

2 and 3 give you referential integrity.  These are structurally ManyToMany join models, but by adding a unique constraint on the device_id and ipaddress_id (on the join models), you can ensure that each Device and IPAddress can only be linked to one Customer.  That is, you can turn it into a ManyToOne as far as the user is concerned, and for database-enforced integrity.
Reply all
Reply to author
Forward
0 new messages