CI: anaconda: permit tls certificate validation bypass

The stock anaconda template previously lacked any ability
to indicate "don't validate the tls certificate".

The capability for the installation to operate *without*
requiring this to be the case is necessary for efficient
and simple CI testing as injecting CA certificates is
an overly complex interaction for CI testing.

Also updates the overall anaconda documentation to indicate
the constraint exists, but does not indicate explicitly how
to disable the setting via ironic.conf.

Change-Id: Ia8e4320cbedb205ab183af121da53562792a8faa
This commit is contained in:
Julia Kreger 2022-08-17 08:28:29 -07:00
parent 5c1dd47e6c
commit e75626392b
6 changed files with 49 additions and 3 deletions

View File

@ -277,5 +277,10 @@ Limitations
This deploy interface has only been tested with Red Hat based operating systems
that use anaconda. Other systems are not supported.
Runtime TLS certifiate injection into ramdisks is not supported. Assets such
as ``ramdisk`` or a ``stage2`` ramdisk image need to have trusted Certificate
Authority certificates present within the images *or* the Ironic API endpoint
utilized should utilize a known trusted Certificate Authority.
.. _`anaconda`: https://fedoraproject.org/wiki/Anaconda
.. _`ks.cfg.template`: https://opendev.org/openstack/ironic/src/branch/master/ironic/drivers/modules/ks.cfg.template

View File

@ -1004,6 +1004,8 @@ def build_kickstart_config_options(task):
if node.driver_internal_info.get('is_source_a_path', False):
# Record a value so it matches as the template opts in.
params['is_source_a_path'] = 'true'
if CONF.anaconda.insecure_heartbeat:
params['insecure_heartbeat'] = 'true'
params['agent_token'] = node.driver_internal_info['agent_secret_token']
heartbeat_url = '%s/v1/heartbeat/%s' % (
deploy_utils.get_ironic_api_url().rstrip('/'),

View File

@ -28,6 +28,17 @@ opts = [
help=_('kickstart template to use when no kickstart template '
'is specified in the instance_info or the glance OS '
'image.')),
cfg.BoolOpt('insecure_heartbeat',
default=False,
mutable=True,
help=_('Option to allow the kickstart configuration to be '
'informed if SSL/TLS certificate verificaiton should '
'be enforced, or not. This option exists largely to '
'facilitate easy testing and use of the ``anaconda`` '
'deployment interface. When this option is set, '
'heartbeat operations, depending on the contents of '
'the utilized kickstart template, may not enfore TLS '
'certificate verification.')),
]

View File

@ -36,11 +36,11 @@ liveimg --url {{ ks_options.liveimg_url }}
# Following %pre and %onerror sections are mandatory
%pre
/usr/bin/curl -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'X-OpenStack-Ironic-API-Version: 1.72' -d '{"callback_url": "", "agent_token": "{{ ks_options.agent_token }}", "agent_status": "start", "agent_status_message": "Deployment starting. Running pre-installation scripts."}' {{ ks_options.heartbeat_url }}
/usr/bin/curl {% if 'insecure_heartbeat' in ks_options %}--insecure{% endif %} -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'X-OpenStack-Ironic-API-Version: 1.72' -d '{"callback_url": "", "agent_token": "{{ ks_options.agent_token }}", "agent_status": "start", "agent_status_message": "Deployment starting. Running pre-installation scripts."}' {{ ks_options.heartbeat_url }}
%end
%onerror
/usr/bin/curl -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'X-OpenStack-Ironic-API-Version: 1.72' -d '{"callback_url": "", "agent_token": "{{ ks_options.agent_token }}", "agent_status": "error", "agent_status_message": "Error: Deploying using anaconda. Check console for more information."}' {{ ks_options.heartbeat_url }}
/usr/bin/curl {% if 'insecure_heartbeat' in ks_options %}--insecure{% endif %} -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'X-OpenStack-Ironic-API-Version: 1.72' -d '{"callback_url": "", "agent_token": "{{ ks_options.agent_token }}", "agent_status": "error", "agent_status_message": "Error: Deploying using anaconda. Check console for more information."}' {{ ks_options.heartbeat_url }}
%end
# Config-drive information, if any.
@ -54,5 +54,5 @@ liveimg --url {{ ks_options.liveimg_url }}
# before rebooting.
%post
sync
/usr/bin/curl -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'X-OpenStack-Ironic-API-Version: 1.72' -d '{"callback_url": "", "agent_token": "{{ ks_options.agent_token }}", "agent_status": "end", "agent_status_message": "Deployment completed successfully."}' {{ ks_options.heartbeat_url }}
/usr/bin/curl {% if 'insecure_heartbeat' in ks_options %}--insecure{% endif %} -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'X-OpenStack-Ironic-API-Version: 1.72' -d '{"callback_url": "", "agent_token": "{{ ks_options.agent_token }}", "agent_status": "end", "agent_status_message": "Deployment completed successfully."}' {{ ks_options.heartbeat_url }}
%end

View File

@ -1628,6 +1628,26 @@ class PXEBuildKickstartConfigOptionsTestCase(db_base.DbTestCase):
params = pxe_utils.build_kickstart_config_options(task)
self.assertTrue(params['ks_options'].pop('agent_token'))
self.assertEqual(expected, params['ks_options'])
self.assertNotIn('insecure_heartbeat', params)
@mock.patch.object(deploy_utils, 'get_ironic_api_url', autospec=True)
def test_build_kickstart_config_options_pxe_insecure_heartbeat(
self, api_url_mock):
api_url_mock.return_value = 'http://ironic-api'
self.assertFalse(CONF.anaconda.insecure_heartbeat)
CONF.set_override('insecure_heartbeat', True, 'anaconda')
with task_manager.acquire(self.context, self.node.uuid,
shared=True) as task:
expected = {}
expected['liveimg_url'] = task.node.instance_info['image_url']
expected['config_drive'] = ''
expected['heartbeat_url'] = (
'http://ironic-api/v1/heartbeat/%s' % task.node.uuid
)
expected['insecure_heartbeat'] = 'true'
params = pxe_utils.build_kickstart_config_options(task)
self.assertTrue(params['ks_options'].pop('agent_token'))
self.assertEqual(expected, params['ks_options'])
@mock.patch('ironic.common.utils.render_template', autospec=True)
def test_prepare_instance_kickstart_config_not_anaconda_boot(self,

View File

@ -0,0 +1,8 @@
---
fixes:
- |
Adds a configuration option, ``[anaconda]insecure_heartbeat`` to allow
for TLS certificate validation to be disabled in the ``anaconda``
deployment interface, which is needed for continious integration to
be able to be performed without substantial substrate image customization.
This option is *not* advised for any production usage.