Refactor mistral workflow to lay foundation for monitor to use it

Change-Id: I101a141dcbfb825f4e25443998eac805d68b6865
This commit is contained in:
yong sheng gong 2017-04-19 10:30:20 +08:00
parent 349b88adbc
commit c9860cea07
7 changed files with 78 additions and 130 deletions

View File

View File

@ -10,18 +10,18 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from mistralclient.api import client as mistral_client
class Workflow(object):
def __init__(self, wf_name, wf_type, version='2.0'):
self._wf_name = wf_name
self._wf_type = wf_type
self._version = '2.0'
def get_name(self): class MistralClient(object):
return self.wf_name """Mistral Client class for NSD"""
def get_type(self): def __init__(self, keystone, auth_token):
return self.wf_type endpoint = keystone.session.get_endpoint(
service_type='workflowv2', region_name=None)
def get_version(self): self.client = mistral_client.client(auth_token=auth_token,
self._version mistral_url=endpoint)
def get_client(self):
return self.client

View File

@ -0,0 +1,36 @@
# 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 uuid
class WorkflowGeneratorBase(object):
def __init__(self, resource, action):
self.resource = resource
self.action = action
self.wf_name = self.action + '_' + self.resource
self.wf_identifier = 'std.' + self.wf_name + str(uuid.uuid4())
self.task = getattr(self, self.wf_name)
self.input_dict = dict()
self._build_basic_workflow()
def _build_basic_workflow(self):
self.definition = {
'version': '2.0',
self.wf_identifier: {
'type': 'direct',
'input': [self.resource]
}
}
def get_tasks(self):
return self.definition[self.wf_identifier].get('tasks')

View File

