root / snfOCCI / APIserver.py @ f25a4623
History | View | Annotate | Download (18.8 kB)
1 | f25a4623 | nasia | # Copyright 2012-2013 GRNET S.A. All rights reserved.
|
---|---|---|---|
2 | f25a4623 | nasia | #
|
3 | f25a4623 | nasia | # Redistribution and use in source and binary forms, with or
|
4 | f25a4623 | nasia | # without modification, are permitted provided that the following
|
5 | f25a4623 | nasia | # conditions are met:
|
6 | f25a4623 | nasia | #
|
7 | f25a4623 | nasia | # 1. Redistributions of source code must retain the above
|
8 | f25a4623 | nasia | # copyright notice, this list of conditions and the following
|
9 | f25a4623 | nasia | # disclaimer.
|
10 | f25a4623 | nasia | #
|
11 | f25a4623 | nasia | # 2. Redistributions in binary form must reproduce the above
|
12 | f25a4623 | nasia | # copyright notice, this list of conditions and the following
|
13 | f25a4623 | nasia | # disclaimer in the documentation and/or other materials
|
14 | f25a4623 | nasia | # provided with the distribution.
|
15 | f25a4623 | nasia | #
|
16 | f25a4623 | nasia | # THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
|
17 | f25a4623 | nasia | # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
18 | f25a4623 | nasia | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
19 | f25a4623 | nasia | # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
|
20 | f25a4623 | nasia | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
21 | f25a4623 | nasia | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
22 | f25a4623 | nasia | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
23 | f25a4623 | nasia | # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
24 | f25a4623 | nasia | # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
25 | f25a4623 | nasia | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
26 | f25a4623 | nasia | # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
27 | f25a4623 | nasia | # POSSIBILITY OF SUCH DAMAGE.
|
28 | f25a4623 | nasia | #
|
29 | f25a4623 | nasia | # The views and conclusions contained in the software and
|
30 | f25a4623 | nasia | # documentation are those of the authors and should not be
|
31 | f25a4623 | nasia | # interpreted as representing official policies, either expressed
|
32 | f25a4623 | nasia | # or implied, of GRNET S.A.
|
33 | f25a4623 | nasia | |
34 | f25a4623 | nasia | |
35 | c687b8f4 | John Giannelos | #!/usr/bin/env python
|
36 | c687b8f4 | John Giannelos | |
37 | fe35958e | nasia | import sys |
38 | fe35958e | nasia | from optparse import OptionParser, OptionValueError |
39 | fe35958e | nasia | import string |
40 | fe35958e | nasia | import sqlite3 |
41 | fe35958e | nasia | import eventlet |
42 | fe35958e | nasia | from eventlet import wsgi |
43 | fe35958e | nasia | import os |
44 | fe35958e | nasia | import json |
45 | fe35958e | nasia | import uuid |
46 | fe35958e | nasia | |
47 | ed91cac4 | John Giannelos | from snfOCCI.registry import snfRegistry |
48 | ed91cac4 | John Giannelos | from snfOCCI.compute import ComputeBackend |
49 | fe35958e | nasia | from snfOCCI.config import SERVER_CONFIG, KAMAKI_CONFIG, VOMS_CONFIG |
50 | fe35958e | nasia | import snf_voms |
51 | 4ab8bfab | nasia | from snfOCCI.network import NetworkBackend, IpNetworkBackend, IpNetworkInterfaceBackend, NetworkInterfaceBackend |
52 | 4ab8bfab | nasia | |
53 | ed91cac4 | John Giannelos | |
54 | c687b8f4 | John Giannelos | from kamaki.clients.compute import ComputeClient |
55 | 4adfebfe | John Giannelos | from kamaki.clients.cyclades import CycladesClient |
56 | fe35958e | nasia | from kamaki.clients import astakos |
57 | 4ab8bfab | nasia | from kamaki.clients import ClientError |
58 | fe35958e | nasia | from kamaki.cli import config as kamaki_config |
59 | c687b8f4 | John Giannelos | |
60 | 77182fb8 | John Giannelos | from occi.core_model import Mixin, Resource |
61 | fe35958e | nasia | from occi.backend import MixinBackend |
62 | 4ab8bfab | nasia | from occi.extensions.infrastructure import COMPUTE, START, STOP, SUSPEND, RESTART, RESOURCE_TEMPLATE, OS_TEMPLATE, NETWORK, IPNETWORK, NETWORKINTERFACE,IPNETWORKINTERFACE |
63 | fe35958e | nasia | from occi import wsgi |
64 | 4ab8bfab | nasia | from occi.exceptions import HTTPError |
65 | 4ab8bfab | nasia | from occi import core_model |
66 | c687b8f4 | John Giannelos | |
67 | c687b8f4 | John Giannelos | from wsgiref.simple_server import make_server |
68 | c687b8f4 | John Giannelos | from wsgiref.validate import validator |
69 | fe35958e | nasia | from webob import Request |
70 | fe35958e | nasia | from pprint import pprint |
71 | fe35958e | nasia | |
72 | c687b8f4 | John Giannelos | |
73 | fe35958e | nasia | class MyAPP(wsgi.Application): |
74 | c687b8f4 | John Giannelos | '''
|
75 | c687b8f4 | John Giannelos | An OCCI WSGI application.
|
76 | c687b8f4 | John Giannelos | '''
|
77 | c687b8f4 | John Giannelos | |
78 | fe35958e | nasia | def __init__(self): |
79 | fe35958e | nasia | """
|
80 | fe35958e | nasia | Initialization of the WSGI OCCI application for synnefo
|
81 | fe35958e | nasia | """
|
82 | fe35958e | nasia | global ENABLE_VOMS, VOMS_DB
|
83 | fe35958e | nasia | ENABLE_VOMS = VOMS_CONFIG['enable_voms']
|
84 | fe35958e | nasia | super(MyAPP,self).__init__(registry=snfRegistry()) |
85 | fe35958e | nasia | self._register_backends()
|
86 | fe35958e | nasia | VALIDATOR_APP = validator(self)
|
87 | fe35958e | nasia | |
88 | fe35958e | nasia | |
89 | fe35958e | nasia | def _register_backends(self): |
90 | fe35958e | nasia | COMPUTE_BACKEND = ComputeBackend() |
91 | fe35958e | nasia | NETWORK_BACKEND = NetworkBackend() |
92 | fe35958e | nasia | NETWORKINTERFACE_BACKEND = NetworkInterfaceBackend() |
93 | fe35958e | nasia | IPNETWORK_BACKEND = IpNetworkBackend() |
94 | fe35958e | nasia | IPNETWORKINTERFACE_BACKEND = IpNetworkInterfaceBackend() |
95 | fe35958e | nasia | |
96 | fe35958e | nasia | self.register_backend(COMPUTE, COMPUTE_BACKEND)
|
97 | fe35958e | nasia | self.register_backend(START, COMPUTE_BACKEND)
|
98 | fe35958e | nasia | self.register_backend(STOP, COMPUTE_BACKEND)
|
99 | fe35958e | nasia | self.register_backend(RESTART, COMPUTE_BACKEND)
|
100 | fe35958e | nasia | self.register_backend(SUSPEND, COMPUTE_BACKEND)
|
101 | fe35958e | nasia | self.register_backend(RESOURCE_TEMPLATE, MixinBackend())
|
102 | fe35958e | nasia | self.register_backend(OS_TEMPLATE, MixinBackend())
|
103 | fe35958e | nasia | |
104 | fe35958e | nasia | # Network related backends
|
105 | fe35958e | nasia | self.register_backend(NETWORK, NETWORK_BACKEND)
|
106 | fe35958e | nasia | self.register_backend(IPNETWORK, IPNETWORK_BACKEND)
|
107 | fe35958e | nasia | self.register_backend(NETWORKINTERFACE,NETWORKINTERFACE_BACKEND)
|
108 | fe35958e | nasia | self.register_backend(IPNETWORKINTERFACE, IPNETWORKINTERFACE_BACKEND)
|
109 | fe35958e | nasia | |
110 | fe35958e | nasia | |
111 | 55ab2427 | John Giannelos | def refresh_images(self, snf, client): |
112 | fe35958e | nasia | try:
|
113 | fe35958e | nasia | images = snf.list_images() |
114 | fe35958e | nasia | for image in images: |
115 | fe35958e | nasia | IMAGE_ATTRIBUTES = {'occi.core.id': str(image['id'])} |
116 | fe35958e | nasia | IMAGE = Mixin("http://schemas.ogf.org/occi/os_tpl#", occify_terms(str(image['name'])), [OS_TEMPLATE],title='IMAGE' ,attributes = IMAGE_ATTRIBUTES) |
117 | fe35958e | nasia | self.register_backend(IMAGE, MixinBackend())
|
118 | fe35958e | nasia | except:
|
119 | fe35958e | nasia | raise HTTPError(404, "Unauthorized access") |
120 | fe35958e | nasia | |
121 | 55ab2427 | John Giannelos | def refresh_flavors(self, snf, client): |
122 | b7fca2d2 | John Giannelos | |
123 | 711721d6 | John Giannelos | flavors = snf.list_flavors() |
124 | 711721d6 | John Giannelos | for flavor in flavors: |
125 | 711721d6 | John Giannelos | details = snf.get_flavor_details(flavor['id'])
|
126 | 711721d6 | John Giannelos | FLAVOR_ATTRIBUTES = {'occi.core.id': flavor['id'], |
127 | 4ab8bfab | nasia | 'occi.compute.cores': str(details['vcpus']), |
128 | 4ab8bfab | nasia | 'occi.compute.memory': str(details['ram']), |
129 | 4ab8bfab | nasia | 'occi.storage.size': str(details['disk']), |
130 | 711721d6 | John Giannelos | } |
131 | fe35958e | nasia | FLAVOR = Mixin("http://schemas.ogf.org/occi/resource_tpl#", str(flavor['name']), [RESOURCE_TEMPLATE], attributes = FLAVOR_ATTRIBUTES) |
132 | b7fca2d2 | John Giannelos | self.register_backend(FLAVOR, MixinBackend())
|
133 | 4ab8bfab | nasia | |
134 | fe35958e | nasia | |
135 | 4ab8bfab | nasia | def refresh_flavors_norecursive(self, snf, client): |
136 | 4ab8bfab | nasia | flavors = snf.list_flavors(True)
|
137 | 4ab8bfab | nasia | print "Retrieving details for each image id" |
138 | 4ab8bfab | nasia | for flavor in flavors: |
139 | 4ab8bfab | nasia | FLAVOR_ATTRIBUTES = {'occi.core.id': flavor['id'], |
140 | 4ab8bfab | nasia | 'occi.compute.cores': str(flavor['vcpus']), |
141 | 4ab8bfab | nasia | 'occi.compute.memory': str(flavor['ram']), |
142 | 4ab8bfab | nasia | 'occi.storage.size': str(flavor['disk']), |
143 | 4ab8bfab | nasia | } |
144 | 4ab8bfab | nasia | |
145 | fe35958e | nasia | FLAVOR = Mixin("http://schemas.ogf.org/occi/resource_tpl#", occify_terms(str(flavor['name'])), [RESOURCE_TEMPLATE], title='FLAVOR',attributes = FLAVOR_ATTRIBUTES) |
146 | 4ab8bfab | nasia | self.register_backend(FLAVOR, MixinBackend())
|
147 | 4ab8bfab | nasia | |
148 | 4ab8bfab | nasia | def refresh_network_instances(self,client): |
149 | 4ab8bfab | nasia | networks =client.networks_get(command = 'detail')
|
150 | 4ab8bfab | nasia | network_details = networks.json['networks']
|
151 | 4ab8bfab | nasia | resources = self.registry.resources
|
152 | 4ab8bfab | nasia | occi_keys = resources.keys() |
153 | 4ab8bfab | nasia | |
154 | 4ab8bfab | nasia | for network in network_details: |
155 | 4ab8bfab | nasia | if '/network/'+str(network['id']) not in occi_keys: |
156 | 4ab8bfab | nasia | netID = '/network/'+str(network['id']) |
157 | 4ab8bfab | nasia | snf_net = core_model.Resource(netID, |
158 | 4ab8bfab | nasia | NETWORK, |
159 | 4ab8bfab | nasia | [IPNETWORK]) |
160 | 4ab8bfab | nasia | |
161 | 4ab8bfab | nasia | snf_net.attributes['occi.core.id'] = str(network['id']) |
162 | 4ab8bfab | nasia | |
163 | 4ab8bfab | nasia | #This info comes from the network details
|
164 | 4ab8bfab | nasia | snf_net.attributes['occi.network.state'] = str(network['status']) |
165 | 4ab8bfab | nasia | snf_net.attributes['occi.network.gateway'] = str(network['gateway']) |
166 | 4ab8bfab | nasia | |
167 | 4ab8bfab | nasia | if network['public'] == True: |
168 | 4ab8bfab | nasia | snf_net.attributes['occi.network.type'] = "Public = True" |
169 | 4ab8bfab | nasia | else:
|
170 | 4ab8bfab | nasia | snf_net.attributes['occi.network.type'] = "Public = False" |
171 | 4ab8bfab | nasia | |
172 | 4ab8bfab | nasia | self.registry.add_resource(netID, snf_net, None) |
173 | 4ab8bfab | nasia | |
174 | 4ab8bfab | nasia | |
175 | fe35958e | nasia | |
176 | 4ab8bfab | nasia | def refresh_compute_instances(self, snf, client): |
177 | dcb17973 | John Giannelos | '''Syncing registry with cyclades resources'''
|
178 | 4ab8bfab | nasia | |
179 | 77182fb8 | John Giannelos | servers = snf.list_servers() |
180 | 77182fb8 | John Giannelos | snf_keys = [] |
181 | 77182fb8 | John Giannelos | for server in servers: |
182 | 77182fb8 | John Giannelos | snf_keys.append(str(server['id'])) |
183 | 77182fb8 | John Giannelos | |
184 | 77182fb8 | John Giannelos | resources = self.registry.resources
|
185 | 77182fb8 | John Giannelos | occi_keys = resources.keys() |
186 | 77182fb8 | John Giannelos | |
187 | fe35958e | nasia | print occi_keys
|
188 | 4ab8bfab | nasia | for serverID in occi_keys: |
189 | 4ab8bfab | nasia | if '/compute/' in serverID and resources[serverID].attributes['occi.compute.hostname'] == "": |
190 | 4ab8bfab | nasia | self.registry.delete_resource(serverID, None) |
191 | 4ab8bfab | nasia | |
192 | 4ab8bfab | nasia | occi_keys = resources.keys() |
193 | 4ab8bfab | nasia | |
194 | 4ab8bfab | nasia | |
195 | 2bd4ca03 | John Giannelos | #Compute instances in synnefo not available in registry
|
196 | 77182fb8 | John Giannelos | diff = [x for x in snf_keys if '/compute/'+x not in occi_keys] |
197 | fe35958e | nasia | |
198 | 77182fb8 | John Giannelos | for key in diff: |
199 | 77182fb8 | John Giannelos | |
200 | 77182fb8 | John Giannelos | details = snf.get_server_details(int(key))
|
201 | 4ab8bfab | nasia | flavor = snf.get_flavor_details(details['flavor']['id']) |
202 | 4ab8bfab | nasia | |
203 | 4ab8bfab | nasia | try:
|
204 | fe35958e | nasia | print "line 65:Finished getting image details for VM "+key+" with ID" + str(details['flavor']['id']) |
205 | 4ab8bfab | nasia | image = snf.get_image_details(details['image']['id']) |
206 | 4ab8bfab | nasia | |
207 | 4ab8bfab | nasia | for i in self.registry.backends: |
208 | fe35958e | nasia | if i.term == occify_terms(str(image['name'])): |
209 | 4ab8bfab | nasia | rel_image = i |
210 | fe35958e | nasia | if i.term == occify_terms(str(flavor['name'])): |
211 | 4ab8bfab | nasia | rel_flavor = i |
212 | fe35958e | nasia | |
213 | 4ab8bfab | nasia | |
214 | 4ab8bfab | nasia | resource = Resource(key, COMPUTE, [rel_flavor, rel_image]) |
215 | 4ab8bfab | nasia | resource.actions = [START] |
216 | 4ab8bfab | nasia | resource.attributes['occi.core.id'] = key
|
217 | 4ab8bfab | nasia | resource.attributes['occi.compute.state'] = 'inactive' |
218 | 4ab8bfab | nasia | resource.attributes['occi.compute.architecture'] = SERVER_CONFIG['compute_arch'] |
219 | 4ab8bfab | nasia | resource.attributes['occi.compute.cores'] = str(flavor['vcpus']) |
220 | 4ab8bfab | nasia | resource.attributes['occi.compute.memory'] = str(flavor['ram']) |
221 | 4ab8bfab | nasia | resource.attributes['occi.core.title'] = str(details['name']) |
222 | 4ab8bfab | nasia | networkIDs = details['addresses'].keys()
|
223 | 4ab8bfab | nasia | if len(networkIDs)>0: |
224 | 4ab8bfab | nasia | resource.attributes['occi.compute.hostname'] = str(details['addresses'][networkIDs[0]][0]['addr']) |
225 | 4ab8bfab | nasia | else:
|
226 | 4ab8bfab | nasia | resource.attributes['occi.compute.hostname'] = "" |
227 | 4ab8bfab | nasia | |
228 | 4ab8bfab | nasia | self.registry.add_resource(key, resource, None) |
229 | 4ab8bfab | nasia | |
230 | 4ab8bfab | nasia | for netKey in networkIDs: |
231 | 4ab8bfab | nasia | link_id = str(uuid.uuid4())
|
232 | 4ab8bfab | nasia | NET_LINK = core_model.Link("http://schemas.ogf.org/occi/infrastructure#networkinterface" + link_id,
|
233 | 4ab8bfab | nasia | NETWORKINTERFACE, |
234 | 4ab8bfab | nasia | [IPNETWORKINTERFACE], resource, |
235 | 4ab8bfab | nasia | self.registry.resources['/network/'+str(netKey)]) |
236 | 4ab8bfab | nasia | |
237 | 4ab8bfab | nasia | for version in details['addresses'][netKey]: |
238 | 4ab8bfab | nasia | if version['version']==4: |
239 | 4ab8bfab | nasia | ip4address = str(version['addr']) |
240 | 4ab8bfab | nasia | allocheme = str(version['OS-EXT-IPS:type']) |
241 | 4ab8bfab | nasia | elif version['version']==6: |
242 | 4ab8bfab | nasia | ip6address = str(version['addr']) |
243 | 4ab8bfab | nasia | |
244 | 4ab8bfab | nasia | if 'attachments' in details.keys(): |
245 | 4ab8bfab | nasia | for item in details['attachments']: |
246 | 4ab8bfab | nasia | NET_LINK.attributes ={'occi.core.id':link_id,
|
247 | 4ab8bfab | nasia | 'occi.networkinterface.allocation' : allocheme,
|
248 | 4ab8bfab | nasia | 'occi.networking.interface': str(item['id']), |
249 | 4ab8bfab | nasia | 'occi.networkinterface.mac' : str(item['mac_address']), |
250 | fe35958e | nasia | 'occi.networkinterface.address' : ip4address,
|
251 | 4ab8bfab | nasia | 'occi.networkinterface.ip6' : ip6address
|
252 | 4ab8bfab | nasia | } |
253 | 4ab8bfab | nasia | elif len(details['addresses'][netKey])>0: |
254 | 4ab8bfab | nasia | NET_LINK.attributes ={'occi.core.id':link_id,
|
255 | 4ab8bfab | nasia | 'occi.networkinterface.allocation' : allocheme,
|
256 | 4ab8bfab | nasia | 'occi.networking.interface': '', |
257 | 4ab8bfab | nasia | 'occi.networkinterface.mac' : '', |
258 | fe35958e | nasia | 'occi.networkinterface.address' : ip4address,
|
259 | 4ab8bfab | nasia | 'occi.networkinterface.ip6' : ip6address
|
260 | 4ab8bfab | nasia | } |
261 | 4ab8bfab | nasia | |
262 | 4ab8bfab | nasia | else:
|
263 | 4ab8bfab | nasia | NET_LINK.attributes ={'occi.core.id':link_id,
|
264 | 4ab8bfab | nasia | 'occi.networkinterface.allocation' : '', |
265 | 4ab8bfab | nasia | 'occi.networking.interface': '', |
266 | 4ab8bfab | nasia | 'occi.networkinterface.mac' : '', |
267 | fe35958e | nasia | 'occi.networkinterface.address' :'', |
268 | 4ab8bfab | nasia | 'occi.networkinterface.ip6' : '' } |
269 | 4ab8bfab | nasia | |
270 | 4ab8bfab | nasia | resource.links.append(NET_LINK) |
271 | 4ab8bfab | nasia | self.registry.add_resource(link_id, NET_LINK, None) |
272 | 4ab8bfab | nasia | |
273 | 4ab8bfab | nasia | |
274 | 4ab8bfab | nasia | except ClientError as ce: |
275 | 4ab8bfab | nasia | if ce.status == 404: |
276 | fe35958e | nasia | print('Image not found (probably older version')
|
277 | 4ab8bfab | nasia | continue
|
278 | 4ab8bfab | nasia | else:
|
279 | 4ab8bfab | nasia | raise ce
|
280 | 4ab8bfab | nasia | |
281 | 2bd4ca03 | John Giannelos | #Compute instances in registry not available in synnefo
|
282 | dcb17973 | John Giannelos | diff = [x for x in occi_keys if x[9:] not in snf_keys] |
283 | dcb17973 | John Giannelos | for key in diff: |
284 | 4ab8bfab | nasia | if '/network/' not in key: |
285 | 4ab8bfab | nasia | self.registry.delete_resource(key, None) |
286 | dcb17973 | John Giannelos | |
287 | fe35958e | nasia | |
288 | b7fca2d2 | John Giannelos | def __call__(self, environ, response): |
289 | 4ab8bfab | nasia | |
290 | fe35958e | nasia | # Enable VOMS Authorization
|
291 | fe35958e | nasia | print "snf-occi application has been called!" |
292 | fe35958e | nasia | |
293 | fe35958e | nasia | req = Request(environ) |
294 | fe35958e | nasia | auth_endpoint = 'snf-auth uri=\'https://'+SERVER_CONFIG['hostname']+':5000/main\'' |
295 | fe35958e | nasia | |
296 | fe35958e | nasia | if not req.environ.has_key('HTTP_X_AUTH_TOKEN'): |
297 | fe35958e | nasia | |
298 | fe35958e | nasia | print "Error: An authentication token has not been provided!" |
299 | fe35958e | nasia | status = '401 Not Authorized'
|
300 | fe35958e | nasia | headers = [('Content-Type', 'text/html'),('Www-Authenticate',auth_endpoint)] |
301 | fe35958e | nasia | response(status,headers) |
302 | fe35958e | nasia | return [str(response)] |
303 | fe35958e | nasia | |
304 | fe35958e | nasia | |
305 | fe35958e | nasia | if ENABLE_VOMS:
|
306 | fe35958e | nasia | |
307 | fe35958e | nasia | if req.environ.has_key('HTTP_X_AUTH_TOKEN'): |
308 | fe35958e | nasia | |
309 | fe35958e | nasia | environ['HTTP_AUTH_TOKEN']= req.environ['HTTP_X_AUTH_TOKEN'] |
310 | fe35958e | nasia | compClient = ComputeClient(KAMAKI_CONFIG['compute_url'], environ['HTTP_AUTH_TOKEN']) |
311 | fe35958e | nasia | cyclClient = CycladesClient(KAMAKI_CONFIG['compute_url'], environ['HTTP_AUTH_TOKEN']) |
312 | fe35958e | nasia | |
313 | fe35958e | nasia | try:
|
314 | fe35958e | nasia | #Up-to-date flavors and images
|
315 | fe35958e | nasia | self.refresh_images(compClient,cyclClient)
|
316 | fe35958e | nasia | self.refresh_flavors_norecursive(compClient,cyclClient)
|
317 | fe35958e | nasia | self.refresh_network_instances(cyclClient)
|
318 | fe35958e | nasia | self.refresh_compute_instances(compClient,cyclClient)
|
319 | fe35958e | nasia | # token will be represented in self.extras
|
320 | fe35958e | nasia | return self._call_occi(environ, response, security = None, token = environ['HTTP_AUTH_TOKEN'], snf = compClient, client = cyclClient) |
321 | fe35958e | nasia | except HTTPError:
|
322 | fe35958e | nasia | print "Exception from unauthorized access!" |
323 | fe35958e | nasia | status = '401 Not Authorized'
|
324 | fe35958e | nasia | headers = [('Content-Type', 'text/html'),('Www-Authenticate',auth_endpoint)] |
325 | fe35958e | nasia | response(status,headers) |
326 | fe35958e | nasia | return [str(response)] |
327 | fe35958e | nasia | |
328 | fe35958e | nasia | else:
|
329 | fe35958e | nasia | |
330 | fe35958e | nasia | #raise HTTPError(404, "Unauthorized access")
|
331 | fe35958e | nasia | status = '401 Not Authorized'
|
332 | fe35958e | nasia | headers = [('Content-Type', 'text/html'),('Www-Authenticate',auth_endpoint)] |
333 | fe35958e | nasia | response(status,headers) |
334 | fe35958e | nasia | return [str(response)] |
335 | fe35958e | nasia | |
336 | fe35958e | nasia | else:
|
337 | 4ab8bfab | nasia | compClient = ComputeClient(KAMAKI_CONFIG['compute_url'], environ['HTTP_AUTH_TOKEN']) |
338 | 4ab8bfab | nasia | cyclClient = CycladesClient(KAMAKI_CONFIG['compute_url'], environ['HTTP_AUTH_TOKEN']) |
339 | 4ab8bfab | nasia | |
340 | 4ab8bfab | nasia | #Up-to-date flavors and images
|
341 | fe35958e | nasia | |
342 | 4ab8bfab | nasia | self.refresh_images(compClient,cyclClient)
|
343 | fe35958e | nasia | |
344 | 4ab8bfab | nasia | self.refresh_flavors_norecursive(compClient,cyclClient)
|
345 | 4ab8bfab | nasia | self.refresh_network_instances(cyclClient)
|
346 | 4ab8bfab | nasia | self.refresh_compute_instances(compClient,cyclClient)
|
347 | fe35958e | nasia | |
348 | 4ab8bfab | nasia | # token will be represented in self.extras
|
349 | 4ab8bfab | nasia | return self._call_occi(environ, response, security = None, token = environ['HTTP_AUTH_TOKEN'], snf = compClient, client = cyclClient) |
350 | c687b8f4 | John Giannelos | |
351 | fe35958e | nasia | def application(env, start_response): |
352 | fe35958e | nasia | |
353 | fe35958e | nasia | print "snf-occi will execute voms authentication" |
354 | fe35958e | nasia | t =snf_voms.VomsAuthN() |
355 | fe35958e | nasia | (user_dn, user_vo, user_fqans) = t.process_request(env) |
356 | fe35958e | nasia | print (user_dn, user_vo, user_fqans)
|
357 | fe35958e | nasia | |
358 | fe35958e | nasia | env['HTTP_AUTH_TOKEN'] = get_user_token(user_dn)
|
359 | fe35958e | nasia | |
360 | fe35958e | nasia | # Get user authentication details
|
361 | fe35958e | nasia | astakosClient = astakos.AstakosClient(KAMAKI_CONFIG['astakos_url'], env['HTTP_AUTH_TOKEN']) |
362 | fe35958e | nasia | user_details = astakosClient.authenticate() |
363 | fe35958e | nasia | |
364 | fe35958e | nasia | response = {'access': {'token':{'issued_at':'','expires': user_details['access']['token']['expires'] , 'id':env['HTTP_AUTH_TOKEN']}, |
365 | fe35958e | nasia | 'serviceCatalog': [],
|
366 | fe35958e | nasia | 'user':{'username': user_dn,'roles_links':user_details['access']['user']['roles_links'],'id': user_details['access']['user']['id'], 'roles':[], 'name':user_dn }, |
367 | fe35958e | nasia | 'metadata': {'is_admin': 0, 'roles': user_details['access']['user']['roles']}}} |
368 | fe35958e | nasia | |
369 | fe35958e | nasia | |
370 | fe35958e | nasia | status = '200 OK'
|
371 | fe35958e | nasia | headers = [('Content-Type', 'application/json')] |
372 | fe35958e | nasia | start_response(status,headers) |
373 | 22167a8c | John Giannelos | |
374 | fe35958e | nasia | body = json.dumps(response) |
375 | fe35958e | nasia | print body
|
376 | fe35958e | nasia | return [body]
|
377 | 43b14afb | John Giannelos | |
378 | fe35958e | nasia | |
379 | fe35958e | nasia | def app_factory(global_config, **local_config): |
380 | fe35958e | nasia | """This function wraps our simple WSGI app so it
|
381 | fe35958e | nasia | can be used with paste.deploy"""
|
382 | fe35958e | nasia | return application
|
383 | fe35958e | nasia | |
384 | fe35958e | nasia | def tenant_application(env, start_response): |
385 | fe35958e | nasia | |
386 | fe35958e | nasia | print "snf-occi will return tenant information" |
387 | fe35958e | nasia | if env.has_key('SSL_CLIENT_S_DN_ENV'): |
388 | fe35958e | nasia | print env['SSL_CLIENT_S_DN_ENV'], env['SSL_CLIENT_CERT_ENV'] |
389 | c687b8f4 | John Giannelos | |
390 | fe35958e | nasia | req = Request(env) |
391 | fe35958e | nasia | if req.environ.has_key('HTTP_X_AUTH_TOKEN'): |
392 | fe35958e | nasia | env['HTTP_AUTH_TOKEN']= req.environ['HTTP_X_AUTH_TOKEN'] |
393 | fe35958e | nasia | else:
|
394 | fe35958e | nasia | raise HTTPError(404, "Unauthorized access") |
395 | fe35958e | nasia | # Get user authentication details
|
396 | fe35958e | nasia | print "@ refresh_user authentication details" |
397 | fe35958e | nasia | astakosClient = astakos.AstakosClient(KAMAKI_CONFIG['astakos_url'], env['HTTP_AUTH_TOKEN']) |
398 | fe35958e | nasia | user_details = astakosClient.authenticate() |
399 | fe35958e | nasia | |
400 | fe35958e | nasia | response = {'tenants_links': [], 'tenants':[{'description':'Instances of EGI Federated Clouds TF','enabled': True, 'id':user_details['access']['user']['id'],'name':'EGI_FCTF'}]} |
401 | fe35958e | nasia | |
402 | fe35958e | nasia | status = '200 OK'
|
403 | fe35958e | nasia | headers = [('Content-Type', 'application/json')] |
404 | fe35958e | nasia | start_response(status,headers) |
405 | fe35958e | nasia | |
406 | fe35958e | nasia | body = json.dumps(response) |
407 | fe35958e | nasia | print body
|
408 | fe35958e | nasia | return [body]
|
409 | fe35958e | nasia | |
410 | fe35958e | nasia | |
411 | fe35958e | nasia | def tenant_app_factory(global_config, **local_config): |
412 | fe35958e | nasia | """This function wraps our simple WSGI app so it
|
413 | fe35958e | nasia | can be used with paste.deploy"""
|
414 | fe35958e | nasia | return tenant_application
|
415 | fe35958e | nasia | |
416 | fe35958e | nasia | |
417 | 43b14afb | John Giannelos | |
418 | fe35958e | nasia | def occify_terms(term_name): |
419 | fe35958e | nasia | '''
|
420 | fe35958e | nasia | Occifies a term_name so that it is compliant with GFD 185.
|
421 | fe35958e | nasia | '''
|
422 | fe35958e | nasia | term = term_name.strip().replace(' ', '_').replace('.', '-').lower() |
423 | fe35958e | nasia | term=term.replace('(','_').replace(')','_').replace('@','_').replace('+','-_') |
424 | fe35958e | nasia | return term
|
425 | fe35958e | nasia | |
426 | fe35958e | nasia | def get_user_token(user_dn): |
427 | fe35958e | nasia | config = kamaki_config.Config() |
428 | fe35958e | nasia | return config.get_cloud("default", "token") |