Exemplo n.º 1
0
    def setUp(self):
        cfg.CONF.set_override("enable_authentication",
                              False,
                              enforce_type=True)
        # To use in-memory SQLite DB
        cfg.CONF.set_override("connection",
                              "sqlite://",
                              group="database",
                              enforce_type=True)
        cfg.CONF.set_override("sqlite_db",
                              "",
                              group="database",
                              enforce_type=True)

        super(DbTestCase, self).setUp()

        self.dbapi = dbapi.get_instance()

        global _DB_CACHE
        if not _DB_CACHE:
            _DB_CACHE = Database(sqla_api,
                                 migration,
                                 sql_connection=CONF.database.connection,
                                 sqlite_db=CONF.database.sqlite_db,
                                 sqlite_clean_db='clean.sqlite')
        self.useFixture(_DB_CACHE)
Exemplo n.º 2
0
def create_test_action_desc(**kwargs):
    """Create test action description entry in DB and return ActionDescription.

    Function to be used to create test ActionDescription objects in the DB.
    :param kwargs: kwargs with overriding values for service's attributes.
    :returns: Test ActionDescription DB object.
    """
    action_desc = get_test_action_desc(**kwargs)
    dbapi = db_api.get_instance()
    return dbapi.create_action_description(action_desc)
Exemplo n.º 3
0
def create_test_strategy(**kwargs):
    """Create test strategy entry in DB and return Strategy DB object.

    Function to be used to create test Strategy objects in the database.
    :param kwargs: kwargs with overriding values for strategy's attributes.
    :returns: Test Strategy DB object.
    """
    strategy = get_test_strategy(**kwargs)
    dbapi = db_api.get_instance()
    return dbapi.create_strategy(strategy)
Exemplo n.º 4
0
def create_test_scoring_engine(**kwargs):
    """Create test scoring engine in DB and return ScoringEngine DB object.

    Function to be used to create test ScoringEngine objects in the database.
    :param kwargs: kwargs with overriding values for SE'sattributes.
    :returns: Test ScoringEngine DB object.
    """
    scoring_engine = get_test_scoring_engine(**kwargs)
    dbapi = db_api.get_instance()
    return dbapi.create_scoring_engine(scoring_engine)
Exemplo n.º 5
0
def create_test_goal(**kwargs):
    """Create test goal entry in DB and return Goal DB object.

    Function to be used to create test Goal objects in the database.
    :param kwargs: kwargs which override default goal values of its attributes.
    :returns: Test Goal DB object.
    """
    goal = get_test_goal(**kwargs)
    dbapi = db_api.get_instance()
    return dbapi.create_goal(goal)
Exemplo n.º 6
0
def create_test_scoring_engine(**kwargs):
    """Create test scoring engine in DB and return ScoringEngine DB object.

    Function to be used to create test ScoringEngine objects in the database.
    :param kwargs: kwargs with overriding values for SE'sattributes.
    :returns: Test ScoringEngine DB object.
    """
    scoring_engine = get_test_scoring_engine(**kwargs)
    dbapi = db_api.get_instance()
    return dbapi.create_scoring_engine(scoring_engine)
Exemplo n.º 7
0
def create_test_goal(**kwargs):
    """Create test goal entry in DB and return Goal DB object.

    Function to be used to create test Goal objects in the database.
    :param kwargs: kwargs which override default goal values of its attributes.
    :returns: Test Goal DB object.
    """
    goal = get_test_goal(**kwargs)
    dbapi = db_api.get_instance()
    return dbapi.create_goal(goal)
Exemplo n.º 8
0
def create_test_service(**kwargs):
    """Create test service entry in DB and return Service DB object.

    Function to be used to create test Service objects in the database.
    :param kwargs: kwargs with overriding values for service's attributes.
    :returns: Test Service DB object.
    """
    service = get_test_service(**kwargs)
    dbapi = db_api.get_instance()
    return dbapi.create_service(service)
Exemplo n.º 9
0
def create_test_strategy(**kwargs):
    """Create test strategy entry in DB and return Strategy DB object.

    Function to be used to create test Strategy objects in the database.
    :param kwargs: kwargs with overriding values for strategy's attributes.
    :returns: Test Strategy DB object.
    """
    strategy = get_test_strategy(**kwargs)
    dbapi = db_api.get_instance()
    return dbapi.create_strategy(strategy)
Exemplo n.º 10
0
def _load_relationships(model, db_data):
    rel_data = {}
    relationships = db_api.get_instance()._get_relationships(model)
    for name, relationship in relationships.items():
        related_model = relationship.argument
        if not db_data.get(name):
            rel_data[name] = None
        else:
            rel_data[name] = related_model(**db_data.get(name))

    return rel_data
Exemplo n.º 11
0
def create_test_action_plan(**kwargs):
    """Create test action plan entry in DB and return Action Plan DB object.

    Function to be used to create test Action objects in the database.
    :param kwargs: kwargsargs with overriding values for action's attributes.
    :returns: Test Action DB object.
    """
    action = get_test_action_plan(**kwargs)
    # Let DB generate ID if it isn't specified explicitly
    if 'id' not in kwargs:
        del action['id']
    dbapi = db_api.get_instance()
    return dbapi.create_action_plan(action)
Exemplo n.º 12
0
def create_test_audit(**kwargs):
    """Create test audit entry in DB and return Audit DB object.

    Function to be used to create test Audit objects in the database.
    :param kwargs: kwargsargs with overriding values for audit's attributes.
    :returns: Test Audit DB object.
    """
    audit = get_test_audit(**kwargs)
    # Let DB generate ID if it isn't specified explicitly
    if 'id' not in kwargs:
        del audit['id']
    dbapi = db_api.get_instance()
    return dbapi.create_audit(audit)
Exemplo n.º 13
0
def create_test_efficacy_indicator(**kwargs):
    """Create and return a test efficacy indicator entry in DB.

    Function to be used to create test EfficacyIndicator objects in the DB.
    :param kwargs: kwargs for overriding the values of the attributes
    :returns: Test EfficacyIndicator DB object.
    """
    efficacy_indicator = get_test_efficacy_indicator(**kwargs)
    # Let DB generate ID if it isn't specified explicitly
    if 'id' not in kwargs:
        del efficacy_indicator['id']
    dbapi = db_api.get_instance()
    return dbapi.create_efficacy_indicator(efficacy_indicator)
Exemplo n.º 14
0
def create_test_audit(**kwargs):
    """Create test audit entry in DB and return Audit DB object.

    Function to be used to create test Audit objects in the database.
    :param kwargs: kwargsargs with overriding values for audit's attributes.
    :returns: Test Audit DB object.
    """
    audit = get_test_audit(**kwargs)
    # Let DB generate ID if it isn't specified explicitly
    if 'id' not in kwargs:
        del audit['id']
    dbapi = db_api.get_instance()
    return dbapi.create_audit(audit)
Exemplo n.º 15
0
def create_test_action_plan(**kwargs):
    """Create test action plan entry in DB and return Action Plan DB object.

    Function to be used to create test Action objects in the database.
    :param kwargs: kwargsargs with overriding values for action's attributes.
    :returns: Test Action DB object.
    """
    action = get_test_action_plan(**kwargs)
    # Let DB generate ID if it isn't specified explicitly
    if 'id' not in kwargs:
        del action['id']
    dbapi = db_api.get_instance()
    return dbapi.create_action_plan(action)
