Coverage for watcher/objects/action_description.py: 92%

47 statements  

« prev     ^ index     » next       coverage.py v7.8.2, created at 2025-06-17 12:22 +0000

1# -*- encoding: utf-8 -*- 

2# Copyright (c) 2017 ZTE 

3# 

4# Licensed under the Apache License, Version 2.0 (the "License"); 

5# you may not use this file except in compliance with the License. 

6# You may obtain a copy of the License at 

7# 

8# http://www.apache.org/licenses/LICENSE-2.0 

9# 

10# Unless required by applicable law or agreed to in writing, software 

11# distributed under the License is distributed on an "AS IS" BASIS, 

12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 

13# implied. 

14# See the License for the specific language governing permissions and 

15# limitations under the License. 

16 

17from watcher.common import exception 

18from watcher.common import utils 

19from watcher.db import api as db_api 

20from watcher.objects import base 

21from watcher.objects import fields as wfields 

22 

23 

24@base.WatcherObjectRegistry.register 

25class ActionDescription(base.WatcherPersistentObject, base.WatcherObject, 

26 base.WatcherObjectDictCompat): 

27 

28 # Version 1.0: Initial version 

29 VERSION = '1.0' 

30 

31 dbapi = db_api.get_instance() 

32 

33 fields = { 

34 'id': wfields.IntegerField(), 

35 'action_type': wfields.StringField(), 

36 'description': wfields.StringField(), 

37 } 

38 

39 @base.remotable_classmethod 

40 def get(cls, context, action_id): 

41 """Find a action description based on its id 

42 

43 :param context: Security context. NOTE: This should only 

44 be used internally by the indirection_api. 

45 Unfortunately, RPC requires context as the first 

46 argument, even though we don't use it. 

47 A context should be set when instantiating the 

48 object 

49 :param action_id: the id of a action description. 

50 :returns: a :class:`ActionDescription` object. 

51 """ 

52 if utils.is_int_like(action_id): 52 ↛ 58line 52 didn't jump to line 58 because the condition on line 52 was always true

53 db_action = cls.dbapi.get_action_description_by_id( 

54 context, action_id) 

55 action = ActionDescription._from_db_object(cls(context), db_action) 

56 return action 

57 else: 

58 raise exception.InvalidIdentity(identity=action_id) 

59 

60 @base.remotable_classmethod 

61 def get_by_type(cls, context, action_type): 

62 """Find a action description based on action type 

63 

64 :param action_type: the action type of a action description. 

65 :param context: Security context 

66 :returns: a :class:`ActionDescription` object. 

67 """ 

68 

69 db_action = cls.dbapi.get_action_description_by_type( 

70 context, action_type) 

71 action = cls._from_db_object(cls(context), db_action) 

72 return action 

73 

74 @base.remotable_classmethod 

75 def list(cls, context, limit=None, marker=None, filters=None, 

76 sort_key=None, sort_dir=None): 

77 """Return a list of :class:`ActionDescription` objects. 

78 

79 :param context: Security context. NOTE: This should only 

80 be used internally by the indirection_api. 

81 Unfortunately, RPC requires context as the first 

82 argument, even though we don't use it. 

83 A context should be set when instantiating the 

84 object, e.g.: ActionDescription(context) 

85 :param filters: dict mapping the filter key to a value. 

86 :param limit: maximum number of resources to return in a single result. 

87 :param marker: pagination marker for large data sets. 

88 :param sort_key: column to sort results by. 

89 :param sort_dir: direction to sort. "asc" or "desc". 

90 :returns: a list of :class:`ActionDescription` object. 

91 """ 

92 db_actions = cls.dbapi.get_action_description_list( 

93 context, 

94 filters=filters, 

95 limit=limit, 

96 marker=marker, 

97 sort_key=sort_key, 

98 sort_dir=sort_dir) 

99 

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

101 

102 @base.remotable 

103 def create(self): 

104 """Create a :class:`ActionDescription` record in the DB.""" 

105 values = self.obj_get_changes() 

106 db_action = self.dbapi.create_action_description(values) 

107 self._from_db_object(self, db_action) 

108 

109 @base.remotable 

110 def save(self): 

111 """Save updates to this :class:`ActionDescription`. 

112 

113 Updates will be made column by column based on the result 

114 of self.what_changed(). 

115 """ 

116 updates = self.obj_get_changes() 

117 db_obj = self.dbapi.update_action_description(self.id, updates) 

118 obj = self._from_db_object(self, db_obj, eager=False) 

119 self.obj_refresh(obj) 

120 self.obj_reset_changes() 

121 

122 def refresh(self): 

123 """Loads updates for this :class:`ActionDescription`. 

124 

125 Loads a action description with the same id from the database and 

126 checks for updated attributes. Updates are applied from 

127 the loaded action description column by column, if there 

128 are any updates. 

129 """ 

130 current = self.get(self._context, action_id=self.id) 

131 for field in self.fields: 

132 if (hasattr(self, base.get_attrname(field)) and 

133 self[field] != current[field]): 

134 self[field] = current[field] 

135 

136 def soft_delete(self): 

137 """Soft Delete the :class:`ActionDescription` from the DB.""" 

138 db_obj = self.dbapi.soft_delete_action_description(self.id) 

139 obj = self._from_db_object( 

140 self.__class__(self._context), db_obj, eager=False) 

141 self.obj_refresh(obj)