class CloudifyClient(object):
    @specs.parameter('app', dsl.MuranoObjectParameter('io.murano.Application'))
    def __init__(self, app):
        cloudify_manager = self.CONF.cloudify_manager
        self._client = cloudify_rest_client.CloudifyClient(cloudify_manager)
        self._blueprint_id = '{0}-{1}'.format(app.type.name, app.type.version)
        self._deployment_id = app.id
        self._application_package = app.package

    @specs.parameter('entry_point', yaqltypes.String())
    def publish_blueprint(self, entry_point):
        global archive_upload_lock

        if self._check_blueprint_exists():
            return
        path = self._application_package.get_resource(entry_point)
        with archive_upload_lock:
            try:
                self._client.blueprints.upload(
                    path, self._blueprint_id)
            except cloudify_exceptions.CloudifyClientError as e:
                if e.status_code != 409:
                    raise

    def _check_blueprint_exists(self):
        try:
            self._client.blueprints.get(self._blueprint_id)
            return True
        except cloudify_exceptions.CloudifyClientError as e:
            if e.status_code == 404:
                return False
            raise

    @specs.parameter('parameters', dict)
    def create_deployment(self, parameters=None):
        self._client.deployments.create(
            self._blueprint_id, self._deployment_id, parameters)

    def delete_deployment(self):
        self._client.deployments.delete(self._deployment_id)

    def wait_deployment_ready(self):
        while True:
            executions = self._client.executions.list(self._deployment_id)
            if any(t.status in ('pending', 'started') for t in executions):
                time.sleep(3)
            else:
                deployment = self._client.deployments.get(self._deployment_id)
                return deployment.outputs

    @specs.parameter('name', yaqltypes.String())
    @specs.parameter('parameters', dict)
    def execute_workflow(self, name, parameters=None):
        self._client.executions.start(self._deployment_id, name, parameters)

    @classmethod
    def init_plugin(cls):
        cls.CONF = cfg.init_config(CONF)
Beispiel #2
0
    def prepare_validate_context(root_context):
        @specs.parameter('value', nullable=True)
        @specs.method
        def int_(value):
            if value is None or isinstance(
                    value, int) and not isinstance(value, bool):
                return value
            raise exceptions.ContractViolationException()

        @specs.parameter('value', nullable=True)
        @specs.method
        def string(value):
            if value is None or isinstance(value, six.string_types):
                return value
            raise exceptions.ContractViolationException()

        @specs.parameter('value', nullable=True)
        @specs.method
        def bool_(value):
            if value is None or isinstance(value, bool):
                return value
            raise exceptions.ContractViolationException()

        @specs.parameter('value', nullable=True)
        @specs.method
        def not_null(value):
            if value is None:
                raise exceptions.ContractViolationException()
            return value

        @specs.parameter('value', nullable=True)
        @specs.parameter('predicate', yaqltypes.Lambda(with_context=True))
        @specs.method
        def check(value, predicate):
            if predicate(root_context.create_child_context(), value):
                return value
            raise exceptions.ContractViolationException()

        @specs.parameter('type', dsl.MuranoTypeParameter(
            nullable=False, context=root_context))
        @specs.parameter('value', nullable=True)
        @specs.parameter('version_spec', yaqltypes.String(True))
        @specs.method
        def class_(value, type, version_spec=None):
            if helpers.is_instance_of(
                    value, type.type.name,
                    version_spec or helpers.get_names_scope(root_context)):
                return value
            raise exceptions.ContractViolationException()

        context = root_context.create_child_context()
        context.register_function(int_)
        context.register_function(string)
        context.register_function(bool_)
        context.register_function(check)
        context.register_function(not_null)
        context.register_function(class_)
        return context
Beispiel #3
0
    def test_super(self):
        @specs.parameter('string', yaqltypes.String())
        @specs.inject('base', yaqltypes.Super())
        def len2(string, base):
            return 2 * base(string)

        context = self.context.create_child_context()
        context.register_function(len2, name='len')
        self.assertEqual(6, self.eval('len(abc)', context=context))
Beispiel #4
0
    def test_delegate_factory(self):
        @specs.parameter('name', yaqltypes.String())
        @specs.inject('__df__', yaqltypes.Delegate())
        def call_func(__df__, name, *args, **kwargs):
            return __df__(name, *args, **kwargs)

        context = self.context.create_child_context()

        context.register_function(call_func)
        self.assertEqual([1, 2],
                         self.eval('callFunc(list, 1, 2)', context=context))

        self.assertEqual(
            6, self.eval("callFunc('#operator_*', 2, 3)", context=context))
Beispiel #5
0
def class_factory(context):
    """Factory for class() contract function that generates schema instead"""
    @specs.parameter('schema', Schema)
    @specs.parameter('name',
                     dsl.MuranoTypeParameter(nullable=False, context=context))
    @specs.parameter('default_name',
                     dsl.MuranoTypeParameter(nullable=True, context=context))
    @specs.parameter('version_spec', yaqltypes.String(True))
    @specs.method
    def class_(schema, name, default_name=None, version_spec=None):
        types = 'muranoObject'
        if '_notNull' not in schema.data:
            types = [types] + ['null']

        return Schema({'type': types, 'muranoType': name.type.name})

    @specs.parameter('schema', Schema)
    @specs.parameter('type_',
                     dsl.MuranoTypeParameter(nullable=False, context=context))
    @specs.parameter('default_type',
                     dsl.MuranoTypeParameter(nullable=True, context=context))
    @specs.parameter('version_spec', yaqltypes.String(True))
    @specs.parameter('exclude_properties', yaqltypes.Sequence(nullable=True))
    @specs.method
    def template(schema,
                 type_,
                 exclude_properties=None,
                 default_type=None,
                 version_spec=None):
        result = class_(schema, type_, default_type, version_spec)
        result.data['owned'] = True
        if exclude_properties:
            result.data['excludedProperties'] = exclude_properties
        return result

    return class_, template