Exemplo n.º 16
0
def create_test_efficacy_indicator(**kwargs):
    """Create and return a test efficacy indicator entry in DB.

    Function to be used to create test EfficacyIndicator objects in the DB.
    :param kwargs: kwargs for overriding the values of the attributes
    :returns: Test EfficacyIndicator DB object.
    """
    efficacy_indicator = get_test_efficacy_indicator(**kwargs)
    # Let DB generate ID if it isn't specified explicitly
    if 'id' not in kwargs:
        del efficacy_indicator['id']
    dbapi = db_api.get_instance()
    return dbapi.create_efficacy_indicator(efficacy_indicator)
Exemplo n.º 17
0
    def setUp(self):
        cfg.CONF.set_override("enable_authentication", False,
                              enforce_type=True)
        super(DbTestCase, self).setUp()

        self.dbapi = dbapi.get_instance()

        global _DB_CACHE
        if not _DB_CACHE:
            _DB_CACHE = Database(sqla_api, migration,
                                 sql_connection=CONF.database.connection,
                                 sqlite_db=CONF.database.sqlite_db,
                                 sqlite_clean_db='clean.sqlite')
        self.useFixture(_DB_CACHE)
Exemplo n.º 18
0
    def setUp(self):
        cfg.CONF.set_override("enable_authentication", False)
        # To use in-memory SQLite DB
        cfg.CONF.set_override("connection", "sqlite://", group="database")

        super(DbTestCase, self).setUp()

        self.dbapi = dbapi.get_instance()

        global _DB_CACHE
        if not _DB_CACHE:
            _DB_CACHE = Database(sqla_api,
                                 migration,
                                 sql_connection=CONF.database.connection)
        self.useFixture(_DB_CACHE)
        self._id_gen = utils.id_generator()
Exemplo n.º 19
0
class ActionPlan(base.WatcherPersistentObject, base.WatcherObject,
                 base.WatcherObjectDictCompat):

    # Version 1.0: Initial version
    # Version 1.1: Added 'audit' and 'strategy' object field
    # Version 1.2: audit_id is not nullable anymore
    # Version 2.0: Removed 'first_action_id' object field
    VERSION = '2.0'

    dbapi = db_api.get_instance()

    fields = {
        'id': wfields.IntegerField(),
        'uuid': wfields.UUIDField(),
        'audit_id': wfields.IntegerField(),
        'strategy_id': wfields.IntegerField(),
        'state': wfields.StringField(nullable=True),
        'global_efficacy': wfields.FlexibleDictField(nullable=True),
        'audit': wfields.ObjectField('Audit', nullable=True),
        'strategy': wfields.ObjectField('Strategy', nullable=True),
    }

    object_fields = {
        'audit': (objects.Audit, 'audit_id'),
        'strategy': (objects.Strategy, 'strategy_id'),
    }

    # Proxified field so we can keep the previous value after an update
    _state = None
    _old_state = None

    # NOTE(v-francoise): The way oslo.versionedobjects works is by using a
    # __new__ that will automatically create the attributes referenced in
    # fields. These attributes are properties that raise an exception if no
    # value has been assigned, which means that they store the actual field
    # value in an "_obj_%(field)s" attribute. So because we want to proxify a
    # value that is already proxified, we have to do what you see below.
    @property
    def _obj_state(self):
        return self._state

    @property
    def _obj_old_state(self):
        return self._old_state

    @property
    def old_state(self):
        return self._old_state

    @_obj_old_state.setter
    def _obj_old_state(self, value):
        self._old_state = value

    @_obj_state.setter
    def _obj_state(self, value):
        if self._old_state is None and self._state is None:
            self._state = value
        else:
            self._old_state, self._state = self._state, value

    @base.remotable_classmethod
    def get(cls, context, action_plan_id, eager=False):
        """Find a action_plan based on its id or uuid and return a Action object.

        :param action_plan_id: the id *or* uuid of a action_plan.
        :param eager: Load object fields if True (Default: False)
        :returns: a :class:`Action` object.
        """
        if utils.is_int_like(action_plan_id):
            return cls.get_by_id(context, action_plan_id, eager=eager)
        elif utils.is_uuid_like(action_plan_id):
            return cls.get_by_uuid(context, action_plan_id, eager=eager)
        else:
            raise exception.InvalidIdentity(identity=action_plan_id)

    @base.remotable_classmethod
    def get_by_id(cls, context, action_plan_id, eager=False):
        """Find a action_plan based on its integer id and return a ActionPlan object.

        :param action_plan_id: the id of a action_plan.
        :param eager: Load object fields if True (Default: False)
        :returns: a :class:`ActionPlan` object.
        """
        db_action_plan = cls.dbapi.get_action_plan_by_id(context,
                                                         action_plan_id,
                                                         eager=eager)
        action_plan = cls._from_db_object(cls(context),
                                          db_action_plan,
                                          eager=eager)
        return action_plan

    @base.remotable_classmethod
    def get_by_uuid(cls, context, uuid, eager=False):
        """Find a action_plan based on uuid and return a :class:`ActionPlan` object.

        :param uuid: the uuid of a action_plan.
        :param context: Security context
        :param eager: Load object fields if True (Default: False)
        :returns: a :class:`ActionPlan` object.
        """
        db_action_plan = cls.dbapi.get_action_plan_by_uuid(context,
                                                           uuid,
                                                           eager=eager)
        action_plan = cls._from_db_object(cls(context),
                                          db_action_plan,
                                          eager=eager)
        return action_plan

    @base.remotable_classmethod
    def list(cls,
             context,
             limit=None,
             marker=None,
             filters=None,
             sort_key=None,
             sort_dir=None,
             eager=False):
        """Return a list of ActionPlan objects.

        :param context: Security context.
        :param limit: maximum number of resources to return in a single result.
        :param marker: pagination marker for large data sets.
        :param filters: Filters to apply. Defaults to None.
        :param sort_key: column to sort results by.
        :param sort_dir: direction to sort. "asc" or "desc".
        :param eager: Load object fields if True (Default: False)
        :returns: a list of :class:`ActionPlan` object.
        """
        db_action_plans = cls.dbapi.get_action_plan_list(context,
                                                         limit=limit,
                                                         marker=marker,
                                                         filters=filters,
                                                         sort_key=sort_key,
                                                         sort_dir=sort_dir,
                                                         eager=eager)

        return [
            cls._from_db_object(cls(context), obj, eager=eager)
            for obj in db_action_plans
        ]

    @base.remotable
    def create(self):
        """Create an :class:`ActionPlan` record in the DB.

        :returns: An :class:`ActionPlan` object.
        """
        values = self.obj_get_changes()
        db_action_plan = self.dbapi.create_action_plan(values)
        # Note(v-francoise): Always load eagerly upon creation so we can send
        # notifications containing information about the related relationships
        self._from_db_object(self, db_action_plan, eager=True)

        def _notify():
            notifications.action_plan.send_create(self._context, self)

        _notify()

    @base.remotable
    def destroy(self):
        """Delete the action plan from the DB"""
        related_efficacy_indicators = objects.EfficacyIndicator.list(
            context=self._context, filters={"action_plan_uuid": self.uuid})

        # Cascade soft_delete of related efficacy indicators
        for related_efficacy_indicator in related_efficacy_indicators:
            related_efficacy_indicator.destroy()

        self.dbapi.destroy_action_plan(self.uuid)
        self.obj_reset_changes()

    @base.remotable
    def save(self):
        """Save updates to this Action plan.

        Updates will be made column by column based on the result
        of self.what_changed().
        """
        updates = self.obj_get_changes()
        db_obj = self.dbapi.update_action_plan(self.uuid, updates)
        obj = self._from_db_object(self.__class__(self._context),
                                   db_obj,
                                   eager=False)
        self.obj_refresh(obj)

        def _notify():
            notifications.action_plan.send_update(self._context,
                                                  self,
                                                  old_state=self.old_state)

        _notify()

        self.obj_reset_changes()

    @base.remotable
    def refresh(self, eager=False):
        """Loads updates for this Action plan.

        Loads a action_plan with the same uuid from the database and
        checks for updated attributes. Updates are applied from
        the loaded action_plan column by column, if there are any updates.
        :param eager: Load object fields if True (Default: False)
        """
        current = self.get_by_uuid(self._context, uuid=self.uuid, eager=eager)
        self.obj_refresh(current)

    @base.remotable
    def soft_delete(self):
        """Soft Delete the Action plan from the DB"""
        related_actions = objects.Action.list(
            context=self._context, filters={"action_plan_uuid": self.uuid})

        # Cascade soft_delete of related actions
        for related_action in related_actions:
            related_action.soft_delete()

        related_efficacy_indicators = objects.EfficacyIndicator.list(
            context=self._context, filters={"action_plan_uuid": self.uuid})

        # Cascade soft_delete of related efficacy indicators
        for related_efficacy_indicator in related_efficacy_indicators:
            related_efficacy_indicator.soft_delete()

        self.state = State.DELETED
        self.save()
        db_obj = self.dbapi.soft_delete_action_plan(self.uuid)
        obj = self._from_db_object(self.__class__(self._context),
                                   db_obj,
                                   eager=False)
        self.obj_refresh(obj)

        def _notify():
            notifications.action_plan.send_delete(self._context, self)

        _notify()
