From 6fa32712dcb1f0e013626408cf872fff297e6a49 Mon Sep 17 00:00:00 2001 From: "ricardo.bartels@telekom.de" Date: Fri, 26 Aug 2022 23:16:31 +0200 Subject: [PATCH] adds 'ip_tenant_inheritance_order' config option #199 --- module/sources/common/source_base.py | 30 +++++++++++++++++++--------- module/sources/vmware/connection.py | 19 ++++++++++++++++-- settings-example.ini | 9 +++++++++ 3 files changed, 47 insertions(+), 11 deletions(-) diff --git a/module/sources/common/source_base.py b/module/sources/common/source_base.py index b68f4fa..9737a4a 100644 --- a/module/sources/common/source_base.py +++ b/module/sources/common/source_base.py @@ -215,7 +215,7 @@ def return_longest_matching_prefix_for_ip(self, ip_to_match=None, site_name=None return current_longest_matching_prefix def add_update_interface(self, interface_object, device_object, interface_data, interface_ips=None, - disable_vlan_sync=False): + disable_vlan_sync=False, ip_tenant_inheritance_order=None): """ Adds/Updates an interface to/of a NBVM or NBDevice including IP addresses. Validates/enriches data in following order: @@ -240,6 +240,8 @@ def add_update_interface(self, interface_object, device_object, interface_data, list of ip addresses which are assigned to this interface disable_vlan_sync: bool if True, VLAN information will be removed from interface before creating/updating interface + ip_tenant_inheritance_order: list + list of order in which the IP tenant should be assigned, possible values: device, prefix, disabled Returns ------- @@ -321,7 +323,7 @@ def add_update_interface(self, interface_object, device_object, interface_data, log.debug2(f"Trying to find prefix for IP: {ip_object}") possible_ip_vrf = None - possible_ip_tenant = None + prefix_tenant = None # test for site prefixes first matching_site_name = site_name @@ -349,7 +351,7 @@ def add_update_interface(self, interface_object, device_object, interface_data, f"does not match network prefix length '{this_prefix}'!") possible_ip_vrf = grab(matching_ip_prefix, "data.vrf") - possible_ip_tenant = grab(matching_ip_prefix, "data.tenant") + prefix_tenant = grab(matching_ip_prefix, "data.tenant") matching_ip_prefixes.append(matching_ip_prefix) @@ -439,16 +441,26 @@ def add_update_interface(self, interface_object, device_object, interface_data, } # grab tenant from device/vm if prefix didn't provide a tenant - if possible_ip_tenant is None: - possible_ip_tenant = device_tenant + ip_tenant = None + if isinstance(ip_tenant_inheritance_order, list) and "disabled" not in ip_tenant_inheritance_order: + + ip_tenant_inheritance_order_copy = ip_tenant_inheritance_order.copy() + while len(ip_tenant_inheritance_order_copy) > 0: + ip_tenant_source = ip_tenant_inheritance_order_copy.pop(0) + if ip_tenant_source == "device" and device_tenant is not None: + ip_tenant = device_tenant + break + if ip_tenant_source == "prefix" and prefix_tenant is not None: + ip_tenant = prefix_tenant + break if not isinstance(this_ip_object, NBIPAddress): log.debug(f"No existing {NBIPAddress.name} object found. Creating a new one.") if possible_ip_vrf is not None: nic_ip_data["vrf"] = possible_ip_vrf - if possible_ip_tenant is not None: - nic_ip_data["tenant"] = possible_ip_tenant + if ip_tenant is not None: + nic_ip_data["tenant"] = ip_tenant this_ip_object = self.inventory.add_object(NBIPAddress, data=nic_ip_data, source=self) @@ -460,8 +472,8 @@ def add_update_interface(self, interface_object, device_object, interface_data, if grab(this_ip_object, "data.vrf") is None and possible_ip_vrf is not None: nic_ip_data["vrf"] = possible_ip_vrf - if grab(this_ip_object, "data.tenant") is None and possible_ip_tenant is not None: - nic_ip_data["tenant"] = possible_ip_tenant + if grab(this_ip_object, "data.tenant") is None and ip_tenant is not None: + nic_ip_data["tenant"] = ip_tenant this_ip_object.update(data=nic_ip_data, source=self) diff --git a/module/sources/vmware/connection.py b/module/sources/vmware/connection.py index 7815856..96112a4 100644 --- a/module/sources/vmware/connection.py +++ b/module/sources/vmware/connection.py @@ -138,7 +138,8 @@ class VMWareHandler(SourceBase): "set_source_name_as_cluster_group": False, "sync_vm_dummy_interfaces": False, "disable_vlan_sync": False, - "host_management_interface_match": "management, mgmt" + "host_management_interface_match": "management, mgmt", + "ip_tenant_inheritance_order": "device, prefix" } deprecated_settings = {} @@ -345,6 +346,18 @@ def parse_config_settings(self, config_settings): config_settings["host_management_interface_match"] = \ [x.strip() for x in host_management_interface_match.split(",")] + config_settings["ip_tenant_inheritance_order"] = \ + [x.strip() for x in grab(config_settings, "ip_tenant_inheritance_order", fallback="").split(",")] + + for ip_tenant_inheritance in config_settings["ip_tenant_inheritance_order"]: + if ip_tenant_inheritance not in ["device", "prefix", "disabled"]: + log.error(f"Config value '{ip_tenant_inheritance}' invalid for " + f"config option 'ip_tenant_inheritance_order'!") + validation_failed = True + if len(config_settings["ip_tenant_inheritance_order"]) > 2: + log.error("Config option 'ip_tenant_inheritance_order' can contain only 2 items max") + validation_failed = True + if validation_failed is True: log.error("Config validation failed. Exit!") exit(1) @@ -1284,7 +1297,9 @@ def add_device_vm_to_inventory(self, object_type, object_data, pnic_data=None, v # add/update interface with retrieved data nic_object, ip_address_objects = self.add_update_interface(nic_object_dict.get(int_name), device_vm_object, int_data, nic_ips.get(int_name, list()), - self.disable_vlan_sync) + disable_vlan_sync=self.disable_vlan_sync, + ip_tenant_inheritance_order= + self.ip_tenant_inheritance_order) # add all interface IPs for ip_object in ip_address_objects: diff --git a/settings-example.ini b/settings-example.ini index 806950b..f2e97be 100644 --- a/settings-example.ini +++ b/settings-example.ini @@ -304,6 +304,15 @@ permitted_subnets = 172.16.0.0/12, 10.0.0.0/8, 192.168.0.0/16, fd00::/8 # default: management, mgmt #host_management_interface_match = management, mgmt +# define in which order the IP address tenant will be assigned if tenant is undefined. +# possible values: +# * device : host or VM tenant will be assigned to the IP address +# * prefix : if the IP address belongs to an existing prefix and this prefix has a tenant assigned, then this one is used +# * disabled : no tenant assignment to the IP address will be performed +# the order of the definition is important, the default is "device, prefix" which means: +# If the device has a tenant then this one will be used. If not, the prefix tenant will be used if defined +#ip_tenant_inheritance_order = device, prefix + [source/my-redfish-example] # Defines if this source is enabled or not