1e57d0ebb75a3e35e2a9f84388f5578bf2287612
[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                          headers=originHeaders(request))
136
137     def post(self, request, vimid):
138
139         return self.send(vimid, request.get_full_path(), request.body, "POST",
140                          headers=originHeaders(request))
141
142     def patch(self, request, vimid):
143
144         return self.send(vimid, request.get_full_path(), request.body, "PATCH",
145                          headers=originHeaders(request))
146
147     def delete(self, request, vimid):
148
149         return self.send(vimid, request.get_full_path(), request.body,
150                          "DELETE", headers=originHeaders(request))
151
152     def head(self, request, vimid):
153
154         return self.send(vimid, request.get_full_path(), request.body, "HEAD",
155                          headers=originHeaders(request))
156
157     def put(self, request, vimid):
158
159         return self.send(vimid, request.get_full_path(), request.body, "PUT",
160                          headers=originHeaders(request))
161
162
163 # Multipart view
164 class MultiPartView(BaseServer):
165
166     parser_classes = (MultiPartParser, )
167
168     def post(self, request, vimid):
169         try:
170             register_openers()
171             fileDict = dict(request.FILES.iterlists())
172             params = {}
173             for key in fileDict.keys():
174                 fileObj = fileDict[key][0]
175                 f = tempfile.NamedTemporaryFile(prefix="django_",
176                                                 suffix=fileObj._name,
177                                                 delete=False)
178                 f.write(fileObj.file.read())
179                 f.seek(fileObj.file.tell(), 0)
180                 fileObj.file.close()
181                 params[key] = open(f.name, 'rb')
182             datagen, headers = multipart_encode(params)
183             regex = re.compile('^HTTP_')
184             for key, value in request.META.iteritems():
185                 if key.startswith("HTTP_"):
186                     headers[regex.sub('', key).replace('_', '-')] = value
187             resp = self.send(vimid, request.path, datagen, "POST",
188                              headers=headers)
189         finally:
190             for key in params:
191                 fileRef = params[key]
192                 if fileRef.closed is False:
193                     fileRef.close()
194                 os.remove(fileRef.name)
195         return resp