deb-murano/murano/policy/modify/actions/action_manager.py
Ravi Shekhar Jethani 7ea4442e9c Fix import order of modules
Make corrections in import order for six, yaml, eventlet and
greenlet as per OpenStack import standards [1].

[1] http://docs.openstack.org/developer/hacking/#import-order-template

Change-Id: I26feb4adb81e8b07a7a36ac7f0a6235536a8c119
2016-01-24 23:34:03 -08:00

96 lines
3.3 KiB
Python

# Copyright (c) 2015 OpenStack Foundation.
# All Rights Reserved.
#
# 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_log import log as logging
from oslo_utils import importutils
import six
from stevedore import extension
import yaml
LOG = logging.getLogger(__name__)
class ModifyActionManager(object):
"""Manages modify actions
The manager encapsulates extensible plugin mechanism for
modify actions loading. Provides ability to apply action on
given object model based on action specification retrieved
from congress
"""
def __init__(self):
self._cache = {}
def load_action(self, name):
"""Loads action by its name
Loaded actions are cached. Plugin mechanism is based on
distutils entry points. Entry point namespace is
'murano_policy_modify_actions'
:param name: action name
:return:
"""
if name in self._cache:
return self._cache[name]
action = self._load_action(name)
self._cache[name] = action
return action
@staticmethod
def _load_action(name):
mgr = extension.ExtensionManager(
namespace='murano_policy_modify_actions',
invoke_on_load=False
)
for ext in mgr.extensions:
if name == ext.name:
target = ext.entry_point_target.replace(':', '.')
return importutils.import_class(target)
raise ValueError('No such action definition: {action_name}'
.format(action_name=name))
def apply_action(self, obj, action_spec):
"""Apply action on given model
Parse action and its parameters from action specification
retrieved from congress. Action specification is YAML format.
E.g. remove-object: {object_id: abc123}")
Action names are keys in top-level dictionary. Values are
dictionaries containing key/value parameters of the action
:param obj: subject of modification
:param action_spec: YAML action spec
:raise ValueError: in case of malformed action spec
"""
actions = yaml.safe_load(action_spec)
if not isinstance(actions, dict):
raise ValueError('Expected action spec format is '
'"action-name: {{p1: v1, ...}}" '
'but got "{action_spec}"'
.format(action_spec=action_spec))
for name, kwargs in six.iteritems(actions):
LOG.debug('Executing action {name}, params {params}'
.format(name=name, params=kwargs))
# loads action class
action_class = self.load_action(name)
# creates action instance
action_instance = action_class(**kwargs)
# apply action on object model
action_instance.modify(obj)