From 486bb79c3d0192c113650fb6369c9c45e3ee640f Mon Sep 17 00:00:00 2001 From: Ana Krivokapic Date: Fri, 14 Apr 2017 13:10:35 +0200 Subject: [PATCH] Migrate plans from Mistral to Swift Partially implements: blueprint stop-using-mistral-env Change-Id: I938d00c2c821791265c8c9a1ac5e56f0f025d4ca --- instack_undercloud/tests/test_undercloud.py | 45 +++++++++---------- instack_undercloud/undercloud.py | 41 ++++++++++++++--- .../notes/migrate-plans-36bdf9a667ce02d5.yaml | 4 ++ requirements.txt | 1 + 4 files changed, 63 insertions(+), 28 deletions(-) create mode 100644 releasenotes/notes/migrate-plans-36bdf9a667ce02d5.yaml diff --git a/instack_undercloud/tests/test_undercloud.py b/instack_undercloud/tests/test_undercloud.py index 1e3525d19..e831de6a6 100644 --- a/instack_undercloud/tests/test_undercloud.py +++ b/instack_undercloud/tests/test_undercloud.py @@ -644,6 +644,7 @@ class TestConfigureSshKeys(base.BaseTestCase): class TestPostConfig(base.BaseTestCase): @mock.patch('instack_undercloud.undercloud._member_role_exists') @mock.patch('novaclient.client.Client', autospec=True) + @mock.patch('swiftclient.client.Connection', autospec=True) @mock.patch('mistralclient.api.client.client', autospec=True) @mock.patch('instack_undercloud.undercloud._delete_default_flavors') @mock.patch('instack_undercloud.undercloud._copy_stackrc') @@ -654,15 +655,18 @@ class TestPostConfig(base.BaseTestCase): def test_post_config(self, mock_post_config_mistral, mock_ensure_flavor, mock_configure_ssh_keys, mock_get_auth_values, mock_copy_stackrc, mock_delete, mock_mistral_client, - mock_nova_client, mock_member_role_exists): + mock_swift_client, mock_nova_client, + mock_member_role_exists): instack_env = { 'UNDERCLOUD_ENDPOINT_MISTRAL_PUBLIC': 'http://192.168.24.1:8989/v2', } mock_get_auth_values.return_value = ('aturing', '3nigma', 'hut8', 'http://bletchley:5000/v2.0') - mock_instance = mock.Mock() - mock_nova_client.return_value = mock_instance + mock_instance_nova = mock.Mock() + mock_nova_client.return_value = mock_instance_nova + mock_instance_swift = mock.Mock() + mock_swift_client.return_value = mock_instance_swift mock_instance_mistral = mock.Mock() mock_mistral_client.return_value = mock_instance_mistral undercloud._post_config(instack_env) @@ -670,24 +674,26 @@ class TestPostConfig(base.BaseTestCase): 2, 'aturing', '3nigma', project_name='hut8', auth_url='http://bletchley:5000/v2.0') self.assertTrue(mock_copy_stackrc.called) - mock_configure_ssh_keys.assert_called_with(mock_instance) - calls = [mock.call(mock_instance, 'baremetal'), - mock.call(mock_instance, 'control', 'control'), - mock.call(mock_instance, 'compute', 'compute'), - mock.call(mock_instance, 'ceph-storage', 'ceph-storage'), - mock.call(mock_instance, 'block-storage', 'block-storage'), - mock.call(mock_instance, 'swift-storage', 'swift-storage'), + mock_configure_ssh_keys.assert_called_with(mock_instance_nova) + calls = [mock.call(mock_instance_nova, 'baremetal'), + mock.call(mock_instance_nova, 'control', 'control'), + mock.call(mock_instance_nova, 'compute', 'compute'), + mock.call(mock_instance_nova, 'ceph-storage', 'ceph-storage'), + mock.call(mock_instance_nova, + 'block-storage', 'block-storage'), + mock.call(mock_instance_nova, + 'swift-storage', 'swift-storage'), ] mock_ensure_flavor.assert_has_calls(calls) - mock_post_config_mistral.assert_called_once_with(instack_env, - mock_instance_mistral) + mock_post_config_mistral.assert_called_once_with( + instack_env, mock_instance_mistral, mock_instance_swift) def test_create_default_plan(self): mock_mistral = mock.Mock() mock_mistral.environments.list.return_value = [] mock_mistral.executions.get.return_value = mock.Mock(state="SUCCESS") - undercloud._create_default_plan(mock_mistral) + undercloud._create_default_plan(mock_mistral, []) mock_mistral.executions.create.assert_called_once_with( 'tripleo.plan_management.v1.create_default_deployment_plan', workflow_input={ @@ -698,12 +704,7 @@ class TestPostConfig(base.BaseTestCase): def test_create_default_plan_existing(self): mock_mistral = mock.Mock() - environment = collections.namedtuple('environment', ['name']) - mock_mistral.environments.list.return_value = [ - environment(name='overcloud') - ] - - undercloud._create_default_plan(mock_mistral) + undercloud._create_default_plan(mock_mistral, ['overcloud']) mock_mistral.executions.create.assert_not_called() def test_create_config_environment(self): @@ -743,21 +744,19 @@ class TestPostConfig(base.BaseTestCase): @mock.patch('time.sleep') def test_create_default_plan_timeout(self, mock_sleep): mock_mistral = mock.Mock() - mock_mistral.environments.list.return_value = [] mock_mistral.executions.get.return_value = mock.Mock(state="RUNNING") self.assertRaises( RuntimeError, - undercloud._create_default_plan, mock_mistral, timeout=0) + undercloud._create_default_plan, mock_mistral, [], timeout=0) def test_create_default_plan_failed(self): mock_mistral = mock.Mock() - mock_mistral.environments.list.return_value = [] mock_mistral.executions.get.return_value = mock.Mock(state="ERROR") self.assertRaises( RuntimeError, - undercloud._create_default_plan, mock_mistral) + undercloud._create_default_plan, mock_mistral, []) @mock.patch('instack_undercloud.undercloud._run_command') def test_copy_stackrc(self, mock_run): diff --git a/instack_undercloud/undercloud.py b/instack_undercloud/undercloud.py index 265a769fe..0c610a006 100644 --- a/instack_undercloud/undercloud.py +++ b/instack_undercloud/undercloud.py @@ -29,6 +29,7 @@ import sys import tempfile import time import uuid +import yaml from keystoneauth1 import exceptions as ks_exceptions from keystoneauth1 import session @@ -43,6 +44,7 @@ from oslo_config import cfg import psutil import pystache import six +from swiftclient import client as swiftclient from instack_undercloud import validator @@ -1331,11 +1333,31 @@ def _create_mistral_config_environment(instack_env, mistral): })) -def _create_default_plan(mistral, timeout=360): +def _migrate_plans(mistral, swift, plans): + """Migrate plan environments from Mistral to Swift.""" + plan_env_filename = 'plan-environment.yaml' + + for plan in plans: + headers, objects = swift.get_container(plan) + + if headers.get('x-container-meta-usage-tripleo') != 'plan': + continue + + try: + swift.get_object(plan, plan_env_filename) + except swiftclient.ClientException: + LOG.info('Migrating environment for plan %s to Swift.' % plan) + env = mistral.environments.get(plan).variables + yaml_string = yaml.safe_dump(env, default_flow_style=False) + swift.put_object(plan, plan_env_filename, yaml_string) + mistral.environments.delete(plan) + + +def _create_default_plan(mistral, plans, timeout=360): plan_name = 'overcloud' queue_name = str(uuid.uuid4()) - if plan_name in [env.name for env in mistral.environments.list()]: + if plan_name in plans: LOG.info('Not creating default plan "%s" because it already exists.', plan_name) return @@ -1373,10 +1395,12 @@ def _prepare_ssh_environment(mistral): mistral.executions.create('tripleo.validations.v1.copy_ssh_key') -def _post_config_mistral(instack_env, mistral): +def _post_config_mistral(instack_env, mistral, swift): + plans = [container["name"] for container in swift.get_account()[1]] _create_mistral_config_environment(instack_env, mistral) - _create_default_plan(mistral) + _migrate_plans(mistral, swift, plans) + _create_default_plan(mistral, plans) if CONF.enable_validations: _prepare_ssh_environment(mistral) @@ -1409,8 +1433,15 @@ def _post_config(instack_env): api_key=password, project_name=tenant, auth_url=auth_url) - _post_config_mistral(instack_env, mistral) + swift = swiftclient.Connection( + authurl=auth_url, + user=user, + key=password, + tenant_name=tenant, + auth_version='2.0' + ) + _post_config_mistral(instack_env, mistral, swift) _member_role_exists() diff --git a/releasenotes/notes/migrate-plans-36bdf9a667ce02d5.yaml b/releasenotes/notes/migrate-plans-36bdf9a667ce02d5.yaml new file mode 100644 index 000000000..b72b473a1 --- /dev/null +++ b/releasenotes/notes/migrate-plans-36bdf9a667ce02d5.yaml @@ -0,0 +1,4 @@ +--- +upgrade: + - Deployment plan environments for existing plans will be migrated from + Mistral to Swift on undercloud upgrade. diff --git a/requirements.txt b/requirements.txt index a6da40d75..7bde0e6ac 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,6 +5,7 @@ six>=1.9.0 # MIT python-keystoneclient>=3.8.0 # Apache-2.0 python-novaclient>=7.1.0 # Apache-2.0 python-mistralclient>=2.0.0 # Apache-2.0 +python-swiftclient>=3.2.0 # Apache-2.0 oslo.config>=3.22.0 # Apache-2.0 psutil>=3.2.2 # BSD netaddr!=0.7.16,>=0.7.13 # BSD