1 from flask_restful
import Resource
2 from flask
import request
, Response
3 from emuvim
.api
.openstack
.openstack_dummies
.base_openstack_dummy
import BaseOpenstackDummy
7 LOG
= logging
.getLogger("api.openstack.keystone")
10 class KeystoneDummyApi(BaseOpenstackDummy
):
11 def __init__(self
, in_ip
, in_port
):
12 super(KeystoneDummyApi
, self
).__init
__(in_ip
, in_port
)
14 self
.api
.add_resource(KeystoneListVersions
, "/", resource_class_kwargs
={'api': self
})
15 self
.api
.add_resource(Shutdown
, "/shutdown")
16 self
.api
.add_resource(KeystoneShowAPIv2
, "/v2.0", resource_class_kwargs
={'api': self
})
17 self
.api
.add_resource(KeystoneGetToken
, "/v2.0/tokens", resource_class_kwargs
={'api': self
})
18 self
.api
.add_resource(KeystoneShowAPIv3
, "/v3", resource_class_kwargs
={'api': self
})
19 self
.api
.add_resource(KeystoneGetTokenv3
, "/v3/auth/tokens", resource_class_kwargs
={'api': self
})
21 def _start_flask(self
):
22 LOG
.info("Starting %s endpoint @ http://%s:%d" % (__name__
, self
.ip
, self
.port
))
23 if self
.app
is not None:
24 self
.app
.before_request(self
.dump_playbook
)
25 self
.app
.run(self
.ip
, self
.port
, debug
=True, use_reloader
=False)
28 class Shutdown(Resource
):
30 A get request to /shutdown will shut down this endpoint.
34 LOG
.debug(("%s is beeing shut down") % (__name__
))
35 func
= request
.environ
.get('werkzeug.server.shutdown')
37 raise RuntimeError('Not running with the Werkzeug Server')
41 class KeystoneListVersions(Resource
):
43 List all known keystone versions.
44 Hardcoded for our version!
47 def __init__(self
, api
):
54 :return: Returns the api versions.
55 :rtype: :class:`flask.response` containing a static json encoded dict.
57 LOG
.debug("API CALL: %s GET" % str(self
.__class
__.__name
__))
59 resp
['versions'] = dict()
65 "href": "http://%s:%d/v2.0" % (self
.api
.ip
, self
.api
.port
),
71 "base": "application/json",
72 "type": "application/vnd.openstack.identity-v2.0+json"
76 "updated": "2014-04-17T00:00:00Z"
78 resp
['versions']['values'] = version
80 return Response(json
.dumps(resp
), status
=200, mimetype
='application/json')
83 class KeystoneShowAPIv2(Resource
):
85 Entrypoint for all openstack clients.
86 This returns all current entrypoints running on son-emu.
89 def __init__(self
, api
):
96 :return: Returns an openstack style response for all entrypoints.
97 :rtype: :class:`flask.response`
99 LOG
.debug("API CALL: %s GET" % str(self
.__class
__.__name
__))
101 neutron_port
= self
.api
.port
+ 4696
102 heat_port
= self
.api
.port
+ 3004
109 "base": "application/json",
110 "type": "application/vnd.openstack.identity-v2.0+json"
116 "href": "http://%s:%d/v2.0" % (self
.api
.ip
, self
.api
.port
),
120 "href": "http://%s:%d/v2.0/tokens" % (self
.api
.ip
, self
.api
.port
),
124 "href": "http://%s:%d/v2.0/networks" % (self
.api
.ip
, neutron_port
),
128 "href": "http://%s:%d/v2.0/subnets" % (self
.api
.ip
, neutron_port
),
132 "href": "http://%s:%d/v2.0/ports" % (self
.api
.ip
, neutron_port
),
136 "href": "http://%s:%d/v1/<tenant_id>/stacks" % (self
.api
.ip
, heat_port
),
142 return Response(json
.dumps(resp
), status
=200, mimetype
='application/json')
145 class KeystoneShowAPIv3(Resource
):
147 Entrypoint for all openstack clients.
148 This returns all current entrypoints running on son-emu.
151 def __init__(self
, api
):
156 List API entrypoints.
158 :return: Returns an openstack style response for all entrypoints.
159 :rtype: :class:`flask.response`
161 LOG
.debug("API CALL: %s GET" % str(self
.__class
__.__name
__))
163 neutron_port
= self
.api
.port
+ 4696
164 heat_port
= self
.api
.port
+ 3004
171 "base": "application/json",
172 "type": "application/vnd.openstack.identity-v2.0+json"
178 "href": "http://%s:%d/v2.0" % (self
.api
.ip
, self
.api
.port
),
182 "href": "http://%s:%d/v2.0/tokens" % (self
.api
.ip
, self
.api
.port
),
186 "href": "http://%s:%d/v2.0/networks" % (self
.api
.ip
, neutron_port
),
190 "href": "http://%s:%d/v2.0/subnets" % (self
.api
.ip
, neutron_port
),
194 "href": "http://%s:%d/v2.0/ports" % (self
.api
.ip
, neutron_port
),
198 "href": "http://%s:%d/v1/<tenant_id>/stacks" % (self
.api
.ip
, heat_port
),
204 return Response(json
.dumps(resp
), status
=200, mimetype
='application/json')
207 class KeystoneGetToken(Resource
):
209 Returns a static keystone token.
210 We don't do any validation so we don't care.
213 def __init__(self
, api
):
218 List API entrypoints.
220 This is hardcoded. For a working "authentication" use these ENVVARS:
222 * OS_AUTH_URL=http://<ip>:<port>/v2.0
223 * OS_IDENTITY_API_VERSION=2.0
224 * OS_TENANT_ID=fc394f2ab2df4114bde39905f800dc57
225 * OS_REGION_NAME=RegionOne
229 :return: Returns an openstack style response for all entrypoints.
230 :rtype: :class:`flask.response`
233 LOG
.debug("API CALL: %s POST" % str(self
.__class
__.__name
__))
236 req
= json
.loads(request
.data
)
237 ret
['access'] = dict()
238 ret
['access']['token'] = dict()
239 token
= ret
['access']['token']
241 token
['issued_at'] = "2014-01-30T15:30:58.819Z"
242 token
['expires'] = "2999-01-30T15:30:58.819Z"
243 token
['id'] = req
['auth'].get('token', {'id': 'fc394f2ab2df4114bde39905f800dc57'}).get('id')
244 token
['tenant'] = dict()
245 token
['tenant']['description'] = None
246 token
['tenant']['enabled'] = True
247 token
['tenant']['id'] = req
['auth'].get('tenantId', 'fc394f2ab2df4114bde39905f800dc57')
248 token
['tenant']['name'] = "tenantName"
250 ret
['access']['user'] = dict()
251 user
= ret
['access']['user']
252 user
['username'] = req
.get('username', "username")
253 user
['name'] = "tenantName"
254 user
['roles_links'] = list()
255 user
['id'] = token
['tenant'].get('id', "fc394f2ab2df4114bde39905f800dc57")
256 user
['roles'] = [{'name': 'Member'}]
258 ret
['access']['region_name'] = "RegionOne"
260 ret
['access']['serviceCatalog'] = [{
263 "adminURL": "http://%s:%s/v2.1/%s" % (self
.api
.ip
, self
.api
.port
+ 3774, user
['id']),
264 "region": "RegionOne",
265 "internalURL": "http://%s:%s/v2.1/%s" % (self
.api
.ip
, self
.api
.port
+ 3774, user
['id']),
266 "id": "2dad48f09e2a447a9bf852bcd93548ef",
267 "publicURL": "http://%s:%s/v2.1/%s" % (self
.api
.ip
, self
.api
.port
+ 3774, user
['id'])
270 "endpoints_links": [],
277 "adminURL": "http://%s:%s/v2.0" % (self
.api
.ip
, self
.api
.port
),
278 "region": "RegionOne",
279 "internalURL": "http://%s:%s/v2.0" % (self
.api
.ip
, self
.api
.port
),
280 "id": "2dad48f09e2a447a9bf852bcd93543fc",
281 "publicURL": "http://%s:%s/v2" % (self
.api
.ip
, self
.api
.port
)
284 "endpoints_links": [],
291 "adminURL": "http://%s:%s" % (self
.api
.ip
, self
.api
.port
+ 4696),
292 "region": "RegionOne",
293 "internalURL": "http://%s:%s" % (self
.api
.ip
, self
.api
.port
+ 4696),
294 "id": "2dad48f09e2a447a9bf852bcd93548cf",
295 "publicURL": "http://%s:%s" % (self
.api
.ip
, self
.api
.port
+ 4696)
298 "endpoints_links": [],
305 "adminURL": "http://%s:%s" % (self
.api
.ip
, self
.api
.port
+ 4242),
306 "region": "RegionOne",
307 "internalURL": "http://%s:%s" % (self
.api
.ip
, self
.api
.port
+ 4242),
308 "id": "2dad48f09e2a447a9bf852bcd93548cf",
309 "publicURL": "http://%s:%s" % (self
.api
.ip
, self
.api
.port
+ 4242)
312 "endpoints_links": [],
319 "adminURL": "http://%s:%s/v1/%s" % (self
.api
.ip
, self
.api
.port
+ 3004, user
['id']),
320 "region": "RegionOne",
321 "internalURL": "http://%s:%s/v1/%s" % (self
.api
.ip
, self
.api
.port
+ 3004, user
['id']),
322 "id": "2dad48f09e2a447a9bf852bcd93548bf",
323 "publicURL": "http://%s:%s/v1/%s" % (self
.api
.ip
, self
.api
.port
+ 3004, user
['id'])
326 "endpoints_links": [],
327 "type": "orchestration",
332 ret
['access']["metadata"] = {
335 "7598ac3c634d4c3da4b9126a5f67ca2b"
338 ret
['access']['trust'] = {
339 "id": "394998fa61f14736b1f0c1f322882949",
340 "trustee_user_id": "269348fdd9374b8885da1418e0730af1",
341 "trustor_user_id": "3ec3164f750146be97f21559ee4d9c51",
342 "impersonation": False
344 return Response(json
.dumps(ret
), status
=200, mimetype
='application/json')
346 except Exception as ex
:
347 logging
.exception("Keystone: Get token failed.")
348 return ex
.message
, 500
350 class KeystoneGetTokenv3(Resource
):
352 Returns a static keystone token.
353 We don't do any validation so we don't care.
356 def __init__(self
, api
):
361 List API entrypoints.
363 This is hardcoded. For a working "authentication" use these ENVVARS:
365 * OS_AUTH_URL=http://<ip>:<port>/v3
366 * OS_IDENTITY_API_VERSION=2.0
367 * OS_TENANT_ID=fc394f2ab2df4114bde39905f800dc57
368 * OS_REGION_NAME=RegionOne
372 :return: Returns an openstack style response for all entrypoints.
373 :rtype: :class:`flask.response`
376 LOG
.debug("API CALL: %s POST" % str(self
.__class
__.__name
__))
379 req
= json
.loads(request
.data
)
380 ret
['token'] = dict()
383 token
['issued_at'] = "2014-01-30T15:30:58.819Z"
384 token
['expires_at'] = "2999-01-30T15:30:58.819Z"
385 token
['methods'] = ["password"]
386 token
['extras'] = dict()
387 token
['user'] = dict()
389 user
['id'] = req
['auth'].get('token', {'id': 'fc394f2ab2df4114bde39905f800dc57'}).get('id')
390 user
['name'] = "tenantName"
391 user
['password_expires_at'] = None
392 user
['domain'] = {"id": "default", "name": "Default"}
393 token
['audit_ids'] = ["ZzZwkUflQfygX7pdYDBCQQ"]
401 "id": "8538a3f13f9541b28c2620eb19065e45",
406 token
['catalog'] = [{
409 "url": "http://%s:%s/v2.1/%s" % (self
.api
.ip
, self
.api
.port
+ 3774, user
['id']),
410 "region": "RegionOne",
411 "interface": "public",
412 "id": "2dad48f09e2a447a9bf852bcd93548ef"
415 "id": "2dad48f09e2a447a9bf852bcd93548ef",
422 "url": "http://%s:%s/v2.0" % (self
.api
.ip
, self
.api
.port
),
423 "region": "RegionOne",
424 "interface": "public",
425 "id": "2dad48f09e2a447a9bf852bcd93543fc"
428 "id": "2dad48f09e2a447a9bf852bcd93543fc",
435 "url": "http://%s:%s" % (self
.api
.ip
, self
.api
.port
+ 4696),
436 "region": "RegionOne",
437 "interface": "public",
438 "id": "2dad48f09e2a447a9bf852bcd93548cf"
441 "id": "2dad48f09e2a447a9bf852bcd93548cf",
448 "url": "http://%s:%s" % (self
.api
.ip
, self
.api
.port
+ 4242),
449 "region": "RegionOne",
450 "interface": "public",
451 "id": "2dad48f09e2a447a9bf852bcd93548cf"
454 "id": "2dad48f09e2a447a9bf852bcd93548cf",
461 "url": "http://%s:%s/v1/%s" % (self
.api
.ip
, self
.api
.port
+ 3004, user
['id']),
462 "region": "RegionOne",
463 "interface": "public",
464 "id": "2dad48f09e2a447a9bf852bcd93548bf"
467 "id": "2dad48f09e2a447a9bf852bcd93548bf",
468 "type": "orchestration",
473 return Response(json
.dumps(ret
), status
=201, mimetype
='application/json')
475 except Exception as ex
:
476 logging
.exception("Keystone: Get token failed.")
477 return ex
.message
, 500