class SoftwareDeployment(base.VersionedObject, base.VersionedObjectDictCompat, base.ComparableVersionedObject): fields = { 'id': fields.StringField(), 'config_id': fields.StringField(), 'server_id': fields.StringField(), 'input_values': heat_fields.JsonField(nullable=True), 'output_values': heat_fields.JsonField(nullable=True), 'tenant': fields.StringField(), 'stack_user_project_id': fields.StringField(nullable=True), 'action': fields.StringField(nullable=True), 'status': fields.StringField(nullable=True), 'status_reason': fields.StringField(nullable=True), 'config': fields.ObjectField('SoftwareConfig'), 'created_at': fields.DateTimeField(read_only=True), 'updated_at': fields.DateTimeField(nullable=True), } @staticmethod def _from_db_object(context, deployment, db_deployment): for field in deployment.fields: if field == 'config': deployment[field] = ( software_config.SoftwareConfig._from_db_object( context, software_config.SoftwareConfig(), db_deployment['config'])) else: deployment[field] = db_deployment[field] deployment._context = context deployment.obj_reset_changes() return deployment @classmethod def create(cls, context, values): return cls._from_db_object( context, cls(), db_api.software_deployment_create(context, values)) @classmethod def get_by_id(cls, context, deployment_id): return cls._from_db_object( context, cls(), db_api.software_deployment_get(context, deployment_id)) @classmethod def get_all(cls, context, server_id=None): return [ cls._from_db_object(context, cls(), db_deployment) for db_deployment in db_api.software_deployment_get_all( context, server_id) ] @classmethod def update_by_id(cls, context, deployment_id, values): return cls._from_db_object( context, cls(), db_api.software_deployment_update(context, deployment_id, values)) @classmethod def delete(cls, context, deployment_id): db_api.software_deployment_delete(context, deployment_id)
class RawTemplate( base.VersionedObject, base.VersionedObjectDictCompat, base.ComparableVersionedObject, ): fields = { 'id': fields.StringField(), 'files': heat_fields.JsonField(nullable=True), 'template': heat_fields.JsonField(), 'environment': heat_fields.JsonField(), 'predecessor': fields.IntegerField(), } @staticmethod def _from_db_object(context, tpl, db_tpl): for field in tpl.fields: tpl[field] = db_tpl[field] tpl._context = context tpl.obj_reset_changes() return tpl @classmethod def get_by_id(cls, context, template_id): raw_template_db = db_api.raw_template_get(context, template_id) raw_template = cls._from_db_object(context, cls(), raw_template_db) return raw_template @classmethod def create(cls, context, values): return db_api.raw_template_create(context, values) @classmethod def update_by_id(cls, context, template_id, values): return db_api.raw_template_update(context, template_id, values)
class RawTemplateFiles( heat_base.HeatObject, base.VersionedObjectDictCompat, base.ComparableVersionedObject, ): # Version 1.0: Initial Version VERSION = '1.0' fields = { 'id': fields.IntegerField(), 'files': heat_fields.JsonField(read_only=True), } @staticmethod def _from_db_object(context, tmpl_files, db_tmpl_files): for field in tmpl_files.fields: tmpl_files[field] = db_tmpl_files[field] tmpl_files._context = context tmpl_files.obj_reset_changes() return tmpl_files @classmethod def create(cls, context, values): return cls._from_db_object(context, cls(), db_api.raw_template_files_create(context, values))
class Event(base.VersionedObject, base.VersionedObjectDictCompat): fields = { 'id': fields.IntegerField(), 'stack_id': fields.StringField(), 'uuid': fields.StringField(), 'resource_action': fields.StringField(nullable=True), 'resource_status': fields.StringField(nullable=True), 'resource_name': fields.StringField(nullable=True), 'physical_resource_id': fields.StringField(nullable=True), 'resource_status_reason': fields.StringField(nullable=True), 'resource_type': fields.StringField(nullable=True), 'resource_properties': heat_fields.JsonField(nullable=True), 'created_at': fields.DateTimeField(read_only=True), 'updated_at': fields.DateTimeField(nullable=True), } @staticmethod def _from_db_object(context, event, db_event): for field in event.fields: event[field] = db_event[field] event._context = context event.obj_reset_changes() return event @classmethod def get_by_id(cls, context, event_id): db_event = db_api.event_get(context, event_id) return cls._from_db_object(context, cls(context), db_event) @classmethod def get_all(cls, context): return [ cls._from_db_object(context, cls(), db_event) for db_event in db_api.event_get_all(context) ] @classmethod def get_all_by_tenant(cls, context, **kwargs): return [ cls._from_db_object(context, cls(), db_event) for db_event in db_api.event_get_all_by_tenant(context, **kwargs) ] @classmethod def get_all_by_stack(cls, context, stack_id, **kwargs): return [ cls._from_db_object(context, cls(), db_event) for db_event in db_api.event_get_all_by_stack( context, stack_id, **kwargs) ] @classmethod def count_all_by_stack(cls, context, stack_id): return db_api.event_count_all_by_stack(context, stack_id) @classmethod def create(cls, context, values): return cls._from_db_object(context, cls(), db_api.event_create(context, values))
class ResourcePropertiesData( base.VersionedObject, base.VersionedObjectDictCompat, base.ComparableVersionedObject, ): fields = { 'id': fields.IntegerField(), 'data': heat_fields.JsonField(nullable=True), 'created_at': fields.DateTimeField(read_only=True), 'updated_at': fields.DateTimeField(nullable=True), } @staticmethod def _from_db_object(rpd, context, db_rpd, data_unencrypted=None): # The data_unencrypted field allows us to avoid an extra # decrypt operation, e.g. when called from create(). for field in rpd.fields: rpd[field] = db_rpd[field] if data_unencrypted: # save a little (decryption) processing rpd['data'] = data_unencrypted elif db_rpd['encrypted'] and rpd['data'] is not None: rpd['data'] = crypt.decrypted_dict(rpd['data']) # TODO(cwolfe) setting the context here should go away, that # should have been done with the initialisation of the rpd # object. For now, maintaining consistency with other # _from_db_object methods. rpd._context = context rpd.obj_reset_changes() return rpd @classmethod def create(cls, context, data): properties_data_encrypted, properties_data = \ ResourcePropertiesData.encrypt_properties_data(data) values = { 'encrypted': properties_data_encrypted, 'data': properties_data } db_obj = db_api.resource_prop_data_create(context, values) return cls._from_db_object(cls(), context, db_obj, data) @staticmethod def encrypt_properties_data(data): if cfg.CONF.encrypt_parameters_and_properties and data: result = {} for prop_name, prop_value in data.items(): prop_string = jsonutils.dumps(prop_value) encrypted_value = crypt.encrypt(prop_string) result[prop_name] = encrypted_value return (True, result) return (False, data) @staticmethod def get_by_id(context, id): db_ref = db_api.resource_prop_data_get(context, id) return ResourcePropertiesData._from_db_object( ResourcePropertiesData(context=context), context, db_ref)
class Snapshot( heat_base.HeatObject, base.VersionedObjectDictCompat, base.ComparableVersionedObject, ): fields = { 'id': fields.StringField(), 'name': fields.StringField(nullable=True), 'stack_id': fields.StringField(), 'data': heat_fields.JsonField(nullable=True), 'tenant': fields.StringField(), 'status': fields.StringField(nullable=True), 'status_reason': fields.StringField(nullable=True), 'created_at': fields.DateTimeField(read_only=True), 'updated_at': fields.DateTimeField(nullable=True), } @staticmethod def _from_db_object(context, snapshot, db_snapshot): for field in snapshot.fields: snapshot[field] = db_snapshot[field] snapshot._context = context snapshot.obj_reset_changes() return snapshot @classmethod def create(cls, context, values): return cls._from_db_object(context, cls(), db_api.snapshot_create(context, values)) @classmethod def get_snapshot_by_stack(cls, context, snapshot_id, stack): return cls._from_db_object( context, cls(), db_api.snapshot_get_by_stack(context, snapshot_id, stack)) @classmethod def update(cls, context, snapshot_id, values): db_snapshot = db_api.snapshot_update(context, snapshot_id, values) return cls._from_db_object(context, cls(), db_snapshot) @classmethod def delete(cls, context, snapshot_id): db_api.snapshot_delete(context, snapshot_id) @classmethod def get_all(cls, context, stack_id): return [ cls._from_db_object(context, cls(), db_snapshot) for db_snapshot in db_api.snapshot_get_all(context, stack_id) ]
class SyncPoint( heat_base.HeatObject, base.VersionedObjectDictCompat, base.ComparableVersionedObject, ): fields = { 'entity_id': fields.StringField(), 'traversal_id': fields.StringField(), 'is_update': fields.BooleanField(), 'created_at': fields.DateTimeField(read_only=True), 'updated_at': fields.DateTimeField(nullable=True), 'atomic_key': fields.IntegerField(), 'stack_id': fields.StringField(), 'input_data': heat_fields.JsonField(nullable=True), } @staticmethod def _from_db_object(context, sdata, db_sdata): if db_sdata is None: return None for field in sdata.fields: sdata[field] = db_sdata[field] sdata._context = context sdata.obj_reset_changes() return sdata @classmethod def get_by_key(cls, context, entity_id, traversal_id, is_update): sync_point_db = db_api.sync_point_get(context, entity_id, traversal_id, is_update) return cls._from_db_object(context, cls(), sync_point_db) @classmethod def create(cls, context, values): sync_point_db = db_api.sync_point_create(context, values) return cls._from_db_object(context, cls(), sync_point_db) @classmethod def update_input_data(cls, context, entity_id, traversal_id, is_update, atomic_key, input_data): return db_api.sync_point_update_input_data(context, entity_id, traversal_id, is_update, atomic_key, input_data) @classmethod def delete_all_by_stack_and_traversal(cls, context, stack_id, traversal_id): return db_api.sync_point_delete_all_by_stack_and_traversal( context, stack_id, traversal_id)
class ResourcePropertiesData( base.VersionedObject, base.VersionedObjectDictCompat, base.ComparableVersionedObject, ): fields = { 'id': fields.IntegerField(), 'data': heat_fields.JsonField(nullable=True), 'created_at': fields.DateTimeField(read_only=True), 'updated_at': fields.DateTimeField(nullable=True), } @staticmethod def _from_db_object(rpd, context, db_rpd, data_unencrypted=None): # The data_unencrypted field allows us to avoid an extra # decrypt operation, e.g. when called from create(). for field in rpd.fields: rpd[field] = db_rpd[field] if data_unencrypted: # save a little (decryption) processing rpd['data'] = data_unencrypted elif db_rpd['encrypted'] and rpd['data'] is not None: rpd['data'] = crypt.decrypted_dict(rpd['data']) rpd.obj_reset_changes() return rpd @classmethod def create(cls, context, data): properties_data_encrypted, properties_data = \ ResourcePropertiesData.encrypt_properties_data(data) values = { 'encrypted': properties_data_encrypted, 'data': properties_data } db_obj = db_api.resource_prop_data_create(context, values) return cls._from_db_object(cls(), context, db_obj, data) @staticmethod def encrypt_properties_data(data): if cfg.CONF.encrypt_parameters_and_properties and data: result = {} for prop_name, prop_value in data.items(): prop_string = jsonutils.dumps(prop_value) encrypted_value = crypt.encrypt(prop_string) result[prop_name] = encrypted_value return (True, result) return (False, data)
class SoftwareConfig( heat_base.HeatObject, base.VersionedObjectDictCompat, base.ComparableVersionedObject, ): fields = { 'id': fields.StringField(), 'name': fields.StringField(nullable=True), 'group': fields.StringField(nullable=True), 'tenant': fields.StringField(nullable=True), 'config': heat_fields.JsonField(nullable=True), 'created_at': fields.DateTimeField(read_only=True), 'updated_at': fields.DateTimeField(nullable=True), } @staticmethod def _from_db_object(context, config, db_config): # SoftwareDeployment._from_db_object may attempt to load a None config if db_config is None: return None for field in config.fields: config[field] = db_config[field] config._context = context config.obj_reset_changes() return config @classmethod def create(cls, context, values): return cls._from_db_object( context, cls(), db_api.software_config_create(context, values)) @classmethod def get_by_id(cls, context, config_id): return cls._from_db_object( context, cls(), db_api.software_config_get(context, config_id)) @classmethod def get_all(cls, context, **kwargs): scs = db_api.software_config_get_all(context, **kwargs) return [cls._from_db_object(context, cls(), sc) for sc in scs] @classmethod def delete(cls, context, config_id): db_api.software_config_delete(context, config_id)
class WatchData( heat_base.HeatObject, base.VersionedObjectDictCompat, ): fields = { 'id': fields.IntegerField(), 'data': heat_fields.JsonField(nullable=True), 'watch_rule_id': fields.StringField(), 'watch_rule': fields.ObjectField('WatchRule'), 'created_at': fields.DateTimeField(read_only=True), 'updated_at': fields.DateTimeField(nullable=True), } @staticmethod def _from_db_object(context, rule, db_data): from heat.objects import watch_rule for field in rule.fields: if field == 'watch_rule': rule[field] = watch_rule.WatchRule._from_db_object( context, watch_rule.WatchRule(), db_data['watch_rule']) else: rule[field] = db_data[field] rule._context = context rule.obj_reset_changes() return rule @classmethod def create(cls, context, values): db_data = db_api.watch_data_create(context, values) return cls._from_db_object(context, cls(), db_data) @classmethod def get_all(cls, context): return [ cls._from_db_object(context, cls(), db_data) for db_data in db_api.watch_data_get_all(context) ] @classmethod def get_all_by_watch_rule_id(cls, context, watch_rule_id): return (cls._from_db_object(context, cls(), db_data) for db_data in db_api.watch_data_get_all_by_watch_rule_id( context, watch_rule_id))
class Resource( heat_base.HeatObject, base.VersionedObjectDictCompat, base.ComparableVersionedObject, ): fields = { 'id': fields.IntegerField(), 'uuid': fields.StringField(), 'stack_id': fields.StringField(), 'created_at': fields.DateTimeField(read_only=True), 'updated_at': fields.DateTimeField(nullable=True), 'physical_resource_id': fields.StringField(nullable=True), 'name': fields.StringField(nullable=True), 'status': fields.StringField(nullable=True), 'status_reason': fields.StringField(nullable=True), 'action': fields.StringField(nullable=True), 'rsrc_metadata': heat_fields.JsonField(nullable=True), 'properties_data': heat_fields.JsonField(nullable=True), 'properties_data_encrypted': fields.BooleanField(default=False), 'data': fields.ListOfObjectsField(resource_data.ResourceData, nullable=True), 'engine_id': fields.StringField(nullable=True), 'atomic_key': fields.IntegerField(nullable=True), 'current_template_id': fields.IntegerField(), 'needed_by': heat_fields.ListField(nullable=True, default=None), 'requires': heat_fields.ListField(nullable=True, default=None), 'replaces': fields.IntegerField(nullable=True), 'replaced_by': fields.IntegerField(nullable=True), 'root_stack_id': fields.StringField(nullable=True), } @staticmethod def _from_db_object(resource, context, db_resource): if db_resource is None: return None for field in resource.fields: if field == 'data': resource['data'] = [ resource_data.ResourceData._from_db_object( resource_data.ResourceData(context), resd) for resd in db_resource.data ] else: resource[field] = db_resource[field] if resource.properties_data_encrypted and resource.properties_data: properties_data = {} for prop_name, prop_value in resource.properties_data.items(): method, value = prop_value decrypted_value = crypt.decrypt(method, value) prop_string = jsonutils.loads(decrypted_value) properties_data[prop_name] = prop_string resource.properties_data = properties_data resource._context = context resource.obj_reset_changes() return resource @classmethod def get_obj(cls, context, resource_id, refresh=False): resource_db = db_api.resource_get(context, resource_id, refresh=refresh) return cls._from_db_object(cls(context), context, resource_db) @classmethod def get_all(cls, context): resources_db = db_api.resource_get_all(context) resources = [ (resource_name, cls._from_db_object(cls(context), context, resource_db)) for resource_name, resource_db in six.iteritems(resources_db) ] return dict(resources) @classmethod def create(cls, context, values): return cls._from_db_object(cls(context), context, db_api.resource_create(context, values)) @classmethod def delete(cls, context, resource_id): db_api.resource_delete(context, resource_id) @classmethod def exchange_stacks(cls, context, resource_id1, resource_id2): return db_api.resource_exchange_stacks(context, resource_id1, resource_id2) @classmethod def get_all_by_stack(cls, context, stack_id, filters=None): cache = context.cache(ResourceCache) resources = cache.by_stack_id_name.get(stack_id) if resources: return dict(resources) resources_db = db_api.resource_get_all_by_stack( context, stack_id, filters) return cls._resources_to_dict(context, resources_db) @classmethod def _resources_to_dict(cls, context, resources_db): resources = [ (resource_name, cls._from_db_object(cls(context), context, resource_db)) for resource_name, resource_db in six.iteritems(resources_db) ] return dict(resources) @classmethod def get_all_active_by_stack(cls, context, stack_id): resources_db = db_api.resource_get_all_active_by_stack( context, stack_id) resources = [ (resource_id, cls._from_db_object(cls(context), context, resource_db)) for resource_id, resource_db in six.iteritems(resources_db) ] return dict(resources) @classmethod def get_all_by_root_stack(cls, context, stack_id, filters, cache=False): resources_db = db_api.resource_get_all_by_root_stack( context, stack_id, filters) all = cls._resources_to_dict(context, resources_db) if cache: context.cache(ResourceCache).set_by_stack_id(all) return all @classmethod def purge_deleted(cls, context, stack_id): return db_api.resource_purge_deleted(context, stack_id) @classmethod def get_by_name_and_stack(cls, context, resource_name, stack_id): resource_db = db_api.resource_get_by_name_and_stack( context, resource_name, stack_id) return cls._from_db_object(cls(context), context, resource_db) @classmethod def get_by_physical_resource_id(cls, context, physical_resource_id): resource_db = db_api.resource_get_by_physical_resource_id( context, physical_resource_id) return cls._from_db_object(cls(context), context, resource_db) @classmethod def update_by_id(cls, context, resource_id, values): db_api.resource_update_and_save(context, resource_id, values) def update_and_save(self, values): db_api.resource_update_and_save(self._context, self.id, values) def select_and_update(self, values, expected_engine_id=None, atomic_key=0): return db_api.resource_update(self._context, self.id, values, atomic_key=atomic_key, expected_engine_id=expected_engine_id) def refresh(self): resource_db = db_api.resource_get(self._context, self.id, refresh=True) return self.__class__._from_db_object(self, self._context, resource_db) @staticmethod def encrypt_properties_data(data): if cfg.CONF.encrypt_parameters_and_properties and data: result = {} for prop_name, prop_value in data.items(): prop_string = jsonutils.dumps(prop_value) encrypted_value = crypt.encrypt(prop_string) result[prop_name] = encrypted_value return (True, result) return (False, data) def update_metadata(self, metadata): if self.rsrc_metadata != metadata: rows_updated = self.select_and_update({'rsrc_metadata': metadata}, self.engine_id, self.atomic_key) if not rows_updated: action = _('metadata setting for resource %s') % self.name raise exception.ConcurrentTransaction(action=action)
class Stack( base.VersionedObject, base.VersionedObjectDictCompat, base.ComparableVersionedObject, ): fields = { 'id': fields.StringField(), 'name': fields.StringField(), 'raw_template_id': fields.IntegerField(), 'backup': fields.BooleanField(), 'created_at': fields.DateTimeField(read_only=True), 'deleted_at': fields.DateTimeField(nullable=True), 'disable_rollback': fields.BooleanField(), 'nested_depth': fields.IntegerField(), 'owner_id': fields.StringField(nullable=True), 'stack_user_project_id': fields.StringField(nullable=True), 'tenant': fields.StringField(nullable=True), 'timeout': fields.IntegerField(nullable=True), 'updated_at': fields.DateTimeField(nullable=True), 'user_creds_id': fields.StringField(nullable=True), 'username': fields.StringField(nullable=True), 'action': fields.StringField(nullable=True), 'status': fields.StringField(nullable=True), 'status_reason': fields.StringField(nullable=True), 'raw_template': fields.ObjectField('RawTemplate'), 'convergence': fields.BooleanField(), 'current_traversal': fields.StringField(), 'current_deps': heat_fields.JsonField(), 'prev_raw_template_id': fields.IntegerField(), 'prev_raw_template': fields.ObjectField('RawTemplate'), 'tags': fields.ObjectField('StackTagList'), 'parent_resource_name': fields.StringField(nullable=True), } @staticmethod def _from_db_object(context, stack, db_stack): for field in stack.fields: if field == 'raw_template': stack['raw_template'] = (raw_template.RawTemplate.get_by_id( context, db_stack['raw_template_id'])) elif field == 'tags': if db_stack.get(field) is not None: stack['tags'] = stack_tag.StackTagList.get( context, db_stack['id']) else: stack['tags'] = None else: stack[field] = db_stack.__dict__.get(field) stack._context = context stack.obj_reset_changes() return stack @classmethod def get_root_id(cls, context, stack_id): return db_api.stack_get_root_id(context, stack_id) @classmethod def get_by_id(cls, context, stack_id, **kwargs): db_stack = db_api.stack_get(context, stack_id, **kwargs) if not db_stack: return None stack = cls._from_db_object(context, cls(context), db_stack) return stack @classmethod def get_by_name_and_owner_id(cls, context, stack_name, owner_id): db_stack = db_api.stack_get_by_name_and_owner_id( context, stack_name, owner_id) if not db_stack: return None stack = cls._from_db_object(context, cls(context), db_stack) return stack @classmethod def get_by_name(cls, context, stack_name): db_stack = db_api.stack_get_by_name(context, stack_name) if not db_stack: return None stack = cls._from_db_object(context, cls(context), db_stack) return stack @classmethod def get_all(cls, context, *args, **kwargs): db_stacks = db_api.stack_get_all(context, *args, **kwargs) stacks = map( lambda db_stack: cls._from_db_object(context, cls(context), db_stack), db_stacks) return stacks @classmethod def get_all_by_owner_id(cls, context, owner_id): db_stacks = db_api.stack_get_all_by_owner_id(context, owner_id) stacks = map( lambda db_stack: cls._from_db_object(context, cls(context), db_stack), db_stacks) return stacks @classmethod def count_all(cls, context, **kwargs): return db_api.stack_count_all(context, **kwargs) @classmethod def count_total_resources(cls, context, stack_id): return db_api.stack_count_total_resources(context, stack_id) @classmethod def create(cls, context, values): return cls._from_db_object(context, cls(context), db_api.stack_create(context, values)) @classmethod def update_by_id(cls, context, stack_id, values): """Update and return (boolean) if it was updated. Note: the underlying stack_update filters by current_traversal and stack_id. """ return db_api.stack_update(context, stack_id, values) @classmethod def delete(cls, context, stack_id): db_api.stack_delete(context, stack_id) def update_and_save(self, values): has_updated = self.__class__.update_by_id(self._context, self.id, values) if not has_updated: raise exception.NotFound( _('Attempt to update a stack with id: ' '%(id)s %(traversal) %(msg)s') % { 'id': self.id, 'traversal': self.current_traversal, 'msg': 'that does not exist' }) return self.refresh() def __eq__(self, another): self.refresh() # to make test object comparison work well return super(Stack, self).__eq__(another) def refresh(self): db_stack = db_api.stack_get(self._context, self.id, show_deleted=True) db_stack.refresh() return self.__class__._from_db_object(self._context, self, db_stack) @classmethod def encrypt_hidden_parameters(cls, tmpl): raw_template.RawTemplate.encrypt_hidden_parameters(tmpl)
class Stack( heat_base.HeatObject, base.VersionedObjectDictCompat, base.ComparableVersionedObject, ): fields = { 'id': fields.StringField(), 'name': fields.StringField(), 'raw_template_id': fields.IntegerField(), 'backup': fields.BooleanField(), 'created_at': fields.DateTimeField(read_only=True), 'deleted_at': fields.DateTimeField(nullable=True), 'disable_rollback': fields.BooleanField(), 'nested_depth': fields.IntegerField(), 'owner_id': fields.StringField(nullable=True), 'stack_user_project_id': fields.StringField(nullable=True), 'tenant': fields.StringField(nullable=True), 'timeout': fields.IntegerField(nullable=True), 'updated_at': fields.DateTimeField(nullable=True), 'user_creds_id': fields.StringField(nullable=True), 'username': fields.StringField(nullable=True), 'action': fields.StringField(nullable=True), 'status': fields.StringField(nullable=True), 'status_reason': fields.StringField(nullable=True), 'raw_template': fields.ObjectField('RawTemplate'), 'convergence': fields.BooleanField(), 'current_traversal': fields.StringField(), 'current_deps': heat_fields.JsonField(), 'prev_raw_template_id': fields.IntegerField(), 'prev_raw_template': fields.ObjectField('RawTemplate'), 'parent_resource_name': fields.StringField(nullable=True), } @staticmethod def _from_db_object(context, stack, db_stack): for field in stack.fields: if field == 'raw_template': stack['raw_template'] = ( raw_template.RawTemplate.from_db_object( context, raw_template.RawTemplate(), db_stack['raw_template'])) else: stack[field] = db_stack.__dict__.get(field) stack._context = context stack.obj_reset_changes() return stack @classmethod def get_root_id(cls, context, stack_id): return db_api.stack_get_root_id(context, stack_id) @classmethod def get_by_id(cls, context, stack_id, **kwargs): db_stack = db_api.stack_get(context, stack_id, **kwargs) if not db_stack: return None stack = cls._from_db_object(context, cls(context), db_stack) return stack @classmethod def get_by_name_and_owner_id(cls, context, stack_name, owner_id): db_stack = db_api.stack_get_by_name_and_owner_id( context, six.text_type(stack_name), owner_id) if not db_stack: return None stack = cls._from_db_object(context, cls(context), db_stack) return stack @classmethod def get_by_name(cls, context, stack_name): db_stack = db_api.stack_get_by_name(context, six.text_type(stack_name)) if not db_stack: return None stack = cls._from_db_object(context, cls(context), db_stack) return stack @classmethod def get_all(cls, context, limit=None, sort_keys=None, marker=None, sort_dir=None, filters=None, show_deleted=False, show_nested=False, show_hidden=False, tags=None, tags_any=None, not_tags=None, not_tags_any=None): db_stacks = db_api.stack_get_all(context, limit=limit, sort_keys=sort_keys, marker=marker, sort_dir=sort_dir, filters=filters, show_deleted=show_deleted, show_nested=show_nested, show_hidden=show_hidden, tags=tags, tags_any=tags_any, not_tags=not_tags, not_tags_any=not_tags_any) for db_stack in db_stacks: try: yield cls._from_db_object(context, cls(context), db_stack) except exception.NotFound: pass @classmethod def get_all_by_owner_id(cls, context, owner_id): db_stacks = db_api.stack_get_all_by_owner_id(context, owner_id) for db_stack in db_stacks: try: yield cls._from_db_object(context, cls(context), db_stack) except exception.NotFound: pass @classmethod def count_all(cls, context, **kwargs): return db_api.stack_count_all(context, **kwargs) @classmethod def count_total_resources(cls, context, stack_id): return db_api.stack_count_total_resources(context, stack_id) @classmethod def create(cls, context, values): return cls._from_db_object(context, cls(context), db_api.stack_create(context, values)) @classmethod def update_by_id(cls, context, stack_id, values): """Update and return (boolean) if it was updated. Note: the underlying stack_update filters by current_traversal and stack_id. """ return db_api.stack_update(context, stack_id, values) @classmethod def select_and_update(cls, context, stack_id, values, exp_trvsl=None): """Update the stack by selecting on traversal ID. Uses UPDATE ... WHERE (compare and swap) to catch any concurrent update problem. If the stack is found with given traversal, it is updated. If there occurs a race while updating, only one will succeed and other will get return value of False. """ return db_api.stack_update(context, stack_id, values, exp_trvsl=exp_trvsl) @classmethod def persist_state_and_release_lock(cls, context, stack_id, engine_id, values): return db_api.persist_state_and_release_lock(context, stack_id, engine_id, values) @classmethod def delete(cls, context, stack_id): db_api.stack_delete(context, stack_id) def update_and_save(self, values): has_updated = self.__class__.update_by_id(self._context, self.id, values) if not has_updated: raise exception.NotFound( _('Attempt to update a stack with id: ' '%(id)s %(traversal)s %(msg)s') % { 'id': self.id, 'traversal': self.current_traversal, 'msg': 'that does not exist' }) def __eq__(self, another): self.refresh() # to make test object comparison work well return super(Stack, self).__eq__(another) def __ne__(self, other): return not self.__eq__(other) def refresh(self): db_stack = db_api.stack_get(self._context, self.id, show_deleted=True) if db_stack is None: message = _('No stack exists with id "%s"') % str(self.id) raise exception.NotFound(message) return self.__class__._from_db_object(self._context, self, db_stack) @classmethod def encrypt_hidden_parameters(cls, tmpl): raw_template.RawTemplate.encrypt_hidden_parameters(tmpl) @classmethod def get_status(cls, context, stack_id): """Return action and status for the given stack.""" return db_api.stack_get_status(context, stack_id) def identifier(self): """Return an identifier for this stack.""" return identifier.HeatIdentifier(self.tenant, self.name, self.id) @property def tags(self): return stack_tag.StackTagList.get(self._context, self.id)
class RawTemplate( heat_base.HeatObject, base.VersionedObjectDictCompat, base.ComparableVersionedObject, ): # Version 1.0: Initial version # Version 1.1: Added files_id VERSION = '1.1' fields = { 'id': fields.IntegerField(), # TODO(cwolfe): remove deprecated files in future release 'files': heat_fields.JsonField(nullable=True), 'files_id': fields.IntegerField(nullable=True), 'template': heat_fields.JsonField(), 'environment': heat_fields.JsonField(), } @staticmethod def from_db_object(context, tpl, db_tpl): for field in tpl.fields: tpl[field] = db_tpl[field] tpl.environment = copy.deepcopy(tpl.environment) # If any of the parameters were encrypted, then decrypt them if (tpl.environment is not None and env_fmt.ENCRYPTED_PARAM_NAMES in tpl.environment): parameters = tpl.environment[env_fmt.PARAMETERS] encrypted_param_names = tpl.environment[ env_fmt.ENCRYPTED_PARAM_NAMES] for param_name in encrypted_param_names: if (isinstance(parameters[param_name], (list, tuple)) and len(parameters[param_name]) == 2): method, enc_value = parameters[param_name] value = crypt.decrypt(method, enc_value) else: value = parameters[param_name] LOG.warning(_LW( 'Encountered already-decrypted data while attempting ' 'to decrypt parameter %s. Please file a Heat bug so ' 'this can be fixed.'), param_name) parameters[param_name] = value tpl.environment[env_fmt.PARAMETERS] = parameters tpl._context = context tpl.obj_reset_changes() return tpl @classmethod def get_by_id(cls, context, template_id): raw_template_db = db_api.raw_template_get(context, template_id) return cls.from_db_object(context, cls(), raw_template_db) @classmethod def encrypt_hidden_parameters(cls, tmpl): if cfg.CONF.encrypt_parameters_and_properties: for param_name, param in tmpl.env.params.items(): if not tmpl.param_schemata()[param_name].hidden: continue clear_text_val = tmpl.env.params.get(param_name) tmpl.env.params[param_name] = crypt.encrypt(clear_text_val) if param_name not in tmpl.env.encrypted_param_names: tmpl.env.encrypted_param_names.append(param_name) @classmethod def create(cls, context, values): return cls.from_db_object(context, cls(), db_api.raw_template_create(context, values)) @classmethod def update_by_id(cls, context, template_id, values): # Only save template files in the new raw_template_files # table, not in the old location of raw_template.files if 'files_id' in values and values['files_id']: values['files'] = None return cls.from_db_object( context, cls(), db_api.raw_template_update(context, template_id, values)) @classmethod def delete(cls, context, template_id): db_api.raw_template_delete(context, template_id)
class Resource( base.VersionedObject, base.VersionedObjectDictCompat, base.ComparableVersionedObject, ): fields = { 'id': fields.IntegerField(), 'uuid': fields.StringField(), 'stack_id': fields.StringField(), 'created_at': fields.DateTimeField(read_only=True), 'updated_at': fields.DateTimeField(nullable=True), 'nova_instance': fields.StringField(nullable=True), 'name': fields.StringField(nullable=True), 'status': fields.StringField(nullable=True), 'status_reason': fields.StringField(nullable=True), 'action': fields.StringField(nullable=True), 'rsrc_metadata': heat_fields.JsonField(nullable=True), 'properties_data': heat_fields.JsonField(nullable=True), 'data': fields.ListOfObjectsField(resource_data.ResourceData, nullable=True), 'stack': fields.ObjectField(stack.Stack), 'engine_id': fields.StringField(nullable=True), 'atomic_key': fields.IntegerField(nullable=True), 'current_template_id': fields.IntegerField(), 'needed_by': heat_fields.ListField(nullable=True, default=None), 'requires': heat_fields.ListField(nullable=True, default=None), 'replaces': fields.IntegerField(nullable=True), 'replaced_by': fields.IntegerField(nullable=True), } @staticmethod def _from_db_object(resource, context, db_resource): if db_resource is None: return None for field in resource.fields: if field == 'data': resource['data'] = map( lambda resd: resource_data.ResourceData._from_db_object( resource_data.ResourceData(context), resd), db_resource.data) else: resource[field] = db_resource[field] resource._context = context resource.obj_reset_changes() return resource @classmethod def get_obj(cls, context, resource_id): resource_db = db_api.resource_get(context, resource_id) resource = cls._from_db_object(cls(context), context, resource_db) return resource @classmethod def get_all(cls, context): resources_db = db_api.resource_get_all(context) resources = [ (resource_name, cls._from_db_object(cls(context), context, resource_db)) for resource_name, resource_db in six.iteritems(resources_db) ] return dict(resources) @classmethod def create(cls, context, values): return db_api.resource_create(context, values) @classmethod def delete(cls, context, resource_id): resource_db = db_api.resource_get(context, resource_id) resource_db.delete() @classmethod def exchange_stacks(cls, context, resource_id1, resource_id2): return db_api.resource_exchange_stacks(context, resource_id1, resource_id2) @classmethod def get_all_by_stack(cls, context, stack_id): resources_db = db_api.resource_get_all_by_stack(context, stack_id) resources = [ (resource_name, cls._from_db_object(cls(context), context, resource_db)) for resource_name, resource_db in six.iteritems(resources_db) ] return dict(resources) @classmethod def get_by_name_and_stack(cls, context, resource_name, stack_id): resource_db = db_api.resource_get_by_name_and_stack( context, resource_name, stack_id) resource = cls._from_db_object(cls(context), context, resource_db) return resource @classmethod def get_by_physical_resource_id(cls, context, physical_resource_id): resource_db = db_api.resource_get_by_physical_resource_id( context, physical_resource_id) resource = cls._from_db_object(cls(context), context, resource_db) return resource def update_and_save(self, values): resource_db = db_api.resource_get(self._context, self.id) resource_db.update_and_save(values) self._refresh() return resource_db def _refresh(self): return self.__class__._from_db_object( self, self._context, self.__class__.get_obj(self._context, self.id)) def refresh(self, attrs=None): resource_db = db_api.resource_get(self._context, self.id) resource_db.refresh(attrs=attrs) return self._refresh()
class RawTemplate( base.VersionedObject, base.VersionedObjectDictCompat, base.ComparableVersionedObject, ): fields = { 'id': fields.StringField(), 'files': heat_fields.JsonField(nullable=True), 'template': heat_fields.JsonField(), 'environment': heat_fields.JsonField(), 'predecessor': fields.IntegerField(), } @staticmethod def _from_db_object(context, tpl, db_tpl): for field in tpl.fields: tpl[field] = db_tpl[field] # If any of the parameters were encrypted, then decrypt them if env_fmt.ENCRYPTED_PARAM_NAMES in tpl.environment: parameters = tpl.environment[env_fmt.PARAMETERS] encrypted_param_names = tpl.environment[ env_fmt.ENCRYPTED_PARAM_NAMES] for param_name in encrypted_param_names: decrypt_function_name = parameters[param_name][0] decrypt_function = getattr(crypt, decrypt_function_name) decrypted_val = decrypt_function(parameters[param_name][1]) parameters[param_name] = encodeutils.safe_decode(decrypted_val) tpl.environment[env_fmt.PARAMETERS] = parameters tpl._context = context tpl.obj_reset_changes() return tpl @classmethod def get_by_id(cls, context, template_id): raw_template_db = db_api.raw_template_get(context, template_id) raw_template = cls._from_db_object(context, cls(), raw_template_db) return raw_template @classmethod def encrypt_hidden_parameters(cls, tmpl): if cfg.CONF.encrypt_parameters_and_properties: for param_name, param in tmpl.env.params.items(): if not tmpl.param_schemata()[param_name].hidden: continue clear_text_val = tmpl.env.params.get(param_name) encoded_val = encodeutils.safe_encode(clear_text_val) tmpl.env.params[param_name] = crypt.encrypt(encoded_val) tmpl.env.encrypted_param_names.append(param_name) @classmethod def create(cls, context, values): return db_api.raw_template_create(context, values) @classmethod def update_by_id(cls, context, template_id, values): return db_api.raw_template_update(context, template_id, values) @classmethod def delete(cls, context, template_id): return db_api.raw_template_delete(context, template_id)
class Resource( heat_base.HeatObject, base.VersionedObjectDictCompat, base.ComparableVersionedObject, ): fields = { 'id': fields.IntegerField(), 'uuid': fields.StringField(), 'stack_id': fields.StringField(), 'created_at': fields.DateTimeField(read_only=True), 'updated_at': fields.DateTimeField(nullable=True), 'physical_resource_id': fields.StringField(nullable=True), 'name': fields.StringField(nullable=True), 'status': fields.StringField(nullable=True), 'status_reason': fields.StringField(nullable=True), 'action': fields.StringField(nullable=True), 'attr_data': fields.ObjectField(rpd.ResourcePropertiesData, nullable=True), 'attr_data_id': fields.IntegerField(nullable=True), 'rsrc_metadata': heat_fields.JsonField(nullable=True), 'data': fields.ListOfObjectsField(resource_data.ResourceData, nullable=True), 'rsrc_prop_data': fields.ObjectField(rpd.ResourcePropertiesData, nullable=True), 'rsrc_prop_data_id': fields.ObjectField(fields.IntegerField(nullable=True)), 'engine_id': fields.StringField(nullable=True), 'atomic_key': fields.IntegerField(nullable=True), 'current_template_id': fields.IntegerField(), 'needed_by': heat_fields.ListField(nullable=True, default=None), 'requires': heat_fields.ListField(nullable=True, default=None), 'replaces': fields.IntegerField(nullable=True), 'replaced_by': fields.IntegerField(nullable=True), 'root_stack_id': fields.StringField(nullable=True), } @staticmethod def _from_db_object(resource, context, db_resource): if db_resource is None: return None for field in resource.fields: if field == 'data': resource['data'] = [ resource_data.ResourceData._from_db_object( resource_data.ResourceData(context), resd) for resd in db_resource.data ] else: resource[field] = db_resource[field] if db_resource['rsrc_prop_data'] is not None: resource['rsrc_prop_data'] = \ rpd.ResourcePropertiesData._from_db_object( rpd.ResourcePropertiesData(context), context, db_resource['rsrc_prop_data']) resource._properties_data = resource['rsrc_prop_data'].data if db_resource['properties_data']: LOG.error( 'Unexpected condition where resource.rsrc_prop_data ' 'and resource.properties_data are both not null. ' 'rsrc_prop_data.id: %(rsrc_prop_data_id)s, ' 'resource id: %(res_id)s', { 'rsrc_prop_data_id': resource['rsrc_prop_data'].id, 'res_id': resource['id'] }) elif db_resource['properties_data']: # legacy field if db_resource['properties_data_encrypted']: decrypted_data = crypt.decrypted_dict( db_resource['properties_data']) resource._properties_data = decrypted_data else: resource._properties_data = db_resource['properties_data'] else: resource._properties_data = {} if db_resource['attr_data'] is not None: resource['attr_data'] = \ rpd.ResourcePropertiesData._from_db_object( rpd.ResourcePropertiesData(context), context, db_resource['attr_data']) resource._context = context resource.obj_reset_changes() return resource @property def properties_data(self): return self._properties_data @classmethod def get_obj(cls, context, resource_id, refresh=False): resource_db = db_api.resource_get(context, resource_id, refresh=refresh) return cls._from_db_object(cls(context), context, resource_db) @classmethod def get_all(cls, context): resources_db = db_api.resource_get_all(context) resources = [ (resource_name, cls._from_db_object(cls(context), context, resource_db)) for resource_name, resource_db in six.iteritems(resources_db) ] return dict(resources) @classmethod def create(cls, context, values): return cls._from_db_object(cls(context), context, db_api.resource_create(context, values)) @classmethod def delete(cls, context, resource_id): db_api.resource_delete(context, resource_id) @classmethod def exchange_stacks(cls, context, resource_id1, resource_id2): return db_api.resource_exchange_stacks(context, resource_id1, resource_id2) @classmethod def get_all_by_stack(cls, context, stack_id, filters=None): cache = context.cache(ResourceCache) resources = cache.by_stack_id_name.get(stack_id) if resources: return dict(resources) resources_db = db_api.resource_get_all_by_stack( context, stack_id, filters) return cls._resources_to_dict(context, resources_db) @classmethod def _resources_to_dict(cls, context, resources_db): resources = [ (resource_name, cls._from_db_object(cls(context), context, resource_db)) for resource_name, resource_db in six.iteritems(resources_db) ] return dict(resources) @classmethod def get_all_active_by_stack(cls, context, stack_id): resources_db = db_api.resource_get_all_active_by_stack( context, stack_id) resources = [ (resource_id, cls._from_db_object(cls(context), context, resource_db)) for resource_id, resource_db in six.iteritems(resources_db) ] return dict(resources) @classmethod def get_all_by_root_stack(cls, context, stack_id, filters, cache=False): resources_db = db_api.resource_get_all_by_root_stack( context, stack_id, filters) all = cls._resources_to_dict(context, resources_db) if cache: context.cache(ResourceCache).set_by_stack_id(all) return all @classmethod def purge_deleted(cls, context, stack_id): return db_api.resource_purge_deleted(context, stack_id) @classmethod def get_by_name_and_stack(cls, context, resource_name, stack_id): resource_db = db_api.resource_get_by_name_and_stack( context, resource_name, stack_id) return cls._from_db_object(cls(context), context, resource_db) @classmethod def get_all_by_physical_resource_id(cls, context, physical_resource_id): matches = db_api.resource_get_all_by_physical_resource_id( context, physical_resource_id) return [ cls._from_db_object(cls(context), context, resource_db) for resource_db in matches ] @classmethod def update_by_id(cls, context, resource_id, values): db_api.resource_update_and_save(context, resource_id, values) def update_and_save(self, values): db_api.resource_update_and_save(self._context, self.id, values) def select_and_update(self, values, expected_engine_id=None, atomic_key=0): return db_api.resource_update(self._context, self.id, values, atomic_key=atomic_key, expected_engine_id=expected_engine_id) def refresh(self): resource_db = db_api.resource_get(self._context, self.id, refresh=True) return self.__class__._from_db_object(self, self._context, resource_db) @staticmethod def encrypt_properties_data(data): if cfg.CONF.encrypt_parameters_and_properties and data: result = crypt.encrypted_dict(data) return (True, result) return (False, data) def update_metadata(self, metadata): if self.rsrc_metadata != metadata: rows_updated = self.select_and_update({'rsrc_metadata': metadata}, self.engine_id, self.atomic_key) if not rows_updated: action = _('metadata setting for resource %s') % self.name raise exception.ConcurrentTransaction(action=action)
class RawTemplate( base.VersionedObject, base.VersionedObjectDictCompat, base.ComparableVersionedObject, ): fields = { 'id': fields.StringField(), 'files': heat_fields.JsonField(nullable=True), 'template': heat_fields.JsonField(), 'environment': heat_fields.JsonField(), } @staticmethod def _from_db_object(context, tpl, db_tpl): for field in tpl.fields: tpl[field] = db_tpl[field] tpl.environment = copy.deepcopy(tpl.environment) # If any of the parameters were encrypted, then decrypt them if (tpl.environment is not None and env_fmt.ENCRYPTED_PARAM_NAMES in tpl.environment): parameters = tpl.environment[env_fmt.PARAMETERS] encrypted_param_names = tpl.environment[ env_fmt.ENCRYPTED_PARAM_NAMES] for param_name in encrypted_param_names: method, value = parameters[param_name] decrypted_val = crypt.decrypt(method, value) parameters[param_name] = decrypted_val tpl.environment[env_fmt.PARAMETERS] = parameters tpl._context = context tpl.obj_reset_changes() return tpl @classmethod def get_by_id(cls, context, template_id): raw_template_db = db_api.raw_template_get(context, template_id) return cls._from_db_object(context, cls(), raw_template_db) @classmethod def encrypt_hidden_parameters(cls, tmpl): if cfg.CONF.encrypt_parameters_and_properties: for param_name, param in tmpl.env.params.items(): if not tmpl.param_schemata()[param_name].hidden: continue clear_text_val = tmpl.env.params.get(param_name) tmpl.env.params[param_name] = crypt.encrypt(clear_text_val) tmpl.env.encrypted_param_names.append(param_name) @classmethod def create(cls, context, values): return cls._from_db_object(context, cls(), db_api.raw_template_create(context, values)) @classmethod def update_by_id(cls, context, template_id, values): return cls._from_db_object( context, cls(), db_api.raw_template_update(context, template_id, values)) @classmethod def delete(cls, context, template_id): db_api.raw_template_delete(context, template_id)
class WatchRule( heat_base.HeatObject, base.VersionedObjectDictCompat, ): fields = { 'id': fields.IntegerField(), 'name': fields.StringField(nullable=True), 'rule': heat_fields.JsonField(nullable=True), 'state': fields.StringField(nullable=True), 'last_evaluated': fields.DateTimeField(nullable=True), 'stack_id': fields.StringField(), 'stack': fields.ObjectField(stack.Stack), 'watch_data': fields.ListOfObjectsField(watch_data.WatchData), 'created_at': fields.DateTimeField(read_only=True), 'updated_at': fields.DateTimeField(nullable=True), } @staticmethod def _from_db_object(context, rule, db_rule): for field in rule.fields: if field == 'stack': rule[field] = stack.Stack._from_db_object( context, stack.Stack(), db_rule[field]) elif field == 'watch_data': rule[field] = watch_data.WatchData.get_all_by_watch_rule_id( context, db_rule['id']) else: rule[field] = db_rule[field] rule._context = context rule.obj_reset_changes() return rule @classmethod def get_by_id(cls, context, rule_id): db_rule = db_api.watch_rule_get(context, rule_id) return cls._from_db_object(context, cls(), db_rule) @classmethod def get_by_name(cls, context, watch_rule_name): db_rule = db_api.watch_rule_get_by_name(context, watch_rule_name) return cls._from_db_object(context, cls(), db_rule) @classmethod def get_all(cls, context): return [ cls._from_db_object(context, cls(), db_rule) for db_rule in db_api.watch_rule_get_all(context) ] @classmethod def get_all_by_stack(cls, context, stack_id): return [ cls._from_db_object(context, cls(), db_rule) for db_rule in db_api.watch_rule_get_all_by_stack( context, stack_id) ] @classmethod def update_by_id(cls, context, watch_id, values): db_api.watch_rule_update(context, watch_id, values) @classmethod def create(cls, context, values): return cls._from_db_object(context, cls(), db_api.watch_rule_create(context, values)) @classmethod def delete(cls, context, watch_id): db_api.watch_rule_delete(context, watch_id)
class Resource( base.VersionedObject, base.VersionedObjectDictCompat, base.ComparableVersionedObject, ): fields = { 'id': fields.IntegerField(), 'uuid': fields.StringField(), 'stack_id': fields.StringField(), 'created_at': fields.DateTimeField(read_only=True), 'updated_at': fields.DateTimeField(nullable=True), 'nova_instance': fields.StringField(nullable=True), 'name': fields.StringField(nullable=True), 'status': fields.StringField(nullable=True), 'status_reason': fields.StringField(nullable=True), 'action': fields.StringField(nullable=True), 'rsrc_metadata': heat_fields.JsonField(nullable=True), 'properties_data': heat_fields.JsonField(nullable=True), 'properties_data_encrypted': fields.BooleanField(default=False), 'data': fields.ListOfObjectsField( resource_data.ResourceData, nullable=True ), 'stack': fields.ObjectField(stack.Stack), 'engine_id': fields.StringField(nullable=True), 'atomic_key': fields.IntegerField(nullable=True), 'current_template_id': fields.IntegerField(), 'needed_by': heat_fields.ListField(nullable=True, default=None), 'requires': heat_fields.ListField(nullable=True, default=None), 'replaces': fields.IntegerField(nullable=True), 'replaced_by': fields.IntegerField(nullable=True), } @staticmethod def _from_db_object(resource, context, db_resource): if db_resource is None: return None for field in resource.fields: if field == 'data': resource['data'] = map( lambda resd: resource_data.ResourceData._from_db_object( resource_data.ResourceData(context), resd ), db_resource.data ) else: resource[field] = db_resource[field] if resource.properties_data_encrypted and resource.properties_data: properties_data = {} for prop_name, prop_value in resource.properties_data.items(): method, value = prop_value decrypted_value = crypt.decrypt(method, value) prop_string = jsonutils.loads(decrypted_value) properties_data[prop_name] = prop_string resource.properties_data = properties_data resource._context = context resource.obj_reset_changes() return resource @classmethod def get_obj(cls, context, resource_id): resource_db = db_api.resource_get(context, resource_id) return cls._from_db_object(cls(context), context, resource_db) @classmethod def get_all(cls, context): resources_db = db_api.resource_get_all(context) resources = [ ( resource_name, cls._from_db_object(cls(context), context, resource_db) ) for resource_name, resource_db in six.iteritems(resources_db) ] return dict(resources) @classmethod def create(cls, context, values): return cls._from_db_object(cls(context), context, db_api.resource_create(context, values)) @classmethod def delete(cls, context, resource_id): resource_db = db_api.resource_get(context, resource_id) resource_db.delete() @classmethod def exchange_stacks(cls, context, resource_id1, resource_id2): return db_api.resource_exchange_stacks( context, resource_id1, resource_id2) @classmethod def get_all_by_stack(cls, context, stack_id, key_id=False): resources_db = db_api.resource_get_all_by_stack(context, stack_id, key_id) resources = [ ( resource_key, cls._from_db_object(cls(context), context, resource_db) ) for resource_key, resource_db in six.iteritems(resources_db) ] return dict(resources) @classmethod def get_by_name_and_stack(cls, context, resource_name, stack_id): resource_db = db_api.resource_get_by_name_and_stack( context, resource_name, stack_id) return cls._from_db_object(cls(context), context, resource_db) @classmethod def get_by_physical_resource_id(cls, context, physical_resource_id): resource_db = db_api.resource_get_by_physical_resource_id( context, physical_resource_id) return cls._from_db_object(cls(context), context, resource_db) def update_and_save(self, values): resource_db = db_api.resource_get(self._context, self.id) resource_db.update_and_save(values) return self.refresh() def select_and_update(self, values, expected_engine_id=None, atomic_key=0): return db_api.resource_update(self._context, self.id, values, atomic_key=atomic_key, expected_engine_id=expected_engine_id) def refresh(self, attrs=None): resource_db = db_api.resource_get(self._context, self.id) resource_db.refresh(attrs=attrs) return self.__class__._from_db_object( self, self._context, resource_db) @staticmethod def encrypt_properties_data(data): if cfg.CONF.encrypt_parameters_and_properties and data: result = {} for prop_name, prop_value in data.items(): prop_string = jsonutils.dumps(prop_value) encrypted_value = crypt.encrypt(prop_string) result[prop_name] = encrypted_value return (True, result) return (False, data)
class Resource( heat_base.HeatObject, base.VersionedObjectDictCompat, base.ComparableVersionedObject, ): fields = { 'id': fields.IntegerField(), 'uuid': fields.StringField(), 'stack_id': fields.StringField(), 'created_at': fields.DateTimeField(read_only=True), 'updated_at': fields.DateTimeField(nullable=True), 'physical_resource_id': fields.StringField(nullable=True), 'name': fields.StringField(nullable=True), 'status': fields.StringField(nullable=True), 'status_reason': fields.StringField(nullable=True), 'action': fields.StringField(nullable=True), 'attr_data': fields.ObjectField(rpd.ResourcePropertiesData, nullable=True), 'attr_data_id': fields.IntegerField(nullable=True), 'rsrc_metadata': heat_fields.JsonField(nullable=True), 'data': fields.ListOfObjectsField(resource_data.ResourceData, nullable=True), 'rsrc_prop_data_id': fields.ObjectField(fields.IntegerField(nullable=True)), 'engine_id': fields.StringField(nullable=True), 'atomic_key': fields.IntegerField(nullable=True), 'current_template_id': fields.IntegerField(), 'needed_by': heat_fields.ListField(nullable=True, default=None), 'requires': heat_fields.ListField(nullable=True, default=None), 'replaces': fields.IntegerField(nullable=True), 'replaced_by': fields.IntegerField(nullable=True), 'root_stack_id': fields.StringField(nullable=True), } @staticmethod def _from_db_object(resource, context, db_resource, only_fields=None): if db_resource is None: return None for field in resource.fields: if (only_fields is not None and field not in only_fields and field != 'id'): continue if field == 'data': resource['data'] = [ resource_data.ResourceData._from_db_object( resource_data.ResourceData(context), resd) for resd in db_resource.data ] elif field != 'attr_data': resource[field] = db_resource[field] if db_resource['rsrc_prop_data_id'] is not None: if hasattr(db_resource, '__dict__'): rpd_obj = db_resource.__dict__.get('rsrc_prop_data') else: rpd_obj = None if rpd_obj is not None: # Object is already eager loaded rpd_obj = (rpd.ResourcePropertiesData._from_db_object( rpd.ResourcePropertiesData(), context, rpd_obj)) resource._properties_data = rpd_obj.data else: resource._properties_data = {} if db_resource['properties_data']: LOG.error( 'Unexpected condition where resource.rsrc_prop_data ' 'and resource.properties_data are both not null. ' 'rsrc_prop_data.id: %(rsrc_prop_data_id)s, ' 'resource id: %(res_id)s', { 'rsrc_prop_data_id': resource['rsrc_prop_data'].id, 'res_id': resource['id'] }) elif db_resource['properties_data']: # legacy field if db_resource['properties_data_encrypted']: decrypted_data = crypt.decrypted_dict( db_resource['properties_data']) resource._properties_data = decrypted_data else: resource._properties_data = db_resource['properties_data'] else: resource._properties_data = None if db_resource['attr_data'] is not None: resource._attr_data = rpd.ResourcePropertiesData._from_db_object( rpd.ResourcePropertiesData(context), context, db_resource['attr_data']).data else: resource._attr_data = None resource._context = context resource.obj_reset_changes() return resource @property def attr_data(self): return self._attr_data @property def properties_data(self): if (not self._properties_data and self.rsrc_prop_data_id is not None): LOG.info('rsrc_prop_data lazy load') rpd_obj = rpd.ResourcePropertiesData.get_by_id( self._context, self.rsrc_prop_data_id) self._properties_data = rpd_obj.data or {} return self._properties_data @classmethod def get_obj(cls, context, resource_id, refresh=False, fields=None): if fields is None or 'data' in fields: refresh_data = refresh else: refresh_data = False resource_db = db_api.resource_get(context, resource_id, refresh=refresh, refresh_data=refresh_data) return cls._from_db_object(cls(context), context, resource_db, only_fields=fields) @classmethod def get_all(cls, context): resources_db = db_api.resource_get_all(context) resources = [(resource_name, cls._from_db_object(cls(context), context, resource_db)) for resource_name, resource_db in resources_db.items()] return dict(resources) @classmethod def create(cls, context, values): return cls._from_db_object(cls(context), context, db_api.resource_create(context, values)) @classmethod def replacement(cls, context, existing_res_id, existing_res_values, new_res_values, atomic_key=0, expected_engine_id=None): replacement = db_api.resource_create_replacement( context, existing_res_id, existing_res_values, new_res_values, atomic_key, expected_engine_id) if replacement is None: return None return cls._from_db_object(cls(context), context, replacement) @classmethod def delete(cls, context, resource_id): db_api.resource_delete(context, resource_id) @classmethod def attr_data_delete(cls, context, resource_id, attr_id): db_api.resource_attr_data_delete(context, resource_id, attr_id) @classmethod def exchange_stacks(cls, context, resource_id1, resource_id2): return db_api.resource_exchange_stacks(context, resource_id1, resource_id2) @classmethod def get_all_by_stack(cls, context, stack_id, filters=None): cache = context.cache(ResourceCache) resources = cache.by_stack_id_name.get(stack_id) if resources: return dict(resources) resources_db = db_api.resource_get_all_by_stack( context, stack_id, filters) return cls._resources_to_dict(context, resources_db) @classmethod def _resources_to_dict(cls, context, resources_db): resources = [(resource_name, cls._from_db_object(cls(context), context, resource_db)) for resource_name, resource_db in resources_db.items()] return dict(resources) @classmethod def get_all_active_by_stack(cls, context, stack_id): resources_db = db_api.resource_get_all_active_by_stack( context, stack_id) resources = [(resource_id, cls._from_db_object(cls(context), context, resource_db)) for resource_id, resource_db in resources_db.items()] return dict(resources) @classmethod def get_all_by_root_stack(cls, context, stack_id, filters, cache=False): resources_db = db_api.resource_get_all_by_root_stack( context, stack_id, filters) all = cls._resources_to_dict(context, resources_db) if cache: context.cache(ResourceCache).set_by_stack_id(all) return all @classmethod def get_all_stack_ids_by_root_stack(cls, context, stack_id): resources_db = db_api.resource_get_all_by_root_stack( context, stack_id, stack_id_only=True) return {db_res.stack_id for db_res in resources_db.values()} @classmethod def purge_deleted(cls, context, stack_id): return db_api.resource_purge_deleted(context, stack_id) @classmethod def get_by_name_and_stack(cls, context, resource_name, stack_id): resource_db = db_api.resource_get_by_name_and_stack( context, resource_name, stack_id) return cls._from_db_object(cls(context), context, resource_db) @classmethod def get_all_by_physical_resource_id(cls, context, physical_resource_id): matches = db_api.resource_get_all_by_physical_resource_id( context, physical_resource_id) return [ cls._from_db_object(cls(context), context, resource_db) for resource_db in matches ] @classmethod def update_by_id(cls, context, resource_id, values): db_api.resource_update_and_save(context, resource_id, values) def update_and_save(self, values): db_api.resource_update_and_save(self._context, self.id, values) def select_and_update(self, values, expected_engine_id=None, atomic_key=0): return db_api.resource_update(self._context, self.id, values, atomic_key=atomic_key, expected_engine_id=expected_engine_id) @classmethod def select_and_update_by_id(cls, context, resource_id, values, expected_engine_id=None, atomic_key=0): return db_api.resource_update(context, resource_id, values, atomic_key=atomic_key, expected_engine_id=expected_engine_id) @classmethod def store_attributes(cls, context, resource_id, atomic_key, attr_data, attr_id): attr_id = rpd.ResourcePropertiesData.create_or_update( context, attr_data, attr_id).id if db_api.resource_attr_id_set(context, resource_id, atomic_key, attr_id): return attr_id return None def refresh(self): resource_db = db_api.resource_get(self._context, self.id, refresh=True) return self.__class__._from_db_object(self, self._context, resource_db) def convert_to_convergence(self, current_template_id, requires): return self.update_and_save({ 'current_template_id': current_template_id, 'requires': sorted(requires, reverse=True), }) @staticmethod def encrypt_properties_data(data): if cfg.CONF.encrypt_parameters_and_properties and data: result = crypt.encrypted_dict(data) return (True, result) return (False, data) def update_metadata(self, metadata): if self.rsrc_metadata != metadata: rows_updated = self.select_and_update({'rsrc_metadata': metadata}, self.engine_id, self.atomic_key) if not rows_updated: action = _('metadata setting for resource %s') % self.name raise exception.ConcurrentTransaction(action=action) return True else: return False
class Stack( base.VersionedObject, base.VersionedObjectDictCompat, base.ComparableVersionedObject, ): fields = { 'id': fields.StringField(), 'name': fields.StringField(), 'raw_template_id': fields.IntegerField(), 'backup': fields.BooleanField(), 'created_at': fields.DateTimeField(read_only=True), 'deleted_at': fields.DateTimeField(nullable=True), 'disable_rollback': fields.BooleanField(), 'nested_depth': fields.IntegerField(), 'owner_id': fields.StringField(nullable=True), 'stack_user_project_id': fields.StringField(nullable=True), 'tenant': fields.StringField(nullable=True), 'timeout': fields.IntegerField(nullable=True), 'updated_at': fields.DateTimeField(nullable=True), 'user_creds_id': fields.StringField(nullable=True), 'username': fields.StringField(nullable=True), 'action': fields.StringField(nullable=True), 'status': fields.StringField(nullable=True), 'status_reason': fields.StringField(nullable=True), 'raw_template': fields.ObjectField('RawTemplate'), 'convergence': fields.BooleanField(), 'current_traversal': fields.StringField(), 'current_deps': heat_fields.JsonField(), 'prev_raw_template_id': fields.IntegerField(), 'prev_raw_template': fields.ObjectField('RawTemplate'), 'tags': fields.ObjectField('StackTagList'), 'parent_resource_name': fields.StringField(nullable=True), } @staticmethod def _from_db_object(context, stack, db_stack): for field in stack.fields: if field == 'raw_template': stack['raw_template'] = (raw_template.RawTemplate.get_by_id( context, db_stack['raw_template_id'])) elif field == 'tags': if db_stack.get(field) is not None: stack['tags'] = stack_tag.StackTagList.get( context, db_stack['id']) else: stack['tags'] = None else: stack[field] = db_stack.__dict__.get(field) stack._context = context stack.obj_reset_changes() return stack @classmethod def get_by_id(cls, context, stack_id, **kwargs): db_stack = db_api.stack_get(context, stack_id, **kwargs) if not db_stack: return db_stack stack = cls._from_db_object(context, cls(context), db_stack) return stack @classmethod def get_by_name_and_owner_id(cls, context, stack_name, owner_id): db_stack = db_api.stack_get_by_name_and_owner_id( context, stack_name, owner_id) if not db_stack: return db_stack stack = cls._from_db_object(context, cls(context), db_stack) return stack @classmethod def get_by_name(cls, context, stack_name): db_stack = db_api.stack_get_by_name(context, stack_name) if not db_stack: return db_stack stack = cls._from_db_object(context, cls(context), db_stack) return stack @classmethod def get_all(cls, context, *args, **kwargs): db_stacks = db_api.stack_get_all(context, *args, **kwargs) stacks = map( lambda db_stack: cls._from_db_object(context, cls(context), db_stack), db_stacks) return stacks @classmethod def get_all_by_owner_id(cls, context, owner_id): db_stacks = db_api.stack_get_all_by_owner_id(context, owner_id) stacks = map( lambda db_stack: cls._from_db_object(context, cls(context), db_stack), db_stacks) return stacks @classmethod def count_all(cls, context, **kwargs): return db_api.stack_count_all(context, **kwargs) @classmethod def create(cls, context, values): return db_api.stack_create(context, values) @classmethod def update_by_id(cls, context, stack_id, values): return db_api.stack_update(context, stack_id, values) @classmethod def delete(cls, context, stack_id): return db_api.stack_delete(context, stack_id) def update_and_save(self, values): db_stack = self.__class__.update_by_id(self._context, self.id, values) self.refresh() return db_stack def __eq__(self, another): self.refresh() # to make test object comparison work well return super(Stack, self).__eq__(another) def refresh(self): db_stack = db_api.stack_get(self._context, self.id, show_deleted=True) db_stack.refresh() return self.__class__._from_db_object(self._context, self, db_stack)