External OpenStack action mapping file support

Release note and command line parameter added.
From now it is optional to list openstack modules in mapping file which
you would not include into supported action set.

Change-Id: I5ab01395c507fc857dca7cf08ab344a07def0dcf
This commit is contained in:
Istvan Imre 2017-02-15 12:34:14 +01:00 committed by Dougal Matthews
parent 9571c5489b
commit 91237c2baa
7 changed files with 84 additions and 7 deletions

View File

@ -23,12 +23,8 @@ from mistral.actions import action_generator
from mistral.utils import inspect_utils as i_u from mistral.utils import inspect_utils as i_u
from mistral import version from mistral import version
os_actions_mapping_path = cfg.StrOpt('openstack_actions_mapping_path',
default='actions/openstack/mapping.json')
CONF = cfg.CONF CONF = cfg.CONF
CONF.register_opt(os_actions_mapping_path)
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -84,7 +80,7 @@ class OpenStackActionGenerator(action_generator.ActionGenerator):
@classmethod @classmethod
def create_actions(cls): def create_actions(cls):
mapping = get_mapping() mapping = get_mapping()
method_dict = mapping[cls.action_namespace] method_dict = mapping.get(cls.action_namespace, {})
action_classes = [] action_classes = []

View File

@ -259,6 +259,18 @@ keycloak_oidc_opts = [
) )
] ]
# note: this command line option is used only from sync_db and
# mistral-db-manage
os_actions_mapping_path = cfg.StrOpt(
'openstack_actions_mapping_path',
short='m',
metavar='MAPPING_PATH',
default='actions/openstack/mapping.json',
help='Path to openstack action mapping json file.'
'It could be relative to mistral package '
'directory or absolute.'
)
CONF = cfg.CONF CONF = cfg.CONF
API_GROUP = 'api' API_GROUP = 'api'

View File

@ -23,6 +23,7 @@ from oslo_utils import importutils
import six import six
import sys import sys
from mistral import config
from mistral.services import action_manager from mistral.services import action_manager
from mistral.services import workflows from mistral.services import workflows
@ -113,6 +114,7 @@ command_opt = cfg.SubCommandOpt('command',
handler=add_command_parsers) handler=add_command_parsers)
CONF.register_cli_opt(command_opt) CONF.register_cli_opt(command_opt)
CONF.register_cli_opt(config.os_actions_mapping_path)
def main(): def main():

View File

@ -0,0 +1,6 @@
{
"_comment": "Mapping OpenStack action namespaces to all its actions. Each action name is mapped to python-client method name in this namespace.",
"nova": {
"servers_get": "servers.get"
}
}

View File

@ -10,11 +10,23 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import contextlib
import os
from oslo_config import cfg
from mistral.actions import generator_factory from mistral.actions import generator_factory
from mistral.actions.openstack import actions from mistral.actions.openstack import actions
from mistral import config
from mistral.tests.unit import base from mistral.tests.unit import base
ABSOLUTE_TEST_MAPPING_PATH = os.path.realpath(
os.path.join(os.path.dirname(__file__),
"../../../resources/openstack/test_mapping.json")
)
RELATIVE_TEST_MAPPING_PATH = "tests/resources/openstack/test_mapping.json"
MODULE_MAPPING = { MODULE_MAPPING = {
'nova': ['nova.servers_get', actions.NovaAction], 'nova': ['nova.servers_get', actions.NovaAction],
@ -44,6 +56,10 @@ MODULE_MAPPING = {
EXTRA_MODULES = ['neutron', 'swift', 'zaqar', 'tacker'] EXTRA_MODULES = ['neutron', 'swift', 'zaqar', 'tacker']
CONF = cfg.CONF
CONF.register_opt(config.os_actions_mapping_path)
class GeneratorTest(base.BaseTest): class GeneratorTest(base.BaseTest):
def test_generator(self): def test_generator(self):
for generator_cls in generator_factory.all_generators(): for generator_cls in generator_factory.all_generators():
@ -65,3 +81,38 @@ class GeneratorTest(base.BaseTest):
self.assertTrue(issubclass(action['class'], action_cls)) self.assertTrue(issubclass(action['class'], action_cls))
self.assertEqual(method_name, action['class'].client_method_name) self.assertEqual(method_name, action['class'].client_method_name)
def test_missing_module_from_mapping(self):
with _patch_openstack_action_mapping_path(RELATIVE_TEST_MAPPING_PATH):
for generator_cls in generator_factory.all_generators():
action_classes = generator_cls.create_actions()
action_names = [action['name'] for action in action_classes]
cls = MODULE_MAPPING.get(generator_cls.action_namespace)[1]
if cls == actions.NovaAction:
self.assertEqual(['nova.servers_get'], action_names)
else:
self.assertEqual([], action_names)
def test_absolute_mapping_path(self):
with _patch_openstack_action_mapping_path(ABSOLUTE_TEST_MAPPING_PATH):
self.assertTrue(os.path.isabs(ABSOLUTE_TEST_MAPPING_PATH),
"Mapping path is relative: %s" %
ABSOLUTE_TEST_MAPPING_PATH)
for generator_cls in generator_factory.all_generators():
action_classes = generator_cls.create_actions()
action_names = [action['name'] for action in action_classes]
cls = MODULE_MAPPING.get(generator_cls.action_namespace)[1]
if cls == actions.NovaAction:
self.assertEqual(['nova.servers_get'], action_names)
else:
self.assertEqual([], action_names)
@contextlib.contextmanager
def _patch_openstack_action_mapping_path(path):
original_path = CONF.openstack_actions_mapping_path
CONF.set_default("openstack_actions_mapping_path", path)
yield
CONF.set_default("openstack_actions_mapping_path", original_path)

View File

@ -0,0 +1,9 @@
---
features:
- External OpenStack action mapping file could be specified at sync_db.sh or
mistral-db-mange script.
For more details see 'sync_db.sh --help' or 'mistral-db-manage --help'.
- From now it is optional to list openstack modules in mapping file which
you would not include into supported action set.

View File

@ -23,7 +23,6 @@ from mistral.db.v2 import api as db_api
from mistral.services import action_manager from mistral.services import action_manager
from mistral.services import workflows from mistral.services import workflows
CONF = cfg.CONF CONF = cfg.CONF
@ -36,6 +35,8 @@ def main():
for group, opts in keystonemw_opts.list_auth_token_opts(): for group, opts in keystonemw_opts.list_auth_token_opts():
CONF.register_opts(opts, group=group) CONF.register_opts(opts, group=group)
CONF.register_cli_opt(config.os_actions_mapping_path)
config.parse_args() config.parse_args()
if len(CONF.config_file) == 0: if len(CONF.config_file) == 0: