diff --git a/module/sources/vmware/config.py b/module/sources/vmware/config.py index 26c972c..de2d226 100644 --- a/module/sources/vmware/config.py +++ b/module/sources/vmware/config.py @@ -223,6 +223,31 @@ def __init__(self): description="""Try to find existing host based on serial number. This can cause issues with blade centers if VMWare does not report the blades serial number properly.""", default_value=True), + + ConfigOption("match_vm_by_serial", + bool, + description="""Fall back to matching VMs by serial number (BIOS UUID) if no name+cluster + match is found. Can misattribute a VM to an unrelated NetBox object if the same UUID is + reported by multiple sources, e.g. a cloned/migrated VM whose stale copy overwrites the + real VM's cluster/site/status.""", + default_value=True), + + ConfigOption("match_vm_by_mac_address", + bool, + description="""Fall back to matching VMs by vNIC MAC address if no name+cluster match is + found. Runs before 'match_vm_by_serial', so disabling that option alone is not enough if + MACs are also shared. Same misattribution risk as match_vm_by_serial, triggered by a + cloned/copied VM with a duplicate MAC.""", + default_value=True), + + ConfigOption("match_vm_by_ip_address", + bool, + description="""Fall back to matching VMs by primary IP if no name/cluster/MAC/serial + match is found. Same misattribution risk, triggered even transiently, e.g. a duplicate VM + in another cluster briefly powered on with the same IP. Not guaranteed to self-correct + afterwards, since vCenter can keep reporting a cached IP after power-off.""", + default_value=True), + ConfigOption("collect_hardware_asset_tag", bool, description="Attempt to collect asset tags from vCenter hosts", diff --git a/module/sources/vmware/connection.py b/module/sources/vmware/connection.py index c087cf8..28b547e 100644 --- a/module/sources/vmware/connection.py +++ b/module/sources/vmware/connection.py @@ -1135,6 +1135,10 @@ def add_device_vm_to_inventory(self, object_type, object_data, pnic_data=None, v (object_type.name, device_vm_object.get_display_name(including_second_key=True))) # keep searching if no exact match was found + elif object_type == NBVM and self.settings.match_vm_by_mac_address is False: + + log.debug2("Matching VMs by MAC address is disabled via 'match_vm_by_mac_address'. Skipping.") + else: log.debug2(f"No exact match found. Trying to find {object_type.name} based on MAC addresses") @@ -1162,7 +1166,8 @@ def add_device_vm_to_inventory(self, object_type, object_data, pnic_data=None, v data={"asset_tag": object_data.get("asset_tag")}) # look for VMs with same serial - if object_type == NBVM and device_vm_object is None and object_data.get("serial") is not None: + if object_type == NBVM and device_vm_object is None and object_data.get("serial") is not None and \ + self.settings.match_vm_by_serial is True: log.debug2(f"No match found. Trying to find {object_type.name} based on serial number") device_vm_object = self.inventory.get_by_data(object_type, data={"serial": object_data.get("serial")}) @@ -1171,6 +1176,10 @@ def add_device_vm_to_inventory(self, object_type, object_data, pnic_data=None, v (object_type.name, device_vm_object.get_display_name(including_second_key=True))) # keep looking for devices with the same primary IP + elif object_type == NBVM and self.settings.match_vm_by_ip_address is False: + + log.debug2("Matching VMs by primary IP address is disabled via 'match_vm_by_ip_address'. Skipping.") + else: log.debug2(f"No match found. Trying to find {object_type.name} based on primary IP addresses") diff --git a/settings-example.ini b/settings-example.ini index 52a288f..4369e88 100644 --- a/settings-example.ini +++ b/settings-example.ini @@ -257,6 +257,24 @@ password = super-secret ; centers if VMWare does not report the blades serial number properly. ;match_host_by_serial = True +; Fall back to matching VMs by serial number (BIOS UUID) if no name+cluster match is +; found. Can misattribute a VM to an unrelated NetBox object if the same UUID is reported +; by multiple sources, e.g. a cloned/migrated VM whose stale copy overwrites the real VM's +; cluster/site/status. +;match_vm_by_serial = True + +; Fall back to matching VMs by vNIC MAC address if no name+cluster match is found. Runs +; before 'match_vm_by_serial', so disabling that option alone is not enough if MACs are +; also shared. Same misattribution risk as match_vm_by_serial, triggered by a +; cloned/copied VM with a duplicate MAC. +;match_vm_by_mac_address = True + +; Fall back to matching VMs by primary IP if no name/cluster/MAC/serial match is found. +; Same misattribution risk, triggered even transiently, e.g. a duplicate VM in another +; cluster briefly powered on with the same IP. Not guaranteed to self-correct afterwards, +; since vCenter can keep reporting a cached IP after power-off. +;match_vm_by_ip_address = True + ; Attempt to collect asset tags from vCenter hosts ;collect_hardware_asset_tag = True