Re: [openstack-dev] [Ceilometer] Question on decorators in Ceilometer pecan framework

2014-08-08 Thread Doug Hellmann

On Aug 8, 2014, at 8:49 AM, Pendergrass, Eric  wrote:

> Hi,
>  
> We have been struggling to get a decorator working for proposed new RBAC 
> functionality in ceilometer-api.  We’re hitting a problem where GET request 
> query parameters are mucked up by our decorator.  Here’s an example call:
>  
> curl -H "X-Auth-Token:$TOKEN" 
> 'http://localhost:8777/v2/meters?q.field=project_id&q.value=8c678720fb5b4e3bb18dee222d7d7933'
>  
> And here’s the decorator method (we’ve tried changing the kwargs, args, etc. 
> with no luck):
>  
> _ENFORCER = None
>  
> def protected(controller_class):
>  
> global _ENFORCER
> if not _ENFORCER:
> _ENFORCER = policy.Enforcer()
>  
> def wrapper(f):
> @functools.wraps(f)
> def inner(self, **kwargs):
> pdb.set_trace()
> self._rbac_context = {}

You need to be careful saving request state on the controller. The controller 
may be shared by multiple requests (I see below that you’re creating a 
MeterController for each incoming request, but that won’t be the case for all 
controller types). It’s better to store the value in the pecan.request, which 
is a thread-safe request-specific object.

If you just need to store some values, and not test ACLs it in the decorator, 
you could use a Pecan hook [1] like we do with the configuration settings [2].

Doug

1 - http://pecan.readthedocs.org/en/latest/hooks.html
2 - 
http://git.openstack.org/cgit/openstack/ceilometer/tree/ceilometer/api/hooks.py#n27

> if not _ENFORCER.enforce('context_is_admin',
>  {},
>  {'roles': 
> pecan.request.headers.get('X-Roles', "").split(",")}):
> self._rbac_context['project_id'] = 
> pecan.request.headers.get('X-Project-Id')
> self._rbac_context['user_id'] = 
> pecan.request.headers.get('X-User-Id')
> return f(self, **kwargs)
> return inner
> return wrapper
>  
> tried this too:
>  
> _ENFORCER = None
>  
> def protected(*args):
>  
> controller_class = 'meter'
> global _ENFORCER
> if not _ENFORCER:
> _ENFORCER = policy.Enforcer()
>  
> def wrapper(f, *args):
> def inner(self, *args):
> pdb.set_trace()
> #self._rbac_context = {}
> #if not _ENFORCER.enforce('context_is_admin',
> # {},
> # {'roles': 
> pecan.request.headers.get('X-Roles', "").split(",")}):
> #self._rbac_context['project_id'] = 
> pecan.request.headers.get('X-Project-Id')
> #self._rbac_context['user_id'] = 
> pecan.request.headers.get('X-User-Id')
> #return f(*args)
> f(self, *args)
> return inner
> return wrapper
>  
> and here’s how it’s used:
>  
> class MetersController(rest.RestController):
> """Works on meters."""
>  
> _rbac_context = {}
> @pecan.expose()
> def _lookup(self, meter_name, *remainder):
> return MeterController(meter_name), remainder
>  
> @wsme_pecan.wsexpose([Meter], [Query])
> @rbac_validate.protected('meters')
> def get_all(self, q=None):
> """Return all known meters, based on the data recorded so far.
>  
> :param q: Filter rules for the meters to be returned.
> """
> q = q or [] …
>  
>  
> but we get errors similar to below where the arg parser cannot find the query 
> parameter because the decorator doesn’t take a q argument as 
> MetersController.get_all does. 
>  
> Is there any way to get a decorator to work within the v2 API code and wsme 
> framework or should we consider another approach?  Decorators would really 
> simplify the RBAC idea we’re working on, which is mostly code-implemented 
> save for this fairly major problem.
>  
> I have a WIP registered BP on this at 
> https://blueprints.launchpad.net/ceilometer/+spec/ready-ceilometer-rbac-keystone-v3.
>  
> If I can provide more details I’ll be happy to.
>  
> Thanks
> Eric
>  
>   /usr/local/bin/ceilometer-api(10)()
> -> sys.exit(api())
>   /opt/stack/ceilometer/ceilometer/cli.py(96)api()
> -> srv.serve_forever()
>   /usr/lib/python2.7/SocketServer.py(227)serve_forever()
> -> self._handle_request_noblock()
>   /usr/lib/python2.7/SocketServer.py(284)_handle_request_noblock()
> -> self.process_request(request, client_address)
>   /usr/lib/python2.7/SocketServer.py(310)process_request()
> -> self.finish_request(request, client_address)
>   /usr/lib/python2.7/SocketServer.py(323)finish_request()
> -> self.RequestHandlerClass(request, client_address, self)
>   /usr/lib/python2.7/SocketServer.py(638)__init__()
> -> self.handle()
>   /usr/lib/python2.7/wsgiref/simple_server.py(124)handle()
> -> handler.run(self.server.get_app())
>   /usr/lib/python2.7/wsgiref/handlers.py(85)run()
> -> self.result = application(self.environ, self.start_response)
>   
> /opt/stack/python-keystoneclient/keystone

Re: [openstack-dev] [Ceilometer] Question on decorators in Ceilometer pecan framework

2014-08-08 Thread Pendergrass, Eric
> From: David Stanek [mailto:dsta...@dstanek.com]
> Sent: Friday, August 08, 2014 7:25 AM
> To: OpenStack Development Mailing List (not for usage questions)
> Subject: Re: [openstack-dev] [Ceilometer] Question on decorators in
> Ceilometer pecan framework

> It looks like maybe WSME or Pecan is inspecting the method signature. Have
you
> tried to change the order of the decorators?

Good suggestion and we did try it.  Unfortunately the wsme decorator must
come
first else the endpoint isn't found and the client gets a 404.

Eric


smime.p7s
Description: S/MIME cryptographic signature
___
OpenStack-dev mailing list
OpenStack-dev@lists.openstack.org
http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev


Re: [openstack-dev] [Ceilometer] Question on decorators in Ceilometer pecan framework

2014-08-08 Thread David Stanek
It looks like maybe WSME or Pecan is inspecting the method signature. Have you 
tried to change the order of the decorators?


On Aug 8, 2014, at 9:16, Pendergrass, Eric  wrote:

> Wrong link again, this is embarrassing L 
> https://review.openstack.org/#/c/112137/3
>  
> From: Pendergrass, Eric 
> Sent: Friday, August 08, 2014 7:15 AM
> To: openstack-dev@lists.openstack.org
> Subject: RE: [Ceilometer] Question on decorators in Ceilometer pecan framework
>  
> Sorry, wrong BP review link below.  Here is the correct one: 
> https://review.openstack.org/#/c/112127/3.  Please disregard the wiki link.
>  
> From: Pendergrass, Eric 
> Sent: Friday, August 08, 2014 6:50 AM
> To: openstack-dev@lists.openstack.org
> Cc: Giannetti, Fabio
> Subject: [Ceilometer] Question on decorators in Ceilometer pecan framework
>  
> Hi,
>  
> We have been struggling to get a decorator working for proposed new RBAC 
> functionality in ceilometer-api.  We’re hitting a problem where GET request 
> query parameters are mucked up by our decorator.  Here’s an example call:
>  
> curl -H "X-Auth-Token:$TOKEN" 
> 'http://localhost:8777/v2/meters?q.field=project_id&q.value=8c678720fb5b4e3bb18dee222d7d7933'
>  
> And here’s the decorator method (we’ve tried changing the kwargs, args, etc. 
> with no luck):
>  
> _ENFORCER = None
>  
> def protected(controller_class):
>  
> global _ENFORCER
> if not _ENFORCER:
> _ENFORCER = policy.Enforcer()
>  
> def wrapper(f):
> @functools.wraps(f)
> def inner(self, **kwargs):
> pdb.set_trace()
> self._rbac_context = {}
> if not _ENFORCER.enforce('context_is_admin',
>  {},
>  {'roles': 
> pecan.request.headers.get('X-Roles', "").split(",")}):
> self._rbac_context['project_id'] = 
> pecan.request.headers.get('X-Project-Id')
> self._rbac_context['user_id'] = 
> pecan.request.headers.get('X-User-Id')
> return f(self, **kwargs)
> return inner
> return wrapper
>  
> tried this too:
>  
> _ENFORCER = None
>  
> def protected(*args):
>  
> controller_class = 'meter'
> global _ENFORCER
> if not _ENFORCER:
> _ENFORCER = policy.Enforcer()
>  
> def wrapper(f, *args):
> def inner(self, *args):
> pdb.set_trace()
> #self._rbac_context = {}
> #if not _ENFORCER.enforce('context_is_admin',
> # {},
> # {'roles': 
> pecan.request.headers.get('X-Roles', "").split(",")}):
> #self._rbac_context['project_id'] = 
> pecan.request.headers.get('X-Project-Id')
> #self._rbac_context['user_id'] = 
> pecan.request.headers.get('X-User-Id')
> #return f(*args)
> f(self, *args)
> return inner
> return wrapper
>  
> and here’s how it’s used:
>  
> class MetersController(rest.RestController):
> """Works on meters."""
>  
> _rbac_context = {}
> @pecan.expose()
> def _lookup(self, meter_name, *remainder):
> return MeterController(meter_name), remainder
>  
> @wsme_pecan.wsexpose([Meter], [Query])
> @rbac_validate.protected('meters')
> def get_all(self, q=None):
> """Return all known meters, based on the data recorded so far.
>  
> :param q: Filter rules for the meters to be returned.
> """
> q = q or [] …
>  
>  
> but we get errors similar to below where the arg parser cannot find the query 
> parameter because the decorator doesn’t take a q argument as 
> MetersController.get_all does. 
>  
> Is there any way to get a decorator to work within the v2 API code and wsme 
> framework or should we consider another approach?  Decorators would really 
> simplify the RBAC idea we’re working on, which is mostly code-implemented 
> save for this fairly major problem.
>  
> I have a WIP registered BP on this 
> athttps://blueprints.launchpad.net/ceilometer/+spec/ready-ceilometer-rbac-keystone-v3.
>  
> If I can provide more details I’ll be happy to.
>  
> Thanks
> Eric
>  
>   /usr/local/bin/ceilometer-api(10)()
> -> sys.exit(api())
>   /opt/stack/ceilometer/ceilometer/cli.py(96)api()
> -> srv.serve_forever()
>   /usr/lib/python2.7/SocketServer.py(227)serve_forever()
> -> self._handle_request_noblock()
>   /usr/lib/python2.7/SocketServer.py(284)_handle_request_noblock()
> -> self.process_request(request, client_address)
>   /usr/lib/python2.7/SocketServer.py(310)process_request()
> -> self.finish_request(request, client_address)
>   /usr/lib/python2.7/SocketServer.py(323)finish_request()
> -> self.RequestHandlerClass(request, client_address, self)
>   /usr/lib/python2.7/SocketServer.py(638)__init__()
> -> self.handle()
>   /usr/lib/python2.7/wsgiref/simple_server.py(124)handle()
> -> handler.run(self.server.get_app())
>   /usr/lib/python2.7/wsgiref/handlers.py(85)run()
> -> self.res

