1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
# Copyright 2017-2018 Intel Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import logging
import json
from lcm.pub.database.models import OOFDataModel
from lcm.pub.utils import values
logger = logging.getLogger(__name__)
class PlaceVnfs(object):
def __init__(self, data):
self.data = data
self.placements = ""
self.request_id = data.get("requestId")
def validateCallbackResponse(self):
if self.data == "":
logger.error("Error occurred in Homing: OOF Async Callback Response is empty")
return False
if self.data.get('requestStatus') == "completed" and self.data.get("requestId"):
if self.data.get("solutions").get("placementSolutions") is not None:
self.placements = self.data.get("solutions").get("placementSolutions")
logger.debug("Got placement solutions in OOF Async Callback response")
return True
else:
logger.error("Error occurred in Homing: OOF Async Callback Response "
"does not contain placement solution")
return False
else:
if self.data.get("statusMessage"):
logger.error(
"Error occurred in Homing: Request has not been completed, the request status is %s, "
"the status message is %s" % (self.data.get('requestStatus'), self.data.get("statusMessage")))
else:
logger.error(
"Error occurred in Homing: Request has not been completed, the request status is %s, "
% self.data.get('requestStatus'))
return False
def extract(self):
params = ["locationId", "vimId", "oof_directives", "cloudOwner"]
vim_info = {}
if not self.validateCallbackResponse():
logger.error("OOF request Failed")
self.update_response_to_db(self.request_id, self.data.get("requestStatus"), "none", "none",
"none", "none")
return
if self.placements == [] or self.placements == [[]]:
logger.debug("No solution found for request %s " % self.request_id)
self.update_response_to_db(self.request_id, self.data.get("requestStatus"), "none", "none",
"none", "none")
return
for item in self.placements:
if not isinstance(item, list):
self.update_response_to_db(self.request_id, self.data.get("requestStatus"), "none", "none",
"none", "none")
continue
for placement in item:
assignmentInfo = placement.get("assignmentInfo")
if not assignmentInfo or not placement.get("solution"):
logger.debug(
"No assignment info/Solution inside Homing response for request %s"
% self.request_id)
self.update_response_to_db(self.request_id, self.data.get("requestStatus"), "none", "none",
"none", "none")
continue
for info in assignmentInfo:
if info.get("key") in params:
vim_info[info.get("key")] = info.get("value")
if not vim_info.get("oof_directives"):
logger.warn("Missing flavor info as no directive found in response")
self.update_response_to_db(self.request_id,
self.data.get("requestStatus"), "none", "none",
"none", "none")
continue
vduinfo = self.get_info_from_directives(
vim_info['oof_directives'])
if not vduinfo:
self.update_response_to_db(self.request_id,
self.data.get("requestStatus"), "none", "none",
"none", "none")
return
else:
cloud_owner = placement.get("solution").get("cloudOwner") \
if placement.get("solution").get("cloudOwner") \
else vim_info.get("cloudOwner")
location_id = vim_info.get("locationId")
if not cloud_owner or not location_id:
self.update_response_to_db(self.request_id,
self.data.get("requestStatus"), "none", "none",
"none", "none")
return
vim_id = vim_info['vimId'] if vim_info.get('vimId') \
else cloud_owner + "_" + location_id
self.update_response_to_db(requestId=self.request_id,
requestStatus=self.data.get("requestStatus"),
vimId=vim_id,
cloudOwner=cloud_owner,
cloudRegionId=values.ignore_case_get(vim_info, "locationId"),
vduInfo=vduinfo)
logger.debug(
"Placement solution has been stored for request %s " % self.request_id)
return "Done"
def get_info_from_directives(self, directives):
vduinfo = []
for directive in directives.get("directives"):
if directive.get("type") == "tosca.nodes.nfv.Vdu.Compute":
vdu = {"vduName": directive.get("id")}
other_directives = []
for item in directive.get("directives"):
if item.get("type") == "flavor_directives":
for attribute in item.get("attributes"):
vdu[attribute.get("attribute_name")] = attribute.get("attribute_value")
else:
other_directives.append(item)
if other_directives:
other_directives = json.dumps(other_directives)
vdu['directive'] = other_directives
vduinfo.append(vdu)
else:
logger.warn("Find unrecognized type %s " % directive.get("type"))
if vduinfo:
vduinfo = json.dumps(vduinfo)
return vduinfo
else:
logger.warn("No OOF directive for VDU")
return None
def update_response_to_db(self, requestId, requestStatus, vimId, cloudOwner,
cloudRegionId, vduInfo):
OOFDataModel.objects.filter(request_id=requestId).update(
request_status=requestStatus,
vim_id=vimId,
cloud_owner=cloudOwner,
cloud_region_id=cloudRegionId,
vdu_info=vduInfo
)
|