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)
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
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))
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))
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
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
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):
# 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
: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
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)
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,
# 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
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
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))
@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)
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
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
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
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):
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}
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
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