[train-only] Validate rendered net_config_override

In change I127c2742522e695dd1fd15413a47bf4d8ebea8fa the
_validate_no_ip_change validation was updated to check for
ip address change in net_config_override template - when a
template using mapping keys like {{PUBLIC_INTERFACE_IP}} the
validation will fail since netaddr cannot parse that as an IP
address.

As was done for OSP17, pass in the rendered network_config_json
to the preflight check and validate against this when checking
for a changed IP address.

Also whe net_config_override allow a match with
CONF.undercloud_public_host to pass validation since doc's and
example net_config_override uses {{PUBLIC_INTERFACE_IP}} not
{{LOCAL_IP}}.

Change-Id: Ia01cfc6957536939232085dd6973ab0b105fe78a
This commit is contained in:
Harald Jensås 2023-09-12 00:05:33 +02:00
parent 8cc1d6da58
commit a57b709395
No known key found for this signature in database
GPG Key ID: 693852E00DCEA408
2 changed files with 42 additions and 21 deletions

View File

@ -753,6 +753,7 @@ def prepare_undercloud_deploy(upgrade=False, no_validations=True,
if CONF.get('cleanup'):
deploy_args.append('--cleanup')
net_config_json = None
if CONF.get('net_config_override', None):
data_file = CONF['net_config_override']
if os.path.abspath(data_file) != data_file:
@ -825,7 +826,8 @@ def prepare_undercloud_deploy(upgrade=False, no_validations=True,
if CONF.get('enable_validations') and not no_validations:
utils.ansible_symlink()
undercloud_preflight.check(verbose_level, upgrade)
undercloud_preflight.check(verbose_level, upgrade,
net_config_json=net_config_json)
deploy_args += ['-e', os.path.join(
tht_templates, "environments/tripleo-validations.yaml")]

View File

@ -287,7 +287,7 @@ def _validate_interface_exists(config_var='local_interface'):
raise FailedValidation(message)
def _validate_no_ip_change():
def _validate_no_ip_change(net_config_json=None):
"""Disallow provisioning interface IP changes
Changing the provisioning network IP causes a number of issues, so we
@ -295,34 +295,53 @@ def _validate_no_ip_change():
be changed.
"""
if CONF.net_config_override:
os_net_config_file = CONF.net_config_override
network_config = net_config_json
else:
os_net_config_file = '/etc/os-net-config/config.json'
# Nothing to do if we haven't already installed
if not os.path.isfile(
os.path.expanduser(os_net_config_file)):
return
try:
os_net_config_file = '/etc/os-net-config/config.yaml'
if not os.path.isfile(os.path.expanduser(os_net_config_file)):
os_net_config_file = '/etc/os-net-config/config.json'
# Nothing to do if we haven't already installed
if not os.path.isfile(os.path.expanduser(os_net_config_file)):
return
with open(os_net_config_file, 'r') as f:
network_config = yaml.safe_load(f)
ctlplane = [i for i in network_config.get('network_config', [])
if i['name'] == 'br-ctlplane'][0]
except ValueError:
if network_config is None:
# File was empty
return
try:
ctlplane = [i for i in network_config.get('network_config', [])
if i.get('name') == 'br-ctlplane'][0]
except IndexError:
# Nothing to check if br-ctlplane wasn't configured
return
existing_ip = ctlplane['addresses'][0]['ip_netmask']
conf_netaddr = netaddr.IPNetwork(CONF.local_ip)
conf_public_netaddr = netaddr.IPNetwork(CONF.undercloud_public_host)
existing_netaddr = netaddr.IPNetwork(existing_ip)
if (conf_netaddr != existing_netaddr
or conf_netaddr.ip != existing_netaddr.ip):
message = _('Changing the local_ip is not allowed. Existing IP: '
'{0}, Configured IP: {1}').format(
existing_ip, CONF.local_ip)
LOG.error(message)
raise FailedValidation(message)
# NOTE(hjensas):
# {{PUBLIC_INTERFACE_IP}} maps to CONF.undercloud_public_host
# {{LOCAL_IP}} maps to CONF.local_ip
# In several examples and docs {{PUBLIC_INTERFACE_IP}} is
# used in net_config_override templates instead of {{LOCAL_IP}}
# so let's make that OK.
if (CONF.net_config_override
and (conf_public_netaddr == existing_netaddr
and conf_public_netaddr.ip == existing_netaddr.ip)):
return
if (conf_netaddr == existing_netaddr
and conf_netaddr.ip == existing_netaddr.ip):
return
message = _('Changing the local_ip is not allowed. Existing IP: '
'{0}, Configured IP: {1}').format(existing_ip, CONF.local_ip)
LOG.error(message)
raise FailedValidation(message)
def _validate_passwords_file():
@ -475,7 +494,7 @@ def _check_all_or_no_subnets_use_dns_nameservers():
raise FailedValidation(message)
def check(verbose_level, upgrade=False):
def check(verbose_level, upgrade=False, net_config_json=None):
# Fetch configuration and use its log file param to add logging to a file
utils.load_config(CONF, constants.UNDERCLOUD_CONF_PATH)
utils.configure_logging(LOG, verbose_level, CONF['undercloud_log_file'])
@ -518,7 +537,7 @@ def check(verbose_level, upgrade=False):
_checking_status('Network interfaces')
_validate_interface_exists()
_checking_status('Provisionning IP change')
_validate_no_ip_change()
_validate_no_ip_change(net_config_json=net_config_json)
_checking_status('Architecture')
_validate_architecure_options()
except KeyError as e: