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