Coverage for osm_policy_module/core/agent.py: 57%

114 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-05-07 08:03 +0000

1# -*- coding: utf-8 -*- 

2 

3# Copyright 2018 Whitestack, LLC 

4# ************************************************************* 

5 

6# This file is part of OSM Monitoring module 

7# All Rights Reserved to Whitestack, LLC 

8 

9# Licensed under the Apache License, Version 2.0 (the "License"); you may 

10# not use this file except in compliance with the License. You may obtain 

11# a copy of the License at 

12 

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

14 

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

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

17# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 

18# License for the specific language governing permissions and limitations 

19# under the License. 

20 

21# For those usages not covered by the Apache License, Version 2.0 please 

22# contact: bdiaz@whitestack.com or glavado@whitestack.com 

23## 

24import asyncio 

25import logging 

26from pathlib import Path 

27import os 

28 

29import peewee 

30 

31from osm_policy_module.alarming.service import AlarmingService 

32from osm_policy_module.autoscaling.service import AutoscalingService 

33from osm_policy_module.healing.service import HealingService 

34from osm_policy_module.common.common_db_client import CommonDbClient 

35from osm_policy_module.common.message_bus_client import MessageBusClient 

36from osm_policy_module.core.config import Config 

37 

38log = logging.getLogger(__name__) 

39 

40ALLOWED_KAFKA_KEYS = [ 

41 "instantiated", 

42 "scaled", 

43 "terminated", 

44 "notify_alarm", 

45 "policy_updated", 

46 "vnf_terminated", 

47] 

48 

49 

50class PolicyModuleAgent: 

51 def __init__(self, config: Config): 

52 self.conf = config 

53 self.msg_bus = MessageBusClient(config) 

54 self.db_client = CommonDbClient(config) 

55 self.autoscaling_service = AutoscalingService(config) 

56 self.alarming_service = AlarmingService(config) 

57 self.healing_service = HealingService(config) 

58 

59 def run(self): 

60 asyncio.run(self.start()) 

61 

62 async def start(self): 

63 Path("/tmp/osm_pol_agent_health_flag").touch() 

64 topics = ["ns", "alarm_response"] 

65 await self.msg_bus.aioread(topics, self._process_msg) 

66 log.critical("Exiting...") 

67 if os.path.exists("/tmp/osm_pol_agent_health_flag"): 

68 os.remove("/tmp/osm_pol_agent_health_flag") 

69 

70 async def _process_msg(self, topic, key, msg): 

71 Path("/tmp/osm_pol_agent_health_flag").touch() 

72 log.debug("_process_msg topic=%s key=%s msg=%s", topic, key, msg) 

73 try: 

74 if key in ALLOWED_KAFKA_KEYS: 

75 if key == "instantiated": 

76 await self._handle_instantiated(msg) 

77 

78 if key == "scaled": 

79 await self._handle_scaled(msg) 

80 

81 if key == "terminated": 

82 await self._handle_terminated(msg) 

83 

84 if key == "notify_alarm": 

85 await self._handle_alarm_notification(msg) 

86 

87 if key == "policy_updated": 

88 await self._handle_policy_update(msg) 

89 

90 if key == "vnf_terminated": 

91 await self._handle_vnf_terminated(msg) 

92 else: 

93 log.debug("Key %s is not in ALLOWED_KAFKA_KEYS", key) 

94 except peewee.PeeweeException: 

95 log.exception("Database error consuming message: ") 

96 raise 

97 except Exception: 

98 log.exception("Error consuming message: ") 

99 

100 async def _handle_alarm_notification(self, content): 

101 log.debug("_handle_alarm_notification: %s", content) 

102 alarm_uuid = content["notify_details"]["alarm_uuid"] 

103 status = content["notify_details"]["status"] 

104 await self.autoscaling_service.handle_alarm(alarm_uuid, status) 

105 await self.alarming_service.handle_alarm(alarm_uuid, status, content) 

106 await self.healing_service.handle_alarm(alarm_uuid, status) 

107 

108 async def _handle_instantiated(self, content): 

109 log.debug("_handle_instantiated: %s", content) 

110 nslcmop_id = content["nslcmop_id"] 

111 nslcmop = self.db_client.get_nslcmop(nslcmop_id) 

112 if ( 

113 nslcmop["operationState"] == "COMPLETED" 

114 or nslcmop["operationState"] == "PARTIALLY_COMPLETED" 

115 ): 

116 nsr_id = nslcmop["nsInstanceId"] 

117 log.info("Configuring nsr_id: %s", nsr_id) 

118 await self.autoscaling_service.configure_scaling_groups(nsr_id) 

119 await self.alarming_service.configure_vnf_alarms(nsr_id) 

