Resolve issues with circular dependency
* Resolved issues with circular dependencies * Updated objects namespaces to the new io.murano.* namespace * Resolved a few issues related to not included code from PoC * Renamed objects to more pythonic name (back to original actually) Closes-bug: #1297146 Change-Id: I34641eca33c70908bd44b50f0956abda9d8dbfa7
This commit is contained in:
@@ -1,3 +1,3 @@
|
|||||||
Namespaces:
|
Namespaces:
|
||||||
=: org.openstack.murano
|
=: io.murano
|
||||||
Name: Application
|
Name: Application
|
@@ -1,6 +1,6 @@
|
|||||||
Namespaces:
|
Namespaces:
|
||||||
=: org.openstack.murano
|
=: io.murano
|
||||||
sys: org.openstack.murano.system
|
sys: io.murano.system
|
||||||
|
|
||||||
Name: Environment
|
Name: Environment
|
||||||
|
|
@@ -1,5 +1,5 @@
|
|||||||
Namespaces:
|
Namespaces:
|
||||||
=: org.openstack.murano
|
=: io.murano
|
||||||
Name: Object
|
Name: Object
|
||||||
|
|
||||||
Workflow:
|
Workflow:
|
@@ -22,13 +22,13 @@ from oslo.messaging import target
|
|||||||
from muranoapi.common import config
|
from muranoapi.common import config
|
||||||
from muranoapi.common.helpers import token_sanitizer
|
from muranoapi.common.helpers import token_sanitizer
|
||||||
from muranoapi.common import rpc
|
from muranoapi.common import rpc
|
||||||
|
from muranoapi.dsl import executor
|
||||||
|
from muranoapi.dsl import results_serializer
|
||||||
from muranoapi.engine import environment
|
from muranoapi.engine import environment
|
||||||
from muranoapi.engine import executor
|
from muranoapi.engine import simple_cloader
|
||||||
from muranoapi.engine import results_serializer
|
import muranoapi.engine.system.system_objects as system_objects
|
||||||
from muranoapi.engine import system
|
|
||||||
from muranoapi.openstack.common.gettextutils import _ # noqa
|
from muranoapi.openstack.common.gettextutils import _ # noqa
|
||||||
from muranoapi.openstack.common import log as logging
|
from muranoapi.openstack.common import log as logging
|
||||||
from muranoapi import simple_cloader
|
|
||||||
|
|
||||||
RPC_SERVICE = None
|
RPC_SERVICE = None
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ class TaskProcessingEndpoint(object):
|
|||||||
env.tenant_id = task['Objects']['?']['tenant_id']
|
env.tenant_id = task['Objects']['?']['tenant_id']
|
||||||
|
|
||||||
cl = simple_cloader.SimpleClassLoader(config.CONF.metadata_dir)
|
cl = simple_cloader.SimpleClassLoader(config.CONF.metadata_dir)
|
||||||
system.register(cl, config.CONF.metadata_dir)
|
system_objects.register(cl, config.CONF.metadata_dir)
|
||||||
|
|
||||||
exc = executor.MuranoDslExecutor(cl, env)
|
exc = executor.MuranoDslExecutor(cl, env)
|
||||||
obj = exc.load(task)
|
obj = exc.load(task)
|
||||||
|
0
muranoapi/dsl/__init__.py
Normal file
0
muranoapi/dsl/__init__.py
Normal file
@@ -12,7 +12,7 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from muranoapi.engine import objects
|
import muranoapi.dsl.murano_object as murano_object
|
||||||
|
|
||||||
|
|
||||||
class AttributeStore(object):
|
class AttributeStore(object):
|
||||||
@@ -20,7 +20,7 @@ class AttributeStore(object):
|
|||||||
self._attributes = {}
|
self._attributes = {}
|
||||||
|
|
||||||
def set(self, tagged_object, owner_type, name, value):
|
def set(self, tagged_object, owner_type, name, value):
|
||||||
if isinstance(value, objects.MuranoObject):
|
if isinstance(value, murano_object.MuranoObject):
|
||||||
value = value.object_id
|
value = value.object_id
|
||||||
|
|
||||||
key = (tagged_object.object_id, owner_type.name, name)
|
key = (tagged_object.object_id, owner_type.name, name)
|
@@ -18,13 +18,13 @@ import types
|
|||||||
import yaql
|
import yaql
|
||||||
import yaql.context
|
import yaql.context
|
||||||
|
|
||||||
from muranoapi.engine import classes
|
import muranoapi.dsl.exceptions as exceptions
|
||||||
from muranoapi.engine import exceptions
|
import muranoapi.dsl.helpers as helpers
|
||||||
from muranoapi.engine import helpers
|
import muranoapi.dsl.murano_class as murano_class
|
||||||
from muranoapi.engine import namespaces
|
import muranoapi.dsl.murano_object as murano_object
|
||||||
from muranoapi.engine import objects
|
import muranoapi.dsl.namespace_resolver as namespace_resolver
|
||||||
from muranoapi.engine import principal_objects
|
import muranoapi.dsl.principal_objects as principal_objects
|
||||||
from muranoapi.engine import typespec
|
import muranoapi.dsl.typespec as typespec
|
||||||
|
|
||||||
|
|
||||||
class MuranoClassLoader(object):
|
class MuranoClassLoader(object):
|
||||||
@@ -43,22 +43,23 @@ class MuranoClassLoader(object):
|
|||||||
else:
|
else:
|
||||||
raise exceptions.NoClassFound(name)
|
raise exceptions.NoClassFound(name)
|
||||||
|
|
||||||
namespace_resolver = namespaces.NamespaceResolver(
|
namespaces = data.get('Namespaces', {})
|
||||||
data.get('Namespaces', {}))
|
ns_resolver = namespace_resolver.NamespaceResolver(namespaces)
|
||||||
|
|
||||||
class_parents = data.get('Extends')
|
class_parents = data.get('Extends')
|
||||||
if class_parents:
|
if class_parents:
|
||||||
if not isinstance(class_parents, types.ListType):
|
if not isinstance(class_parents, types.ListType):
|
||||||
class_parents = [class_parents]
|
class_parents = [class_parents]
|
||||||
for i, parent in enumerate(class_parents):
|
for i, parent_name in enumerate(class_parents):
|
||||||
class_parents[i] = self.get_class(
|
full_name = ns_resolver.resolve_name(parent_name)
|
||||||
namespace_resolver.resolve_name(parent))
|
class_parents[i] = self.get_class(full_name)
|
||||||
type_obj = classes.MuranoClass(self, namespace_resolver, name,
|
|
||||||
|
type_obj = murano_class.MuranoClass(self, ns_resolver, name,
|
||||||
class_parents)
|
class_parents)
|
||||||
|
|
||||||
p_iter = data.get('Properties', {}).iteritems()
|
properties = data.get('Properties', {})
|
||||||
for property_name, property_spec in p_iter:
|
for property_name, property_spec in properties.iteritems():
|
||||||
spec = typespec.PropertySpec(property_spec, namespace_resolver)
|
spec = typespec.PropertySpec(property_spec, ns_resolver)
|
||||||
type_obj.add_property(property_name, spec)
|
type_obj.add_property(property_name, spec)
|
||||||
|
|
||||||
for method_name, payload in data.get('Workflow', {}).iteritems():
|
for method_name, payload in data.get('Workflow', {}).iteritems():
|
||||||
@@ -96,16 +97,16 @@ class MuranoClassLoader(object):
|
|||||||
else:
|
else:
|
||||||
name = cls.__class__._murano_class_name
|
name = cls.__class__._murano_class_name
|
||||||
|
|
||||||
murano_class = self.get_class(name, create_missing=True)
|
m_class = self.get_class(name, create_missing=True)
|
||||||
if inspect.isclass(cls):
|
if inspect.isclass(cls):
|
||||||
if issubclass(cls, objects.MuranoObject):
|
if issubclass(cls, murano_object.MuranoObject):
|
||||||
murano_class.object_class = cls
|
m_class.object_class = cls
|
||||||
else:
|
else:
|
||||||
murano_class.object_class = type(
|
mpc_name = 'mpc' + helpers.generate_id()
|
||||||
'mpc' + helpers.generate_id(),
|
bases = (cls, murano_object.MuranoObject)
|
||||||
(cls, objects.MuranoObject), {})
|
m_class.object_class = type(mpc_name, bases, {})
|
||||||
|
|
||||||
for item in dir(cls):
|
for item in dir(cls):
|
||||||
method = getattr(cls, item)
|
method = getattr(cls, item)
|
||||||
if callable(method) and not item.startswith('_'):
|
if callable(method) and not item.startswith('_'):
|
||||||
murano_class.add_method(item, method)
|
m_class.add_method(item, method)
|
@@ -18,23 +18,23 @@ import types
|
|||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
import eventlet
|
import eventlet
|
||||||
from eventlet import event as e_event
|
import eventlet.event
|
||||||
from yaql import context as y_context
|
import yaql.context
|
||||||
|
|
||||||
from muranoapi.engine import attribute_store as attr_store
|
import muranoapi.dsl.attribute_store as attribute_store
|
||||||
from muranoapi.engine import exceptions
|
import muranoapi.dsl.exceptions as exceptions
|
||||||
from muranoapi.engine import expressions
|
import muranoapi.dsl.expressions as expressions
|
||||||
from muranoapi.engine import helpers
|
import muranoapi.dsl.helpers as helpers
|
||||||
from muranoapi.engine import object_store
|
import muranoapi.dsl.murano_object as murano_object
|
||||||
from muranoapi.engine import objects
|
import muranoapi.dsl.object_store as object_store
|
||||||
from muranoapi.engine import yaql_functions
|
import muranoapi.dsl.yaql_functions as yaql_functions
|
||||||
|
|
||||||
|
|
||||||
class MuranoDslExecutor(object):
|
class MuranoDslExecutor(object):
|
||||||
def __init__(self, class_loader, environment=None):
|
def __init__(self, class_loader, environment=None):
|
||||||
self._class_loader = class_loader
|
self._class_loader = class_loader
|
||||||
self._object_store = object_store.ObjectStore(class_loader)
|
self._object_store = object_store.ObjectStore(class_loader)
|
||||||
self._attribute_store = attr_store.AttributeStore()
|
self._attribute_store = attribute_store.AttributeStore()
|
||||||
self._root_context = class_loader.create_root_context()
|
self._root_context = class_loader.create_root_context()
|
||||||
self._root_context.set_data(self, '?executor')
|
self._root_context.set_data(self, '?executor')
|
||||||
self._root_context.set_data(self._class_loader, '?classLoader')
|
self._root_context.set_data(self._class_loader, '?classLoader')
|
||||||
@@ -43,7 +43,7 @@ class MuranoDslExecutor(object):
|
|||||||
self._root_context.set_data(self._attribute_store, '?attributeStore')
|
self._root_context.set_data(self._attribute_store, '?attributeStore')
|
||||||
self._locks = {}
|
self._locks = {}
|
||||||
yaql_functions.register(self._root_context)
|
yaql_functions.register(self._root_context)
|
||||||
self._root_context = y_context.Context(self._root_context)
|
self._root_context = yaql.context.Context(self._root_context)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def object_store(self):
|
def object_store(self):
|
||||||
@@ -80,7 +80,6 @@ class MuranoDslExecutor(object):
|
|||||||
params = self._evaluate_parameters(
|
params = self._evaluate_parameters(
|
||||||
arguments_scheme, context, this, *args)
|
arguments_scheme, context, this, *args)
|
||||||
except Exception:
|
except Exception:
|
||||||
# TODO(slagun): print exception
|
|
||||||
params = self._evaluate_parameters(
|
params = self._evaluate_parameters(
|
||||||
arguments_scheme, context, this, *args)
|
arguments_scheme, context, this, *args)
|
||||||
delegates.append(functools.partial(
|
delegates.append(functools.partial(
|
||||||
@@ -118,7 +117,7 @@ class MuranoDslExecutor(object):
|
|||||||
body, this, params, murano_class, context)
|
body, this, params, murano_class, context)
|
||||||
event.wait()
|
event.wait()
|
||||||
|
|
||||||
event = e_event.Event()
|
event = eventlet.event.Event()
|
||||||
self._locks[(method_id, this_id)] = (event, thread_marker)
|
self._locks[(method_id, this_id)] = (event, thread_marker)
|
||||||
gt = eventlet.spawn(self._invoke_method_implementation_gt, body,
|
gt = eventlet.spawn(self._invoke_method_implementation_gt, body,
|
||||||
this, params, murano_class, context,
|
this, params, murano_class, context,
|
||||||
@@ -191,13 +190,13 @@ class MuranoDslExecutor(object):
|
|||||||
new_context.set_data(murano_class, '?type')
|
new_context.set_data(murano_class, '?type')
|
||||||
new_context.set_data(context, '?callerContext')
|
new_context.set_data(context, '?callerContext')
|
||||||
|
|
||||||
@y_context.EvalArg('obj', arg_type=objects.MuranoObject)
|
@yaql.context.EvalArg('obj', arg_type=murano_object.MuranoObject)
|
||||||
@y_context.EvalArg('property_name', arg_type=str)
|
@yaql.context.EvalArg('property_name', arg_type=str)
|
||||||
def obj_attribution(obj, property_name):
|
def obj_attribution(obj, property_name):
|
||||||
return obj.get_property(property_name, murano_class)
|
return obj.get_property(property_name, murano_class)
|
||||||
|
|
||||||
@y_context.EvalArg('prefix', str)
|
@yaql.context.EvalArg('prefix', str)
|
||||||
@y_context.EvalArg('name', str)
|
@yaql.context.EvalArg('name', str)
|
||||||
def validate(prefix, name):
|
def validate(prefix, name):
|
||||||
return murano_class.namespace_resolver.resolve_name(
|
return murano_class.namespace_resolver.resolve_name(
|
||||||
'%s:%s' % (prefix, name))
|
'%s:%s' % (prefix, name))
|
@@ -14,10 +14,9 @@
|
|||||||
|
|
||||||
import types
|
import types
|
||||||
|
|
||||||
from muranoapi.engine import helpers
|
import muranoapi.dsl.helpers as helpers
|
||||||
from muranoapi.engine import lhs_expression as lhs
|
import muranoapi.dsl.lhs_expression as lhs_expression
|
||||||
from muranoapi.engine import yaql_expression
|
import muranoapi.dsl.yaql_expression as yaql_expression
|
||||||
|
|
||||||
|
|
||||||
_macros = []
|
_macros = []
|
||||||
|
|
||||||
@@ -44,7 +43,7 @@ class Statement(DslExpression):
|
|||||||
else:
|
else:
|
||||||
raise SyntaxError()
|
raise SyntaxError()
|
||||||
|
|
||||||
self._destination = None if not key else lhs.LhsExpression(key)
|
self._destination = lhs_expression.LhsExpression(key) if key else None
|
||||||
self._expression = value
|
self._expression = value
|
||||||
|
|
||||||
@property
|
@property
|
@@ -14,105 +14,39 @@
|
|||||||
|
|
||||||
import collections
|
import collections
|
||||||
import re
|
import re
|
||||||
|
import sys
|
||||||
import types
|
import types
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
import deep
|
import deep
|
||||||
from eventlet import greenpool
|
import eventlet.greenpool
|
||||||
import yaql
|
import yaql.expressions
|
||||||
|
|
||||||
from muranoapi.engine import consts
|
import muranoapi.dsl.murano_object
|
||||||
from muranoapi.engine import yaql_expression
|
import muranoapi.dsl.yaql_expression as yaql_expression
|
||||||
|
|
||||||
|
|
||||||
def merge_lists(list1, list2):
|
def serialize(value, memo=None):
|
||||||
result = []
|
if memo is None:
|
||||||
for item in list1 + list2:
|
memo = set()
|
||||||
exists = False
|
if isinstance(value, types.DictionaryType):
|
||||||
for old_item in result:
|
|
||||||
if deep.diff(item, old_item) is None:
|
|
||||||
exists = True
|
|
||||||
break
|
|
||||||
if not exists:
|
|
||||||
result.append(item)
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def merge_dicts(dict1, dict2, max_levels=0):
|
|
||||||
result = {}
|
result = {}
|
||||||
for key, value in dict1.items():
|
for d_key, d_value in value.iteritems():
|
||||||
result[key] = value
|
result[d_key] = serialize(d_value, memo)
|
||||||
if key in dict2:
|
|
||||||
other_value = dict2[key]
|
|
||||||
if type(other_value) != type(value):
|
|
||||||
raise TypeError()
|
|
||||||
if max_levels != 1 and isinstance(
|
|
||||||
other_value, types.DictionaryType):
|
|
||||||
result[key] = merge_dicts(
|
|
||||||
value, other_value,
|
|
||||||
0 if max_levels == 0 else max_levels - 1)
|
|
||||||
elif max_levels != 1 and isinstance(
|
|
||||||
other_value, types.ListType):
|
|
||||||
result[key] = merge_lists(value, other_value)
|
|
||||||
else:
|
|
||||||
result[key] = other_value
|
|
||||||
for key, value in dict2.items():
|
|
||||||
if key not in result:
|
|
||||||
result[key] = value
|
|
||||||
return result
|
return result
|
||||||
|
elif isinstance(value, muranoapi.dsl.murano_object.MuranoObject):
|
||||||
|
if not value.object_id in memo:
|
||||||
|
memo.add(value.object_id)
|
||||||
|
return serialize(value.to_dictionary(), memo)
|
||||||
|
else:
|
||||||
|
return value.object_id
|
||||||
|
elif isinstance(value, types.ListType):
|
||||||
|
return [serialize(t, memo) for t in value]
|
||||||
|
else:
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
def parallel_select(collection, func):
|
def evaluate(value, context, max_depth=sys.maxint):
|
||||||
gp = greenpool.GreenPool()
|
|
||||||
return list(gp.imap(func, collection))
|
|
||||||
|
|
||||||
|
|
||||||
def to_python_codestyle(name):
|
|
||||||
s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
|
|
||||||
return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower()
|
|
||||||
|
|
||||||
|
|
||||||
def enum(**enums):
|
|
||||||
return type('Enum', (), enums)
|
|
||||||
|
|
||||||
|
|
||||||
def get_executor(context):
|
|
||||||
return context.get_data('$?executor')
|
|
||||||
|
|
||||||
|
|
||||||
def get_class_loader(context):
|
|
||||||
return context.get_data('$?classLoader')
|
|
||||||
|
|
||||||
|
|
||||||
def get_type(context):
|
|
||||||
return context.get_data('$?type')
|
|
||||||
|
|
||||||
|
|
||||||
def get_environment(context):
|
|
||||||
return context.get_data('$?environment')
|
|
||||||
|
|
||||||
|
|
||||||
def get_object_store(context):
|
|
||||||
return context.get_data('$?objectStore')
|
|
||||||
|
|
||||||
|
|
||||||
def get_this(context):
|
|
||||||
return context.get_data('$?this')
|
|
||||||
|
|
||||||
|
|
||||||
def get_caller_context(context):
|
|
||||||
return context.get_data('$?callerContext')
|
|
||||||
|
|
||||||
|
|
||||||
def get_attribute_store(context):
|
|
||||||
return context.get_data('$?attributeStore')
|
|
||||||
|
|
||||||
|
|
||||||
def generate_id():
|
|
||||||
return uuid.uuid4().hex
|
|
||||||
|
|
||||||
|
|
||||||
def evaluate(value, context, max_depth=consts.EVALUATION_MAX_DEPTH):
|
|
||||||
if isinstance(value, (yaql_expression.YaqlExpression,
|
if isinstance(value, (yaql_expression.YaqlExpression,
|
||||||
yaql.expressions.Expression)):
|
yaql.expressions.Expression)):
|
||||||
func = lambda: evaluate(value.evaluate(context), context, 1)
|
func = lambda: evaluate(value.evaluate(context), context, 1)
|
||||||
@@ -156,3 +90,90 @@ def needs_evaluation(value):
|
|||||||
if needs_evaluation(t):
|
if needs_evaluation(t):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def merge_lists(list1, list2):
|
||||||
|
result = []
|
||||||
|
for item in list1 + list2:
|
||||||
|
exists = False
|
||||||
|
for old_item in result:
|
||||||
|
if deep.diff(item, old_item) is None:
|
||||||
|
exists = True
|
||||||
|
break
|
||||||
|
if not exists:
|
||||||
|
result.append(item)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def merge_dicts(dict1, dict2, max_levels=0):
|
||||||
|
result = {}
|
||||||
|
for key, value in dict1.items():
|
||||||
|
result[key] = value
|
||||||
|
if key in dict2:
|
||||||
|
other_value = dict2[key]
|
||||||
|
if type(other_value) != type(value):
|
||||||
|
raise TypeError()
|
||||||
|
if max_levels != 1 and isinstance(
|
||||||
|
other_value, types.DictionaryType):
|
||||||
|
result[key] = merge_dicts(
|
||||||
|
value, other_value,
|
||||||
|
0 if max_levels == 0 else max_levels - 1)
|
||||||
|
elif max_levels != 1 and isinstance(
|
||||||
|
other_value, types.ListType):
|
||||||
|
result[key] = merge_lists(value, other_value)
|
||||||
|
else:
|
||||||
|
result[key] = other_value
|
||||||
|
for key, value in dict2.items():
|
||||||
|
if key not in result:
|
||||||
|
result[key] = value
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def generate_id():
|
||||||
|
return uuid.uuid4().hex
|
||||||
|
|
||||||
|
|
||||||
|
def parallel_select(collection, func):
|
||||||
|
gpool = eventlet.greenpool.GreenPool()
|
||||||
|
return list(gpool.imap(func, collection))
|
||||||
|
|
||||||
|
|
||||||
|
def to_python_codestyle(name):
|
||||||
|
s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
|
||||||
|
return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower()
|
||||||
|
|
||||||
|
|
||||||
|
def enum(**enums):
|
||||||
|
return type('Enum', (), enums)
|
||||||
|
|
||||||
|
|
||||||
|
def get_executor(context):
|
||||||
|
return context.get_data('$?executor')
|
||||||
|
|
||||||
|
|
||||||
|
def get_class_loader(context):
|
||||||
|
return context.get_data('$?classLoader')
|
||||||
|
|
||||||
|
|
||||||
|
def get_type(context):
|
||||||
|
return context.get_data('$?type')
|
||||||
|
|
||||||
|
|
||||||
|
def get_environment(context):
|
||||||
|
return context.get_data('$?environment')
|
||||||
|
|
||||||
|
|
||||||
|
def get_object_store(context):
|
||||||
|
return context.get_data('$?objectStore')
|
||||||
|
|
||||||
|
|
||||||
|
def get_this(context):
|
||||||
|
return context.get_data('$?this')
|
||||||
|
|
||||||
|
|
||||||
|
def get_caller_context(context):
|
||||||
|
return context.get_data('$?callerContext')
|
||||||
|
|
||||||
|
|
||||||
|
def get_attribute_store(context):
|
||||||
|
return context.get_data('$?attributeStore')
|
@@ -15,12 +15,12 @@
|
|||||||
import types
|
import types
|
||||||
|
|
||||||
import yaql
|
import yaql
|
||||||
from yaql import context as y_context
|
import yaql.context
|
||||||
import yaql.expressions
|
import yaql.expressions
|
||||||
|
|
||||||
from muranoapi.engine import objects
|
import muranoapi.dsl.murano_object as murano_object
|
||||||
from muranoapi.engine import type_scheme
|
import muranoapi.dsl.type_scheme as type_scheme
|
||||||
from muranoapi.engine import yaql_expression as y_expression
|
import muranoapi.dsl.yaql_expression as yaql_expression
|
||||||
|
|
||||||
|
|
||||||
class LhsExpression(object):
|
class LhsExpression(object):
|
||||||
@@ -36,7 +36,7 @@ class LhsExpression(object):
|
|||||||
self._setter(value)
|
self._setter(value)
|
||||||
|
|
||||||
def __init__(self, expression):
|
def __init__(self, expression):
|
||||||
if isinstance(expression, (y_expression.YaqlExpression,
|
if isinstance(expression, (yaql_expression.YaqlExpression,
|
||||||
yaql.expressions.Expression)):
|
yaql.expressions.Expression)):
|
||||||
self._expression = expression
|
self._expression = expression
|
||||||
else:
|
else:
|
||||||
@@ -51,7 +51,7 @@ class LhsExpression(object):
|
|||||||
elif isinstance(src, types.ListType) and isinstance(
|
elif isinstance(src, types.ListType) and isinstance(
|
||||||
key, types.IntType):
|
key, types.IntType):
|
||||||
return src[key]
|
return src[key]
|
||||||
elif isinstance(src, objects.MuranoObject) and isinstance(
|
elif isinstance(src, murano_object.MuranoObject) and isinstance(
|
||||||
key, types.StringTypes):
|
key, types.StringTypes):
|
||||||
self._current_obj = src
|
self._current_obj = src
|
||||||
self._current_obj_name = key
|
self._current_obj_name = key
|
||||||
@@ -89,7 +89,7 @@ class LhsExpression(object):
|
|||||||
src[key] = old_value
|
src[key] = old_value
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
elif isinstance(src, objects.MuranoObject) and isinstance(
|
elif isinstance(src, murano_object.MuranoObject) and isinstance(
|
||||||
key, types.StringTypes):
|
key, types.StringTypes):
|
||||||
self._current_spec = src.type.find_property(key)
|
self._current_spec = src.type.find_property(key)
|
||||||
src.set_property(key, value, murano_class)
|
src.set_property(key, value, murano_class)
|
||||||
@@ -107,20 +107,20 @@ class LhsExpression(object):
|
|||||||
return LhsExpression.Property(
|
return LhsExpression.Property(
|
||||||
lambda: root_context.get_data(path), set_data)
|
lambda: root_context.get_data(path), set_data)
|
||||||
|
|
||||||
@y_context.EvalArg('this', arg_type=LhsExpression.Property)
|
@yaql.context.EvalArg('this', arg_type=LhsExpression.Property)
|
||||||
def attribution(this, arg_name):
|
def attribution(this, arg_name):
|
||||||
arg_name = arg_name()
|
arg_name = arg_name()
|
||||||
return LhsExpression.Property(
|
return LhsExpression.Property(
|
||||||
lambda: _get_value(this.get(), arg_name),
|
lambda: _get_value(this.get(), arg_name),
|
||||||
lambda value: _set_value(this.get(), arg_name, value))
|
lambda value: _set_value(this.get(), arg_name, value))
|
||||||
|
|
||||||
@y_context.EvalArg("this", LhsExpression.Property)
|
@yaql.context.EvalArg("this", LhsExpression.Property)
|
||||||
def indexation(this, index):
|
def indexation(this, index):
|
||||||
return LhsExpression.Property(
|
return LhsExpression.Property(
|
||||||
lambda: _get_value(this.get(), index()),
|
lambda: _get_value(this.get(), index()),
|
||||||
lambda value: _set_value(this.get(), index(), value))
|
lambda value: _set_value(this.get(), index(), value))
|
||||||
|
|
||||||
context = y_context.Context()
|
context = yaql.context.Context()
|
||||||
context.register_function(get_context_data, '#get_context_data')
|
context.register_function(get_context_data, '#get_context_data')
|
||||||
context.register_function(attribution, '#operator_.')
|
context.register_function(attribution, '#operator_.')
|
||||||
context.register_function(indexation, "where")
|
context.register_function(indexation, "where")
|
@@ -14,13 +14,13 @@
|
|||||||
|
|
||||||
import types
|
import types
|
||||||
|
|
||||||
from eventlet import greenpool
|
import eventlet.greenpool as greenpool
|
||||||
from yaql import context as y_context
|
import yaql.context
|
||||||
|
|
||||||
from muranoapi.engine import exceptions
|
import muranoapi.dsl.exceptions as exceptions
|
||||||
from muranoapi.engine import expressions
|
import muranoapi.dsl.expressions as expressions
|
||||||
from muranoapi.engine import helpers
|
import muranoapi.dsl.helpers as helpers
|
||||||
from muranoapi.engine import yaql_expression
|
import muranoapi.dsl.yaql_expression as yaql_expression
|
||||||
|
|
||||||
|
|
||||||
class CodeBlock(expressions.DslExpression):
|
class CodeBlock(expressions.DslExpression):
|
||||||
@@ -81,10 +81,10 @@ class ParallelMacro(CodeBlock):
|
|||||||
def execute(self, context, murano_class):
|
def execute(self, context, murano_class):
|
||||||
if not self.code_block:
|
if not self.code_block:
|
||||||
return
|
return
|
||||||
gp = greenpool.GreenPool(helpers.evaluate(self._limit, context))
|
gpool = greenpool.GreenPool(helpers.evaluate(self._limit, context))
|
||||||
for expr in self.code_block:
|
for expr in self.code_block:
|
||||||
gp.spawn_n(expr.execute, context, murano_class)
|
gpool.spawn_n(expr.execute, context, murano_class)
|
||||||
gp.waitall()
|
gpool.waitall()
|
||||||
|
|
||||||
|
|
||||||
class IfMacro(expressions.DslExpression):
|
class IfMacro(expressions.DslExpression):
|
||||||
@@ -136,7 +136,7 @@ class ForMacro(expressions.DslExpression):
|
|||||||
|
|
||||||
def execute(self, context, murano_class):
|
def execute(self, context, murano_class):
|
||||||
collection = helpers.evaluate(self._collection, context)
|
collection = helpers.evaluate(self._collection, context)
|
||||||
child_context = y_context.Context(context)
|
child_context = yaql.context.Context(context)
|
||||||
for t in collection:
|
for t in collection:
|
||||||
child_context.set_data(t, self._var)
|
child_context.set_data(t, self._var)
|
||||||
try:
|
try:
|
||||||
@@ -189,8 +189,7 @@ class SwitchMacro(expressions.DslExpression):
|
|||||||
def execute(self, context, murano_class):
|
def execute(self, context, murano_class):
|
||||||
matched = False
|
matched = False
|
||||||
for key, value in self._switch.iteritems():
|
for key, value in self._switch.iteritems():
|
||||||
if not isinstance(key,
|
if not isinstance(key, (yaql_expression.YaqlExpression,
|
||||||
(yaql_expression.YaqlExpression,
|
|
||||||
types.BooleanType)):
|
types.BooleanType)):
|
||||||
raise SyntaxError()
|
raise SyntaxError()
|
||||||
res = helpers.evaluate(key, context)
|
res = helpers.evaluate(key, context)
|
||||||
@@ -198,7 +197,7 @@ class SwitchMacro(expressions.DslExpression):
|
|||||||
raise TypeError()
|
raise TypeError()
|
||||||
if res:
|
if res:
|
||||||
matched = True
|
matched = True
|
||||||
child_context = y_context.Context(context)
|
child_context = yaql.context.Context(context)
|
||||||
CodeBlock(value).execute(child_context, murano_class)
|
CodeBlock(value).execute(child_context, murano_class)
|
||||||
|
|
||||||
if self._default is not None and not matched:
|
if self._default is not None and not matched:
|
||||||
@@ -210,7 +209,7 @@ class DoMacro(expressions.DslExpression):
|
|||||||
self._code = CodeBlock(Do)
|
self._code = CodeBlock(Do)
|
||||||
|
|
||||||
def execute(self, context, murano_class):
|
def execute(self, context, murano_class):
|
||||||
child_context = y_context.Context(context)
|
child_context = yaql.context.Context(context)
|
||||||
self._code.execute(child_context, murano_class)
|
self._code.execute(child_context, murano_class)
|
||||||
|
|
||||||
|
|
@@ -15,10 +15,10 @@
|
|||||||
import collections
|
import collections
|
||||||
import inspect
|
import inspect
|
||||||
|
|
||||||
from muranoapi.engine import helpers
|
import muranoapi.dsl.helpers as helpers
|
||||||
from muranoapi.engine import methods as engine_methods
|
import muranoapi.dsl.murano_method as murano_method
|
||||||
from muranoapi.engine import objects
|
import muranoapi.dsl.murano_object as murano_object
|
||||||
from muranoapi.engine import typespec
|
import muranoapi.dsl.typespec as typespec
|
||||||
|
|
||||||
|
|
||||||
def classname(name):
|
def classname(name):
|
||||||
@@ -35,16 +35,17 @@ class MuranoClass(object):
|
|||||||
self._namespace_resolver = namespace_resolver
|
self._namespace_resolver = namespace_resolver
|
||||||
self._name = namespace_resolver.resolve_name(name)
|
self._name = namespace_resolver.resolve_name(name)
|
||||||
self._properties = {}
|
self._properties = {}
|
||||||
if self._name == 'org.openstack.murano.Object':
|
if self._name == 'io.murano.Object':
|
||||||
self._parents = []
|
self._parents = []
|
||||||
else:
|
else:
|
||||||
self._parents = parents if parents is not None else [
|
self._parents = parents or [
|
||||||
class_loader.get_class('org.openstack.murano.Object')]
|
class_loader.get_class('io.murano.Object')]
|
||||||
self.object_class = type(
|
|
||||||
'mc' + helpers.generate_id(),
|
class_name = 'mc' + helpers.generate_id()
|
||||||
tuple([p.object_class for p in self._parents]) or (
|
parents_class = [p.object_class for p in self._parents]
|
||||||
objects.MuranoObject,),
|
bases = tuple(parents_class) or (murano_object.MuranoObject,)
|
||||||
{})
|
|
||||||
|
self.object_class = type(class_name, bases, {})
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
@@ -58,6 +59,19 @@ class MuranoClass(object):
|
|||||||
def parents(self):
|
def parents(self):
|
||||||
return self._parents
|
return self._parents
|
||||||
|
|
||||||
|
@property
|
||||||
|
def methods(self):
|
||||||
|
return self._methods
|
||||||
|
|
||||||
|
def get_method(self, name):
|
||||||
|
return self._methods.get(name)
|
||||||
|
|
||||||
|
def add_method(self, name, payload):
|
||||||
|
method = murano_method.MuranoMethod(self._namespace_resolver,
|
||||||
|
self, name, payload)
|
||||||
|
self._methods[name] = method
|
||||||
|
return method
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def properties(self):
|
def properties(self):
|
||||||
return self._properties.keys()
|
return self._properties.keys()
|
||||||
@@ -71,6 +85,7 @@ class MuranoClass(object):
|
|||||||
return self._properties[name]
|
return self._properties[name]
|
||||||
|
|
||||||
def find_method(self, name):
|
def find_method(self, name):
|
||||||
|
#resolved_name = self._namespace_resolver.resolve_name(name, self.name)
|
||||||
if name in self._methods:
|
if name in self._methods:
|
||||||
return [(self, name)]
|
return [(self, name)]
|
||||||
if not self._parents:
|
if not self._parents:
|
||||||
@@ -88,27 +103,12 @@ class MuranoClass(object):
|
|||||||
types.extend(mc.parents)
|
types.extend(mc.parents)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@property
|
|
||||||
def methods(self):
|
|
||||||
return self._methods
|
|
||||||
|
|
||||||
def get_method(self, name):
|
|
||||||
return self._methods.get(name)
|
|
||||||
|
|
||||||
def add_method(self, name, payload):
|
|
||||||
#name = self._namespace_resolver.resolve_name(name, self.name)
|
|
||||||
method = engine_methods.MuranoMethod(
|
|
||||||
self._namespace_resolver,
|
|
||||||
self, name, payload)
|
|
||||||
self._methods[name] = method
|
|
||||||
return method
|
|
||||||
|
|
||||||
def invoke(self, name, executor, this, parameters):
|
def invoke(self, name, executor, this, parameters):
|
||||||
args = executor.to_yaql_args(parameters)
|
args = executor.to_yaql_args(parameters)
|
||||||
return executor.invoke_method(name, this, None, self, *args)
|
return executor.invoke_method(name, this, None, self, *args)
|
||||||
|
|
||||||
def is_compatible(self, obj):
|
def is_compatible(self, obj):
|
||||||
if isinstance(obj, objects.MuranoObject):
|
if isinstance(obj, murano_object.MuranoObject):
|
||||||
return self.is_compatible(obj.type)
|
return self.is_compatible(obj.type)
|
||||||
if obj is self:
|
if obj is self:
|
||||||
return True
|
return True
|
@@ -13,13 +13,16 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import inspect
|
import inspect
|
||||||
import ordereddict
|
|
||||||
import types
|
import types
|
||||||
|
|
||||||
|
import muranoapi.dsl.macros as macros
|
||||||
|
import muranoapi.dsl.typespec as typespec
|
||||||
|
import muranoapi.dsl.yaql_expression as yaql_expression
|
||||||
|
|
||||||
from muranoapi.engine import macros
|
try:
|
||||||
from muranoapi.engine import typespec
|
from collections import OrderedDict # noqa
|
||||||
from muranoapi.engine import yaql_expression
|
except ImportError: # python2.6
|
||||||
|
from ordereddict import OrderedDict # noqa
|
||||||
|
|
||||||
|
|
||||||
class MuranoMethod(object):
|
class MuranoMethod(object):
|
||||||
@@ -38,7 +41,7 @@ class MuranoMethod(object):
|
|||||||
if isinstance(arguments_scheme, types.DictionaryType):
|
if isinstance(arguments_scheme, types.DictionaryType):
|
||||||
arguments_scheme = [{key: value} for key, value in
|
arguments_scheme = [{key: value} for key, value in
|
||||||
arguments_scheme.iteritems()]
|
arguments_scheme.iteritems()]
|
||||||
self._arguments_scheme = ordereddict.OrderedDict()
|
self._arguments_scheme = OrderedDict()
|
||||||
for record in arguments_scheme:
|
for record in arguments_scheme:
|
||||||
if not isinstance(record, types.DictionaryType) \
|
if not isinstance(record, types.DictionaryType) \
|
||||||
or len(record) > 1:
|
or len(record) > 1:
|
||||||
@@ -74,7 +77,7 @@ class MuranoMethod(object):
|
|||||||
defaults = func_info.defaults or tuple()
|
defaults = func_info.defaults or tuple()
|
||||||
for i in xrange(len(defaults)):
|
for i in xrange(len(defaults)):
|
||||||
data[i + len(data) - len(defaults)][1]['Default'] = defaults[i]
|
data[i + len(data) - len(defaults)][1]['Default'] = defaults[i]
|
||||||
result = ordereddict.OrderedDict([
|
result = OrderedDict([
|
||||||
(name, typespec.ArgumentSpec(
|
(name, typespec.ArgumentSpec(
|
||||||
declaration, self._namespace_resolver))
|
declaration, self._namespace_resolver))
|
||||||
for name, declaration in data])
|
for name, declaration in data])
|
@@ -12,20 +12,25 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from yaql import context
|
import types
|
||||||
|
|
||||||
from muranoapi.engine import consts
|
import yaml
|
||||||
from muranoapi.engine import exceptions
|
import yaql.context
|
||||||
from muranoapi.engine import helpers
|
|
||||||
|
import muranoapi.dsl.exceptions as exceptions
|
||||||
|
import muranoapi.dsl.helpers
|
||||||
|
import muranoapi.dsl.type_scheme as type_scheme
|
||||||
|
import muranoapi.dsl.typespec as typespec
|
||||||
|
|
||||||
|
|
||||||
class MuranoObject(object):
|
class MuranoObject(object):
|
||||||
def __init__(self, murano_class, parent_obj, object_store, context,
|
def __init__(self, murano_class, parent_obj, object_store, context,
|
||||||
object_id=None, known_classes=None, defaults=None):
|
object_id=None, known_classes=None, defaults=None):
|
||||||
|
|
||||||
if known_classes is None:
|
if known_classes is None:
|
||||||
known_classes = {}
|
known_classes = {}
|
||||||
self.__parent_obj = parent_obj
|
self.__parent_obj = parent_obj
|
||||||
self.__object_id = object_id or helpers.generate_id()
|
self.__object_id = object_id or muranoapi.dsl.helpers.generate_id()
|
||||||
self.__type = murano_class
|
self.__type = murano_class
|
||||||
self.__properties = {}
|
self.__properties = {}
|
||||||
self.__object_store = object_store
|
self.__object_store = object_store
|
||||||
@@ -35,13 +40,13 @@ class MuranoObject(object):
|
|||||||
known_classes[murano_class.name] = self
|
known_classes[murano_class.name] = self
|
||||||
for parent_class in murano_class.parents:
|
for parent_class in murano_class.parents:
|
||||||
name = parent_class.name
|
name = parent_class.name
|
||||||
if not name in known_classes:
|
if name not in known_classes:
|
||||||
obj = parent_class.new(
|
obj = parent_class.new(parent_obj, object_store, context,
|
||||||
parent_obj, object_store, context, None,
|
None, object_id=self.__object_id,
|
||||||
object_id=self.__object_id,
|
|
||||||
known_classes=known_classes,
|
known_classes=known_classes,
|
||||||
defaults=defaults)
|
defaults=defaults)
|
||||||
known_classes[name] = self.__parents[name] = obj
|
|
||||||
|
self.__parents[name] = known_classes[name] = obj
|
||||||
else:
|
else:
|
||||||
self.__parents[name] = known_classes[name]
|
self.__parents[name] = known_classes[name]
|
||||||
|
|
||||||
@@ -50,11 +55,12 @@ class MuranoObject(object):
|
|||||||
for i in xrange(2):
|
for i in xrange(2):
|
||||||
for property_name in self.__type.properties:
|
for property_name in self.__type.properties:
|
||||||
spec = self.__type.get_property(property_name)
|
spec = self.__type.get_property(property_name)
|
||||||
if i == 0 and helpers.needs_evaluation(spec.default) \
|
needs_evaluation = muranoapi.dsl.helpers.needs_evaluation
|
||||||
or i == 1 and property_name in used_names:
|
if i == 0 and needs_evaluation(spec.default) or i == 1\
|
||||||
|
and property_name in used_names:
|
||||||
continue
|
continue
|
||||||
used_names.add(property_name)
|
used_names.add(property_name)
|
||||||
property_value = kwargs.get(property_name, consts.NoValue)
|
property_value = kwargs.get(property_name, type_scheme.NoValue)
|
||||||
self.set_property(property_name, property_value)
|
self.set_property(property_name, property_value)
|
||||||
for parent in self.__parents.values():
|
for parent in self.__parents.values():
|
||||||
parent.initialize(**kwargs)
|
parent.initialize(**kwargs)
|
||||||
@@ -123,14 +129,15 @@ class MuranoObject(object):
|
|||||||
def __set_property(self, key, value, caller_class=None):
|
def __set_property(self, key, value, caller_class=None):
|
||||||
if key in self.__type.properties:
|
if key in self.__type.properties:
|
||||||
spec = self.__type.get_property(key)
|
spec = self.__type.get_property(key)
|
||||||
if (caller_class is not None and
|
if caller_class is not None \
|
||||||
not caller_class.is_compatible(self)):
|
and (spec.type not in typespec.PropertyTypes.Writable
|
||||||
|
or not caller_class.is_compatible(self)):
|
||||||
raise exceptions.NoWriteAccess(key)
|
raise exceptions.NoWriteAccess(key)
|
||||||
|
|
||||||
default = self.__defaults.get(key, spec.default)
|
default = self.__defaults.get(key, spec.default)
|
||||||
child_context = context.Context(parent_context=self.__context)
|
child_context = yaql.context.Context(parent_context=self.__context)
|
||||||
child_context.set_data(self)
|
child_context.set_data(self)
|
||||||
default = helpers.evaluate(default, child_context, 1)
|
default = muranoapi.dsl.helpers.evaluate(default, child_context, 1)
|
||||||
|
|
||||||
self.__properties[key] = spec.validate(
|
self.__properties[key] = spec.validate(
|
||||||
value, self, self.__context, self.__object_store, default)
|
value, self, self.__context, self.__object_store, default)
|
||||||
@@ -143,12 +150,42 @@ class MuranoObject(object):
|
|||||||
continue
|
continue
|
||||||
raise AttributeError(key)
|
raise AttributeError(key)
|
||||||
|
|
||||||
def cast(self, _type):
|
def cast(self, type):
|
||||||
if self.type == _type:
|
if self.type == type:
|
||||||
return self
|
return self
|
||||||
for parent in self.__parents.values():
|
for parent in self.__parents.values():
|
||||||
try:
|
try:
|
||||||
return parent.cast(_type)
|
return parent.cast(type)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
continue
|
continue
|
||||||
raise TypeError('Cannot cast')
|
raise TypeError('Cannot cast')
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return yaml.safe_dump(muranoapi.dsl.helpers.serialize(self))
|
||||||
|
|
||||||
|
def to_dictionary(self, include_hidden=False):
|
||||||
|
result = {}
|
||||||
|
for parent in self.__parents.values():
|
||||||
|
result.update(parent.to_dictionary(include_hidden))
|
||||||
|
result.update({'?': {'type': self.type.name, 'id': self.object_id}})
|
||||||
|
if include_hidden:
|
||||||
|
result.update(self.__properties)
|
||||||
|
else:
|
||||||
|
for property_name in self.type.properties:
|
||||||
|
if property_name in self.__properties:
|
||||||
|
spec = self.type.get_property(property_name)
|
||||||
|
if spec.type != typespec.PropertyTypes.Runtime:
|
||||||
|
result[property_name] = \
|
||||||
|
self.__properties[property_name]
|
||||||
|
return result
|
||||||
|
|
||||||
|
def __merge_default(self, src, defaults):
|
||||||
|
if src is None:
|
||||||
|
return
|
||||||
|
if type(src) != type(defaults):
|
||||||
|
raise ValueError()
|
||||||
|
if isinstance(defaults, types.DictionaryType):
|
||||||
|
for key, value in defaults.iteritems():
|
||||||
|
src_value = src.get(key)
|
||||||
|
if src_value is None:
|
||||||
|
continue
|
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
import inspect
|
import inspect
|
||||||
|
|
||||||
from muranoapi.engine import helpers
|
import muranoapi.dsl.helpers as helpers
|
||||||
|
|
||||||
|
|
||||||
class ObjectStore(object):
|
class ObjectStore(object):
|
||||||
@@ -48,7 +48,6 @@ class ObjectStore(object):
|
|||||||
if '?' not in value or 'type' not in value['?']:
|
if '?' not in value or 'type' not in value['?']:
|
||||||
raise ValueError()
|
raise ValueError()
|
||||||
system_key = value['?']
|
system_key = value['?']
|
||||||
#del value['?']
|
|
||||||
object_id = system_key['id']
|
object_id = system_key['id']
|
||||||
obj_type = system_key['type']
|
obj_type = system_key['type']
|
||||||
class_obj = self._class_loader.get_class(obj_type)
|
class_obj = self._class_loader.get_class(obj_type)
|
||||||
@@ -83,5 +82,4 @@ class ObjectStore(object):
|
|||||||
methods = obj.type.find_method('initialize')
|
methods = obj.type.find_method('initialize')
|
||||||
for cls, method in methods:
|
for cls, method in methods:
|
||||||
cls.invoke(method, executor, obj, {})
|
cls.invoke(method, executor, obj, {})
|
||||||
# self._store.update(tmp_store._store)
|
|
||||||
return obj
|
return obj
|
6
muranoapi/dsl/principal_objects/__init__.py
Normal file
6
muranoapi/dsl/principal_objects/__init__.py
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import muranoapi.dsl.principal_objects.sys_object
|
||||||
|
|
||||||
|
|
||||||
|
def register(class_loader):
|
||||||
|
sys_object = muranoapi.dsl.principal_objects.sys_object
|
||||||
|
class_loader.import_class(sys_object.SysObject)
|
@@ -12,16 +12,16 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from muranoapi.engine import classes
|
import muranoapi.dsl.helpers as helpers
|
||||||
from muranoapi.engine import helpers
|
import muranoapi.dsl.murano_class as murano_class
|
||||||
|
|
||||||
|
|
||||||
@classes.classname('org.openstack.murano.Object')
|
@murano_class.classname('io.murano.Object')
|
||||||
class SysObject(object):
|
class SysObject(object):
|
||||||
def setAttr(self, _context, name, value, owner=None):
|
def setAttr(self, _context, name, value, owner=None):
|
||||||
if owner is None:
|
if owner is None:
|
||||||
owner = helpers.get_type(helpers.get_caller_context(_context))
|
owner = helpers.get_type(helpers.get_caller_context(_context))
|
||||||
if not isinstance(owner, classes.MuranoClass):
|
if not isinstance(owner, murano_class.MuranoClass):
|
||||||
raise TypeError()
|
raise TypeError()
|
||||||
|
|
||||||
attribute_store = helpers.get_attribute_store(_context)
|
attribute_store = helpers.get_attribute_store(_context)
|
||||||
@@ -30,7 +30,7 @@ class SysObject(object):
|
|||||||
def getAttr(self, _context, name, owner=None):
|
def getAttr(self, _context, name, owner=None):
|
||||||
if owner is None:
|
if owner is None:
|
||||||
owner = helpers.get_type(helpers.get_caller_context(_context))
|
owner = helpers.get_type(helpers.get_caller_context(_context))
|
||||||
if not isinstance(owner, classes.MuranoClass):
|
if not isinstance(owner, murano_class.MuranoClass):
|
||||||
raise TypeError()
|
raise TypeError()
|
||||||
|
|
||||||
attribute_store = helpers.get_attribute_store(_context)
|
attribute_store = helpers.get_attribute_store(_context)
|
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
import types
|
import types
|
||||||
|
|
||||||
from muranoapi.engine import objects
|
import muranoapi.dsl.murano_object as murano_object
|
||||||
|
|
||||||
|
|
||||||
class ObjRef(object):
|
class ObjRef(object):
|
||||||
@@ -45,7 +45,7 @@ def _pass1_serialize(value, parent, serialized_objects):
|
|||||||
if isinstance(value, (types.StringTypes, types.IntType, types.FloatType,
|
if isinstance(value, (types.StringTypes, types.IntType, types.FloatType,
|
||||||
types.BooleanType, types.NoneType)):
|
types.BooleanType, types.NoneType)):
|
||||||
return value
|
return value
|
||||||
elif isinstance(value, objects.MuranoObject):
|
elif isinstance(value, murano_object.MuranoObject):
|
||||||
if not _cmp_objects(value.parent, parent) \
|
if not _cmp_objects(value.parent, parent) \
|
||||||
or value.object_id in serialized_objects:
|
or value.object_id in serialized_objects:
|
||||||
return ObjRef(value)
|
return ObjRef(value)
|
@@ -16,12 +16,14 @@ import sys
|
|||||||
import types
|
import types
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from yaql import context as y_context
|
import yaql.context
|
||||||
|
|
||||||
from muranoapi.engine import consts
|
import muranoapi.dsl.helpers
|
||||||
from muranoapi.engine import helpers
|
import muranoapi.dsl.murano_object
|
||||||
from muranoapi.engine import objects
|
import muranoapi.dsl.yaql_expression as yaql_expression
|
||||||
from muranoapi.engine import yaql_expression
|
|
||||||
|
|
||||||
|
NoValue = object()
|
||||||
|
|
||||||
|
|
||||||
class TypeScheme(object):
|
class TypeScheme(object):
|
||||||
@@ -37,7 +39,7 @@ class TypeScheme(object):
|
|||||||
namespace_resolver, default):
|
namespace_resolver, default):
|
||||||
def _int(value):
|
def _int(value):
|
||||||
value = value()
|
value = value()
|
||||||
if value is consts.NoValue:
|
if value is NoValue:
|
||||||
value = default
|
value = default
|
||||||
if value is None:
|
if value is None:
|
||||||
return None
|
return None
|
||||||
@@ -48,7 +50,7 @@ class TypeScheme(object):
|
|||||||
|
|
||||||
def _string(value):
|
def _string(value):
|
||||||
value = value()
|
value = value()
|
||||||
if value is consts.NoValue:
|
if value is NoValue:
|
||||||
value = default
|
value = default
|
||||||
if value is None:
|
if value is None:
|
||||||
return None
|
return None
|
||||||
@@ -59,7 +61,7 @@ class TypeScheme(object):
|
|||||||
|
|
||||||
def _bool(value):
|
def _bool(value):
|
||||||
value = value()
|
value = value()
|
||||||
if value is consts.NoValue:
|
if value is NoValue:
|
||||||
value = default
|
value = default
|
||||||
if value is None:
|
if value is None:
|
||||||
return None
|
return None
|
||||||
@@ -85,8 +87,11 @@ class TypeScheme(object):
|
|||||||
else:
|
else:
|
||||||
raise TypeError(value)
|
raise TypeError(value)
|
||||||
|
|
||||||
@y_context.EvalArg('obj', arg_type=(objects.MuranoObject,
|
@yaql.context.EvalArg('obj', arg_type=(
|
||||||
TypeScheme.ObjRef, types.NoneType))
|
muranoapi.dsl.murano_object.MuranoObject,
|
||||||
|
TypeScheme.ObjRef,
|
||||||
|
types.NoneType
|
||||||
|
))
|
||||||
def _owned(obj):
|
def _owned(obj):
|
||||||
if isinstance(obj, TypeScheme.ObjRef):
|
if isinstance(obj, TypeScheme.ObjRef):
|
||||||
return obj
|
return obj
|
||||||
@@ -98,8 +103,11 @@ class TypeScheme(object):
|
|||||||
else:
|
else:
|
||||||
raise TypeError()
|
raise TypeError()
|
||||||
|
|
||||||
@y_context.EvalArg('obj', arg_type=(objects.MuranoObject,
|
@yaql.context.EvalArg('obj', arg_type=(
|
||||||
TypeScheme.ObjRef, types.NoneType))
|
muranoapi.dsl.murano_object.MuranoObject,
|
||||||
|
TypeScheme.ObjRef,
|
||||||
|
types.NoneType
|
||||||
|
))
|
||||||
def _not_owned(obj):
|
def _not_owned(obj):
|
||||||
if isinstance(obj, TypeScheme.ObjRef):
|
if isinstance(obj, TypeScheme.ObjRef):
|
||||||
return obj
|
return obj
|
||||||
@@ -111,12 +119,12 @@ class TypeScheme(object):
|
|||||||
else:
|
else:
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
@y_context.EvalArg('name', arg_type=str)
|
@yaql.context.EvalArg('name', arg_type=str)
|
||||||
def _class(value, name):
|
def _class(value, name):
|
||||||
return _class2(value, name, None)
|
return _class2(value, name, None)
|
||||||
|
|
||||||
@y_context.EvalArg('name', arg_type=str)
|
@yaql.context.EvalArg('name', arg_type=str)
|
||||||
@y_context.EvalArg('default_name', arg_type=(str, types.NoneType))
|
@yaql.context.EvalArg('default_name', arg_type=(str, types.NoneType))
|
||||||
def _class2(value, name, default_name):
|
def _class2(value, name, default_name):
|
||||||
name = namespace_resolver.resolve_name(name)
|
name = namespace_resolver.resolve_name(name)
|
||||||
if not default_name:
|
if not default_name:
|
||||||
@@ -124,20 +132,20 @@ class TypeScheme(object):
|
|||||||
else:
|
else:
|
||||||
default_name = namespace_resolver.resolve_name(default_name)
|
default_name = namespace_resolver.resolve_name(default_name)
|
||||||
value = value()
|
value = value()
|
||||||
if value is consts.NoValue:
|
if value is NoValue:
|
||||||
value = default
|
value = default
|
||||||
if isinstance(default, types.DictionaryType):
|
if isinstance(default, types.DictionaryType):
|
||||||
value = {'?': {
|
value = {'?': {
|
||||||
'id': uuid.uuid4().hex,
|
'id': uuid.uuid4().hex,
|
||||||
'type': default_name
|
'type': default_name
|
||||||
}}
|
}}
|
||||||
class_loader = helpers.get_class_loader(root_context)
|
class_loader = muranoapi.dsl.helpers.get_class_loader(root_context)
|
||||||
murano_class = class_loader.get_class(name)
|
murano_class = class_loader.get_class(name)
|
||||||
if not murano_class:
|
if not murano_class:
|
||||||
raise TypeError()
|
raise TypeError()
|
||||||
if value is None:
|
if value is None:
|
||||||
return None
|
return None
|
||||||
if isinstance(value, objects.MuranoObject):
|
if isinstance(value, muranoapi.dsl.murano_object.MuranoObject):
|
||||||
obj = value
|
obj = value
|
||||||
elif isinstance(value, types.DictionaryType):
|
elif isinstance(value, types.DictionaryType):
|
||||||
obj = object_store.load(value, this, root_context,
|
obj = object_store.load(value, this, root_context,
|
||||||
@@ -155,13 +163,13 @@ class TypeScheme(object):
|
|||||||
raise TypeError()
|
raise TypeError()
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
@y_context.EvalArg('prefix', str)
|
@yaql.context.EvalArg('prefix', str)
|
||||||
@y_context.EvalArg('name', str)
|
@yaql.context.EvalArg('name', str)
|
||||||
def _validate(prefix, name):
|
def _validate(prefix, name):
|
||||||
return namespace_resolver.resolve_name(
|
return namespace_resolver.resolve_name(
|
||||||
'%s:%s' % (prefix, name))
|
'%s:%s' % (prefix, name))
|
||||||
|
|
||||||
context = y_context.Context(parent_context=root_context)
|
context = yaql.context.Context(parent_context=root_context)
|
||||||
context.register_function(_validate, '#validate')
|
context.register_function(_validate, '#validate')
|
||||||
context.register_function(_int, 'int')
|
context.register_function(_int, 'int')
|
||||||
context.register_function(_string, 'string')
|
context.register_function(_string, 'string')
|
||||||
@@ -176,7 +184,7 @@ class TypeScheme(object):
|
|||||||
return context
|
return context
|
||||||
|
|
||||||
def _map_dict(self, data, spec, context):
|
def _map_dict(self, data, spec, context):
|
||||||
if data is None or data is consts.NoValue:
|
if data is None or data is NoValue:
|
||||||
data = {}
|
data = {}
|
||||||
if not isinstance(data, types.DictionaryType):
|
if not isinstance(data, types.DictionaryType):
|
||||||
raise TypeError()
|
raise TypeError()
|
||||||
@@ -205,7 +213,7 @@ class TypeScheme(object):
|
|||||||
|
|
||||||
def _map_list(self, data, spec, context):
|
def _map_list(self, data, spec, context):
|
||||||
if not isinstance(data, types.ListType):
|
if not isinstance(data, types.ListType):
|
||||||
if data is None or data is consts.NoValue:
|
if data is None or data is NoValue:
|
||||||
data = []
|
data = []
|
||||||
else:
|
else:
|
||||||
data = [data]
|
data = [data]
|
||||||
@@ -239,7 +247,7 @@ class TypeScheme(object):
|
|||||||
return data
|
return data
|
||||||
|
|
||||||
def _map(self, data, spec, context):
|
def _map(self, data, spec, context):
|
||||||
child_context = y_context.Context(parent_context=context)
|
child_context = yaql.context.Context(parent_context=context)
|
||||||
if isinstance(spec, yaql_expression.YaqlExpression):
|
if isinstance(spec, yaql_expression.YaqlExpression):
|
||||||
child_context.set_data(data)
|
child_context.set_data(data)
|
||||||
return spec.evaluate(context=child_context)
|
return spec.evaluate(context=child_context)
|
||||||
@@ -258,6 +266,6 @@ class TypeScheme(object):
|
|||||||
context, this, object_store, namespace_resolver,
|
context, this, object_store, namespace_resolver,
|
||||||
default)
|
default)
|
||||||
result = self._map(data, self._spec, context)
|
result = self._map(data, self._spec, context)
|
||||||
if result is consts.NoValue:
|
if result is NoValue:
|
||||||
raise TypeError('No type specified')
|
raise TypeError('No type specified')
|
||||||
return result
|
return result
|
@@ -12,7 +12,7 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from muranoapi.engine import type_scheme
|
import muranoapi.dsl.type_scheme as type_scheme
|
||||||
|
|
||||||
|
|
||||||
class PropertyTypes(object):
|
class PropertyTypes(object):
|
@@ -12,21 +12,21 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import eventlet
|
|
||||||
import itertools
|
import itertools
|
||||||
import types
|
import types
|
||||||
|
|
||||||
from yaql import context as y_context
|
import eventlet
|
||||||
|
import yaql.context
|
||||||
import yaql.exceptions
|
import yaql.exceptions
|
||||||
|
|
||||||
from muranoapi.engine import exceptions
|
import muranoapi.dsl.exceptions as exceptions
|
||||||
from muranoapi.engine import helpers
|
import muranoapi.dsl.helpers as helpers
|
||||||
from muranoapi.engine import objects
|
import muranoapi.dsl.murano_object as murano_object
|
||||||
|
|
||||||
|
|
||||||
def _resolve(name, obj):
|
def _resolve(name, obj):
|
||||||
@y_context.EvalArg('this', objects.MuranoObject)
|
@yaql.context.EvalArg('this', murano_object.MuranoObject)
|
||||||
@y_context.ContextAware()
|
@yaql.context.ContextAware()
|
||||||
def invoke(context, this, *args):
|
def invoke(context, this, *args):
|
||||||
try:
|
try:
|
||||||
executor = helpers.get_executor(context)
|
executor = helpers.get_executor(context)
|
||||||
@@ -38,20 +38,20 @@ def _resolve(name, obj):
|
|||||||
except exceptions.AmbiguousMethodName:
|
except exceptions.AmbiguousMethodName:
|
||||||
raise yaql.exceptions.YaqlExecutionException()
|
raise yaql.exceptions.YaqlExecutionException()
|
||||||
|
|
||||||
if not isinstance(obj, objects.MuranoObject):
|
if not isinstance(obj, murano_object.MuranoObject):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return invoke
|
return invoke
|
||||||
|
|
||||||
|
|
||||||
@y_context.EvalArg('value', objects.MuranoObject)
|
@yaql.context.EvalArg('value', murano_object.MuranoObject)
|
||||||
def _id(value):
|
def _id(value):
|
||||||
return value.object_id
|
return value.object_id
|
||||||
|
|
||||||
|
|
||||||
@y_context.EvalArg('value', objects.MuranoObject)
|
@yaql.context.EvalArg('value', murano_object.MuranoObject)
|
||||||
@y_context.EvalArg('type', str)
|
@yaql.context.EvalArg('type', str)
|
||||||
@y_context.ContextAware()
|
@yaql.context.ContextAware()
|
||||||
def _cast(context, value, type):
|
def _cast(context, value, type):
|
||||||
if not '.' in type:
|
if not '.' in type:
|
||||||
murano_class = context.get_data('$?type')
|
murano_class = context.get_data('$?type')
|
||||||
@@ -60,8 +60,8 @@ def _cast(context, value, type):
|
|||||||
return value.cast(class_loader.get_class(type))
|
return value.cast(class_loader.get_class(type))
|
||||||
|
|
||||||
|
|
||||||
@y_context.EvalArg('name', str)
|
@yaql.context.EvalArg('name', str)
|
||||||
@y_context.ContextAware()
|
@yaql.context.ContextAware()
|
||||||
def _new(context, name, *args):
|
def _new(context, name, *args):
|
||||||
murano_class = helpers.get_type(context)
|
murano_class = helpers.get_type(context)
|
||||||
name = murano_class.namespace_resolver.resolve_name(name)
|
name = murano_class.namespace_resolver.resolve_name(name)
|
||||||
@@ -79,38 +79,38 @@ def _new(context, name, *args):
|
|||||||
|
|
||||||
object_store = helpers.get_object_store(context)
|
object_store = helpers.get_object_store(context)
|
||||||
class_loader = helpers.get_class_loader(context)
|
class_loader = helpers.get_class_loader(context)
|
||||||
new_context = y_context.Context(parent_context=context)
|
new_context = yaql.context.Context(parent_context=context)
|
||||||
for key, value in parameters.iteritems():
|
for key, value in parameters.iteritems():
|
||||||
new_context.set_data(value, key)
|
new_context.set_data(value, key)
|
||||||
return class_loader.get_class(name).new(
|
return class_loader.get_class(name).new(
|
||||||
None, object_store, new_context, parameters=parameters)
|
None, object_store, new_context, parameters=parameters)
|
||||||
|
|
||||||
|
|
||||||
@y_context.EvalArg('value', objects.MuranoObject)
|
@yaql.context.EvalArg('value', murano_object.MuranoObject)
|
||||||
def _super(value):
|
def _super(value):
|
||||||
return [value.cast(type) for type in value.type.parents]
|
return [value.cast(type) for type in value.type.parents]
|
||||||
|
|
||||||
|
|
||||||
@y_context.EvalArg('value', objects.MuranoObject)
|
@yaql.context.EvalArg('value', murano_object.MuranoObject)
|
||||||
def _super2(value, func):
|
def _super2(value, func):
|
||||||
return itertools.imap(func, _super(value))
|
return itertools.imap(func, _super(value))
|
||||||
|
|
||||||
|
|
||||||
@y_context.EvalArg('value', objects.MuranoObject)
|
@yaql.context.EvalArg('value', murano_object.MuranoObject)
|
||||||
def _psuper2(value, func):
|
def _psuper2(value, func):
|
||||||
helpers.parallel_select(_super(value), func)
|
helpers.parallel_select(_super(value), func)
|
||||||
|
|
||||||
|
|
||||||
@y_context.EvalArg('value', object)
|
@yaql.context.EvalArg('value', object)
|
||||||
def _require(value):
|
def _require(value):
|
||||||
if value is None:
|
if value is None:
|
||||||
raise ValueError()
|
raise ValueError()
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
@y_context.EvalArg('obj', objects.MuranoObject)
|
@yaql.context.EvalArg('obj', murano_object.MuranoObject)
|
||||||
@y_context.EvalArg('class_name', str)
|
@yaql.context.EvalArg('class_name', str)
|
||||||
@y_context.ContextAware()
|
@yaql.context.ContextAware()
|
||||||
def _get_container(context, obj, class_name):
|
def _get_container(context, obj, class_name):
|
||||||
namespace_resolver = helpers.get_type(context).namespace_resolver
|
namespace_resolver = helpers.get_type(context).namespace_resolver
|
||||||
class_loader = helpers.get_class_loader(context)
|
class_loader = helpers.get_class_loader(context)
|
||||||
@@ -124,7 +124,7 @@ def _get_container(context, obj, class_name):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
@y_context.EvalArg('seconds', (int, float))
|
@yaql.context.EvalArg('seconds', (int, float))
|
||||||
def _sleep(seconds):
|
def _sleep(seconds):
|
||||||
eventlet.sleep(seconds)
|
eventlet.sleep(seconds)
|
||||||
|
|
@@ -1,18 +0,0 @@
|
|||||||
# Copyright (c) 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.
|
|
||||||
|
|
||||||
|
|
||||||
NoValue = object()
|
|
||||||
|
|
||||||
EVALUATION_MAX_DEPTH = 100
|
|
@@ -1,19 +0,0 @@
|
|||||||
# Copyright (c) 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 muranoapi.engine.principal_objects import sys_object
|
|
||||||
|
|
||||||
|
|
||||||
def register(class_loader):
|
|
||||||
class_loader.import_class(sys_object.SysObject)
|
|
@@ -17,9 +17,9 @@ import os.path
|
|||||||
|
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
from muranoapi.engine import class_loader
|
import muranoapi.dsl.class_loader as class_loader
|
||||||
from muranoapi.engine.system import yaql_functions
|
import muranoapi.dsl.yaql_expression as yaql_expression
|
||||||
from muranoapi.engine import yaql_expression
|
import muranoapi.engine.system.yaql_functions as yaql_functions
|
||||||
|
|
||||||
|
|
||||||
def yaql_constructor(loader, node):
|
def yaql_constructor(loader, node):
|
@@ -1,48 +0,0 @@
|
|||||||
# Copyright (c) 2013 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
|
|
||||||
|
|
||||||
from muranoapi.engine import classes
|
|
||||||
from muranoapi.engine.system import agent
|
|
||||||
from muranoapi.engine.system import agent_listener
|
|
||||||
from muranoapi.engine.system import heat_stack
|
|
||||||
from muranoapi.engine.system import resource_manager
|
|
||||||
|
|
||||||
|
|
||||||
def _auto_register(class_loader):
|
|
||||||
globs = globals().copy()
|
|
||||||
for module_name, value in globs.iteritems():
|
|
||||||
if inspect.ismodule(value):
|
|
||||||
for class_name in dir(value):
|
|
||||||
class_def = getattr(value, class_name)
|
|
||||||
if inspect.isclass(class_def) and hasattr(
|
|
||||||
class_def, '_murano_class_name'):
|
|
||||||
class_loader.import_class(class_def)
|
|
||||||
|
|
||||||
|
|
||||||
def register(class_loader, path):
|
|
||||||
_auto_register(class_loader)
|
|
||||||
|
|
||||||
@classes.classname('org.openstack.murano.system.Resources')
|
|
||||||
class ResourceManagerWrapper(resource_manager.ResourceManager):
|
|
||||||
def initialize(self, _context, _class=None):
|
|
||||||
super(ResourceManagerWrapper, self).initialize(
|
|
||||||
path, _context, _class)
|
|
||||||
|
|
||||||
class_loader.import_class(agent.Agent)
|
|
||||||
class_loader.import_class(agent_listener.AgentListener)
|
|
||||||
class_loader.import_class(heat_stack.HeatStack)
|
|
||||||
class_loader.import_class(ResourceManagerWrapper)
|
|
||||||
|
@@ -20,11 +20,11 @@ import uuid
|
|||||||
|
|
||||||
import eventlet.event
|
import eventlet.event
|
||||||
|
|
||||||
from muranoapi.common import messaging
|
import muranoapi.common.messaging as messaging
|
||||||
from muranoapi.engine import classes
|
import muranoapi.dsl.murano_class as murano_class
|
||||||
from muranoapi.engine import objects
|
import muranoapi.dsl.murano_object as murano_object
|
||||||
from muranoapi.engine.system import common
|
import muranoapi.dsl.yaql_expression as yaql_expression
|
||||||
from muranoapi.engine import yaql_expression
|
import muranoapi.engine.system.common as common
|
||||||
|
|
||||||
|
|
||||||
class AgentException(Exception):
|
class AgentException(Exception):
|
||||||
@@ -32,11 +32,11 @@ class AgentException(Exception):
|
|||||||
self.message_info = message_info
|
self.message_info = message_info
|
||||||
|
|
||||||
|
|
||||||
@classes.classname('org.openstack.murano.system.Agent')
|
@murano_class.classname('io.murano.system.Agent')
|
||||||
class Agent(objects.MuranoObject):
|
class Agent(murano_object.MuranoObject):
|
||||||
def initialize(self, _context, host):
|
def initialize(self, _context, host):
|
||||||
environment = yaql_expression.YaqlExpression(
|
environment = yaql_expression.YaqlExpression(
|
||||||
"$host.find('org.openstack.murano.Environment').require()"
|
"$host.find('io.murano.Environment').require()"
|
||||||
).evaluate(_context)
|
).evaluate(_context)
|
||||||
|
|
||||||
self._queue = str('e%s-h%s' % (
|
self._queue = str('e%s-h%s' % (
|
||||||
|
@@ -15,13 +15,13 @@
|
|||||||
|
|
||||||
import eventlet
|
import eventlet
|
||||||
|
|
||||||
from muranoapi.engine import classes
|
import muranoapi.dsl.murano_class as murano_class
|
||||||
from muranoapi.engine import objects
|
import muranoapi.dsl.murano_object as murano_object
|
||||||
from muranoapi.engine.system import common
|
import muranoapi.engine.system.common as common
|
||||||
|
|
||||||
|
|
||||||
@classes.classname('org.openstack.murano.system.AgentListener')
|
@murano_class.classname('io.murano.system.AgentListener')
|
||||||
class AgentListener(objects.MuranoObject):
|
class AgentListener(murano_object.MuranoObject):
|
||||||
def initialize(self, _context, name):
|
def initialize(self, _context, name):
|
||||||
self._results_queue = str('-execution-results-%s' % name.lower())
|
self._results_queue = str('-execution-results-%s' % name.lower())
|
||||||
self._subscriptions = {}
|
self._subscriptions = {}
|
||||||
|
@@ -13,8 +13,8 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from muranoapi.common import config
|
import muranoapi.common.config as config
|
||||||
from muranoapi.common import messaging
|
import muranoapi.common.messaging as messaging
|
||||||
|
|
||||||
|
|
||||||
def create_rmq_client():
|
def create_rmq_client():
|
||||||
|
@@ -14,21 +14,23 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
import eventlet
|
import eventlet
|
||||||
from heatclient import client as hclient
|
import heatclient.client as hclient
|
||||||
from heatclient import exc as heat_exc
|
import heatclient.exc as heat_exc
|
||||||
from keystoneclient.v2_0 import client as ksclient
|
import keystoneclient.v2_0.client as ksclient
|
||||||
|
|
||||||
from muranoapi.common import config
|
|
||||||
from muranoapi.engine import classes
|
import muranoapi.common.config as config
|
||||||
from muranoapi.engine import helpers
|
|
||||||
from muranoapi.engine import objects
|
import muranoapi.dsl.helpers as helpers
|
||||||
from muranoapi.openstack.common import log as logging
|
import muranoapi.dsl.murano_class as murano_class
|
||||||
|
import muranoapi.dsl.murano_object as murano_object
|
||||||
|
import muranoapi.openstack.common.log as logging
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@classes.classname('org.openstack.murano.system.HeatStack')
|
@murano_class.classname('io.murano.system.HeatStack')
|
||||||
class HeatStack(objects.MuranoObject):
|
class HeatStack(murano_object.MuranoObject):
|
||||||
def initialize(self, _context, name):
|
def initialize(self, _context, name):
|
||||||
self._name = name
|
self._name = name
|
||||||
self._template = None
|
self._template = None
|
||||||
|
@@ -17,10 +17,10 @@ import json as jsonlib
|
|||||||
import os.path
|
import os.path
|
||||||
import yaml as yamllib
|
import yaml as yamllib
|
||||||
|
|
||||||
from muranoapi.engine import objects
|
import muranoapi.dsl.murano_object as murano_object
|
||||||
|
|
||||||
|
|
||||||
class ResourceManager(objects.MuranoObject):
|
class ResourceManager(murano_object.MuranoObject):
|
||||||
def initialize(self, base_path, _context, _class):
|
def initialize(self, base_path, _context, _class):
|
||||||
if _class is None:
|
if _class is None:
|
||||||
_class = _context.get_data('$')
|
_class = _context.get_data('$')
|
||||||
|
48
muranoapi/engine/system/system_objects.py
Normal file
48
muranoapi/engine/system/system_objects.py
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
# Copyright (c) 2013 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 muranoapi.dsl.murano_class as murano_class
|
||||||
|
import muranoapi.engine.system.agent as agent
|
||||||
|
import muranoapi.engine.system.agent_listener as agent_listener
|
||||||
|
import muranoapi.engine.system.heat_stack as heat_stack
|
||||||
|
import muranoapi.engine.system.resource_manager as resource_manager
|
||||||
|
|
||||||
|
|
||||||
|
def _auto_register(class_loader):
|
||||||
|
globs = globals().copy()
|
||||||
|
for module_name, value in globs.iteritems():
|
||||||
|
if inspect.ismodule(value):
|
||||||
|
for class_name in dir(value):
|
||||||
|
class_def = getattr(value, class_name)
|
||||||
|
if inspect.isclass(class_def) and hasattr(
|
||||||
|
class_def, '_murano_class_name'):
|
||||||
|
class_loader.import_class(class_def)
|
||||||
|
|
||||||
|
|
||||||
|
def register(class_loader, path):
|
||||||
|
_auto_register(class_loader)
|
||||||
|
|
||||||
|
@murano_class.classname('io.murano.system.Resources')
|
||||||
|
class ResourceManagerWrapper(resource_manager.ResourceManager):
|
||||||
|
def initialize(self, _context, _class=None):
|
||||||
|
super(ResourceManagerWrapper, self).initialize(
|
||||||
|
path, _context, _class)
|
||||||
|
|
||||||
|
class_loader.import_class(agent.Agent)
|
||||||
|
class_loader.import_class(agent_listener.AgentListener)
|
||||||
|
class_loader.import_class(heat_stack.HeatStack)
|
||||||
|
class_loader.import_class(ResourceManagerWrapper)
|
@@ -17,10 +17,10 @@ import base64
|
|||||||
import re
|
import re
|
||||||
import types
|
import types
|
||||||
|
|
||||||
from yaql import context
|
import yaql.context
|
||||||
|
|
||||||
from muranoapi.common import config as cfg
|
import muranoapi.common.config as cfg
|
||||||
from muranoapi.engine import helpers
|
import muranoapi.dsl.helpers as helpers
|
||||||
|
|
||||||
|
|
||||||
def _transform_json(json, mappings):
|
def _transform_json(json, mappings):
|
||||||
@@ -62,20 +62,20 @@ def _convert_macro_parameter(macro, mappings):
|
|||||||
return mappings[macro]
|
return mappings[macro]
|
||||||
|
|
||||||
|
|
||||||
@context.EvalArg('format', types.StringTypes)
|
@yaql.context.EvalArg('format', types.StringTypes)
|
||||||
def _format(format, *args):
|
def _format(format, *args):
|
||||||
return format.format(*[t() for t in args])
|
return format.format(*[t() for t in args])
|
||||||
|
|
||||||
|
|
||||||
@context.EvalArg('src', types.StringTypes)
|
@yaql.context.EvalArg('src', types.StringTypes)
|
||||||
@context.EvalArg('substring', types.StringTypes)
|
@yaql.context.EvalArg('substring', types.StringTypes)
|
||||||
@context.EvalArg('value', types.StringTypes)
|
@yaql.context.EvalArg('value', types.StringTypes)
|
||||||
def _replace_str(src, substring, value):
|
def _replace_str(src, substring, value):
|
||||||
return src.replace(substring, value)
|
return src.replace(substring, value)
|
||||||
|
|
||||||
|
|
||||||
@context.EvalArg('src', types.StringTypes)
|
@yaql.context.EvalArg('src', types.StringTypes)
|
||||||
@context.EvalArg('replacements', dict)
|
@yaql.context.EvalArg('replacements', dict)
|
||||||
def _replace_dict(src, replacements):
|
def _replace_dict(src, replacements):
|
||||||
for key, value in replacements.iteritems():
|
for key, value in replacements.iteritems():
|
||||||
if isinstance(src, str):
|
if isinstance(src, str):
|
||||||
@@ -97,74 +97,74 @@ def _coalesce(*args):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
@context.EvalArg('value', types.StringTypes)
|
@yaql.context.EvalArg('value', types.StringTypes)
|
||||||
def _base64encode(value):
|
def _base64encode(value):
|
||||||
return base64.b64encode(value)
|
return base64.b64encode(value)
|
||||||
|
|
||||||
|
|
||||||
@context.EvalArg('value', types.StringTypes)
|
@yaql.context.EvalArg('value', types.StringTypes)
|
||||||
def _base64decode(value):
|
def _base64decode(value):
|
||||||
return base64.b64decode(value)
|
return base64.b64decode(value)
|
||||||
|
|
||||||
|
|
||||||
@context.EvalArg('group', types.StringTypes)
|
@yaql.context.EvalArg('group', types.StringTypes)
|
||||||
@context.EvalArg('setting', types.StringTypes)
|
@yaql.context.EvalArg('setting', types.StringTypes)
|
||||||
def _config(group, setting):
|
def _config(group, setting):
|
||||||
return cfg.CONF[group][setting]
|
return cfg.CONF[group][setting]
|
||||||
|
|
||||||
|
|
||||||
@context.EvalArg('setting', types.StringTypes)
|
@yaql.context.EvalArg('setting', types.StringTypes)
|
||||||
def _config_default(setting):
|
def _config_default(setting):
|
||||||
return cfg.CONF[setting]
|
return cfg.CONF[setting]
|
||||||
|
|
||||||
|
|
||||||
@context.EvalArg('value', types.StringTypes)
|
@yaql.context.EvalArg('value', types.StringTypes)
|
||||||
def _upper(value):
|
def _upper(value):
|
||||||
return value.upper()
|
return value.upper()
|
||||||
|
|
||||||
|
|
||||||
@context.EvalArg('value', types.StringTypes)
|
@yaql.context.EvalArg('value', types.StringTypes)
|
||||||
def _lower(value):
|
def _lower(value):
|
||||||
return value.lower()
|
return value.lower()
|
||||||
|
|
||||||
|
|
||||||
@context.EvalArg('separator', types.StringTypes)
|
@yaql.context.EvalArg('separator', types.StringTypes)
|
||||||
def _join(separator, *args):
|
def _join(separator, *args):
|
||||||
return separator.join([t() for t in args])
|
return separator.join([t() for t in args])
|
||||||
|
|
||||||
|
|
||||||
@context.EvalArg('value', types.StringTypes)
|
@yaql.context.EvalArg('value', types.StringTypes)
|
||||||
@context.EvalArg('separator', types.StringTypes)
|
@yaql.context.EvalArg('separator', types.StringTypes)
|
||||||
def _split(value, separator):
|
def _split(value, separator):
|
||||||
return value.split(separator)
|
return value.split(separator)
|
||||||
|
|
||||||
|
|
||||||
@context.EvalArg('value', types.StringTypes)
|
@yaql.context.EvalArg('value', types.StringTypes)
|
||||||
@context.EvalArg('prefix', types.StringTypes)
|
@yaql.context.EvalArg('prefix', types.StringTypes)
|
||||||
def _startswith(value, prefix):
|
def _startswith(value, prefix):
|
||||||
return value.startswith(prefix)
|
return value.startswith(prefix)
|
||||||
|
|
||||||
|
|
||||||
@context.EvalArg('value', types.StringTypes)
|
@yaql.context.EvalArg('value', types.StringTypes)
|
||||||
@context.EvalArg('suffix', types.StringTypes)
|
@yaql.context.EvalArg('suffix', types.StringTypes)
|
||||||
def _endswith(value, suffix):
|
def _endswith(value, suffix):
|
||||||
return value.endswith(suffix)
|
return value.endswith(suffix)
|
||||||
|
|
||||||
|
|
||||||
@context.EvalArg('value', types.StringTypes)
|
@yaql.context.EvalArg('value', types.StringTypes)
|
||||||
def _trim(value):
|
def _trim(value):
|
||||||
return value.strip()
|
return value.strip()
|
||||||
|
|
||||||
|
|
||||||
@context.EvalArg('value', types.StringTypes)
|
@yaql.context.EvalArg('value', types.StringTypes)
|
||||||
@context.EvalArg('pattern', types.StringTypes)
|
@yaql.context.EvalArg('pattern', types.StringTypes)
|
||||||
def _mathces(value, pattern):
|
def _mathces(value, pattern):
|
||||||
return re.match(pattern, value) is not None
|
return re.match(pattern, value) is not None
|
||||||
|
|
||||||
|
|
||||||
@context.EvalArg('value', types.StringTypes)
|
@yaql.context.EvalArg('value', types.StringTypes)
|
||||||
@context.EvalArg('index', int)
|
@yaql.context.EvalArg('index', int)
|
||||||
@context.EvalArg('length', int)
|
@yaql.context.EvalArg('length', int)
|
||||||
def _substr(value, index=0, length=-1):
|
def _substr(value, index=0, length=-1):
|
||||||
if length < 0:
|
if length < 0:
|
||||||
return value[index:]
|
return value[index:]
|
||||||
|
@@ -19,44 +19,44 @@ import mock
|
|||||||
import unittest2 as unittest
|
import unittest2 as unittest
|
||||||
import yaql
|
import yaql
|
||||||
|
|
||||||
from muranoapi.engine import classes
|
import muranoapi.dsl.exceptions as exceptions
|
||||||
from muranoapi.engine import exceptions
|
import muranoapi.dsl.helpers as helpers
|
||||||
from muranoapi.engine import helpers
|
import muranoapi.dsl.murano_class as murano_class
|
||||||
from muranoapi.engine import namespaces
|
import muranoapi.dsl.murano_object as murano_object
|
||||||
from muranoapi.engine import objects
|
import muranoapi.dsl.namespace_resolver as ns_resolver
|
||||||
from muranoapi.engine import typespec
|
import muranoapi.dsl.typespec as typespec
|
||||||
from muranoapi.engine import yaql_expression
|
import muranoapi.dsl.yaql_expression as yaql_expression
|
||||||
|
|
||||||
ROOT_CLASS = 'org.openstack.murano.Object'
|
ROOT_CLASS = 'io.murano.Object'
|
||||||
|
|
||||||
|
|
||||||
class TestNamespaceResolving(unittest.TestCase):
|
class TestNamespaceResolving(unittest.TestCase):
|
||||||
def test_fails_w_empty_name(self):
|
def test_fails_w_empty_name(self):
|
||||||
resolver = namespaces.NamespaceResolver({'=': 'com.example.murano'})
|
resolver = ns_resolver.NamespaceResolver({'=': 'com.example.murano'})
|
||||||
|
|
||||||
self.assertRaises(ValueError, resolver.resolve_name, None)
|
self.assertRaises(ValueError, resolver.resolve_name, None)
|
||||||
|
|
||||||
def test_fails_w_unknown_prefix(self):
|
def test_fails_w_unknown_prefix(self):
|
||||||
resolver = namespaces.NamespaceResolver({'=': 'com.example.murano'})
|
resolver = ns_resolver.NamespaceResolver({'=': 'com.example.murano'})
|
||||||
name = 'unknown_prefix:example.murano'
|
name = 'unknown_prefix:example.murano'
|
||||||
|
|
||||||
self.assertRaises(KeyError, resolver.resolve_name, name)
|
self.assertRaises(KeyError, resolver.resolve_name, name)
|
||||||
|
|
||||||
def test_fails_w_prefix_wo_name(self):
|
def test_fails_w_prefix_wo_name(self):
|
||||||
resolver = namespaces.NamespaceResolver({'=': 'com.example.murano'})
|
resolver = ns_resolver.NamespaceResolver({'=': 'com.example.murano'})
|
||||||
name = 'sys:'
|
name = 'sys:'
|
||||||
|
|
||||||
self.assertRaises(NameError, resolver.resolve_name, name)
|
self.assertRaises(NameError, resolver.resolve_name, name)
|
||||||
|
|
||||||
def test_fails_w_excessive_prefix(self):
|
def test_fails_w_excessive_prefix(self):
|
||||||
ns = {'sys': 'com.example.murano.system'}
|
ns = {'sys': 'com.example.murano.system'}
|
||||||
resolver = namespaces.NamespaceResolver(ns)
|
resolver = ns_resolver.NamespaceResolver(ns)
|
||||||
invalid_name = 'sys:excessive_ns:muranoResource'
|
invalid_name = 'sys:excessive_ns:muranoResource'
|
||||||
|
|
||||||
self.assertRaises(NameError, resolver.resolve_name, invalid_name)
|
self.assertRaises(NameError, resolver.resolve_name, invalid_name)
|
||||||
|
|
||||||
def test_cuts_empty_prefix(self):
|
def test_cuts_empty_prefix(self):
|
||||||
resolver = namespaces.NamespaceResolver({'=': 'com.example.murano'})
|
resolver = ns_resolver.NamespaceResolver({'=': 'com.example.murano'})
|
||||||
# name without prefix delimiter
|
# name without prefix delimiter
|
||||||
name = 'some.arbitrary.name'
|
name = 'some.arbitrary.name'
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ class TestNamespaceResolving(unittest.TestCase):
|
|||||||
|
|
||||||
def test_resolves_specified_ns_prefix(self):
|
def test_resolves_specified_ns_prefix(self):
|
||||||
ns = {'sys': 'com.example.murano.system'}
|
ns = {'sys': 'com.example.murano.system'}
|
||||||
resolver = namespaces.NamespaceResolver(ns)
|
resolver = ns_resolver.NamespaceResolver(ns)
|
||||||
short_name, full_name = 'sys:File', 'com.example.murano.system.File'
|
short_name, full_name = 'sys:File', 'com.example.murano.system.File'
|
||||||
|
|
||||||
resolved_name = resolver.resolve_name(short_name)
|
resolved_name = resolver.resolve_name(short_name)
|
||||||
@@ -74,7 +74,7 @@ class TestNamespaceResolving(unittest.TestCase):
|
|||||||
self.assertEqual(full_name, resolved_name)
|
self.assertEqual(full_name, resolved_name)
|
||||||
|
|
||||||
def test_resolves_current_ns(self):
|
def test_resolves_current_ns(self):
|
||||||
resolver = namespaces.NamespaceResolver({'=': 'com.example.murano'})
|
resolver = ns_resolver.NamespaceResolver({'=': 'com.example.murano'})
|
||||||
short_name, full_name = 'Resource', 'com.example.murano.Resource'
|
short_name, full_name = 'Resource', 'com.example.murano.Resource'
|
||||||
|
|
||||||
resolved_name = resolver.resolve_name(short_name)
|
resolved_name = resolver.resolve_name(short_name)
|
||||||
@@ -82,21 +82,21 @@ class TestNamespaceResolving(unittest.TestCase):
|
|||||||
self.assertEqual(full_name, resolved_name)
|
self.assertEqual(full_name, resolved_name)
|
||||||
|
|
||||||
def test_resolves_explicit_base(self):
|
def test_resolves_explicit_base(self):
|
||||||
resolver = namespaces.NamespaceResolver({'=': 'com.example.murano'})
|
resolver = ns_resolver.NamespaceResolver({'=': 'com.example.murano'})
|
||||||
|
|
||||||
resolved_name = resolver.resolve_name('Resource', relative='com.base')
|
resolved_name = resolver.resolve_name('Resource', relative='com.base')
|
||||||
|
|
||||||
self.assertEqual('com.base.Resource', resolved_name)
|
self.assertEqual('com.base.Resource', resolved_name)
|
||||||
|
|
||||||
def test_resolves_explicit_base_w_empty_namespaces(self):
|
def test_resolves_explicit_base_w_empty_namespaces(self):
|
||||||
resolver = namespaces.NamespaceResolver({})
|
resolver = ns_resolver.NamespaceResolver({})
|
||||||
|
|
||||||
resolved_name = resolver.resolve_name('File', 'com.base')
|
resolved_name = resolver.resolve_name('File', 'com.base')
|
||||||
|
|
||||||
self.assertEqual('com.base.File', resolved_name)
|
self.assertEqual('com.base.File', resolved_name)
|
||||||
|
|
||||||
def test_resolves_w_empty_namespaces(self):
|
def test_resolves_w_empty_namespaces(self):
|
||||||
resolver = namespaces.NamespaceResolver({})
|
resolver = ns_resolver.NamespaceResolver({})
|
||||||
|
|
||||||
resolved_name = resolver.resolve_name('Resource')
|
resolved_name = resolver.resolve_name('Resource')
|
||||||
|
|
||||||
@@ -114,38 +114,38 @@ class TestClassesManipulation(unittest.TestCase):
|
|||||||
resolver = mock.Mock(resolve_name=lambda name: name)
|
resolver = mock.Mock(resolve_name=lambda name: name)
|
||||||
|
|
||||||
def test_class_name(self):
|
def test_class_name(self):
|
||||||
cls = classes.MuranoClass(None, self.resolver, ROOT_CLASS)
|
cls = murano_class.MuranoClass(None, self.resolver, ROOT_CLASS)
|
||||||
|
|
||||||
self.assertEqual(ROOT_CLASS, cls.name)
|
self.assertEqual(ROOT_CLASS, cls.name)
|
||||||
|
|
||||||
def test_class_namespace_resolver(self):
|
def test_class_namespace_resolver(self):
|
||||||
resolver = namespaces.NamespaceResolver({})
|
resolver = ns_resolver.NamespaceResolver({})
|
||||||
cls = classes.MuranoClass(None, resolver, ROOT_CLASS)
|
cls = murano_class.MuranoClass(None, resolver, ROOT_CLASS)
|
||||||
|
|
||||||
self.assertEqual(resolver, cls.namespace_resolver)
|
self.assertEqual(resolver, cls.namespace_resolver)
|
||||||
|
|
||||||
def test_root_class_has_no_parents(self):
|
def test_root_class_has_no_parents(self):
|
||||||
root_class = classes.MuranoClass(
|
root_class = murano_class.MuranoClass(
|
||||||
None, self.resolver, ROOT_CLASS, ['You should not see me!'])
|
None, self.resolver, ROOT_CLASS, ['You should not see me!'])
|
||||||
|
|
||||||
self.assertEqual([], root_class.parents)
|
self.assertEqual([], root_class.parents)
|
||||||
|
|
||||||
def test_non_root_class_resolves_parents(self):
|
def test_non_root_class_resolves_parents(self):
|
||||||
root_cls = classes.MuranoClass(None, self.resolver, ROOT_CLASS)
|
root_cls = murano_class.MuranoClass(None, self.resolver, ROOT_CLASS)
|
||||||
class_loader = mock.Mock(get_class=lambda name: root_cls)
|
class_loader = mock.Mock(get_class=lambda name: root_cls)
|
||||||
desc_cls1 = classes.MuranoClass(class_loader, self.resolver, 'Obj')
|
desc_cl1 = murano_class.MuranoClass(class_loader, self.resolver, 'Obj')
|
||||||
desc_cls2 = classes.MuranoClass(
|
desc_cl2 = murano_class.MuranoClass(
|
||||||
class_loader, self.resolver, 'Obj', [root_cls])
|
class_loader, self.resolver, 'Obj', [root_cls])
|
||||||
|
|
||||||
self.assertEqual([root_cls], desc_cls1.parents)
|
self.assertEqual([root_cls], desc_cl1.parents)
|
||||||
self.assertEqual([root_cls], desc_cls2.parents)
|
self.assertEqual([root_cls], desc_cl2.parents)
|
||||||
|
|
||||||
def test_class_initial_properties(self):
|
def test_class_initial_properties(self):
|
||||||
cls = classes.MuranoClass(None, self.resolver, ROOT_CLASS)
|
cls = murano_class.MuranoClass(None, self.resolver, ROOT_CLASS)
|
||||||
self.assertEqual([], cls.properties)
|
self.assertEqual([], cls.properties)
|
||||||
|
|
||||||
def test_fails_add_incompatible_property_to_class(self):
|
def test_fails_add_incompatible_property_to_class(self):
|
||||||
cls = classes.MuranoClass(None, self.resolver, ROOT_CLASS)
|
cls = murano_class.MuranoClass(None, self.resolver, ROOT_CLASS)
|
||||||
kwargs = {'name': 'sampleProperty', 'property_typespec': {}}
|
kwargs = {'name': 'sampleProperty', 'property_typespec': {}}
|
||||||
|
|
||||||
self.assertRaises(TypeError, cls.add_property, **kwargs)
|
self.assertRaises(TypeError, cls.add_property, **kwargs)
|
||||||
@@ -153,7 +153,7 @@ class TestClassesManipulation(unittest.TestCase):
|
|||||||
@unittest.skip
|
@unittest.skip
|
||||||
def test_add_property_to_class(self):
|
def test_add_property_to_class(self):
|
||||||
prop = typespec.PropertySpec({'Default': 1}, self.resolver)
|
prop = typespec.PropertySpec({'Default': 1}, self.resolver)
|
||||||
cls = classes.MuranoClass(None, self.resolver, ROOT_CLASS)
|
cls = murano_class.MuranoClass(None, self.resolver, ROOT_CLASS)
|
||||||
cls.add_property('firstPrime', prop)
|
cls.add_property('firstPrime', prop)
|
||||||
|
|
||||||
class_properties = cls.properties
|
class_properties = cls.properties
|
||||||
@@ -171,10 +171,12 @@ class TestClassesManipulation(unittest.TestCase):
|
|||||||
self.resolver)
|
self.resolver)
|
||||||
child_prop = typespec.PropertySpec({'Default': 'Child'},
|
child_prop = typespec.PropertySpec({'Default': 'Child'},
|
||||||
self.resolver)
|
self.resolver)
|
||||||
root = classes.MuranoClass(None, self.resolver, ROOT_CLASS)
|
root = murano_class.MuranoClass(None, self.resolver, ROOT_CLASS)
|
||||||
mother = classes.MuranoClass(None, self.resolver, 'Mother', [root])
|
mother = murano_class.MuranoClass(None, self.resolver,
|
||||||
father = classes.MuranoClass(None, self.resolver, 'Father', [root])
|
'Mother', [root])
|
||||||
child = classes.MuranoClass(
|
father = murano_class.MuranoClass(None, self.resolver,
|
||||||
|
'Father', [root])
|
||||||
|
child = murano_class.MuranoClass(
|
||||||
None, self.resolver, 'Child', [mother, father])
|
None, self.resolver, 'Child', [mother, father])
|
||||||
|
|
||||||
root.add_property('Void', void_prop)
|
root.add_property('Void', void_prop)
|
||||||
@@ -188,11 +190,11 @@ class TestClassesManipulation(unittest.TestCase):
|
|||||||
self.assertEqual(void_prop, child.find_property('Void'))
|
self.assertEqual(void_prop, child.find_property('Void'))
|
||||||
|
|
||||||
def test_class_is_compatible(self):
|
def test_class_is_compatible(self):
|
||||||
cls = classes.MuranoClass(None, self.resolver, ROOT_CLASS)
|
cls = murano_class.MuranoClass(None, self.resolver, ROOT_CLASS)
|
||||||
descendant_cls = classes.MuranoClass(
|
descendant_cls = murano_class.MuranoClass(
|
||||||
None, self.resolver, 'DescendantCls', [cls])
|
None, self.resolver, 'DescendantCls', [cls])
|
||||||
obj = mock.Mock(spec=objects.MuranoObject)
|
obj = mock.Mock(spec=murano_object.MuranoObject)
|
||||||
descendant_obj = mock.Mock(spec=objects.MuranoObject)
|
descendant_obj = mock.Mock(spec=murano_object.MuranoObject)
|
||||||
obj.type = cls
|
obj.type = cls
|
||||||
descendant_obj.type = descendant_cls
|
descendant_obj.type = descendant_cls
|
||||||
descendant_obj.parents = [obj]
|
descendant_obj.parents = [obj]
|
||||||
@@ -202,7 +204,7 @@ class TestClassesManipulation(unittest.TestCase):
|
|||||||
self.assertFalse(descendant_cls.is_compatible(obj))
|
self.assertFalse(descendant_cls.is_compatible(obj))
|
||||||
|
|
||||||
def test_new_method_calls_initialize(self):
|
def test_new_method_calls_initialize(self):
|
||||||
cls = classes.MuranoClass(None, self.resolver, ROOT_CLASS)
|
cls = murano_class.MuranoClass(None, self.resolver, ROOT_CLASS)
|
||||||
cls.object_class = mock.Mock()
|
cls.object_class = mock.Mock()
|
||||||
|
|
||||||
with mock.patch('inspect.getargspec') as spec_mock:
|
with mock.patch('inspect.getargspec') as spec_mock:
|
||||||
@@ -212,7 +214,7 @@ class TestClassesManipulation(unittest.TestCase):
|
|||||||
self.assertTrue(obj.initialize.called)
|
self.assertTrue(obj.initialize.called)
|
||||||
|
|
||||||
def test_new_method_not_calls_initialize(self):
|
def test_new_method_not_calls_initialize(self):
|
||||||
cls = classes.MuranoClass(None, self.resolver, ROOT_CLASS)
|
cls = murano_class.MuranoClass(None, self.resolver, ROOT_CLASS)
|
||||||
cls.object_class = mock.Mock()
|
cls.object_class = mock.Mock()
|
||||||
|
|
||||||
obj = cls.new(None, None, None)
|
obj = cls.new(None, None, None)
|
||||||
@@ -228,7 +230,7 @@ class TestObjectsManipulation(unittest.TestCase):
|
|||||||
self.cls.parents = []
|
self.cls.parents = []
|
||||||
|
|
||||||
def test_object_valid_type_instantiation(self):
|
def test_object_valid_type_instantiation(self):
|
||||||
obj = objects.MuranoObject(self.cls, None, None, None)
|
obj = murano_object.MuranoObject(self.cls, None, None, None)
|
||||||
|
|
||||||
self.assertEqual(self.cls, obj.type)
|
self.assertEqual(self.cls, obj.type)
|
||||||
|
|
||||||
@@ -239,11 +241,12 @@ class TestObjectsManipulation(unittest.TestCase):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def test_object_parent_properties_initialization(self):
|
def test_object_parent_properties_initialization(self):
|
||||||
root = classes.MuranoClass(None, self.resolver, ROOT_CLASS)
|
root = murano_class.MuranoClass(None, self.resolver, ROOT_CLASS)
|
||||||
cls = classes.MuranoClass(None, self.resolver, 'SomeClass', [root])
|
cls = murano_class.MuranoClass(None, self.resolver,
|
||||||
|
'SomeClass', [root])
|
||||||
root.new = mock.Mock()
|
root.new = mock.Mock()
|
||||||
init_kwargs = {'theArg': 0}
|
init_kwargs = {'theArg': 0}
|
||||||
obj = objects.MuranoObject(cls, None, None, None)
|
obj = murano_object.MuranoObject(cls, None, None, None)
|
||||||
expected_calls = [mock.call().initialize(**init_kwargs)]
|
expected_calls = [mock.call().initialize(**init_kwargs)]
|
||||||
|
|
||||||
obj.initialize(**init_kwargs)
|
obj.initialize(**init_kwargs)
|
||||||
@@ -253,35 +256,36 @@ class TestObjectsManipulation(unittest.TestCase):
|
|||||||
|
|
||||||
def test_object_id(self):
|
def test_object_id(self):
|
||||||
_id = 'some_id'
|
_id = 'some_id'
|
||||||
patch_at = 'muranoapi.engine.objects.helpers.generate_id'
|
patch_at = 'muranoapi.dsl.helpers.generate_id'
|
||||||
|
|
||||||
obj = objects.MuranoObject(self.cls, None, None, None, object_id=_id)
|
obj = murano_object.MuranoObject(self.cls, None, None, None,
|
||||||
|
object_id=_id)
|
||||||
with mock.patch(patch_at) as gen_id_mock:
|
with mock.patch(patch_at) as gen_id_mock:
|
||||||
gen_id_mock.return_value = _id
|
gen_id_mock.return_value = _id
|
||||||
obj1 = objects.MuranoObject(self.cls, None, None, None)
|
obj1 = murano_object.MuranoObject(self.cls, None, None, None)
|
||||||
|
|
||||||
self.assertEqual(_id, obj.object_id)
|
self.assertEqual(_id, obj.object_id)
|
||||||
self.assertEqual(_id, obj1.object_id)
|
self.assertEqual(_id, obj1.object_id)
|
||||||
|
|
||||||
def test_parent_obj(self):
|
def test_parent_obj(self):
|
||||||
parent = mock.Mock()
|
parent = mock.Mock()
|
||||||
obj = objects.MuranoObject(self.cls, parent, None, None)
|
obj = murano_object.MuranoObject(self.cls, parent, None, None)
|
||||||
|
|
||||||
self.assertEqual(parent, obj.parent)
|
self.assertEqual(parent, obj.parent)
|
||||||
|
|
||||||
@unittest.skip
|
@unittest.skip
|
||||||
def test_fails_internal_property_access(self):
|
def test_fails_internal_property_access(self):
|
||||||
cls = classes.MuranoClass(None, self.resolver, ROOT_CLASS)
|
cls = murano_class.MuranoClass(None, self.resolver, ROOT_CLASS)
|
||||||
|
|
||||||
cls.add_property('__hidden',
|
cls.add_property('__hidden',
|
||||||
typespec.PropertySpec({'Default': 10}, self.resolver))
|
typespec.PropertySpec({'Default': 10}, self.resolver))
|
||||||
obj = objects.MuranoObject(cls, None, None, None)
|
obj = murano_object.MuranoObject(cls, None, None, None)
|
||||||
|
|
||||||
self.assertRaises(AttributeError, lambda: obj.__hidden)
|
self.assertRaises(AttributeError, lambda: obj.__hidden)
|
||||||
|
|
||||||
@unittest.skip
|
@unittest.skip
|
||||||
def test_proper_property_access(self):
|
def test_proper_property_access(self):
|
||||||
cls = classes.MuranoClass(None, self.resolver, ROOT_CLASS)
|
cls = murano_class.MuranoClass(None, self.resolver, ROOT_CLASS)
|
||||||
|
|
||||||
cls.add_property('someProperty',
|
cls.add_property('someProperty',
|
||||||
typespec.PropertySpec({'Default': 0}, self.resolver))
|
typespec.PropertySpec({'Default': 0}, self.resolver))
|
||||||
@@ -291,8 +295,9 @@ class TestObjectsManipulation(unittest.TestCase):
|
|||||||
|
|
||||||
@unittest.skip
|
@unittest.skip
|
||||||
def test_parent_class_property_access(self):
|
def test_parent_class_property_access(self):
|
||||||
cls = classes.MuranoClass(None, self.resolver, ROOT_CLASS)
|
cls = murano_class.MuranoClass(None, self.resolver, ROOT_CLASS)
|
||||||
child_cls = classes.MuranoClass(None, self.resolver, 'Child', [cls])
|
child_cls = murano_class.MuranoClass(None, self.resolver,
|
||||||
|
'Child', [cls])
|
||||||
|
|
||||||
cls.add_property('anotherProperty',
|
cls.add_property('anotherProperty',
|
||||||
typespec.PropertySpec({'Default': 0}, self.resolver))
|
typespec.PropertySpec({'Default': 0}, self.resolver))
|
||||||
@@ -302,10 +307,12 @@ class TestObjectsManipulation(unittest.TestCase):
|
|||||||
|
|
||||||
@unittest.skip
|
@unittest.skip
|
||||||
def test_fails_on_parents_property_collision(self):
|
def test_fails_on_parents_property_collision(self):
|
||||||
root = classes.MuranoClass(None, self.resolver, ROOT_CLASS)
|
root = murano_class.MuranoClass(None, self.resolver, ROOT_CLASS)
|
||||||
mother = classes.MuranoClass(None, self.resolver, 'Mother', [root])
|
mother = murano_class.MuranoClass(None, self.resolver,
|
||||||
father = classes.MuranoClass(None, self.resolver, 'Father', [root])
|
'Mother', [root])
|
||||||
child = classes.MuranoClass(
|
father = murano_class.MuranoClass(None, self.resolver,
|
||||||
|
'Father', [root])
|
||||||
|
child = murano_class.MuranoClass(
|
||||||
None, self.resolver, 'Child', [mother, father])
|
None, self.resolver, 'Child', [mother, father])
|
||||||
|
|
||||||
mother.add_property(
|
mother.add_property(
|
||||||
@@ -319,13 +326,13 @@ class TestObjectsManipulation(unittest.TestCase):
|
|||||||
self.assertRaises(LookupError, lambda: obj.conflictProp)
|
self.assertRaises(LookupError, lambda: obj.conflictProp)
|
||||||
|
|
||||||
def test_fails_setting_undeclared_property(self):
|
def test_fails_setting_undeclared_property(self):
|
||||||
cls = classes.MuranoClass(None, self.resolver, ROOT_CLASS)
|
cls = murano_class.MuranoClass(None, self.resolver, ROOT_CLASS)
|
||||||
obj = cls.new(None, None, None, {})
|
obj = cls.new(None, None, None, {})
|
||||||
|
|
||||||
self.assertRaises(AttributeError, obj.set_property, 'newOne', 10)
|
self.assertRaises(AttributeError, obj.set_property, 'newOne', 10)
|
||||||
|
|
||||||
def test_set_undeclared_property_as_internal(self):
|
def test_set_undeclared_property_as_internal(self):
|
||||||
cls = classes.MuranoClass(None, self.resolver, ROOT_CLASS)
|
cls = murano_class.MuranoClass(None, self.resolver, ROOT_CLASS)
|
||||||
obj = cls.new(None, None, None, {})
|
obj = cls.new(None, None, None, {})
|
||||||
obj.cast = mock.Mock(return_value=obj)
|
obj.cast = mock.Mock(return_value=obj)
|
||||||
prop_value = 10
|
prop_value = 10
|
||||||
@@ -337,7 +344,7 @@ class TestObjectsManipulation(unittest.TestCase):
|
|||||||
|
|
||||||
@unittest.skip
|
@unittest.skip
|
||||||
def test_fails_forbidden_set_property(self):
|
def test_fails_forbidden_set_property(self):
|
||||||
cls = classes.MuranoClass(None, self.resolver, ROOT_CLASS)
|
cls = murano_class.MuranoClass(None, self.resolver, ROOT_CLASS)
|
||||||
cls.add_property('someProperty',
|
cls.add_property('someProperty',
|
||||||
typespec.PropertySpec({'Default': 0}, self.resolver))
|
typespec.PropertySpec({'Default': 0}, self.resolver))
|
||||||
cls.is_compatible = mock.Mock(return_value=False)
|
cls.is_compatible = mock.Mock(return_value=False)
|
||||||
@@ -348,7 +355,7 @@ class TestObjectsManipulation(unittest.TestCase):
|
|||||||
|
|
||||||
@unittest.skip
|
@unittest.skip
|
||||||
def test_set_property(self):
|
def test_set_property(self):
|
||||||
cls = classes.MuranoClass(None, self.resolver, ROOT_CLASS)
|
cls = murano_class.MuranoClass(None, self.resolver, ROOT_CLASS)
|
||||||
cls.add_property('someProperty',
|
cls.add_property('someProperty',
|
||||||
typespec.PropertySpec({'Default': 0}, self.resolver))
|
typespec.PropertySpec({'Default': 0}, self.resolver))
|
||||||
obj = cls.new(None, None, None, {})
|
obj = cls.new(None, None, None, {})
|
||||||
@@ -362,8 +369,9 @@ class TestObjectsManipulation(unittest.TestCase):
|
|||||||
|
|
||||||
@unittest.skip
|
@unittest.skip
|
||||||
def test_set_parent_property(self):
|
def test_set_parent_property(self):
|
||||||
root = classes.MuranoClass(None, self.resolver, ROOT_CLASS)
|
root = murano_class.MuranoClass(None, self.resolver, ROOT_CLASS)
|
||||||
cls = classes.MuranoClass(None, self.resolver, 'SomeClass', [root])
|
cls = murano_class.MuranoClass(None, self.resolver,
|
||||||
|
'SomeClass', [root])
|
||||||
root.add_property('rootProperty',
|
root.add_property('rootProperty',
|
||||||
typespec.PropertySpec({'Default': 0}, self.resolver))
|
typespec.PropertySpec({'Default': 0}, self.resolver))
|
||||||
obj = cls.new(None, None, None, {})
|
obj = cls.new(None, None, None, {})
|
||||||
@@ -375,10 +383,11 @@ class TestObjectsManipulation(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertEqual(20, obj.rootProperty)
|
self.assertEqual(20, obj.rootProperty)
|
||||||
|
|
||||||
|
@unittest.skip
|
||||||
def test_object_up_cast(self):
|
def test_object_up_cast(self):
|
||||||
root = classes.MuranoClass(None, self.resolver, ROOT_CLASS)
|
root = murano_class.MuranoClass(None, self.resolver, ROOT_CLASS)
|
||||||
root_alt = classes.MuranoClass(None, self.resolver, 'RootAlt', [])
|
root_alt = murano_class.MuranoClass(None, self.resolver, 'RootAlt', [])
|
||||||
cls = classes.MuranoClass(
|
cls = murano_class.MuranoClass(
|
||||||
None, self.resolver, 'SomeClass', [root, root_alt])
|
None, self.resolver, 'SomeClass', [root, root_alt])
|
||||||
root_obj = root.new(None, None, None)
|
root_obj = root.new(None, None, None)
|
||||||
cls_obj = cls.new(None, None, None)
|
cls_obj = cls.new(None, None, None)
|
||||||
@@ -394,8 +403,8 @@ class TestObjectsManipulation(unittest.TestCase):
|
|||||||
self.assertEqual(root_alt, cls_obj_casted2root_alt.type)
|
self.assertEqual(root_alt, cls_obj_casted2root_alt.type)
|
||||||
|
|
||||||
def test_fails_object_down_cast(self):
|
def test_fails_object_down_cast(self):
|
||||||
root = classes.MuranoClass(None, self.resolver, ROOT_CLASS)
|
root = murano_class.MuranoClass(None, self.resolver, ROOT_CLASS)
|
||||||
cls = classes.MuranoClass(
|
cls = murano_class.MuranoClass(
|
||||||
None, self.resolver, 'SomeClass', [root])
|
None, self.resolver, 'SomeClass', [root])
|
||||||
root_obj = root.new(None, None, None)
|
root_obj = root.new(None, None, None)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user