Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1# ================================================================================ 

2# Copyright (c) 2017-2020 AT&T Intellectual Property. All rights reserved. 

3# Copyright (c) 2019 Pantheon.tech. All rights reserved. 

4# ================================================================================ 

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

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

7# You may obtain a copy of the License at 

8# 

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

10# 

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

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

13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

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

15# limitations under the License. 

16# ============LICENSE_END========================================================= 

17# 

18 

19"""tasks are the cloudify operations invoked on interfaces defined in the blueprint""" 

20 

21import copy 

22import json 

23import traceback 

24import uuid 

25 

26import requests 

27from cloudify import ctx 

28from cloudify.context import NODE_INSTANCE 

29from cloudify.decorators import operation 

30from cloudify.exceptions import NonRecoverableError 

31 

32from .discovery import discover_service_url, discover_value 

33 

34DCAE_POLICY_PLUGIN = "dcaepolicyplugin" 

35POLICY_ID = 'policy_id' 

36POLICY_REQUIRED = 'policy_required' 

37POLICY_BODY = 'policy_body' 

38POLICIES_FILTERED = 'policies_filtered' 

39POLICY_FILTER = 'policy_filter' 

40LATEST_POLICIES = "latest_policies" 

41 

42REQUEST_ID = "requestID" 

43 

44DCAE_POLICY_TYPE = 'dcae.nodes.policy' 

45DCAE_POLICIES_TYPE = 'dcae.nodes.policies' 

46DCAE_POLICY_TYPES = [DCAE_POLICY_TYPE, DCAE_POLICIES_TYPE] 

47CONFIG_ATTRIBUTES = "configAttributes" 

48 

49 

50class PolicyHandler(object): 

51 """talk to policy-handler""" 

52 SERVICE_NAME_POLICY_HANDLER = "policy_handler" 

53 X_ECOMP_REQUESTID = 'X-ECOMP-RequestID' 

54 STATUS_CODE_POLICIES_NOT_FOUND = 404 

55 DEFAULT_URL = "http://policy-handler" 

56 _url = None 

57 

58 @staticmethod 

59 def _lazy_init(): 

60 """discover policy-handler""" 

61 if PolicyHandler._url: 

62 return 

63 

64 PolicyHandler._url = discover_service_url(PolicyHandler.SERVICE_NAME_POLICY_HANDLER) 

65 if PolicyHandler._url: 

66 return 

67 

68 config = discover_value(DCAE_POLICY_PLUGIN) 

69 if config and isinstance(config, dict): 69 ↛ 82line 69 didn't jump to line 82, because the condition on line 69 was never false

70 # expected structure for the config value for dcaepolicyplugin key 

71 # { 

72 # "dcaepolicyplugin" : { 

73 # "policy_handler" : { 

74 # "target_entity" : "policy_handler", 

75 # "url" : "http://policy-handler:25577" 

76 # } 

77 # } 

78 # } 

79 PolicyHandler._url = config.get(DCAE_POLICY_PLUGIN, {}) \ 

80 .get(PolicyHandler.SERVICE_NAME_POLICY_HANDLER, {}).get("url") 

81 

82 if PolicyHandler._url: 82 ↛ 85line 82 didn't jump to line 85, because the condition on line 82 was never false

83 return 

84 

85 PolicyHandler._url = PolicyHandler.DEFAULT_URL 

86 

87 @staticmethod 

88 def get_latest_policy(policy_id): 

89 """retrieve the latest policy for policy_id from policy-handler""" 

90 PolicyHandler._lazy_init() 

91 

92 ph_path = "{0}/policy_latest/{1}".format(PolicyHandler._url, policy_id) 

93 headers = {PolicyHandler.X_ECOMP_REQUESTID: str(uuid.uuid4())} 

94 

95 ctx.logger.info("getting latest policy from {0} headers={1}".format( 

96 ph_path, json.dumps(headers))) 

97 res = requests.get(ph_path, headers=headers, timeout=60) 

98 ctx.logger.info("latest policy for policy_id({0}) status({1}) response: {2}" 

99 .format(policy_id, res.status_code, res.text)) 

100 

101 if res.status_code == PolicyHandler.STATUS_CODE_POLICIES_NOT_FOUND: 101 ↛ 102line 101 didn't jump to line 102, because the condition on line 101 was never true

102 return 

103 

104 res.raise_for_status() 

105 return res.json() 

106 

107 @staticmethod 

108 def find_latest_policies(policy_filter): 

109 """retrieve the latest policies by policy filter (selection criteria) from policy-handler""" 

110 PolicyHandler._lazy_init() 

111 

112 ph_path = "{0}/policies_latest".format(PolicyHandler._url) 

113 headers = { 

114 PolicyHandler.X_ECOMP_REQUESTID: policy_filter.get(REQUEST_ID, str(uuid.uuid4())) 

115 } 

116 

117 ctx.logger.info("finding the latest polices from {0} by {1} headers={2}".format( 

118 ph_path, json.dumps(policy_filter), json.dumps(headers))) 

119 

120 res = requests.post(ph_path, json=policy_filter, headers=headers, timeout=60) 

121 ctx.logger.info("latest policies status({0}) response: {1}" 

122 .format(res.status_code, res.text)) 

123 

124 if res.status_code == PolicyHandler.STATUS_CODE_POLICIES_NOT_FOUND: 124 ↛ 125line 124 didn't jump to line 125, because the condition on line 124 was never true

125 return 

126 

127 res.raise_for_status() 

128 return res.json().get(LATEST_POLICIES) 

129 

130 

131def _policy_get(): 