@ -23,7 +23,6 @@ from keystoneauth1 import identity
from keystoneauth1.identity import v2 from keystoneauth1.identity import v2
from keystoneauth1.identity import v3 from keystoneauth1.identity import v3
from keystoneauth1 import session from keystoneauth1 import session
from mistralclient.api import client as mistral_client
from neutronclient.common import exceptions as nc_exceptions from neutronclient.common import exceptions as nc_exceptions
from neutronclient.v2_0 import client as neutron_client from neutronclient.v2_0 import client as neutron_client
from oslo_config import cfg from oslo_config import cfg
@ -33,6 +32,7 @@ from tacker._i18n import _LW, _
from tacker.agent.linux import utils as linux_utils from tacker.agent.linux import utils as linux_utils
from tacker.common import log from tacker.common import log
from tacker.extensions import nfvo from tacker.extensions import nfvo
from tacker.mistral import mistral_client
from tacker.nfvo.drivers.vim import abstract_vim_driver from tacker.nfvo.drivers.vim import abstract_vim_driver
from tacker.nfvo.drivers.vnffg import abstract_vnffg_driver from tacker.nfvo.drivers.vnffg import abstract_vnffg_driver
from tacker.nfvo.drivers.workflow import workflow_generator from tacker.nfvo.drivers.workflow import workflow_generator
@ -476,7 +476,7 @@ class OpenStack_Driver(abstract_vim_driver.VimAbstractDriver,
LOG.warning(_("auth dict required to instantiate mistral client")) LOG.warning(_("auth dict required to instantiate mistral client"))
raise EnvironmentError('auth dict required for' raise EnvironmentError('auth dict required for'
' mistral workflow driver') ' mistral workflow driver')
return MistralClient( return mistral_client.MistralClient(
keystone.Keystone().initialize_client('2', **auth_dict), keystone.Keystone().initialize_client('2', **auth_dict),
auth_dict['token']).get_client() auth_dict['token']).get_client()
@ -511,20 +511,6 @@ class OpenStack_Driver(abstract_vim_driver.VimAbstractDriver,
.workflows.delete(workflow_id) .workflows.delete(workflow_id)
class MistralClient(object):
"""Mistral Client class for NSD"""
def __init__(self, keystone, auth_token):
endpoint = keystone.session.get_endpoint(
service_type='workflowv2', region_name=None)
self.client = mistral_client.client(auth_token=auth_token,
mistral_url=endpoint)
def get_client(self):
return self.client
class NeutronClient(object): class NeutronClient(object):
"""Neutron Client class for networking-sfc driver""" """Neutron Client class for networking-sfc driver"""

View File

@ -1,53 +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 yaml
from oslo_log import log as logging
from tacker.nfvo.drivers.workflow import workflow_generator
LOG = logging.getLogger(__name__)
FREQUENCY = 10
SLEEP = 5
class MistralClient(object):
def __init__(self, context, client, resource, action):
self.context = context
self.client = client
self.wg = workflow_generator.WorkflowGenerator(resource, action)
def prepare_workflow(self, **kwargs):
self.wg.task(**kwargs)
def create_workflow(self):
definition_yaml = yaml.safe_dump(self.wg.definition)
wf = self.client.workflows.create(definition_yaml)
wf_id = wf[0].id
return wf_id
def delete_workflow(self, wf_id):
self.client.workflows.delete(wf_id)
def execute_workflow(self, wf_id):
wf_ex = self.client.executions.create(
workflow_identifier=wf_id,
workflow_input=self.wg.input_dict,
wf_params={})
return wf_ex
def get_execution_state(self, ex_id):
return self.client.executions.get(ex_id).state
def delete_execution(self, ex_id):
self.client.executions.delete(ex_id)

View File

@ -11,9 +11,10 @@
# under the License. # under the License.
import ast import ast
from six import iteritems
import uuid import uuid
from six import iteritems from tacker.mistral import workflow_generator
OUTPUT = { OUTPUT = {
@ -21,42 +22,7 @@ OUTPUT = {
} }
class WorkflowGenerator(object): class WorkflowGenerator(workflow_generator.WorkflowGeneratorBase):
def __init__(self, resource, action):
self.resource = resource
self.action = action
self.wf_name = self.action + '_' + self.resource
self.wf_identifier = 'std.' + self.wf_name + str(uuid.uuid4())
self.task = getattr(self, self.wf_name)
self.input_dict = dict()
self._build_basic_workflow()
def _build_basic_workflow(self):
self.definition = {
'version': '2.0',
self.wf_identifier: {
'type': 'direct',
'input': [self.resource]
}
}
def _get_vim_id(self):
pass
def _get_vnfd_id(self):
pass
def _get_vnf_name(self):
pass
def _get_attr(self):
pass
def _get_description(self):
pass
def get_tasks(self):
return self.definition[self.wf_identifier]['tasks']
def _add_create_vnf_tasks(self, ns): def _add_create_vnf_tasks(self, ns):
vnfds = ns['vnfd_details'] vnfds = ns['vnfd_details']

View File

@ -13,7 +13,7 @@
# under the License. # under the License.
from tacker import context from tacker import context
from tacker.nfvo.drivers.workflow import mistral from tacker.nfvo.drivers.workflow import workflow_generator
from tacker.tests.unit import base from tacker.tests.unit import base
@ -133,27 +133,40 @@ class FakeMistral(object):
pass pass
class TestMistralClient(base.TestCase): class FakeNFVOPlugin(object):
def __init__(self, context, client, resource, action):
self.context = context
self.client = client
self.wg = workflow_generator.WorkflowGenerator(resource, action)
def prepare_workflow(self, **kwargs):
self.wg.task(**kwargs)
class TestWorkflowGenerator(base.TestCase):
def setUp(self): def setUp(self):
super(TestMistralClient, self).setUp() super(TestWorkflowGenerator, self).setUp()
self.mistral_client = FakeMistral() self.mistral_client = FakeMistral()
def test_prepare_workflow_create(self): def test_prepare_workflow_create(self):
mc = mistral.MistralClient(context, self.mistral_client, fPlugin = FakeNFVOPlugin(context, self.mistral_client,
resource='vnf', action='create') resource='vnf', action='create')
mc.prepare_workflow(ns=get_dummy_ns(), params=get_dummy_param()) fPlugin.prepare_workflow(ns=get_dummy_ns(), params=get_dummy_param())
wf_def_values = [mc.wg.definition[k] for k in mc.wg.definition] wf_def_values = [fPlugin.wg.definition[k] for
k in fPlugin.wg.definition]
self.assertIn(get_dummy_create_workflow()['std.create_vnf_dummy'], self.assertIn(get_dummy_create_workflow()['std.create_vnf_dummy'],
wf_def_values) wf_def_values)
self.assertEqual(get_dummy_create_workflow()['version'], self.assertEqual(get_dummy_create_workflow()['version'],
mc.wg.definition['version']) fPlugin.wg.definition['version'])
def test_prepare_workflow_delete(self): def test_prepare_workflow_delete(self):
mc = mistral.MistralClient(context, self.mistral_client, fPlugin = FakeNFVOPlugin(context, self.mistral_client,
resource='vnf', action='delete') resource='vnf', action='delete')
mc.prepare_workflow(ns=dummy_delete_ns_obj()) fPlugin.prepare_workflow(ns=dummy_delete_ns_obj())
wf_def_values = [mc.wg.definition[k] for k in mc.wg.definition] wf_def_values = [fPlugin.wg.definition[k] for
k in fPlugin.wg.definition]
self.assertIn(get_dummy_delete_workflow()['std.delete_vnf_dummy'], self.assertIn(get_dummy_delete_workflow()['std.delete_vnf_dummy'],
wf_def_values) wf_def_values)
self.assertEqual(get_dummy_delete_workflow()['version'], self.assertEqual(get_dummy_delete_workflow()['version'],
mc.wg.definition['version']) fPlugin.wg.definition['version'])