diff --git a/ironic/drivers/modules/pxe.py b/ironic/drivers/modules/pxe.py index b4c8f6ff6f..b2072bcad5 100644 --- a/ironic/drivers/modules/pxe.py +++ b/ironic/drivers/modules/pxe.py @@ -215,6 +215,11 @@ def _get_image_file_path(d_info): return os.path.join(_get_image_dir_path(d_info), 'disk') +def _get_token_file_path(node_uuid): + """Generate the path for PKI token file.""" + return os.path.join(CONF.pxe.tftp_root, 'token-' + node_uuid) + + @lockutils.synchronized('master_image', 'ironic-') def _link_master_image(path, dest_path): """Create a link from path to dest_path using locking to @@ -417,6 +422,22 @@ def _destroy_images(d_info): _unlink_master_image(master_image) +def _create_token_file(task, node): + """Save PKI token to file.""" + token_file_path = _get_token_file_path(node['uuid']) + token = task.context.auth_token + if token: + utils.write_to_file(token_file_path, token) + else: + utils.unlink_without_raise(token_file_path) + + +def _destroy_token_file(node): + """Delete PKI token file.""" + token_file_path = _get_token_file_path(node['uuid']) + utils.unlink_without_raise(token_file_path) + + def _create_pxe_config(task, node, pxe_info): """Generate pxe configuration file and link mac ports to it for tftp booting. @@ -466,6 +487,9 @@ class PXEDeploy(base.DeployInterface): _create_pxe_config(task, node, pxe_info) _cache_images(node, pxe_info) + # TODO(yuriyz): more secure way needed for pass auth token to + # deploy ramdisk + _create_token_file(task, node) manager_utils.node_power_action(task, node, states.REBOOT) @@ -566,6 +590,8 @@ class VendorPassthru(base.VendorInterface): return True def _continue_deploy(self, task, node, **kwargs): + # token already not needed + _destroy_token_file(node) params = self._get_deploy_info(node, **kwargs) ctx = task.context node_id = node['uuid'] diff --git a/ironic/tests/drivers/test_pxe.py b/ironic/tests/drivers/test_pxe.py index 31a6058476..fbe7feafb2 100644 --- a/ironic/tests/drivers/test_pxe.py +++ b/ironic/tests/drivers/test_pxe.py @@ -304,6 +304,11 @@ class PXEPrivateMethodsTestCase(base.TestCase): self.assertEqual('/var/lib/ironic/images/fake_instance_name/disk', pxe._get_image_file_path(info)) + def test_get_token_file_path(self): + node_uuid = self.node['uuid'] + self.assertEqual(pxe._get_token_file_path(node_uuid), + '/tftpboot/token-' + node_uuid) + def test__cache_tftp_images_master_path(self): temp_dir = tempfile.mkdtemp() CONF.set_default('tftp_root', temp_dir, group='pxe') @@ -427,6 +432,9 @@ class PXEDriverTestCase(db_base.DbTestCase): def setUp(self): super(PXEDriverTestCase, self).setUp() self.context = context.get_admin_context() + self.context.auth_token = '4562138218392831' + temp_dir = tempfile.mkdtemp() + CONF.set_default('tftp_root', temp_dir, group='pxe') mgr_utils.get_mocked_node_manager(driver='fake_pxe') driver_info = INFO_DICT driver_info['pxe_deploy_key'] = 'fake-56789' @@ -437,6 +445,11 @@ class PXEDriverTestCase(db_base.DbTestCase): self.dbapi = dbapi.get_instance() self.node = self.dbapi.create_node(n) + def _create_token_file(self): + token_path = pxe._get_token_file_path(self.node['uuid']) + open(token_path, 'w').close() + return token_path + def test_validate_good(self): with task_manager.acquire(self.context, [self.node['uuid']], shared=True) as task: @@ -519,7 +532,12 @@ class PXEDriverTestCase(db_base.DbTestCase): None) self.assertEqual(state, states.DEPLOYING) + t_path = pxe._get_token_file_path(self.node['uuid']) + token = open(t_path, 'r').read() + self.assertEqual(self.context.auth_token, token) + def test_continue_deploy_good(self): + token_path = self._create_token_file() def fake_deploy(**kwargs): pass @@ -532,8 +550,10 @@ class PXEDriverTestCase(db_base.DbTestCase): method='pass_deploy_info', address='123456', iqn='aaa-bbb', key='fake-56789') self.assertEqual(self.node['provision_state'], states.DEPLOYDONE) + self.assertFalse(os.path.exists(token_path)) def test_continue_deploy_fail(self): + token_path = self._create_token_file() def fake_deploy(**kwargs): raise exception.InstanceDeployFailure() @@ -547,6 +567,7 @@ class PXEDriverTestCase(db_base.DbTestCase): task, self.node, method='pass_deploy_info', address='123456', iqn='aaa-bbb', key='fake-56789') self.assertEqual(self.node['provision_state'], states.DEPLOYFAIL) + self.assertFalse(os.path.exists(token_path)) def test_lock_elevated(self): with task_manager.acquire(self.context, [self.node['uuid']],