Re: [openstack-dev] [Ceilometer] Question on decorators in Ceilometer pecan framework

2014-08-08 Thread Pendergrass, Eric
Wrong link again, this is embarrassing :( 
https://review.openstack.org/#/c/112137/3

From: Pendergrass, Eric
Sent: Friday, August 08, 2014 7:15 AM
To: openstack-dev@lists.openstack.org
Subject: RE: [Ceilometer] Question on decorators in Ceilometer pecan framework

Sorry, wrong BP review link below.  Here is the correct one:  
https://review.openstack.org/#/c/112127/3.  Please disregard the wiki link.

From: Pendergrass, Eric
Sent: Friday, August 08, 2014 6:50 AM
To: openstack-dev@lists.openstack.org
Cc: Giannetti, Fabio
Subject: [Ceilometer] Question on decorators in Ceilometer pecan framework

Hi,

We have been struggling to get a decorator working for proposed new RBAC 
functionality in ceilometer-api.  We're hitting a problem where GET request 
query parameters are mucked up by our decorator.  Here's an example call:

curl -H "X-Auth-Token:$TOKEN" 
'http://localhost:8777/v2/meters?q.field=project_id&q.value=8c678720fb5b4e3bb18dee222d7d7933'

And here's the decorator method (we've tried changing the kwargs, args, etc. 
with no luck):

_ENFORCER = None

def protected(controller_class):

global _ENFORCER
if not _ENFORCER:
_ENFORCER = policy.Enforcer()

def wrapper(f):
@functools.wraps(f)
def inner(self, **kwargs):
pdb.set_trace()
self._rbac_context = {}
if not _ENFORCER.enforce('context_is_admin',
 {},
 {'roles': 
pecan.request.headers.get('X-Roles', "").split(",")}):
self._rbac_context['project_id'] = 
pecan.request.headers.get('X-Project-Id')
self._rbac_context['user_id'] = 
pecan.request.headers.get('X-User-Id')
return f(self, **kwargs)
return inner
return wrapper

tried this too:

_ENFORCER = None

def protected(*args):

controller_class = 'meter'
global _ENFORCER
if not _ENFORCER:
_ENFORCER = policy.Enforcer()

def wrapper(f, *args):
def inner(self, *args):
pdb.set_trace()
#self._rbac_context = {}
#if not _ENFORCER.enforce('context_is_admin',
# {},
# {'roles': 
pecan.request.headers.get('X-Roles', "").split(",")}):
#self._rbac_context['project_id'] = 
pecan.request.headers.get('X-Project-Id')
#self._rbac_context['user_id'] = 
pecan.request.headers.get('X-User-Id')
#return f(*args)
f(self, *args)
return inner
return wrapper

and here's how it's used:

class MetersController(rest.RestController):
"""Works on meters."""

_rbac_context = {}
@pecan.expose()
def _lookup(self, meter_name, *remainder):
return MeterController(meter_name), remainder

@wsme_pecan.wsexpose([Meter], [Query])
@rbac_validate.protected('meters')
def get_all(self, q=None):
"""Return all known meters, based on the data recorded so far.

:param q: Filter rules for the meters to be returned.
"""
q = q or [] ...


but we get errors similar to below where the arg parser cannot find the query 
parameter because the decorator doesn't take a q argument as 
MetersController.get_all does.

Is there any way to get a decorator to work within the v2 API code and wsme 
framework or should we consider another approach?  Decorators would really 
simplify the RBAC idea we're working on, which is mostly code-implemented save 
for this fairly major problem.

I have a WIP registered BP on this at 
https://blueprints.launchpad.net/ceilometer/+spec/ready-ceilometer-rbac-keystone-v3.

If I can provide more details I'll be happy to.

Thanks
Eric

  /usr/local/bin/ceilometer-api(10)()
-> sys.exit(api())
  /opt/stack/ceilometer/ceilometer/cli.py(96)api()
-> srv.serve_forever()
  /usr/lib/python2.7/SocketServer.py(227)serve_forever()
-> self._handle_request_noblock()
  /usr/lib/python2.7/SocketServer.py(284)_handle_request_noblock()
-> self.process_request(request, client_address)
  /usr/lib/python2.7/SocketServer.py(310)process_request()
-> self.finish_request(request, client_address)
  /usr/lib/python2.7/SocketServer.py(323)finish_request()
-> self.RequestHandlerClass(request, client_address, self)
  /usr/lib/python2.7/SocketServer.py(638)__init__()
-> self.handle()
  /usr/lib/python2.7/wsgiref/simple_server.py(124)handle()
-> handler.run(self.server.get_app())
  /usr/lib/python2.7/wsgiref/handlers.py(85)run()
-> self.result = application(self.environ, self.start_response)
  
/opt/stack/python-keystoneclient/keystoneclient/middleware/auth_token.py(663)__call__()
-> return self.app(env, start_response)
  /opt/stack/ceilometer/ceilometer/api/app.py(97)__call__()
-> return self.v2(environ, start_response)
  
/usr/local/lib/python2.7/dist-packages/pecan/middleware/static.py(151)__call__()
-> return self.app(environ, start_response)
  
/usr/local/lib/pyth

Re: [openstack-dev] [Ceilometer] Question on decorators in Ceilometer pecan framework

2014-08-08 Thread Pendergrass, Eric
Sorry, wrong BP review link below.  Here is the correct one:  
https://review.openstack.org/#/c/112127/3.  Please disregard the wiki link.

From: Pendergrass, Eric
Sent: Friday, August 08, 2014 6:50 AM
To: openstack-dev@lists.openstack.org
Cc: Giannetti, Fabio
Subject: [Ceilometer] Question on decorators in Ceilometer pecan framework

Hi,

We have been struggling to get a decorator working for proposed new RBAC 
functionality in ceilometer-api.  We're hitting a problem where GET request 
query parameters are mucked up by our decorator.  Here's an example call:

curl -H "X-Auth-Token:$TOKEN" 
'http://localhost:8777/v2/meters?q.field=project_id&q.value=8c678720fb5b4e3bb18dee222d7d7933'

And here's the decorator method (we've tried changing the kwargs, args, etc. 
with no luck):

_ENFORCER = None

def protected(controller_class):

global _ENFORCER
if not _ENFORCER:
_ENFORCER = policy.Enforcer()

