Use heat server side env merging

This changes to update the stack without using
the plan and also enables server side env merging
as we don't use the plan-environment.

Also makes changes to call derive params playbooks
without plan.

Depends-On: https://review.opendev.org/c/openstack/tripleo-ansible/+/772197
Change-Id: I8caad3e9185f1c6d23b0941b966192957ca8320b
This commit is contained in:
Rabi Mishra 2020-12-16 15:46:21 +05:30 committed by ramishra
parent d76a3ab9d1
commit 258ecb54b7
10 changed files with 443 additions and 300 deletions

View File

@ -1224,16 +1224,23 @@ class ProcessMultipleEnvironments(TestCase):
self.user_tht_root)
mock_hc_process.assert_has_calls([
mock.call(env_path='./inside.yaml'),
mock.call(env_path='/twd/templates/abs.yaml'),
mock.call(env_path='/twd/templates/puppet/foo.yaml'),
mock.call(env_path='/twd/templates/environments/myenv.yaml'),
mock.call(env_path='/tmp/thtroot42/notouch.yaml'),
mock.call(env_path='./tmp/thtroot/notouch2.yaml'),
mock.call(env_path='../outside.yaml')])
mock.call(env_path='./inside.yaml',
include_env_in_files=False),
mock.call(env_path='/twd/templates/abs.yaml',
include_env_in_files=False),
mock.call(env_path='/twd/templates/puppet/foo.yaml',
include_env_in_files=False),
mock.call(env_path='/twd/templates/environments/myenv.yaml',
include_env_in_files=False),
mock.call(env_path='/tmp/thtroot42/notouch.yaml',
include_env_in_files=False),
mock.call(env_path='./tmp/thtroot/notouch2.yaml',
include_env_in_files=False),
mock.call(env_path='../outside.yaml',
include_env_in_files=False)])
@mock.patch('heatclient.common.template_utils.'
'process_environment_and_files', return_value=({}, {}),
'process_environment_and_files',
autospec=True)
@mock.patch('heatclient.common.template_utils.'
'get_template_contents', return_value=({}, {}),
@ -1282,7 +1289,7 @@ class ProcessMultipleEnvironments(TestCase):
utils.process_multiple_environments(self.created_env_files,
self.tht_root,
self.user_tht_root, False)
self.user_tht_root, None, False)
mock_yaml_dump.assert_has_calls([mock.call(rewritten_env,
default_flow_style=False)])

View File

