diff --git a/README.md b/README.md index 0430a67..2adefac 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ - # NetBox-Sync This is a tool to sync data from different sources to a NetBox instance. @@ -295,6 +294,17 @@ Check out the documentations for the different sources * [vmware](https://github.com/bb-Ricardo/netbox-sync/blob/main/docs/source_vmware.md) * [check_redfish](https://github.com/bb-Ricardo/netbox-sync/blob/main/docs/source_check_redfish.md) +### Filtering +netbox-sync provides various filtering capabilities to control what objects are synced from sources to NetBox: + +1. **General VM filtering**: Use `vm_include_filter` and `vm_exclude_filter` to include or exclude VMs by name. +2. **Tag-based VM filtering**: Use `vm_exclude_by_tag_filter` to exclude VMs with specific vCenter tags. +3. **Partial information filtering**: + - Use `vm_exclude_disk_sync` to exclude disk synchronization for VMs matching specific name patterns. + - Use `vm_exclude_disk_sync_by_tag` to exclude disk synchronization for VMs with specific vCenter tags. + +These filters allow for fine-grained control over what information is synchronized, helping to avoid clutter in the change log from temporary or backup-related disk changes. + If you have multiple vCenter instances or check_redfish folders just add another source with the same type in the **same** file. diff --git a/docs/source_vmware.md b/docs/source_vmware.md index 11f1d03..4552918 100644 --- a/docs/source_vmware.md +++ b/docs/source_vmware.md @@ -107,3 +107,25 @@ Primary IPv4/6 will be determined by interface that provides the default route f **Note:**
IP address information can only be extracted if guest tools are installed and running. + +### Filtering VM Disk Information +VM disks are synchronized between vCenter and NetBox. Since NetBox 3.7.0, virtual disks are tracked as separate objects +linked to VMs. In some scenarios, such as when temporary disks are attached to VMs during backup operations +(e.g., "Independent-nonpersistent" disks from Veeam), you might want to exclude these changes from synchronization +to avoid cluttering your NetBox change log. + +You can use the following filter options to exclude disk synchronization for specific VMs: + +1. **`vm_exclude_disk_sync`**: A regex pattern matching VM names where disk synchronization should be excluded. + ```ini + vm_exclude_disk_sync = backup-.*, veeam-.* + ``` + +2. **`vm_exclude_disk_sync_by_tag`**: A comma-separated list of vCenter tags. VMs with any of these tags will have + their disk information excluded from synchronization. + ```ini + vm_exclude_disk_sync_by_tag = backup-vm, veeam-job + ``` + +When a VM matches these filters, it will still be synchronized to NetBox with all its other information +(CPU, memory, interfaces, IP addresses, etc.), but changes to disk information will be ignored. diff --git a/module/sources/vmware/config.py b/module/sources/vmware/config.py index 7e448a2..640d0cb 100644 --- a/module/sources/vmware/config.py +++ b/module/sources/vmware/config.py @@ -116,7 +116,22 @@ def __init__(self): """, config_example="tag-a, tag-b" ), - + ConfigOption("vm_exclude_disk_sync", + str, + description="""defines a comma separated list of VM names (regex) where disk synchronization + will be excluded. A VM matching this filter will still be synced to NetBox, + but its disk information won't be updated. + """, + config_example="backup-.*, temp-.*" + ), + ConfigOption("vm_exclude_disk_sync_by_tag", + str, + description="""defines a comma separated list of vCenter tags which (if assigned to a VM) + will exclude this VM from disk synchronization. A VM with this tag will still be synced + to NetBox, but its disk information won't be updated. + """, + config_example="backup-vm, veeam-job" + ), ConfigOptionGroup(title="relations", options=[ ConfigOption("cluster_site_relation", @@ -469,6 +484,25 @@ def validate_options(self): continue + if option.key == "vm_exclude_disk_sync_by_tag": + + option.set_value(quoted_split(option.value)) + + continue + + if option.key == "vm_exclude_disk_sync": + + re_compiled = None + try: + re_compiled = re.compile(option.value) + except Exception as e: + log.error(f"Problem parsing regular expression for '{self.source_name}.{option.key}': {e}") + self.set_validation_failed() + + option.set_value(re_compiled) + + continue + if "relation" in option.key and "vlan_group_relation" not in option.key: relation_data = list() diff --git a/module/sources/vmware/connection.py b/module/sources/vmware/connection.py index 9ab8974..88c089f 100644 --- a/module/sources/vmware/connection.py +++ b/module/sources/vmware/connection.py @@ -1128,24 +1128,46 @@ def add_device_vm_to_inventory(self, object_type, object_data, pnic_data=None, v if version.parse(self.inventory.netbox_api_version) >= version.parse("3.7.0") and \ object_type == NBVM and disk_data is not None and len(disk_data) > 0: - # create pairs of existing and discovered disks. - # currently these disks are only used within the VM model. that's why we use this simple approach and - # just rewrite disk as they appear in order. - # otherwise we would need to implement a matching function like matching interfaces. - disk_zip_list = zip_longest( - sorted(device_vm_object.get_virtual_disks(), key=lambda x: grab(x, "data.name")), - sorted(disk_data, key=lambda x: x.get("name")), - fillvalue="X") - - for existing, discovered in disk_zip_list: - if existing == "X": - self.inventory.add_object(NBVirtualDisk, source=self, - data={**discovered, **{"virtual_machine": device_vm_object}}, ) - elif discovered == "X": - log.info(f"{existing.name} '{existing.get_display_name(including_second_key=True)}' has been deleted") - existing.deleted = True - else: - existing.update(data=discovered, source=self) + # Skip disk updates for VMs that match exclusion filters + skip_disk_sync = False + + # Check if VM name matches vm_exclude_disk_sync filter + if hasattr(self.settings, 'vm_exclude_disk_sync') and self.settings.vm_exclude_disk_sync is not None: + if self.settings.vm_exclude_disk_sync.match(object_data.get("name")): + log.debug(f"VM '{object_data.get('name')}' matches vm_exclude_disk_sync filter. " + f"Skipping disk synchronization.") + skip_disk_sync = True + + # Check if VM has any tags that match vm_exclude_disk_sync_by_tag filter + if not skip_disk_sync and hasattr(self.settings, 'vm_exclude_disk_sync_by_tag') and \ + self.settings.vm_exclude_disk_sync_by_tag is not None: + vm_tags = [NetBoxObject.extract_tag_name(tag) for tag in device_vm_object.data.get("tags", list())] + for exclude_tag in self.settings.vm_exclude_disk_sync_by_tag: + if exclude_tag in vm_tags: + log.debug(f"VM '{object_data.get('name')}' has tag '{exclude_tag}' which matches " + f"vm_exclude_disk_sync_by_tag filter. Skipping disk synchronization.") + skip_disk_sync = True + break + + if not skip_disk_sync: + # create pairs of existing and discovered disks. + # currently these disks are only used within the VM model. that's why we use this simple approach and + # just rewrite disk as they appear in order. + # otherwise we would need to implement a matching function like matching interfaces. + disk_zip_list = zip_longest( + sorted(device_vm_object.get_virtual_disks(), key=lambda x: grab(x, "data.name")), + sorted(disk_data, key=lambda x: x.get("name")), + fillvalue="X") + + for existing, discovered in disk_zip_list: + if existing == "X": + self.inventory.add_object(NBVirtualDisk, source=self, + data={**discovered, **{"virtual_machine": device_vm_object}}, ) + elif discovered == "X": + log.info(f"{existing.name} '{existing.get_display_name(including_second_key=True)}' has been deleted") + existing.deleted = True + else: + existing.update(data=discovered, source=self) # compile all nic data into one dictionary if object_type == NBVM: diff --git a/settings-example.ini b/settings-example.ini index 432d4c2..039bd63 100644 --- a/settings-example.ini +++ b/settings-example.ini @@ -405,6 +405,14 @@ password = super-secret ; behavior also applies for VM disk sizes. ;vm_disk_and_ram_in_decimal = True +; defines a comma separated list of VM names (regex) where disk synchronization will be excluded. +; A VM matching this filter will still be synced to NetBox, but its disk information won't be updated. +;vm_exclude_disk_sync = backup-.*, temp-.* + +; defines a comma separated list of vCenter tags which (if assigned to a VM) will exclude this VM from +; disk synchronization. A VM with this tag will still be synced to NetBox, but its disk information won't be updated. +;vm_exclude_disk_sync_by_tag = backup-vm, veeam-job + [source/my-redfish-example] ; Defines if this source is enabled or not