def wrapper(f):
@functools.wraps(f)
def inner(self, **kwargs):
pdb.set_trace()
self._rbac_context = {}
if not _ENFORCER.enforce('context_is_admin',
 {},
 {'roles': 
pecan.request.headers.get('X-Roles', "").split(",")}):
self._rbac_context['project_id'] = 
pecan.request.headers.get('X-Project-Id')
self._rbac_context['user_id'] = 
pecan.request.headers.get('X-User-Id')
return f(self, **kwargs)
return inner
return wrapper

tried this too:

_ENFORCER = None

def protected(*args):

controller_class = 'meter'
global _ENFORCER
if not _ENFORCER:
_ENFORCER = policy.Enforcer()

def wrapper(f, *args):
def inner(self, *args):
pdb.set_trace()
#self._rbac_context = {}
#if not _ENFORCER.enforce('context_is_admin',
# {},
# {'roles': 
pecan.request.headers.get('X-Roles', "").split(",")}):
#self._rbac_context['project_id'] = 
pecan.request.headers.get('X-Project-Id')
#self._rbac_context['user_id'] = 
pecan.request.headers.get('X-User-Id')
#return f(*args)
f(self, *args)
return inner
return wrapper

and here's how it's used:

class MetersController(rest.RestController):
"""Works on meters."""

_rbac_context = {}
@pecan.expose()
def _lookup(self, meter_name, *remainder):
return MeterController(meter_name), remainder

@wsme_pecan.wsexpose([Meter], [Query])
@rbac_validate.protected('meters')
def get_all(self, q=None):
"""Return all known meters, based on the data recorded so far.

:param q: Filter rules for the meters to be returned.
"""
q = q or [] ...


but we get errors similar to below where the arg parser cannot find the query 
parameter because the decorator doesn't take a q argument as 
MetersController.get_all does.

Is there any way to get a decorator to work within the v2 API code and wsme 
framework or should we consider another approach?  Decorators would really 
simplify the RBAC idea we're working on, which is mostly code-implemented save 
for this fairly major problem.

I have a WIP registered BP on this at 
https://blueprints.launchpad.net/ceilometer/+spec/ready-ceilometer-rbac-keystone-v3.

If I can provide more details I'll be happy to.

Thanks
Eric

  /usr/local/bin/ceilometer-api(10)()
-> sys.exit(api())
  /opt/stack/ceilometer/ceilometer/cli.py(96)api()
-> srv.serve_forever()
  /usr/lib/python2.7/SocketServer.py(227)serve_forever()
-> self._handle_request_noblock()
  /usr/lib/python2.7/SocketServer.py(284)_handle_request_noblock()
-> self.process_request(request, client_address)
  /usr/lib/python2.7/SocketServer.py(310)process_request()
-> self.finish_request(request, client_address)
  /usr/lib/python2.7/SocketServer.py(323)finish_request()
-> self.RequestHandlerClass(request, client_address, self)
  /usr/lib/python2.7/SocketServer.py(638)__init__()
-> self.handle()
  /usr/lib/python2.7/wsgiref/simple_server.py(124)handle()
-> handler.run(self.server.get_app())
  /usr/lib/python2.7/wsgiref/handlers.py(85)run()
-> self.result = application(self.environ, self.start_response)
  
/opt/stack/python-keystoneclient/keystoneclient/middleware/auth_token.py(663)__call__()
-> return self.app(env, start_response)
  /opt/stack/ceilometer/ceilometer/api/app.py(97)__call__()
-> return self.v2(environ, start_response)
  
/usr/local/lib/python2.7/dist-packages/pecan/middleware/static.py(151)__call__()
-> return self.app(environ, start_response)
  
/usr/local/lib/python2.7/dist-packages/pecan/middleware/debug.py(289)__call__()
-> return self.app(environ, start_response)
  
/usr/local/lib/python2.7/dist-packages/pecan/middleware/recursive.py(56)__call__()
-> return self.application(environ, start_response)
  /opt/stack/ceilometer/ceilometer/api/middleware.py(83)__call__(

[openstack-dev] [Ceilometer] Question on decorators in Ceilometer pecan framework

2014-08-08 Thread Pendergrass, Eric
Hi,

We have been struggling to get a decorator working for proposed new RBAC 
functionality in ceilometer-api.  We're hitting a problem where GET request 
query parameters are mucked up by our decorator.  Here's an example call:

curl -H "X-Auth-Token:$TOKEN" 
'http://localhost:8777/v2/meters?q.field=project_id&q.value=8c678720fb5b4e3bb18dee222d7d7933'

And here's the decorator method (we've tried changing the kwargs, args, etc. 
with no luck):

_ENFORCER = None

def protected(controller_class):

