Refactor deploy validations for ephemeral heat

All these validations are not executed with ephemeral
heat. With this we'll save stack environment to disk
and validate using it in the next deployment.

Note: Some of these validations have been changed to
not use saved stack environment as we don't update
the stack anymore.

Also cleans up some usage of existing stack in code.

Change-Id: I791407490dcdddb927d488aa73856cd3ef7191bb
This commit is contained in:
rabi 2022-06-21 16:13:58 +05:30
parent 076365f320
commit 5a6c8fc0c3
8 changed files with 109 additions and 313 deletions

View File

@ -297,6 +297,7 @@ KIND_TEMPLATES = {'roles': WD_DEFAULT_ROLES_FILE_NAME,
'baremetal': WD_DEFAULT_BAREMETAL_FILE_NAME, 'baremetal': WD_DEFAULT_BAREMETAL_FILE_NAME,
'vips': WD_DEFAULT_VIP_FILE_NAME} 'vips': WD_DEFAULT_VIP_FILE_NAME}
STACK_ENV_FILE_NAME = 'tripleo-{}-environment.yaml'
# Disk usage percentages to check as related to deploy backups # Disk usage percentages to check as related to deploy backups
DEPLOY_BACKUPS_USAGE_PERCENT = 50 DEPLOY_BACKUPS_USAGE_PERCENT = 50
DISK_USAGE_PERCENT = 80 DISK_USAGE_PERCENT = 80

View File