@ -20,7 +20,6 @@ import six
import tempfile
import yaml
from heatclient import exc as hc_exc
import mock
import openstack
from osc_lib import exceptions as oscexc
@ -177,6 +176,15 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
@mock.patch('tripleoclient.utils.get_rc_params',
autospec=True)
@mock.patch('tripleo_common.utils.plan.generate_passwords',
return_value={})
@mock.patch(
'tripleo_common.image.kolla_builder.container_images_prepare_multi',
return_value={})
@mock.patch('tripleoclient.workflows.roles.get_roles_data',
autospec=True, return_value={})
@mock.patch('heatclient.common.template_utils.'
'process_environment_and_files', autospec=True)
@mock.patch('tripleoclient.utils.check_nic_config_with_ansible')
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
'_get_ctlplane_attrs', autospec=True, return_value={})
@ -203,6 +211,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
mock_ceph_fsid,
mock_get_undercloud_host_entry, mock_copy,
mock_get_ctlplane_attrs, mock_nic_ansiblei,
mock_process_env, mock_roles_data,
mock_container_prepare, mock_generate_password,
mock_rc_params):
fixture = deployment.DeploymentWorkflowFixture()
self.useFixture(fixture)
@ -225,7 +235,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
mock_event = mock.Mock()
mock_event.id = '1234'
mock_events.return_value = [mock_events]
mock_roles_data.return_value = []
object_client = clients.tripleoclient.object_store
object_client.get_object = mock.Mock()
object_client.put_container = mock.Mock()
@ -269,16 +279,16 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
return parameter_defaults
mock_create_parameters_env.side_effect = _custom_create_params_env
mock_rc_params.return_value = {'password': 'password',
'region': 'region1'}
mock_process_env.return_value = {}, {
'parameter_defaults': expected_parameters}
self.cmd.take_action(parsed_args)
self.assertFalse(orchestration_client.stacks.update.called)
self.assertTrue(orchestration_client.stacks.update.called)
mock_get_template_contents.assert_called_with(
object_request=mock.ANY,
template_object=constants.OVERCLOUD_YAML_NAME)
template_file=mock.ANY)
mock_create_tempest_deployer_input.assert_called_with()
mock_copy.assert_called_once()
@ -286,6 +296,15 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
'overcloud', headers={'x-container-meta-usage-tripleo': 'plan'})
@mock.patch('tripleoclient.utils.get_rc_params', autospec=True)
@mock.patch('tripleo_common.utils.plan.generate_passwords',
return_value={})
@mock.patch(
'tripleo_common.image.kolla_builder.container_images_prepare_multi',
return_value={})
@mock.patch('tripleoclient.workflows.roles.get_roles_data',
autospec=True, return_value={})
@mock.patch('heatclient.common.template_utils.'
'process_environment_and_files', autospec=True)
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
'_get_ctlplane_attrs', autospec=True, return_value={})
@mock.patch('tripleoclient.workflows.deployment.create_overcloudrc',
@ -313,7 +332,10 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
mock_invoke_plan_env_wf,
mock_get_undercloud_host_entry,
mock_copy, mock_overcloudrc,
mock_get_ctlplane_attrs, mock_rc_params):
mock_get_ctlplane_attrs,
mock_process_env, mock_roles_data,
mock_container_prepare, mock_generate_password,
mock_rc_params):
fixture = deployment.DeploymentWorkflowFixture()
self.useFixture(fixture)
plane_management_fixture = deployment.PlanManagementFixture()
@ -365,16 +387,15 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
'UndercloudHostsEntries':
['192.168.0.1 uc.ctlplane.localhost uc.ctlplane'],
'CtlplaneNetworkAttributes': {}}}
mock_process_env.return_value = {}, parameters_env
mock_open_context = mock.mock_open()
with mock.patch('six.moves.builtins.open', mock_open_context):
self.cmd.take_action(parsed_args)
self.assertFalse(orchestration_client.stacks.create.called)
self.assertTrue(orchestration_client.stacks.create.called)
mock_get_template_contents.assert_called_with(
object_request=mock.ANY,
template_object=constants.OVERCLOUD_YAML_NAME)
template_file=mock.ANY)
utils_overcloud_fixture.mock_deploy_tht.assert_called_with()
@ -386,20 +407,21 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
mock.call('overcloud',
'user-environments/tripleoclient-parameters.yaml',
yaml.safe_dump(parameters_env,
default_flow_style=False)),
mock.call('overcloud',
'user-environment.yaml',
yaml.safe_dump({}, default_flow_style=False)),
mock.call('overcloud',
'plan-environment.yaml',
yaml.safe_dump({'environments':
[{'path': 'user-environment.yaml'}]},
default_flow_style=False))]
object_client = clients.tripleoclient.object_store
object_client.put_object.assert_has_calls(calls)
@mock.patch('tripleoclient.utils.get_rc_params', autospec=True)
@mock.patch('tripleo_common.utils.plan.generate_passwords',
return_value={})
@mock.patch(
'tripleo_common.image.kolla_builder.container_images_prepare_multi',
return_value={})
@mock.patch('tripleoclient.workflows.roles.get_roles_data',
autospec=True, return_value={})
@mock.patch('heatclient.common.template_utils.'
'process_environment_and_files', autospec=True)
@mock.patch('tripleoclient.workflows.deployment.create_overcloudrc',
autospec=True)
@mock.patch('os.chdir')
@ -431,6 +453,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
mock_postconfig, mock_deprecated_params, mock_stack_network_check,
mock_ceph_fsid, mock_get_undercloud_host_entry, mock_copy,
mock_chdir, mock_overcloudrc,
mock_process_env, mock_roles_data,
mock_image_prepare, mock_generate_password,
mock_rc_params):
fixture = deployment.DeploymentWorkflowFixture()
self.useFixture(fixture)
@ -470,6 +494,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
}
mock_get_template_contents.return_value = [{}, "template"]
mock_process_env.return_value = {}, {}
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
baremetal = clients.baremetal
@ -483,6 +508,15 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
'overcloud', headers={'x-container-meta-usage-tripleo': 'plan'})
@mock.patch('tripleoclient.utils.get_rc_params', autospec=True)
@mock.patch('tripleo_common.utils.plan.generate_passwords',
return_value={})
@mock.patch(
'tripleo_common.image.kolla_builder.container_images_prepare_multi',
return_value={})
@mock.patch('tripleoclient.workflows.roles.get_roles_data',
autospec=True, return_value={})
@mock.patch('heatclient.common.template_utils.'
'process_environment_and_files', autospec=True)
@mock.patch('tripleoclient.utils.check_nic_config_with_ansible')
@mock.patch('tripleoclient.utils.copy_clouds_yaml')
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
@ -507,6 +541,10 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
mock_ceph_fsid,
mock_get_undercloud_host_entry,
mock_copy, mock_nic_ansible,
mock_process_env,
mock_roles_data,
mock_image_prepare,
mock_generate_password,
mock_rc_params):
fixture = deployment.DeploymentWorkflowFixture()
self.useFixture(fixture)
@ -540,20 +578,20 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
object_client = clients.tripleoclient.object_store
object_client.get_object = mock.Mock()
object_client.put_container = mock.Mock()
mock_env = yaml.safe_dump({'environments': []})
object_client.get_object.return_value = ({}, mock_env)
env = {'parameter_defaults': {},
'resource_registry': {}}
mock_process_env.return_value = {}, env
with mock.patch('tempfile.mkstemp') as mkstemp:
mkstemp.return_value = (os.open(self.parameter_defaults_env_file,
os.O_RDWR),
self.parameter_defaults_env_file)
self.cmd.take_action(parsed_args)
self.assertFalse(orchestration_client.stacks.update.called)
self.assertTrue(orchestration_client.stacks.update.called)
mock_get_template_contents.assert_called_with(
object_request=mock.ANY,
template_object=constants.OVERCLOUD_YAML_NAME)
template_file=mock.ANY)
mock_create_tempest_deployer_input.assert_called_with()
mock_copy.assert_called_once()
@ -578,6 +616,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
self.assertFalse(mock_deploy_tht.called)
@mock.patch('tripleoclient.utils.get_rc_params', autospec=True)
@mock.patch('heatclient.common.template_utils.'
'process_environment_and_files', autospec=True)
@mock.patch('tripleoclient.utils.check_nic_config_with_ansible')
@mock.patch('tripleoclient.utils.copy_clouds_yaml')
@mock.patch('tripleoclient.utils.check_stack_network_matches_env_files')
@ -592,7 +632,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
mock_update_parameters, mock_post_config,
mock_stack_network_check, mock_ceph_fsid,
mock_copy, mock_nic_ansible,
mock_rc_params):
mock_process_env, mock_rc_params):
fixture = deployment.DeploymentWorkflowFixture()
self.useFixture(fixture)
plane_management_fixture = deployment.PlanManagementFixture()
@ -612,6 +652,13 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
env_dirs = [os.path.join(os.environ.get('HOME', ''), '.tripleo',
'environments'), self.tmp_dir.path]
env = {'parameter_defaults': {},
'resource_registry': {
'Test': 'OS::Heat::None',
'resources': {'*': {'*': {
'UpdateDeployment': {'hooks': []}}}}}}
mock_process_env.return_value = {}, env
with open(test_env, 'w') as temp_file:
temp_file.write('resource_registry:\n Test: OS::Heat::None')
@ -627,10 +674,10 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
def _fake_heat_deploy(self, stack, stack_name, template_path,
parameters, environments, timeout, tht_root,
env, run_validations,
skip_deploy_identifier, plan_env_file,
env_files_tracker=None,
deployment_options=None):
assertEqual(
{'parameter_defaults': {'NovaComputeLibvirtType': 'qemu'},
{'parameter_defaults': {},
'resource_registry': {
'Test': 'OS::Heat::None',
'resources': {'*': {'*': {
@ -642,69 +689,12 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
object_client = clients.tripleoclient.object_store
object_client.get_object = mock.Mock()
object_client.put_container = mock.Mock()
mock_env = yaml.safe_dump({'parameter_defaults':
{'NovaComputeLibvirtType': 'qemu'}})
object_client.get_object.return_value = ({}, mock_env)
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
mock_copy.assert_called_once()
object_client.put_container.assert_called_once_with(
'overcloud', headers={'x-container-meta-usage-tripleo': 'plan'})
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
'_deploy_postconfig', autospec=True)
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
'_update_parameters', autospec=True)
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
'_heat_deploy', autospec=True)
def test_environment_dirs_env_files_not_found(self, mock_deploy_heat,
mock_update_parameters,
mock_post_config):
plane_management_fixture = deployment.PlanManagementFixture()
self.useFixture(plane_management_fixture)
utils_fixture = deployment.UtilsOvercloudFixture()
self.useFixture(utils_fixture)
clients = self.app.client_manager
mock_update_parameters.return_value = {}
utils_fixture.mock_utils_endpoint.return_value = 'foo.bar'
os.mkdir(self.tmp_dir.join('env'))
os.mkdir(self.tmp_dir.join('common'))
test_env = self.tmp_dir.join('env/foo2.yaml')
with open(test_env, 'w') as temp_file:
temp_file.write('resource_registry:\n '
'Test1: ../common/bar.yaml\n '
'Test2: /tmp/doesnexit.yaml')
test_sub_env = self.tmp_dir.join('common/bar.yaml')
with open(test_sub_env, 'w') as temp_file:
temp_file.write('outputs:\n data:\n value: 1')
arglist = ['--templates']
verifylist = [
('templates', '/usr/share/openstack-tripleo-heat-templates/'),
]
self.useFixture(
fixtures.EnvironmentVariable('TRIPLEO_ENVIRONMENT_DIRECTORY',
self.tmp_dir.join('env')))
object_client = clients.tripleoclient.object_store
object_client.get_object = mock.Mock()
object_client.put_container = mock.Mock()
mock_env = yaml.safe_dump({'parameter_defaults':
{'NovaComputeLibvirtType': 'qemu'}})
object_client.get_object.return_value = ({}, mock_env)
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
error = self.assertRaises(hc_exc.CommandError, self.cmd.take_action,
parsed_args)
self.assertIn('tmp/doesnexit.yaml', str(error))
object_client.put_container.assert_called_once_with(
'overcloud', headers={'x-container-meta-usage-tripleo': 'plan'})
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
'_deploy_postconfig', autospec=True)
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
@ -770,14 +760,14 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
self, mock_heat_deploy_func):
result = self.cmd._try_overcloud_deploy_with_compat_yaml(
'/fake/path', {}, 'overcloud', {}, ['~/overcloud-env.json'], 1,
{}, False, True, False, None)
{}, False, None, None)
# If it returns None it succeeded
self.assertIsNone(result)
mock_heat_deploy_func.assert_called_once_with(
self.cmd, {}, 'overcloud',
'/fake/path/' + constants.OVERCLOUD_YAML_NAME, {},
['~/overcloud-env.json'], 1, '/fake/path', {}, False, True,
False, deployment_options=None)
['~/overcloud-env.json'], 1, '/fake/path', {}, False,
deployment_options=None, env_files_tracker=None)
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
'_heat_deploy', autospec=True)
@ -788,7 +778,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
self.cmd._try_overcloud_deploy_with_compat_yaml,
'/fake/path', mock.ANY, mock.ANY, mock.ANY,
mock.ANY, mock.ANY, mock.ANY, mock.ANY, mock.ANY,
mock.ANY, None)
None)
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
'_heat_deploy', autospec=True)
@ -799,7 +789,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
try:
self.cmd._try_overcloud_deploy_with_compat_yaml(
'/fake/path', mock.ANY, mock.ANY, mock.ANY,
mock.ANY, mock.ANY, mock.ANY, mock.ANY, mock.ANY, mock.ANY,
mock.ANY, mock.ANY, mock.ANY, mock.ANY, mock.ANY,
None)
except ValueError as value_error:
self.assertIn('/fake/path', str(value_error))
@ -829,6 +819,13 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
self.assertFalse(mock_create_tempest_deployer_input.called)
@mock.patch('tripleoclient.utils.get_rc_params', autospec=True)
@mock.patch('tripleo_common.utils.plan.generate_passwords',
return_value={})
@mock.patch(
'tripleo_common.image.kolla_builder.container_images_prepare_multi',
return_value={})
@mock.patch('tripleoclient.workflows.roles.get_roles_data',
autospec=True, return_value={})
@mock.patch('tripleoclient.utils.check_nic_config_with_ansible')
@mock.patch('tripleoclient.utils.copy_clouds_yaml')
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
@ -844,7 +841,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
mock_heat_deploy, mock_stack_network_check,
mock_ceph_fsid, mock_get_undercloud_host_entry,
mock_copy, mock_nic_ansible,
mock_rc_params):
mock_roles_data, mock_image_prepare,
mock_generate_password, mock_rc_params):
fixture = deployment.DeploymentWorkflowFixture()
self.useFixture(fixture)
clients = self.app.client_manager
@ -873,6 +871,12 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
with open(test_env2, 'w') as temp_file:
temp_file.write('resource_registry:\n Test2: OS::Heat::None')
os.makedirs(self.tmp_dir.join('tripleo-heat-templates'))
reg_file = self.tmp_dir.join(
'tripleo-heat-templates/overcloud-resource-registry-puppet.yaml')
with open(reg_file, 'w+') as temp_file:
temp_file.write('resource_registry:\n Test2: OS::Heat::None')
test_answerfile = self.tmp_dir.join('answerfile')
with open(test_answerfile, 'w') as answerfile:
yaml.dump(
@ -922,6 +926,13 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
'overcloud', headers={'x-container-meta-usage-tripleo': 'plan'})
@mock.patch('tripleoclient.utils.get_rc_params', autospec=True)
@mock.patch('tripleo_common.utils.plan.generate_passwords',
return_value={})
@mock.patch(
'tripleo_common.image.kolla_builder.container_images_prepare_multi',
return_value={})
@mock.patch('tripleoclient.workflows.roles.get_roles_data',
autospec=True, return_value={})
@mock.patch('tripleoclient.utils.check_nic_config_with_ansible')
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
'_get_undercloud_host_entry', autospec=True,
@ -941,6 +952,9 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
mock_ceph_fsid,
mock_get_undercloud_host_entry,
mock_nic_ansible,
mock_roles_data,
mock_image_prepare,
mock_generate_password,
mock_rc_params):
plane_management_fixture = deployment.PlanManagementFixture()
self.useFixture(plane_management_fixture)
@ -983,6 +997,13 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
'overcloud', headers={'x-container-meta-usage-tripleo': 'plan'})
@mock.patch('tripleoclient.utils.get_rc_params', autospec=True)
@mock.patch('tripleo_common.utils.plan.generate_passwords',
return_value={})
@mock.patch(
'tripleo_common.image.kolla_builder.container_images_prepare_multi',
return_value={})
@mock.patch('tripleoclient.workflows.roles.get_roles_data',
autospec=True, return_value={})
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
'_get_ctlplane_attrs', autospec=True, return_value={})
@mock.patch('tripleoclient.utils.copy_clouds_yaml')
@ -1015,6 +1036,9 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
mock_ceph_fsid,
mock_get_undercloud_host_entry, mock_copy,
mock_get_ctlplane_attrs,
mock_roles_data,
mock_image_prepare,
mock_generate_password,
mock_rc_params):
fixture = deployment.DeploymentWorkflowFixture()
self.useFixture(fixture)
@ -1094,8 +1118,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
self.cmd.take_action(parsed_args)
mock_get_template_contents.assert_called_with(
object_request=mock.ANY,
template_object=constants.OVERCLOUD_YAML_NAME)
template_file=mock.ANY)
mock_create_tempest_deployer_input.assert_called_with()
@ -1295,6 +1318,15 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
mock_copy.assert_called_once()
@mock.patch('tripleoclient.utils.get_rc_params', autospec=True)
@mock.patch('tripleo_common.utils.plan.generate_passwords',
return_value={})
@mock.patch(
'tripleo_common.image.kolla_builder.container_images_prepare_multi',
return_value={})
@mock.patch('tripleoclient.workflows.roles.get_roles_data',
autospec=True, return_value={})
@mock.patch('heatclient.common.template_utils.'
'process_environment_and_files', autospec=True)
@mock.patch('tripleoclient.utils.check_nic_config_with_ansible')
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
'_get_ctlplane_attrs', autospec=True, return_value={})
@ -1314,6 +1346,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
mock_ceph_fsid, mock_hd,
mock_get_undercloud_host_entry, mock_copy,
mock_get_ctlplane_attrs, mock_nic_ansible,
mock_process_env, mock_roles_data,
mock_container_prepare, mock_generate_password,
mock_rc_params):
fixture = deployment.DeploymentWorkflowFixture()
self.useFixture(fixture)
@ -1329,6 +1363,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
('templates', '/usr/share/openstack-tripleo-heat-templates/'),
('overcloud_ssh_port_timeout', 42), ('timeout', 451)
]
mock_process_env.return_value = {}, {}
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
mock_rc_params.return_value = {'password': 'password',
@ -1345,8 +1380,9 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
'RootStackName': 'overcloud',
'UndercloudHostsEntries':
['192.168.0.1 uc.ctlplane.localhost uc.ctlplane'],
'CtlplaneNetworkAttributes': {}}, {}, 451, mock.ANY,
{}, False, False, None, deployment_options={})],
'CtlplaneNetworkAttributes': {}}, mock.ANY,
451, mock.ANY, mock.ANY, False,
deployment_options={}, env_files_tracker=mock.ANY)],
mock_hd.mock_calls)
self.assertIn(
[mock.call(mock.ANY, mock.ANY, mock.ANY, 'ctlplane', None, None,

View File

@ -133,7 +133,7 @@ class TestOvercloudUpgradePrepare(fakes.TestOvercloudUpgradePrepare):
check_mech.return_value = 'Wrong mech'
mock_stack = mock.Mock(parameters={'DeployIdentifier': ''})
argslist = (mock_stack, 'mock_stack', '/tmp', {},
{}, 1, '/tmp', {}, True, False, False, None)
{}, 1, '/tmp', {}, True, False, None)
self.cmd.object_client = mock.Mock()
self.assertRaises(oscexc.CommandError,
self.cmd._heat_deploy, *argslist)

View File

@ -385,12 +385,18 @@ class TestDeployUndercloud(TestPluginV1):
self.cmd._deploy_tripleo_heat_templates(self.orc, parsed_args)
mock_hc_process.assert_has_calls([
mock.call(env_path='./inside.yaml'),
mock.call(env_path='/twd/templates/abs.yaml'),
mock.call(env_path='/twd/templates/puppet/foo.yaml'),
mock.call(env_path='/twd/templates/environments/myenv.yaml'),
mock.call(env_path='/tmp/thtroot42/notouch.yaml'),
mock.call(env_path='../outside.yaml')])
mock.call(env_path='./inside.yaml',
include_env_in_files=False),
mock.call(env_path='/twd/templates/abs.yaml',
include_env_in_files=False),
mock.call(env_path='/twd/templates/puppet/foo.yaml',
include_env_in_files=False),
mock.call(env_path='/twd/templates/environments/myenv.yaml',
include_env_in_files=False),
mock.call(env_path='/tmp/thtroot42/notouch.yaml',
include_env_in_files=False),
mock.call(env_path='../outside.yaml',
include_env_in_files=False)])
@mock.patch('tripleoclient.utils.rel_or_abs_path')
@mock.patch('heatclient.common.template_utils.'

View File

@ -95,7 +95,10 @@ class TestParameterWorkflows(utils.TestCommand):
parameters.invoke_plan_env_workflows(
self.app.client_manager,
'overcloud',
'the-plan-environment.yaml'
'the-plan-environment.yaml',
stack_data=mock.Mock(),
role_list=mock.Mock(),
derived_environment_path=mock.Mock()
)
calls = [
mock.call(
@ -104,7 +107,11 @@ class TestParameterWorkflows(utils.TestCommand):
workdir=mock.ANY,
playbook_dir=mock.ANY,
verbosity=0,
extra_vars={'num_phy_cores_per_numa_node_for_pmd': 2}
extra_vars={'num_phy_cores_per_numa_node_for_pmd': 2,
'tripleo_get_flatten_params': {
'stack_data': mock.ANY},
'tripleo_role_list': mock.ANY,
'derived_environment_path': mock.ANY}
)
]
mock_playbook.assert_has_calls(calls, any_order=True)
@ -134,7 +141,10 @@ class TestParameterWorkflows(utils.TestCommand):
parameters.invoke_plan_env_workflows(
self.app.client_manager,
'overcloud',
'the-plan-environment.yaml'
'the-plan-environment.yaml',
stack_data=mock.Mock(),
role_list=mock.Mock(),
derived_environment_path=mock.Mock()
)
calls = [
mock.call(
@ -143,7 +153,11 @@ class TestParameterWorkflows(utils.TestCommand):
workdir=mock.ANY,
playbook_dir=mock.ANY,
verbosity=0,
extra_vars={'num_phy_cores_per_numa_node_for_pmd': 2}
extra_vars={'num_phy_cores_per_numa_node_for_pmd': 2,
'tripleo_get_flatten_params': {
'stack_data': mock.ANY},
'tripleo_role_list': mock.ANY,
'derived_environment_path': mock.ANY}
),
mock.call(
playbook='sample-playbook-2.yaml',
@ -151,7 +165,11 @@ class TestParameterWorkflows(utils.TestCommand):
workdir=mock.ANY,
playbook_dir='/playbook/dir-1',
verbosity=0,
extra_vars={'some_opt': 0}
extra_vars={'some_opt': 0,
'tripleo_get_flatten_params': {
'stack_data': mock.ANY},
'tripleo_role_list': mock.ANY,
'derived_environment_path': mock.ANY}
)
]
mock_playbook.assert_has_calls(calls, any_order=True)

View File

@ -59,6 +59,7 @@ from heatclient import exc as hc_exc
from six.moves.urllib import error as url_error
from six.moves.urllib import request
from tripleo_common.utils import stack as stack_utils
from tripleo_common.utils import swift as swiftutils
from tripleoclient import constants
from tripleoclient import exceptions
@ -1616,11 +1617,48 @@ def cleanup_tripleo_ansible_inventory_file(path):
processutils.execute('/usr/bin/rm', '-f', path)
def get_roles_file_path(roles_file, tht_root):
roles_file = roles_file or os.path.join(
tht_root, constants.OVERCLOUD_ROLES_FILE)
return os.path.abspath(roles_file)
def get_networks_file_path(networks_file, tht_root):
networks_file = networks_file or os.path.join(
tht_root, constants.OVERCLOUD_NETWORKS_FILE)
return os.path.abspath(networks_file)
def build_stack_data(clients, stack_name, template,
files, env_files):
orchestration_client = clients.orchestration
fields = {
'template': template,
'files': files,
'environment_files': env_files,
'show_nested': True
}
stack_data = {}
result = orchestration_client.stacks.validate(**fields)
if result:
stack_data['environment_parameters'] = result.get(
'Environment', {}).get('parameter_defaults')
flattened = {'resources': {}, 'parameters': {}}
stack_utils._flat_it(flattened, 'Root', result)
stack_data['heat_resource_tree'] = flattened
return stack_data
def process_multiple_environments(created_env_files, tht_root,
user_tht_root, cleanup=True):
user_tht_root,
env_files_tracker=None,
cleanup=True):
log = logging.getLogger(__name__ + ".process_multiple_environments")
env_files = {}
localenv = {}
include_env_in_files = env_files_tracker is not None
# Normalize paths for full match checks
user_tht_root = os.path.normpath(user_tht_root)
tht_root = os.path.normpath(tht_root)
@ -1639,7 +1677,10 @@ def process_multiple_environments(created_env_files, tht_root,
env_path = new_env_path
try:
files, env = template_utils.process_environment_and_files(
env_path=env_path)
env_path=env_path, include_env_in_files=include_env_in_files)
if env_files_tracker is not None:
env_files_tracker.append(
heat_utils.normalise_file_path_to_url(env_path))
except hc_exc.CommandError as ex:
# This provides fallback logic so that we can reference files
# inside the resource_registry values that may be rendered via
@ -1687,7 +1728,10 @@ def process_multiple_environments(created_env_files, tht_root,
f.write(yaml.safe_dump(env_map, default_flow_style=False))
f.flush()
files, env = template_utils.process_environment_and_files(
env_path=f.name)
env_path=f.name, include_env_in_files=include_env_in_files)
if env_files_tracker is not None:
env_files_tracker.append(
heat_utils.normalise_file_path_to_url(f.name))
if files:
log.debug("Adding files %s for %s" % (files, env_path))
env_files.update(files)