Exemplo n.º 20
0
class Service(base.WatcherObject):

    dbapi = dbapi.get_instance()

    fields = {
        'id': int,
        'name': obj_utils.str_or_none,
        'host': obj_utils.str_or_none,
        'last_seen_up': obj_utils.datetime_or_str_or_none
    }

    @staticmethod
    def _from_db_object(service, db_service):
        """Converts a database entity to a formal object."""
        for field in service.fields:
            service[field] = db_service[field]

        service.obj_reset_changes()
        return service

    @staticmethod
    def _from_db_object_list(db_objects, cls, context):
        """Converts a list of database entities to a list of formal objects."""
        return [Service._from_db_object(cls(context), obj)
                for obj in db_objects]

    @classmethod
    def get(cls, context, service_id):
        """Find a service based on its id

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: Service(context)
        :param service_id: the id of a service.
        :returns: a :class:`Service` object.
        """
        if utils.is_int_like(service_id):
            db_service = cls.dbapi.get_service_by_id(context, service_id)
            service = Service._from_db_object(cls(context), db_service)
            return service
        else:
            raise exception.InvalidIdentity(identity=service_id)

    @classmethod
    def get_by_name(cls, context, name):
        """Find a service based on name

        :param name: the name of a service.
        :param context: Security context
        :returns: a :class:`Service` object.
        """

        db_service = cls.dbapi.get_service_by_name(context, name)
        service = cls._from_db_object(cls(context), db_service)
        return service

    @classmethod
    def list(cls, context, limit=None, marker=None, filters=None,
             sort_key=None, sort_dir=None):
        """Return a list of :class:`Service` objects.

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: Service(context)
        :param filters: dict mapping the filter key to a value.
        :param limit: maximum number of resources to return in a single result.
        :param marker: pagination marker for large data sets.
        :param sort_key: column to sort results by.
        :param sort_dir: direction to sort. "asc" or "desc".
        :returns: a list of :class:`Service` object.
        """
        db_services = cls.dbapi.get_service_list(
            context,
            filters=filters,
            limit=limit,
            marker=marker,
            sort_key=sort_key,
            sort_dir=sort_dir)
        return Service._from_db_object_list(db_services, cls, context)

    def create(self, context=None):
        """Create a :class:`Service` record in the DB.

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: Service(context)
        """

        values = self.obj_get_changes()
        db_service = self.dbapi.create_service(values)
        self._from_db_object(self, db_service)

    def save(self, context=None):
        """Save updates to this :class:`Service`.

        Updates will be made column by column based on the result
        of self.what_changed().

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: Service(context)
        """
        updates = self.obj_get_changes()
        self.dbapi.update_service(self.id, updates)

        self.obj_reset_changes()

    def refresh(self, context=None):
        """Loads updates for this :class:`Service`.

        Loads a service with the same id from the database and
        checks for updated attributes. Updates are applied from
        the loaded service column by column, if there are any updates.

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: Service(context)
        """
        current = self.__class__.get(self._context, service_id=self.id)
        for field in self.fields:
            if (hasattr(self, base.get_attrname(field)) and
                    self[field] != current[field]):
                self[field] = current[field]

    def soft_delete(self, context=None):
        """Soft Delete the :class:`Service` from the DB.

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: Service(context)
        """
        self.dbapi.soft_delete_service(self.id)
Exemplo n.º 21
0
class EfficacyIndicator(base.WatcherObject):
    # Version 1.0: Initial version
    VERSION = '1.0'

    dbapi = dbapi.get_instance()

    fields = {
        'id': int,
        'uuid': obj_utils.str_or_none,
        'action_plan_id': obj_utils.int_or_none,
        'name': obj_utils.str_or_none,
        'description': obj_utils.str_or_none,
        'unit': obj_utils.str_or_none,
        'value': obj_utils.numeric_or_none,
    }

    @staticmethod
    def _from_db_object(efficacy_indicator, db_efficacy_indicator):
        """Converts a database entity to a formal object."""
        for field in efficacy_indicator.fields:
            efficacy_indicator[field] = db_efficacy_indicator[field]

        efficacy_indicator.obj_reset_changes()
        return efficacy_indicator

    @staticmethod
    def _from_db_object_list(db_objects, cls, context):
        """Converts a list of database entities to a list of formal objects."""
        return [
            EfficacyIndicator._from_db_object(cls(context), obj)
            for obj in db_objects
        ]

    @classmethod
    def get(cls, context, efficacy_indicator_id):
        """Find an efficacy indicator object given its ID or UUID

        :param efficacy_indicator_id: the ID or UUID of an efficacy indicator.
        :returns: a :class:`EfficacyIndicator` object.
        """
        if utils.is_int_like(efficacy_indicator_id):
            return cls.get_by_id(context, efficacy_indicator_id)
        elif utils.is_uuid_like(efficacy_indicator_id):
            return cls.get_by_uuid(context, efficacy_indicator_id)
        else:
            raise exception.InvalidIdentity(identity=efficacy_indicator_id)

    @classmethod
    def get_by_id(cls, context, efficacy_indicator_id):
        """Find an efficacy indicator given its integer ID

        :param efficacy_indicator_id: the id of an efficacy indicator.
        :returns: a :class:`EfficacyIndicator` object.
        """
        db_efficacy_indicator = cls.dbapi.get_efficacy_indicator_by_id(
            context, efficacy_indicator_id)
        efficacy_indicator = EfficacyIndicator._from_db_object(
            cls(context), db_efficacy_indicator)
        return efficacy_indicator

    @classmethod
    def get_by_uuid(cls, context, uuid):
        """Find an efficacy indicator given its UUID

        :param uuid: the uuid of an efficacy indicator.
        :param context: Security context
        :returns: a :class:`EfficacyIndicator` object.
        """
        db_efficacy_indicator = cls.dbapi.get_efficacy_indicator_by_uuid(
            context, uuid)
        efficacy_indicator = EfficacyIndicator._from_db_object(
            cls(context), db_efficacy_indicator)
        return efficacy_indicator

    @classmethod
    def list(cls,
             context,
             limit=None,
             marker=None,
             filters=None,
             sort_key=None,
             sort_dir=None):
        """Return a list of EfficacyIndicator objects.

        :param context: Security context.
        :param limit: maximum number of resources to return in a single result.
        :param marker: pagination marker for large data sets.
        :param filters: Filters to apply. Defaults to None.
        :param sort_key: column to sort results by.
        :param sort_dir: direction to sort. "asc" or "desc".
        :returns: a list of :class:`EfficacyIndicator` object.

        """
        db_efficacy_indicators = cls.dbapi.get_efficacy_indicator_list(
            context,
            limit=limit,
            marker=marker,
            filters=filters,
            sort_key=sort_key,
            sort_dir=sort_dir)
        return EfficacyIndicator._from_db_object_list(db_efficacy_indicators,
                                                      cls, context)

    def create(self, context=None):
        """Create a EfficacyIndicator record in the DB.

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: EfficacyIndicator(context)

        """
        values = self.obj_get_changes()
        db_efficacy_indicator = self.dbapi.create_efficacy_indicator(values)
        self._from_db_object(self, db_efficacy_indicator)

    def destroy(self, context=None):
        """Delete the EfficacyIndicator from the DB.

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: EfficacyIndicator(context)
        """
        self.dbapi.destroy_efficacy_indicator(self.uuid)
        self.obj_reset_changes()

    def save(self, context=None):
        """Save updates to this EfficacyIndicator.

        Updates will be made column by column based on the result
        of self.what_changed().

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: EfficacyIndicator(context)
        """
        updates = self.obj_get_changes()
        self.dbapi.update_efficacy_indicator(self.uuid, updates)

        self.obj_reset_changes()

    def refresh(self, context=None):
        """Loads updates for this EfficacyIndicator.

        Loads an efficacy indicator with the same uuid from the database and
        checks for updated attributes. Updates are applied to the loaded
        efficacy indicator column by column, if there are any updates.

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: EfficacyIndicator(context)
        """
        current = self.__class__.get_by_uuid(self._context, uuid=self.uuid)
        for field in self.fields:
            if (hasattr(self, base.get_attrname(field))
                    and self[field] != current[field]):
                self[field] = current[field]

    def soft_delete(self, context=None):
        """Soft Delete the efficacy indicator from the DB.

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: Audit(context)
        """
        self.dbapi.soft_delete_efficacy_indicator(self.uuid)