Beispiel #6
0
class Check(contracts.ContractMethod):
    name = 'check'

    @specs.parameter('predicate', yaqltypes.YaqlExpression())
    @specs.parameter('msg', yaqltypes.String(nullable=True))
    def __init__(self, engine, predicate, msg=None):
        self.engine = engine
        self.predicate = predicate
        self.msg = msg

    def _call_predicate(self, value):
        context = self.root_context.create_child_context()
        context['$'] = value
        return self.predicate(utils.NO_VALUE, context, self.engine)

    def validate(self):
        if isinstance(self.value, contracts.ObjRef) or self._call_predicate(
                self.value):
            return self.value
        else:
            msg = self.msg
            if not msg:
                msg = "Value {0} doesn't match predicate".format(
                    helpers.format_scalar(self.value))
            raise exceptions.ContractViolationException(msg)

    def transform(self):
        return self.validate()

    def generate_schema(self):
        rest = [True]
        while rest:
            if (isinstance(self.predicate, expressions.BinaryOperator)
                    and self.predicate.operator == 'and'):
                rest = self.predicate.args[1]
                self.predicate = self.predicate.args[0]
            else:
                rest = []
            res = extract_pattern(self.predicate, self.engine,
                                  self.root_context)
            if res is not None:
                self.value.update(res)
            self.predicate = rest
        return self.value
Beispiel #7
0
from murano.dsl import constants
from murano.dsl import dsl
from murano.dsl import dsl_types
from murano.dsl import helpers
from murano.dsl import linked_context


@specs.parameter('value', dsl_types.MuranoObject)
def id_(value):
    return value.object_id


@specs.parameter('value', dsl_types.MuranoObject)
@specs.parameter('type__', dsl.MuranoTypeName())
@specs.parameter('version_spec', yaqltypes.String(True))
def cast(context, value, type__, version_spec=None):
    return helpers.cast(value, type__.murano_class.name, version_spec
                        or helpers.get_type(context))


@specs.parameter('__type_name', dsl.MuranoTypeName())
@specs.parameter('__extra', utils.MappingType)
@specs.parameter('__owner', dsl_types.MuranoObject)
@specs.parameter('__object_name', yaqltypes.String(True))
def new(__context,
        __type_name,
        __owner=None,
        __object_name=None,
        __extra=None,
        **parameters):
Beispiel #8
0
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.
"""
The module contains functions for regular expressions.
"""

import re

from yaql.language import specs
from yaql.language import yaqltypes

REGEX_TYPE = type(re.compile('.'))


@specs.parameter('pattern', yaqltypes.String())
def regex(pattern, ignore_case=False, multi_line=False, dot_all=False):
    """:yaql:regex

    Returns regular expression object with provided flags. Can be used for
    matching using matches method.

    :signature: regex(pattern,ignoreCase => false, multiLine => false,
        dotAll => false)
    :arg pattern: regular expression pattern to be compiled to regex object
    :argType pattern: string
    :arg ignoreCase: true makes performing case-insensitive matching.
    :argType ignoreCase: boolean
    :arg multiLine: true makes character '^' to match at the beginning of the
        string and at the beginning of each line, the character '$' to match
        at the end of the string and at the end of each line. false means
Beispiel #9
0
    :returnType: expression result or null

    .. code::

        yaql> [0, 1]?.select($+1)
        [1, 2]
        yaql> null?.select($+1)
        null
    """
    if receiver is None:
        return None
    return operator(receiver, expr)


@specs.parameter('sequence', yaqltypes.Iterable())
@specs.parameter('args', yaqltypes.String())
@specs.method
def unpack(sequence, context, *args):
    """:yaql:unpack

    Returns context object with sequence values unpacked to args.
    If args size is equal to sequence size then args get appropriate
    sequence values.
    If args size is 0 then args are 1-based indexes.
    Otherwise ValueError is raised.

    :signature: sequence.unpack([args])
    :receiverArg sequence: iterable of items to be passed as context values
    :argType sequence: iterable
    :arg [args]: keys to be associated with sequence items. If args size is
        equal to sequence size then args get appropriate sequence items. If
Beispiel #10
0
                   offset=ZERO_TIMESPAN):
    zone = _get_tz(offset)
    return DATETIME_TYPE(year, month, day, hour, minute, second, microsecond,
                         zone)


@specs.name('datetime')
@specs.parameter('timestamp', yaqltypes.Number())
@specs.parameter('offset', TIMESPAN_TYPE)
def datetime_from_timestamp(timestamp, offset=ZERO_TIMESPAN):
    zone = _get_tz(offset)
    return datetime.datetime.fromtimestamp(timestamp, tz=zone)


@specs.name('datetime')
@specs.parameter('string', yaqltypes.String())
@specs.parameter('format__', yaqltypes.String(True))
def datetime_from_string(string, format__=None):
    if not format__:
        result = parser.parse(string)
    else:
        result = DATETIME_TYPE.strptime(string, format__)
    if not result.tzinfo:
        return result.replace(tzinfo=UTCTZ)
    return result


@specs.name('timespan')
@specs.parameter('days', int)
@specs.parameter('hours', int)
@specs.parameter('minutes', int)
Beispiel #11
0
from murano.dsl import constants
from murano.dsl import dsl
from murano.dsl import dsl_types
from murano.dsl import helpers
from murano.dsl import reflection
from murano.dsl import serializer


@specs.parameter('object_', dsl.MuranoObjectParameter())
def id_(object_):
    return object_.id


@specs.parameter('object_', dsl.MuranoObjectParameter())
@specs.parameter('type__', dsl.MuranoTypeParameter())
@specs.parameter('version_spec', yaqltypes.String(True))
def cast(context, object_, type__, version_spec=None):
    return helpers.cast(object_, type__.type.name, version_spec
                        or helpers.get_type(context))


@specs.parameter('__type_name', dsl.MuranoTypeParameter())
@specs.parameter('__extra', utils.MappingType)
@specs.parameter('__owner',
                 dsl.MuranoObjectParameter(nullable=True, decorate=False))
@specs.parameter('__object_name', yaqltypes.String(True))
def new(__context,
        __type_name,
        __owner=None,
        __object_name=None,
        __extra=None,
Beispiel #12
0
#    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.
"""
The module describes which operations can be done with strings in YAQL.
"""

import string as string_module

from yaql.language import specs
from yaql.language import utils
from yaql.language import yaqltypes


@specs.parameter('left', yaqltypes.String())
@specs.parameter('right', yaqltypes.String())
@specs.name('#operator_>')
def gt(left, right):
    """:yaql:operator >

    Returns true if the left operand is strictly greater than the right,
    ordering lexicographically, otherwise false.

    :signature: left > right
    :arg left: left operand
    :argType left: string
    :arg right: right operand
    :argType right: string
    :returnType: boolean
Beispiel #13
0
class Template(contracts.ContractMethod):
    name = 'template'

    @specs.parameter('type_', dsl.MuranoTypeParameter(nullable=False,
                                                      lazy=True))
    @specs.parameter('default_type',
                     dsl.MuranoTypeParameter(nullable=True, lazy=True))
    @specs.parameter('version_spec', yaqltypes.String(True))
    @specs.parameter('exclude_properties', yaqltypes.Sequence(nullable=True))
    def __init__(self,
                 engine,
                 type_,
                 default_type=None,
                 version_spec=None,
                 exclude_properties=None):
        self.type = type_(self.context).type
        self.default_type = default_type(self.context) or self.type
        self.version_spec = version_spec
        self.exclude_properties = exclude_properties
        self.engine = engine

    def validate(self):
        if self.value is None or helpers.is_instance_of(
                self.value, self.type.name, self.version_spec
                or helpers.get_names_scope(self.root_context)):
            return self.value
        if not isinstance(
                self.value,
            (dsl_types.MuranoObject, dsl_types.MuranoObjectInterface)):
            raise exceptions.ContractViolationException(
                'Value is not an object')
        raise exceptions.ContractViolationException(
            'Object of type {0} is not compatible with '
            'requested type {1}'.format(self.value.type, self.type))

    def check_type(self):
        if isinstance(self.value, utils.MappingType):
            return self.value
        return self.validate()

    def transform(self):
        object_store = helpers.get_object_store()
        if self.value is None:
            return None
        if isinstance(self.value, dsl_types.MuranoObject):
            obj = self.value
        elif isinstance(self.value, dsl_types.MuranoObjectInterface):
            obj = self.value.object
        elif isinstance(self.value, utils.MappingType):
            passkey = utils.create_marker('<Contract Passkey>')
            if self.exclude_properties:
                parsed = helpers.parse_object_definition(
                    self.value, self.calling_type, self.context)
                props = dsl.to_mutable(parsed['properties'], self.engine)
                for p in self.exclude_properties:
                    helpers.patch_dict(props, p, passkey)
                parsed['properties'] = props
                value = helpers.assemble_object_definition(parsed)
            else:
                value = self.value
            with helpers.thread_local_attribute(constants.TL_CONTRACT_PASSKEY,
                                                passkey):
                with helpers.thread_local_attribute(
                        constants.TL_OBJECTS_DRY_RUN, True):
                    obj = object_store.load(value,
                                            self.owner,
                                            context=self.context,
                                            default_type=self.default_type,
                                            scope_type=self.calling_type)
                    obj.__passkey__ = passkey
        else:
            raise exceptions.ContractViolationException(
                'Value {0} cannot be represented as class {1}'.format(
                    helpers.format_scalar(self.value), self.type))
        self.value = obj
        return self.validate()

    def finalize(self):
        if self.value is None:
            return None
        object_store = helpers.get_object_store()
        if object_store.initializing:
            return {}
        passkey = getattr(self.value, '__passkey__', None)
        with helpers.thread_local_attribute(constants.TL_CONTRACT_PASSKEY,
                                            passkey):
            result = serializer.serialize(self.value.real_this,
                                          object_store.executor,
                                          dsl_types.DumpTypes.Mixed)
            if self.exclude_properties:
                for p in self.exclude_properties:
                    helpers.patch_dict(result, p, utils.NO_VALUE)
            return result

    def generate_schema(self):
        result = Class.generate_class_schema(self.value, self.type)
        result['owned'] = True
        if self.exclude_properties:
            result['excludedProperties'] = self.exclude_properties
        return result