View File

@ -34,7 +34,9 @@ from keystoneauth1.exceptions.catalog import EndpointNotFound
import openstack
from osc_lib import exceptions as oscexc
from osc_lib.i18n import _
from tripleo_common.image import kolla_builder
from tripleo_common import update
from tripleo_common.utils import plan as plan_utils
from tripleoclient import command
from tripleoclient import constants
@ -43,6 +45,7 @@ from tripleoclient import utils
from tripleoclient.workflows import deployment
from tripleoclient.workflows import parameters as workflow_params
from tripleoclient.workflows import plan_management
from tripleoclient.workflows import roles
CONF = cfg.CONF
@ -73,7 +76,6 @@ class DeployOvercloud(command.Command):
parsed_args.deployed_server = True
def _update_args_from_answers_file(self, args):
# Update parameters from answers file:
if args.answers_file is not None:
with open(args.answers_file, 'r') as answers_file:
answers = yaml.safe_load(answers_file)
@ -85,7 +87,7 @@ class DeployOvercloud(command.Command):
answers['environments'].extend(args.environment_files)
args.environment_files = answers['environments']
def _update_parameters(self, args, stack):
def _update_parameters(self, args, stack, tht_root, user_tht_root):
parameters = {}
stack_is_new = stack is None
@ -98,6 +100,29 @@ class DeployOvercloud(command.Command):
parameters['StackAction'] = 'CREATE' if stack_is_new else 'UPDATE'
# We need the processed env for the image parameters atm
env_files = []
if args.environment_directories:
env_files.extend(utils.load_environment_directories(
args.environment_directories))
if args.environment_files:
env_files.extend(args.environment_files)
_, env = utils.process_multiple_environments(
env_files, tht_root, user_tht_root,
cleanup=(not args.no_cleanup))
image_params = kolla_builder.container_images_prepare_multi(
env, roles.get_roles_data(args.roles_file,
tht_root), dry_run=True)
if image_params:
parameters.update(image_params)
password_params = plan_utils.generate_passwords(
self.object_client, self.orchestration_client,
args.stack)
parameters.update(password_params)
param_args = (
('NtpServer', 'ntp_server'),
)
@ -186,21 +211,21 @@ class DeployOvercloud(command.Command):
def _create_breakpoint_cleanup_env(self, tht_root, container_name):
bp_env = {}
update.add_breakpoints_cleanup_into_env(bp_env)
env_path, swift_path = self._write_user_environment(
env_path, _ = self._write_user_environment(
bp_env,
'tripleoclient-breakpoint-cleanup.yaml',
tht_root,
container_name)
return bp_env
return [env_path]
def _create_parameters_env(self, parameters, tht_root, container_name):
parameter_defaults = {"parameter_defaults": parameters}
env_path, swift_path = self._write_user_environment(
env_path, _ = self._write_user_environment(
parameter_defaults,
'tripleoclient-parameters.yaml',
tht_root,
container_name)
return parameter_defaults
return [env_path]
def _check_limit_skiplist_warning(self, env):
if env.get('parameter_defaults').get('DeploymentServerBlacklist'):
@ -242,7 +267,8 @@ class DeployOvercloud(command.Command):
def _heat_deploy(self, stack, stack_name, template_path, parameters,
env_files, timeout, tht_root, env,
run_validations, skip_deploy_identifier, plan_env_file,
run_validations,
env_files_tracker=None,
deployment_options=None):
"""Verify the Baremetal nodes are available and do a stack update"""
@ -256,162 +282,19 @@ class DeployOvercloud(command.Command):
raise oscexc.CommandError(msg)
self.log.debug("Getting template contents from plan %s" % stack_name)
# We need to reference the plan here, not the local
# tht root, as we need template_object to refer to
# the rendered overcloud.yaml, not the tht_root overcloud.j2.yaml
# FIXME(shardy) we need to move more of this into mistral actions
plan_yaml_path = os.path.relpath(template_path, tht_root)
# heatclient template_utils needs a function that can
# retrieve objects from a container by name/path
def do_object_request(method='GET', object_path=None):
obj = self.object_client.get_object(stack_name, object_path)
return obj and obj[1]
template_files, template = template_utils.get_template_contents(
template_object=plan_yaml_path,
object_request=do_object_request)
template_file=template_path)
files = dict(list(template_files.items()) + list(env_files.items()))
moved_files = self._upload_missing_files(
stack_name, files, tht_root)
self._process_and_upload_environment(
stack_name, env, moved_files, tht_root)
# Invokes the workflows specified in plan environment file
if plan_env_file:
workflow_params.invoke_plan_env_workflows(
self.clients,
stack_name,
plan_env_file,
verbosity=utils.playbook_verbosity(self=self)
)
workflow_params.check_deprecated_parameters(self.clients, stack_name)
self.log.info("Deploying templates in the directory {0}".format(
os.path.abspath(tht_root)))
deployment.deploy_and_wait(
log=self.log,
clients=self.clients,
stack=stack,
plan_name=stack_name,
verbose_level=utils.playbook_verbosity(self=self),
timeout=timeout,
run_validations=run_validations,
skip_deploy_identifier=skip_deploy_identifier,
deployment_options=deployment_options
)
def _process_and_upload_environment(self, container_name,
env, moved_files, tht_root):
"""Process the environment and upload to Swift
The environment at this point should be the result of the merged
custom user environments. We need to look at the paths in the
environment and update any that changed when they were uploaded to
swift.
"""
file_prefix = "file://"
if env.get('resource_registry'):
for name, path in env['resource_registry'].items():
if not isinstance(path, six.string_types):
continue
if path in moved_files:
new_path = moved_files[path]
env['resource_registry'][name] = new_path
elif path.startswith(file_prefix):
path = path[len(file_prefix):]
if path.startswith(tht_root):
path = path[len(tht_root):]
# We want to make sure all the paths are relative.
if path.startswith("/"):
path = path[1:]
env['resource_registry'][name] = path
# Parameters are removed from the environment
params = env.pop('parameter_defaults', None)
contents = yaml.safe_dump(env, default_flow_style=False)
# Until we have a well defined plan update workflow in tripleo-common
# we need to manually add an environment in swift and for users
# custom environments passed to the deploy command.
# See bug: https://bugs.launchpad.net/tripleo/+bug/1623431
# Update plan env.
swift_path = "user-environment.yaml"
self.object_client.put_object(container_name, swift_path, contents)
env = yaml.safe_load(self.object_client.get_object(
container_name, constants.PLAN_ENVIRONMENT)[1])
user_env = {'path': swift_path}
if user_env not in env['environments']:
env['environments'].append(user_env)
yaml_string = yaml.safe_dump(env, default_flow_style=False)
self.object_client.put_object(
container_name, constants.PLAN_ENVIRONMENT, yaml_string)
# Parameters are sent to the update parameters action, this stores them
# in the plan environment and means the UI can find them.
if params:
with utils.TempDirs() as tmp:
utils.run_ansible_playbook(
playbook='cli-update-params.yaml',
inventory='localhost,',
workdir=tmp,
playbook_dir=constants.ANSIBLE_TRIPLEO_PLAYBOOKS,
verbosity=utils.playbook_verbosity(self=self),
extra_vars={
"container": container_name
},
extra_vars_file={
"parameters": params
}
)
def _upload_missing_files(self, container_name, files_dict, tht_root):
"""Find the files referenced in custom environments and upload them
Heat environments can be passed to be included in the deployment, these
files can include references to other files anywhere on the local
file system. These need to be discovered and uploaded to Swift. When
they have been uploaded to Swift the path to them will be different,
the new paths are store din the file_relocation dict, which is returned
and used by _process_and_upload_environment which will merge the
environment and update paths to the relative Swift path.
"""
file_relocation = {}
file_prefix = "file://"
# select files files for relocation & upload
for fullpath in files_dict.keys():
if not fullpath.startswith(file_prefix):
continue
path = fullpath[len(file_prefix):]
if path.startswith(tht_root):
# This should already be uploaded.
continue
file_relocation[fullpath] = "user-files/{}".format(
os.path.normpath(path[1:]))
# make sure links within files point to new locations, and upload them
for orig_path, reloc_path in file_relocation.items():
link_replacement = utils.relative_link_replacement(
file_relocation, os.path.dirname(reloc_path))
contents = utils.replace_links_in_template_contents(
files_dict[orig_path], link_replacement)
self.object_client.put_object(container_name, reloc_path, contents)
return file_relocation
deployment.deploy_without_plan(
self.clients, stack, stack_name,
template, files, env_files_tracker,
self.log)
def _download_missing_files_from_plan(self, tht_dir, plan_name):
# get and download missing files into tmp directory
@ -486,27 +369,23 @@ class DeployOvercloud(command.Command):
os.path.abspath(tht_root)))
self.log.debug("Creating Environment files")
env = {}
created_env_files = []
created_env_files.append(
os.path.join(tht_root, 'overcloud-resource-registry-puppet.yaml'))
created_env_files.extend(
self._provision_baremetal(parsed_args, tht_root))
if parsed_args.environment_directories:
created_env_files.extend(utils.load_environment_directories(
parsed_args.environment_directories))
parameters = {}
if stack:
try:
# If user environment already exist then keep it
user_env = yaml.safe_load(self.object_client.get_object(
parsed_args.stack, constants.USER_ENVIRONMENT)[1])
template_utils.deep_update(env, user_env)
except Exception:
pass
parameters.update(self._update_parameters(parsed_args, stack))
template_utils.deep_update(env, self._create_parameters_env(
parameters, tht_root, parsed_args.stack))
parameters.update(self._update_parameters(
parsed_args, stack, tht_root, user_tht_root))
param_env = self._create_parameters_env(
parameters, tht_root, parsed_args.stack)
created_env_files.extend(param_env)
if parsed_args.deployed_server:
created_env_files.append(
@ -520,11 +399,34 @@ class DeployOvercloud(command.Command):
deployment_options['ansible_python_interpreter'] = \
parsed_args.deployment_python_interpreter
if stack:
env_path = self._create_breakpoint_cleanup_env(
tht_root, parsed_args.stack)
created_env_files.extend(env_path)
self.log.debug("Processing environment files %s" % created_env_files)
env_files, localenv = utils.process_multiple_environments(
env_files_tracker = []
env_files, env = utils.process_multiple_environments(
created_env_files, tht_root, user_tht_root,
env_files_tracker=env_files_tracker,
cleanup=(not parsed_args.no_cleanup))
template_utils.deep_update(env, localenv)
# Invokes the workflows specified in plan environment file
if parsed_args.plan_environment_file:
output_path = self._user_env_path(
'derived_parameters.yaml', tht_root)
workflow_params.build_derived_params_environment(
self.clients, parsed_args.stack, tht_root, env_files,
env_files_tracker, parsed_args.roles_file,
parsed_args.plan_environment_file,
output_path, utils.playbook_verbosity(self=self))
created_env_files.append(output_path)
env_files_tracker = []
env_files, env = utils.process_multiple_environments(
created_env_files, tht_root, user_tht_root,
env_files_tracker=env_files_tracker,
cleanup=(not parsed_args.no_cleanup))
if parsed_args.limit:
# check if skip list is defined while using --limit and throw a
@ -545,10 +447,6 @@ class DeployOvercloud(command.Command):
if (ceph_deployed != "OS::Heat::None"
or ceph_external != "OS::Heat::None"):
utils.check_ceph_fsid_matches_env_files(stack, env)
bp_cleanup = self._create_breakpoint_cleanup_env(
tht_root, parsed_args.stack)
template_utils.deep_update(env, bp_cleanup)
# check migration to new nic config with ansible
utils.check_nic_config_with_ansible(stack, env)
@ -563,10 +461,11 @@ class DeployOvercloud(command.Command):
'(with HA).')
self._try_overcloud_deploy_with_compat_yaml(
tht_root, stack, parsed_args.stack, parameters, env_files,
tht_root, stack,
parsed_args.stack, parameters, env_files,
parsed_args.timeout, env,
parsed_args.run_validations, parsed_args.skip_deploy_identifier,
parsed_args.plan_environment_file,
parsed_args.run_validations,
env_files_tracker=env_files_tracker,
deployment_options=deployment_options)
self._unprovision_baremetal(parsed_args)
@ -575,16 +474,15 @@ class DeployOvercloud(command.Command):
stack_name, parameters,
env_files, timeout,
env, run_validations,
skip_deploy_identifier,
plan_env_file,
env_files_tracker=None,
deployment_options=None):
overcloud_yaml = os.path.join(tht_root, constants.OVERCLOUD_YAML_NAME)
try:
self._heat_deploy(stack, stack_name, overcloud_yaml,
parameters, env_files, timeout,
tht_root, env,
run_validations, skip_deploy_identifier,
plan_env_file,
run_validations,
env_files_tracker=env_files_tracker,
deployment_options=deployment_options)
except Exception as e:
messages = 'Failed to deploy: %s' % str(e)