Exemplo n.º 22
0
class Goal(base.WatcherPersistentObject, base.WatcherObject,
           base.WatcherObjectDictCompat):
    # Version 1.0: Initial version
    VERSION = '1.0'

    dbapi = db_api.get_instance()

    fields = {
        'id': wfields.IntegerField(),
        'uuid': wfields.UUIDField(),
        'name': wfields.StringField(),
        'display_name': wfields.StringField(),
        'efficacy_specification': wfields.FlexibleListOfDictField(),
    }

    @base.remotable_classmethod
    def get(cls, context, goal_id):
        """Find a goal based on its id or uuid

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: Goal(context)
        :param goal_id: the id *or* uuid of a goal.
        :returns: a :class:`Goal` object.
        """
        if utils.is_int_like(goal_id):
            return cls.get_by_id(context, goal_id)
        elif utils.is_uuid_like(goal_id):
            return cls.get_by_uuid(context, goal_id)
        else:
            raise exception.InvalidIdentity(identity=goal_id)

    @base.remotable_classmethod
    def get_by_id(cls, context, goal_id):
        """Find a goal based on its integer id

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: Goal(context)
        :param goal_id: the id *or* uuid of a goal.
        :returns: a :class:`Goal` object.
        """
        db_goal = cls.dbapi.get_goal_by_id(context, goal_id)
        goal = cls._from_db_object(cls(context), db_goal)
        return goal

    @base.remotable_classmethod
    def get_by_uuid(cls, context, uuid):
        """Find a goal based on uuid

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: Goal(context)
        :param uuid: the uuid of a goal.
        :returns: a :class:`Goal` object.
        """
        db_goal = cls.dbapi.get_goal_by_uuid(context, uuid)
        goal = cls._from_db_object(cls(context), db_goal)
        return goal

    @base.remotable_classmethod
    def get_by_name(cls, context, name):
        """Find a goal based on name

        :param name: the name of a goal.
        :param context: Security context
        :returns: a :class:`Goal` object.
        """
        db_goal = cls.dbapi.get_goal_by_name(context, name)
        goal = cls._from_db_object(cls(context), db_goal)
        return goal

    @base.remotable_classmethod
    def list(cls, context, limit=None, marker=None, filters=None,
             sort_key=None, sort_dir=None):
        """Return a list of :class:`Goal` objects.

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: Goal(context)
        :param filters: dict mapping the filter key to a value.
        :param limit: maximum number of resources to return in a single result.
        :param marker: pagination marker for large data sets.
        :param sort_key: column to sort results by.
        :param sort_dir: direction to sort. "asc" or "desc".
        :returns: a list of :class:`Goal` object.
        """
        db_goals = cls.dbapi.get_goal_list(
            context,
            filters=filters,
            limit=limit,
            marker=marker,
            sort_key=sort_key,
            sort_dir=sort_dir)

        return [cls._from_db_object(cls(context), obj) for obj in db_goals]

    @base.remotable
    def create(self):
        """Create a :class:`Goal` record in the DB"""
        values = self.obj_get_changes()
        db_goal = self.dbapi.create_goal(values)
        self._from_db_object(self, db_goal)

    def destroy(self):
        """Delete the :class:`Goal` from the DB"""
        self.dbapi.destroy_goal(self.id)
        self.obj_reset_changes()

    @base.remotable
    def save(self):
        """Save updates to this :class:`Goal`.

        Updates will be made column by column based on the result
        of self.what_changed().
        """
        updates = self.obj_get_changes()
        db_obj = self.dbapi.update_goal(self.uuid, updates)
        obj = self._from_db_object(self, db_obj, eager=False)
        self.obj_refresh(obj)
        self.obj_reset_changes()

    @base.remotable
    def refresh(self):
        """Loads updates for this :class:`Goal`.

        Loads a goal with the same uuid from the database and
        checks for updated attributes. Updates are applied from
        the loaded goal column by column, if there are any updates.
        """
        current = self.get_by_uuid(self._context, uuid=self.uuid)
        self.obj_refresh(current)

    @base.remotable
    def soft_delete(self):
        """Soft Delete the :class:`Goal` from the DB"""
        db_obj = self.dbapi.soft_delete_goal(self.uuid)
        obj = self._from_db_object(
            self.__class__(self._context), db_obj, eager=False)
        self.obj_refresh(obj)