132 """ 

133 dcae.nodes.policy - 

134 retrieve the latest policy_body for policy_id property 

135 and save policy_body in runtime_properties 

136 """ 

137 if DCAE_POLICY_TYPE not in ctx.node.type_hierarchy: 

138 return 

139 

140 policy_id = ctx.node.properties.get(POLICY_ID) 

141 policy_required = ctx.node.properties.get(POLICY_REQUIRED) 

142 if not policy_id: 142 ↛ 143line 142 didn't jump to line 143, because the condition on line 142 was never true

143 error = "no {0} found in ctx.node.properties".format(POLICY_ID) 

144 ctx.logger.error(error) 

145 raise NonRecoverableError(error) 

146 

147 policy = None 

148 try: 

149 policy = PolicyHandler.get_latest_policy(policy_id) 

150 except Exception as ex: 

151 error = "failed to get policy({0}): {1}".format(policy_id, str(ex)) 

152 ctx.logger.error("{0}: {1}".format(error, traceback.format_exc())) 

153 raise NonRecoverableError(error) 

154 

155 if not policy: 155 ↛ 156line 155 didn't jump to line 156, because the condition on line 155 was never true

156 error = "policy not found for policy_id {0}".format(policy_id) 

157 ctx.logger.info(error) 

158 if policy_required: 

159 raise NonRecoverableError(error) 

160 return True 

161 

162 ctx.logger.info("found policy {0}: {1}".format(policy_id, json.dumps(policy))) 

163 if POLICY_BODY in policy: 163 ↛ 165line 163 didn't jump to line 165, because the condition on line 163 was never false

164 ctx.instance.runtime_properties[POLICY_BODY] = policy[POLICY_BODY] 

165 return True 

166 

167 

168def _fix_policy_filter(policy_filter): 

169 if CONFIG_ATTRIBUTES in policy_filter: 169 ↛ exitline 169 didn't return from function '_fix_policy_filter', because the condition on line 169 was never false

170 config_attributes = policy_filter.get(CONFIG_ATTRIBUTES) 

171 if isinstance(config_attributes, dict): 171 ↛ 172line 171 didn't jump to line 172, because the condition on line 171 was never true

172 return 

173 try: 

174 config_attributes = json.loads(config_attributes) 

175 if config_attributes and isinstance(config_attributes, dict): 175 ↛ 180line 175 didn't jump to line 180, because the condition on line 175 was never false

176 policy_filter[CONFIG_ATTRIBUTES] = config_attributes 

177 return 

178 except (ValueError, TypeError): 

179 pass 

180 if config_attributes: 

181 ctx.logger.warn("unexpected %s: %s", CONFIG_ATTRIBUTES, config_attributes) 

182 del policy_filter[CONFIG_ATTRIBUTES] 

183 

184 

185def _policies_find(): 

186 """ 

187 dcae.nodes.policies - 

188 retrieve the latest policies for selection criteria 

189 and save found policies in runtime_properties 

190 """ 

191 if DCAE_POLICIES_TYPE not in ctx.node.type_hierarchy: 

192 return 

193 

194 policy_required = ctx.node.properties.get(POLICY_REQUIRED) 

195 

196 try: 

197 policy_filter = ctx.node.properties.get(POLICY_FILTER) 

198 if policy_filter: 198 ↛ 205line 198 didn't jump to line 205, because the condition on line 198 was never false

199 policy_filter = { 

200 k: copy.deepcopy(v) for k, v in policy_filter.items() 

201 if v or isinstance(v, (int, float)) 

202 } 

203 _fix_policy_filter(policy_filter) 

204 else: 

205 policy_filter = {} 

206 

207 if REQUEST_ID not in policy_filter: 207 ↛ 210line 207 didn't jump to line 210, because the condition on line 207 was never false

208 policy_filter[REQUEST_ID] = str(uuid.uuid4()) 

209 

210 policies_filtered = PolicyHandler.find_latest_policies(policy_filter) 

211 

212 if not policies_filtered: 212 ↛ 213line 212 didn't jump to line 213, because the condition on line 212 was never true

213 error = "policies not found by {0}".format(json.dumps(policy_filter)) 

214 ctx.logger.info(error) 

215 if policy_required: 

216 raise NonRecoverableError(error) 

217 return True 

218 

219 ctx.logger.info("found policies by {0}: {1}".format( 

220 json.dumps(policy_filter), json.dumps(policies_filtered) 

221 )) 

222 ctx.instance.runtime_properties[POLICIES_FILTERED] = policies_filtered 

223 

224 except Exception as ex: 

225 error = "failed to find policies: {0}".format(str(ex)) 

226 ctx.logger.error("{0}: {1}".format(error, traceback.format_exc())) 

227 raise NonRecoverableError(error) 

228 

229 return True 

230 

231 

232######################################################### 

233@operation 

234def policy_get(**kwargs): 

235 """retrieve the policy or policies and save it in runtime_properties""" 

236 if ctx.type != NODE_INSTANCE: 236 ↛ 237line 236 didn't jump to line 237, because the condition on line 236 was never true

237 raise NonRecoverableError("can only invoke policy_get on node of types: {0}" 

238 .format(DCAE_POLICY_TYPES)) 

239 

240 if not _policy_get() and not _policies_find(): 

241 error = "unexpected node type {0} for policy_get - expected types: {1}" \ 

242 .format(ctx.node.type_hierarchy, DCAE_POLICY_TYPES) 

243 ctx.logger.error(error) 

244 raise NonRecoverableError(error) 

245 

246 ctx.logger.info("exit policy_get")