@ -678,170 +678,51 @@ class TestWaitForStackUtil(TestCase):
self.assertEqual(False, result) self.assertEqual(False, result)
def test_check_heat_network_config(self): def test_check_heat_network_config(self):
stack_reg = {
'OS::TripleO::Controller::Net::SoftwareConfig': 'val',
'OS::TripleO::Compute::Net::SoftwareConfig': 'val',
}
env_reg = { env_reg = {
'OS::TripleO::Controller::Net::SoftwareConfig': 'val', 'OS::TripleO::Controller::Net::SoftwareConfig': 'val',
'OS::TripleO::Compute::Net::SoftwareConfig': 'val', 'OS::TripleO::Compute::Net::SoftwareConfig': 'val',
} }
mock_stack = mock.MagicMock()
mock_stack.environment = mock.MagicMock()
mock_stack.environment.return_value = {
'resource_registry': stack_reg,
}
env = { env = {
'resource_registry': env_reg 'resource_registry': env_reg
} }
self.assertRaises(exceptions.InvalidConfiguration, self.assertRaises(exceptions.InvalidConfiguration,
utils.check_nic_config_with_ansible, utils.check_nic_config_with_ansible, env)
mock_stack, env)
def test_check_service_vips_migrated_to_service(self): def test_check_service_vips_migrated_to_service(self):
stack_reg = {
'OS::TripleO::Network::Ports::RedisVipPort': 'val',
'OS::TripleO::Network::Ports::OVNDBsVipPort': 'val',
}
env_reg = { env_reg = {
'OS::TripleO::Network::Ports::RedisVipPort': 'val', 'OS::TripleO::Network::Ports::RedisVipPort': 'val',
'OS::TripleO::Network::Ports::OVNDBsVipPort': 'val', 'OS::TripleO::Network::Ports::OVNDBsVipPort': 'val',
} }
mock_stack = mock.MagicMock()
mock_stack.environment = mock.MagicMock()
mock_stack.environment.return_value = {
'resource_registry': stack_reg,
}
env = { env = {
'resource_registry': env_reg 'resource_registry': env_reg
} }
self.assertRaises(exceptions.InvalidConfiguration, self.assertRaises(exceptions.InvalidConfiguration,
utils.check_service_vips_migrated_to_service, utils.check_service_vips_migrated_to_service,
mock_stack, env) env)
def test_check_heat_missing_network_config(self):
stack_reg = {
'OS::TripleO::Controller::Net::SoftwareConfig': 'val',
'OS::TripleO::Compute::Net::SoftwareConfig': 'val',
}
env_reg = {
'OS::TripleO::Controller::Net::SoftwareConfig': 'OS::Heat::None',
}
mock_stack = mock.MagicMock()
mock_stack.environment = mock.MagicMock()
mock_stack.environment.return_value = {
'resource_registry': stack_reg,
}
env = {
'resource_registry': env_reg
}
self.assertRaises(exceptions.InvalidConfiguration,
utils.check_nic_config_with_ansible,
mock_stack, env)
def test_check_heat_none_network_config(self): def test_check_heat_none_network_config(self):
stack_reg = {
'OS::TripleO::Controller::Net::SoftwareConfig': 'val',
'OS::TripleO::Compute::Net::SoftwareConfig': 'val',
}
env_reg = { env_reg = {
'OS::TripleO::Controller::Net::SoftwareConfig': 'OS::Heat::None', 'OS::TripleO::Controller::Net::SoftwareConfig': 'OS::Heat::None',
'OS::TripleO::Compute::Net::SoftwareConfig': 'OS::Heat::None', 'OS::TripleO::Compute::Net::SoftwareConfig': 'OS::Heat::None',
} }
mock_stack = mock.MagicMock()
mock_stack.environment = mock.MagicMock()
mock_stack.environment.return_value = {
'resource_registry': stack_reg,
}
env = { env = {
'resource_registry': env_reg, 'resource_registry': env_reg,
'parameter_defaults': {'NetworkConfigWithAnsible': True} 'parameter_defaults': {'NetworkConfigWithAnsible': True}
} }
utils.check_nic_config_with_ansible(mock_stack, env) utils.check_nic_config_with_ansible(env)
def test_check_heat_network_config_no_ansible(self): def test_check_heat_network_config_no_ansible(self):
stack_reg = {
'OS::TripleO::Controller::Net::SoftwareConfig': 'val',
'OS::TripleO::Compute::Net::SoftwareConfig': 'val',
}
env_reg = { env_reg = {
'OS::TripleO::Controller::Net::SoftwareConfig': 'val', 'OS::TripleO::Controller::Net::SoftwareConfig': 'val',
'OS::TripleO::Compute::Net::SoftwareConfig': 'val', 'OS::TripleO::Compute::Net::SoftwareConfig': 'val',
} }
mock_stack = mock.MagicMock()
mock_stack.environment = mock.MagicMock()
mock_stack.environment.return_value = {
'resource_registry': stack_reg,
}
env = { env = {
'resource_registry': env_reg, 'resource_registry': env_reg,
'parameter_defaults': {'NetworkConfigWithAnsible': False} 'parameter_defaults': {'NetworkConfigWithAnsible': False}
} }
utils.check_nic_config_with_ansible(mock_stack, env) utils.check_nic_config_with_ansible(env)
def test_check_stack_network_matches_env_files(self):
stack_reg = {
'OS::TripleO::Network': 'val',
'OS::TripleO::Network::External': 'val',
'OS::TripleO::Network::ExtraConfig': 'OS::Heat::None',
'OS::TripleO::Network::InternalApi': 'val',
'OS::TripleO::Network::Port::InternalApi': 'val',
'OS::TripleO::Network::Management': 'val',
'OS::TripleO::Network::Storage': 'val',
'OS::TripleO::Network::StorageMgmt': 'val',
'OS::TripleO::Network::Tenant': 'val'
}
env_reg = {
'OS::TripleO::Network': 'newval',
'OS::TripleO::Network::External': 'newval',
'OS::TripleO::Network::ExtraConfig': 'OS::Heat::None',
'OS::TripleO::Network::InternalApi': 'newval',
'OS::TripleO::Network::Management': 'newval',
'OS::TripleO::Network::Storage': 'val',
'OS::TripleO::Network::StorageMgmt': 'val',
'OS::TripleO::Network::Tenant': 'val'
}
mock_stack = mock.MagicMock()
mock_stack.environment = mock.MagicMock()
mock_stack.environment.return_value = {
'resource_registry': stack_reg
}
env = {
'resource_registry': env_reg
}
utils.check_stack_network_matches_env_files(mock_stack, env)
def test_check_stack_network_matches_env_files_fail(self):
stack_reg = {
'OS::TripleO::LoggingConfiguration': 'val',
'OS::TripleO::Network': 'val',
'OS::TripleO::Network::External': 'val',
'OS::TripleO::Network::ExtraConfig': 'OS::Heat::None',
'OS::TripleO::Network::InternalApi': 'val',
'OS::TripleO::Network::Port::InternalApi': 'val',
'OS::TripleO::Network::Management': 'val',
'OS::TripleO::Network::Storage': 'val',
'OS::TripleO::Network::StorageMgmt': 'val',
'OS::TripleO::Network::Tenant': 'val'
}
env_reg = {
'OS::TripleO::LoggingConfiguration': 'newval',
'OS::TripleO::Network': 'newval',
'OS::TripleO::Network::InternalApi': 'newval'
}
mock_stack = mock.MagicMock()
mock_stack.environment = mock.MagicMock()
mock_stack.environment.return_value = {
'resource_registry': stack_reg
}
env = {
'resource_registry': env_reg
}
with self.assertRaises(exceptions.InvalidConfiguration):
utils.check_stack_network_matches_env_files(mock_stack, env)
def test_check_ceph_fsid_matches_env_files(self): def test_check_ceph_fsid_matches_env_files(self):
stack_params = { stack_params = {
@ -863,7 +744,8 @@ class TestWaitForStackUtil(TestCase):
'key2': 'val2', 'key2': 'val2',
} }
} }
utils.check_ceph_fsid_matches_env_files(mock_stack, provided_env) utils.check_ceph_fsid_matches_env_files(mock_stack.environment(),
provided_env)
def test_check_ceph_fsid_matches_env_files_fail(self): def test_check_ceph_fsid_matches_env_files_fail(self):
stack_params = { stack_params = {
@ -884,10 +766,10 @@ class TestWaitForStackUtil(TestCase):
'parameter_defaults': stack_params 'parameter_defaults': stack_params
} }
with self.assertRaises(exceptions.InvalidConfiguration): with self.assertRaises(exceptions.InvalidConfiguration):
utils.check_ceph_fsid_matches_env_files(mock_stack, provided_env) utils.check_ceph_fsid_matches_env_files(mock_stack.environment(),
provided_env)
def test_check_ceph_ansible(self): def test_check_ceph_ansible(self):
res_reg = { res_reg = {
'resource_registry': { 'resource_registry': {
'OS::Tripleo::Services::CephMon': '/path/to/ceph-ansible.yml', 'OS::Tripleo::Services::CephMon': '/path/to/ceph-ansible.yml',
@ -900,7 +782,6 @@ class TestWaitForStackUtil(TestCase):
'UpgradeConverge') 'UpgradeConverge')
def test_check_ceph_ansible_fail(self): def test_check_ceph_ansible_fail(self):
res_reg = { res_reg = {
'resource_registry': { 'resource_registry': {
'OS::Tripleo::Services::CephMon': '/path/to/ceph-ansible.yml', 'OS::Tripleo::Services::CephMon': '/path/to/ceph-ansible.yml',
@ -927,7 +808,8 @@ class TestWaitForStackUtil(TestCase):
'resource_registry': env_reg, 'resource_registry': env_reg,
} }
utils.check_swift_and_rgw(mock_stack, env, 'UpgradePrepare') utils.check_swift_and_rgw(mock_stack.environment(),
env, 'UpgradePrepare')
def test_check_swift_and_rgw_fail(self): def test_check_swift_and_rgw_fail(self):
stack_reg = { stack_reg = {
@ -945,7 +827,8 @@ class TestWaitForStackUtil(TestCase):
'resource_registry': env_reg, 'resource_registry': env_reg,
} }
with self.assertRaises(exceptions.InvalidConfiguration): with self.assertRaises(exceptions.InvalidConfiguration):
utils.check_swift_and_rgw(mock_stack, env, 'UpgradePrepare') utils.check_swift_and_rgw(mock_stack.environment(),
env, 'UpgradePrepare')
@mock.patch('subprocess.check_call') @mock.patch('subprocess.check_call')
@mock.patch('os.path.exists') @mock.patch('os.path.exists')

View File

@ -73,6 +73,7 @@ FAKE_STACK = {
def create_to_dict_mock(**kwargs): def create_to_dict_mock(**kwargs):
mock_with_to_dict = mock.Mock() mock_with_to_dict = mock.Mock()
mock_with_to_dict.configure_mock(**kwargs) mock_with_to_dict.configure_mock(**kwargs)
mock_with_to_dict.environment.return_value = {}
mock_with_to_dict.to_dict.return_value = kwargs mock_with_to_dict.to_dict.return_value = kwargs
return mock_with_to_dict return mock_with_to_dict

View File

@ -161,7 +161,6 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
@mock.patch('tripleoclient.utils.copy_clouds_yaml') @mock.patch('tripleoclient.utils.copy_clouds_yaml')
@mock.patch('tripleoclient.utils.get_undercloud_host_entry', autospec=True, @mock.patch('tripleoclient.utils.get_undercloud_host_entry', autospec=True,
return_value='192.168.0.1 uc.ctlplane.localhost uc.ctlplane') return_value='192.168.0.1 uc.ctlplane.localhost uc.ctlplane')
@mock.patch('tripleoclient.utils.check_stack_network_matches_env_files')
@mock.patch('tripleoclient.utils.check_ceph_fsid_matches_env_files') @mock.patch('tripleoclient.utils.check_ceph_fsid_matches_env_files')
@mock.patch('tripleoclient.utils.check_swift_and_rgw') @mock.patch('tripleoclient.utils.check_swift_and_rgw')
@mock.patch('tripleoclient.utils.check_ceph_ansible') @mock.patch('tripleoclient.utils.check_ceph_ansible')
@ -177,7 +176,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
mock_create_tempest_deployer_input, mock_create_tempest_deployer_input,
mock_create_parameters_env, mock_create_parameters_env,
mock_breakpoints_cleanup, mock_breakpoints_cleanup,
mock_events, mock_stack_network_check, mock_events,
mock_ceph_fsid, mock_swift_rgw, mock_ceph_fsid, mock_swift_rgw,
mock_ceph_ansible, mock_ceph_ansible,
mock_get_undercloud_host_entry, mock_copy, mock_get_undercloud_host_entry, mock_copy,
@ -203,6 +202,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
clients = self.app.client_manager clients = self.app.client_manager
orchestration_client = clients.orchestration orchestration_client = clients.orchestration
orchestration_client.stacks.get.return_value = fakes.create_tht_stack() orchestration_client.stacks.get.return_value = fakes.create_tht_stack()
utils_fixture.mock_launch_heat.return_value = orchestration_client
mock_event = mock.Mock() mock_event = mock.Mock()
mock_event.id = '1234' mock_event.id = '1234'
mock_events.return_value = [mock_events] mock_events.return_value = [mock_events]
@ -325,7 +325,9 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
mock_tmpdir.return_value = self.tmp_dir.path mock_tmpdir.return_value = self.tmp_dir.path
clients = self.app.client_manager clients = self.app.client_manager
orchestration_client = clients.orchestration
orchestration_client.stacks.get.return_value = fakes.create_tht_stack()
utils_fixture.mock_launch_heat.return_value = orchestration_client
clients.network.api.find_attr.return_value = { clients.network.api.find_attr.return_value = {
"id": "network id" "id": "network id"
} }
@ -380,7 +382,6 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
@mock.patch('tripleoclient.utils.copy_clouds_yaml') @mock.patch('tripleoclient.utils.copy_clouds_yaml')
@mock.patch('tripleoclient.utils.get_undercloud_host_entry', autospec=True, @mock.patch('tripleoclient.utils.get_undercloud_host_entry', autospec=True,
return_value='192.168.0.1 uc.ctlplane.localhost uc.ctlplane') return_value='192.168.0.1 uc.ctlplane.localhost uc.ctlplane')
@mock.patch('tripleoclient.utils.check_stack_network_matches_env_files')
@mock.patch('tripleoclient.utils.check_ceph_fsid_matches_env_files') @mock.patch('tripleoclient.utils.check_ceph_fsid_matches_env_files')
@mock.patch('tripleoclient.utils.check_swift_and_rgw') @mock.patch('tripleoclient.utils.check_swift_and_rgw')
@mock.patch('tripleoclient.utils.check_ceph_ansible') @mock.patch('tripleoclient.utils.check_ceph_ansible')
@ -401,7 +402,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
mock_create_parameters_env, mock_validate_args, mock_create_parameters_env, mock_validate_args,
mock_validate_vip_file, mock_validate_vip_file,
mock_breakpoints_cleanup, mock_breakpoints_cleanup,
mock_postconfig, mock_stack_network_check, mock_postconfig,
mock_ceph_fsid, mock_swift_rgw, mock_ceph_ansible, mock_ceph_fsid, mock_swift_rgw, mock_ceph_ansible,
mock_get_undercloud_host_entry, mock_copy, mock_get_undercloud_host_entry, mock_copy,
mock_chdir, mock_chdir,
@ -429,7 +430,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
clients = self.app.client_manager clients = self.app.client_manager
orchestration_client = clients.orchestration orchestration_client = clients.orchestration
mock_stack = fakes.create_tht_stack() mock_stack = fakes.create_tht_stack()
orchestration_client.stacks.get.side_effect = [None, mock_stack] orchestration_client.stacks.get.side_effect = [mock_stack]
utils_fixture.mock_launch_heat.return_value = orchestration_client
def _orch_clt_create(**kwargs): def _orch_clt_create(**kwargs):
orchestration_client.stacks.get.return_value = mock_stack orchestration_client.stacks.get.return_value = mock_stack
@ -478,7 +480,6 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
@mock.patch('tripleoclient.utils.copy_clouds_yaml') @mock.patch('tripleoclient.utils.copy_clouds_yaml')
@mock.patch('tripleoclient.utils.get_undercloud_host_entry', autospec=True, @mock.patch('tripleoclient.utils.get_undercloud_host_entry', autospec=True,
return_value='192.168.0.1 uc.ctlplane.localhost uc.ctlplane') return_value='192.168.0.1 uc.ctlplane.localhost uc.ctlplane')
@mock.patch('tripleoclient.utils.check_stack_network_matches_env_files')
@mock.patch('tripleoclient.utils.check_ceph_fsid_matches_env_files') @mock.patch('tripleoclient.utils.check_ceph_fsid_matches_env_files')
@mock.patch('tripleoclient.utils.check_swift_and_rgw') @mock.patch('tripleoclient.utils.check_swift_and_rgw')
@mock.patch('tripleoclient.utils.check_ceph_ansible') @mock.patch('tripleoclient.utils.check_ceph_ansible')
@ -495,7 +496,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
mock_create_tempest_deployer_input, mock_create_tempest_deployer_input,
mock_deploy_postconfig, mock_deploy_postconfig,
mock_breakpoints_cleanup, mock_breakpoints_cleanup,
mock_events, mock_stack_network_check, mock_events,
mock_ceph_fsid, mock_swift_rgw, mock_ceph_fsid, mock_swift_rgw,
mock_ceph_ansible, mock_ceph_ansible,
mock_get_undercloud_host_entry, mock_get_undercloud_host_entry,
@ -513,13 +514,15 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
self.useFixture(fixture) self.useFixture(fixture)
utils_fixture = deployment.UtilsFixture() utils_fixture = deployment.UtilsFixture()
self.useFixture(utils_fixture) self.useFixture(utils_fixture)
clients = self.app.client_manager
orchestration_client = clients.orchestration
orchestration_client.stacks.get.return_value = fakes.create_tht_stack()
utils_fixture.mock_launch_heat.return_value = orchestration_client
arglist = ['--templates', '/home/stack/tripleo-heat-templates'] arglist = ['--templates', '/home/stack/tripleo-heat-templates']
verifylist = [ verifylist = [
('templates', '/home/stack/tripleo-heat-templates'), ('templates', '/home/stack/tripleo-heat-templates'),
] ]
clients = self.app.client_manager
mock_events.return_value = [] mock_events.return_value = []
clients.network.api.find_attr.return_value = { clients.network.api.find_attr.return_value = {
@ -576,7 +579,6 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
autospec=True) autospec=True)
@mock.patch('tripleoclient.utils.check_nic_config_with_ansible') @mock.patch('tripleoclient.utils.check_nic_config_with_ansible')
@mock.patch('tripleoclient.utils.copy_clouds_yaml') @mock.patch('tripleoclient.utils.copy_clouds_yaml')
@mock.patch('tripleoclient.utils.check_stack_network_matches_env_files')
@mock.patch('tripleoclient.utils.check_ceph_fsid_matches_env_files') @mock.patch('tripleoclient.utils.check_ceph_fsid_matches_env_files')
@mock.patch('tripleoclient.utils.check_swift_and_rgw') @mock.patch('tripleoclient.utils.check_swift_and_rgw')
@mock.patch('tripleoclient.utils.check_ceph_ansible') @mock.patch('tripleoclient.utils.check_ceph_ansible')
@ -590,7 +592,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
'_heat_deploy', autospec=True) '_heat_deploy', autospec=True)
def test_environment_dirs(self, mock_deploy_heat, mock_create_env, def test_environment_dirs(self, mock_deploy_heat, mock_create_env,
mock_update_parameters, mock_post_config, mock_update_parameters, mock_post_config,
mock_stack_network_check, mock_ceph_fsid, mock_ceph_fsid,
mock_swift_rgw, mock_ceph_ansible, mock_swift_rgw, mock_ceph_ansible,
mock_copy, mock_nic_ansible, mock_copy, mock_nic_ansible,
mock_process_env, mock_rc_params, mock_process_env, mock_rc_params,
@ -601,13 +603,12 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
self.useFixture(utils_overcloud_fixture) self.useFixture(utils_overcloud_fixture)
utils_fixture = deployment.UtilsFixture() utils_fixture = deployment.UtilsFixture()
self.useFixture(utils_fixture) self.useFixture(utils_fixture)
clients = self.app.client_manager
clients = self.app.client_manager clients = self.app.client_manager
orchestration_client = clients.orchestration orchestration_client = clients.orchestration
orchestration_client.stacks.get.return_value = fakes.create_tht_stack() orchestration_client.stacks.get.return_value = fakes.create_tht_stack()
mock_update_parameters.return_value = {} utils_fixture.mock_launch_heat.return_value = orchestration_client
utils_overcloud_fixture.mock_utils_endpoint.return_value = 'foo.bar' utils_overcloud_fixture.mock_utils_endpoint.return_value = 'foo.bar'
mock_update_parameters.return_value = {}
test_env = os.path.join(self.tmp_dir.path, 'foo1.yaml') test_env = os.path.join(self.tmp_dir.path, 'foo1.yaml')
@ -637,7 +638,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
def assertEqual(*args): def assertEqual(*args):
self.assertEqual(*args) self.assertEqual(*args)
def _fake_heat_deploy(self, stack, stack_name, template_path, def _fake_heat_deploy(self, stack_name, template_path,
environments, timeout, tht_root, environments, timeout, tht_root,
env, run_validations, env, run_validations,
roles_file, roles_file,
@ -724,12 +725,12 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
def test_try_overcloud_deploy_with_first_template_existing( def test_try_overcloud_deploy_with_first_template_existing(
self, mock_heat_deploy_func): self, mock_heat_deploy_func):
result = self.cmd._try_overcloud_deploy_with_compat_yaml( result = self.cmd._try_overcloud_deploy_with_compat_yaml(
'/fake/path', {}, 'overcloud', ['~/overcloud-env.json'], 1, '/fake/path', 'overcloud', ['~/overcloud-env.json'], 1,
{}, False, None, None) {}, False, None, None)
# If it returns None it succeeded # If it returns None it succeeded
self.assertIsNone(result) self.assertIsNone(result)
mock_heat_deploy_func.assert_called_once_with( mock_heat_deploy_func.assert_called_once_with(
self.cmd, {}, 'overcloud', self.cmd, 'overcloud',
'/fake/path/' + constants.OVERCLOUD_YAML_NAME, '/fake/path/' + constants.OVERCLOUD_YAML_NAME,
['~/overcloud-env.json'], 1, '/fake/path', {}, False, ['~/overcloud-env.json'], 1, '/fake/path', {}, False,
None, deployment_options=None, env_files_tracker=None) None, deployment_options=None, env_files_tracker=None)
@ -741,7 +742,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
mock_heat_deploy_func.side_effect = oscexc.CommandError('error') mock_heat_deploy_func.side_effect = oscexc.CommandError('error')
self.assertRaises(ValueError, self.assertRaises(ValueError,
self.cmd._try_overcloud_deploy_with_compat_yaml, self.cmd._try_overcloud_deploy_with_compat_yaml,
'/fake/path', mock.ANY, mock.ANY, '/fake/path', mock.ANY,
mock.ANY, mock.ANY, mock.ANY, mock.ANY, mock.ANY, mock.ANY, mock.ANY, mock.ANY, mock.ANY, mock.ANY,
None) None)
@ -753,7 +754,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
oscexc.CommandError('/fake/path not found') oscexc.CommandError('/fake/path not found')
try: try:
self.cmd._try_overcloud_deploy_with_compat_yaml( self.cmd._try_overcloud_deploy_with_compat_yaml(
'/fake/path', mock.ANY, mock.ANY, '/fake/path', mock.ANY,
mock.ANY, mock.ANY, mock.ANY, mock.ANY, mock.ANY, mock.ANY, mock.ANY, mock.ANY, mock.ANY, mock.ANY,
None) None)
except ValueError as value_error: except ValueError as value_error:
@ -802,7 +803,6 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
@mock.patch('tripleoclient.utils.copy_clouds_yaml') @mock.patch('tripleoclient.utils.copy_clouds_yaml')
@mock.patch('tripleoclient.utils.get_undercloud_host_entry', autospec=True, @mock.patch('tripleoclient.utils.get_undercloud_host_entry', autospec=True,
return_value='192.168.0.1 uc.ctlplane.localhost uc.ctlplane') return_value='192.168.0.1 uc.ctlplane.localhost uc.ctlplane')
@mock.patch('tripleoclient.utils.check_stack_network_matches_env_files')
@mock.patch('tripleoclient.utils.check_ceph_fsid_matches_env_files') @mock.patch('tripleoclient.utils.check_ceph_fsid_matches_env_files')
@mock.patch('tripleoclient.utils.check_swift_and_rgw') @mock.patch('tripleoclient.utils.check_swift_and_rgw')
@mock.patch('tripleoclient.utils.check_ceph_ansible') @mock.patch('tripleoclient.utils.check_ceph_ansible')
@ -811,7 +811,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
@mock.patch('tempfile.mkdtemp', autospec=True) @mock.patch('tempfile.mkdtemp', autospec=True)
@mock.patch('shutil.rmtree', autospec=True) @mock.patch('shutil.rmtree', autospec=True)
def test_answers_file(self, mock_rmtree, mock_tmpdir, def test_answers_file(self, mock_rmtree, mock_tmpdir,
mock_heat_deploy, mock_stack_network_check, mock_heat_deploy,
mock_ceph_fsid, mock_swift_rgw, mock_ceph_fsid, mock_swift_rgw,
mock_ceph_ansible, mock_ceph_ansible,
mock_get_undercloud_host_entry, mock_get_undercloud_host_entry,
@ -832,6 +832,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
self.useFixture(utils_oc_fixture) self.useFixture(utils_oc_fixture)
utils_fixture = deployment.UtilsFixture() utils_fixture = deployment.UtilsFixture()
self.useFixture(utils_fixture) self.useFixture(utils_fixture)
utils_fixture.mock_launch_heat.return_value = orchestration_client
clients = self.app.client_manager clients = self.app.client_manager
@ -884,17 +885,16 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
self.cmd.take_action(parsed_args) self.cmd.take_action(parsed_args)
self.assertTrue(mock_heat_deploy.called) self.assertTrue(mock_heat_deploy.called)
self.assertTrue(utils_oc_fixture.mock_deploy_tht.called)
# Check that Heat was called with correct parameters: # Check that Heat was called with correct parameters:
call_args = mock_heat_deploy.call_args[0] call_args = mock_heat_deploy.call_args[0]
self.assertEqual(call_args[3], self.assertEqual(call_args[2],
self.tmp_dir.join( self.tmp_dir.join(
'tripleo-heat-templates/overcloud.yaml')) 'tripleo-heat-templates/overcloud.yaml'))
self.assertEqual(call_args[6], self.assertEqual(call_args[5],
self.tmp_dir.join('tripleo-heat-templates')) self.tmp_dir.join('tripleo-heat-templates'))
self.assertIn('Test', call_args[7]['resource_registry']) self.assertIn('Test', call_args[6]['resource_registry'])
self.assertIn('Test2', call_args[7]['resource_registry']) self.assertIn('Test2', call_args[6]['resource_registry'])
utils_oc_fixture.mock_deploy_tht.assert_called_with( utils_oc_fixture.mock_deploy_tht.assert_called_with(
output_dir=self.cmd.working_dir) output_dir=self.cmd.working_dir)
@ -923,7 +923,6 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
@mock.patch('tripleoclient.utils.copy_clouds_yaml') @mock.patch('tripleoclient.utils.copy_clouds_yaml')
@mock.patch('tripleoclient.utils.get_undercloud_host_entry', autospec=True, @mock.patch('tripleoclient.utils.get_undercloud_host_entry', autospec=True,
return_value='192.168.0.1 uc.ctlplane.localhost uc.ctlplane') return_value='192.168.0.1 uc.ctlplane.localhost uc.ctlplane')
@mock.patch('tripleoclient.utils.check_stack_network_matches_env_files')
@mock.patch('tripleoclient.utils.check_ceph_fsid_matches_env_files') @mock.patch('tripleoclient.utils.check_ceph_fsid_matches_env_files')
@mock.patch('tripleoclient.utils.check_swift_and_rgw') @mock.patch('tripleoclient.utils.check_swift_and_rgw')
@mock.patch('tripleoclient.utils.check_ceph_ansible') @mock.patch('tripleoclient.utils.check_ceph_ansible')
@ -947,7 +946,6 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
mock_validate_vip_file, mock_validate_vip_file,
mock_breakpoints_cleanup, mock_breakpoints_cleanup,
mock_deploy_post_config, mock_deploy_post_config,
mock_stack_network_check,
mock_ceph_fsid, mock_swift_rgw, mock_ceph_fsid, mock_swift_rgw,
mock_ceph_ansible, mock_ceph_ansible,
mock_get_undercloud_host_entry, mock_copy, mock_get_undercloud_host_entry, mock_copy,
@ -976,9 +974,9 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
orchestration_client = clients.orchestration orchestration_client = clients.orchestration
mock_stack = fakes.create_tht_stack() mock_stack = fakes.create_tht_stack()
orchestration_client.stacks.get.side_effect = [ orchestration_client.stacks.get.side_effect = [
None,
mock_stack mock_stack
] ]
utils_fixture.mock_launch_heat.return_value = orchestration_client
def _orch_clt_create(**kwargs): def _orch_clt_create(**kwargs):
orchestration_client.stacks.get.return_value = mock_stack orchestration_client.stacks.get.return_value = mock_stack
@ -1078,6 +1076,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
clients.compute = mock.Mock() clients.compute = mock.Mock()
orchestration_client = clients.orchestration orchestration_client = clients.orchestration
orchestration_client.stacks.get.return_value = fakes.create_tht_stack() orchestration_client.stacks.get.return_value = fakes.create_tht_stack()
utils_fixture.mock_launch_heat.return_value = orchestration_client
mock_create_env.return_value = ( mock_create_env.return_value = (
dict(ContainerHeatApiImage='container-heat-api-image', dict(ContainerHeatApiImage='container-heat-api-image',
ContainerHeatEngineImage='container-heat-engine-image'), ContainerHeatEngineImage='container-heat-engine-image'),
@ -1111,6 +1110,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
clients = self.app.client_manager clients = self.app.client_manager
orchestration_client = clients.orchestration orchestration_client = clients.orchestration
orchestration_client.stacks.get.return_value = fakes.create_tht_stack() orchestration_client.stacks.get.return_value = fakes.create_tht_stack()
utils_fixture.mock_launch_heat.return_value = orchestration_client
arglist = ['--templates', '--config-download'] arglist = ['--templates', '--config-download']
verifylist = [ verifylist = [
@ -1156,6 +1156,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
clients = self.app.client_manager clients = self.app.client_manager
orchestration_client = clients.orchestration orchestration_client = clients.orchestration
orchestration_client.stacks.get.return_value = fakes.create_tht_stack() orchestration_client.stacks.get.return_value = fakes.create_tht_stack()
utils_fixture.mock_launch_heat.return_value = orchestration_client
mock_create_env.return_value = ({}, []) mock_create_env.return_value = ({}, [])
mock_create_env.return_value = ( mock_create_env.return_value = (
dict(ContainerHeatApiImage='container-heat-api-image', dict(ContainerHeatApiImage='container-heat-api-image',
@ -1202,6 +1203,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
clients = self.app.client_manager clients = self.app.client_manager
orchestration_client = clients.orchestration orchestration_client = clients.orchestration
orchestration_client.stacks.get.return_value = fakes.create_tht_stack() orchestration_client.stacks.get.return_value = fakes.create_tht_stack()
utils_fixture.mock_launch_heat.return_value = orchestration_client
mock_create_parameters_env.return_value = ( mock_create_parameters_env.return_value = (
dict(ContainerHeatApiImage='container-heat-api-image', dict(ContainerHeatApiImage='container-heat-api-image',
ContainerHeatEngineImage='container-heat-engine-image'), ContainerHeatEngineImage='container-heat-engine-image'),
@ -1251,6 +1253,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
clients = self.app.client_manager clients = self.app.client_manager
orchestration_client = clients.orchestration orchestration_client = clients.orchestration
orchestration_client.stacks.get.return_value = fakes.create_tht_stack() orchestration_client.stacks.get.return_value = fakes.create_tht_stack()
utils_fixture.mock_launch_heat.return_value = orchestration_client
mock_create_parameters_env.return_value = ( mock_create_parameters_env.return_value = (
dict(ContainerHeatApiImage='container-heat-api-image', dict(ContainerHeatApiImage='container-heat-api-image',
ContainerHeatEngineImage='container-heat-engine-image'), ContainerHeatEngineImage='container-heat-engine-image'),
@ -1299,6 +1302,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
clients = self.app.client_manager clients = self.app.client_manager
orchestration_client = clients.orchestration orchestration_client = clients.orchestration
orchestration_client.stacks.get.return_value = fakes.create_tht_stack() orchestration_client.stacks.get.return_value = fakes.create_tht_stack()
utils_fixture.mock_launch_heat.return_value = orchestration_client
arglist = ['--templates', arglist = ['--templates',
'--override-ansible-cfg', 'ansible.cfg'] '--override-ansible-cfg', 'ansible.cfg']
@ -1342,13 +1346,12 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
return_value='192.168.0.1 uc.ctlplane.localhost uc.ctlplane') return_value='192.168.0.1 uc.ctlplane.localhost uc.ctlplane')
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
'_heat_deploy', autospec=True) '_heat_deploy', autospec=True)
@mock.patch('tripleoclient.utils.check_stack_network_matches_env_files')
@mock.patch('tripleoclient.utils.check_ceph_fsid_matches_env_files') @mock.patch('tripleoclient.utils.check_ceph_fsid_matches_env_files')
@mock.patch('tripleoclient.utils.check_swift_and_rgw') @mock.patch('tripleoclient.utils.check_swift_and_rgw')
@mock.patch('tripleoclient.utils.check_ceph_ansible') @mock.patch('tripleoclient.utils.check_ceph_ansible')
@mock.patch('heatclient.common.template_utils.deep_update', autospec=True) @mock.patch('heatclient.common.template_utils.deep_update', autospec=True)
def test_config_download_timeout( def test_config_download_timeout(
self, mock_hc, mock_stack_network_check, self, mock_hc,
mock_ceph_fsid, mock_swift_rgw, mock_ceph_ansible, mock_ceph_fsid, mock_swift_rgw, mock_ceph_ansible,
mock_hd, mock_get_undercloud_host_entry, mock_copy, mock_hd, mock_get_undercloud_host_entry, mock_copy,
mock_get_ctlplane_attrs, mock_nic_ansible, mock_get_ctlplane_attrs, mock_nic_ansible,
@ -1366,6 +1369,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
clients = self.app.client_manager clients = self.app.client_manager
orchestration_client = clients.orchestration orchestration_client = clients.orchestration
orchestration_client.stacks.get.return_value = fakes.create_tht_stack() orchestration_client.stacks.get.return_value = fakes.create_tht_stack()
utils_fixture.mock_launch_heat.return_value = orchestration_client
mock_create_parameters_env.return_value = [] mock_create_parameters_env.return_value = []
arglist = ['--templates', '--overcloud-ssh-port-timeout', '42', arglist = ['--templates', '--overcloud-ssh-port-timeout', '42',
@ -1395,7 +1399,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
self.cmd.take_action(parsed_args) self.cmd.take_action(parsed_args)
self.assertIn([ self.assertIn([
mock.call( mock.call(
mock.ANY, mock.ANY, 'overcloud', mock.ANY, mock.ANY, 'overcloud', mock.ANY,
mock.ANY, 451, mock.ANY, mock.ANY, 451, mock.ANY,
{'parameter_defaults': { {'parameter_defaults': {
'ContainerHeatApiImage': 'container-heat-api-image', 'ContainerHeatApiImage': 'container-heat-api-image',

View File

@ -15,7 +15,6 @@
from unittest import mock from unittest import mock
from osc_lib import exceptions as oscexc
from osc_lib.tests.utils import ParserException from osc_lib.tests.utils import ParserException
from tripleoclient import constants from tripleoclient import constants
from tripleoclient import exceptions from tripleoclient import exceptions
@ -127,16 +126,6 @@ class TestOvercloudUpgradePrepare(fakes.TestOvercloudUpgradePrepare):
mock_usercheck.assert_called_once() mock_usercheck.assert_called_once()
mock_overcloud_deploy.assert_called_once_with(parsed_args) mock_overcloud_deploy.assert_called_once_with(parsed_args)
@mock.patch('tripleo_common.update.check_neutron_mechanism_drivers')
def test_upgrade_failed_wrong_driver(self, check_mech):
check_mech.return_value = 'Wrong mech'
mock_stack = mock.Mock(parameters={'DeployIdentifier': ''})
argslist = (mock_stack, 'mock_stack', '/tmp', {},
{}, 1, '/tmp', {}, True, False, None)
self.cmd.object_client = mock.Mock()
self.assertRaises(oscexc.CommandError,
self.cmd._heat_deploy, *argslist)
class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun): class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun):

View File

@ -1077,7 +1077,7 @@ def check_ceph_ansible(resource_registry, stage):
'file.') 'file.')
def check_ceph_fsid_matches_env_files(stack, environment): def check_ceph_fsid_matches_env_files(old_env, environment):
"""Check CephClusterFSID against proposed env files """Check CephClusterFSID against proposed env files
There have been cases where operators inadvertenly changed the There have been cases where operators inadvertenly changed the
@ -1089,8 +1089,8 @@ def check_ceph_fsid_matches_env_files(stack, environment):
""" """
env_ceph_fsid = environment.get('parameter_defaults', env_ceph_fsid = environment.get('parameter_defaults',
{}).get('CephClusterFSID', False) {}).get('CephClusterFSID', False)
stack_ceph_fsid = stack.environment().get('parameter_defaults', stack_ceph_fsid = old_env.get('parameter_defaults',
{}).get('CephClusterFSID', False) {}).get('CephClusterFSID', False)
if bool(env_ceph_fsid) and env_ceph_fsid != stack_ceph_fsid: if bool(env_ceph_fsid) and env_ceph_fsid != stack_ceph_fsid:
raise exceptions.InvalidConfiguration('The CephFSID environment value ' raise exceptions.InvalidConfiguration('The CephFSID environment value '
@ -1104,7 +1104,7 @@ def check_ceph_fsid_matches_env_files(stack, environment):
stack_ceph_fsid)) stack_ceph_fsid))
def check_swift_and_rgw(stack, env, stage): def check_swift_and_rgw(old_env, env, stage):
"""Check that Swift and RGW aren't both enabled in the overcloud """Check that Swift and RGW aren't both enabled in the overcloud
When Ceph is deployed by TripleO using the default cephadm environment When Ceph is deployed by TripleO using the default cephadm environment
@ -1126,9 +1126,9 @@ def check_swift_and_rgw(stack, env, stage):
if not re.match(allowed_stage, stage) or rgw_env == 'OS::Heat::None': if not re.match(allowed_stage, stage) or rgw_env == 'OS::Heat::None':
return return
sw = stack.environment().get('resource_registry', sw = old_env.get('resource_registry',
{}).get('OS::TripleO::Services::SwiftProxy', {}).get('OS::TripleO::Services::SwiftProxy',
'OS::Heat::None') 'OS::Heat::None')
# RGW is present in the env list and swift was previously deployed # RGW is present in the env list and swift was previously deployed
if sw != "OS::Heat::None": if sw != "OS::Heat::None":
@ -1141,22 +1141,11 @@ def check_swift_and_rgw(stack, env, stage):
'RGW)') 'RGW)')
def check_nic_config_with_ansible(stack, environment): def check_nic_config_with_ansible(environment):
registry = environment.get('resource_registry', {}) registry = environment.get('resource_registry', {})
stack_registry = {}
is_ansible_config_stack = True
if stack:
stack_registry = stack.environment().get(
'resource_registry', {})
is_ansible_config_stack = stack.environment().get(
'parameter_defaults', {}).get(
'NetworkConfigWithAnsible', True)
is_ansible_config = environment.get( is_ansible_config = environment.get(
'parameter_defaults', {}).get( 'parameter_defaults', {}).get(
'NetworkConfigWithAnsible', is_ansible_config_stack) 'NetworkConfigWithAnsible', True)
nic_configs_in_update = set()
if is_ansible_config: if is_ansible_config:
for k, v in registry.items(): for k, v in registry.items():
if k.endswith('Net::SoftwareConfig'): if k.endswith('Net::SoftwareConfig'):
@ -1166,23 +1155,10 @@ def check_nic_config_with_ansible(stack, environment):
"Migrate to ansible jinja templates or use " "Migrate to ansible jinja templates or use "
"'NetworkConfigWithAnsible: false' " "'NetworkConfigWithAnsible: false' "
"in 'parameter_defaults'.") "in 'parameter_defaults'.")
nic_configs_in_update.add(k)
for k, v in stack_registry.items():
if (k.endswith('Net::SoftwareConfig') and v != 'OS::Heat::None'
and k not in nic_configs_in_update):
raise exceptions.InvalidConfiguration(
"DEPRECATED: Old heat nic configs are used, "
"Migrate to ansible jinja templates or use "
"'NetworkConfigWithAnsible: false' "
"in 'parameter_defaults'.")
def check_service_vips_migrated_to_service(stack, environment): def check_service_vips_migrated_to_service(environment):
registry = environment.get('resource_registry', {}) registry = environment.get('resource_registry', {})
stack_registry = {}
if stack:
stack_registry = stack.environment().get(
'resource_registry', {})
removed_resources = {'OS::TripleO::Network::Ports::RedisVipPort', removed_resources = {'OS::TripleO::Network::Ports::RedisVipPort',
'OS::TripleO::Network::Ports::OVNDBsVipPort'} 'OS::TripleO::Network::Ports::OVNDBsVipPort'}
msg = ("Resources 'OS::TripleO::Network::Ports::RedisVipPort' and " msg = ("Resources 'OS::TripleO::Network::Ports::RedisVipPort' and "
@ -1194,7 +1170,7 @@ def check_service_vips_migrated_to_service(stack, environment):
"'ServiceNetMap' and/or 'VipSubnetMap' parameters with the desired " "'ServiceNetMap' and/or 'VipSubnetMap' parameters with the desired "
"network and/or subnet for the service.") "network and/or subnet for the service.")
for resource in removed_resources: for resource in removed_resources:
if ((resource in registry or resource in stack_registry) and if (resource in registry and
registry.get(resource) != 'OS::Heat::None'): registry.get(resource) != 'OS::Heat::None'):
raise exceptions.InvalidConfiguration(msg) raise exceptions.InvalidConfiguration(msg)
@ -1213,43 +1189,6 @@ def check_neutron_resources(environment):
raise exceptions.InvalidConfiguration(msg.format(rsrc, rsrc_type)) raise exceptions.InvalidConfiguration(msg.format(rsrc, rsrc_type))
def check_stack_network_matches_env_files(stack, environment):
"""Check stack against proposed env files to ensure non-breaking change
Historically we have have had issues with folks forgetting the network
isolation templates in subsequent overcloud actions which have completely
broken the stack. We need to check that the networks continue to be
provided on updates and if they aren't, it's likely that the user has
failed to provide the network-isolation templates. This is a light check
to only ensure they are defined. A user can still change settings in these
networks that may break things but this will catch folks who forget
network-isolation in a subsequent update.
"""
def _get_networks(registry):
nets = set()
for k, v in registry.items():
if (k.startswith('OS::TripleO::Network::')
and not k.startswith('OS::TripleO::Network::Port')
and v != 'OS::Heat::None'):
nets.add(k)
return nets
stack_registry = stack.environment().get('resource_registry', {})
env_registry = environment.get('resource_registry', {})
stack_nets = _get_networks(stack_registry)
env_nets = _get_networks(env_registry)
env_diff = set(stack_nets) - set(env_nets)
if env_diff:
raise exceptions.InvalidConfiguration('Missing networks from '
'environment configuration. '
'Ensure the following networks '
'are properly configured in '
'the provided environment files '
'[{}]'.format(env_diff))
def remove_known_hosts(overcloud_ip): def remove_known_hosts(overcloud_ip):
"""For a given IP address remove SSH keys from the known_hosts file""" """For a given IP address remove SSH keys from the known_hosts file"""
@ -3238,7 +3177,9 @@ def parse_ansible_inventory(inventory_file, group):
return(inventory.get_hosts(pattern=group)) return(inventory.get_hosts(pattern=group))
def save_stack_outputs(heat, stack, working_dir): def save_stack(stack, working_dir):
if not stack:
return
outputs_dir = os.path.join(working_dir, 'outputs') outputs_dir = os.path.join(working_dir, 'outputs')
makedirs(outputs_dir) makedirs(outputs_dir)
for output in constants.STACK_OUTPUTS: for output in constants.STACK_OUTPUTS:
@ -3246,6 +3187,24 @@ def save_stack_outputs(heat, stack, working_dir):
output_path = os.path.join(outputs_dir, output) output_path = os.path.join(outputs_dir, output)
with open(output_path, 'w') as f: with open(output_path, 'w') as f:
f.write(yaml.dump(val)) f.write(yaml.dump(val))
env_dir = os.path.join(working_dir, 'environment')
makedirs(env_dir)
env = stack.environment()
env_path = os.path.join(
env_dir,
constants.STACK_ENV_FILE_NAME.format(stack.stack_name))
with open(env_path, 'w') as f:
f.write(yaml.dump(env))
def get_saved_stack_env(working_dir, stack_name):
env_path = os.path.join(
working_dir, 'environment',
constants.STACK_ENV_FILE_NAME.format(stack_name))
if not os.path.isfile(env_path):
return None
with open(env_path) as f:
return yaml.safe_load(f.read())
def get_ceph_networks(network_data_path, def get_ceph_networks(network_data_path,

View File

@ -29,7 +29,6 @@ import yaml
from heatclient.common import template_utils from heatclient.common import template_utils
from osc_lib import exceptions as oscexc from osc_lib import exceptions as oscexc
from osc_lib.i18n import _ from osc_lib.i18n import _
from tripleo_common import update
from tripleo_common.utils import plan as plan_utils from tripleo_common.utils import plan as plan_utils
from tripleoclient import command from tripleoclient import command
@ -204,7 +203,7 @@ class DeployOvercloud(command.Command):
'be ignored because --limit has been specified.') 'be ignored because --limit has been specified.')
self.log.warning(msg) self.log.warning(msg)
def _heat_deploy(self, stack, stack_name, template_path, def _heat_deploy(self, stack_name, template_path,
env_files, timeout, tht_root, env, env_files, timeout, tht_root, env,
run_validations, run_validations,
roles_file, roles_file,
@ -212,15 +211,6 @@ class DeployOvercloud(command.Command):
deployment_options=None): deployment_options=None):
"""Verify the Baremetal nodes are available and do a stack update""" """Verify the Baremetal nodes are available and do a stack update"""
if stack:
self.log.debug(
"Checking compatibilities of neutron drivers for {0}".format(
stack_name))
msg = update.check_neutron_mechanism_drivers(
env, stack, None, stack_name)
if msg:
raise oscexc.CommandError(msg)
self.log.debug("Getting template contents from plan %s" % stack_name) self.log.debug("Getting template contents from plan %s" % stack_name)
template_files, template = template_utils.get_template_contents( template_files, template = template_utils.get_template_contents(
@ -238,7 +228,7 @@ class DeployOvercloud(command.Command):
self.log.info("Deploying templates in the directory {0}".format( self.log.info("Deploying templates in the directory {0}".format(
os.path.abspath(tht_root))) os.path.abspath(tht_root)))
deployment.deploy_without_plan( deployment.deploy_without_plan(
self.clients, stack, stack_name, self.clients, stack_name,
template, files, env_files_tracker, template, files, env_files_tracker,
self.log, self.working_dir) self.log, self.working_dir)
@ -261,7 +251,7 @@ class DeployOvercloud(command.Command):
base_path=new_tht_root) base_path=new_tht_root)
return new_tht_root, tht_root return new_tht_root, tht_root
def create_env_files(self, stack, parsed_args, def create_env_files(self, parsed_args,
new_tht_root, user_tht_root): new_tht_root, user_tht_root):
self.log.debug("Creating Environment files") self.log.debug("Creating Environment files")
# A dictionary to store resource registry types that are internal, # A dictionary to store resource registry types that are internal,
@ -277,18 +267,10 @@ class DeployOvercloud(command.Command):
self._update_parameters( self._update_parameters(
parsed_args, parameters, new_tht_root, user_tht_root) parsed_args, parameters, new_tht_root, user_tht_root)
stack_is_new = stack is None
parameters['StackAction'] = 'CREATE' if stack_is_new else 'UPDATE'
param_env = utils.create_parameters_env( param_env = utils.create_parameters_env(
parameters, new_tht_root, parsed_args.stack) parameters, new_tht_root, parsed_args.stack)
created_env_files.extend(param_env) created_env_files.extend(param_env)
if stack:
env_path = utils.create_breakpoint_cleanup_env(
new_tht_root, parsed_args.stack)
created_env_files.extend(env_path)
if parsed_args.deployed_server: if parsed_args.deployed_server:
created_env_files.append( created_env_files.append(
os.path.join( os.path.join(
@ -328,7 +310,7 @@ class DeployOvercloud(command.Command):
return created_env_files return created_env_files
def deploy_tripleo_heat_templates(self, stack, parsed_args, def deploy_tripleo_heat_templates(self, parsed_args,
new_tht_root, user_tht_root, new_tht_root, user_tht_root,
created_env_files): created_env_files):
"""Deploy the fixed templates in TripleO Heat Templates""" """Deploy the fixed templates in TripleO Heat Templates"""
@ -373,10 +355,10 @@ class DeployOvercloud(command.Command):
# warning if necessary # warning if necessary
self._check_limit_skiplist_warning(env) self._check_limit_skiplist_warning(env)
if stack: old_stack_env = utils.get_saved_stack_env(
self.working_dir, parsed_args.stack)
if old_stack_env:
if not parsed_args.disable_validations: if not parsed_args.disable_validations:
# note(aschultz): network validation goes here before we deploy
utils.check_stack_network_matches_env_files(stack, env)
ceph_deployed = env.get('resource_registry', {}).get( ceph_deployed = env.get('resource_registry', {}).get(
'OS::TripleO::Services::CephMon', 'OS::Heat::None') 'OS::TripleO::Services::CephMon', 'OS::Heat::None')
ceph_external = env.get('resource_registry', {}).get( ceph_external = env.get('resource_registry', {}).get(
@ -386,21 +368,22 @@ class DeployOvercloud(command.Command):
# make this check and we can simply ignore it # make this check and we can simply ignore it
if (ceph_deployed != "OS::Heat::None" if (ceph_deployed != "OS::Heat::None"
or ceph_external != "OS::Heat::None"): or ceph_external != "OS::Heat::None"):
utils.check_ceph_fsid_matches_env_files(stack, env) utils.check_ceph_fsid_matches_env_files(old_stack_env, env)
# upgrades: check if swift is deployed # upgrades: check if swift is deployed
utils.check_swift_and_rgw(stack, env, utils.check_swift_and_rgw(old_stack_env, env,
self.__class__.__name__) self.__class__.__name__)
# check migration to new nic config with ansible
utils.check_nic_config_with_ansible(env)
# check migration to service vips managed by servce
utils.check_service_vips_migrated_to_service(env)
# check if ceph-ansible env is present # check if ceph-ansible env is present
utils.check_ceph_ansible(env.get('resource_registry', {}), utils.check_ceph_ansible(env.get('resource_registry', {}),
self.__class__.__name__) self.__class__.__name__)
# check migration to new nic config with ansible
utils.check_nic_config_with_ansible(stack, env)
# check migration to service vips managed by servce
utils.check_service_vips_migrated_to_service(stack, env)
utils.check_neutron_resources(env) utils.check_neutron_resources(env)
self._try_overcloud_deploy_with_compat_yaml( self._try_overcloud_deploy_with_compat_yaml(
new_tht_root, stack, new_tht_root,
parsed_args.stack, env_files, parsed_args.stack, env_files,
parsed_args.timeout, env, parsed_args.timeout, env,
parsed_args.run_validations, parsed_args.run_validations,
@ -410,7 +393,7 @@ class DeployOvercloud(command.Command):
self._unprovision_baremetal(parsed_args) self._unprovision_baremetal(parsed_args)
def _try_overcloud_deploy_with_compat_yaml(self, tht_root, stack, def _try_overcloud_deploy_with_compat_yaml(self, tht_root,
stack_name, stack_name,
env_files, timeout, env_files, timeout,
env, run_validations, env, run_validations,
@ -419,7 +402,7 @@ class DeployOvercloud(command.Command):
deployment_options=None): deployment_options=None):
overcloud_yaml = os.path.join(tht_root, constants.OVERCLOUD_YAML_NAME) overcloud_yaml = os.path.join(tht_root, constants.OVERCLOUD_YAML_NAME)
try: try:
self._heat_deploy(stack, stack_name, overcloud_yaml, self._heat_deploy(stack_name, overcloud_yaml,
env_files, timeout, env_files, timeout,
tht_root, env, tht_root, env,
run_validations, run_validations,
@ -1096,13 +1079,12 @@ class DeployOvercloud(command.Command):
return return
self.heat_launcher = None self.heat_launcher = None
stack = None
start = time.time() start = time.time()
new_tht_root, user_tht_root = \ new_tht_root, user_tht_root = \
self.create_template_dirs(parsed_args) self.create_template_dirs(parsed_args)
created_env_files = self.create_env_files( created_env_files = self.create_env_files(
stack, parsed_args, new_tht_root, user_tht_root) parsed_args, new_tht_root, user_tht_root)
# full_deploy means we're doing a full deployment # full_deploy means we're doing a full deployment
# e.g., no --*-only args were passed # e.g., no --*-only args were passed
@ -1143,13 +1125,12 @@ class DeployOvercloud(command.Command):
self.setup_ephemeral_heat(parsed_args) self.setup_ephemeral_heat(parsed_args)
self.deploy_tripleo_heat_templates( self.deploy_tripleo_heat_templates(
stack, parsed_args, new_tht_root, parsed_args, new_tht_root,
user_tht_root, created_env_files) user_tht_root, created_env_files)
stack = utils.get_stack( stack = utils.get_stack(
self.orchestration_client, parsed_args.stack) self.orchestration_client, parsed_args.stack)
utils.save_stack_outputs( utils.save_stack(stack, self.working_dir)
self.orchestration_client, stack, self.working_dir)
horizon_url = deployment.get_horizon_url( horizon_url = deployment.get_horizon_url(
stack=stack.stack_name, stack=stack.stack_name,

View File

@ -17,7 +17,6 @@ import os
import shutil import shutil
import yaml import yaml
from heatclient.common import event_utils
from openstackclient import shell from openstackclient import shell
from tripleo_common.utils import heat as tc_heat_utils from tripleo_common.utils import heat as tc_heat_utils
from tripleo_common.utils import overcloudrc as rc_utils from tripleo_common.utils import overcloudrc as rc_utils
@ -44,26 +43,13 @@ def create_overcloudrc(stack_name, endpoint, admin_vip, rc_params,
return os.path.abspath(rcpath) return os.path.abspath(rcpath)
def deploy_without_plan(clients, stack, stack_name, template, def deploy_without_plan(clients, stack_name, template,
files, env_files, files, env_files,
log, log,
working_dir): working_dir):
orchestration_client = clients.orchestration orchestration_client = clients.orchestration
if stack is None: log.info("Performing Heat stack create")
log.info("Performing Heat stack create") marker = None
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(stack_name, set_deployment_status(stack_name,
status='DEPLOYING', status='DEPLOYING',
working_dir=working_dir) working_dir=working_dir)
@ -73,12 +59,7 @@ def deploy_without_plan(clients, stack, stack_name, template,
'environment_files': env_files, 'environment_files': env_files,
'files': files} 'files': files}
try: try:
if stack: orchestration_client.stacks.create(**stack_args)
stack_args['existing'] = True
orchestration_client.stacks.update(stack.id, **stack_args)
else:
stack = orchestration_client.stacks.create(**stack_args)
print("Success.") print("Success.")
except Exception: except Exception:
set_deployment_status(stack_name, set_deployment_status(stack_name,
@ -87,7 +68,7 @@ def deploy_without_plan(clients, stack, stack_name, template,
raise raise
create_result = utils.wait_for_stack_ready( create_result = utils.wait_for_stack_ready(
orchestration_client, stack_name, marker, action) orchestration_client, stack_name, marker)
if not create_result: if not create_result:
shell.OpenStackShell().run( shell.OpenStackShell().run(
["stack", "failures", "list", '--long', stack_name]) ["stack", "failures", "list", '--long', stack_name])
@ -96,10 +77,7 @@ def deploy_without_plan(clients, stack, stack_name, template,
status='DEPLOY_FAILED', status='DEPLOY_FAILED',
working_dir=working_dir working_dir=working_dir
) )
if stack is None: raise exceptions.DeploymentError("Heat Stack create failed.")
raise exceptions.DeploymentError("Heat Stack create failed.")
else:
raise exceptions.DeploymentError("Heat Stack update failed.")
def get_overcloud_hosts(stack, ssh_network, working_dir): def get_overcloud_hosts(stack, ssh_network, working_dir):