Esempio n. 1
0
 class TestObject(base.WatcherObject):
     VERSION = '1.0'
     fields = {
         'field_1': wfields.StringField(),
         'field_2': wfields.IntegerField(),
         'not_important_field': wfields.IntegerField(),
     }
Esempio n. 2
0
class TerseAuditPayload(notificationbase.NotificationPayloadBase):
    SCHEMA = {
        'uuid': ('audit', 'uuid'),
        'audit_type': ('audit', 'audit_type'),
        'state': ('audit', 'state'),
        'parameters': ('audit', 'parameters'),
        'interval': ('audit', 'interval'),
        'scope': ('audit', 'scope'),
        'created_at': ('audit', 'created_at'),
        'updated_at': ('audit', 'updated_at'),
        'deleted_at': ('audit', 'deleted_at'),
    }

    # Version 1.0: Initial version
    VERSION = '1.0'

    fields = {
        '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_uuid': wfields.UUIDField(),
        'strategy_uuid': wfields.UUIDField(nullable=True),
        'created_at': wfields.DateTimeField(nullable=True),
        'updated_at': wfields.DateTimeField(nullable=True),
        'deleted_at': wfields.DateTimeField(nullable=True),
    }

    def __init__(self, audit, goal_uuid, strategy_uuid=None, **kwargs):
        super(TerseAuditPayload, self).__init__(goal_uuid=goal_uuid,
                                                strategy_uuid=strategy_uuid,
                                                **kwargs)
        self.populate_schema(audit=audit)
Esempio n. 3
0
        class TestObj(base.WatcherPersistentObject, base.WatcherObject,
                      base.WatcherObjectDictCompat):
            fields = {'foo': fields.IntegerField()}
            obj_extra_fields = ['bar']

            @property
            def bar(self):
                return 'this is bar'
Esempio n. 4
0
class Instance(compute_resource.ComputeResource):

    fields = {
        "state": wfields.StringField(default=InstanceState.ACTIVE.value),
        "memory": wfields.NonNegativeIntegerField(),
        "disk": wfields.IntegerField(),
        "disk_capacity": wfields.NonNegativeIntegerField(),
        "vcpus": wfields.NonNegativeIntegerField(),
    }

    def accept(self, visitor):
        raise NotImplementedError()
Esempio n. 5
0
        class TestNotificationPayload(
                notificationbase.NotificationPayloadBase):
            VERSION = '1.0'

            SCHEMA = {
                'field_1': ('source_field', 'field_1'),
                'field_2': ('source_field', 'field_2'),
            }

            fields = {
                'extra_field': wfields.StringField(),  # filled by ctor
                'field_1': wfields.StringField(),  # filled by the schema
                'field_2': wfields.IntegerField(),   # filled by the schema
            }
Esempio n. 6
0
class ComputeNode(compute_resource.ComputeResource):

    fields = {
        "id": wfields.NonNegativeIntegerField(),
        "hostname": wfields.StringField(),
        "status": wfields.StringField(default=ServiceState.ENABLED.value),
        "state": wfields.StringField(default=ServiceState.ONLINE.value),
        "memory": wfields.NonNegativeIntegerField(),
        "disk": wfields.IntegerField(),
        "disk_capacity": wfields.NonNegativeIntegerField(),
        "vcpus": wfields.NonNegativeIntegerField(),
    }

    def accept(self, visitor):
        raise NotImplementedError()
Esempio n. 7
0
class MyObj(base.WatcherPersistentObject, base.WatcherObject,
            base.WatcherObjectDictCompat):
    VERSION = '1.5'

    fields = {
        'foo': fields.IntegerField(),
        'bar': fields.StringField(),
        'missing': fields.StringField()
    }

    def obj_load_attr(self, attrname):
        setattr(self, attrname, 'loaded!')

    @object_base.remotable_classmethod
    def query(cls, context):
        obj = cls(context)
        obj.foo = 1
        obj.bar = 'bar'
        obj.obj_reset_changes()
        return obj

    @object_base.remotable
    def marco(self, context=None):
        return 'polo'

    @object_base.remotable
    def update_test(self, context=None):
        if context and context.user == 'alternate':
            self.bar = 'alternate-context'
        else:
            self.bar = 'updated'

    @object_base.remotable
    def save(self, context=None):
        self.obj_reset_changes()

    @object_base.remotable
    def refresh(self, context=None):
        self.foo = 321
        self.bar = 'refreshed'
        self.obj_reset_changes()

    @object_base.remotable
    def modify_save_modify(self, context=None):
        self.bar = 'meow'
        self.save()
        self.foo = 42
Esempio n. 8
0
class Instance(compute_resource.ComputeResource):

    fields = {
        # If the resource is excluded by the scope,
        # 'watcher_exclude' property will be set True.
        "watcher_exclude": wfields.BooleanField(default=False),
        "state": wfields.StringField(default=InstanceState.ACTIVE.value),

        "memory": wfields.NonNegativeIntegerField(),
        "disk": wfields.IntegerField(),
        "disk_capacity": wfields.NonNegativeIntegerField(),
        "vcpus": wfields.NonNegativeIntegerField(),
        "metadata": wfields.JsonField(),
    }

    def accept(self, visitor):
        raise NotImplementedError()
Esempio n. 9
0
    class TestNotificationPayload(notificationbase.NotificationPayloadBase):
        VERSION = '1.0'

        SCHEMA = {
            'field_1': ('source_field', 'field_1'),
            'field_2': ('source_field', 'field_2'),
        }

        fields = {
            'extra_field': wfields.StringField(),  # filled by ctor
            'field_1': wfields.StringField(),  # filled by the schema
            'field_2': wfields.IntegerField(),   # filled by the schema
        }

        def populate_schema(self, source_field):
            super(TestNotificationBase.TestNotificationPayload,
                  self).populate_schema(source_field=source_field)
Esempio n. 10
0
 class TestObj(base.WatcherPersistentObject, base.WatcherObject,
               base.WatcherObjectDictCompat):
     fields = {'foo': fields.IntegerField(),
               'bar': fields.StringField()}
Esempio n. 11
0
 class Foo(base.WatcherPersistentObject, base.WatcherObject,
           base.WatcherObjectDictCompat):
     fields = {'foobar': fields.IntegerField()}
Esempio n. 12
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)
Esempio n. 13
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()
Esempio n. 14
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)
Esempio n. 15
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)
Esempio n. 16
0
 class TestObj(base.WatcherObject):
     fields = {'foo': fields.IntegerField(),
               'bar': fields.StringField()}
Esempio n. 17
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)
Esempio n. 18
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()
Esempio n. 19
0
class EfficacyIndicator(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(),
        'action_plan_id': wfields.IntegerField(),
        'name': wfields.StringField(),
        'description': wfields.StringField(nullable=True),
        'unit': wfields.StringField(nullable=True),
        'value': wfields.NumericField(),
    }

    @base.remotable_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)

    @base.remotable_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

    @base.remotable_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

    @base.remotable_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 [
            cls._from_db_object(cls(context), obj)
            for obj in db_efficacy_indicators
        ]

    @base.remotable
    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()

    @base.remotable
    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()

    @base.remotable
    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)
        self.obj_refresh(current)

    @base.remotable
    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)