global _ENFORCER
if not _ENFORCER:
_ENFORCER = policy.Enforcer()

def wrapper(f):
@functools.wraps(f)
def inner(self, **kwargs):
pdb.set_trace()
self._rbac_context = {}
if not _ENFORCER.enforce('context_is_admin',
 {},
 {'roles': 
pecan.request.headers.get('X-Roles', "").split(",")}):
self._rbac_context['project_id'] = 
pecan.request.headers.get('X-Project-Id')
self._rbac_context['user_id'] = 
pecan.request.headers.get('X-User-Id')
return f(self, **kwargs)
return inner
return wrapper

tried this too:

_ENFORCER = None

def protected(*args):

controller_class = 'meter'
global _ENFORCER
if not _ENFORCER:
_ENFORCER = policy.Enforcer()

def wrapper(f, *args):
def inner(self, *args):
pdb.set_trace()
#self._rbac_context = {}
#if not _ENFORCER.enforce('context_is_admin',
# {},
# {'roles': 
pecan.request.headers.get('X-Roles', "").split(",")}):
#self._rbac_context['project_id'] = 
pecan.request.headers.get('X-Project-Id')
#self._rbac_context['user_id'] = 
pecan.request.headers.get('X-User-Id')
#return f(*args)
f(self, *args)
return inner
return wrapper

and here's how it's used:

class MetersController(rest.RestController):
"""Works on meters."""

_rbac_context = {}
@pecan.expose()
def _lookup(self, meter_name, *remainder):
return MeterController(meter_name), remainder

@wsme_pecan.wsexpose([Meter], [Query])
@rbac_validate.protected('meters')
def get_all(self, q=None):
"""Return all known meters, based on the data recorded so far.

:param q: Filter rules for the meters to be returned.
"""
q = q or [] ...


but we get errors similar to below where the arg parser cannot find the query 
parameter because the decorator doesn't take a q argument as 
MetersController.get_all does.

Is there any way to get a decorator to work within the v2 API code and wsme 
framework or should we consider another approach?  Decorators would really 
simplify the RBAC idea we're working on, which is mostly code-implemented save 
for this fairly major problem.

I have a WIP registered BP on this at 
https://blueprints.launchpad.net/ceilometer/+spec/ready-ceilometer-rbac-keystone-v3.

If I can provide more details I'll be happy to.

Thanks
Eric

  /usr/local/bin/ceilometer-api(10)()
-> sys.exit(api())
  /opt/stack/ceilometer/ceilometer/cli.py(96)api()
-> srv.serve_forever()
  /usr/lib/python2.7/SocketServer.py(227)serve_forever()
-> self._handle_request_noblock()
  /usr/lib/python2.7/SocketServer.py(284)_handle_request_noblock()
-> self.process_request(request, client_address)
  /usr/lib/python2.7/SocketServer.py(310)process_request()
-> self.finish_request(request, client_address)
  /usr/lib/python2.7/SocketServer.py(323)finish_request()
-> self.RequestHandlerClass(request, client_address, self)
  /usr/lib/python2.7/SocketServer.py(638)__init__()
-> self.handle()
  /usr/lib/python2.7/wsgiref/simple_server.py(124)handle()
-> handler.run(self.server.get_app())
  /usr/lib/python2.7/wsgiref/handlers.py(85)run()
-> self.result = application(self.environ, self.start_response)
  
/opt/stack/python-keystoneclient/keystoneclient/middleware/auth_token.py(663)__call__()
-> return self.app(env, start_response)
  /opt/stack/ceilometer/ceilometer/api/app.py(97)__call__()
-> return self.v2(environ, start_response)
  
/usr/local/lib/python2.7/dist-packages/pecan/middleware/static.py(151)__call__()
-> return self.app(environ, start_response)
  
/usr/local/lib/python2.7/dist-packages/pecan/middleware/debug.py(289)__call__()
-> return self.app(environ, start_response)
  
/usr/local/lib/python2.7/dist-packages/pecan/middleware/recursive.py(56)__call__()
-> return self.application(environ, start_response)
  /opt/stack/ceilometer/ceilometer/api/middleware.py(83)__call__()
-> app_iter = self.app(environ, replacement_start_response)
  /usr/local/lib/python2.7/dist-packages/pecan/core.py(750)__call__()
-> return super(Pecan, self).__call__(environ, start_response)
  /usr/local/lib/python2.7/dist-packages/pecan/core.py(616)__call__()
-> self.invoke_controller(controller, args, kwargs, state)
  /usr/local/