Exemplo n.º 23
0
class ActionDescription(base.WatcherPersistentObject, base.WatcherObject,
                        base.WatcherObjectDictCompat):

    # Version 1.0: Initial version
    VERSION = '1.0'

    dbapi = db_api.get_instance()

    fields = {
        'id': wfields.IntegerField(),
        'action_type': wfields.StringField(),
        'description': wfields.StringField(),
    }

    @base.remotable_classmethod
    def get(cls, context, action_id):
        """Find a action description based on its id

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object
        :param action_id: the id of a action description.
        :returns: a :class:`ActionDescription` object.
        """
        if utils.is_int_like(action_id):
            db_action = cls.dbapi.get_action_description_by_id(
                context, action_id)
            action = ActionDescription._from_db_object(cls(context), db_action)
            return action
        else:
            raise exception.InvalidIdentity(identity=action_id)

    @base.remotable_classmethod
    def get_by_type(cls, context, action_type):
        """Find a action description based on action type

        :param action_type: the action type of a action description.
        :param context: Security context
        :returns: a :class:`ActionDescription` object.
        """

        db_action = cls.dbapi.get_action_description_by_type(
            context, action_type)
        action = cls._from_db_object(cls(context), db_action)
        return action

    @base.remotable_classmethod
    def list(cls, context, limit=None, marker=None, filters=None,
             sort_key=None, sort_dir=None):
        """Return a list of :class:`ActionDescription` objects.

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: ActionDescription(context)
        :param filters: dict mapping the filter key to a value.
        :param limit: maximum number of resources to return in a single result.
        :param marker: pagination marker for large data sets.
        :param sort_key: column to sort results by.
        :param sort_dir: direction to sort. "asc" or "desc".
        :returns: a list of :class:`ActionDescription` object.
        """
        db_actions = cls.dbapi.get_action_description_list(
            context,
            filters=filters,
            limit=limit,
            marker=marker,
            sort_key=sort_key,
            sort_dir=sort_dir)

        return [cls._from_db_object(cls(context), obj) for obj in db_actions]

    @base.remotable
    def create(self):
        """Create a :class:`ActionDescription` record in the DB."""
        values = self.obj_get_changes()
        db_action = self.dbapi.create_action_description(values)
        self._from_db_object(self, db_action)

    @base.remotable
    def save(self):
        """Save updates to this :class:`ActionDescription`.

        Updates will be made column by column based on the result
        of self.what_changed().
        """
        updates = self.obj_get_changes()
        db_obj = self.dbapi.update_action_description(self.id, updates)
        obj = self._from_db_object(self, db_obj, eager=False)
        self.obj_refresh(obj)
        self.obj_reset_changes()

    def refresh(self):
        """Loads updates for this :class:`ActionDescription`.

        Loads a action description with the same id from the database and
        checks for updated attributes. Updates are applied from
        the loaded action description column by column, if there
        are any updates.
        """
        current = self.get(self._context, action_id=self.id)
        for field in self.fields:
            if (hasattr(self, base.get_attrname(field)) and
                    self[field] != current[field]):
                self[field] = current[field]

    def soft_delete(self):
        """Soft Delete the :class:`ActionDescription` from the DB."""
        db_obj = self.dbapi.soft_delete_action_description(self.id)
        obj = self._from_db_object(
            self.__class__(self._context), db_obj, eager=False)
        self.obj_refresh(obj)
Exemplo n.º 24
0
class Action(base.WatcherPersistentObject, base.WatcherObject,
             base.WatcherObjectDictCompat):

    # Version 1.0: Initial version
    # Version 1.1: Added 'action_plan' object field
    # Version 2.0: Removed 'next' object field, Added 'parents' object field
    VERSION = '2.0'

    dbapi = db_api.get_instance()

    fields = {
        'id': wfields.IntegerField(),
        'uuid': wfields.UUIDField(),
        'action_plan_id': wfields.IntegerField(),
        'action_type': wfields.StringField(nullable=True),
        'input_parameters': wfields.DictField(nullable=True),
        'state': wfields.StringField(nullable=True),
        'parents': wfields.ListOfStringsField(nullable=True),

        'action_plan': wfields.ObjectField('ActionPlan', nullable=True),
    }
    object_fields = {
        'action_plan': (objects.ActionPlan, 'action_plan_id'),
    }

    @base.remotable_classmethod
    def get(cls, context, action_id, eager=False):
        """Find a action based on its id or uuid and return a Action object.

        :param action_id: the id *or* uuid of a action.
        :param eager: Load object fields if True (Default: False)
        :returns: a :class:`Action` object.
        """
        if utils.is_int_like(action_id):
            return cls.get_by_id(context, action_id, eager=eager)
        elif utils.is_uuid_like(action_id):
            return cls.get_by_uuid(context, action_id, eager=eager)
        else:
            raise exception.InvalidIdentity(identity=action_id)

    @base.remotable_classmethod
    def get_by_id(cls, context, action_id, eager=False):
        """Find a action based on its integer id and return a Action object.

        :param action_id: the id of a action.
        :param eager: Load object fields if True (Default: False)
        :returns: a :class:`Action` object.
        """
        db_action = cls.dbapi.get_action_by_id(context, action_id, eager=eager)
        action = cls._from_db_object(cls(context), db_action, eager=eager)
        return action

    @base.remotable_classmethod
    def get_by_uuid(cls, context, uuid, eager=False):
        """Find a action based on uuid and return a :class:`Action` object.

        :param uuid: the uuid of a action.
        :param context: Security context
        :param eager: Load object fields if True (Default: False)
        :returns: a :class:`Action` object.
        """
        db_action = cls.dbapi.get_action_by_uuid(context, uuid, eager=eager)
        action = cls._from_db_object(cls(context), db_action, eager=eager)
        return action

    @base.remotable_classmethod
    def list(cls, context, limit=None, marker=None, filters=None,
             sort_key=None, sort_dir=None, eager=False):
        """Return a list of Action objects.

        :param context: Security context.
        :param limit: maximum number of resources to return in a single result.
        :param marker: pagination marker for large data sets.
        :param filters: Filters to apply. Defaults to None.
        :param sort_key: column to sort results by.
        :param sort_dir: direction to sort. "asc" or "desc".
        :param eager: Load object fields if True (Default: False)
        :returns: a list of :class:`Action` object.
        """
        db_actions = cls.dbapi.get_action_list(context,
                                               limit=limit,
                                               marker=marker,
                                               filters=filters,
                                               sort_key=sort_key,
                                               sort_dir=sort_dir,
                                               eager=eager)

        return [cls._from_db_object(cls(context), obj, eager=eager)
                for obj in db_actions]

    @base.remotable
    def create(self):
        """Create an :class:`Action` record in the DB.

        :returns: An :class:`Action` object.
        """
        values = self.obj_get_changes()
        db_action = self.dbapi.create_action(values)
        # Note(v-francoise): Always load eagerly upon creation so we can send
        # notifications containing information about the related relationships
        self._from_db_object(self, db_action, eager=True)

        notifications.action.send_create(self.obj_context, self)

    def destroy(self):
        """Delete the Action from the DB"""
        self.dbapi.destroy_action(self.uuid)
        self.obj_reset_changes()

    @base.remotable
    def save(self):
        """Save updates to this Action.

        Updates will be made column by column based on the result
        of self.what_changed().
        """
        updates = self.obj_get_changes()
        db_obj = self.dbapi.update_action(self.uuid, updates)
        obj = self._from_db_object(self, db_obj, eager=False)
        self.obj_refresh(obj)
        notifications.action.send_update(self.obj_context, self)
        self.obj_reset_changes()

    @base.remotable
    def refresh(self, eager=False):
        """Loads updates for this Action.

        Loads a action with the same uuid from the database and
        checks for updated attributes. Updates are applied from
        the loaded action column by column, if there are any updates.
        :param eager: Load object fields if True (Default: False)
        """
        current = self.get_by_uuid(self._context, uuid=self.uuid, eager=eager)
        self.obj_refresh(current)

    @base.remotable
    def soft_delete(self):
        """Soft Delete the Audit from the DB"""
        self.state = State.DELETED
        self.save()
        db_obj = self.dbapi.soft_delete_action(self.uuid)
        obj = self._from_db_object(
            self.__class__(self._context), db_obj, eager=False)
        self.obj_refresh(obj)

        notifications.action.send_delete(self.obj_context, self)
