From b25e93dbddb425b96b912dadcea4ed0884ad37d2 Mon Sep 17 00:00:00 2001 From: Dmitriy Rabotyagov Date: Thu, 31 Aug 2023 15:06:38 +0200 Subject: [PATCH] Prevent routers to be always updated if no shared public network Current logic assumes that external_fixed_ips should be always defined, otherwise `req_fip_map` is an empty sequence, which makes _needs_update to return True. With that not having external_fixed_ips is a vaild case whenever deployment does not have shared public network. This usually the case when public network is not passed to computes and public network is used only for routers and floating IPs. Patch changes logic by addind a `is not None` support to only compare external_fip configration when user explicitly passed something (passing an empty dict is equal to requesting "empty" configuration). Co-Authored-by: Artem Goncharov Change-Id: Id0f69fe4c985c4c38b493577250cad4e589b9d24 --- plugins/modules/router.py | 59 ++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/plugins/modules/router.py b/plugins/modules/router.py index c82819f4..efbbd19f 100644 --- a/plugins/modules/router.py +++ b/plugins/modules/router.py @@ -366,38 +366,36 @@ class RouterModule(OpenStackModule): if 'ip_address' in p: cur_fip_map[p['subnet_id']].add(p['ip_address']) req_fip_map = defaultdict(set) - for p in external_fixed_ips: - if 'ip_address' in p: - req_fip_map[p['subnet_id']].add(p['ip_address']) + if external_fixed_ips is not None: + # User passed expected external_fixed_ips configuration. + # Build map of requested ips/subnets. + for p in external_fixed_ips: + if 'ip_address' in p: + req_fip_map[p['subnet_id']].add(p['ip_address']) - # Check if external ip addresses need to be added - for fip in external_fixed_ips: - subnet = fip['subnet_id'] - ip = fip.get('ip_address', None) - if subnet in cur_fip_map: - if ip is not None and ip not in cur_fip_map[subnet]: - # mismatching ip for subnet + # Check if external ip addresses need to be added + for fip in external_fixed_ips: + subnet = fip['subnet_id'] + ip = fip.get('ip_address', None) + if subnet in cur_fip_map: + if ip is not None and ip not in cur_fip_map[subnet]: + # mismatching ip for subnet + return True + else: + # adding ext ip with subnet 'subnet' return True - else: - # adding ext ip with subnet 'subnet' - return True - # Check if external ip addresses need to be removed - for fip in cur_ext_fips: - subnet = fip['subnet_id'] - ip = fip['ip_address'] - if subnet in req_fip_map: - if ip not in req_fip_map[subnet]: - # removing ext ip with subnet (ip clash) + # Check if external ip addresses need to be removed. + for fip in cur_ext_fips: + subnet = fip['subnet_id'] + ip = fip['ip_address'] + if subnet in req_fip_map: + if ip not in req_fip_map[subnet]: + # removing ext ip with subnet (ip clash) + return True + else: + # removing ext ip with subnet return True - else: - # removing ext ip with subnet - return True - - if not external_fixed_ips and len(cur_ext_fips) > 1: - # No external fixed ips requested but - # router has several external fixed ips - return True # Check if internal interfaces need update if to_add or to_remove or missing_port_ids: @@ -448,7 +446,8 @@ class RouterModule(OpenStackModule): return kwargs def _build_router_interface_config(self, filters): - external_fixed_ips = [] + # Undefine external_fixed_ips to have possibility to unset them + external_fixed_ips = None internal_ports_missing = [] internal_ifaces = [] @@ -459,6 +458,8 @@ class RouterModule(OpenStackModule): .get('external_fixed_ips') ext_fixed_ips = ext_fixed_ips or self.params['external_fixed_ips'] if ext_fixed_ips: + # User passed external_fixed_ips configuration. Initialize ips list + external_fixed_ips = [] for iface in ext_fixed_ips: subnet = self.conn.network.find_subnet( iface['subnet'], ignore_missing=False, **filters)