def new(__context, __type_name, __owner=None, __object_name=None, __extra=None, **parameters): object_store = helpers.get_object_store(__context) new_context = __context.create_child_context() for key, value in parameters.iteritems(): if helpers.is_keyword(key): new_context[key] = value return __type_name.murano_class.new(__owner, object_store, name=__object_name)(new_context, **parameters)
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 __init__(self, definition, target, scope_type): scope_type = weakref.ref(scope_type) definition = helpers.list_value(definition) factories = [] used_types = set() for d in definition: if isinstance(d, dict): if len(d) != 1: raise ValueError('Invalid Meta format') name = next(iter(d.keys())) props = d[name] or {} else: name = d props = {} type_obj = helpers.resolve_type(name, scope_type()) if type_obj.usage != dsl_types.ClassUsages.Meta: raise ValueError('Only Meta classes can be attached') if target not in type_obj.targets: raise ValueError( u'Meta class {} is not applicable here'.format( type_obj.name)) if type_obj in used_types and ( type_obj.cardinality != dsl_types.MetaCardinality.Many): raise ValueError('Cannot attach several Meta instances ' 'with cardinality One') used_types.add(type_obj) factory_maker = lambda template: \ lambda context: helpers.get_object_store().load( template, owner=None, context=context, scope_type=scope_type()) factories.append(factory_maker({type_obj: props})) self._meta_factories = factories self._meta = None
def instantiate(context): obj = helpers.get_object_store().load( template, owner=None, context=context, scope_type=declaring_type) obj.declaring_type = declaring_type return obj
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
def spawn(func, *args, **kwargs): context = helpers.get_context() object_store = helpers.get_object_store() def wrapper(): with helpers.with_object_store(object_store): with helpers.contextual(context): return func(*args, **kwargs) return eventlet.spawn(wrapper)
def new(__context, __type_name, __owner=None, __object_name=None, __extra=None, **parameters): object_store = helpers.get_object_store(__context) executor = helpers.get_executor(__context) new_context = __context.create_child_context() for key, value in six.iteritems(parameters): if utils.is_keyword(key): new_context[key] = value return __type_name.type.new( __owner, object_store, executor, name=__object_name)( new_context, **parameters)
def load_dependencies(self, dependencies): self._destruction_dependencies = [] if not dependencies: return destruction_dependencies = dependencies.get('onDestruction', []) object_store = helpers.get_object_store() for record in destruction_dependencies: subscriber_id = record['subscriber'] subscriber = object_store.get(subscriber_id) if not subscriber: continue garbage_collector.GarbageCollector.subscribe_destruction( self, subscriber, record.get('handler'))
def new(__context, __type_name, __owner=None, __object_name=None, __extra=None, **parameters): data = { __type_name: parameters, 'name': __object_name } for key, value in six.iteritems(__extra or {}): if key.startswith('_'): data[key] = value object_store = helpers.get_object_store() return object_store.load(data, __owner, context=__context, scope_type=helpers.get_names_scope(__context))
def finalize(self): if self.value is None: return None object_store = helpers.get_object_store() 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 _push(self, object_store=None): template = copy.deepcopy(self._template) s_template = token_sanitizer.TokenSanitizer().sanitize(template) LOG.debug( 'Pushing: {template}'.format(template=json.dumps(s_template))) object_store = object_store or helpers.get_object_store() while True: try: with helpers.with_object_store(object_store): current_status = self._get_status() resources = template.get('Resources') or template.get( 'resources') if current_status == 'NOT_FOUND': if resources is not None: token_client = self._get_token_client() token_client.stacks.create( stack_name=self._name, parameters=self._parameters, template=template, files=self._files, environment=self._hot_environment, disable_rollback=True, tags=self._tags) self._wait_state( lambda status: status == 'CREATE_COMPLETE') else: if resources is not None: self._client.stacks.update( stack_id=self._name, parameters=self._parameters, files=self._files, environment=self._hot_environment, template=template, disable_rollback=True, tags=self._tags) self._wait_state( lambda status: status == 'UPDATE_COMPLETE', True) else: self.delete() except heat_exc.HTTPConflict as e: LOG.warning('Conflicting operation: {msg}'.format(msg=e)) eventlet.sleep(3) else: break self._applied = self._template == template
def new(__context, __type_name, __owner=None, __object_name=None, __extra=None, **parameters): data = {__type_name: parameters, 'name': __object_name} for key, value in (__extra or {}).items(): if key.startswith('_'): data[key] = value object_store = helpers.get_object_store() return object_store.load(data, __owner, context=__context, scope_type=helpers.get_names_scope(__context))
def _new(context, name, *args): murano_class = helpers.get_type(context) name = murano_class.namespace_resolver.resolve_name(name) parameters = {} arg_values = [t() for t in args] if len(arg_values) == 1 and isinstance(arg_values[0], types.DictionaryType): parameters = arg_values[0] elif len(arg_values) > 0: for p in arg_values: if not isinstance(p, types.TupleType) or not isinstance(p[0], types.StringType): raise SyntaxError() parameters[p[0]] = p[1] object_store = helpers.get_object_store(context) class_loader = helpers.get_class_loader(context) new_context = yaql.context.Context(parent_context=context) for key, value in parameters.iteritems(): new_context.set_data(value, key) return class_loader.get_class(name).new(None, object_store, new_context, parameters=parameters)
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
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 _new(context, name, *args): murano_class = helpers.get_type(context) name = murano_class.namespace_resolver.resolve_name(name) parameters = {} arg_values = [t() for t in args] if len(arg_values) == 1 and isinstance(arg_values[0], types.DictionaryType): parameters = arg_values[0] elif len(arg_values) > 0: for p in arg_values: if not isinstance(p, types.TupleType) or \ not isinstance(p[0], types.StringType): raise SyntaxError() parameters[p[0]] = p[1] object_store = helpers.get_object_store(context) class_loader = helpers.get_class_loader(context) new_context = yaql.context.Context(parent_context=context) for key, value in parameters.iteritems(): new_context.set_data(value, key) return class_loader.get_class(name).new(None, object_store, new_context, parameters=parameters)
def __init__(self, mpl_object, object_store=None): self.__object = mpl_object self.__object_store = object_store or helpers.get_object_store()
def new(properties, owner=None, type=None): context = helpers.get_context() return helpers.get_object_store().load( properties, owner, type or get_this(context).type, context=context)
def initialize(self, context, params): if self.__initialized: return context = context.create_child_context() context[constants.CTX_ALLOW_PROPERTY_WRITES] = True object_store = helpers.get_object_store() for property_name in self.__type.properties: spec = self.__type.properties[property_name] if spec.usage == dsl_types.PropertyUsages.Config: if property_name in self.__config: property_value = self.__config[property_name] else: property_value = dsl.NO_VALUE self.set_property(property_name, property_value) init = self.type.methods.get('.init') used_names = set() names = set(self.__type.properties) if init: names.update(six.iterkeys(init.arguments_scheme)) last_errors = len(names) init_args = {} while True: errors = 0 for property_name in names: if init and property_name in init.arguments_scheme: spec = init.arguments_scheme[property_name] is_init_arg = True else: spec = self.__type.properties[property_name] is_init_arg = False if property_name in used_names: continue if spec.usage in (dsl_types.PropertyUsages.Config, dsl_types.PropertyUsages.Static): used_names.add(property_name) continue if spec.usage == dsl_types.PropertyUsages.Runtime: if not spec.has_default: used_names.add(property_name) continue property_value = dsl.NO_VALUE else: property_value = params.get(property_name, dsl.NO_VALUE) try: if is_init_arg: init_args[property_name] = property_value else: self.set_property( property_name, property_value, context) used_names.add(property_name) except exceptions.UninitializedPropertyAccessError: errors += 1 except exceptions.ContractViolationException: if spec.usage != dsl_types.PropertyUsages.Runtime: raise if not errors: break if errors >= last_errors: raise exceptions.CircularExpressionDependenciesError() last_errors = errors if ((object_store is None or not object_store.initializing) and self.__extension is None): method = self.type.methods.get('__init__') if method: filtered_params = yaql_integration.filter_parameters( method.body, **params) self.__extension = method.invoke( self, filtered_params[0], filtered_params[1], context) for parent in self.__parents.values(): parent.initialize(context, params) if not object_store.initializing and init: context[constants.CTX_ARGUMENT_OWNER] = self.real_this init.invoke(self.real_this, (), init_args, context.create_child_context()) self.__initialized = True
def __init__(self, mpl_object): self._object = mpl_object self._object_store = helpers.get_object_store()
def new_from_model(context, model, owner=None): object_store = helpers.get_object_store() return object_store.load(model, owner, context=context, scope_type=helpers.get_names_scope(context))
def is_doomed(object_): return helpers.get_object_store().is_doomed(object_)
def initialize(self, context, params, used_names=None): context = context.create_child_context() context[constants.CTX_ALLOW_PROPERTY_WRITES] = True object_store = helpers.get_object_store() for property_name in self.type.properties: spec = self.type.properties[property_name] if spec.usage == dsl_types.PropertyUsages.Config: if property_name in self._config: property_value = self._config[property_name] else: property_value = dsl.NO_VALUE self.set_property(property_name, property_value, dry_run=self._initialized) init = self.type.methods.get('.init') used_names = used_names or set() names = set(self.type.properties) if init: names.update(init.arguments_scheme.keys()) last_errors = len(names) init_args = {} while True: errors = 0 for property_name in names: if init and property_name in init.arguments_scheme: spec = init.arguments_scheme[property_name] is_init_arg = True else: spec = self.type.properties[property_name] is_init_arg = False if property_name in used_names: continue if spec.usage in (dsl_types.PropertyUsages.Config, dsl_types.PropertyUsages.Static): used_names.add(property_name) continue if spec.usage == dsl_types.PropertyUsages.Runtime: if not spec.has_default: used_names.add(property_name) continue property_value = dsl.NO_VALUE else: property_value = params.get(property_name, dsl.NO_VALUE) try: if is_init_arg: init_args[property_name] = property_value else: self.set_property(property_name, property_value, context, dry_run=self._initialized) used_names.add(property_name) except exceptions.UninitializedPropertyAccessError: errors += 1 except exceptions.ContractViolationException: if spec.usage != dsl_types.PropertyUsages.Runtime: raise if not errors: break if errors >= last_errors: raise exceptions.CircularExpressionDependenciesError() last_errors = errors if (not object_store.initializing and self._extension is None and not self._initialized and not self._destroyed and not helpers.is_objects_dry_run_mode()): method = self.type.methods.get('__init__') if method: filtered_params = yaql_integration.filter_parameters( method.body, **params) yield lambda: method.invoke(self, filtered_params[0], filtered_params[1], context) for parent in self._parents.values(): for t in parent.initialize(context, params, used_names): yield t def run_init(): if init: context[constants.CTX_ARGUMENT_OWNER] = self.real_this init.invoke(self.real_this, (), init_args, context.create_child_context()) self._initialized = True if (not object_store.initializing and not helpers.is_objects_dry_run_mode() and not self._initialized and not self._destroyed): yield run_init
class HeatStack(object): def __init__(self, name, description=None, region_name=None): self._name = name self._template = None self._parameters = {} self._files = {} self._hot_environment = '' self._applied = True self._description = description self._last_stack_timestamps = (None, None) self._tags = '' self._region_name = region_name self._push_thread = None def _is_push_thread_alive(self): return self._push_thread is not None and not self._push_thread.dead def _kill_push_thread(self): if self._is_push_thread_alive(): self._push_thread.cancel() self._wait_push_thread() def _wait_push_thread(self): if not self._is_push_thread_alive(): return self._push_thread.wait() @staticmethod def _create_client(session, region_name): parameters = auth_utils.get_session_client_parameters( service_type='orchestration', region=region_name, conf=CONF.heat, session=session) return hclient.Client('1', **parameters) @property def _client(self): return self._get_client(self._region_name) @staticmethod @session_local_storage.execution_session_memoize def _get_client(region_name): session = auth_utils.get_client_session(conf=CONF.heat) return HeatStack._create_client(session, region_name) def _get_token_client(self): ks_session = auth_utils.get_token_client_session(conf=CONF.heat) return self._create_client(ks_session, self._region_name) def current(self): if self._template is not None: return self._template try: stack_info = self._client.stacks.get(stack_id=self._name) template = self._client.stacks.template(stack_id='{0}/{1}'.format( stack_info.stack_name, stack_info.id)) self._template = template self._parameters.update( HeatStack._remove_system_params(stack_info.parameters)) self._applied = True return self._template.copy() except heat_exc.HTTPNotFound: self._applied = True self._template = {} self._parameters.clear() return {} def parameters(self): self.current() return self._parameters.copy() def reload(self): self._template = None self._parameters.clear() return self.current() def set_template(self, template): self._template = template self._parameters.clear() self._applied = False def set_parameters(self, parameters): self._parameters = parameters self._applied = False def set_files(self, files): self._files = files self._applied = False def set_hot_environment(self, hot_environment): self._hot_environment = hot_environment self._applied = False def update_template(self, template): template_version = template.get('heat_template_version', HEAT_TEMPLATE_VERSION) if template_version != HEAT_TEMPLATE_VERSION: err_msg = ("Currently only heat_template_version %s " "is supported." % HEAT_TEMPLATE_VERSION) raise HeatStackError(err_msg) current = self.current() self._template = helpers.merge_dicts(self._template, template) self._applied = self._template == current and self._applied @staticmethod def _remove_system_params(parameters): return dict((k, v) for k, v in six.iteritems(parameters) if not k.startswith('OS::')) def _get_status(self): status = [None] def status_func(state_value): status[0] = state_value return True self._wait_state(status_func) return status[0] def _wait_state(self, status_func, wait_progress=False): tries = 4 delay = 1 while tries > 0: while True: try: stack_info = self._client.stacks.get(stack_id=self._name) status = stack_info.stack_status tries = 4 delay = 1 except heat_exc.HTTPNotFound: stack_info = None status = 'NOT_FOUND' except Exception: tries -= 1 delay *= 2 if not tries: raise eventlet.sleep(delay) break if 'IN_PROGRESS' in status: eventlet.sleep(2) continue last_stack_timestamps = self._last_stack_timestamps self._last_stack_timestamps = (None, None) if not stack_info \ else(stack_info.creation_time, stack_info.updated_time) if (wait_progress and last_stack_timestamps == self._last_stack_timestamps and last_stack_timestamps != (None, None)): eventlet.sleep(2) continue if not status_func(status): reason = ': {0}'.format( stack_info.stack_status_reason) if stack_info else '' raise EnvironmentError( "Unexpected stack state {0}{1}".format(status, reason)) try: return dict([(t['output_key'], t['output_value']) for t in stack_info.outputs]) except Exception: return {} return {} def output(self): self._wait_push_thread() return self._wait_state(lambda status: True) def _push(self, object_store=None): template = copy.deepcopy(self._template) LOG.debug('Pushing: {template}'.format(template=json.dumps(template))) object_store = object_store or helpers.get_object_store() while True: try: with helpers.with_object_store(object_store): current_status = self._get_status() resources = template.get('Resources') or template.get( 'resources') if current_status == 'NOT_FOUND': if resources is not None: token_client = self._get_token_client() token_client.stacks.create( stack_name=self._name, parameters=self._parameters, template=template, files=self._files, environment=self._hot_environment, disable_rollback=True, tags=self._tags) self._wait_state( lambda status: status == 'CREATE_COMPLETE') else: if resources is not None: self._client.stacks.update( stack_id=self._name, parameters=self._parameters, files=self._files, environment=self._hot_environment, template=template, disable_rollback=True, tags=self._tags) self._wait_state( lambda status: status == 'UPDATE_COMPLETE', True) else: self.delete() except heat_exc.HTTPConflict as e: LOG.warning('Conflicting operation: {msg}'.format(msg=e)) eventlet.sleep(3) else: break self._applied = self._template == template def push(self, async=False): if self._applied or self._template is None: return self._tags = ','.join(CONF.heat.stack_tags) if 'heat_template_version' not in self._template: self._template['heat_template_version'] = HEAT_TEMPLATE_VERSION if 'description' not in self._template and self._description: self._template['description'] = self._description self._kill_push_thread() if async: if self._push_thread is None: def cleanup(): try: self._wait_push_thread() finally: self._push_thread = None dsl.get_execution_session().on_session_finish(cleanup) self._push_thread =\ eventlet.greenthread.spawn_after( 1, self._push, helpers.get_object_store()) else: self._push()