Refactor mistral workflow to lay foundation for monitor to use it
Change-Id: I101a141dcbfb825f4e25443998eac805d68b6865
This commit is contained in:
parent
349b88adbc
commit
c9860cea07
0
tacker/mistral/__init__.py
Normal file
0
tacker/mistral/__init__.py
Normal 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
|
36
tacker/mistral/workflow_generator.py
Normal file
36
tacker/mistral/workflow_generator.py
Normal 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')
|
@ -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"""
|
||||||
|
|
||||||
|
@ -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)
|
|
@ -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']
|
||||||
|
@ -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'])
|
Loading…
Reference in New Issue
Block a user