From 661ab6480ae910c10db0060220ae1a1b66331ac3 Mon Sep 17 00:00:00 2001 From: Fabiano Correa Mercer Date: Wed, 29 Nov 2023 06:17:25 -0300 Subject: [PATCH] Updates after the mgmt network reconfiguration Updates the no_proxy list in the service-parameter-list during the management network reconfiguration. In the first reboot after the management network reconfiguration, The system will use the new management IPs and some files will be updated, like the /etc/hosts. It is necessary to update the following paths, with the new values: /opt/platform/sysinv /opt/platform/config Additionally, during the first reboot the system is still using the old mgmt IPs until the apply_network_config.sh and puppet code updates the system. The sw-patch services starts before or at same time of these operations and can use the old MGMT IPs and failed to answer audit requests. For this reason it is necessary to restart these services. Tests: IPv6 mgmt network reconfig in subcloud AIO-SX IPv4 mgmt network reconfig in standalone AIO-SX AIO-DX Fresh install AIO-SX Fresh install AIO-SX IPv4 apply patch after mgmt reconfig Story: 2010722 Task: 49203 Change-Id: I8a17f50c229a53965e13c889f0ea6ff8efd687c3 Signed-off-by: Fabiano Correa Mercer --- .../scripts/controller_config | 10 +++-- .../sysinv/api/controllers/v1/address_pool.py | 43 +++++++++++++++++++ .../api/controllers/v1/interface_network.py | 39 +++++++++++++++++ .../sysinv/sysinv/sysinv/common/constants.py | 1 + .../sysinv/sysinv/sysinv/conductor/manager.py | 32 +++++++++----- tsconfig/tsconfig/tsconfig/tsconfig.py | 5 +++ 6 files changed, 116 insertions(+), 14 deletions(-) diff --git a/controllerconfig/controllerconfig/scripts/controller_config b/controllerconfig/controllerconfig/scripts/controller_config index 2bcf5c10f6..c92d667d65 100755 --- a/controllerconfig/controllerconfig/scripts/controller_config +++ b/controllerconfig/controllerconfig/scripts/controller_config @@ -108,8 +108,7 @@ get_ip() local dnsmasq_file=dnsmasq.addn_hosts # Replace the dnsmasq files with new Management Network range - if [ -e $ETC_PLATFORM_DIR/.mgmt_network_reconfiguration_unlock ] && \ - [ -e $ETC_PLATFORM_DIR/.mgmt_network_reconfiguration_ongoing ]; then + if [ -e $ETC_PLATFORM_DIR/.mgmt_network_reconfiguration_unlock ]; then dnsmasq_file=dnsmasq.addn_hosts.temp fi @@ -538,8 +537,7 @@ start() fi # Replace the dnsmasq files with new Management Network range - if [ -e $ETC_PLATFORM_DIR/.mgmt_network_reconfiguration_unlock ] && \ - [ -e $ETC_PLATFORM_DIR/.mgmt_network_reconfiguration_ongoing ]; then + if [ -e $ETC_PLATFORM_DIR/.mgmt_network_reconfiguration_unlock ]; then echo "Management networking reconfiguration ongoing, replacing dnsmasq config files." if [ -e $CONFIG_DIR/dnsmasq.addn_hosts.temp ] && \ [ -e $CONFIG_DIR/dnsmasq.hosts.temp ]; then @@ -552,6 +550,10 @@ start() else fatal_error "Management networking reconfiguration ongoing and dnsmasq files do not exist." fi + + # Create a flag to update files in /opt/platform/ ( i.e: hosts file ) + touch $ETC_PLATFORM_DIR/.mgmt_reconfig_update_hosts_file + # delete flags rm -f $ETC_PLATFORM_DIR/.mgmt_network_reconfiguration_ongoing rm -f $ETC_PLATFORM_DIR/.mgmt_network_reconfiguration_unlock diff --git a/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/address_pool.py b/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/address_pool.py index 2d69ff56fe..9f6dbec633 100644 --- a/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/address_pool.py +++ b/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/address_pool.py @@ -513,6 +513,43 @@ class AddressPoolController(rest.RestController): self._validate_range_updates(addrpool, updates) return + def _remove_mgmt_ips_from_no_proxy_list(self, addresses): + if addresses: + try: + # get no_proxy from service-parameter-list + no_proxy_entry = pecan.request.dbapi.service_parameter_get_one( + service=constants.SERVICE_TYPE_DOCKER, + section=constants.SERVICE_PARAM_SECTION_DOCKER_PROXY, + name=constants.SERVICE_PARAM_NAME_DOCKER_NO_PROXY + ) + + except exception.NotFound: + # Proxy is not being used. Nothing to do. + return + + no_proxy_list = no_proxy_entry.value.split(',') + + proxy_changed = False + for addr in addresses: + if (addr.name == constants.CONTROLLER_0_MGMT or + addr.name == constants.CONTROLLER_FLOATING_MGMT): + + mgmt_address = addr.address + + # for IPv6 need to add brackets + if cutils.is_valid_ipv6(mgmt_address): + mgmt_address = "[" + mgmt_address + "]" + + # remove the old mgmt IPs from no_proxy list + no_proxy_list.remove(mgmt_address) + proxy_changed = True + + if proxy_changed: + no_proxy_string = ','.join(no_proxy_list) + # update the DB with no_proxy list wihtout the mgmt IPs + pecan.request.dbapi.service_parameter_update(no_proxy_entry.uuid, + {'value': no_proxy_string}) + def _address_create(self, addrpool_dict, address): values = { 'address': str(address), @@ -682,6 +719,12 @@ class AddressPoolController(rest.RestController): for addr in addresses: pecan.request.dbapi.address_destroy(addr.uuid) + # if proxy is being used, remove the old management network IPs + # from the no_proxy list + if cutils.is_initial_config_complete() and \ + addrpool.name == MANAGEMENT_ADDRESS_POOL: + self._remove_mgmt_ips_from_no_proxy_list(addresses) + # Delete the address pool, which will also delete any associated # network and interface association. pecan.request.dbapi.address_pool_destroy(address_pool_uuid) diff --git a/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/interface_network.py b/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/interface_network.py index 793c8785a4..d719daa2c8 100644 --- a/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/interface_network.py +++ b/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/interface_network.py @@ -162,11 +162,13 @@ class InterfaceNetworkController(rest.RestController): # Management Network reconfiguration after initial config complete # is just supported by AIO-SX, set the flag + is_mgmt_reconfig = False if (network_type == constants.NETWORK_TYPE_MGMT and utils.get_system_mode() == constants.SYSTEM_MODE_SIMPLEX and cutils.is_initial_config_complete() and host.hostname == constants.CONTROLLER_0_HOSTNAME): pecan.request.rpcapi.set_mgmt_network_reconfig_flag(pecan.request.context) + is_mgmt_reconfig = True # Update address mode based on network type if network_type in [constants.NETWORK_TYPE_MGMT, @@ -212,6 +214,10 @@ class InterfaceNetworkController(rest.RestController): elif network_type == constants.NETWORK_TYPE_OAM: pecan.request.rpcapi.initialize_oam_config(pecan.request.context, host) + # update service-parameter no_proxy field if necessary + if is_mgmt_reconfig: + self._add_mgmt_ips_to_no_proxy_list() + return InterfaceNetwork.convert_with_links(result) def _get_interface_network_collection( @@ -247,6 +253,39 @@ class InterfaceNetworkController(rest.RestController): pecan.request.context, interface_network_uuid) return InterfaceNetwork.convert_with_links(rpc_interface_network) + def _add_mgmt_ips_to_no_proxy_list(self): + + try: + # get no_proxy from service-parameter-list + no_proxy_entry = pecan.request.dbapi.service_parameter_get_one( + service=constants.SERVICE_TYPE_DOCKER, + section=constants.SERVICE_PARAM_SECTION_DOCKER_PROXY, + name=constants.SERVICE_PARAM_NAME_DOCKER_NO_PROXY + ) + + except exception.NotFound: + # Proxy is not being used. Nothing to do. + return + + mgmt_ip = utils.lookup_static_ip_address( + constants.CONTROLLER_HOSTNAME, constants.NETWORK_TYPE_MGMT) + mgmt_0_ip = utils.lookup_static_ip_address( + constants.CONTROLLER_0_HOSTNAME, constants.NETWORK_TYPE_MGMT) + + # for IPv6 need to add brackets + if cutils.is_valid_ipv6(mgmt_ip): + mgmt_ip = "[" + mgmt_ip + "]" + mgmt_0_ip = "[" + mgmt_0_ip + "]" + + no_proxy_list = no_proxy_entry.value.split(',') + no_proxy_list.append(mgmt_ip) + no_proxy_list.append(mgmt_0_ip) + + no_proxy_string = ','.join(no_proxy_list) + + # update the DB with no_proxy list wihtout the mgmt IPs + pecan.request.dbapi.service_parameter_update(no_proxy_entry.uuid, {'value': no_proxy_string}) + def _check_interface_class(self, interface_uuid): interface = pecan.request.dbapi.iinterface_get(interface_uuid) if not interface.ifclass or interface.ifclass == constants.INTERFACE_CLASS_NONE: diff --git a/sysinv/sysinv/sysinv/sysinv/common/constants.py b/sysinv/sysinv/sysinv/sysinv/common/constants.py index 7e3375c421..62fec8cb6b 100644 --- a/sysinv/sysinv/sysinv/sysinv/common/constants.py +++ b/sysinv/sysinv/sysinv/sysinv/common/constants.py @@ -189,6 +189,7 @@ CONTROLLER_1_HOSTNAME = '%s-1' % CONTROLLER_HOSTNAME CONTROLLER_GATEWAY = '%s-gateway' % CONTROLLER_HOSTNAME CONTROLLER_CINDER = '%s-cinder' % CONTROLLER_HOSTNAME CONTROLLER_0_MGMT = '%s-mgmt' % CONTROLLER_0_HOSTNAME +CONTROLLER_FLOATING_MGMT = '%s-mgmt' % CONTROLLER_HOSTNAME PXECONTROLLER_HOSTNAME = 'pxecontroller' OAMCONTROLLER_HOSTNAME = 'oamcontroller' diff --git a/sysinv/sysinv/sysinv/sysinv/conductor/manager.py b/sysinv/sysinv/sysinv/sysinv/conductor/manager.py index 4111acf907..ec0e4ccf8d 100644 --- a/sysinv/sysinv/sysinv/sysinv/conductor/manager.py +++ b/sysinv/sysinv/sysinv/sysinv/conductor/manager.py @@ -6335,20 +6335,29 @@ class ConductorManager(service.PeriodicService): # required oam_config_runtime_apply_file = self._get_oam_runtime_apply_file() + manifest = [] + if (os.path.isfile(oam_config_runtime_apply_file) or os.path.isfile(constants.HTTPS_CONFIG_REQUIRED) or - os.path.isfile(constants.ADMIN_ENDPOINT_CONFIG_REQUIRED) or - os.path.isfile(constants.PLATFORM_FIREWALL_CONFIG_REQUIRED)): + os.path.isfile(constants.PLATFORM_FIREWALL_CONFIG_REQUIRED) or + os.path.isfile(constants.ADMIN_ENDPOINT_CONFIG_REQUIRED)): - manifest = ['openstack::keystone::endpoint::runtime', - 'platform::firewall::runtime', - 'platform::nfv::runtime'] + # Firewall will be applied too + manifest.extend(['openstack::keystone::endpoint::runtime', + 'platform::firewall::runtime', + 'platform::nfv::runtime']) - # if the only change is the firewall, run only that. - if (os.path.isfile(constants.PLATFORM_FIREWALL_CONFIG_REQUIRED) - and not (os.path.isfile(constants.HTTPS_CONFIG_REQUIRED) - or os.path.isfile(constants.ADMIN_ENDPOINT_CONFIG_REQUIRED))): - manifest = ['platform::firewall::runtime'] + # if the only change is the firewall, run only that. + if (os.path.isfile(constants.PLATFORM_FIREWALL_CONFIG_REQUIRED) + and not (os.path.isfile(constants.HTTPS_CONFIG_REQUIRED) + or os.path.isfile(constants.ADMIN_ENDPOINT_CONFIG_REQUIRED))): + manifest = ['platform::firewall::runtime'] + + # append the mgmt network update if necessary + if (os.path.isfile(tsc.MGMT_NETWORK_RECONFIG_UPDATE_HOST_FILES)): + manifest.append('platform::config::mgmt_network_reconfig_update_runtime') + + if manifest: if cutils.is_initial_config_complete(): # apply keystone changes to current active controller @@ -6375,6 +6384,9 @@ class ConductorManager(service.PeriodicService): if os.path.isfile(constants.PLATFORM_FIREWALL_CONFIG_REQUIRED): LOG.info(f"remove {constants.PLATFORM_FIREWALL_CONFIG_REQUIRED}") os.remove(constants.PLATFORM_FIREWALL_CONFIG_REQUIRED) + if os.path.isfile(tsc.MGMT_NETWORK_RECONFIG_UPDATE_HOST_FILES): + LOG.info(f"remove {tsc.MGMT_NETWORK_RECONFIG_UPDATE_HOST_FILES}") + os.remove(tsc.MGMT_NETWORK_RECONFIG_UPDATE_HOST_FILES) # apply filesystem config changes if all controllers at target standby_config_target_flipped = None diff --git a/tsconfig/tsconfig/tsconfig/tsconfig.py b/tsconfig/tsconfig/tsconfig/tsconfig.py index 673f092105..fb5f36e289 100644 --- a/tsconfig/tsconfig/tsconfig/tsconfig.py +++ b/tsconfig/tsconfig/tsconfig/tsconfig.py @@ -218,6 +218,11 @@ MGMT_NETWORK_RECONFIGURATION_ONGOING = os.path.join( MGMT_NETWORK_RECONFIGURATION_UNLOCK = os.path.join( PLATFORM_CONF_PATH, ".mgmt_network_reconfiguration_unlock") +# Set by controller_config script to inform the sysinv to update +# /opt/platform/config//hosts with new mgmt IPs +MGMT_NETWORK_RECONFIG_UPDATE_HOST_FILES = os.path.join( + PLATFORM_CONF_PATH, ".mgmt_reconfig_update_hosts_file") + # Worker configuration flags # Set after initial application of node manifest