TheNetworkGuy / netbox-zabbix-sync

Python script to synchronise Netbox devices to Zabbix.
MIT License
109 stars 27 forks source link

[idea] Device name (netbox) as visible hostname (zabbix) #45

Closed k109x closed 1 month ago

k109x commented 5 months ago

Hi! Great project! I needed support for long device host name, so and I made a small patch, it might be interesting. I changed the variable mapping, self.name is now "visible name" field in zabbix:

image

createInZabbix:

                host = self.zabbix.host.create(host=self.ip,
                                                     name=self.name,

zabbixHostnameExists:

        host = self.zabbix.host.get(filter={'name': self.ip}, output=[])

ConsistencyCheck:

        if(host["name"] == self.name):
            logger.debug(f"Device {self.name}: visible name in-sync.")
        else:
            logger.warning(f"Device {self.name}: visible name OUT of sync. "
                           f"Received value: {host['name']}")
            self.updateZabbixHost(name=self.name)
        if(host["host"] == self.ip):
            logger.debug(f"Device {self.name}: hostname in-sync.")
        else:
            logger.warning(f"Device {self.name}: hostname OUT of sync. "
                           f"Received value: {host['host']}")
            self.updateZabbixHost(host=self.ip,name=self.name)
TheNetworkGuy commented 4 months ago

Glad to hear that you like the project! I used the "host name" field as a starting point given that the "host name" field is mandatory and the "visible name" field is optional. I might implement a simple function that would allow users to set the "visible name" field as preferred instead of the "host name" field.

However since the host name field is mandatory, what would your preference be? A shorter version of the visible name or replace it with the IP address (like you did.)

k109x commented 4 months ago

It's clear.. ;) But, look at zabbix docs about hostname field: Alphanumerics, spaces, dots, dashes and underscores are allowed. However, leading and trailing spaces are disallowed. Device name in netbox can contain any characters. Due to this, an error may occur during synchronization

There are two ways: filter device name variable, or change hostname variable mapping to visible name, primary_ip -> hostname I can also note that "device name" field in netbox is not unique, but "hostname" in zabbix - does.

q1x commented 4 months ago

I agree it would be useful to utilize 'visible name' and 'host name' fields separately, as 'host name' is often a technical name and 'visible name' a more user friendly name for the user using the dashboard.

However, I'm not fond of using the IP address as the 'host name' in Zabbix as that could easily result in naming clashes in multi tenant or multi-vrf environments.

Food for thought?

k109x commented 4 months ago

Maybe you're right. What about another suggestions? 'host name' can be filled as 'asset tag' value, if it is missing, set 'host name' as "device[netbox_device_id]"

TheNetworkGuy commented 4 months ago

The asset tag could be useful, however this is not an option in clustered setup where the name is overwritten by the cluster name. Assuming that you give similar names to clustered devices (eg. long names, umlauts, non-allowed characters.)

Personally i don't see a lot of Netbox deployment utilizing the asset field. However this doesn't mean its not viable. It could provide for an easy "backdoor" trick for long names and special characters.

TheNetworkGuy commented 1 month ago

I would propose to use the same values for both fields but shorten the hostname field and replacing any special characters. This would be quick to implement, solve the 2 problems we currently have and won't make an impact on the user UI.

However it would make an impact for users utalizing the API. It will only clash when names are either too long or have special characters.

I'll start working on this request and make a branch to test this functionallity.

TheNetworkGuy commented 1 month ago

On second thought this might also clash with the requirement of unique hostnames. Given this scenario with 2 switches:

Cutting off the last couple of characters would end the string with something like "in Netbox declared which is longer than 128 chara". Therefore making them both identical and failing the hostname unique requirement.

On the other hand starting at the front isn't ideal either since this comes with the same risks.

@k109x Can you elaborate your use case on why you use such long names? If it's just one or 2 hosts within an inventory of a few 100s then i'm more tempted to make a check for the length of a hostname and skip a host if its name is longer than 128 characters.

Another trick would be a bit weird but would suffice all scenario's, which would be to hash the visible name and use the hash as hostname. Pro's:

Con's:

A final trick would be to use the Netbox ID with a basic prefix. I think this will be my preferred option since the Netbox ID is already an unique ID therefore fulfilling the unique requirement. And its more familiair / makes more sense than a complete hash function.

TheNetworkGuy commented 1 month ago

So after some code digging i found the following:

Testing on Netbox 4: it seems that i hit a hard limit of 64 characters for the device name. My fix does seem to work for #42. Looking forward to your reply and use case since i don't see a problem with an enforced 64 character limit in Netbox syncing to a 128 character limit field in Zabbix.

k109x commented 1 month ago

@TheNetworkGuy I have this cases:

I use this construct in production:

 host = self.zabbix.host.create(name=self.name,
                                               host=f"netbox_device_{self.id}",
                                               status=self.zabbix_state,
                                               interfaces=interfaces,
                                               groups=groups,
                                               templates=self.zbx_templates,
                                               proxy_hostid=self.zbxproxy,
                                               description=f"https://mynetboxhost.domain/dcim/devices/{self.id}/")
TheNetworkGuy commented 1 month ago

Okay that makes sense. I've updated the code to use the same method as you did but only for "special names" to fix the point that you bring up: "the hostname can contains special characters or non-English characters".

However i am unable to replicate your initial comment about the character limit. Can i conclude that this fix for now is enough for you to close this issue? :)

k109x commented 1 month ago

Yes, sure Thanks a lot