Coverage for watcher/applier/actions/change_nova_service_state.py: 92%

48 statements  

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

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

2# Copyright (c) 2015 b<>com 

3# 

4# Authors: Jean-Emile DARTOIS <jean-emile.dartois@b-com.com> 

5# 

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

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

8# You may obtain a copy of the License at 

9# 

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

11# 

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

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

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

15# implied. 

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

17# limitations under the License. 

18# 

19 

20from watcher._i18n import _ 

21from watcher.applier.actions import base 

22from watcher.common import exception 

23from watcher.common import nova_helper 

24from watcher.decision_engine.model import element 

25 

26 

27class ChangeNovaServiceState(base.BaseAction): 

28 """Disables or enables the nova-compute service, deployed on a host 

29 

30 By using this action, you will be able to update the state of a 

31 nova-compute service. A disabled nova-compute service can not be selected 

32 by the nova scheduler for future deployment of server. 

33 

34 The action schema is:: 

35 

36 schema = Schema({ 

37 'resource_id': str, 

38 'state': str, 

39 'disabled_reason': str, 

40 }) 

41 

42 The `resource_id` references a nova-compute service name. 

43 The `state` value should either be `up` or `down`. 

44 The `disabled_reason` references the reason why Watcher disables this 

45 nova-compute service. The value should be with `watcher_` prefix, such as 

46 `watcher_disabled`, `watcher_maintaining`. 

47 """ 

48 

49 STATE = 'state' 

50 REASON = 'disabled_reason' 

51 RESOURCE_NAME = 'resource_name' 

52 

53 @property 

54 def schema(self): 

55 return { 

56 'type': 'object', 

57 'properties': { 

58 'resource_id': { 

59 'type': 'string', 

60 "minlength": 1 

61 }, 

62 'resource_name': { 

63 'type': 'string', 

64 "minlength": 1 

65 }, 

66 'state': { 

67 'type': 'string', 

68 'enum': [element.ServiceState.ONLINE.value, 

69 element.ServiceState.OFFLINE.value, 

70 element.ServiceState.ENABLED.value, 

71 element.ServiceState.DISABLED.value] 

72 }, 

73 'disabled_reason': { 

74 'type': 'string', 

75 "minlength": 1 

76 } 

77 }, 

78 'required': ['resource_id', 'state'], 

79 'additionalProperties': False, 

80 } 

81 

82 @property 

83 def host(self): 

84 return self.input_parameters.get(self.RESOURCE_NAME) 

85 

86 @property 

87 def state(self): 

88 return self.input_parameters.get(self.STATE) 

89 

90 @property 

91 def reason(self): 

92 return self.input_parameters.get(self.REASON) 

93 

94 def execute(self): 

95 target_state = None 

96 if self.state == element.ServiceState.DISABLED.value: 

97 target_state = False 

98 elif self.state == element.ServiceState.ENABLED.value: 98 ↛ 100line 98 didn't jump to line 100 because the condition on line 98 was always true

99 target_state = True 

100 return self._nova_manage_service(target_state) 

101 

102 def revert(self): 

103 target_state = None 

104 if self.state == element.ServiceState.DISABLED.value: 

105 target_state = True 

106 elif self.state == element.ServiceState.ENABLED.value: 106 ↛ 108line 106 didn't jump to line 108 because the condition on line 106 was always true

107 target_state = False 

108 return self._nova_manage_service(target_state) 

109 

110 def _nova_manage_service(self, state): 

111 if state is None: 111 ↛ 112line 111 didn't jump to line 112 because the condition on line 111 was never true

112 raise exception.IllegalArgumentException( 

113 message=_("The target state is not defined")) 

114 

115 nova = nova_helper.NovaHelper(osc=self.osc) 

116 if state is True: 

117 return nova.enable_service_nova_compute(self.host) 

118 else: 

119 return nova.disable_service_nova_compute(self.host, self.reason) 

120 

121 def pre_condition(self): 

122 pass 

123 

124 def post_condition(self): 

125 pass 

126 

127 def get_description(self): 

128 """Description of the action""" 

129 return ("Disables or enables the nova-compute service." 

130 "A disabled nova-compute service can not be selected " 

131 "by the nova for future deployment of new server.")