Exemplo n.º 25
0
class Strategy(base.WatcherPersistentObject, base.WatcherObject,
               base.WatcherObjectDictCompat):

    # Version 1.0: Initial version
    # Version 1.1: Added Goal object field
    VERSION = '1.1'

    dbapi = db_api.get_instance()

    fields = {
        'id': wfields.IntegerField(),
        'uuid': wfields.UUIDField(),
        'name': wfields.StringField(),
        'display_name': wfields.StringField(),
        'goal_id': wfields.IntegerField(),
        'parameters_spec': wfields.FlexibleDictField(nullable=True),
        'goal': wfields.ObjectField('Goal', nullable=True),
    }

    object_fields = {'goal': (objects.Goal, 'goal_id')}

    @base.remotable_classmethod
    def get(cls, context, strategy_id, eager=False):
        """Find a strategy based on its id or uuid

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: Strategy(context)
        :param strategy_id: the id *or* uuid of a strategy.
        :param eager: Load object fields if True (Default: False)
        :returns: A :class:`Strategy` object.
        """
        if utils.is_int_like(strategy_id):
            return cls.get_by_id(context, strategy_id, eager=eager)
        elif utils.is_uuid_like(strategy_id):
            return cls.get_by_uuid(context, strategy_id, eager=eager)
        else:
            raise exception.InvalidIdentity(identity=strategy_id)

    @base.remotable_classmethod
    def get_by_id(cls, context, strategy_id, eager=False):
        """Find a strategy based on its integer id

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: Strategy(context)
        :param strategy_id: the id of a strategy.
        :param eager: Load object fields if True (Default: False)
        :returns: A :class:`Strategy` object.
        """
        db_strategy = cls.dbapi.get_strategy_by_id(context,
                                                   strategy_id,
                                                   eager=eager)
        strategy = cls._from_db_object(cls(context), db_strategy, eager=eager)
        return strategy

    @base.remotable_classmethod
    def get_by_uuid(cls, context, uuid, eager=False):
        """Find a strategy based on uuid

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: Strategy(context)
        :param uuid: the uuid of a strategy.
        :param eager: Load object fields if True (Default: False)
        :returns: A :class:`Strategy` object.
        """

        db_strategy = cls.dbapi.get_strategy_by_uuid(context,
                                                     uuid,
                                                     eager=eager)
        strategy = cls._from_db_object(cls(context), db_strategy, eager=eager)
        return strategy

    @base.remotable_classmethod
    def get_by_name(cls, context, name, eager=False):
        """Find a strategy based on name

        :param context: Security context
        :param name: the name of a strategy.
        :param eager: Load object fields if True (Default: False)
        :returns: A :class:`Strategy` object.
        """

        db_strategy = cls.dbapi.get_strategy_by_name(context,
                                                     name,
                                                     eager=eager)
        strategy = cls._from_db_object(cls(context), db_strategy, eager=eager)
        return strategy

    @base.remotable_classmethod
    def list(cls,
             context,
             limit=None,
             marker=None,
             filters=None,
             sort_key=None,
             sort_dir=None,
             eager=False):
        """Return a list of :class:`Strategy` objects.

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: Strategy(context)
        :param limit: maximum number of resources to return in a single result.
        :param marker: pagination marker for large data sets.
        :param filters: dict mapping the filter key to a value.
        :param sort_key: column to sort results by.
        :param sort_dir: direction to sort. "asc" or "desc`".
        :param eager: Load object fields if True (Default: False)
        :returns: a list of :class:`Strategy` object.
        """
        db_strategies = cls.dbapi.get_strategy_list(context,
                                                    filters=filters,
                                                    limit=limit,
                                                    marker=marker,
                                                    sort_key=sort_key,
                                                    sort_dir=sort_dir)

        return [
            cls._from_db_object(cls(context), obj, eager=eager)
            for obj in db_strategies
        ]

    @base.remotable
    def create(self, context=None):
        """Create a :class:`Strategy` record in the DB.

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: Strategy(context)
        :returns: A :class:`Strategy` object.
        """

        values = self.obj_get_changes()
        db_strategy = self.dbapi.create_strategy(values)
        # Note(v-francoise): Always load eagerly upon creation so we can send
        # notifications containing information about the related relationships
        self._from_db_object(self, db_strategy, eager=True)

    def destroy(self, context=None):
        """Delete the :class:`Strategy` from the DB.

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: Strategy(context)
        """
        self.dbapi.destroy_strategy(self.id)
        self.obj_reset_changes()

    @base.remotable
    def save(self, context=None):
        """Save updates to this :class:`Strategy`.

        Updates will be made column by column based on the result
        of self.what_changed().

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: Strategy(context)
        """
        updates = self.obj_get_changes()
        self.dbapi.update_strategy(self.id, updates)

        self.obj_reset_changes()

    @base.remotable
    def refresh(self, context=None, eager=False):
        """Loads updates for this :class:`Strategy`.

        Loads a strategy with the same uuid from the database and
        checks for updated attributes. Updates are applied from
        the loaded strategy column by column, if there are any updates.

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: Strategy(context)
        :param eager: Load object fields if True (Default: False)
        """
        current = self.__class__.get_by_id(self._context,
                                           strategy_id=self.id,
                                           eager=eager)
        for field in self.fields:
            if (hasattr(self, base.get_attrname(field))
                    and self[field] != current[field]):
                self[field] = current[field]

    @base.remotable
    def soft_delete(self, context=None):
        """Soft Delete the :class:`Strategy` from the DB.

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: Strategy(context)
        """
        self.dbapi.soft_delete_strategy(self.id)
Exemplo n.º 26
0
 def setUp(self):
     super(SqlAlchemyCustomTypesTestCase, self).setUp()
     self.dbapi = dbapi.get_instance()
Exemplo n.º 27
0
 def setUp(self):
     super(SqlAlchemyCustomTypesTestCase, self).setUp()
     self.dbapi = dbapi.get_instance()