Beispiel #14
0
class Logger(object):
    """Logger object for MuranoPL.
    Instance of this object returned by 'logger' YAQL function
    and should not be instantiated directly
    """
    def __init__(self, logger_name):
        self._underlying_logger = logging.getLogger(
            NAME_TEMPLATE.format(logger_name))

    @specs.parameter('_Logger__message', yaqltypes.String())
    @inject_format
    def trace(__self, __yaql_format_function, __message, *args, **kwargs):
        __self._log(__self._underlying_logger.trace, __yaql_format_function,
                    __message, args, kwargs)

    @specs.parameter('_Logger__message', yaqltypes.String())
    @inject_format
    def debug(__self, __yaql_format_function, __message, *args, **kwargs):
        __self._log(__self._underlying_logger.debug, __yaql_format_function,
                    __message, args, kwargs)

    @specs.parameter('_Logger__message', yaqltypes.String())
    @inject_format
    def info(__self, __yaql_format_function, __message, *args, **kwargs):
        __self._log(__self._underlying_logger.info, __yaql_format_function,
                    __message, args, kwargs)

    @specs.parameter('_Logger__message', yaqltypes.String())
    @inject_format
    def warning(__self, __yaql_format_function, __message, *args, **kwargs):
        __self._log(__self._underlying_logger.warning, __yaql_format_function,
                    __message, args, kwargs)

    @specs.parameter('_Logger__message', yaqltypes.String())
    @inject_format
    def error(__self, __yaql_format_function, __message, *args, **kwargs):
        __self._log(__self._underlying_logger.error, __yaql_format_function,
                    __message, args, kwargs)

    @specs.parameter('_Logger__message', yaqltypes.String())
    @inject_format
    def critical(__self, __yaql_format_function, __message, *args, **kwargs):
        __self._log(__self._underlying_logger.critical, __yaql_format_function,
                    __message, args, kwargs)

    @specs.parameter('_Logger__message', yaqltypes.String())
    @inject_format
    def exception(__self, __yaql_format_function, __exc, __message, *args,
                  **kwargs):
        """Print error message and stacktrace"""
        stack_trace_message = u'\n'.join([
            __self._format_without_exceptions(__yaql_format_function,
                                              __message, args, kwargs),
            __exc['stackTrace']().toString()
        ])
        __self._underlying_logger.error(stack_trace_message)

    def _format_without_exceptions(self, format_function, message, args,
                                   kwargs):
        """Wrap YAQL function "format" to suppress exceptions
        whose may be raised when message cannot be formatted
        due to invalid parameters provided
        We do not want to break program workflow
        even formatting parameters are incorrect
        """
        try:
            message = format_function(message, *args, **kwargs)
        except (IndexError, KeyError):
            # NOTE(akhivin): we do not want break program workflow
            # even formatting parameters are incorrect
            self._underlying_logger.warning(
                u'Can not format string: {0}'.format(message))
        return message

    def _log(self, log_function, yaql_format_function, message, args, kwargs):
        log_function(
            self._format_without_exceptions(yaql_format_function, message,
                                            args, kwargs))
Beispiel #15
0

@specs.parameter('kwargs', yaqltypes.Lambda(with_context=True))
def with_original(context, **kwargs):
    new_context = context.create_child_context()

    original_context = context[constants.CTX_ORIGINAL_CONTEXT]
    for k, v in six.iteritems(kwargs):
        new_context['$' + k] = v(original_context)
    return new_context


@specs.parameter('target',
                 yaqltypes.AnyOf(dsl.MuranoTypeParameter(),
                                 dsl.MuranoObjectParameter()))
@specs.parameter('target_method', yaqltypes.String())
@specs.parameter('mock_object', dsl.MuranoObjectParameter())
@specs.parameter('mock_name', yaqltypes.String())
def inject_method_with_str(context, target, target_method, mock_object,
                           mock_name):
    ctx_manager = helpers.get_executor(context).context_manager

    current_class = helpers.get_type(context)
    mock_func = current_class.find_single_method(mock_name)
    original_class = target.type

    original_function = original_class.find_single_method(target_method)
    result_fd = original_function.instance_stub.clone()

    def payload_adapter(__context, __sender, *args, **kwargs):
        executor = helpers.get_executor(__context)
