summaryrefslogtreecommitdiff
path: root/ironic
diff options
context:
space:
mode:
authorZuul <zuul@review.opendev.org>2020-12-19 22:14:12 +0000
committerGerrit Code Review <review@openstack.org>2020-12-19 22:14:12 +0000
commit6c9e28dd505a19d405b5ab75500cde555b4aca8d (patch)
tree61638fbbe50830325de067405497139a319a6079 /ironic
parentf11f330d00ff5dbd64bbfc74b0fe60b947241fb1 (diff)
parent628109f9601cd8e6e8f3e0185d3f0bedf2cf9200 (diff)
downloadironic-6c9e28dd505a19d405b5ab75500cde555b4aca8d.tar.gz
Merge "Inject TLS certificate when using virtual media"16.1.0
Diffstat (limited to 'ironic')
-rw-r--r--ironic/common/images.py2
-rw-r--r--ironic/conf/agent.py4
-rw-r--r--ironic/drivers/modules/image_utils.py11
-rw-r--r--ironic/tests/unit/drivers/modules/test_image_utils.py47
4 files changed, 64 insertions, 0 deletions
diff --git a/ironic/common/images.py b/ironic/common/images.py
index 3f9fb8837..778f9a12d 100644
--- a/ironic/common/images.py
+++ b/ironic/common/images.py
@@ -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:
diff --git a/ironic/conf/agent.py b/ironic/conf/agent.py
index 55e9aea1c..33b8b6554 100644
--- a/ironic/conf/agent.py
+++ b/ironic/conf/agent.py
@@ -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.')),
]
diff --git a/ironic/drivers/modules/image_utils.py b/ironic/drivers/modules/image_utils.py
index b50ffe867..b8d2f0c16 100644
--- a/ironic/drivers/modules/image_utils.py
+++ b/ironic/drivers/modules/image_utils.py
@@ -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',
diff --git a/ironic/tests/unit/drivers/modules/test_image_utils.py b/ironic/tests/unit/drivers/modules/test_image_utils.py
index 7c177a552..d555ab3f3 100644
--- a/ironic/tests/unit/drivers/modules/test_image_utils.py
+++ b/ironic/tests/unit/drivers/modules/test_image_utils.py
@@ -14,6 +14,7 @@
# under the License.
import os
+import tempfile
from unittest import mock
from oslo_utils import importutils
@@ -432,6 +433,52 @@ class RedfishImageUtilsTestCase(db_base.DbTestCase):
@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)
def test_prepare_boot_iso(self, mock_create_boot_iso,
mock__prepare_iso_image, find_mock):