Exemplo n.º 28
0
class AuditTemplate(base.WatcherObject):
    # Version 1.0: Initial version
    VERSION = '1.0'

    dbapi = dbapi.get_instance()

    fields = {
        'id': int,
        'uuid': obj_utils.str_or_none,
        'name': obj_utils.str_or_none,
        'description': obj_utils.str_or_none,
        'goal_id': obj_utils.int_or_none,
        'strategy_id': obj_utils.int_or_none,
        'extra': obj_utils.dict_or_none,
        'version': obj_utils.str_or_none,
        'scope': obj_utils.list_or_none,
    }

    @staticmethod
    def _from_db_object(audit_template, db_audit_template):
        """Converts a database entity to a formal object."""
        for field in audit_template.fields:
            audit_template[field] = db_audit_template[field]

        audit_template.obj_reset_changes()
        return audit_template

    @staticmethod
    def _from_db_object_list(db_objects, cls, context):
        """Converts a list of database entities to a list of formal objects."""
        return [
            AuditTemplate._from_db_object(cls(context), obj)
            for obj in db_objects
        ]

    @classmethod
    def get(cls, context, audit_template_id):
        """Find an audit template based on its id or uuid

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: AuditTemplate(context)
        :param audit_template_id: the id *or* uuid of a audit_template.
        :returns: a :class:`AuditTemplate` object.
        """

        if utils.is_int_like(audit_template_id):
            return cls.get_by_id(context, audit_template_id)
        elif utils.is_uuid_like(audit_template_id):
            return cls.get_by_uuid(context, audit_template_id)
        else:
            raise exception.InvalidIdentity(identity=audit_template_id)

    @classmethod
    def get_by_id(cls, context, audit_template_id):
        """Find an audit template based on its integer id

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: AuditTemplate(context)
        :param audit_template_id: the id of a audit_template.
        :returns: a :class:`AuditTemplate` object.
        """

        db_audit_template = cls.dbapi.get_audit_template_by_id(
            context, audit_template_id)
        audit_template = AuditTemplate._from_db_object(cls(context),
                                                       db_audit_template)
        return audit_template

    @classmethod
    def get_by_uuid(cls, context, uuid):
        """Find an audit template based on uuid

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: AuditTemplate(context)
        :param uuid: the uuid of a audit_template.
        :returns: a :class:`AuditTemplate` object.
        """

        db_audit_template = cls.dbapi.get_audit_template_by_uuid(context, uuid)
        audit_template = AuditTemplate._from_db_object(cls(context),
                                                       db_audit_template)
        return audit_template

    @classmethod
    def get_by_name(cls, context, name):
        """Find an audit template based on name

        :param name: the logical name of a audit_template.
        :param context: Security context
        :returns: a :class:`AuditTemplate` object.
        """

        db_audit_template = cls.dbapi.get_audit_template_by_name(context, name)
        audit_template = AuditTemplate._from_db_object(cls(context),
                                                       db_audit_template)
        return audit_template

    @classmethod
    def list(cls,
             context,
             filters=None,
             limit=None,
             marker=None,
             sort_key=None,
             sort_dir=None):
        """Return a list of :class:`AuditTemplate` objects.

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: AuditTemplate(context)
        :param filters: dict mapping the filter key to a value.
        :param limit: maximum number of resources to return in a single result.
        :param marker: pagination marker for large data sets.
        :param sort_key: column to sort results by.
        :param sort_dir: direction to sort. "asc" or "desc".
        :returns: a list of :class:`AuditTemplate` object.
        """

        db_audit_templates = cls.dbapi.get_audit_template_list(
            context,
            filters=filters,
            limit=limit,
            marker=marker,
            sort_key=sort_key,
            sort_dir=sort_dir)
        return AuditTemplate._from_db_object_list(db_audit_templates, cls,
                                                  context)

    def create(self, context=None):
        """Create a :class:`AuditTemplate` record in the DB.

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: AuditTemplate(context)
        """

        values = self.obj_get_changes()
        db_audit_template = self.dbapi.create_audit_template(values)
        self._from_db_object(self, db_audit_template)

    def destroy(self, context=None):
        """Delete the :class:`AuditTemplate` from the DB.

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: AuditTemplate(context)
        """

        self.dbapi.destroy_audit_template(self.uuid)
        self.obj_reset_changes()

    def save(self, context=None):
        """Save updates to this :class:`AuditTemplate`.

        Updates will be made column by column based on the result
        of self.what_changed().

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: AuditTemplate(context)
        """

        updates = self.obj_get_changes()
        self.dbapi.update_audit_template(self.uuid, updates)

        self.obj_reset_changes()

    def refresh(self, context=None):
        """Loads updates for this :class:`AuditTemplate`.

        Loads a audit_template with the same uuid from the database and
        checks for updated attributes. Updates are applied from
        the loaded audit_template column by column, if there are any updates.

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: AuditTemplate(context)
        """

        current = self.__class__.get_by_uuid(self._context, uuid=self.uuid)
        for field in self.fields:
            if (hasattr(self, base.get_attrname(field))
                    and self[field] != current[field]):
                self[field] = current[field]

    def soft_delete(self, context=None):
        """soft Delete the :class:`AuditTemplate` from the DB.

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: AuditTemplate(context)
        """

        self.dbapi.soft_delete_audit_template(self.uuid)
Exemplo n.º 29
0
class ActionPlan(base.WatcherObject):
    # Version 1.0: Initial version
    VERSION = '1.0'

    dbapi = dbapi.get_instance()

    fields = {
        'id': int,
        'uuid': obj_utils.str_or_none,
        'audit_id': obj_utils.int_or_none,
        'first_action_id': obj_utils.int_or_none,
        'state': obj_utils.str_or_none,
    }

    @staticmethod
    def _from_db_object(action_plan, db_action_plan):
        """Converts a database entity to a formal object."""
        for field in action_plan.fields:
            action_plan[field] = db_action_plan[field]

        action_plan.obj_reset_changes()
        return action_plan

    @staticmethod
    def _from_db_object_list(db_objects, cls, context):
        """Converts a list of database entities to a list of formal objects."""
        return [ActionPlan._from_db_object(
            cls(context), obj) for obj in db_objects]

    @classmethod
    def get(cls, context, action_plan_id):
        """Find a action_plan based on its id or uuid and return a Action object.

        :param action_plan_id: the id *or* uuid of a action_plan.
        :returns: a :class:`Action` object.
        """
        if utils.is_int_like(action_plan_id):
            return cls.get_by_id(context, action_plan_id)
        elif utils.is_uuid_like(action_plan_id):
            return cls.get_by_uuid(context, action_plan_id)
        else:
            raise exception.InvalidIdentity(identity=action_plan_id)

    @classmethod
    def get_by_id(cls, context, action_plan_id):
        """Find a action_plan based on its integer id and return a Action object.

        :param action_plan_id: the id of a action_plan.
        :returns: a :class:`Action` object.
        """
        db_action_plan = cls.dbapi.get_action_plan_by_id(
            context, action_plan_id)
        action_plan = ActionPlan._from_db_object(
            cls(context), db_action_plan)
        return action_plan

    @classmethod
    def get_by_uuid(cls, context, uuid):
        """Find a action_plan based on uuid and return a :class:`Action` object.

        :param uuid: the uuid of a action_plan.
        :param context: Security context
        :returns: a :class:`Action` object.
        """
        db_action_plan = cls.dbapi.get_action_plan_by_uuid(context, uuid)
        action_plan = ActionPlan._from_db_object(cls(context), db_action_plan)
        return action_plan

    @classmethod
    def list(cls, context, limit=None, marker=None, filters=None,
             sort_key=None, sort_dir=None):
        """Return a list of Action objects.

        :param context: Security context.
        :param limit: maximum number of resources to return in a single result.
        :param marker: pagination marker for large data sets.
        :param filters: Filters to apply. Defaults to None.
        :param sort_key: column to sort results by.
        :param sort_dir: direction to sort. "asc" or "desc".
        :returns: a list of :class:`ActionPlan` object.

        """
        db_action_plans = cls.dbapi.get_action_plan_list(context,
                                                         limit=limit,
                                                         marker=marker,
                                                         filters=filters,
                                                         sort_key=sort_key,
                                                         sort_dir=sort_dir)
        return ActionPlan._from_db_object_list(db_action_plans, cls, context)

    def create(self, context=None):
        """Create a Action record in the DB.

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: Action(context)

        """
        values = self.obj_get_changes()
        db_action_plan = self.dbapi.create_action_plan(values)
        self._from_db_object(self, db_action_plan)

    def destroy(self, context=None):
        """Delete the Action from the DB.

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: Action(context)
        """
        self.dbapi.destroy_action_plan(self.uuid)
        self.obj_reset_changes()

    def save(self, context=None):
        """Save updates to this Action plan.

        Updates will be made column by column based on the result
        of self.what_changed().

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: Action(context)
        """
        updates = self.obj_get_changes()
        self.dbapi.update_action_plan(self.uuid, updates)

        self.obj_reset_changes()

    def refresh(self, context=None):
        """Loads updates for this Action plan.

        Loads a action_plan with the same uuid from the database and
        checks for updated attributes. Updates are applied from
        the loaded action_plan column by column, if there are any updates.

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: Action(context)
        """
        current = self.__class__.get_by_uuid(self._context, uuid=self.uuid)
        for field in self.fields:
            if (hasattr(self, base.get_attrname(field)) and
                    self[field] != current[field]):
                    self[field] = current[field]

    def soft_delete(self, context=None):
        """soft Delete the Action plan from the DB.

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: Audit(context)
        """
        related_actions = action_objects.Action.list(
            context=self._context,
            filters={"action_plan_uuid": self.uuid})

        # Cascade soft_delete of related actions
        for related_action in related_actions:
            related_action.soft_delete()

        self.dbapi.soft_delete_action_plan(self.uuid)
        self.state = State.DELETED
        self.save()