Beispiel #16
0
    def prepare_transform_context(root_context, this, owner, default,
                                  calling_type):
        @specs.parameter('value', nullable=True)
        @specs.method
        def int_(value):
            if value is dsl.NO_VALUE:
                value = default
            if value is None:
                return None
            try:
                return int(value)
            except Exception:
                raise exceptions.ContractViolationException(
                    'Value {0} violates int() contract'.format(
                        format_scalar(value)))

        @specs.parameter('value', nullable=True)
        @specs.method
        def string(value):
            if value is dsl.NO_VALUE:
                value = default
            if value is None:
                return None
            try:
                return six.text_type(value)
            except Exception:
                raise exceptions.ContractViolationException(
                    'Value {0} violates string() contract'.format(
                        format_scalar(value)))

        @specs.parameter('value', nullable=True)
        @specs.method
        def bool_(value):
            if value is dsl.NO_VALUE:
                value = default
            if value is None:
                return None
            return True if value else False

        @specs.parameter('value', nullable=True)
        @specs.method
        def not_null(value):
            if isinstance(value, TypeScheme.ObjRef):
                return value

            if value is None:
                raise exceptions.ContractViolationException(
                    'null value violates notNull() contract')
            return value

        @specs.parameter('value', nullable=True)
        @specs.method
        def error(value):
            raise exceptions.ContractViolationException('error() contract')

        @specs.parameter('value', nullable=True)
        @specs.parameter('predicate', yaqltypes.Lambda(with_context=True))
        @specs.parameter('msg', yaqltypes.String(nullable=True))
        @specs.method
        def check(value, predicate, msg=None):
            if isinstance(value, TypeScheme.ObjRef) or predicate(
                    root_context.create_child_context(), value):
                return value
            else:
                if not msg:
                    msg = "Value {0} doesn't match predicate".format(
                        format_scalar(value))
                raise exceptions.ContractViolationException(msg)

        @specs.parameter('obj', TypeScheme.ObjRef, nullable=True)
        @specs.name('owned')
        @specs.method
        def owned_ref(obj):
            if obj is None:
                return None
            if isinstance(obj, TypeScheme.ObjRef):
                return obj

        @specs.parameter('obj', dsl_types.MuranoObject)
        @specs.method
        def owned(obj):
            p = obj.owner
            while p is not None:
                if p is this:
                    return obj
                p = p.owner

            raise exceptions.ContractViolationException(
                'Object {0} violates owned() contract'.format(obj))

        @specs.parameter('obj', TypeScheme.ObjRef, nullable=True)
        @specs.name('not_owned')
        @specs.method
        def not_owned_ref(obj):
            if isinstance(obj, TypeScheme.ObjRef):
                return obj

            if obj is None:
                return None

        @specs.parameter('obj', dsl_types.MuranoObject)
        @specs.method
        def not_owned(obj):
            try:
                owned(obj)
            except exceptions.ContractViolationException:
                return obj
            else:
                raise exceptions.ContractViolationException(
                    'Object {0} violates notOwned() contract'.format(obj))

        @specs.parameter('name',
                         dsl.MuranoTypeParameter(nullable=False,
                                                 context=root_context))
        @specs.parameter('default_name',
                         dsl.MuranoTypeParameter(nullable=True,
                                                 context=root_context))
        @specs.parameter('value', nullable=True)
        @specs.parameter('version_spec', yaqltypes.String(True))
        @specs.method
        def class_(value, name, default_name=None, version_spec=None):
            object_store = helpers.get_object_store()
            if not default_name:
                default_name = name
            murano_class = name.type
            if isinstance(value, TypeScheme.ObjRef):
                value = value.object_id
            if value is None:
                return None
            if isinstance(value, dsl_types.MuranoObject):
                obj = value
            elif isinstance(value, dsl_types.MuranoObjectInterface):
                obj = value.object
            elif isinstance(value, utils.MappingType):
                obj = object_store.load(value,
                                        owner,
                                        context=root_context,
                                        default_type=default_name,
                                        scope_type=calling_type)
            elif isinstance(value, six.string_types):
                obj = object_store.get(value)
                if obj is None:
                    if not object_store.initializing:
                        raise exceptions.NoObjectFoundError(value)
                    else:
                        return TypeScheme.ObjRef(value)
            else:
                raise exceptions.ContractViolationException(
                    'Value {0} cannot be represented as class {1}'.format(
                        format_scalar(value), name))
            if not helpers.is_instance_of(
                    obj, murano_class.name, version_spec
                    or helpers.get_type(root_context)):
                raise exceptions.ContractViolationException(
                    'Object of type {0} is not compatible with '
                    'requested type {1}'.format(obj.type.name, murano_class))
            return obj

        @specs.parameter('type_',
                         dsl.MuranoTypeParameter(nullable=False,
                                                 context=root_context))
        @specs.parameter('default_type',
                         dsl.MuranoTypeParameter(nullable=True,
                                                 context=root_context))
        @specs.parameter('value', nullable=True)
        @specs.parameter('version_spec', yaqltypes.String(True))
        @specs.parameter('exclude_properties',
                         yaqltypes.Sequence(nullable=True))
        @specs.method
        def template(engine,
                     value,
                     type_,
                     exclude_properties=None,
                     default_type=None,
                     version_spec=None):
            object_store = helpers.get_object_store()
            passkey = None
            if not default_type:
                default_type = type_
            murano_class = type_.type
            if value is None:
                return None
            if isinstance(value, dsl_types.MuranoObject):
                obj = value
            elif isinstance(value, dsl_types.MuranoObjectInterface):
                obj = value.object
            elif isinstance(value, utils.MappingType):
                passkey = utils.create_marker('<Contract Passkey>')
                if exclude_properties:
                    parsed = helpers.parse_object_definition(
                        value, calling_type, context)
                    props = dsl.to_mutable(parsed['properties'], engine)
                    for p in exclude_properties:
                        helpers.patch_dict(props, p, passkey)
                    parsed['properties'] = props
                    value = helpers.assemble_object_definition(parsed)
                with helpers.thread_local_attribute(
                        constants.TL_CONTRACT_PASSKEY, passkey):
                    with helpers.thread_local_attribute(
                            constants.TL_OBJECTS_DRY_RUN, True):
                        obj = object_store.load(value,
                                                owner,
                                                context=context,
                                                default_type=default_type,
                                                scope_type=calling_type)
            else:
                raise exceptions.ContractViolationException(
                    'Value {0} cannot be represented as class {1}'.format(
                        format_scalar(value), type_))
            if not helpers.is_instance_of(
                    obj, murano_class.name, version_spec
                    or helpers.get_type(root_context)):
                raise exceptions.ContractViolationException(
                    'Object of type {0} is not compatible with '
                    'requested type {1}'.format(obj.type.name, type_))

            with helpers.thread_local_attribute(constants.TL_CONTRACT_PASSKEY,
                                                passkey):
                result = serializer.serialize(obj.real_this,
                                              object_store.executor,
                                              dsl_types.DumpTypes.Mixed)
                if exclude_properties:
                    for p in exclude_properties:
                        helpers.patch_dict(result, p, utils.NO_VALUE)
                return result

        context = root_context.create_child_context()
        context.register_function(int_)
        context.register_function(string)
        context.register_function(bool_)
        context.register_function(check)
        context.register_function(not_null)
        context.register_function(error)
        context.register_function(class_)
        context.register_function(template)
        context.register_function(owned_ref)
        context.register_function(owned)
        context.register_function(not_owned_ref)
        context.register_function(not_owned)
        return context