120 await self.healing_service.configure_healing_alarms(nsr_id) 

121 else: 

122 log.info( 

123 "Network_service is not in COMPLETED or PARTIALLY_COMPLETED state. " 

124 "Current state is %s. Skipping...", 

125 nslcmop["operationState"], 

126 ) 

127 

128 async def _handle_scaled(self, content): 

129 log.debug("_handle_scaled: %s", content) 

130 nslcmop_id = content["nslcmop_id"] 

131 nslcmop = self.db_client.get_nslcmop(nslcmop_id) 

132 if ( 

133 nslcmop["operationState"] == "COMPLETED" 

134 or nslcmop["operationState"] == "PARTIALLY_COMPLETED" 

135 ): 

136 nsr_id = nslcmop["nsInstanceId"] 

137 log.info("Configuring scaled service with nsr_id: %s", nsr_id) 

138 await self.autoscaling_service.configure_scaling_groups(nsr_id) 

139 await self.autoscaling_service.delete_orphaned_alarms(nsr_id) 

140 await self.alarming_service.configure_vnf_alarms(nsr_id) 

141 await self.healing_service.configure_healing_alarms(nsr_id) 

142 await self.healing_service.delete_orphaned_healing_alarms(nsr_id) 

143 else: 

144 log.debug( 

145 "Network service is not in COMPLETED or PARTIALLY_COMPLETED state. " 

146 "Current state is %s. Skipping...", 

147 nslcmop["operationState"], 

148 ) 

149 

150 async def _handle_terminated(self, content): 

151 log.debug("_handle_deleted: %s", content) 

152 nsr_id = content["nsr_id"] 

153 if ( 

154 content["operationState"] == "COMPLETED" 

155 or content["operationState"] == "PARTIALLY_COMPLETED" 

156 ): 

157 log.info( 

158 "Deleting scaling groups and alarms for network autoscaling_service with nsr_id: %s", 

159 nsr_id, 

160 ) 

161 await self.autoscaling_service.delete_scaling_groups(nsr_id) 

162 await self.alarming_service.delete_vnf_alarms(nsr_id) 

163 await self.healing_service.delete_healing_alarms(nsr_id) 

164 else: 

165 log.info( 

166 "Network service is not in COMPLETED or PARTIALLY_COMPLETED state. " 

167 "Current state is %s. Skipping...", 

168 content["operationState"], 

169 ) 

170 

171 async def _handle_policy_update(self, content): 

172 log.info("_handle_policy_update: %s", content) 

173 nsr_id = content["nsr_id"] 

174 vnf_member_index = content["vnf_member_index"] 

175 if ( 

176 content["operationState"] == "COMPLETED" 

177 or content["operationState"] == "PARTIALLY_COMPLETED" 

178 ): 

179 log.info( 

180 "Updating policies of VNF with nsr_id: %s and vnf-member-index: %s" 

181 % (nsr_id, vnf_member_index) 

182 ) 

183 await self.autoscaling_service.delete_scaling_groups( 

184 nsr_id, vnf_member_index 

185 ) 

186 await self.alarming_service.delete_vnf_alarms(nsr_id, vnf_member_index) 

187 await self.healing_service.delete_healing_alarms(nsr_id, vnf_member_index) 

188 await self.autoscaling_service.configure_scaling_groups( 

189 nsr_id, vnf_member_index 

190 ) 

191 await self.alarming_service.configure_vnf_alarms(nsr_id, vnf_member_index) 

192 await self.healing_service.configure_healing_alarms( 

193 nsr_id, vnf_member_index 

194 ) 

195 else: 

196 log.info( 

197 "Network service is not in COMPLETED or PARTIALLY_COMPLETED state. " 

198 "Current state is %s. Skipping...", 

199 content["operationState"], 

200 ) 

201 

202 async def _handle_vnf_terminated(self, content): 

203 nsr_id = content["nsr_id"] 

204 vnf_member_index = content["vnf_member_index"] 

205 if ( 

206 content["operationState"] == "COMPLETED" 

207 or content["operationState"] == "PARTIALLY_COMPLETED" 

208 ): 

209 log.info( 

210 "Deleting policies of VNF with nsr_id: %s and vnf-member-index: %s" 

211 % (nsr_id, vnf_member_index) 

212 ) 

213 await self.autoscaling_service.delete_scaling_groups( 

214 nsr_id, vnf_member_index 

215 ) 

216 await self.alarming_service.delete_vnf_alarms(nsr_id, vnf_member_index) 

217 else: 

218 log.info( 

219 "Network service is not in COMPLETED or PARTIALLY_COMPLETED state. " 

220 "Current state is %s. Skipping...", 

221 content["operationState"], 

222 )