From 8bdf341af7348d3d092c6523a09df118c51c2a53 Mon Sep 17 00:00:00 2001 From: Eyal Date: Tue, 21 Jan 2020 16:53:34 +0200 Subject: [PATCH] Remove OpenStack actions from mistral Depends-on: https://review.opendev.org/#/c/703296/ Depends-On: https://review.opendev.org/#/c/704280/ Change-Id: Id62fdabe7699e7c3b2977166e253cfc77779e467 --- .zuul.yaml | 16 + devstack/plugin.sh | 8 + devstack/settings | 4 + doc/requirements.txt | 1 + lower-constraints.txt | 2 +- mistral/actions/action_generator.py | 31 - mistral/actions/base.py | 91 - mistral/actions/generator_factory.py | 43 - mistral/actions/openstack/__init__.py | 0 .../openstack/action_generator/__init__.py | 0 .../openstack/action_generator/base.py | 172 -- mistral/actions/openstack/actions.py | 1084 ------------ mistral/actions/openstack/base.py | 136 -- mistral/actions/openstack/mapping.json | 1505 ----------------- mistral/config.py | 37 - mistral/db/sqlalchemy/migration/cli.py | 2 - mistral/engine/base.py | 2 +- mistral/executors/default_executor.py | 2 +- mistral/services/action_manager.py | 40 +- .../openstack/action_collection_wb.yaml | 53 - .../resources/openstack/test_mapping.json | 16 - .../tests/unit/actions/openstack/__init__.py | 0 .../unit/actions/openstack/test_generator.py | 193 --- .../openstack/test_openstack_actions.py | 411 ----- .../tests/unit/actions/test_action_manager.py | 18 - .../unit/api/v2/test_action_executions.py | 7 +- mistral/tests/unit/api/v2/test_executions.py | 7 +- mistral/tests/unit/base.py | 11 +- mistral/tests/unit/test_exception_base.py | 2 +- .../tests/unit/utils/test_inspect_utils.py | 69 - .../tests/unit/utils/test_keystone_utils.py | 61 - mistral/utils/inspect_utils.py | 94 - mistral/utils/openstack/keystone.py | 221 +-- mistral/workflow/data_flow.py | 2 +- ...ral_to_mistral_extra-b3f7bc71ffd72c6e.yaml | 3 + requirements.txt | 29 +- test-requirements.txt | 14 +- tools/get_action_list.py | 356 ---- tools/sync_db.py | 2 - 39 files changed, 79 insertions(+), 4666 deletions(-) delete mode 100644 mistral/actions/action_generator.py delete mode 100644 mistral/actions/base.py delete mode 100644 mistral/actions/generator_factory.py delete mode 100644 mistral/actions/openstack/__init__.py delete mode 100644 mistral/actions/openstack/action_generator/__init__.py delete mode 100644 mistral/actions/openstack/action_generator/base.py delete mode 100644 mistral/actions/openstack/actions.py delete mode 100644 mistral/actions/openstack/base.py delete mode 100644 mistral/actions/openstack/mapping.json delete mode 100644 mistral/tests/resources/openstack/action_collection_wb.yaml delete mode 100644 mistral/tests/resources/openstack/test_mapping.json delete mode 100644 mistral/tests/unit/actions/openstack/__init__.py delete mode 100644 mistral/tests/unit/actions/openstack/test_generator.py delete mode 100644 mistral/tests/unit/actions/openstack/test_openstack_actions.py delete mode 100644 mistral/tests/unit/utils/test_inspect_utils.py delete mode 100644 mistral/tests/unit/utils/test_keystone_utils.py delete mode 100644 mistral/utils/inspect_utils.py create mode 100644 releasenotes/notes/move_openstack_actions_from_mistral_to_mistral_extra-b3f7bc71ffd72c6e.yaml delete mode 100644 tools/get_action_list.py diff --git a/.zuul.yaml b/.zuul.yaml index d0e248ff4..44a76f866 100644 --- a/.zuul.yaml +++ b/.zuul.yaml @@ -9,6 +9,8 @@ USE_PYTHON3: true required-projects: - openstack/rally-openstack + - openstack/mistral-lib + - openstack/mistral-extra - job: name: mistral-docker-buildimage @@ -46,6 +48,7 @@ timeout: 3600 required-projects: - openstack/mistral-lib + - openstack/mistral-extra - job: name: mistral-tox-unit-postgresql @@ -60,6 +63,7 @@ timeout: 3600 required-projects: - openstack/mistral-lib + - openstack/mistral-extra - project: templates: @@ -78,12 +82,23 @@ - ^releasenotes/.*$ required-projects: - openstack/mistral-lib + - openstack/mistral-extra - openstack-tox-py36: required-projects: - openstack/mistral-lib + - openstack/mistral-extra - openstack-tox-py37: required-projects: - openstack/mistral-lib + - openstack/mistral-extra + - openstack-tox-py38: + required-projects: + - openstack/mistral-lib + - openstack/mistral-extra + - openstack-tox-docs: + required-projects: + - openstack/mistral-lib + - openstack/mistral-extra - mistral-devstack - mistral-devstack-tempest-ipv6-only - mistral-devstack-non-apache-tempest-ipv6-only @@ -103,6 +118,7 @@ - openstack-tox-lower-constraints: required-projects: - openstack/mistral-lib + - openstack/mistral-extra gate: queue: mistral jobs: diff --git a/devstack/plugin.sh b/devstack/plugin.sh index e20ac4af5..ee2203a60 100755 --- a/devstack/plugin.sh +++ b/devstack/plugin.sh @@ -161,6 +161,13 @@ function install_mistral_lib { fi } +function install_mistral_extra { + if use_library_from_git "mistral-extra"; then + git_clone $MISTRAL_EXTRA_REPO $MISTRAL_EXTRA_DIR $MISTRAL_EXTRA_BRANCH + setup_develop $MISTRAL_EXTRA_DIR + fi +} + # start_mistral - Start running processes function start_mistral { # If the site is not enabled then we are in a grenade scenario @@ -255,6 +262,7 @@ if is_service_enabled mistral; then echo_summary "Installing mistral" install_mistral install_mistral_lib + install_mistral_extra install_mistral_pythonclient elif [[ "$1" == "stack" && "$2" == "post-config" ]]; then echo_summary "Configuring mistral" diff --git a/devstack/settings b/devstack/settings index 5a8bcaa02..7bf0c60c0 100644 --- a/devstack/settings +++ b/devstack/settings @@ -23,6 +23,10 @@ MISTRAL_LIB_REPO=${MISTRAL_LIB_REPO:-${GIT_BASE}/openstack/mistral-lib.git} MISTRAL_LIB_BRANCH=${MISTRAL_LIB_BRANCH:-master} MISTRAL_LIB_DIR=${DEST}/mistral-lib +MISTRAL_EXTRA_REPO=${MISTRAL_EXTRA_REPO:-${GIT_BASE}/openstack/mistral-extra.git} +MISTRAL_EXTRA_BRANCH=${MISTRAL_EXTRA_BRANCH:-master} +MISTRAL_EXTRA_DIR=${DEST}/mistral-extra + GITDIR["python-mistralclient"]=${DEST}/python-mistralclient GITREPO["python-mistralclient"]=${MISTRALCLIENT_REPO:-${GIT_BASE}/openstack/python-mistralclient.git} GITBRANCH["python-mistralclient"]=${MISTRALCLIENT_BRANCH:-master} diff --git a/doc/requirements.txt b/doc/requirements.txt index 7ddda5529..9bc364519 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -2,4 +2,5 @@ sphinx>=1.8.0,!=2.1.0;python_version>='3.4' # BSD sphinxcontrib-httpdomain>=1.3.0 # BSD sphinxcontrib-pecanwsme>=0.8.0 # Apache-2.0 openstackdocstheme>=1.30.0 # Apache-2.0 +os-api-ref>=1.4.0 # Apache-2.0 reno>=2.5.0 # Apache-2.0 diff --git a/lower-constraints.txt b/lower-constraints.txt index e59c71a33..34671c04d 100644 --- a/lower-constraints.txt +++ b/lower-constraints.txt @@ -50,7 +50,7 @@ logutils==0.3.5 Mako==0.4.0 MarkupSafe==1.0 mccabe==0.2.1 -mistral-lib==1.2.0 +mistral-lib==1.4.0 mock==2.0.0 monotonic==0.6 mox3==0.20.0 diff --git a/mistral/actions/action_generator.py b/mistral/actions/action_generator.py deleted file mode 100644 index e38eb43f3..000000000 --- a/mistral/actions/action_generator.py +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright 2014 - Mirantis, Inc. -# -# 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 abc - - -class ActionGenerator(object): - """Action generator. - - Action generator uses some data to build Action classes - dynamically. - """ - @abc.abstractmethod - def create_actions(self, *args, **kwargs): - """Constructs classes of needed action. - - return: list of actions dicts containing name, class, - description and parameter info. - """ - pass diff --git a/mistral/actions/base.py b/mistral/actions/base.py deleted file mode 100644 index 1154a0d86..000000000 --- a/mistral/actions/base.py +++ /dev/null @@ -1,91 +0,0 @@ -# Copyright 2014 - Mirantis, Inc. -# -# 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 abc -import warnings - -warnings.warn( - "mistral.actions.Action is deprecated as of the 5.0.0 release in favor of " - "mistral_lib. It will be removed in a future release.", DeprecationWarning -) - - -class Action(object): - """Action. - - Action is a means in Mistral to perform some useful work associated with - a workflow during its execution. Every workflow task is configured with - an action and when the task runs it eventually delegates to the action. - When it happens task parameters get evaluated (calculating expressions, - if any) and are treated as action parameters. So in a regular general - purpose languages terminology action is a method declaration and task is - a method call. - - Base action class initializer doesn't have arguments. However, concrete - action classes may have any number of parameters defining action behavior. - These parameters must correspond to parameters declared in action - specification (e.g. using DSL or others). - Action initializer may have a conventional argument with name - "action_context". If it presents then action factory will fill it with - a dictionary containing contextual information like execution identifier, - workbook name and other that may be needed for some specific action - implementations. - """ - - @abc.abstractmethod - def run(self): - """Run action logic. - - :return: Result of the action. Note that for asynchronous actions - it should always be None, however, if even it's not None it will be - ignored by a caller. - - Result can be of two types: - 1) Any serializable value meaningful from a user perspective (such - as string, number or dict). - 2) Instance of {mistral.workflow.utils.Result} which has field "data" - for success result and field "error" for keeping so called "error - result" like HTTP error code and similar. Using the second type - allows to communicate a result even in case of error and hence to have - conditions in "on-error" clause of direct workflows. Depending on - particular action semantics one or another option may be preferable. - In case if action failed and there's no need to communicate any error - result this method should throw a ActionException. - """ - pass - - @abc.abstractmethod - def test(self): - """Returns action test result. - - This method runs in test mode as a test version of method run() to - generate and return a representative test result. It's basically a - contract for action 'dry-run' behavior specifically useful for - testing and workflow designing purposes. - - :return: Representative action result. - """ - pass - - def is_sync(self): - """Returns True if the action is synchronous, otherwise False. - - :return: True if the action is synchronous and method run() returns - final action result. Otherwise returns False which means that - a result of method run() should be ignored and a real action - result is supposed to be delivered in an asynchronous manner - using public API. By default, if a concrete implementation - doesn't override this method then the action is synchronous. - """ - return True diff --git a/mistral/actions/generator_factory.py b/mistral/actions/generator_factory.py deleted file mode 100644 index f7f6a9e39..000000000 --- a/mistral/actions/generator_factory.py +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright 2014 - Mirantis, Inc. -# -# 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. - -from oslo_utils import importutils - -from mistral.actions.openstack.action_generator import base - - -SUPPORTED_MODULES = [ - 'Nova', 'Glance', 'Keystone', 'Heat', 'Neutron', 'Cinder', - 'Trove', 'Ironic', 'Baremetal Introspection', 'Swift', 'SwiftService', - 'Zaqar', 'Barbican', 'Mistral', 'Designate', 'Magnum', 'Murano', 'Tacker', - 'Aodh', 'Gnocchi', 'Glare', 'Vitrage', 'Senlin', 'Zun', 'Qinling', 'Manila' -] - - -def all_generators(): - for mod_name in SUPPORTED_MODULES: - prefix = mod_name.replace(' ', '') - mod_namespace = mod_name.lower().replace(' ', '_') - mod_cls_name = 'mistral.actions.openstack.actions.%sAction' % prefix - mod_action_cls = importutils.import_class(mod_cls_name) - generator_cls_name = '%sActionGenerator' % prefix - - yield type( - generator_cls_name, - (base.OpenStackActionGenerator,), - { - 'action_namespace': mod_namespace, - 'base_action_class': mod_action_cls - } - ) diff --git a/mistral/actions/openstack/__init__.py b/mistral/actions/openstack/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/mistral/actions/openstack/action_generator/__init__.py b/mistral/actions/openstack/action_generator/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/mistral/actions/openstack/action_generator/base.py b/mistral/actions/openstack/action_generator/base.py deleted file mode 100644 index 876c5f465..000000000 --- a/mistral/actions/openstack/action_generator/base.py +++ /dev/null @@ -1,172 +0,0 @@ -# Copyright 2014 - Mirantis, Inc. -# -# 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 json -import os - -from oslo_config import cfg -from oslo_log import log as logging -import pkg_resources as pkg - -from mistral.actions import action_generator -from mistral.utils import inspect_utils as i_u -from mistral import version - -CONF = cfg.CONF - -LOG = logging.getLogger(__name__) - - -def get_mapping(): - def delete_comment(map_part): - for key, value in map_part.items(): - if isinstance(value, dict): - delete_comment(value) - if '_comment' in map_part: - del map_part['_comment'] - package = version.version_info.package - - if os.path.isabs(CONF.openstack_actions_mapping_path): - mapping_file_path = CONF.openstack_actions_mapping_path - else: - path = CONF.openstack_actions_mapping_path - mapping_file_path = pkg.resource_filename(package, path) - - LOG.info( - "Processing OpenStack action mapping from file: %s", - mapping_file_path - ) - - with open(mapping_file_path) as fh: - mapping = json.load(fh) - - for k, v in mapping.items(): - if isinstance(v, dict): - delete_comment(v) - - return mapping - - -class OpenStackActionGenerator(action_generator.ActionGenerator): - """OpenStackActionGenerator. - - Base generator for all OpenStack actions, - creates a client method declaration using - specific python-client and sets needed arguments - to actions. - """ - action_namespace = None - base_action_class = None - - @classmethod - def prepare_action_inputs(cls, origin_inputs, added=()): - """Modify action input string. - - Sometimes we need to change the default action input definition for - OpenStack actions in order to make the workflow more powerful. - - Examples:: - - >>> prepare_action_inputs('a,b,c', added=['region=RegionOne']) - a, b, c, region=RegionOne - >>> prepare_action_inputs('a,b,c=1', added=['region=RegionOne']) - a, b, region=RegionOne, c=1 - >>> prepare_action_inputs('a,b,c=1,**kwargs', - added=['region=RegionOne']) - a, b, region=RegionOne, c=1, **kwargs - >>> prepare_action_inputs('**kwargs', added=['region=RegionOne']) - region=RegionOne, **kwargs - >>> prepare_action_inputs('', added=['region=RegionOne']) - region=RegionOne - - :param origin_inputs: A string consists of action inputs, separated by - comma. - :param added: (Optional) A list of params to add to input string. - :return: The new action input string. - """ - if not origin_inputs: - return ", ".join(added) - - inputs = [i.strip() for i in origin_inputs.split(',')] - kwarg_index = None - - for index, input in enumerate(inputs): - if "=" in input: - kwarg_index = index - if "**" in input: - kwarg_index = index - 1 - - kwarg_index = len(inputs) if kwarg_index is None else kwarg_index - kwarg_index = kwarg_index + 1 if kwarg_index < 0 else kwarg_index - - for a in added: - if "=" not in a: - inputs.insert(0, a) - kwarg_index += 1 - else: - inputs.insert(kwarg_index, a) - - return ", ".join(inputs) - - @classmethod - def create_action_class(cls, method_name): - if not method_name: - return None - - action_class = type(str(method_name), (cls.base_action_class,), - {'client_method_name': method_name}) - - return action_class - - @classmethod - def create_actions(cls): - mapping = get_mapping() - method_dict = mapping.get(cls.action_namespace, {}) - - action_classes = [] - - for action_name, method_name in method_dict.items(): - class_ = cls.create_action_class(method_name) - - try: - client_method = class_.get_fake_client_method() - except Exception: - LOG.exception( - "Failed to create action: %s.%s", - cls.action_namespace, action_name - ) - continue - - arg_list = i_u.get_arg_list_as_str(client_method) - - # Support specifying region for OpenStack actions. - modules = CONF.openstack_actions.modules_support_region - if cls.action_namespace in modules: - arg_list = cls.prepare_action_inputs( - arg_list, - added=['action_region=""'] - ) - - description = i_u.get_docstring(client_method) - - action_classes.append( - { - 'class': class_, - 'name': "%s.%s" % (cls.action_namespace, action_name), - 'description': description, - 'arg_list': arg_list, - } - ) - - return action_classes diff --git a/mistral/actions/openstack/actions.py b/mistral/actions/openstack/actions.py deleted file mode 100644 index b2af086f5..000000000 --- a/mistral/actions/openstack/actions.py +++ /dev/null @@ -1,1084 +0,0 @@ -# Copyright 2014 - Mirantis, Inc. -# -# 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 functools - -from oslo_config import cfg -from oslo_log import log -from oslo_utils import importutils - -from keystoneauth1.identity import v3 as ks_identity_v3 -from keystoneauth1 import session as ks_session -from keystoneauth1.token_endpoint import Token -from keystoneclient import httpclient - -from mistral.actions.openstack import base -from mistral.utils import inspect_utils -from mistral.utils.openstack import keystone as keystone_utils - - -LOG = log.getLogger(__name__) - -CONF = cfg.CONF - - -IRONIC_API_VERSION = '1.34' -"""The default microversion to pass to Ironic API. - -1.34 corresponds to Pike final. -""" - - -def _try_import(module_name): - try: - return importutils.try_import(module_name) - except Exception as e: - msg = 'Unable to load module "%s". %s' % (module_name, str(e)) - LOG.error(msg) - return None - - -aodhclient = _try_import('aodhclient.v2.client') -barbicanclient = _try_import('barbicanclient.client') -cinderclient = _try_import('cinderclient.client') -cinder_api_versions = _try_import('cinderclient.api_versions') -designateclient = _try_import('designateclient.v2.client') -glanceclient = _try_import('glanceclient') -glareclient = _try_import('glareclient.v1.client') -gnocchiclient = _try_import('gnocchiclient.v1.client') -heatclient = _try_import('heatclient.client') -ironic_inspector_client = _try_import('ironic_inspector_client.v1') -ironicclient = _try_import('ironicclient.v1.client') -keystoneclient = _try_import('keystoneclient.v3.client') -manila = _try_import('manilaclient') -manilaclient = _try_import('manilaclient.client') -manila_api_versions = _try_import('manilaclient.api_versions') -magnumclient = _try_import('magnumclient.v1.client') -mistralclient = _try_import('mistralclient.api.v2.client') -muranoclient = _try_import('muranoclient.v1.client') -neutronclient = _try_import('neutronclient.v2_0.client') -nova = _try_import('novaclient') -novaclient = _try_import('novaclient.client') -nova_api_versions = _try_import('novaclient.api_versions') -qinlingclient = _try_import('qinlingclient.v1.client') -senlinclient = _try_import('senlinclient.v1.client') -swift_client = _try_import('swiftclient.client') -swiftservice = _try_import('swiftclient.service') -tackerclient = _try_import('tackerclient.v1_0.client') -troveclient = _try_import('troveclient.v1.client') -vitrageclient = _try_import('vitrageclient.v1.client') -zaqarclient = _try_import('zaqarclient.queues.client') -zunclient = _try_import('zunclient.v1.client') -zun_api_versions = _try_import('zunclient.api_versions') - - -class NovaAction(base.OpenStackAction): - _service_type = 'compute' - - @classmethod - def _get_client_class(cls): - return novaclient.Client - - def _create_client(self, context): - LOG.debug("Nova action security context: %s", context) - - nova_endpoint = self.get_service_endpoint() - - session_and_auth = self.get_session_and_auth(context) - - temp_client = self._get_client_class()( - nova.API_MAX_VERSION, - endpoint_override=nova_endpoint.url, - session=session_and_auth['session'] - ) - - discovered_version = nova_api_versions.discover_version( - temp_client, - nova.API_MAX_VERSION - ) - - return self._get_client_class()( - discovered_version, - endpoint_override=nova_endpoint.url, - session=session_and_auth['session'] - ) - - @classmethod - def _get_fake_client(cls): - return cls._get_client_class()(2) - - -class GlanceAction(base.OpenStackAction): - _service_type = 'image' - - @classmethod - def _get_client_class(cls): - return glanceclient.Client - - def _create_client(self, context): - - LOG.debug("Glance action security context: %s", context) - - glance_endpoint = self.get_service_endpoint() - - session_and_auth = self.get_session_and_auth(context) - - return self._get_client_class()( - '2', - endpoint=glance_endpoint.url, - session=session_and_auth['session'] - ) - - @classmethod - def _get_fake_client(cls): - return cls._get_client_class()(endpoint="http://127.0.0.1:9292/v2") - - -class KeystoneAction(base.OpenStackAction): - - _service_type = 'identity' - - @classmethod - def _get_client_class(cls): - return keystoneclient.Client - - def _create_client(self, context): - - LOG.debug("Keystone action security context: %s", context) - - keystone_endpoint = self.get_service_endpoint() - - session_and_auth = self.get_session_and_auth(context) - - return self._get_client_class()( - endpoint=keystone_endpoint.url, - session=session_and_auth['session'] - ) - - @classmethod - def _get_fake_client(cls): - # Here we need to replace httpclient authenticate method temporarily - authenticate = httpclient.HTTPClient.authenticate - - httpclient.HTTPClient.authenticate = lambda x: True - fake_client = cls._get_client_class()() - - # Once we get fake client, return back authenticate method - httpclient.HTTPClient.authenticate = authenticate - - return fake_client - - -class HeatAction(base.OpenStackAction): - _service_type = 'orchestration' - - @classmethod - def _get_client_class(cls): - return heatclient.Client - - def _create_client(self, context): - - LOG.debug("Heat action security context: %s", context) - - heat_endpoint = self.get_service_endpoint() - - session_and_auth = self.get_session_and_auth(context) - - return self._get_client_class()( - '1', - endpoint_override=heat_endpoint.url, - session=session_and_auth['session'] - ) - - @classmethod - def _get_fake_client(cls): - return cls._get_client_class()( - '1', - endpoint="http://127.0.0.1:8004/v1/fake" - ) - - -class NeutronAction(base.OpenStackAction): - _service_type = 'network' - - @classmethod - def _get_client_class(cls): - return neutronclient.Client - - def _create_client(self, context): - - LOG.debug("Neutron action security context: %s", context) - - neutron_endpoint = self.get_service_endpoint() - - session_and_auth = self.get_session_and_auth(context) - - return self._get_client_class()( - endpoint_override=neutron_endpoint.url, - session=session_and_auth['session'] - ) - - @classmethod - def _get_fake_client(cls): - return cls._get_client_class()(endpoint="http://127.0.0.1") - - -class CinderAction(base.OpenStackAction): - _service_type = 'volumev3' - - @classmethod - def _get_client_class(cls): - return cinderclient.Client - - def _create_client(self, context): - - LOG.debug("Cinder action security context: %s", context) - - cinder_endpoint = self.get_service_endpoint() - - session_and_auth = self.get_session_and_auth(context) - - temp_client = self._get_client_class()( - cinder_api_versions.MAX_VERSION, - endpoint_override=cinder_endpoint.url, - session=session_and_auth['session'] - ) - - discovered_version = cinder_api_versions.discover_version( - temp_client, - cinder_api_versions.APIVersion(cinder_api_versions.MAX_VERSION), - ) - - return self._get_client_class()( - discovered_version, - endpoint_override=cinder_endpoint.url, - session=session_and_auth['session'] - ) - - @classmethod - def _get_fake_client(cls): - return cls._get_client_class()('3') - - -class MistralAction(base.OpenStackAction): - _service_type = 'workflowv2' - - @classmethod - def _get_client_class(cls): - return mistralclient.Client - - def _create_client(self, context): - - LOG.debug("Mistral action security context: %s", context) - - if CONF.pecan.auth_enable: - session_and_auth = self.get_session_and_auth(context) - - return self._get_client_class()( - mistral_url=session_and_auth['auth'].endpoint, - **session_and_auth) - else: - mistral_url = 'http://{}:{}/v2'.format(CONF.api.host, - CONF.api.port) - return self._get_client_class()(mistral_url=mistral_url) - - @classmethod - def _get_fake_client(cls): - return cls._get_client_class()() - - -class TroveAction(base.OpenStackAction): - _service_type = 'database' - - @classmethod - def _get_client_class(cls): - return troveclient.Client - - def _create_client(self, context): - - LOG.debug("Trove action security context: %s", context) - - trove_endpoint = self.get_service_endpoint() - - trove_url = keystone_utils.format_url( - trove_endpoint.url, - {'tenant_id': context.project_id} - ) - - client = self._get_client_class()( - context.user_name, - context.auth_token, - project_id=context.project_id, - auth_url=trove_url, - region_name=trove_endpoint.region, - insecure=context.insecure - ) - - client.client.auth_token = context.auth_token - client.client.management_url = trove_url - - return client - - @classmethod - def _get_fake_client(cls): - return cls._get_client_class()("fake_user", "fake_passwd") - - -class IronicAction(base.OpenStackAction): - _service_name = 'ironic' - - @classmethod - def _get_client_class(cls): - return ironicclient.Client - - def _create_client(self, context): - - LOG.debug("Ironic action security context: %s", context) - - ironic_endpoint = self.get_service_endpoint() - - session_and_auth = self.get_session_and_auth(context) - - client = self._get_client_class()( - os_ironic_api_version=IRONIC_API_VERSION, - endpoint_override=ironic_endpoint.url, - session=session_and_auth['session'] - ) - - return client - - @classmethod - def _get_fake_client(cls): - return cls._get_client_class()( - endpoint_override="http://127.0.0.1:6385/", - session=ks_session.Session(), - ) - - -class BaremetalIntrospectionAction(base.OpenStackAction): - - @classmethod - def _get_client_class(cls): - return ironic_inspector_client.ClientV1 - - @classmethod - def _get_fake_client(cls): - return cls._get_client_class()(inspector_url='http://127.0.0.1') - - def _create_client(self, context): - LOG.debug( - "Baremetal introspection action security context: %s", context) - - inspector_endpoint = keystone_utils.get_endpoint_for_project( - service_type='baremetal-introspection' - ) - auth = Token(endpoint=inspector_endpoint.url, - token=context.auth_token) - - return self._get_client_class()( - api_version=1, - session=ks_session.Session(auth) - ) - - -class SwiftAction(base.OpenStackAction): - _service_name = 'swift' - - @classmethod - def _get_client_class(cls): - return swift_client.Connection - - def _create_client(self, context): - - LOG.debug("Swift action security context: %s", context) - - swift_endpoint = self.get_service_endpoint() - - swift_url = keystone_utils.format_url( - swift_endpoint.url, - {'tenant_id': context.project_id} - ) - - session_and_auth = self.get_session_and_auth(context) - - return self._get_client_class()( - session=session_and_auth['session'], - preauthurl=swift_url - ) - - -class SwiftServiceAction(base.OpenStackAction): - _service_name = 'swift' - - @classmethod - def _get_client_class(cls): - return swiftservice.SwiftService - - def _create_client(self, context): - - LOG.debug("Swift action security context: %s", context) - - swift_endpoint = self.get_service_endpoint() - - swift_opts = { - 'os_storage_url': swift_endpoint.url % { - 'tenant_id': context.project_id - }, - 'os_auth_token': context.auth_token, - 'os_region_name': swift_endpoint.region, - 'os_project_id': context.security.project_id, - } - - return swiftservice.SwiftService(options=swift_opts) - - @classmethod - def _get_client_method(cls, client): - return getattr(client, cls.client_method_name) - - -class ZaqarAction(base.OpenStackAction): - _service_type = 'messaging' - - @classmethod - def _get_client_class(cls): - return zaqarclient.Client - - def _create_client(self, context): - LOG.debug("Zaqar action security context: %s", context) - - zaqar_endpoint = self.get_service_endpoint() - - session_and_auth = self.get_session_and_auth(context) - - return self._get_client_class()( - version=2, - url=zaqar_endpoint.url, - session=session_and_auth['session'] - ) - - @classmethod - def _get_fake_client(cls): - return cls._get_client_class()(version=2) - - @classmethod - def _get_client_method(cls, client): - method = getattr(cls, cls.client_method_name) - - # We can't use partial as it's not supported by getargspec - @functools.wraps(method) - def wrap(*args, **kwargs): - return method(client, *args, **kwargs) - - arguments = inspect_utils.get_arg_list_as_str(method) - # Remove client - wrap.__arguments__ = arguments.split(', ', 1)[1] - - return wrap - - @staticmethod - def queue_messages(client, queue_name, **params): - """Gets a list of messages from the queue. - - :param client: the Zaqar client - :type client: zaqarclient.queues.client - - :param queue_name: Name of the target queue. - :type queue_name: `six.string_type` - - :param params: Filters to use for getting messages. - :type params: **kwargs dict - - :returns: List of messages. - :rtype: `list` - """ - queue = client.queue(queue_name) - - return queue.messages(**params) - - @staticmethod - def queue_post(client, queue_name, messages): - """Posts one or more messages to a queue. - - :param client: the Zaqar client - :type client: zaqarclient.queues.client - - :param queue_name: Name of the target queue. - :type queue_name: `six.string_type` - - :param messages: One or more messages to post. - :type messages: `list` or `dict` - - :returns: A dict with the result of this operation. - :rtype: `dict` - """ - queue = client.queue(queue_name) - - return queue.post(messages) - - @staticmethod - def queue_pop(client, queue_name, count=1): - """Pop `count` messages from the queue. - - :param client: the Zaqar client - :type client: zaqarclient.queues.client - - :param queue_name: Name of the target queue. - :type queue_name: `six.string_type` - - :param count: Number of messages to pop. - :type count: int - - :returns: List of messages. - :rtype: `list` - """ - queue = client.queue(queue_name) - - return queue.pop(count) - - @staticmethod - def claim_messages(client, queue_name, **params): - """Claim messages from the queue - - :param client: the Zaqar client - :type client: zaqarclient.queues.client - - :param queue_name: Name of the target queue. - :type queue_name: `six.string_type` - - :returns: List of claims - :rtype: `list` - """ - queue = client.queue(queue_name) - return queue.claim(**params) - - @staticmethod - def delete_messages(client, queue_name, messages): - """Delete messages from the queue - - :param client: the Zaqar client - :type client: zaqarclient.queues.client - - :param queue_name: Name of the target queue. - :type queue_name: `six.string_type` - - :param messages: List of messages' ids to delete. - :type messages: *args of `six.string_type` - - :returns: List of messages' ids that have been deleted - :rtype: `list` - """ - queue = client.queue(queue_name) - return queue.delete_messages(*messages) - - -class BarbicanAction(base.OpenStackAction): - _service_type = 'key-manager' - - @classmethod - def _get_client_class(cls): - return barbicanclient.Client - - def _create_client(self, context): - LOG.debug("Barbican action security context: %s", context) - - barbican_endpoint = self.get_service_endpoint() - session_and_auth = self.get_session_and_auth(context) - - return self._get_client_class()( - endpoint=barbican_endpoint.url, - session=session_and_auth['session'] - ) - - @classmethod - def _get_fake_client(cls): - return cls._get_client_class()( - project_id="1", - endpoint="http://127.0.0.1:9311" - ) - - @classmethod - def _get_client_method(cls, client): - if cls.client_method_name not in ["secrets_store", - "secrets_retrieve"]: - return super(BarbicanAction, cls)._get_client_method(client) - - method = getattr(cls, cls.client_method_name) - - @functools.wraps(method) - def wrap(*args, **kwargs): - return method(client, *args, **kwargs) - - arguments = inspect_utils.get_arg_list_as_str(method) - - # Remove client. - wrap.__arguments__ = arguments.split(', ', 1)[1] - - return wrap - - @staticmethod - def secrets_store(client, - name=None, - payload=None, - algorithm=None, - bit_length=None, - secret_type=None, - mode=None, expiration=None): - """Create and Store a secret in Barbican. - - :param client: the Barbican client - :type client: barbicanclient.client - - :param name: A friendly name for the Secret - :type name: string - - :param payload: The unencrypted secret data - :type payload: string - - :param algorithm: The algorithm associated with this secret key - :type algorithm: string - - :param bit_length: The bit length of this secret key - :type bit_length: int - - :param secret_type: The secret type for this secret key - :type secret_type: string - - :param mode: The algorithm mode used with this secret keybit_length: - :type mode: string - - :param expiration: The expiration time of the secret in ISO 8601 format - :type expiration: string - - :returns: A new Secret object - :rtype: class:`barbicanclient.secrets.Secret' - """ - - entity = client.secrets.create( - name, - payload, - algorithm, - bit_length, - secret_type, - mode, - expiration - ) - - entity.store() - - return entity._get_formatted_entity() - - @staticmethod - def secrets_retrieve(client, secret_ref): - """Retrieve the payload from a secret in Barbican. - - :param client: the Barbican client - :type client: barbicanclient.client - - :param secret_ref: Full HATEOAS reference to a Secret - :type secret_ref: string - """ - - return client.secrets.get(secret_ref).payload - - -class DesignateAction(base.OpenStackAction): - _service_type = 'dns' - - @classmethod - def _get_client_class(cls): - return designateclient.Client - - def _create_client(self, context): - LOG.debug("Designate action security context: %s", context) - - session_and_auth = self.get_session_and_auth(context) - - client = self._get_client_class()( - session=session_and_auth['session'] - ) - - return client - - @classmethod - def _get_fake_client(cls): - session = keystone_utils.get_admin_session() - return cls._get_client_class()( - endpoint_override="http://127.0.0.1:9001/", - session=session - ) - - -class MagnumAction(base.OpenStackAction): - - @classmethod - def _get_client_class(cls): - return magnumclient.Client - - def _create_client(self, context): - - LOG.debug("Magnum action security context: %s", context) - - keystone_endpoint = keystone_utils.get_keystone_endpoint() - auth_url = keystone_endpoint.url - magnum_url = keystone_utils.get_endpoint_for_project('magnum').url - - return self._get_client_class()( - magnum_url=magnum_url, - auth_token=context.auth_token, - project_id=context.project_id, - auth_url=auth_url, - insecure=context.insecure - ) - - @classmethod - def _get_fake_client(cls): - return cls._get_client_class()(auth_url='X', magnum_url='X') - - -class MuranoAction(base.OpenStackAction): - _service_name = 'murano' - - @classmethod - def _get_client_class(cls): - return muranoclient.Client - - def _create_client(self, context): - - LOG.debug("Murano action security context: %s", context) - - keystone_endpoint = keystone_utils.get_keystone_endpoint() - murano_endpoint = self.get_service_endpoint() - - return self._get_client_class()( - endpoint=murano_endpoint.url, - token=context.auth_token, - tenant=context.project_id, - region_name=murano_endpoint.region, - auth_url=keystone_endpoint.url, - insecure=context.insecure - ) - - @classmethod - def _get_fake_client(cls): - return cls._get_client_class()("http://127.0.0.1:8082/") - - -class TackerAction(base.OpenStackAction): - _service_name = 'tacker' - - @classmethod - def _get_client_class(cls): - return tackerclient.Client - - def _create_client(self, context): - - LOG.debug("Tacker action security context: %s", context) - - keystone_endpoint = keystone_utils.get_keystone_endpoint() - tacker_endpoint = self.get_service_endpoint() - - return self._get_client_class()( - endpoint_url=tacker_endpoint.url, - token=context.auth_token, - tenant_id=context.project_id, - region_name=tacker_endpoint.region, - auth_url=keystone_endpoint.url, - insecure=context.insecure - ) - - @classmethod - def _get_fake_client(cls): - return cls._get_client_class()() - - -class SenlinAction(base.OpenStackAction): - _service_name = 'senlin' - - @classmethod - def _get_client_class(cls): - return senlinclient.Client - - def _create_client(self, context): - - LOG.debug("Senlin action security context: %s", context) - - keystone_endpoint = keystone_utils.get_keystone_endpoint() - senlin_endpoint = self.get_service_endpoint() - - if context.is_trust_scoped and keystone_utils.is_token_trust_scoped( - context.auth_token): - if context.trust_id is None: - raise Exception( - "'trust_id' must be provided in the admin context." - ) - - auth = ks_identity_v3.Password( - auth_url=keystone_endpoint.url, - trust_id=context.trust_id, - username=CONF.keystone_authtoken.username, - password=CONF.keystone_authtoken.password, - user_domain_name=CONF.keystone_authtoken.user_domain_name - ) - else: - auth = ks_identity_v3.Token( - auth_url=keystone_endpoint.url, - token=context.auth_token, - project_id=context.project_id - ) - - return self._get_client_class()( - endpoint_url=senlin_endpoint.url, - session=ks_session.Session(auth=auth), - tenant_id=context.project_id, - region_name=senlin_endpoint.region, - auth_url=keystone_endpoint.url, - insecure=context.insecure - ) - - @classmethod - def _get_fake_client(cls): - # Senlin client changed interface a bit, let's skip __init__ altogether - class_ = cls._get_client_class() - return class_.__new__(class_) - - -class AodhAction(base.OpenStackAction): - _service_type = 'alarming' - - @classmethod - def _get_client_class(cls): - return aodhclient.Client - - def _create_client(self, context): - - LOG.debug("Aodh action security context: %s", context) - - aodh_endpoint = self.get_service_endpoint() - - endpoint_url = keystone_utils.format_url( - aodh_endpoint.url, - {'tenant_id': context.project_id} - ) - - return self._get_client_class()( - endpoint_url, - region_name=aodh_endpoint.region, - token=context.auth_token, - username=context.user_name, - insecure=context.insecure - ) - - @classmethod - def _get_fake_client(cls): - return cls._get_client_class()() - - -class GnocchiAction(base.OpenStackAction): - _service_type = 'metric' - - @classmethod - def _get_client_class(cls): - return gnocchiclient.Client - - def _create_client(self, context): - LOG.debug("Gnocchi action security context: %s", context) - - gnocchi_endpoint = keystone_utils.get_endpoint_for_project( - service_type="metric") - keystone_endpoint = keystone_utils.get_keystone_endpoint() - - auth = ks_identity_v3.Token( - auth_url=keystone_endpoint.url, - tenant_name=context.user_name, - token=context.auth_token, - tenant_id=context.project_id - ) - - return self._get_client_class()( - adapter_options={"region_name": gnocchi_endpoint.region, - "project_id": context.project_id, - "endpoint": gnocchi_endpoint.url, - "insecure": context.insecure}, - session_options={"auth": auth} - ) - - @classmethod - def _get_fake_client(cls): - return cls._get_client_class()() - - -class GlareAction(base.OpenStackAction): - _service_name = 'glare' - - @classmethod - def _get_client_class(cls): - return glareclient.Client - - def _create_client(self, context): - - LOG.debug("Glare action security context: %s", context) - - glare_endpoint = self.get_service_endpoint() - - endpoint_url = keystone_utils.format_url( - glare_endpoint.url, - {'tenant_id': context.project_id} - ) - - return self._get_client_class()( - endpoint_url, - **self.get_session_and_auth(context) - ) - - @classmethod - def _get_fake_client(cls): - return cls._get_client_class()("http://127.0.0.1:9494/") - - -class VitrageAction(base.OpenStackAction): - _service_type = 'rca' - - @classmethod - def _get_client_class(cls): - return vitrageclient.Client - - def _create_client(self, context): - - LOG.debug("Vitrage action security context: %s", context) - - vitrage_endpoint = self.get_service_endpoint() - - endpoint_url = keystone_utils.format_url( - vitrage_endpoint.url, - {'tenant_id': context.project_id} - ) - - session_and_auth = self.get_session_and_auth(context) - - return vitrageclient.Client( - session=session_and_auth['session'], - endpoint_override=endpoint_url - ) - - @classmethod - def _get_fake_client(cls): - return cls._get_client_class()() - - -class ZunAction(base.OpenStackAction): - _service_name = 'appcontainer' - - @classmethod - def _get_client_class(cls): - return zunclient.Client - - def _create_client(self, context): - - LOG.debug("Zun action security context: %s", context) - - keystone_endpoint = keystone_utils.get_keystone_endpoint() - zun_endpoint = self.get_service_endpoint() - session_and_auth = self.get_session_and_auth(context) - - temp_client = self._get_client_class()( - zun_api_versions.MAX_API_VERSION, - endpoint_override=zun_endpoint.url, - auth_url=keystone_endpoint.url, - session=session_and_auth['auth'] - ) - - discovered_version = zun_api_versions.discover_version( - temp_client, - zun_api_versions.APIVersion(zun_api_versions.MAX_API_VERSION) - ) - - return self._get_client_class()( - discovered_version, - endpoint_override=zun_endpoint.url, - auth_url=keystone_endpoint.url, - session=session_and_auth['session'] - ) - - @classmethod - def _get_fake_client(cls): - session = keystone_utils.get_admin_session() - return cls._get_client_class()( - endpoint_override="http://127.0.0.1:9517/", - session=session - ) - - -class QinlingAction(base.OpenStackAction): - _service_type = 'function-engine' - - @classmethod - def _get_client_class(cls): - return qinlingclient.Client - - def _create_client(self, context): - qinling_endpoint = self.get_service_endpoint() - session_and_auth = self.get_session_and_auth(context) - - return self._get_client_class()(endpoint_override=qinling_endpoint.url, - session=session_and_auth['session']) - - @classmethod - def _get_fake_client(cls): - session = keystone_utils.get_admin_session() - return cls._get_client_class()( - endpoint_override="http://127.0.0.1:7070/", - session=session - ) - - -class ManilaAction(base.OpenStackAction): - _service_type = 'sharev2' - - @classmethod - def _get_client_class(cls): - return manilaclient.Client - - def _create_client(self, context): - - LOG.debug("Manila action security context: %s", context) - - manila_endpoint = self.get_service_endpoint() - - session_and_auth = self.get_session_and_auth(context) - - temp_client = self._get_client_class()( - manila.API_MAX_VERSION, - service_catalog_url=manila_endpoint.url, - session=session_and_auth['auth'] - ) - - discovered_version = manila_api_versions.discover_version( - temp_client, - manila.API_MAX_VERSION - ) - - client = self._get_client_class()( - discovered_version, - service_catalog_url=manila_endpoint.url, - session=session_and_auth['session'] - ) - - return client - - @classmethod - def _get_fake_client(cls): - return cls._get_client_class()( - manila.API_MAX_VERSION, - input_auth_token='token', - service_catalog_url='http://127.0.0.1:8786') diff --git a/mistral/actions/openstack/base.py b/mistral/actions/openstack/base.py deleted file mode 100644 index 0317bee88..000000000 --- a/mistral/actions/openstack/base.py +++ /dev/null @@ -1,136 +0,0 @@ -# Copyright 2014 - Mirantis, Inc. -# -# 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 abc -import inspect -import traceback - -from oslo_log import log - -from mistral import exceptions as exc -from mistral.utils.openstack import keystone as keystone_utils -from mistral_lib import actions - -LOG = log.getLogger(__name__) - - -class OpenStackAction(actions.Action): - """OpenStack Action. - - OpenStack Action is the basis of all OpenStack-specific actions, - which are constructed via OpenStack Action generators. - """ - _kwargs_for_run = {} - client_method_name = None - _service_name = None - _service_type = None - _client_class = None - - def __init__(self, **kwargs): - self._kwargs_for_run = kwargs - self.action_region = self._kwargs_for_run.pop('action_region', None) - - @abc.abstractmethod - def _create_client(self, context): - """Creates client required for action operation.""" - return None - - @classmethod - def _get_client_class(cls): - return cls._client_class - - @classmethod - def _get_client_method(cls, client): - hierarchy_list = cls.client_method_name.split('.') - attribute = client - - for attr in hierarchy_list: - attribute = getattr(attribute, attr) - - return attribute - - @classmethod - def _get_fake_client(cls): - """Returns python-client instance which initiated via wrong args. - - It is needed for getting client-method args and description for - saving into DB. - """ - # Default is simple _get_client_class instance - return cls._get_client_class()() - - @classmethod - def get_fake_client_method(cls): - return cls._get_client_method(cls._get_fake_client()) - - def _get_client(self, context): - """Returns python-client instance via cache or creation - - Gets client instance according to specific OpenStack Service - (e.g. Nova, Glance, Heat, Keystone etc) - - """ - return self._create_client(context) - - def get_session_and_auth(self, context): - """Get keystone session and auth parameters. - - :param context: the action context - :return: dict that can be used to initialize service clients - """ - - return keystone_utils.get_session_and_auth( - service_name=self._service_name, - service_type=self._service_type, - region_name=self.action_region, - ctx=context) - - def get_service_endpoint(self): - """Get OpenStack service endpoint. - - 'service_name' and 'service_type' are defined in specific OpenStack - service action. - """ - endpoint = keystone_utils.get_endpoint_for_project( - service_name=self._service_name, - service_type=self._service_type, - region_name=self.action_region - ) - - return endpoint - - def run(self, context): - try: - method = self._get_client_method(self._get_client(context)) - - result = method(**self._kwargs_for_run) - - if inspect.isgenerator(result): - return [v for v in result] - - return result - except Exception as e: - # Print the traceback for the last exception so that we can see - # where the issue comes from. - LOG.warning(traceback.format_exc()) - - raise exc.ActionException( - "%s.%s failed: %s" % - (self.__class__.__name__, self.client_method_name, str(e)) - ) - - def test(self, context): - return dict( - zip(self._kwargs_for_run, ['test'] * len(self._kwargs_for_run)) - ) diff --git a/mistral/actions/openstack/mapping.json b/mistral/actions/openstack/mapping.json deleted file mode 100644 index f5028d308..000000000 --- a/mistral/actions/openstack/mapping.json +++ /dev/null @@ -1,1505 +0,0 @@ -{ - "_comment": "Mapping OpenStack action namespaces to all its actions. Each action name is mapped to python-client method name in this namespace.", - "nova": { - "_comment": "It uses novaclient.v2.", - "agents_convert_into_with_meta": "agents.convert_into_with_meta", - "agents_create": "agents.create", - "agents_delete": "agents.delete", - "agents_find": "agents.find", - "agents_findall": "agents.findall", - "agents_list": "agents.list", - "agents_update": "agents.update", - "aggregates_add_host": "aggregates.add_host", - "aggregates_convert_into_with_meta": "aggregates.convert_into_with_meta", - "aggregates_create": "aggregates.create", - "aggregates_delete": "aggregates.delete", - "aggregates_find": "aggregates.find", - "aggregates_findall": "aggregates.findall", - "aggregates_get": "aggregates.get", - "aggregates_get_details": "aggregates.get_details", - "aggregates_list": "aggregates.list", - "aggregates_remove_host": "aggregates.remove_host", - "aggregates_set_metadata": "aggregates.set_metadata", - "aggregates_update": "aggregates.update", - "availability_zones_convert_into_with_meta": "availability_zones.convert_into_with_meta", - "availability_zones_find": "availability_zones.find", - "availability_zones_findall": "availability_zones.findall", - "availability_zones_list": "availability_zones.list", - "flavor_access_add_tenant_access": "flavor_access.add_tenant_access", - "flavor_access_convert_into_with_meta": "flavor_access.convert_into_with_meta", - "flavor_access_find": "flavor_access.find", - "flavor_access_findall": "flavor_access.findall", - "flavor_access_list": "flavor_access.list", - "flavor_access_remove_tenant_access": "flavor_access.remove_tenant_access", - "flavors_convert_into_with_meta": "flavors.convert_into_with_meta", - "flavors_create": "flavors.create", - "flavors_delete": "flavors.delete", - "flavors_find": "flavors.find", - "flavors_findall": "flavors.findall", - "flavors_get": "flavors.get", - "flavors_list": "flavors.list", - "hypervisor_stats_convert_into_with_meta": "hypervisor_stats.convert_into_with_meta", - "hypervisor_stats_statistics": "hypervisor_stats.statistics", - "hypervisors_convert_into_with_meta": "hypervisors.convert_into_with_meta", - "hypervisors_find": "hypervisors.find", - "hypervisors_findall": "hypervisors.findall", - "hypervisors_get": "hypervisors.get", - "hypervisors_list": "hypervisors.list", - "hypervisors_search": "hypervisors.search", - "hypervisors_statistics": "hypervisors.statistics", - "hypervisors_uptime": "hypervisors.uptime", - "glance_find_image": "glance.find_image", - "glance_list": "glance.list", - "keypairs_convert_into_with_meta": "keypairs.convert_into_with_meta", - "keypairs_create": "keypairs.create", - "keypairs_delete": "keypairs.delete", - "keypairs_find": "keypairs.find", - "keypairs_findall": "keypairs.findall", - "keypairs_get": "keypairs.get", - "keypairs_list": "keypairs.list", - "limits_convert_into_with_meta": "limits.convert_into_with_meta", - "limits_get": "limits.get", - "neutron_find_network": "neutron.find_network", - "quota_classes_convert_into_with_meta": "quota_classes.convert_into_with_meta", - "quota_classes_get": "quota_classes.get", - "quota_classes_update": "quota_classes.update", - "quotas_convert_into_with_meta": "quotas.convert_into_with_meta", - "quotas_defaults": "quotas.defaults", - "quotas_delete": "quotas.delete", - "quotas_get": "quotas.get", - "quotas_update": "quotas.update", - "server_groups_convert_into_with_meta": "server_groups.convert_into_with_meta", - "server_groups_create": "server_groups.create", - "server_groups_delete": "server_groups.delete", - "server_groups_find": "server_groups.find", - "server_groups_findall": "server_groups.findall", - "server_groups_get": "server_groups.get", - "server_groups_list": "server_groups.list", - "server_migrations_convert_into_with_meta": "server_migrations.convert_into_with_meta", - "server_migrations_find": "server_migrations.find", - "server_migrations_findall": "server_migrations.findall", - "server_migrations_get": "server_migrations.get", - "server_migrations_list": "server_migrations.list", - "server_migrations_live_migrate_force_complete": "server_migrations.live_migrate_force_complete", - "server_migrations_live_migration_abort": "server_migrations.live_migration_abort", - "servers_add_security_group": "servers.add_security_group", - "servers_backup": "servers.backup", - "servers_change_password": "servers.change_password", - "servers_clear_password": "servers.clear_password", - "servers_confirm_resize": "servers.confirm_resize", - "servers_convert_into_with_meta": "servers.convert_into_with_meta", - "servers_create": "servers.create", - "servers_create_image": "servers.create_image", - "servers_delete": "servers.delete", - "servers_delete_meta": "servers.delete_meta", - "servers_diagnostics": "servers.diagnostics", - "servers_evacuate": "servers.evacuate", - "servers_find": "servers.find", - "servers_findall": "servers.findall", - "servers_force_delete": "servers.force_delete", - "servers_get": "servers.get", - "servers_get_console_output": "servers.get_console_output", - "servers_get_mks_console": "servers.get_mks_console", - "servers_get_password": "servers.get_password", - "servers_get_rdp_console": "servers.get_rdp_console", - "servers_get_serial_console": "servers.get_serial_console", - "servers_get_spice_console": "servers.get_spice_console", - "servers_get_vnc_console": "servers.get_vnc_console", - "servers_interface_attach": "servers.interface_attach", - "servers_interface_detach": "servers.interface_detach", - "servers_interface_list": "servers.interface_list", - "servers_ips": "servers.ips", - "servers_list": "servers.list", - "servers_list_security_group": "servers.list_security_group", - "servers_live_migrate": "servers.live_migrate", - "servers_lock": "servers.lock", - "servers_migrate": "servers.migrate", - "servers_pause": "servers.pause", - "servers_reboot": "servers.reboot", - "servers_rebuild": "servers.rebuild", - "servers_remove_security_group": "servers.remove_security_group", - "servers_rescue": "servers.rescue", - "servers_reset_network": "servers.reset_network", - "servers_reset_state": "servers.reset_state", - "servers_resize": "servers.resize", - "servers_restore": "servers.restore", - "servers_resume": "servers.resume", - "servers_revert_resize": "servers.revert_resize", - "servers_set_meta": "servers.set_meta", - "servers_set_meta_item": "servers.set_meta_item", - "servers_shelve": "servers.shelve", - "servers_shelve_offload": "servers.shelve_offload", - "servers_start": "servers.start", - "servers_stop": "servers.stop", - "servers_suspend": "servers.suspend", - "servers_trigger_crash_dump": "servers.trigger_crash_dump", - "servers_unlock": "servers.unlock", - "servers_unpause": "servers.unpause", - "servers_unrescue": "servers.unrescue", - "servers_unshelve": "servers.unshelve", - "servers_update": "servers.update", - "services_convert_into_with_meta": "services.convert_into_with_meta", - "services_delete": "services.delete", - "services_disable": "services.disable", - "services_disable_log_reason": "services.disable_log_reason", - "services_enable": "services.enable", - "services_find": "services.find", - "services_findall": "services.findall", - "services_force_down": "services.force_down", - "services_list": "services.list", - "usage_convert_into_with_meta": "usage.convert_into_with_meta", - "usage_find": "usage.find", - "usage_findall": "usage.findall", - "usage_get": "usage.get", - "usage_list": "usage.list", - "versions_convert_into_with_meta": "versions.convert_into_with_meta", - "versions_find": "versions.find", - "versions_findall": "versions.findall", - "versions_get_current": "versions.get_current", - "versions_list": "versions.list", - "volumes_convert_into_with_meta": "volumes.convert_into_with_meta", - "volumes_create_server_volume": "volumes.create_server_volume", - "volumes_delete_server_volume": "volumes.delete_server_volume", - "volumes_get_server_volume": "volumes.get_server_volume", - "volumes_get_server_volumes": "volumes.get_server_volumes", - "volumes_update_server_volume": "volumes.update_server_volume" - }, - "glance": { - "_comment": "It uses glanceclient.v2.", - "image_members_create": "image_members.create", - "image_members_delete": "image_members.delete", - "image_members_list": "image_members.list", - "image_members_update": "image_members.update", - "image_tags_delete": "image_tags.delete", - "image_tags_update": "image_tags.update", - "images_add_location": "images.add_location", - "images_create": "images.create", - "images_data": "images.data", - "images_deactivate": "images.deactivate", - "images_delete": "images.delete", - "images_delete_locations": "images.delete_locations", - "images_get": "images.get", - "images_list": "images.list", - "images_reactivate": "images.reactivate", - "images_update": "images.update", - "images_update_location": "images.update_location", - "images_upload": "images.upload", - "schemas_get": "schemas.get", - "tasks_create": "tasks.create", - "tasks_get": "tasks.get", - "tasks_list": "tasks.list", - "metadefs_resource_type_associate": "metadefs_resource_type.associate", - "metadefs_resource_type_deassociate": "metadefs_resource_type.deassociate", - "metadefs_resource_type_get": "metadefs_resource_type.get", - "metadefs_resource_type_list": "metadefs_resource_type.list", - "metadefs_property_create": "metadefs_property.create", - "metadefs_property_delete": "metadefs_property.delete", - "metadefs_property_delete_all": "metadefs_property.delete_all", - "metadefs_property_get": "metadefs_property.get", - "metadefs_property_list": "metadefs_property.list", - "metadefs_property_update": "metadefs_property.update", - "metadefs_object_create": "metadefs_object.create", - "metadefs_object_delete": "metadefs_object.delete", - "metadefs_object_delete_all": "metadefs_object.delete_all", - "metadefs_object_get": "metadefs_object.get", - "metadefs_object_list": "metadefs_object.list", - "metadefs_object_update": "metadefs_object.update", - "metadefs_tag_create": "metadefs_tag.create", - "metadefs_tag_create_multiple": "metadefs_tag.create_multiple", - "metadefs_tag_delete": "metadefs_tag.delete", - "metadefs_tag_delete_all": "metadefs_tag.delete_all", - "metadefs_tag_get": "metadefs_tag.get", - "metadefs_tag_list": "metadefs_tag.list", - "metadefs_tag_update": "metadefs_tag.update", - "metadefs_namespace_create": "metadefs_namespace.create", - "metadefs_namespace_delete": "metadefs_namespace.delete", - "metadefs_namespace_get": "metadefs_namespace.get", - "metadefs_namespace_list": "metadefs_namespace.list", - "metadefs_namespace_update": "metadefs_namespace.update", - "versions_list": "versions.list" - }, - "keystone": { - "_comment": "It uses keystoneclient.v3.", - "credentials_create": "credentials.create", - "credentials_delete": "credentials.delete", - "credentials_find": "credentials.find", - "credentials_get": "credentials.get", - "credentials_list": "credentials.list", - "credentials_update": "credentials.update", - "domains_create": "domains.create", - "domains_delete": "domains.delete", - "domains_find": "domains.find", - "domains_get": "domains.get", - "domains_list": "domains.list", - "domains_update": "domains.update", - "endpoint_filter_add_endpoint_to_project": "endpoint_filter.add_endpoint_to_project", - "endpoint_filter_check_endpoint_in_project": "endpoint_filter.check_endpoint_in_project", - "endpoint_filter_delete_endpoint_from_project": "endpoint_filter.delete_endpoint_from_project", - "endpoint_filter_list_endpoints_for_project": "endpoint_filter.list_endpoints_for_project", - "endpoint_filter_list_projects_for_endpoint": "endpoint_filter.list_projects_for_endpoint", - "endpoint_policy_check_policy_association_for_endpoint": "endpoint_policy.check_policy_association_for_endpoint", - "endpoint_policy_check_policy_association_for_region_and_service": "endpoint_policy.check_policy_association_for_region_and_service", - "endpoint_policy_check_policy_association_for_service": "endpoint_policy.check_policy_association_for_service", - "endpoint_policy_create_policy_association_for_endpoint": "endpoint_policy.create_policy_association_for_endpoint", - "endpoint_policy_create_policy_association_for_region_and_service": "endpoint_policy.create_policy_association_for_region_and_service", - "endpoint_policy_create_policy_association_for_service": "endpoint_policy.create_policy_association_for_service", - "endpoint_policy_delete_policy_association_for_endpoint": "endpoint_policy.delete_policy_association_for_endpoint", - "endpoint_policy_delete_policy_association_for_region_and_service": "endpoint_policy.delete_policy_association_for_region_and_service", - "endpoint_policy_delete_policy_association_for_service": "endpoint_policy.delete_policy_association_for_service", - "endpoint_policy_get_policy_for_endpoint": "endpoint_policy.get_policy_for_endpoint", - "endpoint_policy_list_endpoints_for_policy": "endpoint_policy.list_endpoints_for_policy", - "endpoints_create": "endpoints.create", - "endpoints_delete": "endpoints.delete", - "endpoints_find": "endpoints.find", - "endpoints_get": "endpoints.get", - "endpoints_list": "endpoints.list", - "endpoints_update": "endpoints.update", - "groups_create": "groups.create", - "groups_delete": "groups.delete", - "groups_find": "groups.find", - "groups_get": "groups.get", - "groups_list": "groups.list", - "groups_update": "groups.update", - "oauth1.consumers_build_url": "oauth1.consumers.build_url", - "oauth1.consumers_create": "oauth1.consumers.create", - "oauth1.consumers_delete": "oauth1.consumers.delete", - "oauth1.consumers_find": "oauth1.consumers.find", - "oauth1.consumers_get": "oauth1.consumers.get", - "oauth1.consumers_list": "oauth1.consumers.list", - "oauth1.consumers_put": "oauth1.consumers.put", - "oauth1.consumers_update": "oauth1.consumers.update", - "oauth1.request_tokens_authorize": "oauth1.request_tokens.authorize", - "oauth1.request_tokens_build_url": "oauth1.request_tokens.build_url", - "oauth1.request_tokens_create": "oauth1.request_tokens.create", - "oauth1.request_tokens_delete": "oauth1.request_tokens.delete", - "oauth1.request_tokens_find": "oauth1.request_tokens.find", - "oauth1.request_tokens_get": "oauth1.request_tokens.get", - "oauth1.request_tokens_list": "oauth1.request_tokens.list", - "oauth1.request_tokens_put": "oauth1.request_tokens.put", - "oauth1.request_tokens_update": "oauth1.request_tokens.update", - "oauth1.access_tokens_build_url": "oauth1.access_tokens.build_url", - "oauth1.access_tokens_create": "oauth1.access_tokens.create", - "oauth1.access_tokens_delete": "oauth1.access_tokens.delete", - "oauth1.access_tokens_find": "oauth1.access_tokens.find", - "oauth1.access_tokens_get": "oauth1.access_tokens.get", - "oauth1.access_tokens_list": "oauth1.access_tokens.list", - "oauth1.access_tokens_put": "oauth1.access_tokens.put", - "oauth1.access_tokens_update": "oauth1.access_tokens.update", - "policies_create": "policies.create", - "policies_delete": "policies.delete", - "policies_find": "policies.find", - "policies_get": "policies.get", - "policies_list": "policies.list", - "policies_update": "policies.update", - "projects_create": "projects.create", - "projects_delete": "projects.delete", - "projects_find": "projects.find", - "projects_get": "projects.get", - "projects_list": "projects.list", - "projects_update": "projects.update", - "regions_create": "regions.create", - "regions_delete": "regions.delete", - "regions_find": "regions.find", - "regions_get": "regions.get", - "regions_list": "regions.list", - "regions_update": "regions.update", - "role_assignments_create": "role_assignments.create", - "role_assignments_delete": "role_assignments.delete", - "role_assignments_find": "role_assignments.find", - "role_assignments_get": "role_assignments.get", - "role_assignments_list": "role_assignments.list", - "role_assignments_update": "role_assignments.update", - "roles_check": "roles.check", - "roles_create": "roles.create", - "roles_delete": "roles.delete", - "roles_find": "roles.find", - "roles_get": "roles.get", - "roles_grant": "roles.grant", - "roles_list": "roles.list", - "roles_revoke": "roles.revoke", - "roles_update": "roles.update", - "services_create": "services.create", - "services_delete": "services.delete", - "services_find": "services.find", - "services_get": "services.get", - "services_list": "services.list", - "services_update": "services.update", - "trusts_create": "trusts.create", - "trusts_delete": "trusts.delete", - "trusts_find": "trusts.find", - "trusts_get": "trusts.get", - "trusts_list": "trusts.list", - "trusts_update": "trusts.update", - "users_add_to_group": "users.add_to_group", - "users_check_in_group": "users.check_in_group", - "users_create": "users.create", - "users_delete": "users.delete", - "users_find": "users.find", - "users_get": "users.get", - "users_list": "users.list", - "users_remove_from_group": "users.remove_from_group", - "users_update": "users.update", - "users_update_password": "users.update_password" - }, - "heat": { - "_comment": "It uses heatclient.v1.", - "actions_cancel_update": "actions.cancel_update", - "actions_check": "actions.check", - "actions_resume": "actions.resume", - "actions_suspend": "actions.suspend", - "build_info_build_info": "build_info.build_info", - "events_get": "events.get", - "events_list": "events.list", - "resource_types_generate_template": "resource_types.generate_template", - "resource_types_get": "resource_types.get", - "resource_types_list": "resource_types.list", - "resources_generate_template": "resources.generate_template", - "resources_get": "resources.get", - "resources_list": "resources.list", - "resources_mark_unhealthy": "resources.mark_unhealthy", - "resources_metadata": "resources.metadata", - "resources_signal": "resources.signal", - "services_list": "services.list", - "software_configs_create": "software_configs.create", - "software_configs_delete": "software_configs.delete", - "software_configs_get": "software_configs.get", - "software_configs_list": "software_configs.list", - "software_deployments_create": "software_deployments.create", - "software_deployments_delete": "software_deployments.delete", - "software_deployments_get": "software_deployments.get", - "software_deployments_list": "software_deployments.list", - "software_deployments_metadata": "software_deployments.metadata", - "software_deployments_update": "software_deployments.update", - "stacks_abandon": "stacks.abandon", - "stacks_create": "stacks.create", - "stacks_delete": "stacks.delete", - "stacks_environment": "stacks.environment", - "stacks_get": "stacks.get", - "stacks_list": "stacks.list", - "stacks_output_list": "stacks.output_list", - "stacks_output_show": "stacks.output_show", - "stacks_preview": "stacks.preview", - "stacks_preview_update": "stacks.preview_update", - "stacks_restore": "stacks.restore", - "stacks_snapshot": "stacks.snapshot", - "stacks_snapshot_delete": "stacks.snapshot_delete", - "stacks_snapshot_list": "stacks.snapshot_list", - "stacks_snapshot_show": "stacks.snapshot_show", - "stacks_template": "stacks.template", - "stacks_update": "stacks.update", - "stacks_validate": "stacks.validate", - "template_versions_get": "template_versions.get", - "template_versions_list": "template_versions.list" - }, - "aodh": { - "_comment": "It uses aodhclient.v2.", - "capabilities_list": "capabilities.list", - "alarm_create": "alarm.create", - "alarm_delete": "alarm.delete", - "alarm_get": "alarm.get", - "alarm_get_state": "alarm.get_state", - "alarm_list": "alarm.list", - "alarm_set_state": "alarm.set_state", - "alarm_update": "alarm.update", - "alarm_query": "alarm.query", - "alarm_history_get": "alarm_history.get", - "alarm_history_search": "alarm_history.search" - }, - "gnocchi":{ - "_comment": "It uses gnocchiclient.v1.", - "archive_policy_create": "archive_policy.create", - "archive_policy_delete": "archive_policy.delete", - "archive_policy_get": "archive_policy.get", - "archive_policy_list": "archive_policy.list", - "archive_policy_update": "archive_policy.update", - "archive_policy_rule_create": "archive_policy_rule.create", - "archive_policy_rule_delete": "archive_policy_rule.delete", - "archive_policy_rule_get": "archive_policy_rule.get", - "archive_policy_rule_list": "archive_policy_rule.list", - "capabilities_list": "capabilities.list", - "measures_add": "metric.add_measures", - "metric_batch_metrics_measures": "metric.batch_metrics_measures", - "metric_batch_resources_metrics_measures": "metric.batch_resources_metrics_measures", - "metric_create": "metric.create", - "metric_delete": "metric.delete", - "metric_get": "metric.get", - "measures_get": "metric.get_measures", - "metric_list": "metric.list", - "resource_batch_delete_resource": "resource.batch_delete", - "resource_create": "resource.create", - "resource_delete": "resource.delete", - "resource_get": "resource.get", - "resource_history": "resource.history", - "resource_list": "resource.list", - "resource_search": "resource.search", - "resource_update": "resource.update", - "resource_type_create": "resource_type.create", - "resource_type_delete": "resource_type.delete", - "resource_type_get": "resource_type.get", - "resource_type_list": "resource_type.list", - "resource_type_update": "resource_type.update", - "measures_aggregation": "metric.aggregation", - "status": "status.get" - }, - "neutron": { - "_comment": "It uses neutronclient.v2_0.", - "add_gateway_router": "add_gateway_router", - "add_interface_router": "add_interface_router", - "add_network_to_dhcp_agent": "add_network_to_dhcp_agent", - "add_router_to_l3_agent": "add_router_to_l3_agent", - "associate_health_monitor": "associate_health_monitor", - "connect_network_gateway": "connect_network_gateway", - "create_ext": "create_ext", - "create_firewall": "create_firewall", - "create_firewall_policy": "create_firewall_policy", - "create_firewall_rule": "create_firewall_rule", - "create_floatingip": "create_floatingip", - "create_gateway_device": "create_gateway_device", - "create_health_monitor": "create_health_monitor", - "create_ikepolicy": "create_ikepolicy", - "create_ipsec_site_connection": "create_ipsec_site_connection", - "create_ipsecpolicy": "create_ipsecpolicy", - "create_lbaas_healthmonitor": "create_lbaas_healthmonitor", - "create_lbaas_member": "create_lbaas_member", - "create_lbaas_pool": "create_lbaas_pool", - "create_listener": "create_listener", - "create_loadbalancer": "create_loadbalancer", - "create_member": "create_member", - "create_metering_label": "create_metering_label", - "create_metering_label_rule": "create_metering_label_rule", - "create_network": "create_network", - "create_network_gateway": "create_network_gateway", - "create_pool": "create_pool", - "create_port": "create_port", - "create_qos_queue": "create_qos_queue", - "create_router": "create_router", - "create_security_group": "create_security_group", - "create_security_group_rule": "create_security_group_rule", - "create_subnet": "create_subnet", - "create_subnetpool": "create_subnetpool", - "create_vip": "create_vip", - "create_vpnservice": "create_vpnservice", - "delete_agent": "delete_agent", - "delete_ext": "delete_ext", - "delete_firewall": "delete_firewall", - "delete_firewall_policy": "delete_firewall_policy", - "delete_firewall_rule": "delete_firewall_rule", - "delete_floatingip": "delete_floatingip", - "delete_gateway_device": "delete_gateway_device", - "delete_health_monitor": "delete_health_monitor", - "delete_ikepolicy": "delete_ikepolicy", - "delete_ipsec_site_connection": "delete_ipsec_site_connection", - "delete_ipsecpolicy": "delete_ipsecpolicy", - "delete_lbaas_healthmonitor": "delete_lbaas_healthmonitor", - "delete_lbaas_member": "delete_lbaas_member", - "delete_lbaas_pool": "delete_lbaas_pool", - "delete_listener": "delete_listener", - "delete_loadbalancer": "delete_loadbalancer", - "delete_member": "delete_member", - "delete_metering_label": "delete_metering_label", - "delete_metering_label_rule": "delete_metering_label_rule", - "delete_network": "delete_network", - "delete_network_gateway": "delete_network_gateway", - "delete_pool": "delete_pool", - "delete_port": "delete_port", - "delete_qos_queue": "delete_qos_queue", - "delete_quota": "delete_quota", - "delete_router": "delete_router", - "delete_security_group": "delete_security_group", - "delete_security_group_rule": "delete_security_group_rule", - "delete_subnet": "delete_subnet", - "delete_subnetpool": "delete_subnetpool", - "delete_vip": "delete_vip", - "delete_vpnservice": "delete_vpnservice", - "disassociate_health_monitor": "disassociate_health_monitor", - "disconnect_network_gateway": "disconnect_network_gateway", - "extend_create": "extend_create", - "extend_delete": "extend_delete", - "extend_list": "extend_list", - "extend_show": "extend_show", - "extend_update": "extend_update", - "firewall_policy_insert_rule": "firewall_policy_insert_rule", - "firewall_policy_remove_rule": "firewall_policy_remove_rule", - "get_lbaas_agent_hosting_loadbalancer": "get_lbaas_agent_hosting_loadbalancer", - "get_lbaas_agent_hosting_pool": "get_lbaas_agent_hosting_pool", - "get_quotas_tenant": "get_quotas_tenant", - "list_agents": "list_agents", - "list_dhcp_agent_hosting_networks": "list_dhcp_agent_hosting_networks", - "list_ext": "list_ext", - "list_extensions": "list_extensions", - "list_firewall_policies": "list_firewall_policies", - "list_firewall_rules": "list_firewall_rules", - "list_firewalls": "list_firewalls", - "list_floatingips": "list_floatingips", - "list_gateway_devices": "list_gateway_devices", - "list_health_monitors": "list_health_monitors", - "list_ikepolicies": "list_ikepolicies", - "list_ipsec_site_connections": "list_ipsec_site_connections", - "list_ipsecpolicies": "list_ipsecpolicies", - "list_l3_agent_hosting_routers": "list_l3_agent_hosting_routers", - "list_lbaas_healthmonitors": "list_lbaas_healthmonitors", - "list_lbaas_loadbalancers": "list_lbaas_loadbalancers", - "list_lbaas_members": "list_lbaas_members", - "list_lbaas_pools": "list_lbaas_pools", - "list_listeners": "list_listeners", - "list_loadbalancers": "list_loadbalancers", - "list_loadbalancers_on_lbaas_agent": "list_loadbalancers_on_lbaas_agent", - "list_members": "list_members", - "list_metering_label_rules": "list_metering_label_rules", - "list_metering_labels": "list_metering_labels", - "list_network_gateways": "list_network_gateways", - "list_networks": "list_networks", - "list_networks_on_dhcp_agent": "list_networks_on_dhcp_agent", - "list_pools": "list_pools", - "list_pools_on_lbaas_agent": "list_pools_on_lbaas_agent", - "list_ports": "list_ports", - "list_qos_queues": "list_qos_queues", - "list_quotas": "list_quotas", - "list_routers": "list_routers", - "list_routers_on_l3_agent": "list_routers_on_l3_agent", - "list_security_group_rules": "list_security_group_rules", - "list_security_groups": "list_security_groups", - "list_service_providers": "list_service_providers", - "list_subnetpools": "list_subnetpools", - "list_subnets": "list_subnets", - "list_vips": "list_vips", - "list_vpnservices": "list_vpnservices", - "remove_gateway_router": "remove_gateway_router", - "remove_interface_router": "remove_interface_router", - "remove_network_from_dhcp_agent": "remove_network_from_dhcp_agent", - "remove_router_from_l3_agent": "remove_router_from_l3_agent", - "retrieve_pool_stats": "retrieve_pool_stats", - "show_agent": "show_agent", - "show_ext": "show_ext", - "show_extension": "show_extension", - "show_firewall": "show_firewall", - "show_firewall_policy": "show_firewall_policy", - "show_firewall_rule": "show_firewall_rule", - "show_floatingip": "show_floatingip", - "show_gateway_device": "show_gateway_device", - "show_health_monitor": "show_health_monitor", - "show_ikepolicy": "show_ikepolicy", - "show_ipsec_site_connection": "show_ipsec_site_connection", - "show_ipsecpolicy": "show_ipsecpolicy", - "show_lbaas_healthmonitor": "show_lbaas_healthmonitor", - "show_lbaas_member": "show_lbaas_member", - "show_lbaas_pool": "show_lbaas_pool", - "show_listener": "show_listener", - "show_loadbalancer": "show_loadbalancer", - "show_member": "show_member", - "show_metering_label": "show_metering_label", - "show_metering_label_rule": "show_metering_label_rule", - "show_network": "show_network", - "show_network_gateway": "show_network_gateway", - "show_pool": "show_pool", - "show_port": "show_port", - "show_qos_queue": "show_qos_queue", - "show_quota": "show_quota", - "show_router": "show_router", - "show_security_group": "show_security_group", - "show_security_group_rule": "show_security_group_rule", - "show_subnet": "show_subnet", - "show_subnetpool": "show_subnetpool", - "show_vip": "show_vip", - "show_vpnservice": "show_vpnservice", - "update_agent": "update_agent", - "update_ext": "update_ext", - "update_firewall": "update_firewall", - "update_firewall_policy": "update_firewall_policy", - "update_firewall_rule": "update_firewall_rule", - "update_floatingip": "update_floatingip", - "update_gateway_device": "update_gateway_device", - "update_health_monitor": "update_health_monitor", - "update_ikepolicy": "update_ikepolicy", - "update_ipsec_site_connection": "update_ipsec_site_connection", - "update_ipsecpolicy": "update_ipsecpolicy", - "update_lbaas_healthmonitor": "update_lbaas_healthmonitor", - "update_lbaas_member": "update_lbaas_member", - "update_lbaas_pool": "update_lbaas_pool", - "update_listener": "update_listener", - "update_loadbalancer": "update_loadbalancer", - "update_member": "update_member", - "update_network": "update_network", - "update_network_gateway": "update_network_gateway", - "update_pool": "update_pool", - "update_port": "update_port", - "update_quota": "update_quota", - "update_router": "update_router", - "update_security_group": "update_security_group", - "update_subnet": "update_subnet", - "update_subnetpool": "update_subnetpool", - "update_vip": "update_vip", - "update_vpnservice": "update_vpnservice" - }, - "cinder": { - "_comment": "It uses cinderclient.v3.", - "availability_zones_find": "availability_zones.find", - "availability_zones_findall": "availability_zones.findall", - "availability_zones_list": "availability_zones.list", - "backups_create": "backups.create", - "backups_delete": "backups.delete", - "backups_export_record": "backups.export_record", - "backups_find": "backups.find", - "backups_findall": "backups.findall", - "backups_get": "backups.get", - "backups_import_record": "backups.import_record", - "backups_list": "backups.list", - "backups_reset_state": "backups.reset_state", - "capabilities_get": "capabilities.get", - "cgsnapshots_create": "cgsnapshots.create", - "cgsnapshots_delete": "cgsnapshots.delete", - "cgsnapshots_find": "cgsnapshots.find", - "cgsnapshots_findall": "cgsnapshots.findall", - "cgsnapshots_get": "cgsnapshots.get", - "cgsnapshots_list": "cgsnapshots.list", - "cgsnapshots_update": "cgsnapshots.update", - "consistencygroups_create": "consistencygroups.create", - "consistencygroups_create_from_src": "consistencygroups.create_from_src", - "consistencygroups_delete": "consistencygroups.delete", - "consistencygroups_find": "consistencygroups.find", - "consistencygroups_findall": "consistencygroups.findall", - "consistencygroups_get": "consistencygroups.get", - "consistencygroups_list": "consistencygroups.list", - "consistencygroups_update": "consistencygroups.update", - "limits_get": "limits.get", - "pools_list": "pools.list", - "qos_specs_associate": "qos_specs.associate", - "qos_specs_create": "qos_specs.create", - "qos_specs_delete": "qos_specs.delete", - "qos_specs_disassociate": "qos_specs.disassociate", - "qos_specs_disassociate_all": "qos_specs.disassociate_all", - "qos_specs_find": "qos_specs.find", - "qos_specs_findall": "qos_specs.findall", - "qos_specs_get": "qos_specs.get", - "qos_specs_get_associations": "qos_specs.get_associations", - "qos_specs_list": "qos_specs.list", - "qos_specs_set_keys": "qos_specs.set_keys", - "qos_specs_unset_keys": "qos_specs.unset_keys", - "quota_classes_get": "quota_classes.get", - "quota_classes_update": "quota_classes.update", - "quotas_defaults": "quotas.defaults", - "quotas_delete": "quotas.delete", - "quotas_get": "quotas.get", - "quotas_update": "quotas.update", - "restores_restore": "restores.restore", - "services_disable": "services.disable", - "services_disable_log_reason": "services.disable_log_reason", - "services_enable": "services.enable", - "services_find": "services.find", - "services_findall": "services.findall", - "services_list": "services.list", - "transfers_accept": "transfers.accept", - "transfers_create": "transfers.create", - "transfers_delete": "transfers.delete", - "transfers_find": "transfers.find", - "transfers_findall": "transfers.findall", - "transfers_get": "transfers.get", - "transfers_list": "transfers.list", - "volume_encryption_types_create": "volume_encryption_types.create", - "volume_encryption_types_delete": "volume_encryption_types.delete", - "volume_encryption_types_find": "volume_encryption_types.find", - "volume_encryption_types_findall": "volume_encryption_types.findall", - "volume_encryption_types_get": "volume_encryption_types.get", - "volume_encryption_types_list": "volume_encryption_types.list", - "volume_encryption_types_update": "volume_encryption_types.update", - "volume_snapshots_create": "volume_snapshots.create", - "volume_snapshots_delete": "volume_snapshots.delete", - "volume_snapshots_delete_metadata": "volume_snapshots.delete_metadata", - "volume_snapshots_find": "volume_snapshots.find", - "volume_snapshots_findall": "volume_snapshots.findall", - "volume_snapshots_get": "volume_snapshots.get", - "volume_snapshots_list": "volume_snapshots.list", - "volume_snapshots_reset_state": "volume_snapshots.reset_state", - "volume_snapshots_set_metadata": "volume_snapshots.set_metadata", - "volume_snapshots_update": "volume_snapshots.update", - "volume_snapshots_update_all_metadata": "volume_snapshots.update_all_metadata", - "volume_snapshots_update_snapshot_status": "volume_snapshots.update_snapshot_status", - "volume_type_access_add_project_access": "volume_type_access.add_project_access", - "volume_type_access_find": "volume_type_access.find", - "volume_type_access_findall": "volume_type_access.findall", - "volume_type_access_list": "volume_type_access.list", - "volume_type_access_remove_project_access": "volume_type_access.remove_project_access", - "volume_types_create": "volume_types.create", - "volume_types_default": "volume_types.default", - "volume_types_delete": "volume_types.delete", - "volume_types_find": "volume_types.find", - "volume_types_findall": "volume_types.findall", - "volume_types_get": "volume_types.get", - "volume_types_list": "volume_types.list", - "volume_types_update": "volume_types.update", - "volumes_attach": "volumes.attach", - "volumes_begin_detaching": "volumes.begin_detaching", - "volumes_create": "volumes.create", - "volumes_delete": "volumes.delete", - "volumes_delete_image_metadata": "volumes.delete_image_metadata", - "volumes_delete_metadata": "volumes.delete_metadata", - "volumes_detach": "volumes.detach", - "volumes_extend": "volumes.extend", - "volumes_find": "volumes.find", - "volumes_findall": "volumes.findall", - "volumes_force_delete": "volumes.force_delete", - "volumes_get": "volumes.get", - "volumes_get_encryption_metadata": "volumes.get_encryption_metadata", - "volumes_get_pools": "volumes.get_pools", - "volumes_initialize_connection": "volumes.initialize_connection", - "volumes_list": "volumes.list", - "volumes_manage": "volumes.manage", - "volumes_migrate_volume": "volumes.migrate_volume", - "volumes_migrate_volume_completion": "volumes.migrate_volume_completion", - "volumes_reserve": "volumes.reserve", - "volumes_reset_state": "volumes.reset_state", - "volumes_retype": "volumes.retype", - "volumes_roll_detaching": "volumes.roll_detaching", - "volumes_set_bootable": "volumes.set_bootable", - "volumes_set_image_metadata": "volumes.set_image_metadata", - "volumes_set_metadata": "volumes.set_metadata", - "volumes_show_image_metadata": "volumes.show_image_metadata", - "volumes_terminate_connection": "volumes.terminate_connection", - "volumes_unmanage": "volumes.unmanage", - "volumes_unreserve": "volumes.unreserve", - "volumes_update": "volumes.update", - "volumes_update_all_metadata": "volumes.update_all_metadata", - "volumes_update_readonly_flag": "volumes.update_readonly_flag", - "volumes_upload_to_image": "volumes.upload_to_image" - }, - "trove": { - "_comment": "It uses troveclient.v1.", - "backups_create": "backups.create", - "backups_delete": "backups.delete", - "backups_find": "backups.find", - "backups_findall": "backups.findall", - "backups_get": "backups.get", - "backups_list": "backups.list", - "clusters_add_shard": "clusters.add_shard", - "clusters_create": "clusters.create", - "clusters_delete": "clusters.delete", - "clusters_find": "clusters.find", - "clusters_findall": "clusters.findall", - "clusters_get": "clusters.get", - "clusters_grow": "clusters.grow", - "clusters_list": "clusters.list", - "clusters_shrink": "clusters.shrink", - "configuration_parameters_find": "configuration_parameters.find", - "configuration_parameters_findall": "configuration_parameters.findall", - "configuration_parameters_get_parameter": "configuration_parameters.get_parameter", - "configuration_parameters_get_parameter_by_version": "configuration_parameters.get_parameter_by_version", - "configuration_parameters_list": "configuration_parameters.list", - "configuration_parameters_parameters": "configuration_parameters.parameters", - "configuration_parameters_parameters_by_version": "configuration_parameters.parameters_by_version", - "configurations_create": "configurations.create", - "configurations_delete": "configurations.delete", - "configurations_edit": "configurations.edit", - "configurations_find": "configurations.find", - "configurations_findall": "configurations.findall", - "configurations_get": "configurations.get", - "configurations_instances": "configurations.instances", - "configurations_list": "configurations.list", - "configurations_update": "configurations.update", - "databases_create": "databases.create", - "databases_delete": "databases.delete", - "databases_find": "databases.find", - "databases_findall": "databases.findall", - "databases_list": "databases.list", - "datastore_versions_find": "datastore_versions.find", - "datastore_versions_findall": "datastore_versions.findall", - "datastore_versions_get": "datastore_versions.get", - "datastore_versions_get_by_uuid": "datastore_versions.get_by_uuid", - "datastore_versions_list": "datastore_versions.list", - "datastore_versions_update": "datastore_versions.update", - "datastores_find": "datastores.find", - "datastores_findall": "datastores.findall", - "datastores_get": "datastores.get", - "datastores_list": "datastores.list", - "flavors_find": "flavors.find", - "flavors_findall": "flavors.findall", - "flavors_get": "flavors.get", - "flavors_list": "flavors.list", - "flavors_list_datastore_version_associated_flavors": "flavors.list_datastore_version_associated_flavors", - "instances_backups": "instances.backups", - "instances_configuration": "instances.configuration", - "instances_create": "instances.create", - "instances_delete": "instances.delete", - "instances_edit": "instances.edit", - "instances_eject_replica_source": "instances.eject_replica_source", - "instances_find": "instances.find", - "instances_findall": "instances.findall", - "instances_get": "instances.get", - "instances_list": "instances.list", - "instances_modify": "instances.modify", - "instances_promote_to_replica_source": "instances.promote_to_replica_source", - "instances_resize_instance": "instances.resize_instance", - "instances_resize_volume": "instances.resize_volume", - "instances_restart": "instances.restart", - "limits_find": "limits.find", - "limits_findall": "limits.findall", - "limits_list": "limits.list", - "metadata_create": "metadata.create", - "metadata_delete": "metadata.delete", - "metadata_edit": "metadata.edit", - "metadata_list": "metadata.list", - "metadata_show": "metadata.show", - "metadata_update": "metadata.update", - "root_create": "root.create", - "root_create_cluster_root": "root.create_cluster_root", - "root_create_instance_root": "root.create_instance_root", - "root_delete": "root.delete", - "root_disable_instance_root": "root.disable_instance_root", - "root_find": "root.find", - "root_findall": "root.findall", - "root_is_cluster_root_enabled": "root.is_cluster_root_enabled", - "root_is_instance_root_enabled": "root.is_instance_root_enabled", - "root_is_root_enabled": "root.is_root_enabled", - "root_list": "root.list", - "security_group_rules_create": "security_group_rules.create", - "security_group_rules_delete": "security_group_rules.delete", - "security_group_rules_find": "security_group_rules.find", - "security_group_rules_findall": "security_group_rules.findall", - "security_group_rules_list": "security_group_rules.list", - "security_groups_find": "security_groups.find", - "security_groups_findall": "security_groups.findall", - "security_groups_get": "security_groups.get", - "security_groups_list": "security_groups.list", - "users_change_passwords": "users.change_passwords", - "users_create": "users.create", - "users_delete": "users.delete", - "users_find": "users.find", - "users_findall": "users.findall", - "users_get": "users.get", - "users_grant": "users.grant", - "users_list": "users.list", - "users_list_access": "users.list_access", - "users_revoke": "users.revoke", - "users_update_attributes": "users.update_attributes" - }, - "ironic": { - "_comment": "It uses ironicclient.v1.", - "chassis_create": "chassis.create", - "chassis_delete": "chassis.delete", - "chassis_get": "chassis.get", - "chassis_list": "chassis.list", - "chassis_list_nodes": "chassis.list_nodes", - "chassis_update": "chassis.update", - "driver_delete": "driver.delete", - "driver_get": "driver.get", - "driver_get_vendor_passthru_methods": "driver.get_vendor_passthru_methods", - "driver_list": "driver.list", - "driver_properties": "driver.properties", - "driver_raid_logical_disk_properties": "driver.raid_logical_disk_properties", - "driver_update": "driver.update", - "driver_vendor_passthru": "driver.vendor_passthru", - "node_create": "node.create", - "node_delete": "node.delete", - "node_get": "node.get", - "node_get_boot_device": "node.get_boot_device", - "node_get_by_instance_uuid": "node.get_by_instance_uuid", - "node_get_console": "node.get_console", - "node_get_supported_boot_devices": "node.get_supported_boot_devices", - "node_get_vendor_passthru_methods": "node.get_vendor_passthru_methods", - "node_list": "node.list", - "node_list_ports": "node.list_ports", - "node_set_boot_device": "node.set_boot_device", - "node_set_console_mode": "node.set_console_mode", - "node_set_maintenance": "node.set_maintenance", - "node_set_power_state": "node.set_power_state", - "node_set_provision_state": "node.set_provision_state", - "node_set_target_raid_config": "node.set_target_raid_config", - "node_states": "node.states", - "node_update": "node.update", - "node_validate": "node.validate", - "node_vendor_passthru": "node.vendor_passthru", - "node_vif_attach": "node.vif_attach", - "node_vif_detach": "node.vif_detach", - "node_vif_list": "node.vif_list", - "node_wait_for_provision_state": "node.wait_for_provision_state", - "port_create": "port.create", - "port_delete": "port.delete", - "port_get": "port.get", - "port_get_by_address": "port.get_by_address", - "port_list": "port.list", - "port_update": "port.update" - }, - "baremetal_introspection": { - "_comment": "It uses ironic_inspector_client.v1.", - "abort": "abort", - "introspect": "introspect", - "get_status": "get_status", - "get_data": "get_data", - "rules_create": "rules.create", - "rules_delete": "rules.delete", - "rules_delete_all": "rules.delete_all", - "rules_from_json": "rules.from_json", - "rules_get": "rules.get", - "rules_get_all": "rules.get_all", - "wait_for_finish": "wait_for_finish" - }, - "swift": { - "_comment": "It uses swiftclient.v1.", - "head_account": "head_account", - "get_account": "get_account", - "post_account": "post_account", - "head_container": "head_container", - "get_container": "get_container", - "put_container": "put_container", - "post_container": "post_container", - "delete_container": "delete_container", - "head_object": "head_object", - "get_object": "get_object", - "put_object": "put_object", - "post_object": "post_object", - "delete_object": "delete_object", - "copy_object": "copy_object", - "get_capabilities": "get_capabilities" - }, - "swiftservice": { - "_comment": "It uses swiftclient.service.", - "capabilities": "capabilities", - "copy": "copy", - "delete": "delete", - "download": "download", - "list": "list", - "post": "post", - "stat": "stat", - "upload": "upload" - }, - "zaqar": { - "_comment": "It uses zaqarclient.v2.", - "claim_messages": "claim_messages", - "delete_messages": "delete_messages", - "queue_messages": "queue_messages", - "queue_post": "queue_post", - "queue_pop": "queue_pop" - }, - "barbican": { - "_comment": "It uses barbicanclient", - "cas_get": "cas.get", - "cas_list": "cas.list", - "cas_total": "cas.total", - "containers_create": "containers.create", - "containers_create_certificate": "containers.create_certificate", - "containers_create_rsa": "containers.create_rsa", - "containers_delete": "containers.delete", - "containers_get": "containers.get", - "containers_list": "containers.list", - "containers_register_consumer": "containers.register_consumer", - "containers_remove_consumer": "containers.remove_consumer", - "containers_total": "containers.total", - "orders_create": "orders.create", - "orders_create_asymmetric": "orders.create_asymmetric", - "orders_create_certificate": "orders.create_certificate", - "orders_create_key": "orders.create_key", - "orders_delete": "orders.delete", - "orders_get": "orders.get", - "orders_list": "orders.list", - "orders_total": "orders.total", - "secrets_create": "secrets.create", - "secrets_delete": "secrets.delete", - "secrets_get": "secrets.get", - "secrets_list": "secrets.list", - "secrets_total": "secrets.total", - "secrets_retrieve": "secrets_retrieve", - "secrets_store": "secrets_store" - }, - "mistral": { - "_comment": "It uses mistralclient.v2.", - "action_executions_create": "action_executions.create", - "action_executions_delete": "action_executions.delete", - "action_executions_find": "action_executions.find", - "action_executions_get": "action_executions.get", - "action_executions_list": "action_executions.list", - "action_executions_update": "action_executions.update", - "actions_create": "actions.create", - "actions_delete": "actions.delete", - "actions_find": "actions.find", - "actions_get": "actions.get", - "actions_list": "actions.list", - "actions_update": "actions.update", - "cron_triggers_create": "cron_triggers.create", - "cron_triggers_delete": "cron_triggers.delete", - "cron_triggers_find": "cron_triggers.find", - "cron_triggers_get": "cron_triggers.get", - "cron_triggers_list": "cron_triggers.list", - "environments_create": "environments.create", - "environments_delete": "environments.delete", - "environments_find": "environments.find", - "environments_get": "environments.get", - "environments_list": "environments.list", - "environments_update": "environments.update", - "executions_create": "executions.create", - "executions_delete": "executions.delete", - "executions_find": "executions.find", - "executions_get": "executions.get", - "executions_list": "executions.list", - "executions_update": "executions.update", - "members_create": "members.create", - "members_delete": "members.delete", - "members_find": "members.find", - "members_get": "members.get", - "members_list": "members.list", - "members_update": "members.update", - "services_find": "services.find", - "services_list": "services.list", - "tasks_find": "tasks.find", - "tasks_get": "tasks.get", - "tasks_list": "tasks.list", - "tasks_rerun": "tasks.rerun", - "workbooks_create": "workbooks.create", - "workbooks_delete": "workbooks.delete", - "workbooks_find": "workbooks.find", - "workbooks_get": "workbooks.get", - "workbooks_list": "workbooks.list", - "workbooks_update": "workbooks.update", - "workbooks_validate": "workbooks.validate", - "workflows_create": "workflows.create", - "workflows_delete": "workflows.delete", - "workflows_find": "workflows.find", - "workflows_get": "workflows.get", - "workflows_list": "workflows.list", - "workflows_update": "workflows.update", - "workflows_validate": "workflows.validate" - }, - "designate": { - "_comment": "It uses designateclient.v2.", - "quotas_list": "quotas.list", - "quotas_reset": "quotas.reset", - "quotas_update": "quotas.update", - "recordset_create": "recordsets.create", - "recordset_delete": "recordsets.delete", - "recordset_get": "recordsets.get", - "recordset_list": "recordsets.list", - "recordset_list_all_zones": "recordsets.list_all_zones", - "recordset_update": "recordsets.update", - "nameservers_list": "nameservers.list", - "pools_list": "pools.list", - "limits_get": "limits.get", - "blacklists_create": "blacklists.create", - "blacklists_get": "blacklists.get", - "blacklists_list": "blacklists.list", - "blacklists_update": "blacklists.update", - "blacklists_delete": "blacklists.delete" - }, - "magnum": { - "_comment": "It uses magnumclient.v1.", - "baymodels_create": "baymodels.create", - "baymodels_delete": "baymodels.delete", - "baymodels_get": "baymodels.get", - "baymodels_list": "baymodels.list", - "baymodels_update": "baymodels.update", - "bays_create": "bays.create", - "bays_delete": "bays.delete", - "bays_get": "bays.get", - "bays_list": "bays.list", - "bays_update": "bays.update", - "certificates_create": "certificates.create", - "certificates_get": "certificates.get", - "certificates_rotate_ca": "certificates.rotate_ca", - "mservices_list": "mservices.list" - }, - "murano":{ - "_comment": "It uses muranoclient.v1.", - "categories_add": "categories.add", - "categories_delete": "categories.delete", - "categories_get": "categories.get", - "categories_list": "categories.list", - "deployments_list": "deployments.list", - "deployments_reports": "deployments.reports", - "env_templates_clone": "env_templates.clone", - "env_templates_create": "env_templates.create", - "env_templates_create_app": "env_templates.create_app", - "env_templates_create_env": "env_templates.create_env", - "env_templates_delete": "env_templates.delete", - "env_templates_delete_app": "env_templates.delete_app", - "env_templates_get": "env_templates.get", - "env_templates_list": "env_templates.list", - "env_templates_update": "env_templates.update", - "environments_create": "environments.create", - "environments_delete": "environments.delete", - "environments_find": "environments.find", - "environments_findall": "environments.findall", - "environments_get": "environments.get", - "environments_last_status": "environments.last_status", - "environments_list": "environments.list", - "environments_update": "environments.update", - "instance_statistics_get": "instance_statistics.get", - "instance_statistics_get_aggregated": "instance_statistics.get_aggregated", - "packages_create": "packages.create", - "packages_delete": "packages.delete", - "packages_download": "packages.download", - "packages_filter": "packages.filter", - "packages_get": "packages.get", - "packages_get_logo": "packages.get_logo", - "packages_get_supplier_logo": "packages.get_supplier_logo", - "packages_get_ui": "packages.get_ui", - "packages_list": "packages.list", - "packages_toggle_active": "packages.toggle_active", - "packages_toggle_public": "packages.toggle_public", - "packages_update": "packages.update", - "request_statistics_list": "request_statistics.list", - "services_delete": "services.delete", - "services_get": "services.get", - "services_list": "services.list", - "services_post": "services.post", - "sessions_configure": "sessions.configure", - "sessions_delete": "sessions.delete", - "sessions_deploy": "sessions.deploy", - "sessions_get": "sessions.get" - }, - "tacker":{ - "_comment": "It uses tackerclient.v1_0.", - "list_extensions": "list_extensions", - "show_extension": "show_extension", - "create_vnfd": "create_vnfd", - "delete_vnfd": "delete_vnfd", - "list_vnfds": "list_vnfds", - "show_vnfd": "show_vnfd", - "create_vnf": "create_vnf", - "update_vnf": "update_vnf", - "delete_vnf": "delete_vnf", - "list_vnfs": "list_vnfs", - "show_vnf": "show_vnf", - "create_vnffgd": "create_vnffgd", - "delete_vnffgd": "delete_vnffgd", - "list_vnffgds": "list_vnffgds", - "show_vnffgd": "show_vnffgd", - "create_vnffg": "create_vnffg", - "update_vnffg": "update_vnffg", - "delete_vnffg": "delete_vnffg", - "list_vnffgs": "list_vnffgs", - "show_vnffg": "show_vnffg", - "create_nsd": "create_nsd", - "delete_nsd": "delete_nsd", - "list_nsds": "list_nsds", - "show_nsd": "show_nsd", - "create_ns": "create_ns", - "delete_ns": "delete_ns", - "list_nss": "list_nss", - "show_ns": "show_ns", - "create_vim": "create_vim", - "update_vim": "update_vim", - "delete_vim": "delete_vim", - "list_vims": "list_vims", - "show_vim": "show_vim" - }, - "senlin":{ - "_comment": "It uses senlinclient.v1_0.", - "profile_types": "profile_types", - "get_profile_type": "get_profile_type", - "profiles": "profiles", - "create_profile": "create_profile", - "get_profile": "get_profile", - "update_profile": "update_profile", - "delete_profile": "delete_profile", - "validate_profile": "validate_profile", - "policy_types": "policy_types", - "get_policy_type": "get_policy_type", - "policies": "policies", - "create_policy": "create_policy", - "get_policy": "get_policy", - "update_policy": "update_policy", - "delete_policy": "delete_policy", - "validate_policy": "validate_policy", - "clusters": "clusters", - "create_cluster": "create_cluster", - "get_cluster": "get_cluster", - "update_cluster": "update_cluster", - "delete_cluster": "delete_cluster", - "cluster_add_nodes": "cluster_add_nodes", - "cluster_del_nodes": "cluster_del_nodes", - "cluster_resize": "cluster_resize", - "cluster_scale_out": "cluster_scale_out", - "cluster_scale_in": "cluster_scale_in", - "cluster_policies": "cluster_policies", - "get_cluster_policy": "get_cluster_policy", - "cluster_attach_policy": "cluster_attach_policy", - "cluster_detach_policy": "cluster_detach_policy", - "cluster_update_policy": "cluster_update_policy", - "check_cluster": "check_cluster", - "recover_cluster": "recover_cluster", - "nodes": "nodes", - "create_node": "create_node", - "get_node": "get_node", - "update_node": "update_node", - "delete_node": "delete_node", - "check_node": "check_node", - "recover_node": "recover_node", - "receivers": "receivers", - "create_receiver": "create_receiver", - "get_receiver": "get_receiver", - "delete_receiver": "delete_receiver", - "events": "events", - "get_event": "get_event", - "actions": "actions", - "get_action": "get_action" - }, - "glare": { - "_comment": "It uses glareclient.v1.", - "artifacts_create": "artifacts.create", - "artifacts_delete": "artifacts.delete", - "artifacts_get": "artifacts.get", - "artifacts_list": "artifacts.list", - "artifacts_update": "artifacts.update", - "artifacts_activate": "artifacts.activate", - "artifacts_deactivate": "artifacts.deactivate", - "artifacts_reactivate": "artifacts.reactivate", - "artifacts_publish": "artifacts.publish", - "artifacts_add_tag": "artifacts.add_tag", - "artifacts_remove_tag": "artifacts.remove_tag", - "artifacts_get_type_list": "artifacts.get_type_list", - "artifacts_get_type_schema": "artifacts.get_type_schema", - "artifacts_upload_blob": "artifacts.upload_blob", - "artifacts_download_blob": "artifacts.download_blob", - "artifacts_add_external_location": "artifacts.add_external_location" - }, - "vitrage": { - "_comment": "It uses vitrageclient.v1.", - "alarm_list": "alarm.list", - "alarm_get": "alarm.get", - "alarm_count": "alarm.count", - "event_post": "event.post", - "healthcheck_get": "healthcheck.get", - "rca_get": "rca.get", - "resource_list": "resource.list", - "resource_get": "resource.get", - "template_list": "template.list", - "template_show": "template.show", - "template_add": "template.add", - "template_delete": "template.delete", - "template_validate": "template.validate", - "topology_get": "topology.get", - "webhook_list": "webhook.list", - "webhook_show": "webhook.show", - "webhook_add": "webhook.add", - "webhook_delete": "webhook.delete" - }, - "zun":{ - "_comment": "It uses zunclient.v1. ", - "containers_add_security_group": "containers.add_security_group", - "containers_attach": "containers.attach", - "containers_commit": "containers.commit", - "containers_create": "containers.create", - "containers_delete": "containers.delete", - "containers_execute": "containers.execute", - "containers_execute_resize": "containers.execute_resize", - "containers_get": "containers.get", - "containers_get_archive": "containers.get_archive", - "containers_kill": "containers.kill", - "containers_list": "containers.list", - "containers_logs": "containers.logs", - "containers_network_attach": "containers.network_attach", - "containers_network_detach": "containers.network_detach", - "containers_pause": "containers.pause", - "containers_put_archive": "containers.put_archive", - "containers_remove_security_group": "containers.remove_security_group", - "containers_rename": "containers.rename", - "containers_resize": "containers.resize", - "containers_restart": "containers.restart", - "containers_run": "containers.run", - "containers_start": "containers.start", - "containers_stats": "containers.stats", - "containers_stop": "containers.stop", - "containers_top": "containers.top", - "containers_update": "containers.update", - "hosts_list": "hosts.list", - "hosts_get": "hosts.get", - "images_delete": "images.delete", - "images_list": "images.list", - "services_delete": "services.delete", - "services_disable": "services.disable", - "services_enable": "services.enable", - "services_list": "services.list" - }, - "qinling": { - "_comment": "Qinling v1 actions", - "runtimes_create": "runtimes.create", - "runtimes_list": "runtimes.list", - "runtimes_get": "runtimes.get", - "runtimes_delete": "runtimes.delete", - "functions_create": "functions.create", - "functions_list": "functions.list", - "functions_get": "functions.get", - "functions_update": "functions.update", - "functions_delete": "functions.delete", - "function_executions_create": "function_executions.create", - "function_executions_list": "function_executions.list", - "function_executions_get": "function_executions.get", - "function_executions_delete": "function_executions.delete", - "function_executions_get_log": "function_executions.get_log", - "jobs_create": "jobs.create", - "jobs_list": "jobs.list", - "jobs_get": "jobs.get", - "jobs_update": "jobs.update", - "jobs_delete": "jobs.delete", - "webhooks_create": "webhooks.create", - "webhooks_list": "webhooks.list", - "webhooks_get": "webhooks.get", - "webhooks_update": "webhooks.update", - "webhooks_delete": "webhooks.delete" - }, - "manila": { - "_comment": "It uses manilaclient.v2.", - "availability_zones_list": "availability_zones.list", - "limits_get": "limits.get", - "messages_delete": "messages.delete", - "messages_find": "messages.find", - "messages_findall": "messages.findall", - "messages_get": "messages.get", - "messages_list": "messages.list", - "pools_list": "pools.list", - "quota_classes_find": "quota_classes.find", - "quota_classes_findall": "quota_classes.findall", - "quota_classes_get": "quota_classes.get", - "quota_classes_list": "quota_classes.list", - "quota_classes_update": "quota_classes.update", - "quotas_defaults": "quotas.defaults", - "quotas_delete": "quotas.delete", - "quotas_find": "quotas.find", - "quotas_findall": "quotas.findall", - "quotas_get": "quotas.get", - "quotas_list": "quotas.list", - "quotas_update": "quotas.update", - "security_services_create": "security_services.create", - "security_services_delete": "security_services.delete", - "security_services_find": "security_services.find", - "security_services_findall": "security_services.findall", - "security_services_get": "security_services.get", - "security_services_list": "security_services.list", - "security_services_update": "security_services.update", - "services_disable": "services.disable", - "services_enable": "services.enable", - "services_list": "services.list", - "services_server_api_version": "services.server_api_version", - "share_export_locations_find": "share_export_locations.find", - "share_export_locations_findall": "share_export_locations.findall", - "share_export_locations_get": "share_export_locations.get", - "share_export_locations_list": "share_export_locations.list", - "share_group_snapshots_create": "share_group_snapshots.create", - "share_group_snapshots_delete": "share_group_snapshots.delete", - "share_group_snapshots_find": "share_group_snapshots.find", - "share_group_snapshots_findall": "share_group_snapshots.findall", - "share_group_snapshots_get": "share_group_snapshots.get", - "share_group_snapshots_list": "share_group_snapshots.list", - "share_group_snapshots_reset_state": "share_group_snapshots.reset_state", - "share_group_snapshots_update": "share_group_snapshots.update", - "share_group_type_access_add_project_access": "share_group_type_access.add_project_access", - "share_group_type_access_find": "share_group_type_access.find", - "share_group_type_access_findall": "share_group_type_access.findall", - "share_group_type_access_list": "share_group_type_access.list", - "share_group_type_access_remove_project_access": "share_group_type_access.remove_project_access", - "share_group_types_create": "share_group_types.create", - "share_group_types_delete": "share_group_types.delete", - "share_group_types_find": "share_group_types.find", - "share_group_types_findall": "share_group_types.findall", - "share_group_types_get": "share_group_types.get", - "share_group_types_list": "share_group_types.list", - "share_groups_create": "share_groups.create", - "share_groups_delete": "share_groups.delete", - "share_groups_find": "share_groups.find", - "share_groups_findall": "share_groups.findall", - "share_groups_get": "share_groups.get", - "share_groups_list": "share_groups.list", - "share_groups_reset_state": "share_groups.reset_state", - "share_groups_update": "share_groups.update", - "share_instance_export_locations_find": "share_instance_export_locations.find", - "share_instance_export_locations_findall": "share_instance_export_locations.findall", - "share_instance_export_locations_get": "share_instance_export_locations.get", - "share_instance_export_locations_list": "share_instance_export_locations.list", - "share_instances_do_list": "share_instances.do_list", - "share_instances_find": "share_instances.find", - "share_instances_findall": "share_instances.findall", - "share_instances_force_delete": "share_instances.force_delete", - "share_instances_get": "share_instances.get", - "share_instances_list": "share_instances.list", - "share_instances_reset_state": "share_instances.reset_state", - "share_networks_add_security_service": "share_networks.add_security_service", - "share_networks_create": "share_networks.create", - "share_networks_delete": "share_networks.delete", - "share_networks_find": "share_networks.find", - "share_networks_findall": "share_networks.findall", - "share_networks_get": "share_networks.get", - "share_networks_list": "share_networks.list", - "share_networks_remove_security_service": "share_networks.remove_security_service", - "share_networks_update": "share_networks.update", - "share_replicas_create": "share_replicas.create", - "share_replicas_delete": "share_replicas.delete", - "share_replicas_find": "share_replicas.find", - "share_replicas_findall": "share_replicas.findall", - "share_replicas_get": "share_replicas.get", - "share_replicas_list": "share_replicas.list", - "share_replicas_promote": "share_replicas.promote", - "share_replicas_reset_replica_state": "share_replicas.reset_replica_state", - "share_replicas_reset_state": "share_replicas.reset_state", - "share_replicas_resync": "share_replicas.resync", - "share_servers_delete": "share_servers.delete", - "share_servers_details": "share_servers.details", - "share_servers_find": "share_servers.find", - "share_servers_findall": "share_servers.findall", - "share_servers_get": "share_servers.get", - "share_servers_list": "share_servers.list", - "share_snapshot_export_locations_find": "share_snapshot_export_locations.find", - "share_snapshot_export_locations_findall": "share_snapshot_export_locations.findall", - "share_snapshot_export_locations_get": "share_snapshot_export_locations.get", - "share_snapshot_export_locations_list": "share_snapshot_export_locations.list", - "share_snapshot_instance_export_locations_find": "share_snapshot_instance_export_locations.find", - "share_snapshot_instance_export_locations_findall": "share_snapshot_instance_export_locations.findall", - "share_snapshot_instance_export_locations_get": "share_snapshot_instance_export_locations.get", - "share_snapshot_instance_export_locations_list": "share_snapshot_instance_export_locations.list", - "share_snapshot_instances_find": "share_snapshot_instances.find", - "share_snapshot_instances_findall": "share_snapshot_instances.findall", - "share_snapshot_instances_get": "share_snapshot_instances.get", - "share_snapshot_instances_list": "share_snapshot_instances.list", - "share_snapshot_instances_reset_state": "share_snapshot_instances.reset_state", - "share_snapshots_access_list": "share_snapshots.access_list", - "share_snapshots_allow": "share_snapshots.allow", - "share_snapshots_create": "share_snapshots.create", - "share_snapshots_delete": "share_snapshots.delete", - "share_snapshots_deny": "share_snapshots.deny", - "share_snapshots_find": "share_snapshots.find", - "share_snapshots_findall": "share_snapshots.findall", - "share_snapshots_force_delete": "share_snapshots.force_delete", - "share_snapshots_get": "share_snapshots.get", - "share_snapshots_list": "share_snapshots.list", - "share_snapshots_manage": "share_snapshots.manage", - "share_snapshots_reset_state": "share_snapshots.reset_state", - "share_snapshots_unmanage": "share_snapshots.unmanage", - "share_snapshots_update": "share_snapshots.update", - "share_type_access_add_project_access": "share_type_access.add_project_access", - "share_type_access_find": "share_type_access.find", - "share_type_access_findall": "share_type_access.findall", - "share_type_access_list": "share_type_access.list", - "share_type_access_remove_project_access": "share_type_access.remove_project_access", - "share_types_create": "share_types.create", - "share_types_delete": "share_types.delete", - "share_types_find": "share_types.find", - "share_types_findall": "share_types.findall", - "share_types_get": "share_types.get", - "share_types_list": "share_types.list", - "share_types_show": "share_types.show", - "shares_access_list": "shares.access_list", - "shares_allow": "shares.allow", - "shares_create": "shares.create", - "shares_delete": "shares.delete", - "shares_delete_metadata": "shares.delete_metadata", - "shares_deny": "shares.deny", - "shares_do_list": "shares.do_list", - "shares_extend": "shares.extend", - "shares_find": "shares.find", - "shares_findall": "shares.findall", - "shares_force_delete": "shares.force_delete", - "shares_get": "shares.get", - "shares_get_metadata": "shares.get_metadata", - "shares_list": "shares.list", - "shares_list_instances": "shares.list_instances", - "shares_manage": "shares.manage", - "shares_migration_cancel": "shares.migration_cancel", - "shares_migration_complete": "shares.migration_complete", - "shares_migration_get_progress": "shares.migration_get_progress", - "shares_migration_start": "shares.migration_start", - "shares_reset_state": "shares.reset_state", - "shares_reset_task_state": "shares.reset_task_state", - "shares_revert_to_snapshot": "shares.revert_to_snapshot", - "shares_set_metadata": "shares.set_metadata", - "shares_shrink": "shares.shrink", - "shares_unmanage": "shares.unmanage", - "shares_update": "shares.update", - "shares_update_all_metadata": "shares.update_all_metadata" - } -} diff --git a/mistral/config.py b/mistral/config.py index 3427bd690..fb325575c 100644 --- a/mistral/config.py +++ b/mistral/config.py @@ -21,7 +21,6 @@ Configuration options registration and useful routines. import itertools import json -import os from keystoneauth1 import loading from oslo_config import cfg @@ -558,39 +557,6 @@ keycloak_oidc_opts = [ ) ] -openstack_actions_opts = [ - cfg.StrOpt( - 'os-actions-endpoint-type', - default=os.environ.get('OS_ACTIONS_ENDPOINT_TYPE', 'public'), - choices=['public', 'admin', 'internal'], - deprecated_group='DEFAULT', - help=_('Type of endpoint in identity service catalog to use for' - ' communication with OpenStack services.') - ), - cfg.ListOpt( - 'modules-support-region', - default=['nova', 'glance', 'heat', 'neutron', 'cinder', - 'trove', 'ironic', 'designate', 'murano', 'tacker', 'senlin', - 'aodh', 'gnocchi'], - help=_('List of module names that support region in actions.') - ), - cfg.StrOpt( - 'default_region', - help=_('Default region name for openstack actions supporting region.') - ), -] - -# 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.' -) yaql_opts = [ cfg.IntOpt( @@ -692,7 +658,6 @@ EXECUTION_EXPIRATION_POLICY_GROUP = 'execution_expiration_policy' ACTION_HEARTBEAT_GROUP = 'action_heartbeat' PROFILER_GROUP = profiler.list_opts()[0][0] KEYCLOAK_OIDC_GROUP = "keycloak_oidc" -OPENSTACK_ACTIONS_GROUP = 'openstack_actions' YAQL_GROUP = "yaql" KEYSTONE_GROUP = "keystone" @@ -725,7 +690,6 @@ CONF.register_opts(pecan_opts, group=PECAN_GROUP) CONF.register_opts(coordination_opts, group=COORDINATION_GROUP) CONF.register_opts(profiler_opts, group=PROFILER_GROUP) CONF.register_opts(keycloak_oidc_opts, group=KEYCLOAK_OIDC_GROUP) -CONF.register_opts(openstack_actions_opts, group=OPENSTACK_ACTIONS_GROUP) CONF.register_opts(yaql_opts, group=YAQL_GROUP) loading.register_session_conf_options(CONF, KEYSTONE_GROUP) @@ -773,7 +737,6 @@ def list_opts(): (EXECUTION_EXPIRATION_POLICY_GROUP, execution_expiration_policy_opts), (PROFILER_GROUP, profiler_opts), (KEYCLOAK_OIDC_GROUP, keycloak_oidc_opts), - (OPENSTACK_ACTIONS_GROUP, openstack_actions_opts), (YAQL_GROUP, yaql_opts), (ACTION_HEARTBEAT_GROUP, action_heartbeat_opts), (None, default_group_opts) diff --git a/mistral/db/sqlalchemy/migration/cli.py b/mistral/db/sqlalchemy/migration/cli.py index 380cce344..a57c8b139 100644 --- a/mistral/db/sqlalchemy/migration/cli.py +++ b/mistral/db/sqlalchemy/migration/cli.py @@ -24,7 +24,6 @@ from oslo_utils import importutils import six import sys -from mistral import config from mistral.services import action_manager from mistral.services import workflows @@ -127,7 +126,6 @@ command_opt = cfg.SubCommandOpt('command', handler=add_command_parsers) CONF.register_cli_opt(command_opt) -CONF.register_cli_opt(config.os_actions_mapping_path) def main(): diff --git a/mistral/engine/base.py b/mistral/engine/base.py index f0686be79..bcb57b8bc 100644 --- a/mistral/engine/base.py +++ b/mistral/engine/base.py @@ -20,8 +20,8 @@ import jsonschema import six from mistral import exceptions as exc -from mistral.utils import inspect_utils from mistral.workflow import data_flow +from mistral_lib.utils import inspect_utils @six.add_metaclass(abc.ABCMeta) diff --git a/mistral/executors/default_executor.py b/mistral/executors/default_executor.py index 7813c1d6c..9b183859e 100644 --- a/mistral/executors/default_executor.py +++ b/mistral/executors/default_executor.py @@ -24,7 +24,7 @@ from mistral import exceptions as exc from mistral.executors import base from mistral.rpc import clients as rpc from mistral.services import action_heartbeat_sender -from mistral.utils import inspect_utils as i_u +from mistral_lib.utils import inspect_utils as i_u LOG = logging.getLogger(__name__) diff --git a/mistral/services/action_manager.py b/mistral/services/action_manager.py index b8b99bd6f..fb594f50f 100644 --- a/mistral/services/action_manager.py +++ b/mistral/services/action_manager.py @@ -18,12 +18,11 @@ from oslo_log import log as logging from stevedore import extension from mistral.actions import action_factory -from mistral.actions import generator_factory from mistral.db.v2 import api as db_api from mistral import exceptions as exc from mistral.services import actions -from mistral.utils import inspect_utils as i_utils from mistral_lib import utils +from mistral_lib.utils import inspect_utils as i_utils # TODO(rakhmerov): Make methods more consistent and granular. @@ -84,25 +83,32 @@ def sync_db(): def _register_dynamic_action_classes(namespace=''): - for generator in generator_factory.all_generators(): - actions = generator.create_actions() + extensions = extension.ExtensionManager( + namespace='mistral.generators', + invoke_on_load=True + ) - module = generator.base_action_class.__module__ - class_name = generator.base_action_class.__name__ + for ext in extensions: + for generator in ext.obj: + _register_actions(generator, namespace) - action_class_str = "%s.%s" % (module, class_name) - for action in actions: - attrs = i_utils.get_public_fields(action['class']) +def _register_actions(generator, namespace): + module = generator.base_action_class.__module__ + class_name = generator.base_action_class.__name__ + action_class_str = "%s.%s" % (module, class_name) - register_action_class( - action['name'], - action_class_str, - attrs, - action['description'], - action['arg_list'], - namespace=namespace - ) + for action in generator.create_actions(): + attrs = i_utils.get_public_fields(action['class']) + + register_action_class( + action['name'], + action_class_str, + attrs, + action['description'], + action['arg_list'], + namespace=namespace + ) def register_action_classes(namespace=''): diff --git a/mistral/tests/resources/openstack/action_collection_wb.yaml b/mistral/tests/resources/openstack/action_collection_wb.yaml deleted file mode 100644 index d675a58b3..000000000 --- a/mistral/tests/resources/openstack/action_collection_wb.yaml +++ /dev/null @@ -1,53 +0,0 @@ ---- -version: '2.0' -name: action_collection - -workflows: - keystone: - type: direct - tasks: - projects_list: - action: keystone.projects_list - publish: - result: <% task().result %> - - nova: - type: direct - tasks: - flavors_list: - action: nova.flavors_list - publish: - result: <% task().result %> - - glance: - type: direct - tasks: - images_list: - action: glance.images_list - publish: - result: <% task().result %> - - heat: - type: direct - tasks: - stacks_list: - action: heat.stacks_list - publish: - result: <% task().result %> - - neutron: - type: direct - tasks: - list_subnets: - action: neutron.list_subnets - publish: - result: <% task().result %> - - cinder: - type: direct - tasks: - volumes_list: - action: cinder.volumes_list - publish: - result: <% task().result %> - diff --git a/mistral/tests/resources/openstack/test_mapping.json b/mistral/tests/resources/openstack/test_mapping.json deleted file mode 100644 index 82d1347f3..000000000 --- a/mistral/tests/resources/openstack/test_mapping.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "_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", - "servers_find": "servers.find", - "volumes_delete_server_volume": "volumes.delete_server_volume" - }, - "keystone": { - "users_list": "users.list", - "trusts_create": "trusts.create" - }, - "glance": { - "images_list": "images.list", - "images_delete": "images.delete" - } -} diff --git a/mistral/tests/unit/actions/openstack/__init__.py b/mistral/tests/unit/actions/openstack/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/mistral/tests/unit/actions/openstack/test_generator.py b/mistral/tests/unit/actions/openstack/test_generator.py deleted file mode 100644 index 31ec44049..000000000 --- a/mistral/tests/unit/actions/openstack/test_generator.py +++ /dev/null @@ -1,193 +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 contextlib -import os - -from oslo_config import cfg - -import mock - -from mistral.actions import generator_factory -from mistral.actions.openstack.action_generator import base as generator_base -from mistral.actions.openstack import actions -from mistral import config - -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 = { - 'nova': ['nova.servers_get', actions.NovaAction], - 'glance': ['glance.images_list', actions.GlanceAction], - 'keystone': ['keystone.users_create', actions.KeystoneAction], - 'heat': ['heat.stacks_list', actions.HeatAction], - 'neutron': ['neutron.show_network', actions.NeutronAction], - 'cinder': ['cinder.volumes_list', actions.CinderAction], - 'trove': ['trove.instances_list', actions.TroveAction], - 'ironic': ['ironic.node_list', actions.IronicAction], - 'baremetal_introspection': ['baremetal_introspection.introspect', - actions.BaremetalIntrospectionAction], - 'swift': ['swift.head_account', actions.SwiftAction], - 'swiftservice': ['swiftservice.delete', actions.SwiftServiceAction], - 'zaqar': ['zaqar.queue_messages', actions.ZaqarAction], - 'barbican': ['barbican.orders_list', actions.BarbicanAction], - 'mistral': ['mistral.workflows_get', actions.MistralAction], - 'designate': ['designate.quotas_list', actions.DesignateAction], - 'manila': ['manila.shares_list', actions.ManilaAction], - 'magnum': ['magnum.bays_list', actions.MagnumAction], - 'murano': ['murano.deployments_list', actions.MuranoAction], - 'tacker': ['tacker.list_vims', actions.TackerAction], - 'senlin': ['senlin.get_profile', actions.SenlinAction], - 'aodh': ['aodh.alarm_list', actions.AodhAction], - 'gnocchi': ['gnocchi.metric_list', actions.GnocchiAction], - 'glare': ['glare.artifacts_list', actions.GlareAction], - 'vitrage': ['vitrage.alarm_get', actions.VitrageAction], - 'zun': ['zun.containers_list', actions.ZunAction], - 'qinling': ['qinling.runtimes_list', actions.QinlingAction] -} - -EXTRA_MODULES = ['neutron', 'swift', 'zaqar', 'tacker', 'senlin'] - - -CONF = cfg.CONF -CONF.register_opt(config.os_actions_mapping_path) - - -class GeneratorTest(base.BaseTest): - - def setUp(self): - super(GeneratorTest, self).setUp() - - # The baremetal inspector client expects the service to be running - # when it is initialised and attempts to connect. This mocks out this - # service only and returns a simple function that can be used by the - # inspection utils. - self.baremetal_patch = mock.patch.object( - actions.BaremetalIntrospectionAction, - "get_fake_client_method", - return_value=lambda x: None) - - self.baremetal_patch.start() - self.addCleanup(self.baremetal_patch.stop) - - # Do the same for the Designate client. - self.designate_patch = mock.patch.object( - actions.DesignateAction, - "get_fake_client_method", - return_value=lambda x: None) - - self.designate_patch.start() - self.addCleanup(self.designate_patch.stop) - - def test_generator(self): - for generator_cls in generator_factory.all_generators(): - action_classes = generator_cls.create_actions() - - action_name = MODULE_MAPPING[generator_cls.action_namespace][0] - action_cls = MODULE_MAPPING[generator_cls.action_namespace][1] - method_name_pre = action_name.split('.')[1] - method_name = ( - method_name_pre - if generator_cls.action_namespace in EXTRA_MODULES - else method_name_pre.replace('_', '.') - ) - - action = self._assert_single_item( - action_classes, - name=action_name - ) - - self.assertTrue(issubclass(action['class'], action_cls)) - self.assertEqual(method_name, action['class'].client_method_name) - - modules = CONF.openstack_actions.modules_support_region - if generator_cls.action_namespace in modules: - self.assertIn('action_region', action['arg_list']) - - 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.assertIn('nova.servers_get', action_names) - self.assertEqual(3, len(action_names)) - elif cls not in (actions.GlanceAction, actions.KeystoneAction): - 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.assertIn('nova.servers_get', action_names) - self.assertEqual(3, len(action_names)) - elif cls not in (actions.GlanceAction, actions.KeystoneAction): - self.assertEqual([], action_names) - - def test_prepare_action_inputs(self): - inputs = generator_base.OpenStackActionGenerator.prepare_action_inputs( - 'a,b,c', - added=['region=RegionOne'] - ) - - self.assertEqual('a, b, c, region=RegionOne', inputs) - - inputs = generator_base.OpenStackActionGenerator.prepare_action_inputs( - 'a,b,c=1', - added=['region=RegionOne'] - ) - - self.assertEqual('a, b, region=RegionOne, c=1', inputs) - - inputs = generator_base.OpenStackActionGenerator.prepare_action_inputs( - 'a,b,c=1,**kwargs', - added=['region=RegionOne'] - ) - - self.assertEqual('a, b, region=RegionOne, c=1, **kwargs', inputs) - - inputs = generator_base.OpenStackActionGenerator.prepare_action_inputs( - '**kwargs', - added=['region=RegionOne'] - ) - - self.assertEqual('region=RegionOne, **kwargs', inputs) - - inputs = generator_base.OpenStackActionGenerator.prepare_action_inputs( - '', - added=['region=RegionOne'] - ) - - self.assertEqual('region=RegionOne', inputs) - - -@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) diff --git a/mistral/tests/unit/actions/openstack/test_openstack_actions.py b/mistral/tests/unit/actions/openstack/test_openstack_actions.py deleted file mode 100644 index 3b3f21407..000000000 --- a/mistral/tests/unit/actions/openstack/test_openstack_actions.py +++ /dev/null @@ -1,411 +0,0 @@ -# Copyright 2014 - Mirantis, Inc. -# -# 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 mock - -from mistral.actions.openstack import actions -from oslo_config import cfg -from oslo_utils import importutils -from oslotest import base - -CONF = cfg.CONF - - -class FakeEndpoint(object): - def __init__(self, **kwargs): - self.__dict__.update(kwargs) - - -class OpenStackActionTest(base.BaseTestCase): - def tearDown(self): - super(OpenStackActionTest, self).tearDown() - cfg.CONF.set_default('auth_enable', False, group='pecan') - - @mock.patch.object(actions.NovaAction, '_get_client') - def test_nova_action(self, mocked): - mock_ctx = mock.Mock() - method_name = "servers.get" - action_class = actions.NovaAction - action_class.client_method_name = method_name - params = {'server': '1234-abcd'} - action = action_class(**params) - action.run(mock_ctx) - - self.assertTrue(mocked().servers.get.called) - mocked().servers.get.assert_called_once_with(server="1234-abcd") - - @mock.patch.object(actions.GlanceAction, '_get_client') - def test_glance_action(self, mocked): - mock_ctx = mock.Mock() - method_name = "images.delete" - action_class = actions.GlanceAction - action_class.client_method_name = method_name - params = {'image': '1234-abcd'} - action = action_class(**params) - action.run(mock_ctx) - - self.assertTrue(mocked().images.delete.called) - mocked().images.delete.assert_called_once_with(image="1234-abcd") - - @mock.patch.object(actions.KeystoneAction, '_get_client') - def test_keystone_action(self, mocked): - mock_ctx = mock.Mock() - method_name = "users.get" - action_class = actions.KeystoneAction - action_class.client_method_name = method_name - params = {'user': '1234-abcd'} - action = action_class(**params) - action.run(mock_ctx) - - self.assertTrue(mocked().users.get.called) - mocked().users.get.assert_called_once_with(user="1234-abcd") - - @mock.patch.object(actions.HeatAction, '_get_client') - def test_heat_action(self, mocked): - mock_ctx = mock.Mock() - method_name = "stacks.get" - action_class = actions.HeatAction - action_class.client_method_name = method_name - params = {'id': '1234-abcd'} - action = action_class(**params) - action.run(mock_ctx) - - self.assertTrue(mocked().stacks.get.called) - mocked().stacks.get.assert_called_once_with(id="1234-abcd") - - @mock.patch.object(actions.NeutronAction, '_get_client') - def test_neutron_action(self, mocked): - mock_ctx = mock.Mock() - method_name = "show_network" - action_class = actions.NeutronAction - action_class.client_method_name = method_name - params = {'id': '1234-abcd'} - action = action_class(**params) - action.run(mock_ctx) - - self.assertTrue(mocked().show_network.called) - mocked().show_network.assert_called_once_with(id="1234-abcd") - - @mock.patch.object(actions.CinderAction, '_get_client') - def test_cinder_action(self, mocked): - mock_ctx = mock.Mock() - method_name = "volumes.get" - action_class = actions.CinderAction - action_class.client_method_name = method_name - params = {'volume': '1234-abcd'} - action = action_class(**params) - action.run(mock_ctx) - - self.assertTrue(mocked().volumes.get.called) - mocked().volumes.get.assert_called_once_with(volume="1234-abcd") - - @mock.patch.object(actions.TroveAction, '_get_client') - def test_trove_action(self, mocked): - mock_ctx = mock.Mock() - method_name = "instances.get" - action_class = actions.TroveAction - action_class.client_method_name = method_name - params = {'instance': '1234-abcd'} - action = action_class(**params) - action.run(mock_ctx) - - self.assertTrue(mocked().instances.get.called) - mocked().instances.get.assert_called_once_with(instance="1234-abcd") - - @mock.patch.object(actions.IronicAction, '_get_client') - def test_ironic_action(self, mocked): - mock_ctx = mock.Mock() - method_name = "node.get" - action_class = actions.IronicAction - action_class.client_method_name = method_name - params = {'node': '1234-abcd'} - action = action_class(**params) - action.run(mock_ctx) - - self.assertTrue(mocked().node.get.called) - mocked().node.get.assert_called_once_with(node="1234-abcd") - - @mock.patch.object(actions.BaremetalIntrospectionAction, '_get_client') - def test_baremetal_introspector_action(self, mocked): - mock_ctx = mock.Mock() - method_name = "get_status" - action_class = actions.BaremetalIntrospectionAction - action_class.client_method_name = method_name - params = {'uuid': '1234'} - action = action_class(**params) - action.run(mock_ctx) - - self.assertTrue(mocked().get_status.called) - mocked().get_status.assert_called_once_with(uuid="1234") - - @mock.patch.object(actions.MistralAction, '_get_client') - def test_mistral_action(self, mocked): - mock_ctx = mock.Mock() - method_name = "workflows.get" - action_class = actions.MistralAction - action_class.client_method_name = method_name - params = {'name': '1234-abcd'} - action = action_class(**params) - action.run(mock_ctx) - - self.assertTrue(mocked().workflows.get.called) - mocked().workflows.get.assert_called_once_with(name="1234-abcd") - - @mock.patch.object(actions.MistralAction, 'get_session_and_auth') - def test_integrated_mistral_action(self, mocked): - CONF.set_default('auth_enable', True, group='pecan') - mock_endpoint = mock.Mock() - mock_endpoint.endpoint = 'http://testendpoint.com:8989/v2' - mocked.return_value = {'auth': mock_endpoint, 'session': None} - mock_ctx = mock.Mock() - action_class = actions.MistralAction - params = {'identifier': '1234-abcd'} - action = action_class(**params) - client = action._get_client(mock_ctx) - self.assertEqual(client.workbooks.http_client.base_url, - mock_endpoint.endpoint) - - def test_standalone_mistral_action(self): - CONF.set_default('auth_enable', False, group='pecan') - mock_ctx = mock.Mock() - action_class = actions.MistralAction - params = {'identifier': '1234-abcd'} - action = action_class(**params) - client = action._get_client(mock_ctx) - base_url = 'http://{}:{}/v2'.format(CONF.api.host, CONF.api.port) - self.assertEqual(client.workbooks.http_client.base_url, base_url) - - @mock.patch.object(actions.SwiftAction, '_get_client') - def test_swift_action(self, mocked): - mock_ctx = mock.Mock() - method_name = "get_object" - action_class = actions.SwiftAction - action_class.client_method_name = method_name - params = {'container': 'foo', 'object': 'bar'} - action = action_class(**params) - action.run(mock_ctx) - - self.assertTrue(mocked().get_object.called) - mocked().get_object.assert_called_once_with(container='foo', - object='bar') - - @mock.patch.object(actions.SwiftServiceAction, '_get_client') - def test_swift_service_action(self, mocked): - mock_ctx = mock.Mock() - method_name = "list" - action_class = actions.SwiftServiceAction - action_class.client_method_name = method_name - action = action_class() - action.run(mock_ctx) - - self.assertTrue(mocked().list.called) - mocked().list.assert_called_once_with() - - @mock.patch.object(actions.ZaqarAction, '_get_client') - def test_zaqar_action(self, mocked): - mock_ctx = mock.Mock() - method_name = "queue_messages" - action_class = actions.ZaqarAction - action_class.client_method_name = method_name - params = {'queue_name': 'foo'} - action = action_class(**params) - action.run(mock_ctx) - - mocked().queue.assert_called_once_with('foo') - mocked().queue().messages.assert_called_once_with() - - @mock.patch.object(actions.BarbicanAction, '_get_client') - def test_barbican_action(self, mocked): - mock_ctx = mock.Mock() - method_name = "orders_list" - action_class = actions.BarbicanAction - action_class.client_method_name = method_name - params = {'limit': 5} - action = action_class(**params) - action.run(mock_ctx) - - self.assertTrue(mocked().orders_list.called) - mocked().orders_list.assert_called_once_with(limit=5) - - @mock.patch.object(actions.DesignateAction, '_get_client') - def test_designate_action(self, mocked): - mock_ctx = mock.Mock() - method_name = "domain.get" - action_class = actions.DesignateAction - action_class.client_method_name = method_name - params = {'domain': 'example.com'} - action = action_class(**params) - action.run(mock_ctx) - - self.assertTrue(mocked().domain.get.called) - mocked().domain.get.assert_called_once_with(domain="example.com") - - @mock.patch.object(actions.MagnumAction, '_get_client') - def test_magnum_action(self, mocked): - mock_ctx = mock.Mock() - method_name = "baymodels.get" - action_class = actions.MagnumAction - action_class.client_method_name = method_name - params = {'id': '1234-abcd'} - action = action_class(**params) - action.run(mock_ctx) - - self.assertTrue(mocked().baymodels.get.called) - mocked().baymodels.get.assert_called_once_with(id="1234-abcd") - - @mock.patch.object(actions.MuranoAction, '_get_client') - def test_murano_action(self, mocked): - mock_ctx = mock.Mock() - method_name = "categories.get" - action_class = actions.MuranoAction - action_class.client_method_name = method_name - params = {'category_id': '1234-abcd'} - action = action_class(**params) - action.run(mock_ctx) - - self.assertTrue(mocked().categories.get.called) - mocked().categories.get.assert_called_once_with( - category_id="1234-abcd" - ) - - @mock.patch.object(actions.TackerAction, '_get_client') - def test_tacker_action(self, mocked): - mock_ctx = mock.Mock() - method_name = "show_vim" - action_class = actions.TackerAction - action_class.client_method_name = method_name - params = {'vim_id': '1234-abcd'} - action = action_class(**params) - action.run(mock_ctx) - - self.assertTrue(mocked().show_vim.called) - mocked().show_vim.assert_called_once_with( - vim_id="1234-abcd" - ) - - @mock.patch.object(actions.SenlinAction, '_get_client') - def test_senlin_action(self, mocked): - mock_ctx = mock.Mock() - action_class = actions.SenlinAction - action_class.client_method_name = "get_cluster" - action = action_class(cluster_id='1234-abcd') - - action.run(mock_ctx) - - self.assertTrue(mocked().get_cluster.called) - - mocked().get_cluster.assert_called_once_with( - cluster_id="1234-abcd" - ) - - @mock.patch.object(actions.AodhAction, '_get_client') - def test_aodh_action(self, mocked): - mock_ctx = mock.Mock() - method_name = "alarm.get" - action_class = actions.AodhAction - action_class.client_method_name = method_name - params = {'alarm_id': '1234-abcd'} - action = action_class(**params) - action.run(mock_ctx) - - self.assertTrue(mocked().alarm.get.called) - mocked().alarm.get.assert_called_once_with(alarm_id="1234-abcd") - - @mock.patch.object(actions.GnocchiAction, '_get_client') - def test_gnocchi_action(self, mocked): - mock_ctx = mock.Mock() - method_name = "metric.get" - action_class = actions.GnocchiAction - action_class.client_method_name = method_name - params = {'metric_id': '1234-abcd'} - action = action_class(**params) - action.run(mock_ctx) - - self.assertTrue(mocked().metric.get.called) - mocked().metric.get.assert_called_once_with(metric_id="1234-abcd") - - @mock.patch.object(actions.GlareAction, '_get_client') - def test_glare_action(self, mocked): - mock_ctx = mock.Mock() - method_name = "artifacts.get" - action_class = actions.GlareAction - action_class.client_method_name = method_name - params = {'artifact_id': '1234-abcd'} - action = action_class(**params) - action.run(mock_ctx) - - self.assertTrue(mocked().artifacts.get.called) - mocked().artifacts.get.assert_called_once_with(artifact_id="1234-abcd") - - @mock.patch.object(actions.VitrageAction, '_get_client') - def test_vitrage_action(self, mocked): - mock_ctx = mock.Mock() - method_name = "alarm.get" - action_class = actions.VitrageAction - action_class.client_method_name = method_name - params = {'vitrage_id': '1234-abcd'} - action = action_class(**params) - action.run(mock_ctx) - - self.assertTrue(mocked().alarm.get.called) - mocked().alarm.get.assert_called_once_with(vitrage_id="1234-abcd") - - @mock.patch.object(actions.ZunAction, '_get_client') - def test_zun_action(self, mocked): - mock_ctx = mock.Mock() - method_name = "containers.get" - action_class = actions.ZunAction - action_class.client_method_name = method_name - params = {'container_id': '1234-abcd'} - action = action_class(**params) - action.run(mock_ctx) - - self.assertTrue(mocked().containers.get.called) - mocked().containers.get.assert_called_once_with( - container_id="1234-abcd" - ) - - @mock.patch.object(actions.QinlingAction, '_get_client') - def test_qinling_action(self, mocked): - mock_ctx = mock.Mock() - method_name = "runtimes.get" - action_class = actions.QinlingAction - action_class.client_method_name = method_name - params = {'id': '1234-abcd'} - action = action_class(**params) - action.run(mock_ctx) - - self.assertTrue(mocked().runtimes.get.called) - mocked().runtimes.get.assert_called_once_with(id="1234-abcd") - - @mock.patch.object(actions.ManilaAction, '_get_client') - def test_manila_action(self, mocked): - mock_ctx = mock.Mock() - method_name = "shares.get" - action_class = actions.ManilaAction - action_class.client_method_name = method_name - params = {'share': '1234-abcd'} - action = action_class(**params) - action.run(mock_ctx) - - self.assertTrue(mocked().shares.get.called) - mocked().shares.get.assert_called_once_with(share="1234-abcd") - - -class TestImport(base.BaseTestCase): - @mock.patch.object(importutils, 'try_import') - def test_try_import_fails(self, mocked): - mocked.side_effect = Exception('Exception when importing module') - bad_module = actions._try_import('raiser') - self.assertIsNone(bad_module) diff --git a/mistral/tests/unit/actions/test_action_manager.py b/mistral/tests/unit/actions/test_action_manager.py index ff6994376..44dac12ee 100644 --- a/mistral/tests/unit/actions/test_action_manager.py +++ b/mistral/tests/unit/actions/test_action_manager.py @@ -30,24 +30,6 @@ class ActionManagerTest(base.DbTestCase): self._assert_single_item(action_list, name="std.ssh") self._assert_single_item(action_list, name="std.javascript") - self._assert_single_item(action_list, name="nova.servers_get") - self._assert_single_item( - action_list, - name="nova.volumes_delete_server_volume" - ) - - server_find_action = self._assert_single_item( - action_list, - name="nova.servers_find" - ) - self.assertIn('**', server_find_action.input) - - self._assert_single_item(action_list, name="keystone.users_list") - self._assert_single_item(action_list, name="keystone.trusts_create") - - self._assert_single_item(action_list, name="glance.images_list") - self._assert_single_item(action_list, name="glance.images_delete") - def test_get_action_class(self): self.assertTrue( issubclass(a_m.get_action_class("std.echo"), std.EchoAction) diff --git a/mistral/tests/unit/api/v2/test_action_executions.py b/mistral/tests/unit/api/v2/test_action_executions.py index 8a729e5f5..6f56d5f8e 100644 --- a/mistral/tests/unit/api/v2/test_action_executions.py +++ b/mistral/tests/unit/api/v2/test_action_executions.py @@ -24,6 +24,7 @@ from oslo_messaging import exceptions as oslo_exc import sqlalchemy as sa from mistral.api.controllers.v2 import action_execution +from mistral.api.controllers.v2 import resources from mistral.db.v2 import api as db_api from mistral.db.v2.sqlalchemy import models from mistral import exceptions as exc @@ -581,7 +582,8 @@ class TestActionExecutionsController(base.APITest): self.assertEqual(1, len(resp.json['action_executions'])) self.assertDictEqual(ACTION_EX, resp.json['action_executions'][0]) - @mock.patch.object(rest_utils, 'get_all') + @mock.patch.object(rest_utils, 'get_all', + return_value=resources.ActionExecutions()) def test_get_all_without_output(self, mock_get_all): resp = self.app.get('/v2/action_executions') @@ -594,7 +596,8 @@ class TestActionExecutionsController(base.APITest): resource_function ) - @mock.patch.object(rest_utils, 'get_all') + @mock.patch.object(rest_utils, 'get_all', + return_value=resources.ActionExecutions()) def test_get_all_with_output(self, mock_get_all): resp = self.app.get('/v2/action_executions?include_output=true') diff --git a/mistral/tests/unit/api/v2/test_executions.py b/mistral/tests/unit/api/v2/test_executions.py index 1f1bfe1e5..06faa1c07 100644 --- a/mistral/tests/unit/api/v2/test_executions.py +++ b/mistral/tests/unit/api/v2/test_executions.py @@ -28,6 +28,7 @@ import sqlalchemy as sa from webtest import app as webtest_app from mistral.api.controllers.v2 import execution +from mistral.api.controllers.v2 import resources from mistral.db.v2 import api as db_api from mistral.db.v2.sqlalchemy import api as sql_db_api from mistral.db.v2.sqlalchemy import models @@ -903,7 +904,8 @@ class TestExecutionsController(base.APITest): ) @mock.patch.object(db_api, 'get_workflow_executions', MOCK_WF_EXECUTIONS) - @mock.patch.object(rest_utils, 'get_all') + @mock.patch.object(rest_utils, 'get_all', + return_value=resources.Executions()) def test_get_all_executions_with_output(self, mock_get_all): resp = self.app.get('/v2/executions?include_output=true') @@ -918,7 +920,8 @@ class TestExecutionsController(base.APITest): ) @mock.patch.object(db_api, 'get_workflow_executions', MOCK_WF_EXECUTIONS) - @mock.patch.object(rest_utils, 'get_all') + @mock.patch.object(rest_utils, 'get_all', + return_value=resources.Executions()) def test_get_all_executions_without_output(self, mock_get_all): resp = self.app.get('/v2/executions') diff --git a/mistral/tests/unit/base.py b/mistral/tests/unit/base.py index f64bbf150..b5361bf8f 100644 --- a/mistral/tests/unit/base.py +++ b/mistral/tests/unit/base.py @@ -25,7 +25,6 @@ from oslo_log import log as logging from oslotest import base import testtools.matchers as ttm -from mistral import config from mistral import context as auth_context from mistral.db.sqlalchemy import base as db_sa_base from mistral.db.sqlalchemy import sqlite_lock @@ -34,8 +33,8 @@ from mistral.lang import parser as spec_parser from mistral.services import action_manager from mistral.services import security from mistral.tests.unit import config as test_config -from mistral.utils import inspect_utils as i_utils from mistral import version +from mistral_lib.utils import inspect_utils as i_utils RESOURCES_PATH = 'tests/resources/' LOG = logging.getLogger(__name__) @@ -265,14 +264,6 @@ class DbTestCase(BaseTest): if cfg.CONF.database.connection.startswith('sqlite'): cfg.CONF.set_default('connection', 'sqlite://', group='database') - # This option is normally registered in sync_db.py so we have to - # register it here specifically for tests. - cfg.CONF.register_opt(config.os_actions_mapping_path) - - cfg.CONF.set_default( - 'openstack_actions_mapping_path', - 'tests/resources/openstack/test_mapping.json' - ) cfg.CONF.set_default('max_overflow', -1, group='database') cfg.CONF.set_default('max_pool_size', 1000, group='database') diff --git a/mistral/tests/unit/test_exception_base.py b/mistral/tests/unit/test_exception_base.py index e9a81e648..55c154241 100644 --- a/mistral/tests/unit/test_exception_base.py +++ b/mistral/tests/unit/test_exception_base.py @@ -16,7 +16,7 @@ import six from mistral import exceptions from mistral.tests.unit import base -from mistral.utils import inspect_utils +from mistral_lib.utils import inspect_utils class ExceptionTest(base.BaseTest): diff --git a/mistral/tests/unit/utils/test_inspect_utils.py b/mistral/tests/unit/utils/test_inspect_utils.py deleted file mode 100644 index bcc1b3687..000000000 --- a/mistral/tests/unit/utils/test_inspect_utils.py +++ /dev/null @@ -1,69 +0,0 @@ -# Copyright 2014 - Mirantis, Inc. -# -# 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 time - -from mistral.actions import std_actions -from mistral.tests.unit import base -from mistral.utils import inspect_utils as i_u -from mistral.workflow import commands - - -class ClassWithProperties(object): - - a = 1 - - @property - def prop(self): - pass - - -class InspectUtilsTest(base.BaseTest): - def test_get_parameters_str(self): - action_class = std_actions.HTTPAction - parameters_str = i_u.get_arg_list_as_str(action_class.__init__) - - http_action_params = ( - 'url, method="GET", params=null, body=null, ' - 'json=null, headers=null, cookies=null, auth=null, ' - 'timeout=null, allow_redirects=null, ' - 'proxies=null, verify=null' - ) - - self.assertEqual(http_action_params, parameters_str) - - def test_get_parameters_str_all_mandatory(self): - clazz = commands.RunTask - parameters_str = i_u.get_arg_list_as_str(clazz.__init__) - - self.assertEqual( - 'wf_ex, wf_spec, task_spec, ctx, triggered_by=null,' - ' handles_error=false', - parameters_str - ) - - def test_get_parameters_str_with_function_parameter(self): - - def test_func(foo, bar=None, test_func=time.sleep): - pass - - parameters_str = i_u.get_arg_list_as_str(test_func) - - self.assertEqual("foo, bar=null", parameters_str) - - def test_get_public_fields(self): - - attrs = i_u.get_public_fields(ClassWithProperties) - - self.assertEqual(attrs, {'a': 1}) diff --git a/mistral/tests/unit/utils/test_keystone_utils.py b/mistral/tests/unit/utils/test_keystone_utils.py deleted file mode 100644 index 6393ffa8c..000000000 --- a/mistral/tests/unit/utils/test_keystone_utils.py +++ /dev/null @@ -1,61 +0,0 @@ -# Copyright 2015 - Mirantis, Inc. -# -# 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 mock - -from mistral import context as auth_context -from mistral import exceptions -from mistral.tests.unit import base -from mistral.utils.openstack import keystone - - -class KeystoneUtilsTest(base.BaseTest): - def setUp(self): - super(KeystoneUtilsTest, self).setUp() - - self.values = {'id': 'my_id'} - - def test_format_url_dollar_sign(self): - url_template = "http://host:port/v1/$(id)s" - - expected = "http://host:port/v1/my_id" - - self.assertEqual( - expected, - keystone.format_url(url_template, self.values) - ) - - def test_format_url_percent_sign(self): - url_template = "http://host:port/v1/%(id)s" - - expected = "http://host:port/v1/my_id" - - self.assertEqual( - expected, - keystone.format_url(url_template, self.values) - ) - - @mock.patch.object(keystone, 'client') - def test_get_endpoint_for_project_noauth(self, client): - client().tokens.get_token_data.return_value = {'token': None} - - # service_catalog is not set by default. - auth_context.set_ctx(base.get_context()) - self.addCleanup(auth_context.set_ctx, None) - - self.assertRaises( - exceptions.UnauthorizedException, - keystone.get_endpoint_for_project, - 'keystone' - ) diff --git a/mistral/utils/inspect_utils.py b/mistral/utils/inspect_utils.py deleted file mode 100644 index fd856fc96..000000000 --- a/mistral/utils/inspect_utils.py +++ /dev/null @@ -1,94 +0,0 @@ -# Copyright 2014 - Mirantis, Inc. -# -# 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 inspect -import json - -import six - - -def get_public_fields(obj): - """Returns only public fields from object or class.""" - - public_attributes = [attr for attr in dir(obj) - if not attr.startswith("_")] - - public_fields = {} - - for attribute_str in public_attributes: - attr = getattr(obj, attribute_str) - is_field = not (inspect.isbuiltin(attr) - or inspect.isfunction(attr) - or inspect.ismethod(attr) - or isinstance(attr, property)) - - if is_field: - public_fields[attribute_str] = attr - - return public_fields - - -def get_docstring(obj): - return inspect.getdoc(obj) - - -def get_arg_list(func): - argspec = get_args_spec(func) - - args = argspec.args - - if 'self' in args: - args.remove('self') - - return args - - -def get_arg_list_as_str(func): - args = getattr(func, "__arguments__", None) - if args: - return args - - argspec = get_args_spec(func) - defs = list(argspec.defaults or []) - - args = get_arg_list(func) - - diff_args_defs = len(args) - len(defs) - arg_str_list = [] - - for index, default in enumerate(args): - if index >= diff_args_defs: - try: - arg_str_list.append( - "%s=%s" % ( - args[index], - json.dumps(defs[index - diff_args_defs]) - ) - ) - except TypeError: - pass - else: - arg_str_list.append("%s" % args[index]) - - keywords = argspec.keywords if six.PY2 else argspec.varkw - if keywords: - arg_str_list.append("**%s" % keywords) - - return ", ".join(arg_str_list) - - -def get_args_spec(func): - if six.PY2: - return inspect.getargspec(func) - return inspect.getfullargspec(func) diff --git a/mistral/utils/openstack/keystone.py b/mistral/utils/openstack/keystone.py index 8fb0ed3ed..a0534daca 100644 --- a/mistral/utils/openstack/keystone.py +++ b/mistral/utils/openstack/keystone.py @@ -13,19 +13,11 @@ # See the License for the specific language governing permissions and # limitations under the License. -import keystoneauth1.identity.generic as auth_plugins from keystoneauth1 import loading -from keystoneauth1 import session as ks_session -from keystoneauth1.token_endpoint import Token -from keystoneclient import service_catalog as ks_service_catalog from keystoneclient.v3 import client as ks_client -from keystoneclient.v3 import endpoints as ks_endpoints from oslo_config import cfg -from oslo_utils import timeutils -import six from mistral import context -from mistral import exceptions CONF = cfg.CONF @@ -46,50 +38,12 @@ def client(): return cl -def _determine_verify(ctx): - if ctx.insecure: - return False - elif ctx.auth_cacert: - return ctx.auth_cacert - else: - return True +def client_for_admin(): + return _admin_client() -def get_session_and_auth(ctx, **kwargs): - """Get session and auth parameters. - - :param ctx: action context - :return: dict to be used as kwargs for client service initialization - """ - - if not ctx: - raise AssertionError('context is mandatory') - - project_endpoint = get_endpoint_for_project(**kwargs) - endpoint = format_url( - project_endpoint.url, - { - 'tenant_id': ctx.project_id, - 'project_id': ctx.project_id - } - ) - - auth = Token(endpoint=endpoint, token=ctx.auth_token) - - auth_uri = ctx.auth_uri or CONF.keystone_authtoken.www_authenticate_uri - ks_auth = Token( - endpoint=auth_uri, - token=ctx.auth_token - ) - session = ks_session.Session( - auth=ks_auth, - verify=_determine_verify(ctx) - ) - - return { - "session": session, - "auth": auth - } +def client_for_trusts(trust_id): + return _admin_client(trust_id=trust_id) def _admin_client(trust_id=None): @@ -138,170 +92,3 @@ def _admin_client(trust_id=None): ) return ks_client.Client(session=sess) - - -def client_for_admin(): - return _admin_client() - - -def client_for_trusts(trust_id): - return _admin_client(trust_id=trust_id) - - -def get_endpoint_for_project(service_name=None, service_type=None, - region_name=None): - if service_name is None and service_type is None: - raise exceptions.MistralException( - "Either 'service_name' or 'service_type' must be provided." - ) - - ctx = context.ctx() - - service_catalog = obtain_service_catalog(ctx) - - # When region_name is not passed, first get from context as region_name - # could be passed to rest api in http header ('X-Region-Name'). Otherwise, - # just get region from mistral configuration. - region = (region_name or ctx.region_name) - if service_name == 'keystone': - # Determining keystone endpoint should be done using - # keystone_authtoken section as this option is special for keystone. - region = region or CONF.keystone_authtoken.region_name - else: - region = region or CONF.openstack_actions.default_region - - service_endpoints = service_catalog.get_endpoints( - service_name=service_name, - service_type=service_type, - region_name=region - ) - - endpoint = None - os_actions_endpoint_type = CONF.openstack_actions.os_actions_endpoint_type - - for endpoints in six.itervalues(service_endpoints): - for ep in endpoints: - # is V3 interface? - if 'interface' in ep: - interface_type = ep['interface'] - if os_actions_endpoint_type in interface_type: - endpoint = ks_endpoints.Endpoint( - None, - ep, - loaded=True - ) - break - # is V2 interface? - if 'publicURL' in ep: - endpoint_data = { - 'url': ep['publicURL'], - 'region': ep['region'] - } - endpoint = ks_endpoints.Endpoint( - None, - endpoint_data, - loaded=True - ) - break - - if not endpoint: - raise exceptions.MistralException( - "No endpoints found [service_name=%s, service_type=%s," - " region_name=%s]" - % (service_name, service_type, region) - ) - else: - return endpoint - - -def obtain_service_catalog(ctx): - token = ctx.auth_token - - if ctx.is_trust_scoped and is_token_trust_scoped(token): - if ctx.trust_id is None: - raise Exception( - "'trust_id' must be provided in the admin context." - ) - - # trust_client = client_for_trusts(ctx.trust_id) - # Using trust client, it can't validate token - # when cron trigger running because keystone policy - # don't allow do this. So we need use admin client to - # get token data - token_data = _admin_client().tokens.get_token_data( - token, - include_catalog=True - ) - response = token_data['token'] - else: - response = ctx.service_catalog - - # Target service catalog may not be passed via API. - # If we don't have the catalog yet, it should be requested. - if not response: - response = client().tokens.get_token_data( - token, - include_catalog=True - )['token'] - - if not response: - raise exceptions.UnauthorizedException() - - service_catalog = ks_service_catalog.ServiceCatalog.factory(response) - - return service_catalog - - -def get_keystone_endpoint(): - return get_endpoint_for_project('keystone', service_type='identity') - - -def get_keystone_url(): - return get_endpoint_for_project('keystone', service_type='identity').url - - -def format_url(url_template, values): - # Since we can't use keystone module, we can do similar thing: - # see https://github.com/openstack/keystone/blob/master/keystone/ - # catalog/core.py#L42-L60 - return url_template.replace('$(', '%(') % values - - -def is_token_trust_scoped(auth_token): - return 'OS-TRUST:trust' in client_for_admin().tokens.validate(auth_token) - - -def get_admin_session(): - """Returns a keystone session from Mistral's service credentials.""" - if CONF.keystone_authtoken.auth_type is None: - auth = auth_plugins.Password( - CONF.keystone_authtoken.www_authenticate_uri, - username=CONF.keystone_authtoken.admin_user, - password=CONF.keystone_authtoken.admin_password, - project_name=CONF.keystone_authtoken.admin_tenant_name, - # NOTE(jaosorior): Once mistral supports keystone v3 properly, we - # can fetch the following values from the configuration. - user_domain_name='Default', - project_domain_name='Default') - - return ks_session.Session(auth=auth) - else: - auth = loading.load_auth_from_conf_options( - CONF, - 'keystone_authtoken' - ) - - return loading.load_session_from_conf_options( - CONF, - 'keystone', - auth=auth - ) - - -def will_expire_soon(expires_at): - if not expires_at: - return False - stale_duration = CONF.expiration_token_duration - assert stale_duration, "expiration_token_duration must be specified" - expires = timeutils.parse_isotime(expires_at) - return timeutils.is_soon(expires, stale_duration) diff --git a/mistral/workflow/data_flow.py b/mistral/workflow/data_flow.py index a5a5cc49c..7dd94a895 100644 --- a/mistral/workflow/data_flow.py +++ b/mistral/workflow/data_flow.py @@ -22,9 +22,9 @@ from mistral.db.v2.sqlalchemy import models from mistral import exceptions as exc from mistral import expressions as expr from mistral.lang import parser as spec_parser -from mistral.utils import inspect_utils from mistral.workflow import states from mistral_lib import utils +from mistral_lib.utils import inspect_utils LOG = logging.getLogger(__name__) CONF = cfg.CONF diff --git a/releasenotes/notes/move_openstack_actions_from_mistral_to_mistral_extra-b3f7bc71ffd72c6e.yaml b/releasenotes/notes/move_openstack_actions_from_mistral_to_mistral_extra-b3f7bc71ffd72c6e.yaml new file mode 100644 index 000000000..00bb14aad --- /dev/null +++ b/releasenotes/notes/move_openstack_actions_from_mistral_to_mistral_extra-b3f7bc71ffd72c6e.yaml @@ -0,0 +1,3 @@ +--- +features: + - Move Mistral actions for OpenStack to mistral-extra library \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 674472dfc..3bf804852 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,18 +3,16 @@ # process, which may cause wedges in the gate later. alembic>=0.8.10 # MIT -aodhclient>=0.9.0 # Apache-2.0 Babel!=2.4.0,>=2.3.4 # BSD croniter>=0.3.4 # MIT License cachetools>=2.0.0 # MIT License dogpile.cache>=0.6.2 # BSD eventlet!=0.20.1,!=0.21.0,!=0.23.0,!=0.25.0,>=0.20.0 # MIT -gnocchiclient>=3.3.1 # Apache-2.0 Jinja2>=2.10 # BSD License (3 clause) -#jsonschema>=2.6.0 # MIT +jsonschema>=2.6.0 # MIT keystonemiddleware>=4.18.0 # Apache-2.0 kombu!=4.0.2,>=4.6.1 # BSD -mistral-lib>=1.2.0 # Apache-2.0 +mistral-lib>=1.4.0 # Apache-2.0 networkx<2.3,>=1.10;python_version<'3.0' # BSD networkx>=2.3;python_version>='3.4' # BSD oslo.concurrency>=3.26.0 # Apache-2.0 @@ -33,29 +31,6 @@ osprofiler>=1.4.0 # Apache-2.0 paramiko>=2.0.0 # LGPLv2.1+ pbr!=2.1.0,>=2.0.0 # Apache-2.0 pecan>=1.2.1 # BSD -python-barbicanclient>=4.5.2 # Apache-2.0 -python-cinderclient!=4.0.0,>=3.3.0 # Apache-2.0 -python-zaqarclient>=1.0.0 # Apache-2.0 -python-designateclient>=2.7.0 # Apache-2.0 -python-glanceclient>=2.8.0 # Apache-2.0 -python-glareclient>=0.3.0 # Apache-2.0 -python-heatclient>=1.10.0 # Apache-2.0 -python-keystoneclient>=3.8.0 # Apache-2.0 -python-mistralclient!=3.2.0,>=3.1.0 # Apache-2.0 -python-manilaclient>=1.23.0 # Apache-2.0 -python-magnumclient>=2.1.0 # Apache-2.0 -python-muranoclient>=0.8.2 # Apache-2.0 -python-neutronclient>=6.7.0 # Apache-2.0 -python-novaclient>=9.1.0 # Apache-2.0 -python-senlinclient>=1.1.0 # Apache-2.0 -python-swiftclient>=3.2.0 # Apache-2.0 -python-tackerclient>=0.8.0 # Apache-2.0 -python-troveclient>=2.2.0 # Apache-2.0 -python-ironicclient!=2.7.1,!=3.0.0,>=2.7.0 # Apache-2.0 -python-ironic-inspector-client>=1.5.0 # Apache-2.0 -python-vitrageclient>=2.0.0 # Apache-2.0 -python-zunclient>=3.4.0 # Apache-2.0 -python-qinlingclient>=1.0.0 # Apache-2.0 PyJWT>=1.5 # MIT PyYAML>=5.1 # MIT requests>=2.14.2 # Apache-2.0 diff --git a/test-requirements.txt b/test-requirements.txt index 3f1daa245..3f3393065 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -4,26 +4,16 @@ hacking>=1.1.0 # Apache-2.0 coverage!=4.4,>=4.0 # Apache-2.0 -croniter>=0.3.4 # MIT License doc8>=0.6.0 # Apache-2.0 +Pygments>=2.2.0 # BSD license fixtures>=3.0.0 # Apache-2.0/BSD -keystonemiddleware>=4.18.0 # Apache-2.0 -mistral-lib>=1.2.0 # Apache-2.0 mock>=2.0.0 # BSD -networkx<2.3,>=1.10;python_version<'3.0' # BSD -networkx>=2.3;python_version>='3.4' # BSD nose>=1.3.7 # LGPL oslotest>=3.2.0 # Apache-2.0 -oslo.db>=4.27.0 # Apache-2.0 -oslo.messaging>=5.29.0 # Apache-2.0 -oslo.policy>=1.30.0 # Apache-2.0 -osprofiler>=1.4.0 # Apache-2.0 -os-api-ref>=1.4.0 # Apache-2.0 -oauthlib>=0.6.2 # BSD requests-mock>=1.2.0 # Apache-2.0 tooz>=1.58.0 # Apache-2.0 tempest>=17.1.0 # Apache-2.0 stestr>=2.0.0 # Apache-2.0 testtools>=2.2.0 # MIT unittest2>=1.1.0 # BSD -WSME>=0.8.0 # MIT + diff --git a/tools/get_action_list.py b/tools/get_action_list.py deleted file mode 100644 index 522c96e4d..000000000 --- a/tools/get_action_list.py +++ /dev/null @@ -1,356 +0,0 @@ -# Copyright 2015 - Mirantis, Inc. -# -# 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 argparse -import collections -import inspect -import json -import os - -from aodhclient.v2 import base as aodh_base -from aodhclient.v2 import client as aodhclient -from barbicanclient import base as barbican_base -from barbicanclient import client as barbicanclient -from cinderclient.apiclient import base as cinder_base -from cinderclient.v2 import client as cinderclient -from designateclient import client as designateclient -from glanceclient.v2 import client as glanceclient -from glareclient.v1 import client as glareclient -from gnocchiclient.v1 import base as gnocchi_base -from gnocchiclient.v1 import client as gnocchiclient -from heatclient.common import base as heat_base -from heatclient.v1 import client as heatclient -from ironicclient.common import base as ironic_base -from ironicclient.v1 import client as ironicclient -from keystoneclient import base as keystone_base -from keystoneclient.v3 import client as keystoneclient -from magnumclient.common import base as magnum_base -from magnumclient.v1 import client as magnumclient -from manilaclient import base as manila_base -from manilaclient.v2 import client as manilaclient -from mistralclient.api import base as mistral_base -from mistralclient.api.v2 import client as mistralclient -from muranoclient.common import base as murano_base -from muranoclient.v1 import client as muranoclient -from novaclient import base as nova_base -from novaclient import client as novaclient -from troveclient import base as trove_base -from troveclient.v1 import client as troveclient - -# TODO(nmakhotkin): Find a rational way to do it for neutron. -# TODO(nmakhotkin): Implement recursive way of searching for managers -# TODO(nmakhotkin): (e.g. keystone). -# TODO(dprince): Need to update ironic_inspector_client before we can -# plug it in cleanly here. -# TODO(dprince): Swiftclient doesn't currently support discovery -# like we do in this class. -# TODO(therve): Zaqarclient doesn't currently support discovery -# like we do in this class. -# TODO(sa709c): Tackerclient doesn't currently support discovery -# like we do in this class. - -"""It is simple CLI tool which allows to see and update mapping.json file -if needed. mapping.json contains all allowing OpenStack actions sorted by -service name. Usage example: - - python tools/get_action_list.py nova - -The result will be simple JSON containing action name as a key and method -path as a value. For updating mapping.json it is need to copy all keys and -values of the result to corresponding section of mapping.json: - - ...mapping.json... - "nova": { - - }, - ...mapping.json... - - -Note: in case of Keystone service, correct OS_AUTH_URL v3 and the rest auth -info must be provided. It can be provided either via environment variables -or CLI arguments. See --help for details. -""" - -BASE_HEAT_MANAGER = heat_base.HookableMixin -BASE_NOVA_MANAGER = nova_base.HookableMixin -BASE_KEYSTONE_MANAGER = keystone_base.Manager -BASE_CINDER_MANAGER = cinder_base.HookableMixin -BASE_MISTRAL_MANAGER = mistral_base.ResourceManager -BASE_TROVE_MANAGER = trove_base.Manager -BASE_IRONIC_MANAGER = ironic_base.Manager -BASE_BARBICAN_MANAGER = barbican_base.BaseEntityManager -BASE_MANILA_MANAGER = manila_base.Manager -BASE_MAGNUM_MANAGER = magnum_base.Manager -BASE_MURANO_MANAGER = murano_base.Manager -BASE_AODH_MANAGER = aodh_base.Manager -BASE_GNOCCHI_MANAGER = gnocchi_base.Manager - - -def get_parser(): - parser = argparse.ArgumentParser( - description='Gets All needed methods of OpenStack clients.', - usage="python get_action_list.py " - ) - parser.add_argument( - 'service', - choices=CLIENTS.keys(), - help='Service name which methods need to be found.' - ) - parser.add_argument( - '--os-username', - dest='username', - default=os.environ.get('OS_USERNAME', 'admin'), - help='Authentication username (Env: OS_USERNAME)' - ) - parser.add_argument( - '--os-password', - dest='password', - default=os.environ.get('OS_PASSWORD', 'openstack'), - help='Authentication password (Env: OS_PASSWORD)' - ) - parser.add_argument( - '--os-tenant-name', - dest='tenant_name', - default=os.environ.get('OS_TENANT_NAME', 'Default'), - help='Authentication tenant name (Env: OS_TENANT_NAME)' - ) - parser.add_argument( - '--os-auth-url', - dest='auth_url', - default=os.environ.get('OS_AUTH_URL'), - help='Authentication URL (Env: OS_AUTH_URL)' - ) - - return parser - - -GLANCE_NAMESPACE_LIST = [ - 'image_members', 'image_tags', 'images', 'schemas', 'tasks', - 'metadefs_resource_type', 'metadefs_property', 'metadefs_object', - 'metadefs_tag', 'metadefs_namespace', 'versions' -] - - -DESIGNATE_NAMESPACE_LIST = [ - 'diagnostics', 'domains', 'quotas', 'records', 'reports', 'servers', - 'sync', 'touch' -] - - -GLARE_NAMESPACE_LIST = ['artifacts', 'versions'] - - -def get_nova_client(**kwargs): - return novaclient.Client(2) - - -def get_keystone_client(**kwargs): - return keystoneclient.Client(**kwargs) - - -def get_glance_client(**kwargs): - return glanceclient.Client(kwargs.get('auth_url')) - - -def get_heat_client(**kwargs): - return heatclient.Client('') - - -def get_cinder_client(**kwargs): - return cinderclient.Client() - - -def get_mistral_client(**kwargs): - return mistralclient.Client() - - -def get_trove_client(**kwargs): - return troveclient.Client('username', 'password') - - -def get_ironic_client(**kwargs): - return ironicclient.Client("http://127.0.0.1:6385/") - - -def get_barbican_client(**kwargs): - return barbicanclient.Client( - project_id="1", - endpoint="http://127.0.0.1:9311" - ) - - -def get_designate_client(**kwargs): - return designateclient.Client('2') - - -def get_magnum_client(**kwargs): - return magnumclient.Client() - - -def get_murano_client(**kwargs): - return muranoclient.Client('') - - -def get_aodh_client(**kwargs): - return aodhclient.Client('') - - -def get_gnocchi_client(**kwargs): - return gnocchiclient.Client() - - -def get_glare_client(**kwargs): - return glareclient.Client('') - - -def get_manila_client(**kwargs): - return manilaclient.Client( - input_auth_token='token', - service_catalog_url='http://127.0.0.1:8786' - ) - - -CLIENTS = { - 'nova': get_nova_client, - 'heat': get_heat_client, - 'cinder': get_cinder_client, - 'keystone': get_keystone_client, - 'glance': get_glance_client, - 'trove': get_trove_client, - 'ironic': get_ironic_client, - 'barbican': get_barbican_client, - 'mistral': get_mistral_client, - 'designate': get_designate_client, - 'magnum': get_magnum_client, - 'murano': get_murano_client, - 'aodh': get_aodh_client, - 'gnocchi': get_gnocchi_client, - 'glare': get_glare_client, - 'manila': get_manila_client, - # 'neutron': get_nova_client - # 'baremetal_introspection': ... - # 'swift': ... - # 'zaqar': ... -} -BASE_MANAGERS = { - 'nova': BASE_NOVA_MANAGER, - 'heat': BASE_HEAT_MANAGER, - 'cinder': BASE_CINDER_MANAGER, - 'keystone': BASE_KEYSTONE_MANAGER, - 'glance': None, - 'trove': BASE_TROVE_MANAGER, - 'ironic': BASE_IRONIC_MANAGER, - 'barbican': BASE_BARBICAN_MANAGER, - 'mistral': BASE_MISTRAL_MANAGER, - 'designate': None, - 'magnum': BASE_MAGNUM_MANAGER, - 'murano': BASE_MURANO_MANAGER, - 'aodh': BASE_AODH_MANAGER, - 'gnocchi': BASE_GNOCCHI_MANAGER, - 'glare': None, - 'manila': BASE_MANILA_MANAGER, - # 'neutron': BASE_NOVA_MANAGER - # 'baremetal_introspection': ... - # 'swift': ... - # 'zaqar': ... -} -NAMESPACES = { - 'glance': GLANCE_NAMESPACE_LIST, - 'designate': DESIGNATE_NAMESPACE_LIST, - 'glare': GLARE_NAMESPACE_LIST -} -ALLOWED_ATTRS = ['service_catalog', 'catalog'] -FORBIDDEN_METHODS = [ - 'add_hook', 'alternate_service_type', 'completion_cache', 'run_hooks', - 'write_to_completion_cache', 'model', 'build_key_only_query', 'build_url', - 'head', 'put', 'unvalidated_model' -] - - -def get_public_attrs(obj): - all_attrs = dir(obj) - - return [a for a in all_attrs if not a.startswith('_')] - - -def get_public_methods(attr, client): - hierarchy_list = attr.split('.') - attribute = client - - for attr in hierarchy_list: - attribute = getattr(attribute, attr) - all_attributes_list = get_public_attrs(attribute) - - methods = [] - for a in all_attributes_list: - allowed = a in ALLOWED_ATTRS - forbidden = a in FORBIDDEN_METHODS - - if (not forbidden and - (allowed or inspect.ismethod(getattr(attribute, a)))): - methods.append(a) - - return methods - - -def get_manager_list(service_name, client): - base_manager = BASE_MANAGERS[service_name] - - if not base_manager: - return NAMESPACES[service_name] - - public_attrs = get_public_attrs(client) - - manager_list = [] - - for attr in public_attrs: - if (isinstance(getattr(client, attr), base_manager) - or attr in ALLOWED_ATTRS): - manager_list.append(attr) - - return manager_list - - -def get_mapping_for_service(service, client): - mapping = collections.OrderedDict() - for man in get_manager_list(service, client): - public_methods = get_public_methods(man, client) - for method in public_methods: - key = "%s_%s" % (man, method) - value = "%s.%s" % (man, method) - mapping[key] = value - - return mapping - - -def print_mapping(mapping): - print(json.dumps(mapping, indent=8, separators=(',', ': '))) - - -if __name__ == "__main__": - args = get_parser().parse_args() - - auth_info = { - 'username': args.username, - 'tenant_name': args.tenant_name, - 'password': args.password, - 'auth_url': args.auth_url - } - - service = args.service - client = CLIENTS.get(service)(**auth_info) - - print("Find methods for service: %s..." % service) - - print_mapping(get_mapping_for_service(service, client)) diff --git a/tools/sync_db.py b/tools/sync_db.py index 09ea3300f..818801eb5 100644 --- a/tools/sync_db.py +++ b/tools/sync_db.py @@ -36,8 +36,6 @@ def main(): for group, opts in keystonemw_opts.list_auth_token_opts(): CONF.register_opts(opts, group=group) - CONF.register_cli_opt(config.os_actions_mapping_path) - logging.register_options(CONF) config.parse_args()