View File

@ -131,14 +131,68 @@ def create_overcloudrc(stack, rc_params, no_proxy='',
rc_params['password'],
rc_params['region'])
rcpath = os.path.join(output_dir, '%src' % stack.stack_name)
with open(rcpath, 'w') as rcfile:
rcfile.write(overcloudrcs['overcloudrc'])
os.chmod(rcpath, 0o600)
return os.path.abspath(rcpath)
def deploy_without_plan(clients, stack, stack_name, template,
files, env_files,
log):
orchestration_client = clients.orchestration
if stack is None:
log.info("Performing Heat stack create")
action = 'CREATE'
marker = None
else:
log.info("Performing Heat stack update")
# Make sure existing parameters for stack are reused
# Find the last top-level event to use for the first marker
events = event_utils.get_events(orchestration_client,
stack_id=stack_name,
event_args={'sort_dir': 'desc',
'limit': 1})
marker = events[0].id if events else None
action = 'UPDATE'
set_deployment_status(clients=clients,
plan=stack_name,
status='DEPLOYING')
stack_args = {
'stack_name': stack_name,
'template': template,
'environment_files': env_files,
'files': files}
try:
if stack:
stack_args['existing'] = True
orchestration_client.stacks.update(stack.id, **stack_args)
else:
stack = orchestration_client.stacks.create(**stack_args)
print("Success.")
except Exception:
set_deployment_status(clients=clients,
plan=stack_name,
status='DEPLOY_FAILED')
raise
create_result = utils.wait_for_stack_ready(
orchestration_client, stack_name, marker, action)
if not create_result:
shell.OpenStackShell().run(["stack", "failures", "list", stack_name])
set_deployment_status(
clients=clients,
plan=stack_name,
status='DEPLOY_FAILED'
)
if stack is None:
raise exceptions.DeploymentError("Heat Stack create failed.")
else:
raise exceptions.DeploymentError("Heat Stack update failed.")
def get_overcloud_hosts(stack, ssh_network):
ips = []
role_net_ip_map = utils.get_role_net_ip_map(stack)

