Migrate plans from Mistral to Swift

Partially implements: blueprint stop-using-mistral-env

Change-Id: I938d00c2c821791265c8c9a1ac5e56f0f025d4ca
This commit is contained in:
Ana Krivokapic 2017-04-14 13:10:35 +02:00
parent c1bfb84e6e
commit 486bb79c3d
4 changed files with 63 additions and 28 deletions

View File

@ -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):

View File

@ -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()

View File

@ -0,0 +1,4 @@
---
upgrade:
- Deployment plan environments for existing plans will be migrated from
Mistral to Swift on undercloud upgrade.

View File

@ -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