Exemplo n.º 30
0
class Audit(base.WatcherPersistentObject, base.WatcherObject,
            base.WatcherObjectDictCompat):

    # Version 1.0: Initial version
    # Version 1.1: Added 'goal' and 'strategy' object field
    # Version 1.2  Added 'auto_trigger' boolean field
    VERSION = '1.2'

    dbapi = db_api.get_instance()

    fields = {
        'id': wfields.IntegerField(),
        'uuid': wfields.UUIDField(),
        'audit_type': wfields.StringField(),
        'state': wfields.StringField(),
        'parameters': wfields.FlexibleDictField(nullable=True),
        'interval': wfields.IntegerField(nullable=True),
        'scope': wfields.FlexibleListOfDictField(nullable=True),
        'goal_id': wfields.IntegerField(),
        'strategy_id': wfields.IntegerField(nullable=True),
        'auto_trigger': wfields.BooleanField(),

        'goal': wfields.ObjectField('Goal', nullable=True),
        'strategy': wfields.ObjectField('Strategy', nullable=True),
    }

    object_fields = {
        'goal': (objects.Goal, 'goal_id'),
        'strategy': (objects.Strategy, 'strategy_id'),
    }

    # Proxified field so we can keep the previous value after an update
    _state = None
    _old_state = None

    # NOTE(v-francoise): The way oslo.versionedobjects works is by using a
    # __new__ that will automatically create the attributes referenced in
    # fields. These attributes are properties that raise an exception if no
    # value has been assigned, which means that they store the actual field
    # value in an "_obj_%(field)s" attribute. So because we want to proxify a
    # value that is already proxified, we have to do what you see below.
    @property
    def _obj_state(self):
        return self._state

    @property
    def _obj_old_state(self):
        return self._old_state

    @property
    def old_state(self):
        return self._old_state

    @_obj_old_state.setter
    def _obj_old_state(self, value):
        self._old_state = value

    @_obj_state.setter
    def _obj_state(self, value):
        if self._old_state is None and self._state is None:
            self._state = value
        else:
            self._old_state, self._state = self._state, value

    @base.remotable_classmethod
    def get(cls, context, audit_id, eager=False):
        """Find a audit based on its id or uuid and return a Audit object.

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: Audit(context)
        :param audit_id: the id *or* uuid of a audit.
        :param eager: Load object fields if True (Default: False)
        :returns: a :class:`Audit` object.
        """
        if utils.is_int_like(audit_id):
            return cls.get_by_id(context, audit_id, eager=eager)
        elif utils.is_uuid_like(audit_id):
            return cls.get_by_uuid(context, audit_id, eager=eager)
        else:
            raise exception.InvalidIdentity(identity=audit_id)

    @base.remotable_classmethod
    def get_by_id(cls, context, audit_id, eager=False):
        """Find a audit based on its integer id and return a Audit object.

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: Audit(context)
        :param audit_id: the id of a audit.
        :param eager: Load object fields if True (Default: False)
        :returns: a :class:`Audit` object.
        """
        db_audit = cls.dbapi.get_audit_by_id(context, audit_id, eager=eager)
        audit = cls._from_db_object(cls(context), db_audit, eager=eager)
        return audit

    @base.remotable_classmethod
    def get_by_uuid(cls, context, uuid, eager=False):
        """Find a audit based on uuid and return a :class:`Audit` object.

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: Audit(context)
        :param uuid: the uuid of a audit.
        :param eager: Load object fields if True (Default: False)
        :returns: a :class:`Audit` object.
        """

        db_audit = cls.dbapi.get_audit_by_uuid(context, uuid, eager=eager)
        audit = cls._from_db_object(cls(context), db_audit, eager=eager)
        return audit

    @base.remotable_classmethod
    def list(cls, context, limit=None, marker=None, filters=None,
             sort_key=None, sort_dir=None, eager=False):
        """Return a list of Audit objects.

        :param context: Security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: Audit(context)
        :param limit: maximum number of resources to return in a single result.
        :param marker: pagination marker for large data sets.
        :param filters: Filters to apply. Defaults to None.
        :param sort_key: column to sort results by.
        :param sort_dir: direction to sort. "asc" or "desc".
        :param eager: Load object fields if True (Default: False)
        :returns: a list of :class:`Audit` object.

        """
        db_audits = cls.dbapi.get_audit_list(context,
                                             limit=limit,
                                             marker=marker,
                                             filters=filters,
                                             sort_key=sort_key,
                                             sort_dir=sort_dir,
                                             eager=eager)
        return [cls._from_db_object(cls(context), obj, eager=eager)
                for obj in db_audits]

    @base.remotable
    def create(self):
        """Create an :class:`Audit` record in the DB.

        :returns: An :class:`Audit` object.
        """
        values = self.obj_get_changes()
        db_audit = self.dbapi.create_audit(values)
        # Note(v-francoise): Always load eagerly upon creation so we can send
        # notifications containing information about the related relationships
        self._from_db_object(self, db_audit, eager=True)

        def _notify():
            notifications.audit.send_create(self._context, self)

        _notify()

    @base.remotable
    def destroy(self):
        """Delete the Audit from the DB."""
        self.dbapi.destroy_audit(self.uuid)
        self.obj_reset_changes()

    @base.remotable
    def save(self):
        """Save updates to this Audit.

        Updates will be made column by column based on the result
        of self.what_changed().
        """
        updates = self.obj_get_changes()
        db_obj = self.dbapi.update_audit(self.uuid, updates)
        obj = self._from_db_object(
            self.__class__(self._context), db_obj, eager=False)
        self.obj_refresh(obj)

        def _notify():
            notifications.audit.send_update(
                self._context, self, old_state=self.old_state)

        _notify()

        self.obj_reset_changes()

    @base.remotable
    def refresh(self, eager=False):
        """Loads updates for this Audit.

        Loads a audit with the same uuid from the database and
        checks for updated attributes. Updates are applied from
        the loaded audit column by column, if there are any updates.
        :param eager: Load object fields if True (Default: False)
        """
        current = self.get_by_uuid(self._context, uuid=self.uuid, eager=eager)
        self.obj_refresh(current)

    @base.remotable
    def soft_delete(self):
        """Soft Delete the Audit from the DB."""
        self.state = State.DELETED
        self.save()
        db_obj = self.dbapi.soft_delete_audit(self.uuid)
        obj = self._from_db_object(
            self.__class__(self._context), db_obj, eager=False)
        self.obj_refresh(obj)

        def _notify():
            notifications.audit.send_delete(self._context, self)

        _notify()