1 # Copyright (c) 2015 SONATA-NFV and Paderborn University
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
8 # http://www.apache.org/licenses/LICENSE-2.0
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.
16 # Neither the name of the SONATA-NFV, Paderborn University
17 # nor the names of its contributors may be used to endorse or promote
18 # products derived from this software without specific prior written
21 # This work has been performed in the framework of the SONATA project,
22 # funded by the European Commission under Grant number 671517 through
23 # the Horizon 2020 and 5G-PPP programmes. The authors would like to
24 # acknowledge the contributions of their colleagues of the SONATA
25 # partner consortium (www.sonata-nfv.eu).
26 from flask_restful
import Resource
27 from flask
import request
, Response
28 from emuvim
.api
.openstack
.openstack_dummies
.base_openstack_dummy
import BaseOpenstackDummy
29 from emuvim
.api
.openstack
.helper
import get_host
33 LOG
= logging
.getLogger("api.openstack.keystone")
36 class KeystoneDummyApi(BaseOpenstackDummy
):
37 def __init__(self
, in_ip
, in_port
):
38 super(KeystoneDummyApi
, self
).__init
__(in_ip
, in_port
)
40 self
.api
.add_resource(KeystoneListVersions
, "/",
41 resource_class_kwargs
={'api': self
})
42 self
.api
.add_resource(KeystoneShowAPIv2
, "/v2.0",
43 resource_class_kwargs
={'api': self
})
44 self
.api
.add_resource(KeystoneGetToken
, "/v2.0/tokens",
45 resource_class_kwargs
={'api': self
})
46 self
.api
.add_resource(KeystoneShowAPIv3
, "/v3.0",
47 resource_class_kwargs
={'api': self
})
48 self
.api
.add_resource(
49 KeystoneGetTokenv3
, "/v3.0/auth/tokens", resource_class_kwargs
={'api': self
})
52 class KeystoneListVersions(Resource
):
54 List all known keystone versions.
55 Hardcoded for our version!
58 def __init__(self
, api
):
65 :return: Returns the api versions.
66 :rtype: :class:`flask.response` containing a static json encoded dict.
68 LOG
.debug("API CALL: %s GET" % str(self
.__class
__.__name
__))
70 resp
['versions'] = dict()
76 "href": "http://%s:%d/v2.0" % (get_host(request
), self
.api
.port
),
82 "base": "application/json",
83 "type": "application/vnd.openstack.identity-v2.0+json"
87 "updated": "2014-04-17T00:00:00Z"
89 resp
['versions']['values'] = version
91 return Response(json
.dumps(resp
), status
=200,
92 mimetype
='application/json')
95 class KeystoneShowAPIv2(Resource
):
97 Entrypoint for all openstack clients.
98 This returns all current entrypoints running on son-emu.
101 def __init__(self
, api
):
106 List API entrypoints.
108 :return: Returns an openstack style response for all entrypoints.
109 :rtype: :class:`flask.response`
111 LOG
.debug("API CALL: %s GET" % str(self
.__class
__.__name
__))
113 # neutron_port = self.api.port + 4696
114 # heat_port = self.api.port + 3004
121 "base": "application/json",
122 "type": "application/vnd.openstack.identity-v2.0+json"
128 "href": "http://%s:%d/v2.0" % (get_host(request
), self
.api
.port
),
133 LOG
.debug(json
.dumps(resp
))
134 return Response(json
.dumps(resp
), status
=200,
135 mimetype
='application/json')
138 class KeystoneShowAPIv3(Resource
):
140 Entrypoint for all openstack clients.
141 This returns all current entrypoints running on son-emu.
144 def __init__(self
, api
):
149 List API entrypoints.
151 :return: Returns an openstack style response for all entrypoints.
152 :rtype: :class:`flask.response`
154 LOG
.debug("API CALL: %s GET" % str(self
.__class
__.__name
__))
156 # neutron_port = self.api.port + 4696
157 # heat_port = self.api.port + 3004
164 "base": "application/json",
165 "type": "application/vnd.openstack.identity-v3.0+json"
171 "href": "http://%s:%d/v3.0" % (get_host(request
), self
.api
.port
),
177 return Response(json
.dumps(resp
), status
=200,
178 mimetype
='application/json')
181 class KeystoneGetToken(Resource
):
183 Returns a static keystone token.
184 We don't do any validation so we don't care.
187 def __init__(self
, api
):
192 List API entrypoints.
194 This is hardcoded. For a working "authentication" use these ENVVARS:
196 * OS_AUTH_URL=http://<ip>:<port>/v2.0
197 * OS_IDENTITY_API_VERSION=2.0
198 * OS_TENANT_ID=fc394f2ab2df4114bde39905f800dc57
199 * OS_REGION_NAME=RegionOne
203 :return: Returns an openstack style response for all entrypoints.
204 :rtype: :class:`flask.response`
207 LOG
.debug("API CALL: %s POST" % str(self
.__class
__.__name
__))
210 req
= json
.loads(request
.data
)
211 ret
['access'] = dict()
212 ret
['access']['token'] = dict()
213 token
= ret
['access']['token']
215 token
['issued_at'] = "2014-01-30T15:30:58.819Z"
216 token
['expires'] = "2999-01-30T15:30:58.819Z"
217 token
['id'] = req
['auth'].get(
218 'token', {'id': 'fc394f2ab2df4114bde39905f800dc57'}).get('id')
219 token
['tenant'] = dict()
220 token
['tenant']['description'] = None
221 token
['tenant']['enabled'] = True
222 token
['tenant']['id'] = req
['auth'].get(
223 'tenantId', 'fc394f2ab2df4114bde39905f800dc57')
224 token
['tenant']['name'] = "tenantName"
226 ret
['access']['user'] = dict()
227 user
= ret
['access']['user']
228 user
['username'] = req
.get('username', "username")
229 user
['name'] = "tenantName"
230 user
['roles_links'] = list()
231 user
['id'] = token
['tenant'].get(
232 'id', "fc394f2ab2df4114bde39905f800dc57")
233 user
['roles'] = [{'name': 'Member'}]
235 ret
['access']['region_name'] = "RegionOne"
237 ret
['access']['serviceCatalog'] = [{
240 "adminURL": "http://%s:%s/v2.1/%s" % (get_host(request
), self
.api
.port
+ 3774, user
['id']),
241 "region": "RegionOne",
242 "internalURL": "http://%s:%s/v2.1/%s" % (get_host(request
), self
.api
.port
+ 3774, user
['id']),
243 "id": "2dad48f09e2a447a9bf852bcd93548ef",
244 "publicURL": "http://%s:%s/v2.1/%s" % (get_host(request
), self
.api
.port
+ 3774, user
['id'])
247 "endpoints_links": [],
254 "adminURL": "http://%s:%s/v2.0" % (get_host(request
), self
.api
.port
),
255 "region": "RegionOne",
256 "internalURL": "http://%s:%s/v2.0" % (get_host(request
), self
.api
.port
),
257 "id": "2dad48f09e2a447a9bf852bcd93543fc",
258 "publicURL": "http://%s:%s/v2" % (get_host(request
), self
.api
.port
)
261 "endpoints_links": [],
268 "adminURL": "http://%s:%s" % (get_host(request
), self
.api
.port
+ 4696),
269 "region": "RegionOne",
270 "internalURL": "http://%s:%s" % (get_host(request
), self
.api
.port
+ 4696),
271 "id": "2dad48f09e2a447a9bf852bcd93548cf",
272 "publicURL": "http://%s:%s" % (get_host(request
), self
.api
.port
+ 4696)
275 "endpoints_links": [],
282 "adminURL": "http://%s:%s" % (get_host(request
), self
.api
.port
+ 4242),
283 "region": "RegionOne",
284 "internalURL": "http://%s:%s" % (get_host(request
), self
.api
.port
+ 4242),
285 "id": "2dad48f09e2a447a9bf852bcd93548cf",
286 "publicURL": "http://%s:%s" % (get_host(request
), self
.api
.port
+ 4242)
289 "endpoints_links": [],
296 "adminURL": "http://%s:%s/v1/%s" % (get_host(request
), self
.api
.port
+ 3004, user
['id']),
297 "region": "RegionOne",
298 "internalURL": "http://%s:%s/v1/%s" % (get_host(request
), self
.api
.port
+ 3004, user
['id']),
299 "id": "2dad48f09e2a447a9bf852bcd93548bf",
300 "publicURL": "http://%s:%s/v1/%s" % (get_host(request
), self
.api
.port
+ 3004, user
['id'])
303 "endpoints_links": [],
304 "type": "orchestration",
309 ret
['access']["metadata"] = {
312 "7598ac3c634d4c3da4b9126a5f67ca2b"
315 ret
['access']['trust'] = {
316 "id": "394998fa61f14736b1f0c1f322882949",
317 "trustee_user_id": "269348fdd9374b8885da1418e0730af1",
318 "trustor_user_id": "3ec3164f750146be97f21559ee4d9c51",
319 "impersonation": False
321 return Response(json
.dumps(ret
), status
=200,
322 mimetype
='application/json')
324 except Exception as ex
:
325 logging
.exception("Keystone: Get token failed.")
329 class KeystoneGetTokenv3(Resource
):
331 Returns a static keystone token.
332 We don't do any validation so we don't care.
335 def __init__(self
, api
):
340 List API entrypoints.
342 This is hardcoded. For a working "authentication" use these ENVVARS:
344 * OS_AUTH_URL=http://<ip>:<port>/v3
345 * OS_IDENTITY_API_VERSION=2.0
346 * OS_TENANT_ID=fc394f2ab2df4114bde39905f800dc57
347 * OS_REGION_NAME=RegionOne
351 :return: Returns an openstack style response for all entrypoints.
352 :rtype: :class:`flask.response`
355 LOG
.debug("API CALL: %s POST" % str(self
.__class
__.__name
__))
358 req
= json
.loads(request
.data
)
359 ret
['token'] = dict()
362 token
['issued_at'] = "2014-01-30T15:30:58.819Z"
363 token
['expires_at'] = "2999-01-30T15:30:58.819Z"
364 token
['methods'] = ["password"]
365 token
['extras'] = dict()
366 token
['user'] = dict()
368 user
['id'] = req
['auth'].get(
369 'token', {'id': 'fc394f2ab2df4114bde39905f800dc57'}).get('id')
370 user
['name'] = "tenantName"
371 user
['password_expires_at'] = None
372 user
['domain'] = {"id": "default", "name": "Default"}
373 token
['audit_ids'] = ["ZzZwkUflQfygX7pdYDBCQQ"]
381 "id": "8538a3f13f9541b28c2620eb19065e45",
386 token
['catalog'] = [{
389 "url": "http://%s:%s/v2.1/%s" % (get_host(request
), self
.api
.port
+ 3774, user
['id']),
390 "region": "RegionOne",
391 "interface": "public",
392 "id": "2dad48f09e2a447a9bf852bcd93548ef"
395 "id": "2dad48f09e2a447a9bf852bcd93548ef",
402 "url": "http://%s:%s/v2.0" % (get_host(request
), self
.api
.port
),
403 "region": "RegionOne",
404 "interface": "public",
405 "id": "2dad48f09e2a447a9bf852bcd93543fc"
408 "id": "2dad48f09e2a447a9bf852bcd93543fc",
415 "url": "http://%s:%s" % (get_host(request
), self
.api
.port
+ 4696),
416 "region": "RegionOne",
417 "interface": "public",
418 "id": "2dad48f09e2a447a9bf852bcd93548cf"
421 "id": "2dad48f09e2a447a9bf852bcd93548cf",
428 "url": "http://%s:%s" % (get_host(request
), self
.api
.port
+ 4242),
429 "region": "RegionOne",
430 "interface": "public",
431 "id": "2dad48f09e2a447a9bf852bcd93548cf"
434 "id": "2dad48f09e2a447a9bf852bcd93548cf",
441 "url": "http://%s:%s/v1/%s" % (get_host(request
), self
.api
.port
+ 3004, user
['id']),
442 "region": "RegionOne",
443 "interface": "public",
444 "id": "2dad48f09e2a447a9bf852bcd93548bf"
447 "id": "2dad48f09e2a447a9bf852bcd93548bf",
448 "type": "orchestration",
452 return Response(json
.dumps(ret
), status
=201,
453 mimetype
='application/json')
455 except Exception as ex
:
456 logging
.exception("Keystone: Get token failed.")