Beispiel #17
0
from muranodashboard.catalog import forms as catalog_forms
from muranodashboard.dynamic_ui import helpers


@specs.parameter('times', int)
def _repeat(context, template, times):
    for i in xrange(times):
        context['index'] = i + 1
        yield helpers.evaluate(template, context)


_random_string_counter = None


@specs.parameter('pattern', yaqltypes.String())
@specs.parameter('number', int)
def _generate_hostname(pattern, number):
    """Generates hostname based on pattern

    Replaces '#' char in pattern with supplied number, if no pattern is
    supplied generates short and unique name for the host.

    :param pattern: hostname pattern
    :param number: number to replace with in pattern
    :return: hostname
    """
    global _random_string_counter

    if pattern:
        # NOTE(kzaitsev) works both for unicode and simple strings in py2
Beispiel #18
0
    def prepare_transform_context(root_context, this, owner, default,
                                  calling_type):
        @specs.parameter('value', nullable=True)
        @specs.method
        def int_(value):
            if value is dsl.NO_VALUE:
                value = default
            if value is None:
                return None
            try:
                return int(value)
            except Exception:
                raise exceptions.ContractViolationException(
                    'Value {0} violates int() contract'.format(
                        format_scalar(value)))

        @specs.parameter('value', nullable=True)
        @specs.method
        def string(value):
            if value is dsl.NO_VALUE:
                value = default
            if value is None:
                return None
            try:
                return six.text_type(value)
            except Exception:
                raise exceptions.ContractViolationException(
                    'Value {0} violates string() contract'.format(
                        format_scalar(value)))

        @specs.parameter('value', nullable=True)
        @specs.method
        def bool_(value):
            if value is dsl.NO_VALUE:
                value = default
            if value is None:
                return None
            return True if value else False

        @specs.parameter('value', nullable=True)
        @specs.method
        def not_null(value):
            if isinstance(value, TypeScheme.ObjRef):
                return value

            if value is None:
                raise exceptions.ContractViolationException(
                    'null value violates notNull() contract')
            return value

        @specs.parameter('value', nullable=True)
        @specs.method
        def error(value):
            raise exceptions.ContractViolationException('error() contract')

        @specs.parameter('value', nullable=True)
        @specs.parameter('predicate', yaqltypes.Lambda(with_context=True))
        @specs.parameter('msg', yaqltypes.String(nullable=True))
        @specs.method
        def check(value, predicate, msg=None):
            if isinstance(value, TypeScheme.ObjRef) or predicate(
                    root_context.create_child_context(), value):
                return value
            else:
                if not msg:
                    msg = "Value {0} doesn't match predicate".format(
                        format_scalar(value))
                raise exceptions.ContractViolationException(msg)

        @specs.parameter('obj', TypeScheme.ObjRef, nullable=True)
        @specs.name('owned')
        @specs.method
        def owned_ref(obj):
            if obj is None:
                return None
            if isinstance(obj, TypeScheme.ObjRef):
                return obj

        @specs.parameter('obj', dsl_types.MuranoObject)
        @specs.method
        def owned(obj):
            p = obj.owner
            while p is not None:
                if p is this:
                    return obj
                p = p.owner

            raise exceptions.ContractViolationException(
                'Object {0} violates owned() contract'.format(obj))

        @specs.parameter('obj', TypeScheme.ObjRef, nullable=True)
        @specs.name('not_owned')
        @specs.method
        def not_owned_ref(obj):
            if isinstance(obj, TypeScheme.ObjRef):
                return obj

            if obj is None:
                return None

        @specs.parameter('obj', dsl_types.MuranoObject)
        @specs.method
        def not_owned(obj):
            try:
                owned(obj)
            except exceptions.ContractViolationException:
                return obj
            else:
                raise exceptions.ContractViolationException(
                    'Object {0} violates notOwned() contract'.format(obj))

        @specs.parameter('name', dsl.MuranoTypeParameter(
            nullable=False, context=root_context))
        @specs.parameter('default_name', dsl.MuranoTypeParameter(
            nullable=True, context=root_context))
        @specs.parameter('value', nullable=True)
        @specs.parameter('version_spec', yaqltypes.String(True))
        @specs.method
        def class_(value, name, default_name=None, version_spec=None):
            object_store = None if this is None else this.object_store
            if not default_name:
                default_name = name
            murano_class = name.type
            if value is None:
                return None
            if isinstance(value, dsl_types.MuranoObject):
                obj = value
            elif isinstance(value, dsl_types.MuranoObjectInterface):
                obj = value.object
            elif isinstance(value, utils.MappingType):
                obj = helpers.instantiate(
                    value, owner, object_store, root_context,
                    calling_type, default_name)
            elif isinstance(value, six.string_types) and object_store:
                obj = object_store.get(value)
                if obj is None:
                    if not object_store.initializing:
                        raise exceptions.NoObjectFoundError(value)
                    else:
                        return TypeScheme.ObjRef(value)
            else:
                raise exceptions.ContractViolationException(
                    'Value {0} cannot be represented as class {1}'.format(
                        format_scalar(value), name))
            if not helpers.is_instance_of(
                    obj, murano_class.name,
                    version_spec or helpers.get_type(root_context)):
                raise exceptions.ContractViolationException(
                    'Object of type {0} is not compatible with '
                    'requested type {1}'.format(obj.type.name, name))
            return obj

        context = root_context.create_child_context()
        context.register_function(int_)
        context.register_function(string)
        context.register_function(bool_)
        context.register_function(check)
        context.register_function(not_null)
        context.register_function(error)
        context.register_function(class_)
        context.register_function(owned_ref)
        context.register_function(owned)
        context.register_function(not_owned_ref)
        context.register_function(not_owned)
        return context
