Random Inovocation ID
[multicloud/framework.git] / multivimbroker / multivimbroker / forwarder / views.py
1 # Copyright 2017 Wind River Systems, Inc.
2 # Copyright (c) 2017-2018 VMware, Inc.
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 implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15
16 import os
17 import json
18 import re
19 import tempfile
20 from poster.encode import multipart_encode
21 from poster.streaminghttp import register_openers
22
23 from rest_framework.views import APIView
24 from rest_framework.views import Response
25 from rest_framework.views import status
26 from multivimbroker.forwarder.base import BaseHandler
27 from multivimbroker.pub.utils.syscomm import originHeaders
28 from multivimbroker.pub.utils import syscomm
29 from rest_framework.parsers import MultiPartParser
30
31
32 class BaseServer(BaseHandler, APIView):
33
34     def get(self, request, vimid):
35         raise NotImplementedError()
36
37     def post(self, request, vimid):
38         raise NotImplementedError()
39
40     def put(self, request, vimid):
41         raise NotImplementedError()
42
43     def delete(self, request, vimid):
44         raise NotImplementedError()
45
46     def head(self, request, vimid):
47         raise NotImplementedError()
48
49     def patch(self, request, vimid):
50         raise NotImplementedError()
51
52
53 # proxy handler
54 class Identity(BaseServer):
55
56     def get(self, request, vimid):
57
58         return self.send(vimid, request.get_full_path(), request.body, "GET",
59                          headers=originHeaders(request))
60
61     def post(self, request, vimid):
62
63         return self.send(vimid, request.get_full_path(), request.body, "POST",
64                          headers=originHeaders(request))
65
66
67 class Registry(BaseServer):
68
69     def post(self, request, vimid):
70
71         return self.send(vimid, request.get_full_path(), request.body, "POST",
72                          headers=originHeaders(request))
73
74
75 class UnRegistry(BaseServer):
76
77     def delete(self, request, vimid):
78
79         return self.send(vimid, request.get_full_path(), request.body,
80                          "DELETE", headers=originHeaders(request))
81
82
83 class Extension(BaseServer):
84
85     def get(self, request, vimid):
86
87         return self.send(vimid, request.get_full_path(), request.body, "GET",
88                          headers=originHeaders(request))
89
90
91 class VIMTypes(BaseServer):
92
93     def get(self, request):
94         return Response(data=syscomm.getVIMTypes(), status=status.HTTP_200_OK)
95
96
97 class CheckCapacity(BaseServer):
98
99     def post(self, request):
100         try:
101             body = json.loads(request.body)
102         except ValueError as e:
103             return Response(
104                 data={'error': 'Invalidate request body %s.' % e},
105                 status=status.HTTP_400_BAD_REQUEST)
106
107         ret = {"VIMs": []}
108         newbody = {
109             "vCPU": body.get("vCPU", 0),
110             "Memory": body.get("Memory", 0),
111             "Storage": body.get("Storage", 0)
112         }
113         for vim in body.get("VIMs", []):
114             url = request.get_full_path().replace(
115                 "check_vim_capacity", "%s/capacity_check" % vim)
116             resp = self.send(vim, url, json.dumps(newbody), "POST")
117             if int(resp.status_code) != status.HTTP_200_OK:
118                 continue
119             try:
120                 resp_body = json.loads(resp.content)
121             except ValueError:
122                 continue
123             if not resp_body.get("result", False):
124                 continue
125             ret['VIMs'].append(vim)
126         return Response(data=ret, status=status.HTTP_200_OK)
127
128
129 # forward  handler
130 class Forward(BaseServer):
131
132     def get(self, request, vimid):
133
134         return self.send(vimid, request.get_full_path(), request.body, "GET")
135
136     def post(self, request, vimid):
137
138         return self.send(vimid, request.get_full_path(), request.body, "POST",
139                          headers=None)
140
141     def patch(self, request, vimid):
142
143         return self.send(vimid, request.get_full_path(), request.body, "PATCH",
144                          headers=None)
145
146     def delete(self, request, vimid):
147
148         return self.send(vimid, request.get_full_path(), request.body,
149                          "DELETE", headers=None)
150
151     def head(self, request, vimid):
152
153         return self.send(vimid, request.get_full_path(), request.body, "HEAD")
154
155     def put(self, request, vimid):
156
157         return self.send(vimid, request.get_full_path(), request.body, "PUT",
158                          headers=None)
159
160
161 # Multipart view
162 class MultiPartView(BaseServer):
163
164     parser_classes = (MultiPartParser, )
165
166     def post(self, request, vimid):
167         try:
168             register_openers()
169             fileDict = dict(request.FILES.iterlists())
170             params = {}
171             for key in fileDict.keys():
172                 fileObj = fileDict[key][0]
173                 f = tempfile.NamedTemporaryFile(prefix="django_",
174                                                 suffix=fileObj._name,
175                                                 delete=False)
176                 f.write(fileObj.file.read())
177                 f.seek(fileObj.file.tell(), 0)
178                 fileObj.file.close()
179                 params[key] = open(f.name, 'rb')
180             datagen, headers = multipart_encode(params)
181             regex = re.compile('^HTTP_')
182             for key, value in request.META.iteritems():
183                 if key.startswith("HTTP_"):
184                     headers[regex.sub('', key).replace('_', '-')] = value
185             resp = self.send(vimid, request.path, datagen, "POST",
186                              headers=headers)
187         finally:
188             for key in params:
189                 fileRef = params[key]
190                 if fileRef.closed is False:
191                     fileRef.close()
192                 os.remove(fileRef.name)
193         return resp