Beispiel #1
0
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)
Beispiel #2
0
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)
Beispiel #3
0
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))
Beispiel #4
0
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))
Beispiel #5
0
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)
Beispiel #6
0
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)
        ]
Beispiel #7
0
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)
Beispiel #8
0
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)
Beispiel #9
0
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)
Beispiel #10
0
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))
Beispiel #11
0
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)
Beispiel #12
0
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)
Beispiel #13
0
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)
Beispiel #15
0
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()
Beispiel #16
0
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)
Beispiel #17
0
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)
Beispiel #19
0
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)
Beispiel #20
0
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)
Beispiel #21
0
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
Beispiel #22
0
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)