class GarbageCollector(object):
    @staticmethod
    @specs.parameter('publisher', dsl.MuranoObjectParameter(decorate=False))
    @specs.parameter('subscriber', dsl.MuranoObjectParameter(decorate=False))
    @specs.parameter('handler', yaqltypes.String(nullable=True))
    def subscribe_destruction(publisher, subscriber, handler=None):
        publisher_this = publisher.real_this
        subscriber_this = subscriber.real_this

        if handler:
            subscriber.type.find_single_method(handler)

        dependency = GarbageCollector._find_dependency(
            publisher_this, subscriber_this, handler)

        if not dependency:
            dependency = {'subscriber': helpers.weak_ref(subscriber_this),
                          'handler': handler}
            publisher_this.destruction_dependencies.append(dependency)

    @staticmethod
    @specs.parameter('publisher', dsl.MuranoObjectParameter(decorate=False))
    @specs.parameter('subscriber', dsl.MuranoObjectParameter(decorate=False))
    @specs.parameter('handler', yaqltypes.String(nullable=True))
    def unsubscribe_destruction(publisher, subscriber, handler=None):
        publisher_this = publisher.real_this
        subscriber_this = subscriber.real_this

        if handler:
            subscriber.type.find_single_method(handler)

        dds = publisher_this.destruction_dependencies
        dependency = GarbageCollector._find_dependency(
            publisher_this, subscriber_this, handler)

        if dependency:
            dds.remove(dependency)

    @staticmethod
    def _find_dependency(publisher, subscriber, handler):
        dds = publisher.destruction_dependencies
        for dd in dds:
            if dd['handler'] != handler:
                continue
            d_subscriber = dd['subscriber']
            if d_subscriber:
                d_subscriber = d_subscriber()
            if d_subscriber == subscriber:
                return dd

    @staticmethod
    def collect():
        helpers.get_executor().object_store.cleanup()

    @staticmethod
    @specs.parameter('object_', dsl.MuranoObjectParameter(decorate=False))
    def is_doomed(object_):
        return helpers.get_object_store().is_doomed(object_)

    @staticmethod
    @specs.parameter('object_', dsl.MuranoObjectParameter(decorate=False))
    def is_destroyed(object_):
        return object_.destroyed
Beispiel #20
0
import jsonpatch
import jsonpointer
from yaql.language import specs
from yaql.language import utils
from yaql.language import yaqltypes

from murano.common import config as cfg
from murano.dsl import constants
from murano.dsl import dsl
from murano.dsl import helpers
from murano.dsl import yaql_integration

_random_string_counter = None


@specs.parameter('value', yaqltypes.String())
@specs.extension_method
def base64encode(value):
    return base64.b64encode(value)


@specs.parameter('value', yaqltypes.String())
@specs.extension_method
def base64decode(value):
    return base64.b64decode(value)


@specs.parameter('collection', yaqltypes.Iterable())
@specs.parameter('composer', yaqltypes.Lambda())
@specs.extension_method
def pselect(collection, composer):
Beispiel #21
0
class Class(contracts.ContractMethod):
    name = 'class'

    @specs.parameter('name', dsl.MuranoTypeParameter(nullable=False,
                                                     lazy=True))
    @specs.parameter('default_name',
                     dsl.MuranoTypeParameter(nullable=True, lazy=True))
    @specs.parameter('version_spec', yaqltypes.String(True))
    def __init__(self, name, default_name=None, version_spec=None):
        self.type = name(self.context).type
        self.default_type = default_name(self.context) or self.type
        self.version_spec = version_spec

    def validate(self):
        if self.value is None or helpers.is_instance_of(
                self.value, self.type.name, self.version_spec
                or helpers.get_names_scope(self.root_context)):
            return self.value
        if not isinstance(
                self.value,
            (dsl_types.MuranoObject, dsl_types.MuranoObjectInterface)):
            raise exceptions.ContractViolationException(
                'Value is not an object')
        raise exceptions.ContractViolationException(
            'Object of type {0} is not compatible with '
            'requested type {1}'.format(self.value.type, self.type))

    def transform(self):
        value = self.value
        object_store = helpers.get_object_store()
        if isinstance(self.value, contracts.ObjRef):
            value = self.value.object_id
        if value is None:
            return None
        if isinstance(value, dsl_types.MuranoObject):
            obj = value
        elif isinstance(value, dsl_types.MuranoObjectInterface):
            obj = value.object
        elif isinstance(value, utils.MappingType):
            obj = object_store.load(value,
                                    self.owner,
                                    context=self.root_context,
                                    default_type=self.default_type,
                                    scope_type=self.calling_type)
        elif isinstance(value, str):
            obj = object_store.get(value)
            if obj is None:
                if not object_store.initializing:
                    raise exceptions.NoObjectFoundError(value)
                else:
                    return contracts.ObjRef(value)
        else:
            raise exceptions.ContractViolationException(
                'Value {0} cannot be represented as class {1}'.format(
                    helpers.format_scalar(value), self.type))
        self.value = obj
        return self.validate()

    def generate_schema(self):
        return self.generate_class_schema(self.value, self.type)

    @staticmethod
    def generate_class_schema(value, type_):
        types = 'muranoObject'
        if '_notNull' not in value:
            types = [types] + ['null']

        return {'type': types, 'muranoType': type_.name}
Beispiel #22
0
from oslo_log import log as logging

LOG = logging.getLogger(__name__)