View File

@ -15,9 +15,11 @@ import os
import re
import yaml
from heatclient.common import template_utils
from tripleo_common.utils import stack_parameters as stk_parameters
from tripleoclient.constants import ANSIBLE_TRIPLEO_PLAYBOOKS
from tripleoclient.constants import OVERCLOUD_YAML_NAME
from tripleoclient.constants import UNUSED_PARAMETER_EXCLUDES_RE
from tripleoclient import exceptions
from tripleoclient import utils
@ -28,6 +30,8 @@ LOG = logging.getLogger(__name__)
def invoke_plan_env_workflows(clients, stack_name, plan_env_file,
stack_data, role_list,
derived_environment_path,
verbosity=0):
"""Invokes the workflows in plan environment file"""
@ -57,6 +61,9 @@ def invoke_plan_env_workflows(clients, stack_name, plan_env_file,
pb_vars
)
)
pb_vars['tripleo_get_flatten_params'] = {'stack_data': stack_data}
pb_vars['tripleo_role_list'] = role_list
pb_vars['derived_environment_path'] = derived_environment_path
playbook_dir = os.path.dirname(pb)
if not playbook_dir:
playbook_dir = ANSIBLE_TRIPLEO_PLAYBOOKS
@ -71,6 +78,39 @@ def invoke_plan_env_workflows(clients, stack_name, plan_env_file,
)
def build_derived_params_environment(clients, stack_name,
tht_root, env_files,
env_files_tracker,
roles_file,
plan_env_file,
derived_env_file,
verbosity):
template_path = os.path.join(tht_root, OVERCLOUD_YAML_NAME)
template_files, template = template_utils.get_template_contents(
template_file=template_path)
files = dict(list(template_files.items()) + list(
env_files.items()))
# Build stack_data
stack_data = utils.build_stack_data(
clients, stack_name, template,
files, env_files_tracker)
# Get role list
role_list = roles.get_roles(
clients, roles_file, template, files,
env_files_tracker, detail=False, valid=True)
invoke_plan_env_workflows(
clients,
stack_name,
plan_env_file,
stack_data=stack_data,
role_list=role_list,
derived_environment_path=derived_env_file,
verbosity=verbosity
)
def check_deprecated_parameters(clients, container):
"""Checks for deprecated parameters in plan and adds warning if present.

View File

@ -18,10 +18,50 @@ from tripleo_common.actions import plan
# TODO(cloudnull): Convert to a swiftutils in tripleo-common
# from tripleo_common.utils import swift as swiftutils
from tripleoclient import utils
LOG = logging.getLogger(__name__)
def get_roles_data(roles_file, tht_root):
abs_roles_file = utils.get_roles_file_path(
roles_file, tht_root)
roles_data = None
with open(abs_roles_file, 'r') as fp:
roles_data = yaml.safe_load(fp)
return roles_data
def get_roles(clients, roles_file, tht_root,
stack_name,
template,
files,
env_files,
detail=False, valid=False):
roles_data = get_roles_data(roles_file, tht_root)
if detail:
return roles_data
role_names = [role['name'] for role in roles_data]
if not valid:
return role_names
stack_data = utils.build_stack_data(
clients, stack_name, template,
files, env_files)
valid_roles = []
for name in role_names:
role_count = stack_data['parameters'].get(
name + 'Count', {}).get('default', 0)
if role_count > 0:
valid_roles.append(name)
return valid_roles
def list_available_roles(clients, container='overcloud'):
"""Return a list of available roles.