diff --git a/releasenotes/notes/remove-overcloud-plan-commands-69e89097fc9351fa.yaml b/releasenotes/notes/remove-overcloud-plan-commands-69e89097fc9351fa.yaml new file mode 100644 index 000000000..241335f2a --- /dev/null +++ b/releasenotes/notes/remove-overcloud-plan-commands-69e89097fc9351fa.yaml @@ -0,0 +1,8 @@ +--- +upgrade: + - | + ``openstack overcloud plan *`` commands have been removed. + These commands are irrelevant as overcloud deploy/update/upgrade + does not create/update swift plan anymore. Also, some of the + ``openstack overcloud role`` commands that use swift plan have + been removed. diff --git a/setup.cfg b/setup.cfg index 4aca1be80..0533e1005 100644 --- a/setup.cfg +++ b/setup.cfg @@ -67,19 +67,12 @@ openstack.tripleoclient.v2 = overcloud_node_unprovision = tripleoclient.v2.overcloud_node:UnprovisionNode overcloud_node_extract_provisioned = tripleoclient.v1.overcloud_node:ExtractProvisionedNode overcloud_parameters_set = tripleoclient.v1.overcloud_parameters:SetParameters - overcloud_plan_create = tripleoclient.v1.overcloud_plan:CreatePlan - overcloud_plan_delete = tripleoclient.v1.overcloud_plan:DeletePlan - overcloud_plan_deploy = tripleoclient.v1.overcloud_plan:DeployPlan - overcloud_plan_list = tripleoclient.v1.overcloud_plan:ListPlans - overcloud_plan_export = tripleoclient.v1.overcloud_plan:ExportPlan overcloud_profiles_match = tripleoclient.v1.overcloud_profiles:MatchProfiles overcloud_profiles_list = tripleoclient.v1.overcloud_profiles:ListProfiles overcloud_raid_create = tripleoclient.v1.overcloud_raid:CreateRAID overcloud_role_show= tripleoclient.v1.overcloud_roles:RoleShow overcloud_role_list = tripleoclient.v1.overcloud_roles:RoleList overcloud_roles_generate = tripleoclient.v1.overcloud_roles:RolesGenerate - overcloud_roles_list = tripleoclient.v1.overcloud_plan_roles:ListRoles - overcloud_roles_show = tripleoclient.v1.overcloud_plan_roles:ShowRole overcloud_support_report_collect = tripleoclient.v2.overcloud_support:ReportExecute overcloud_update_prepare= tripleoclient.v1.overcloud_update:UpdatePrepare overcloud_update_run = tripleoclient.v1.overcloud_update:UpdateRun diff --git a/tripleoclient/constants.py b/tripleoclient/constants.py index 1503cbfb2..4e45e8e76 100644 --- a/tripleoclient/constants.py +++ b/tripleoclient/constants.py @@ -205,16 +205,6 @@ try: except (configparser.NoOptionError, FileNotFoundError): UNDERCLOUD_OUTPUT_DIR = CLOUD_HOME_DIR -# regex patterns to exclude when looking for unused params -# - exclude *Image params as they may be unused because the service is not -# enabled -# - exclude SwiftFetchDir*Tempurl because it's used by ceph and generated by us -# - exclude PythonInterpreter because it's generated by us and only used -# in some custom scripts -UNUSED_PARAMETER_EXCLUDES_RE = ['^(Docker|Container).*Image$', - '^SwiftFetchDir(Get|Put)Tempurl$', - '^PythonInterpreter$'] - EXPORT_PASSWORD_EXCLUDE_PATTERNS = [ 'ceph.*' ] diff --git a/tripleoclient/tests/v1/overcloud_deploy/test_overcloud_deploy.py b/tripleoclient/tests/v1/overcloud_deploy/test_overcloud_deploy.py index 8e02cd8c4..15cdc29d4 100644 --- a/tripleoclient/tests/v1/overcloud_deploy/test_overcloud_deploy.py +++ b/tripleoclient/tests/v1/overcloud_deploy/test_overcloud_deploy.py @@ -27,8 +27,6 @@ from osc_lib.tests import utils from tripleoclient import constants from tripleoclient import exceptions -from tripleoclient import plugin -from tripleoclient.tests import fakes as ooofakes from tripleoclient.tests.fixture_data import deployment from tripleoclient.tests.v1.overcloud_deploy import fakes from tripleoclient.v1 import overcloud_deploy @@ -91,53 +89,6 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud): mock_run_command.start() self.addCleanup(mock_run_command.stop) - plan_list = mock.patch( - "tripleoclient.workflows.plan_management.list_deployment_plans", - autospec=True - ) - plan_list.start() - plan_list.return_value = ([ - "test-plan-1", - "test-plan-2", - ]) - self.addCleanup(plan_list.stop) - roles = mock.patch( - 'tripleoclient.workflows.roles.list_available_roles', - autospec=True, - return_value=[ - { - 'TestRole1': { - 'TestParameter1': {} - } - } - ] - ) - roles.start() - self.addCleanup(roles.stop) - flatten = mock.patch( - 'tripleo_common.utils.stack_parameters.get_flattened_parameters', - autospec=True, - return_value={ - 'environment_parameters': { - 'TestParameter1': {}, - 'TestRole1': 'TestParameter2' - }, - 'heat_resource_tree': { - 'parameters': { - 'TestParameter2': { - 'name': 'TestParameter2', - 'tags': [ - 'role_specific' - ] - } - }, - 'resources': {} - } - } - ) - flatten.start() - self.addCleanup(flatten.stop) - # Mock playbook runner playbook_runner = mock.patch( 'tripleoclient.utils.run_ansible_playbook', @@ -404,8 +355,6 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud): 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.workflows.parameters.' - 'check_deprecated_parameters', autospec=True) @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' '_deploy_postconfig', autospec=True) @mock.patch('tripleo_common.update.add_breakpoints_cleanup_into_env', @@ -423,7 +372,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud): mock_get_template_contents, mock_create_parameters_env, mock_validate_args, mock_breakpoints_cleanup, - mock_postconfig, mock_deprecated_params, mock_stack_network_check, + mock_postconfig, mock_stack_network_check, mock_ceph_fsid, mock_get_undercloud_host_entry, mock_copy, mock_chdir, mock_overcloudrc, mock_process_env, mock_roles_data, @@ -1274,10 +1223,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud): @mock.patch('tripleoclient.utils.check_stack_network_matches_env_files') @mock.patch('tripleoclient.utils.check_ceph_fsid_matches_env_files') @mock.patch('heatclient.common.template_utils.deep_update', autospec=True) - @mock.patch('tripleoclient.workflows.plan_management.' - 'create_plan_from_templates', autospec=True) def test_config_download_timeout( - self, mock_plan_man, mock_hc, mock_stack_network_check, + self, mock_hc, mock_stack_network_check, mock_ceph_fsid, mock_hd, mock_get_undercloud_host_entry, mock_copy, mock_get_ctlplane_attrs, mock_nic_ansible, @@ -1633,14 +1580,6 @@ class TestGetDeploymentStatus(utils.TestCommand): super(TestGetDeploymentStatus, self).setUp() self.cmd = overcloud_deploy.GetDeploymentStatus(self.app, None) self.app.client_manager = mock.Mock() - clients = self.clients = self.app.client_manager - tc = clients.tripleoclient = ooofakes.FakeClientWrapper() - tc.create_mistral_context = plugin.ClientWrapper( - instance=ooofakes.FakeInstanceData - ).create_mistral_context - obj = tc.object_store = mock.Mock() - obj.put_object = mock.Mock() - obj.put_container = mock.Mock() @mock.patch("tripleoclient.workflows.deployment.get_deployment_status") def test_get_deployment_status(self, mock_get_deployment_status): @@ -1652,10 +1591,10 @@ class TestGetDeploymentStatus(utils.TestCommand): self.cmd.take_action(parsed_args) expected = ( - '+-----------+-------------------+\n' - '| Plan Name | Deployment Status |\n' - '+-----------+-------------------+\n' - '| overcloud | DEPLOY_SUCCESS |\n' - '+-----------+-------------------+\n') + '+------------+-------------------+\n' + '| Stack Name | Deployment Status |\n' + '+------------+-------------------+\n' + '| overcloud | DEPLOY_SUCCESS |\n' + '+------------+-------------------+\n') self.assertEqual(expected, self.cmd.app.stdout.getvalue()) diff --git a/tripleoclient/tests/v1/test_overcloud_plan.py b/tripleoclient/tests/v1/test_overcloud_plan.py deleted file mode 100644 index 011f2e127..000000000 --- a/tripleoclient/tests/v1/test_overcloud_plan.py +++ /dev/null @@ -1,412 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -import mock - -from osc_lib.tests import utils - -from tripleoclient import constants -from tripleoclient import exceptions -from tripleoclient import plugin -from tripleoclient.tests import fakes -from tripleoclient.v1 import overcloud_plan - - -class TestStringCapture(object): - def __init__(self): - self.capture_string = '' - - def write(self, msg): - self.capture_string = self.capture_string + msg - - def getvalue(self): - return self.capture_string - - def flush(self): - return - - -class TestOvercloudPlanList(utils.TestCommand): - - def setUp(self): - super(TestOvercloudPlanList, self).setUp() - self.app.client_manager.tripleoclient = plugin.ClientWrapper( - instance=fakes.FakeInstanceData - ) - self.cmd = overcloud_plan.ListPlans(self.app, None) - - @mock.patch("tripleoclient.workflows.plan_management." - "list_deployment_plans", - autospec=True) - def test_list_empty(self, mock_list_plans): - mock_list_plans.return_value = [] - - result = self.cmd.take_action(None) - - self.assertEqual(0, len(result[1])) - - @mock.patch("tripleoclient.workflows.plan_management." - "list_deployment_plans", - autospec=True) - def test_list(self, mock_list_plans): - mock_list_plans.return_value = (['test-plan-1', 'test-plan-2']) - - result = self.cmd.take_action(None) - - self.assertEqual(1, len(result[0])) - self.assertEqual([('test-plan-1',), ('test-plan-2',)], result[1]) - - -class TestOvercloudDeletePlan(fakes.FakePlaybookExecution): - - def setUp(self): - super(TestOvercloudDeletePlan, self).setUp() - - self.cmd = overcloud_plan.DeletePlan(self.app, None) - - @mock.patch("tripleo_common.actions.plan.DeletePlanAction.run", - return_value=None) - def test_delete_plan(self, mock_run): - parsed_args = self.check_parser(self.cmd, ['test-plan'], - [('plans', ['test-plan'])]) - - self.cmd.take_action(parsed_args) - - @mock.patch("tripleo_common.actions.plan.DeletePlanAction.run", - return_value=None) - def test_delete_multiple_plans(self, mock_run): - argslist = ['test-plan1', 'test-plan2'] - verifylist = [('plans', ['test-plan1', 'test-plan2'])] - parsed_args = self.check_parser(self.cmd, argslist, verifylist) - - self.cmd.take_action(parsed_args) - - -class TestOvercloudCreatePlan(utils.TestCommand): - - def setUp(self): - super(TestOvercloudCreatePlan, self).setUp() - - app_args = mock.Mock() - app_args.verbose_level = 1 - self.app.options = fakes.FakeOptions() - self.cmd = overcloud_plan.CreatePlan(self.app, app_args) - self.app.client_manager.workflow_engine = mock.Mock() - self.tripleoclient = mock.Mock() - self.app.client_manager.tripleoclient = self.tripleoclient - - self.swift = self.app.client_manager.tripleoclient.object_store - self.swift.get_account = mock.MagicMock() - self.mock_tar = mock.patch( - 'tripleo_common.utils.tarball.create_tarball', - autospec=True - ) - self.mock_tar.start() - - def tearDown(self): - super(TestOvercloudCreatePlan, self).tearDown() - self.mock_tar.stop() - - @mock.patch("tripleoclient.utils.run_ansible_playbook", autospec=True) - @mock.patch('os.chdir', autospec=True) - @mock.patch('tempfile.mkdtemp', autospec=True) - def test_create_default_plan(self, mock_tmp, mock_cd, mock_run_playbook): - - # Setup - arglist = ['overcast'] - verifylist = [ - ('name', 'overcast'), - ('templates', None) - ] - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - - # Run - self.cmd.take_action(parsed_args) - - # Verify - mock_run_playbook.assert_called_with( - 'cli-create-deployment-plan.yaml', - 'undercloud,', - mock.ANY, - constants.ANSIBLE_TRIPLEO_PLAYBOOKS, - extra_vars={ - "container": "overcast", - "generate_passwords": True, - "use_default_templates": True, - "disable_image_params_prepare": False, - }, - verbosity=3, - ) - - @mock.patch("tripleoclient.utils.run_ansible_playbook", autospec=True) - @mock.patch('os.chdir', autospec=True) - @mock.patch('tempfile.mkdtemp', autospec=True) - def test_create_custom_plan(self, mock_tmp, mock_cd, - mock_run_playbook): - - # Setup - arglist = ['overcast', '--templates', '/fake/path'] - verifylist = [ - ('name', 'overcast'), - ('templates', '/fake/path') - ] - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - - # Run - self.cmd.take_action(parsed_args) - - # Verify - mock_run_playbook.assert_called_with( - 'cli-create-deployment-plan.yaml', - 'undercloud,', - mock.ANY, - constants.ANSIBLE_TRIPLEO_PLAYBOOKS, - extra_vars={ - "container": "overcast", - "generate_passwords": True, - "use_default_templates": False, - "disable_image_params_prepare": False, - }, - verbosity=3, - ) - self.swift.get_account.assert_called_once() - - @mock.patch("tripleoclient.utils.run_ansible_playbook", autospec=True) - @mock.patch('os.chdir', autospec=True) - @mock.patch('tempfile.mkdtemp', autospec=True) - def test_create_custom_plan_plan_environment_file( - self, mock_tmp, mock_cd, mock_run_playbook): - # Setup - arglist = ['overcast', '--templates', '/fake/path', - '-p', 'the_plan_environment.yaml'] - verifylist = [ - ('name', 'overcast'), - ('templates', '/fake/path'), - ('plan_environment_file', 'the_plan_environment.yaml') - ] - self.app.options = fakes.FakeOptions() - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - - mock_open = mock.mock_open() - # Run - with mock.patch('six.moves.builtins.open', mock_open): - self.cmd.take_action(parsed_args) - - mock_open.assert_has_calls( - [mock.call('the_plan_environment.yaml', 'rb')]) - - # Verify - mock_run_playbook.assert_called_with( - 'cli-create-deployment-plan.yaml', - 'undercloud,', - mock.ANY, - constants.ANSIBLE_TRIPLEO_PLAYBOOKS, - extra_vars={ - "container": "overcast", - "generate_passwords": True, - "plan_environment": "the_plan_environment.yaml", - "use_default_templates": False, - "disable_image_params_prepare": False, - }, - verbosity=3, - ) - self.swift.get_account.assert_called_once() - - @mock.patch("tripleoclient.utils.run_ansible_playbook", autospec=True) - @mock.patch('os.chdir', autospec=True) - @mock.patch('tempfile.mkdtemp', autospec=True) - def test_create_default_plan_with_password_gen_disabled( - self, mock_tmp, mock_cd, mock_run_playbook): - - # Setup - arglist = ['overcast', '--disable-password-generation', - '--disable-container-prepare'] - verifylist = [ - ('name', 'overcast'), - ('templates', None), - ('disable_password_generation', True), - ('disable_container_prepare', True) - ] - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - - # Run - self.app.options = fakes.FakeOptions() - self.cmd.take_action(parsed_args) - # Verify - mock_run_playbook.assert_called_with( - 'cli-create-deployment-plan.yaml', - 'undercloud,', - mock.ANY, - constants.ANSIBLE_TRIPLEO_PLAYBOOKS, - extra_vars={ - "container": "overcast", - "generate_passwords": False, - "use_default_templates": True, - "disable_image_params_prepare": True, - }, - verbosity=3, - ) - - @mock.patch("tripleoclient.utils.run_ansible_playbook", autospec=True) - @mock.patch('os.chdir', autospec=True) - @mock.patch('tempfile.mkdtemp', autospec=True) - def test_create_custom_plan_from_source_url( - self, mock_tmp, mock_cd, mock_run_playbook): - - # Setup - arglist = ['overcast', '--source-url', 'http://tripleo.org/templates'] - verifylist = [ - ('name', 'overcast'), - ('templates', None), - ('source_url', 'http://tripleo.org/templates') - ] - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - - # Run - self.cmd.take_action(parsed_args) - - # Verify - mock_run_playbook.assert_called_with( - 'cli-create-deployment-plan.yaml', - 'undercloud,', - mock.ANY, - constants.ANSIBLE_TRIPLEO_PLAYBOOKS, - extra_vars={ - "container": "overcast", - "generate_passwords": True, - "use_default_templates": False, - "source_url": "http://tripleo.org/templates", - "disable_image_params_prepare": False, - }, - verbosity=3, - ) - - -class TestOvercloudDeployPlan(utils.TestCommand): - - def setUp(self): - super(TestOvercloudDeployPlan, self).setUp() - - app_args = mock.Mock() - app_args.verbose_level = 1 - self.app.options = fakes.FakeOptions() - self.cmd = overcloud_plan.DeployPlan(self.app, app_args) - - sleep_patch = mock.patch('time.sleep') - self.addCleanup(sleep_patch.stop) - sleep_patch.start() - - @mock.patch("tripleoclient.utils.update_deployment_status", autospec=True) - @mock.patch("tripleoclient.utils.run_ansible_playbook", autospec=True) - @mock.patch('tripleoclient.utils.wait_for_stack_ready', autospec=True) - @mock.patch('os.chdir', autospec=True) - @mock.patch('tempfile.mkdtemp', autospec=True) - def test_overcloud_deploy_plan(self, mock_tmp, mock_cd, - mock_for_stack_ready, - mock_run_playbook, - mock_update_status): - - # Setup - arglist = ['--run-validations', 'overcast'] - verifylist = [ - ('name', 'overcast'), - ('run_validations', True), - ('timeout', 240) - ] - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - - self.orch = self.app.client_manager.orchestration = mock.Mock() - # No existing stack, this is a new deploy. - self.orch.stacks.get.return_value = None - - mock_for_stack_ready.return_value = True - - # Run - self.cmd.take_action(parsed_args) - - mock_run_playbook.assert_called_with( - 'cli-deploy-deployment-plan.yaml', - 'undercloud,', - mock.ANY, - constants.ANSIBLE_TRIPLEO_PLAYBOOKS, - timeout=240, - extra_vars={ - "container": "overcast", - "run_validations": True, - "skip_deploy_identifier": False, - }, - verbosity=3, - ) - mock_update_status.assert_called() - - -class TestOvercloudExportPlan(utils.TestCommand): - - def setUp(self): - super(TestOvercloudExportPlan, self).setUp() - self.cmd = overcloud_plan.ExportPlan(self.app, None) - self.app.client_manager = mock.Mock() - self.clients = self.app.client_manager - - # Mock urlopen - f = mock.Mock() - f.read.return_value = 'tarball contents' - urlopen_patcher = mock.patch('six.moves.urllib.request.urlopen', - return_value=f) - self.mock_urlopen = urlopen_patcher.start() - self.addCleanup(self.mock_urlopen.stop) - - @mock.patch( - 'tripleoclient.workflows.plan_management.export_deployment_plan', - autospec=True) - def test_export_plan(self, export_deployment_plan_mock): - parsed_args = self.check_parser(self.cmd, ['test-plan'], - [('plan', 'test-plan')]) - - export_deployment_plan_mock.return_value = 'http://fake-url.com' - - with mock.patch('six.moves.builtins.open', mock.mock_open()): - self.cmd.take_action(parsed_args) - - export_deployment_plan_mock.assert_called_once_with( - self.clients, 'test-plan') - - @mock.patch('os.path.exists') - def test_export_plan_outfile_exists(self, exists_mock): - parsed_args = self.check_parser(self.cmd, ['test-plan'], - [('plan', 'test-plan')]) - - exists_mock.return_value = True - - self.assertRaises(exceptions.PlanExportError, - self.cmd.take_action, parsed_args) - - @mock.patch( - 'tripleoclient.workflows.plan_management.export_deployment_plan', - autospec=True) - @mock.patch('os.path.exists') - def test_export_plan_outfile_exists_with_overwrite( - self, exists_mock, export_deployment_plan_mock): - arglist = ['-f', 'test-plan'] - verifylist = [ - ('plan', 'test-plan'), - ('force_overwrite', True) - ] - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - - exists_mock.return_value = True - export_deployment_plan_mock.return_value = 'http://fake-url.com' - - with mock.patch('six.moves.builtins.open', mock.mock_open()): - self.cmd.take_action(parsed_args) - - export_deployment_plan_mock.assert_called_once_with( - self.clients, 'test-plan') diff --git a/tripleoclient/tests/v1/test_overcloud_plan_roles.py b/tripleoclient/tests/v1/test_overcloud_plan_roles.py deleted file mode 100644 index bbab0ace1..000000000 --- a/tripleoclient/tests/v1/test_overcloud_plan_roles.py +++ /dev/null @@ -1,169 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import mock - -from osc_lib import exceptions -from osc_lib.tests import utils - -from tripleoclient.v1 import overcloud_plan_roles - - -class BaseTestCommand(utils.TestCommand): - def setUp(self): - super(BaseTestCommand, self).setUp() - - tc = self.app.client_manager.tripleoclient = mock.Mock() - tc.object_store.get_object.return_value = ( - {}, - '{"result": [{"name":"Controller","description":"Test desc",' - '"random": "abcd"},{"name":"Test"}]}' - ) - tc.object_store.get_container.return_value = ( - 'container', - [ - { - "name": "Controller", - "description": "Test desc", - "random": "abcd", - "efg": "123", - "ServicesDefault": [ - "b", - "c", - "a" - ] - } - ] - ) - self.tripleoclient = tc - - -class TestOvercloudListCurrentRoles(BaseTestCommand): - - def setUp(self): - super(TestOvercloudListCurrentRoles, self).setUp() - - self.cmd = overcloud_plan_roles.ListRoles(self.app, None) - - @mock.patch( - 'tripleo_common.actions.plan.ListRolesAction.run', - autospec=True, - return_value=[] - ) - def test_list_empty_on_non_default_plan(self, mock_list): - arglist = ['--name', 'overcast', '--current'] - verifylist = [('name', 'overcast'), ('current', True)] - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - result = self.cmd.take_action(parsed_args) - self.assertEqual(0, len(result[1])) - - @mock.patch( - 'tripleo_common.actions.plan.ListRolesAction.run', - autospec=True, - return_value=["ObjectStorage", "Controller"] - ) - def test_list(self, mock_list): - arglist = ['--current'] - verifylist = [('name', 'overcloud'), ('current', True)] - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - result = self.cmd.take_action(parsed_args) - self.assertEqual(2, len(result[1])) - self.assertEqual([('Controller',), ('ObjectStorage',)], result[1]) - - @mock.patch( - 'tripleo_common.actions.plan.ListRolesAction.run', - autospec=True, - return_value=[ - { - "name": "Controller", - "description": "Test desc", - "random": "abcd" - }, - {"name": "Test"} - ] - ) - def test_list_with_details(self, mock_list): - parsed_args = self.check_parser(self.cmd, - ['--current', '--detail'], - []) - result = self.cmd.take_action(parsed_args) - - data = result[1] - self.assertEqual(2, len(data)) - - self.assertEqual(data[0][0], "Controller") - self.assertEqual(data[0][3], "random: abcd") - self.assertEqual(data[1][0], "Test") - self.assertEqual(data[1][3], "") - - @mock.patch( - 'tripleo_common.actions.plan.ListRolesAction.run', - autospec=True, - return_value=[] - ) - def test_list_with_details_empty(self, mock_list): - parsed_args = self.check_parser(self.cmd, - ['--current', '--detail'], - []) - result = self.cmd.take_action(parsed_args) - - self.assertEqual(0, len(result[1])) - - @mock.patch( - 'tripleo_common.actions.plan.ListRolesAction.run', - autospec=True, - return_value=[ - {"name": "Compute"}, - {"name": "Random"}, - {"name": "BlockStorage", "ServicesDefault": ["c", "b", "a"]} - ] - ) - def test_list_with_details_sorted(self, mock_list): - - parsed_args = self.check_parser(self.cmd, - ['--current', '--detail'], - []) - result = self.cmd.take_action(parsed_args) - - self.assertEqual(3, len(result[1])) - - # Test main list sorted - self.assertEqual(result[1][0][0], "BlockStorage") - self.assertEqual(result[1][1][0], "Compute") - self.assertEqual(result[1][2][0], "Random") - - # Test service sublist sorted - self.assertEqual(result[1][0][2], "a\nb\nc") - - -class TestOvercloudShowRole(BaseTestCommand): - - def setUp(self): - super(TestOvercloudShowRole, self).setUp() - - self.cmd = overcloud_plan_roles.ShowRole(self.app, None) - - self.app.client_manager.tripleoclient = self.tripleoclient - - @mock.patch( - 'tripleo_common.actions.plan.ListRolesAction.run', - autospec=True, - return_value=[] - ) - def test_role_not_found(self, mock_list): - arglist = ['--name', 'overcast', 'doesntexist'] - verifylist = [('name', 'overcast'), ('role', 'doesntexist')] - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - - self.assertRaises(exceptions.CommandError, - self.cmd.take_action, - parsed_args) diff --git a/tripleoclient/tests/workflows/test_parameters.py b/tripleoclient/tests/workflows/test_parameters.py index 5c810013b..bbbcd8933 100644 --- a/tripleoclient/tests/workflows/test_parameters.py +++ b/tripleoclient/tests/workflows/test_parameters.py @@ -174,46 +174,6 @@ class TestParameterWorkflows(utils.TestCommand): ] mock_playbook.assert_has_calls(calls, any_order=True) - def test_check_deprecated_params_no_output(self): - parameters.check_deprecated_parameters( - self.app.client_manager, - container='container-name') - - def test_check_deprecated_params_user_defined(self): - with mock.patch('tripleoclient.workflows.parameters.LOG') as mock_log: - parameters.check_deprecated_parameters( - self.app.client_manager, - container='container-name') - self.assertTrue(mock_log.warning.called) - - def test_check_deprecated_params_user_not_defined(self): - with mock.patch('tripleoclient.workflows.parameters.LOG') as mock_log: - parameters.check_deprecated_parameters( - self.app.client_manager, - container='container-name') - self.assertFalse(mock_log.log.warning.called) - - def test_check_deprecated_multiple_parameters(self): - with mock.patch('tripleoclient.workflows.parameters.LOG') as mock_log: - parameters.check_deprecated_parameters( - self.app.client_manager, - container='container-name') - self.assertTrue(mock_log.warning.called) - - def test_check_unused_multiple_parameters(self): - with mock.patch('tripleoclient.workflows.parameters.LOG') as mock_log: - parameters.check_deprecated_parameters( - self.app.client_manager, - container='container-name') - self.assertTrue(mock_log.warning.called) - - def test_check_invalid_role_specific_parameters(self): - with mock.patch('tripleoclient.workflows.parameters.LOG') as mock_log: - parameters.check_deprecated_parameters( - self.app.client_manager, - container='container-name') - self.assertTrue(mock_log.warning.called) - @mock.patch( 'tripleo_common.utils.stack_parameters.generate_fencing_parameters', return_value={}) diff --git a/tripleoclient/tests/workflows/test_plan_management.py b/tripleoclient/tests/workflows/test_plan_management.py deleted file mode 100644 index c50eb992f..000000000 --- a/tripleoclient/tests/workflows/test_plan_management.py +++ /dev/null @@ -1,397 +0,0 @@ -# -*- coding: utf-8 -*- - -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -import mock - -from osc_lib.tests import utils - -from tripleoclient import constants -from tripleoclient.tests import base -from tripleoclient.workflows import plan_management - - -class TestPlanCreationWorkflows(utils.TestCommand): - - def setUp(self): - super(TestPlanCreationWorkflows, self).setUp() - self.tripleoclient = mock.Mock() - self.app.client_manager.tripleoclient = self.tripleoclient - self.tripleoclient.object_store.get_account = mock.MagicMock() - self.mock_tar = mock.patch( - 'tripleo_common.utils.tarball.create_tarball', - autospec=True - ) - self.mock_tar.start() - - def tearDown(self): - super(TestPlanCreationWorkflows, self).tearDown() - self.mock_tar.stop() - - @mock.patch("tripleoclient.utils.run_ansible_playbook", autospec=True) - @mock.patch('os.chdir', autospec=True) - @mock.patch('tempfile.mkdtemp', autospec=True) - def test_create_plan_from_templates_success(self, mock_tmp, mock_cd, - mock_run_playbook): - plan_management.create_plan_from_templates( - self.app.client_manager, - 'test-overcloud', - '/tht-root/') - - mock_run_playbook.assert_called_with( - 'cli-create-deployment-plan.yaml', - 'undercloud,', - mock.ANY, - constants.ANSIBLE_TRIPLEO_PLAYBOOKS, - extra_vars={ - "container": "test-overcloud", - "generate_passwords": True, - "use_default_templates": False, - "disable_image_params_prepare": False, - }, - verbosity=0, - ) - - @mock.patch("tripleoclient.utils.run_ansible_playbook", autospec=True) - @mock.patch('tripleoclient.utils.rel_or_abs_path') - @mock.patch('os.chdir', autospec=True) - @mock.patch('tempfile.mkdtemp', autospec=True) - def test_create_plan_from_templates_roles_data(self, mock_tmp, mock_cd, - mock_norm_path, - mock_run_playbook): - mock_open_context = mock.mock_open() - with mock.patch('six.moves.builtins.open', mock_open_context): - plan_management.create_plan_from_templates( - self.app.client_manager, - 'test-overcloud', - '/tht-root/', - 'the_roles_file.yaml') - - mock_run_playbook.assert_called_with( - 'cli-create-deployment-plan.yaml', - 'undercloud,', - mock.ANY, - constants.ANSIBLE_TRIPLEO_PLAYBOOKS, - extra_vars={ - "container": "test-overcloud", - "generate_passwords": True, - "use_default_templates": False, - "disable_image_params_prepare": False, - }, - verbosity=0, - ) - - self.assertIn(mock.call('the_roles_file.yaml', '/tht-root/'), - mock_norm_path.call_args_list) - - self.tripleoclient.object_store.put_object.assert_called_with( - 'test-overcloud', 'roles_data.yaml', mock_open_context()) - - @mock.patch("tripleoclient.utils.run_ansible_playbook", autospec=True) - @mock.patch('os.chdir', autospec=True) - @mock.patch('tempfile.mkdtemp', autospec=True) - def test_create_plan_from_templates_plan_env_data(self, mock_tmp, mock_cd, - mock_run_playbook): - mock_open_context = mock.mock_open() - with mock.patch('six.moves.builtins.open', mock_open_context): - plan_management.create_plan_from_templates( - self.app.client_manager, - 'test-overcloud', - '/tht-root/', - plan_env_file='the-plan-environment.yaml') - - mock_run_playbook.assert_called_with( - 'cli-create-deployment-plan.yaml', - 'undercloud,', - mock.ANY, - constants.ANSIBLE_TRIPLEO_PLAYBOOKS, - extra_vars={ - "container": "test-overcloud", - "generate_passwords": True, - "plan_environment": "the-plan-environment.yaml", - "use_default_templates": False, - "disable_image_params_prepare": False, - }, - verbosity=0, - ) - mock_open_context.assert_has_calls( - [mock.call('the-plan-environment.yaml', 'rb')]) - - self.tripleoclient.object_store.put_object.assert_called_with( - 'test-overcloud', 'plan-environment.yaml', mock_open_context()) - - @mock.patch("tripleoclient.utils.run_ansible_playbook", autospec=True) - @mock.patch('os.chdir', autospec=True) - @mock.patch('tempfile.mkdtemp', autospec=True) - def test_create_plan_from_templates_networks_data(self, mock_tmp, mock_cd, - mock_run_playbook): - mock_open_context = mock.mock_open() - with mock.patch('six.moves.builtins.open', mock_open_context): - plan_management.create_plan_from_templates( - self.app.client_manager, - 'test-overcloud', - '/tht-root/', - networks_file='the-network-data.yaml') - - mock_run_playbook.assert_called_with( - 'cli-create-deployment-plan.yaml', - 'undercloud,', - mock.ANY, - constants.ANSIBLE_TRIPLEO_PLAYBOOKS, - extra_vars={ - "container": "test-overcloud", - "generate_passwords": True, - "use_default_templates": False, - "disable_image_params_prepare": False, - }, - verbosity=0, - ) - mock_open_context.assert_has_calls( - [mock.call('the-network-data.yaml', 'rb')]) - - self.tripleoclient.object_store.put_object.assert_called_with( - 'test-overcloud', 'network_data.yaml', mock_open_context()) - - @mock.patch("tripleoclient.utils.run_ansible_playbook", autospec=True) - @mock.patch('os.chdir', autospec=True) - @mock.patch('tempfile.mkdtemp', autospec=True) - def test_create_plan_with_password_gen_disabled(self, mock_tmp, mock_cd, - mock_run_playbook): - plan_management.create_plan_from_templates( - self.app.client_manager, - 'test-overcloud', - '/tht-root/', - generate_passwords=False, - disable_image_params_prepare=True) - - mock_run_playbook.assert_called_with( - 'cli-create-deployment-plan.yaml', - 'undercloud,', - mock.ANY, - constants.ANSIBLE_TRIPLEO_PLAYBOOKS, - extra_vars={ - "container": "test-overcloud", - "generate_passwords": False, - "use_default_templates": False, - "disable_image_params_prepare": True, - }, - verbosity=0, - ) - - -class TestPlanUpdateWorkflows(base.TestCommand): - - def setUp(self): - super(TestPlanUpdateWorkflows, self).setUp() - self.app.client_manager.tripleoclient = self.tripleoclient = \ - mock.Mock() - self.tripleoclient.object_store = self.object_store = mock.Mock() - - self.object_store.get_container.return_value = ( - {}, - [ - {'name': 'plan-environment.yaml'}, - {'name': 'user-environment.yaml'}, - {'name': 'roles_data.yaml'}, - {'name': 'network_data.yaml'}, - {'name': 'user-files/somecustomfile.yaml'}, - {'name': 'user-files/othercustomfile.yaml'}, - {'name': 'this-should-not-be-persisted.yaml'}, - ] - ) - - def get_object(*args, **kwargs): - if args[0] != 'test-overcloud': - raise RuntimeError('Unexpected container') - if args[1] == 'plan-environment.yaml': - return {}, ('passwords: somepasswords\n' - 'plan-environment.yaml: mock content\n') - # Generic return valuebased on param, - # e.g. 'plan-environment.yaml: mock content' - return {}, '{0}: mock content\n'.format(args[1]) - self.object_store.get_object.side_effect = get_object - self.mock_tar = mock.patch( - 'tripleo_common.utils.tarball.create_tarball', - autospec=True - ) - self.mock_tar.start() - - def tearDown(self): - super(TestPlanUpdateWorkflows, self).tearDown() - self.mock_tar.stop() - - @mock.patch("tripleoclient.utils.run_ansible_playbook", autospec=True) - @mock.patch('tripleo_common.utils.swift.empty_container', - autospec=True) - @mock.patch('os.chdir', autospec=True) - @mock.patch('tempfile.mkdtemp', autospec=True) - def test_update_plan_from_templates_keep_env( - self, mock_tmp, mock_cd, mock_empty_container, - mock_run_playbook): - - plan_management.update_plan_from_templates( - self.app.client_manager, - 'test-overcloud', - '/tht-root/', - keep_env=True) - - mock_empty_container.assert_called_once_with( - self.object_store, 'test-overcloud') - - # make sure we're pushing the saved files back to plan - self.object_store.put_object.assert_has_calls( - [ - mock.call('test-overcloud', 'plan-environment.yaml', - 'passwords: somepasswords\n' - 'plan-environment.yaml: mock content\n'), - mock.call('test-overcloud', 'user-environment.yaml', - 'user-environment.yaml: mock content\n'), - mock.call('test-overcloud', 'roles_data.yaml', - 'roles_data.yaml: mock content\n'), - mock.call('test-overcloud', 'network_data.yaml', - 'network_data.yaml: mock content\n'), - mock.call('test-overcloud', 'user-files/somecustomfile.yaml', - 'user-files/somecustomfile.yaml: mock content\n'), - mock.call('test-overcloud', 'user-files/othercustomfile.yaml', - 'user-files/othercustomfile.yaml: mock content\n'), - ], - any_order=True, - ) - mock_run_playbook.assert_called_with( - 'cli-update-deployment-plan.yaml', - 'undercloud,', - mock.ANY, - constants.ANSIBLE_TRIPLEO_PLAYBOOKS, - extra_vars={ - "container": "test-overcloud", - "generate_passwords": True, - "disable_image_params_prepare": False, - }, - verbosity=1, - ) - - @mock.patch("tripleoclient.utils.run_ansible_playbook", autospec=True) - @mock.patch('tripleo_common.utils.swift.empty_container', - autospec=True) - def test_update_plan_from_templates_recreate_env( - self, mock_empty_container, mock_run_playbook): - - plan_management.update_plan_from_templates( - self.app.client_manager, - 'test-overcloud', - '/tht-root/') - - mock_empty_container.assert_called_once_with( - self.object_store, 'test-overcloud') - - # make sure passwords got persisted - self.object_store.put_object.assert_called_with( - 'test-overcloud', 'plan-environment.yaml', - 'passwords: somepasswords\n' - 'plan-environment.yaml: mock content\n' - ) - - mock_run_playbook.assert_called_with( - 'cli-update-deployment-plan.yaml', - 'undercloud,', - mock.ANY, - constants.ANSIBLE_TRIPLEO_PLAYBOOKS, - extra_vars={ - "container": "test-overcloud", - "generate_passwords": True, - "disable_image_params_prepare": False, - }, - verbosity=1, - ) - - @mock.patch("tripleoclient.utils.run_ansible_playbook", autospec=True) - @mock.patch('tripleoclient.workflows.plan_management._update_passwords', - autospec=True) - @mock.patch('yaml.safe_load', - autospec=True) - @mock.patch('tripleo_common.utils.swift.empty_container', - autospec=True) - @mock.patch('os.chdir', autospec=True) - @mock.patch('tempfile.mkdtemp', autospec=True) - def test_update_plan_from_templates_recreate_env_missing_passwords( - self, mock_tmp, mock_cd, mock_empty_container, - mock_yaml_safe_load, mock_update_passwords, mock_run_playbook): - plan_management.update_plan_from_templates( - self.app.client_manager, - 'test-overcloud', - '/tht-root/', - disable_image_params_prepare=True) - # A dictionary without the "passwords" key is provided in - # the _load_passwords method. - mock_yaml_safe_load.return_value = {} - # Ensure that the passwords variable is passed with a value of None. - mock_update_passwords.assert_called_with( - mock.ANY, 'test-overcloud', None) - mock_run_playbook.assert_called_with( - 'cli-update-deployment-plan.yaml', - 'undercloud,', - mock.ANY, - constants.ANSIBLE_TRIPLEO_PLAYBOOKS, - extra_vars={ - "container": "test-overcloud", - "generate_passwords": True, - "disable_image_params_prepare": True, - }, - verbosity=1, - ) - - -class TestUpdatePasswords(base.TestCase): - - YAML_CONTENTS = """version: 1.0 -name: overcloud -template: overcloud.yaml -parameter_defaults: - ControllerCount: 7 -""" - - def setUp(self): - super(TestUpdatePasswords, self).setUp() - self.swift_client = mock.MagicMock() - self.swift_client.get_object.return_value = ({}, self.YAML_CONTENTS) - - self.plan_name = "overcast" - - def test_update_passwords(self): - plan_management._update_passwords(self.swift_client, - self.plan_name, - {'AdminPassword': "1234"}) - - result = self.swift_client.put_object.call_args_list[0][0][2] - - # Check new data is in - self.assertIn("passwords:\n", result) - self.assertIn("\n AdminPassword: '1234'", result) - # Check previous data still is too - self.assertIn("name: overcloud", result) - - def test_no_passwords(self): - plan_management._update_passwords(self.swift_client, - self.plan_name, - []) - - self.swift_client.put_object.assert_not_called() - - def test_no_plan_environment(self): - self.swift_client.get_object.side_effect = ( - Exception("404")) - - plan_management._update_passwords(self.swift_client, - self.plan_name, - {'SecretPassword': 'abcd'}) - - self.swift_client.put_object.assert_not_called() diff --git a/tripleoclient/v1/overcloud_deploy.py b/tripleoclient/v1/overcloud_deploy.py index 017c69571..c9b04c186 100644 --- a/tripleoclient/v1/overcloud_deploy.py +++ b/tripleoclient/v1/overcloud_deploy.py @@ -280,9 +280,6 @@ class DeployOvercloud(command.Command): template_file=template_path) files = dict(list(template_files.items()) + list(env_files.items())) - # Fix if required - # 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_without_plan( @@ -1081,18 +1078,18 @@ class GetDeploymentStatus(command.Command): def take_action(self, parsed_args): self.log.debug("take_action(%s)" % parsed_args) - plan = parsed_args.plan + stack = parsed_args.plan status = deployment.get_deployment_status( self.app.client_manager, - plan + stack ) if not status: - self.log.info('No deployment was found for %s' % plan) + self.log.info('No deployment was found for %s' % stack) return table = PrettyTable( - ['Plan Name', 'Deployment Status']) - table.add_row([plan, status]) + ['Stack Name', 'Deployment Status']) + table.add_row([stack, status]) print(table, file=self.app.stdout) diff --git a/tripleoclient/v1/overcloud_plan.py b/tripleoclient/v1/overcloud_plan.py deleted file mode 100644 index d3fffd13d..000000000 --- a/tripleoclient/v1/overcloud_plan.py +++ /dev/null @@ -1,227 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import logging -import os.path - -from osc_lib.i18n import _ -from six.moves.urllib import request - -from tripleoclient import command -from tripleoclient import constants -from tripleoclient import exceptions -from tripleoclient import utils -from tripleoclient.workflows import deployment -from tripleoclient.workflows import plan_management - - -class ListPlans(command.Lister): - """List overcloud deployment plans.""" - - log = logging.getLogger(__name__ + ".ListPlans") - - def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) - - clients = self.app.client_manager - - plans = plan_management.list_deployment_plans(clients) - - result = [] - for r in plans: - result.append((r,)) - - return (("Plan Name",), result) - - -class DeletePlan(command.Command): - """Delete an overcloud deployment plan. - - The plan will not be deleted if a stack exists with the same name. - """ - - log = logging.getLogger(__name__ + ".DeletePlan") - - def get_parser(self, prog_name): - parser = super(DeletePlan, self).get_parser(prog_name) - parser.add_argument('plans', metavar='', nargs="+", - help=_('Name of the plan(s) to delete')) - return parser - - def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) - - clients = self.app.client_manager - - for plan in parsed_args.plans: - print("Deleting plan %s..." % plan) - plan_management.delete_deployment_plan(clients, - container=plan) - - -class CreatePlan(command.Command): - """Create a deployment plan""" - - log = logging.getLogger(__name__ + ".CreatePlan") - - def get_parser(self, prog_name): - parser = super(CreatePlan, self).get_parser(prog_name) - source_group = parser.add_mutually_exclusive_group() - parser.add_argument( - 'name', - help=_('The name of the plan, which is used for the object ' - 'storage container, workflow environment and orchestration ' - 'stack names.')) - source_group.add_argument( - '--templates', - help=_('The directory containing the Heat templates to deploy. ' - 'If this or --source_url isn\'t provided, the templates ' - 'packaged on the Undercloud will be used.'), - ) - parser.add_argument( - '--plan-environment-file', '-p', - help=_('Plan Environment file, overrides the default %s in the ' - '--templates directory') % constants.PLAN_ENVIRONMENT - ) - parser.add_argument( - '--disable-password-generation', - action='store_true', - default=False, - help=_('Disable password generation.') - ) - source_group.add_argument( - '--source-url', - help=_('The url of a git repository containing the Heat templates ' - 'to deploy. If this or --templates isn\'t provided, the ' - 'templates packaged on the Undercloud will be used.') - ) - parser.add_argument( - '--disable-container-prepare', - action='store_true', - default=False, - help=_('Disable the container preparation actions to prevent ' - 'container tags from being updated and new containers ' - 'from being fetched. If you skip this but do not have ' - 'the container parameters configured, the deployment ' - 'action may fail.') - ) - return parser - - def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) - clients = self.app.client_manager - - name = parsed_args.name - use_default_templates = False - generate_passwords = not parsed_args.disable_password_generation - source_url = parsed_args.source_url - # if the templates and source_url params are not used, then - # use the default templates - if not parsed_args.templates and not parsed_args.source_url: - use_default_templates = True - - # Needs this to avoid too long lines - disable_container_prepare = parsed_args.disable_container_prepare - - if parsed_args.templates: - plan_management.create_plan_from_templates( - clients, name, parsed_args.templates, - generate_passwords=generate_passwords, - plan_env_file=parsed_args.plan_environment_file, - verbosity_level=utils.playbook_verbosity(self=self), - disable_image_params_prepare=disable_container_prepare - ) - else: - plan_management.create_deployment_plan( - container=name, - generate_passwords=generate_passwords, - source_url=source_url, - use_default_templates=use_default_templates, - verbosity_level=utils.playbook_verbosity(self=self), - disable_image_params_prepare=disable_container_prepare - ) - - -class DeployPlan(command.Command): - """Deploy a deployment plan""" - - log = logging.getLogger(__name__ + ".DeployPlan") - - def get_parser(self, prog_name): - parser = super(DeployPlan, self).get_parser(prog_name) - parser.add_argument('name', help=_('The name of the plan to deploy.')) - parser.add_argument('--timeout', '-t', metavar='', - type=int, default=240, - help=_('Deployment timeout in minutes.')) - parser.add_argument('--run-validations', action='store_true', - default=False, - help=_('Run the pre-deployment validations. These ' - 'external validations are from the TripleO ' - 'Validations project.')) - return parser - - def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) - - clients = self.app.client_manager - orchestration_client = clients.orchestration - stack = utils.get_stack(orchestration_client, parsed_args.name) - - print("Starting to deploy plan: {}".format(parsed_args.name)) - deployment.deploy_and_wait( - log=self.log, - clients=clients, - stack=stack, - plan_name=parsed_args.name, - verbose_level=utils.playbook_verbosity(self=self), - timeout=parsed_args.timeout, - run_validations=parsed_args.run_validations, - ) - - -class ExportPlan(command.Command): - """Export a deployment plan""" - - log = logging.getLogger(__name__ + ".ExportPlan") - - def get_parser(self, prog_name): - parser = super(ExportPlan, self).get_parser(prog_name) - parser.add_argument('plan', metavar='', - help=_('Name of the plan to export.')) - parser.add_argument('--output-file', '-o', metavar='', - help=_('Name of the output file for export. ' - 'It will default to ".tar.gz".')) - parser.add_argument('--force-overwrite', '-f', action='store_true', - default=False, - help=_('Overwrite output file if it exists.')) - return parser - - def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) - plan = parsed_args.plan - outfile = parsed_args.output_file or '%s.tar.gz' % plan - - if os.path.exists(outfile) and not parsed_args.force_overwrite: - raise exceptions.PlanExportError( - "File '%s' already exists, not exporting." % outfile) - - print("Exporting plan %s..." % plan) - - tempurl = plan_management.export_deployment_plan( - self.app.client_manager, plan - ) - f = request.urlopen(tempurl) - tarball_contents = f.read() - f.close() - - with open(outfile, 'wb') as f: - f.write(tarball_contents) diff --git a/tripleoclient/v1/overcloud_plan_roles.py b/tripleoclient/v1/overcloud_plan_roles.py deleted file mode 100644 index dfb087e30..000000000 --- a/tripleoclient/v1/overcloud_plan_roles.py +++ /dev/null @@ -1,158 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import logging - -from osc_lib.command import command -from osc_lib import exceptions -from osc_lib.i18n import _ - -from tripleoclient.workflows import roles - - -class ListRoles(command.Lister): - """List the current and available roles in a given plan""" - - log = logging.getLogger(__name__ + ".ListRoles") - - def get_parser(self, prog_name): - parser = super(ListRoles, self).get_parser(prog_name) - parser.add_argument( - '--name', - dest='name', - default='overcloud', - help=_('The name of the plan, which is used for the object ' - 'storage container, workflow environment and orchestration ' - 'stack names.'), - ) - parser.add_argument( - '--detail', - action='store_true', - help=_('Include details about each role')) - parser.add_argument( - '--current', - action='store_true', - help=_('Only show the information for the roles currently enabled ' - 'for the plan.')) - return parser - - def take_action(self, parsed_args): - self.log.debug('take_action({})'.format(parsed_args)) - - if parsed_args.current: - result = roles.list_roles( - self.app.client_manager, - container=parsed_args.name, - detail=parsed_args.detail) - else: - result = roles.list_available_roles( - self.app.client_manager, - container=parsed_args.name) - # The workflow returns all the details by default, trim - # them down if not required. - if not parsed_args.detail: - result = [r['name'] for r in result] - - if parsed_args.detail: - if result: - result.sort(key=lambda r: r['name']) - - role_list = self.format_role_details(result) - column_names = ("Role Name", - "Description", - "Services Default", - "Other Details") - return (column_names, role_list) - else: - if result: - result.sort() - return (("Role Name",), [(r,) for r in result]) - - def format_role_details(self, result): - role_list = [] - for r in result: - name = r.pop('name') - description = service_defaults = '' - detail = [] - - if 'description' in r: - description = r.pop('description') - if 'ServicesDefault' in r: - r['ServicesDefault'].sort() - service_defaults = '\n'.join(r.pop('ServicesDefault')) - for k, v in r.items(): - detail.append("%s: %s" % (k, v)) - - role_list.append((name, description, service_defaults, - '\n'.join(detail))) - return role_list - - -class ShowRole(command.ShowOne): - """Show details for a specific role, given a plan""" - - log = logging.getLogger(__name__ + ".ShowRole") - - def get_parser(self, prog_name): - parser = super(ShowRole, self).get_parser(prog_name) - parser.add_argument( - '--name', - dest='name', - default='overcloud', - help=_('The name of the plan, which is used for the object ' - 'storage container, workflow environment and orchestration ' - 'stack names.'), - ) - parser.add_argument('role', - metavar="", - help=_('Name of the role to look up.')) - return parser - - def take_action(self, parsed_args): - self.log.debug('take_action({})'.format(parsed_args)) - - role = self.get_role_details(parsed_args.name, parsed_args.role) - if not role: - raise exceptions.CommandError( - "Could not find role %s" % parsed_args.role) - - return self.format_role(role) - - def get_role_details(self, name, role_name): - result = roles.list_available_roles( - self.app.client_manager, - container=name) - - for r in result: - if r['name'] == role_name: - return r - return [] - - def format_role(self, role): - column_names = ['Name'] - data = [role.pop('name')] - - if 'description' in role: - column_names.append('Description') - data.append(role.pop('description')) - if 'ServicesDefault' in role: - column_names.append('Services Default') - role['ServicesDefault'].sort() - data.append('\n'.join(role.pop('ServicesDefault'))) - - other_fields = list(role.keys()) - other_fields.sort() - for field in other_fields: - column_names.append(field) - data.append(role[field]) - - return column_names, data diff --git a/tripleoclient/workflows/deployment.py b/tripleoclient/workflows/deployment.py index 3d63000d9..de9385305 100644 --- a/tripleoclient/workflows/deployment.py +++ b/tripleoclient/workflows/deployment.py @@ -30,96 +30,6 @@ from tripleoclient import utils _WORKFLOW_TIMEOUT = 360 # 6 * 60 seconds -def deploy(container, run_validations, skip_deploy_identifier, - timeout, verbosity=0): - """Run the deployment playbook. - - :param container: Name of the container - :type container: String - - :param run_validations: Enable or disable validations - :type run_validations: Boolean - - :param skip_deploy_identifier: Enable or disable validations - :type skip_deploy_identifier: Boolean - - :param timeout: Deployment timeout (minutes). - :type timeout: Integer - - :param verbosity: Verbosity level - :type verbosity: Integer - """ - with utils.TempDirs() as tmp: - utils.run_ansible_playbook( - "cli-deploy-deployment-plan.yaml", - 'undercloud,', - workdir=tmp, - playbook_dir=ANSIBLE_TRIPLEO_PLAYBOOKS, - verbosity=verbosity, - timeout=timeout, - extra_vars={ - "container": container, - "run_validations": run_validations, - "skip_deploy_identifier": skip_deploy_identifier, - } - ) - - print("Success.") - - -def deploy_and_wait(log, clients, stack, plan_name, verbose_level, - timeout=None, run_validations=False, - skip_deploy_identifier=False, deployment_options={}): - """Start the deploy and wait for it to finish""" - - 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=plan_name, - event_args={'sort_dir': 'desc', - 'limit': 1}) - marker = events[0].id if events else None - action = 'UPDATE' - - set_deployment_status(plan_name, - status='DEPLOYING') - - try: - deploy( - container=plan_name, - run_validations=run_validations, - skip_deploy_identifier=skip_deploy_identifier, - timeout=timeout, - verbosity=verbose_level) - except Exception: - set_deployment_status(plan_name, - status='DEPLOY_FAILED') - raise - - # TODO(rabi) Simplify call to get events as we don't need to wait - # for stack to be ready anymore i.e just get the events. - create_result = utils.wait_for_stack_ready( - orchestration_client, plan_name, marker, action) - if not create_result: - shell.OpenStackShell().run(["stack", "failures", "list", plan_name]) - set_deployment_status( - plan_name, - status='DEPLOY_FAILED' - ) - if stack is None: - raise exceptions.DeploymentError("Heat Stack create failed.") - else: - raise exceptions.DeploymentError("Heat Stack update failed.") - - def create_overcloudrc(stack, rc_params, no_proxy='', output_dir=CLOUD_HOME_DIR): overcloudrcs = rc_utils._create_overcloudrc( diff --git a/tripleoclient/workflows/parameters.py b/tripleoclient/workflows/parameters.py index abde133b3..83cc02533 100644 --- a/tripleoclient/workflows/parameters.py +++ b/tripleoclient/workflows/parameters.py @@ -12,7 +12,6 @@ import logging import os -import re import yaml from heatclient.common import template_utils @@ -20,7 +19,6 @@ 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 from tripleoclient.workflows import roles @@ -111,118 +109,6 @@ def build_derived_params_environment(clients, stack_name, ) -def check_deprecated_parameters(clients, container): - """Checks for deprecated parameters in plan and adds warning if present. - - :param clients: application client object. - :type clients: Object - - :param container: Name of the stack container. - :type container: String - """ - role_name_list = roles.list_available_roles( - clients=clients, - container=container - ) - flattened_parms = stk_parameters.get_flattened_parameters( - clients.tripleoclient.object_store, - clients.orchestration, container=container) - user_params = flattened_parms.get('environment_parameters', {}) - heat_resource_tree = flattened_parms.get('heat_resource_tree', {}) - heat_resource_tree_params = heat_resource_tree.get('parameters', {}) - heat_resource_tree_resources = heat_resource_tree.get('resources', {}) - plan_params = heat_resource_tree_params.keys() - parameter_groups = [ - i.get('parameter_groups') - for i in heat_resource_tree_resources.values() - if i.get('parameter_groups') - ] - params_role_specific_tag = [ - i.get('name') - for i in heat_resource_tree_params.values() - if 'tags' in i and 'role_specific' in i['tags'] - ] - - r = re.compile(".*Count") - filtered_names = list(filter(r.match, plan_params)) - valid_role_name_list = list() - for name in filtered_names: - default = heat_resource_tree_params[name].get('default', 0) - if default and int(default) > 0: - role_name = name.rstrip('Count') - if [i for i in role_name_list if i.get('name') == role_name]: - valid_role_name_list.append(role_name) - - deprecated_params = [ - i[0] for i in parameter_groups - if i[0].get('label') == 'deprecated' - ] - # We are setting a frozenset here because python 3 complains that dict is - # a unhashable type. - # On user_defined, we check if the size is higher than 0 because an empty - # frozenset still is a subset of a frozenset, so we can't use issubset - # here. - user_params_keys = frozenset(user_params.keys()) - deprecated_result = [ - { - 'parameter': i, - 'deprecated': True, - 'user_defined': len( - [x for x in frozenset(i) if x in user_params_keys]) > 0 - } - for i in deprecated_params - ] - unused_params = [i for i in user_params.keys() if i not in plan_params] - user_provided_role_specific = [ - v for i in role_name_list - for k, v in user_params.items() - if k in i - ] - invalid_role_specific_params = [ - i for i in user_provided_role_specific - if i in params_role_specific_tag - ] - deprecated_parameters = [ - param['parameter'] for param in deprecated_result - if param.get('user_defined') - ] - - if deprecated_parameters: - deprecated_join = ', '.join(deprecated_parameters) - LOG.warning( - 'WARNING: Following parameter(s) are deprecated and still ' - 'defined. Deprecated parameters will be removed soon!' - ' {deprecated_join}'.format( - deprecated_join=deprecated_join - ) - ) - - # exclude our known params that may not be used - ignore_re = re.compile('|'.join(UNUSED_PARAMETER_EXCLUDES_RE)) - unused_params = [p for p in unused_params if not ignore_re.search(p)] - - if unused_params: - unused_join = ', '.join(unused_params) - LOG.warning( - 'WARNING: Following parameter(s) are defined but not ' - 'currently used in the deployment plan. These parameters ' - 'may be valid but not in use due to the service or ' - 'deployment configuration.' - ' {unused_join}'.format( - unused_join=unused_join - ) - ) - - if invalid_role_specific_params: - invalid_join = ', '.join(invalid_role_specific_params) - LOG.warning( - 'WARNING: Following parameter(s) are not supported as ' - 'role-specific inputs. {invalid_join}'.format( - invalid_join=invalid_join - ) - ) - - def generate_fencing_parameters(clients, nodes_json, delay, ipmi_level, ipmi_cipher, ipmi_lanplus): """Generate and return fencing parameters. diff --git a/tripleoclient/workflows/plan_management.py b/tripleoclient/workflows/plan_management.py deleted file mode 100644 index 1c1fea969..000000000 --- a/tripleoclient/workflows/plan_management.py +++ /dev/null @@ -1,412 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -import logging -import os -import yaml - -from tripleo_common.actions import plan -from tripleo_common.utils import plan as plan_utils -from tripleo_common.utils import swift as swiftutils -from tripleo_common.utils import template as temputils - -from tripleoclient import constants -from tripleoclient import exceptions -from tripleoclient import utils - -LOG = logging.getLogger(__name__) -# Plan management workflows should generally be quick. However, the creation -# of the default plan in instack has demonstrated that sometimes it can take -# several minutes. The previous timeout of 6 minutes from Instack does not -# seem to be sufficient anymore. Bumping this to 20 minutes. It doesn't mean -# that it will take 20 minutes, but just that the listen for completion will -# timeout after 20 minutes. If it takes longer than that, something is really -# wrong. -_WORKFLOW_TIMEOUT = 20 * 60 # 20 minutes * 60 seconds - - -def _upload_templates(swift_client, container_name, tht_root, roles_file=None, - plan_env_file=None, networks_file=None): - """tarball up a given directory and upload it to Swift to be extracted""" - - temputils.upload_templates_as_tarball( - swift=swift_client, - dir_to_upload=tht_root, - container=container_name - ) - - # Optional override of the roles_data.yaml file - if roles_file: - _upload_file(swift_client, container_name, - constants.OVERCLOUD_ROLES_FILE, - utils.rel_or_abs_path(roles_file, tht_root)) - - # Optional override of the network_data.yaml file - if networks_file: - _upload_file(swift_client, container_name, - constants.OVERCLOUD_NETWORKS_FILE, networks_file) - - # Optional override of the plan-environment.yaml file - if plan_env_file: - # TODO(jpalanis): Instead of overriding default file, - # merging the user override plan-environment with default - # plan-environment file will avoid explict merging issues. - _upload_file(swift_client, container_name, - constants.PLAN_ENVIRONMENT, plan_env_file) - - -def create_deployment_plan(container, generate_passwords, - use_default_templates=False, source_url=None, - verbosity_level=0, plan_env_file=None, - disable_image_params_prepare=False): - """Create a deployment plan. - - :param container: Container name to push to. - :type container: String - - :param generate_passwords: Whether to generate password - :type generate_passwords: Boolean - - :param use_default_templates: Whether to use default template files - :type use_default_templates: Boolean - - :param source_url: The url of a git repository containing the Heat - templates to deploy - :type source_url: String - - :param verbosity_level: Verbosity level used in playbook execution - :type verbosity_level: Integer - - :param plan_env_file: Path to plan environment file - :type plan_env_file: String - - :param disable_image_params_prepare: Disable container params prepare task - :type disable_image_params_prepare: Boolean - """ - - extra_vars = { - "container": container, - "generate_passwords": generate_passwords, - "use_default_templates": use_default_templates, - "disable_image_params_prepare": disable_image_params_prepare - } - - if source_url: - extra_vars['source_url'] = source_url - - if plan_env_file: - extra_vars['plan_environment'] = plan_env_file - - with utils.TempDirs() as tmp: - utils.run_ansible_playbook( - "cli-create-deployment-plan.yaml", - 'undercloud,', - workdir=tmp, - playbook_dir=constants.ANSIBLE_TRIPLEO_PLAYBOOKS, - extra_vars=extra_vars, - verbosity=verbosity_level - ) - - print("Success.") - - -def delete_deployment_plan(clients, container): - """Delete a deployment plan. - - :param clients: Application client object. - :type clients: Object - - :param container: Container name to pull from. - :type container: String - """ - - context = clients.tripleoclient.create_mistral_context() - result = plan.DeletePlanAction(container=container).run(context=context) - # The action returns None if there are no errors. - if result: - raise RuntimeError(result) - - -def update_deployment_plan(clients, container, generate_passwords, - verbosity_level=0, - disable_image_params_prepare=False): - """Update a deployment plan. - - :param clients: Application client object. - :type clients: Object - - :param container: Container name to pull from. - :type container: String - - :param generate_passwords: Whether to generate password - :type generate_passwords: Boolean - - :param verbosity_level: Verbosity level used in playbook execution - :type verbosity_level: Integer - - :param disable_image_params_prepare: Disable container params prepare task - :type disable_image_params_prepare: Boolean - """ - - with utils.TempDirs() as tmp: - utils.run_ansible_playbook( - "cli-update-deployment-plan.yaml", - 'undercloud,', - workdir=tmp, - playbook_dir=constants.ANSIBLE_TRIPLEO_PLAYBOOKS, - extra_vars={ - "container": container, - "generate_passwords": generate_passwords, - "disable_image_params_prepare": disable_image_params_prepare - }, - verbosity=verbosity_level - ) - - print("Success.") - - -def list_deployment_plans(clients): - mistral_context = clients.tripleoclient.create_mistral_context() - return plan.ListPlansAction().run(mistral_context) - - -def create_plan_from_templates(clients, name, tht_root, roles_file=None, - generate_passwords=True, plan_env_file=None, - networks_file=None, verbosity_level=0, - disable_image_params_prepare=False): - - with utils.TempDirs() as tmp: - utils.run_ansible_playbook( - "cli-undercloud-local-artifacts.yaml", - 'undercloud,', - workdir=tmp, - playbook_dir=constants.ANSIBLE_TRIPLEO_PLAYBOOKS, - extra_vars={ - "stack": name, - }, - verbosity=verbosity_level - ) - - swift_client = clients.tripleoclient.object_store - - print("Creating Swift container to store the plan") - plan_utils.create_plan_container(swift_client, name) - - print("Creating plan from template files in: {}".format(tht_root)) - _upload_templates(swift_client, name, tht_root, - utils.rel_or_abs_path(roles_file, tht_root), - plan_env_file, networks_file) - - try: - create_deployment_plan( - container=name, - generate_passwords=generate_passwords, - plan_env_file=plan_env_file, - verbosity_level=verbosity_level, - disable_image_params_prepare=disable_image_params_prepare) - except exceptions.WorkflowServiceError: - swiftutils.delete_container(swift_client, name) - raise - - -def update_plan_from_templates(clients, name, tht_root, roles_file=None, - generate_passwords=True, plan_env_file=None, - networks_file=None, keep_env=False, - verbosity_level=1, - disable_image_params_prepare=False): - - with utils.TempDirs() as tmp: - utils.run_ansible_playbook( - "cli-undercloud-local-artifacts.yaml", - 'undercloud,', - workdir=tmp, - playbook_dir=constants.ANSIBLE_TRIPLEO_PLAYBOOKS, - extra_vars={ - "stack": name, - }, - verbosity=verbosity_level - ) - - swift_client = clients.tripleoclient.object_store - passwords = None - keep_file_contents = {} - roles_file = utils.rel_or_abs_path(roles_file, tht_root) - - if keep_env: - # Dict items are (remote_name, local_name). local_name may be - # None in which case we only try to load from Swift (remote). - keep_map = { - constants.PLAN_ENVIRONMENT: plan_env_file, - constants.USER_ENVIRONMENT: None, - constants.OVERCLOUD_ROLES_FILE: roles_file, - constants.OVERCLOUD_NETWORKS_FILE: networks_file, - } - # Also try to fetch any files under 'user-files/' - # dir. local_name is always None for these - keep_map.update(dict(map( - lambda path: (path, None), - _list_user_files(swift_client, name)))) - keep_file_contents = _load_content_or_file( - swift_client, name, keep_map) - else: - passwords = _load_passwords(swift_client, name) - - # TODO(dmatthews): Removing the existing plan files should probably be - # a Mistral action. - print("Removing the current plan files") - swiftutils.empty_container(swift_client, name) - - # Until we have a well defined plan update workflow in - # tripleo-common we need to manually reset the environments and - # parameter_defaults here. This is to ensure that no environments - # are in the plan environment but not actually in swift. - # See bug: https://bugs.launchpad.net/tripleo/+bug/1623431 - # - # Currently this is being done incidentally because we overwrite - # the existing plan-environment.yaml with the skeleton one in THT - # when updating the templates. Once LP#1623431 is resolved we may - # need to special-case plan-environment.yaml to avoid this. - - print("Uploading new plan files") - if keep_env: - _upload_templates(swift_client, name, tht_root) - for filename in keep_file_contents: - _upload_file_content(swift_client, name, filename, - keep_file_contents[filename]) - else: - _upload_templates(swift_client, name, tht_root, roles_file, - plan_env_file, networks_file) - _update_passwords(swift_client, name, passwords) - - update_deployment_plan( - clients, container=name, - generate_passwords=generate_passwords, - verbosity_level=verbosity_level, - disable_image_params_prepare=disable_image_params_prepare) - - -def _load_content_or_file(swift_client, container, remote_and_local_map): - # mapping (remote_name, content) - file_contents = {} - - plan_files = _list_plan_files(swift_client, container) - - for remote_name in remote_and_local_map: - LOG.debug("Attempting to load {0}".format(remote_name)) - local_name = remote_and_local_map[remote_name] - # it's possible that the file doesn't exist in Swift and isn't - # passed on filesystem, in which case we won't do anything - content = None - # local override takes priority - if local_name: - LOG.debug("Using provided file {0}".format(local_name)) - with open(os.path.abspath(local_name)) as local_content: - content = local_content.read() - elif remote_name in plan_files: - LOG.debug("Preserving plan file {0}".format(remote_name)) - content = swift_client.get_object(container, remote_name)[1] - - if content: - file_contents[remote_name] = content - - return file_contents - - -def _list_user_files(swift_client, container): - return list(filter(lambda path: path.startswith('user-files/'), - _list_plan_files(swift_client, container))) - - -def _list_plan_files(swift_client, container): - return list(map(lambda i: i['name'], - swift_client.get_container( - container, full_listing=True)[1])) - - -def _upload_file(swift_client, container, filename, local_filename): - with open(local_filename, 'rb') as file_content: - swiftutils.put_object_string( - swift=swift_client, - container=container, - object_name=filename, - contents=file_content - ) - - -# short function, just alias for interface parity with _upload_plan_file -def _upload_file_content(swift_client, container, filename, content): - LOG.debug("Uploading {0} to plan".format(filename)) - swiftutils.put_object_string( - swift=swift_client, - container=container, - object_name=filename, - contents=content - ) - - -def _load_passwords(swift_client, name): - plan_env = yaml.safe_load(swift_client.get_object( - name, constants.PLAN_ENVIRONMENT)[1]) - - if "passwords" in plan_env: - return plan_env['passwords'] - else: - LOG.warning("No passwords found in existing plan {}. " - "Updating plan with passwords.".format(name)) - - -def _update_passwords(swift_client, name, passwords): - # Update the plan environment with the generated passwords. This - # will be solved more elegantly once passwords are saved in a - # separate environment (https://review.opendev.org/#/c/467909/) - if passwords: - try: - env = yaml.safe_load(swift_client.get_object( - name, constants.PLAN_ENVIRONMENT)[1]) - env['passwords'] = passwords - swiftutils.put_object_string( - swift=swift_client, - container=name, - object_name=constants.PLAN_ENVIRONMENT, - contents=yaml.safe_dump(env, default_flow_style=False) - ) - except Exception as exp: - # The plan likely has not been migrated to using Swift yet. - LOG.debug("Could not find plan environment %s in %s - error: %s", - constants.PLAN_ENVIRONMENT, name, exp) - - -def export_deployment_plan(clients, plan_name): - - plan_path = os.path.join('/var/lib/tripleo/stacks', plan_name) - if os.path.exists(plan_path): - print("Plan information can be found here: {}".format(plan_path)) - return plan_path - else: - # NOTE(cloudnull): When swift is no longer in service remove this. - export_container = "plan-exports" - delete_after = 3600 - - mistral_context = clients.tripleoclient.create_mistral_context() - action = plan.ExportPlanAction(plan_name, delete_after=delete_after, - exports_container=export_container) - result = action.run(mistral_context) - if result: - raise exceptions.WorkflowServiceError( - 'Exception exporting plan: {}'.format(result.error)) - - url = swiftutils.get_temp_url( - clients.tripleoclient.object_store, - container=export_container, - object_name="{}.tar.gz".format(plan_name) - ) - print(url) - return url diff --git a/tripleoclient/workflows/roles.py b/tripleoclient/workflows/roles.py index fc5a4f594..fb8d11b3a 100644 --- a/tripleoclient/workflows/roles.py +++ b/tripleoclient/workflows/roles.py @@ -14,10 +14,6 @@ import logging import yaml -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__) @@ -60,54 +56,3 @@ def get_roles(clients, roles_file, tht_root, valid_roles.append(name) return valid_roles - - -def list_available_roles(clients, container='overcloud'): - """Return a list of available roles. - - :param clients: openstack clients - :type clients: Object - - :param container: Name of swift object container - :type container: String - - :returns: List - """ - - LOG.info('Pulling role list from: {}'.format(container)) - obj_client = clients.tripleoclient.object_store - available_yaml_roles = list() - LOG.info('Indexing roles from: {}'.format(container)) - # TODO(cloudnull): Convert to a swiftutils in tripleo-common - for obj in obj_client.get_container(container)[-1]: - name = obj['name'] - if name.startswith('roles/') and name.endswith(('yml', 'yaml')): - role_data = yaml.safe_load( - obj_client.get_object(container, name)[-1] - ) - available_yaml_roles.append(role_data[0]) - - return available_yaml_roles - - -def list_roles(clients, container, detail=False): - """Return a list of roles. - - :param clients: openstack clients - :type clients: Object - - :param container: Name of swift object container - :type container: String - - :param detail: Enable or disable extra detail - :type detail: Boolean - - :returns: List - """ - - context = clients.tripleoclient.create_mistral_context() - LOG.info('Pulling roles from: {}'.format(container)) - return plan.ListRolesAction( - container=container, - detail=detail - ).run(context=context)