@specs.parameter('times', int)
def _repeat(context, template, times):
    for i in range(times):
        context['index'] = i + 1
        yield helpers.evaluate(template, context)


_random_string_counter = None


@specs.parameter('pattern', yaqltypes.String())
@specs.parameter('number', int)
def _generate_hostname(pattern, number):
    """Generates hostname based on pattern

    Replaces '#' char in pattern with supplied number, if no pattern is
    supplied generates short and unique name for the host.

    :param pattern: hostname pattern
    :param number: number to replace with in pattern
    :return: hostname
    """
    global _random_string_counter

    if pattern:
        # NOTE(kzaitsev) works both for unicode and simple strings in py2
Beispiel #23
0
    def prepare_context(root_context, this, owner, default):
        @specs.parameter('value', nullable=True)
        @specs.method
        def int_(value):
            if value is dsl.NO_VALUE:
                value = default
            if value is None:
                return None
            try:
                return int(value)
            except Exception:
                raise exceptions.ContractViolationException(
                    'Value {0} violates int() contract'.format(value))

        @specs.parameter('value', nullable=True)
        @specs.method
        def string(value):
            if value is dsl.NO_VALUE:
                value = default
            if value is None:
                return None
            try:
                return unicode(value)
            except Exception:
                raise exceptions.ContractViolationException(
                    'Value {0} violates string() contract'.format(value))

        @specs.parameter('value', nullable=True)
        @specs.method
        def bool_(value):
            if value is dsl.NO_VALUE:
                value = default
            if value is None:
                return None
            return True if value else False

        @specs.parameter('value', nullable=True)
        @specs.method
        def not_null(value):
            if isinstance(value, TypeScheme.ObjRef):
                return value

            if value is None:
                raise exceptions.ContractViolationException(
                    'null value violates notNull() contract')
            return value

        @specs.parameter('value', nullable=True)
        @specs.method
        def error(value):
            raise exceptions.ContractViolationException('error() contract')

        @specs.parameter('value', nullable=True)
        @specs.parameter('predicate', yaqltypes.Lambda(with_context=True))
        @specs.method
        def check(value, predicate):
            if isinstance(value, TypeScheme.ObjRef) or predicate(
                    root_context.create_child_context(), value):
                return value
            else:
                raise exceptions.ContractViolationException(
                    "Value {0} doesn't match predicate".format(value))

        @specs.parameter('obj', TypeScheme.ObjRef, nullable=True)
        @specs.name('owned')
        @specs.method
        def owned_ref(obj):
            if obj is None:
                return None
            if isinstance(obj, TypeScheme.ObjRef):
                return obj

        @specs.parameter('obj', dsl_types.MuranoObject)
        @specs.method
        def owned(obj):
            p = obj.owner
            while p is not None:
                if p is this:
                    return obj
                p = p.owner

            raise exceptions.ContractViolationException(
                'Object {0} violates owned() contract'.format(obj.object_id))

        @specs.parameter('obj', TypeScheme.ObjRef, nullable=True)
        @specs.name('not_owned')
        @specs.method
        def not_owned_ref(obj):
            if isinstance(obj, TypeScheme.ObjRef):
                return obj

            if obj is None:
                return None

        @specs.parameter('obj', dsl_types.MuranoObject)
        @specs.method
        def not_owned(obj):
            try:
                owned(obj)
            except exceptions.ContractViolationException:
                return obj
            else:
                raise exceptions.ContractViolationException(
                    'Object {0} violates notOwned() contract'.format(
                        obj.object_id))

        @specs.parameter('name', dsl.MuranoTypeName(False, root_context))
        @specs.parameter('default_name',
                         dsl.MuranoTypeName(True, root_context))
        @specs.parameter('value', nullable=True)
        @specs.parameter('version_spec', yaqltypes.String(True))
        @specs.method
        def class_(value, name, default_name=None, version_spec=None):
            object_store = this.object_store
            if not default_name:
                default_name = name
            murano_class = name.murano_class
            if value is None:
                return None
            if isinstance(value, dsl_types.MuranoObject):
                obj = value
            elif isinstance(value, dsl_types.MuranoObjectInterface):
                obj = value.object
            elif isinstance(value, utils.MappingType):
                if '?' not in value:
                    new_value = {
                        '?': {
                            'id': uuid.uuid4().hex,
                            'type': default_name.murano_class.name,
                            'classVersion':
                            str(default_name.murano_class.version)
                        }
                    }
                    new_value.update(value)
                    value = new_value

                obj = object_store.load(value,
                                        owner,
                                        root_context,
                                        defaults=default)
            elif isinstance(value, types.StringTypes):
                obj = object_store.get(value)
                if obj is None:
                    if not object_store.initializing:
                        raise exceptions.NoObjectFoundError(value)
                    else:
                        return TypeScheme.ObjRef(value)
            else:
                raise exceptions.ContractViolationException(
                    'Value {0} cannot be represented as class {1}'.format(
                        value, name))
            if not helpers.is_instance_of(
                    obj, murano_class.name, version_spec
                    or helpers.get_type(root_context)):
                raise exceptions.ContractViolationException(
                    'Object of type {0} is not compatible with '
                    'requested type {1}'.format(obj.type.name, name))
            return obj

        context = root_context.create_child_context()
        context.register_function(int_)
        context.register_function(string)
        context.register_function(bool_)
        context.register_function(check)
        context.register_function(not_null)
        context.register_function(error)
        context.register_function(class_)
        context.register_function(owned_ref)
        context.register_function(owned)
        context.register_function(not_owned_ref)
        context.register_function(not_owned)
        return context