Inject TLS certificate when using virtual media
A new option allows embedding a CA certificate in the virtual media ISO to allow fully secure TLS between ironic and IPA. Depends-On: https://review.opendev.org/763207 Change-Id: Idaacf44fd829c441d708b11704a97f9cd2b7a74c
This commit is contained in:
parent
2d70e6e26e
commit
628109f960
@ -1703,12 +1703,14 @@ function configure_ironic_conductor {
|
||||
|
||||
local kernel_append_params="nofb nomodeset console=${IRONIC_TTY_DEV}"
|
||||
kernel_append_params+=" systemd.journald.forward_to_console=yes"
|
||||
if is_service_enabled tls-proxy; then
|
||||
kernel_append_params+=" ipa-insecure=1"
|
||||
fi
|
||||
|
||||
if [[ -n "kernel_append_params" ]]; then
|
||||
iniset $IRONIC_CONF_FILE redfish kernel_append_params "$kernel_append_params"
|
||||
# NOTE(dtantsur): avoid setting ipa-insecure for redfish, we have a way to
|
||||
# pass the TLS certificate.
|
||||
iniset $IRONIC_CONF_FILE redfish kernel_append_params "$kernel_append_params"
|
||||
|
||||
if is_service_enabled tls-proxy; then
|
||||
deploy_int_CA "$IRONIC_STATE_PATH/ironic-ca.pem"
|
||||
iniset $IRONIC_CONF_FILE agent api_ca_file "$IRONIC_STATE_PATH/ironic-ca.pem"
|
||||
fi
|
||||
|
||||
# Set these options for scenarios in which the agent fetches the image
|
||||
|
@ -58,6 +58,8 @@ def _create_root_fs(root_directory, files_info):
|
||||
:raises: IOError, if copying any of the files failed.
|
||||
"""
|
||||
for src_file, path in files_info.items():
|
||||
LOG.debug('Injecting %(path)s into an ISO from %(source)r',
|
||||
{'path': path, 'source': src_file})
|
||||
target_file = os.path.join(root_directory, path)
|
||||
dirname = os.path.dirname(target_file)
|
||||
if dirname:
|
||||
|
@ -159,6 +159,10 @@ opts = [
|
||||
'ramdisk. Set to True to use the system default CA '
|
||||
'storage. Set to False to disable validation. Ignored '
|
||||
'when automatic TLS setup is used.')),
|
||||
cfg.StrOpt('api_ca_file',
|
||||
help=_('Path to the TLS CA that is used to start the bare '
|
||||
'metal API. In some boot methods this file can be '
|
||||
'passed to the ramdisk.')),
|
||||
]
|
||||
|
||||
|
||||
|
@ -388,6 +388,12 @@ def _find_param(param_str, param_dict):
|
||||
return val
|
||||
|
||||
|
||||
_TLS_REMOTE_FILE = 'etc/ironic-python-agent/ironic.crt'
|
||||
_TLS_CONFIG_TEMPLATE = """[DEFAULT]
|
||||
cafile = /%s
|
||||
""" % _TLS_REMOTE_FILE
|
||||
|
||||
|
||||
def prepare_deploy_iso(task, params, mode, d_info):
|
||||
"""Prepare deploy or rescue ISO image
|
||||
|
||||
@ -430,6 +436,11 @@ def prepare_deploy_iso(task, params, mode, d_info):
|
||||
bootloader_href=bootloader_href, params=params)
|
||||
|
||||
inject_files = {}
|
||||
if CONF.agent.api_ca_file:
|
||||
inject_files[CONF.agent.api_ca_file] = _TLS_REMOTE_FILE
|
||||
inject_files[_TLS_CONFIG_TEMPLATE.encode('utf-8')] = \
|
||||
'etc/ironic-python-agent.d/ironic-tls.conf'
|
||||
|
||||
network_data = task.driver.network.get_node_network_data(task)
|
||||
if network_data:
|
||||
LOG.debug('Injecting custom network data for node %s',
|
||||
|
@ -14,6 +14,7 @@
|
||||
# under the License.
|
||||
|
||||
import os
|
||||
import tempfile
|
||||
from unittest import mock
|
||||
|
||||
from oslo_utils import importutils
|
||||
@ -430,6 +431,52 @@ class RedfishImageUtilsTestCase(db_base.DbTestCase):
|
||||
|
||||
find_mock.assert_has_calls(find_call_list)
|
||||
|
||||
@mock.patch.object(image_utils, '_find_param', autospec=True)
|
||||
@mock.patch.object(image_utils, '_prepare_iso_image', autospec=True)
|
||||
def test_prepare_deploy_iso_tls(self, mock__prepare_iso_image,
|
||||
find_mock):
|
||||
with tempfile.NamedTemporaryFile(delete=False) as tf:
|
||||
temp_name = tf.name
|
||||
self.addCleanup(lambda: os.unlink(temp_name))
|
||||
self.config(api_ca_file=temp_name, group='agent')
|
||||
tf.write(b'I can haz SSLz')
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=True) as task:
|
||||
|
||||
d_info = {
|
||||
'ilo_deploy_kernel': 'kernel',
|
||||
'ilo_deploy_ramdisk': 'ramdisk',
|
||||
'ilo_bootloader': 'bootloader'
|
||||
}
|
||||
task.node.driver_info.update(d_info)
|
||||
|
||||
find_call_list = [
|
||||
mock.call('deploy_kernel', d_info),
|
||||
mock.call('deploy_ramdisk', d_info),
|
||||
mock.call('bootloader', d_info)
|
||||
]
|
||||
find_mock.side_effect = [
|
||||
'kernel', 'ramdisk', 'bootloader'
|
||||
]
|
||||
|
||||
task.node.instance_info.update(deploy_boot_mode='uefi')
|
||||
|
||||
image_utils.prepare_deploy_iso(task, {}, 'deploy', d_info)
|
||||
|
||||
expected_files = {
|
||||
b"""[DEFAULT]
|
||||
cafile = /etc/ironic-python-agent/ironic.crt
|
||||
""": 'etc/ironic-python-agent.d/ironic-tls.conf',
|
||||
temp_name: 'etc/ironic-python-agent/ironic.crt'
|
||||
}
|
||||
|
||||
mock__prepare_iso_image.assert_called_once_with(
|
||||
task, 'kernel', 'ramdisk', 'bootloader', params={},
|
||||
inject_files=expected_files)
|
||||
|
||||
find_mock.assert_has_calls(find_call_list)
|
||||
|
||||
@mock.patch.object(image_utils, '_find_param', autospec=True)
|
||||
@mock.patch.object(image_utils, '_prepare_iso_image', autospec=True)
|
||||
@mock.patch.object(images, 'create_boot_iso', autospec=True)
|
||||
|
6
releasenotes/notes/vmedia-tls-117daa5ae0a9e30d.yaml
Normal file
6
releasenotes/notes/vmedia-tls-117daa5ae0a9e30d.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
A new option ``[agent]api_ca_file`` allows passing a CA file to the
|
||||
ramdisk when ``redfish-virtual-media`` boot is used. Requires
|
||||
ironic-python-agent from the Wallaby cycle.
|
Loading…
Reference in New Issue
Block a user