[openstack-dev] [Ceilometer] Way to get wrapped method's name/class using Pecan secure decorators?

Pendergrass, Eric eric.pendergrass at hp.com
Wed Aug 20 19:43:45 UTC 2014


Hi Ryan,

We tried globally applying the hook but could not get execution to enter the
hook class. 

Perhaps we made a mistake, but we concluded the Controller still had to
inherit from HookController using the project-wide method.  Otherwise we
would have been satisfied applying it project-wide.

Thanks,
Eric

> Eric,

> 
> Doug's correct - this looks like a bug in pecan that occurs when you
subclass both rest.RestController and hooks.HookController.  I'm working on
a bug fix as we speak.  In the meantime, have you tried applying hooks at a
global application level?  This approach should still work.
> 
> On 08/14/14 04:38 PM, Pendergrass, Eric wrote:
> > Sure, Doug.  We want the ability to selectively apply policies to 
> > certain Ceilometer API methods based on user/tenant roles.
> > 
> > For example, we want to restrict the ability to execute Alarm deletes 
> > to admins and user/tenants who have a special role, say "domainadmin".
> > 
> > The policy file might look like this:
> > {
> >     "context_is_admin":  [["role:admin"]],
> >     "admin_and_matching_project_domain_id":  [["role:domainadmin"]],
> >     "admin_or_cloud_admin": [["rule:context_is_admin"], 
> > ["rule:admin_and_matching_project_domain_id"]],
> >     "telemetry:delete_alarms":  [["rule:admin_or_cloud_admin"]] }
> > 
> > The current acl.py and _query_to_kwargs access control setup either 
> > sets project_id scope to None (do everything) or to the project_id in 
> > the request header 'X-Project-Id'.  This allows for admin or project 
> > scope, but nothing in between.
> > 
> > We tried hooks.  Unfortunately we can't seem to turn the API 
> > controllers into HookControllers just by adding HookController to the 
> > Controller class definition.  It causes infinite recursion on API 
> > startup.  For example, this doesn't work because ceilometer-api will 
> > not start with it:
> >     class MetersController(rest.RestController, HookController):
> > 
> > If there was a way to use hooks with the v2. API controllers that 
> > might work really well.
> > 
> > So we are left using the @secure decorator and deriving the method 
> > name from the request environ PATH_INFO and REQUEST_METHOD values.  
> > This is how we determine the wrapped method within the class 
> > (REQUEST_METHOD + PATH_INFO = "telemetry:delete_alarms" with some 
> > munging).  We need the method name in order to selectively apply acces 
> > control to certain methods.
> > 
> > Deriving the method this way isn't ideal but it's the only thing we've 
> > gotten working between hooks, @secure, and regular decorators.
> > 
> > I submitted a WIP BP here: https://review.openstack.org/#/c/112137/3.  
> > It is slightly out of date but should give you a beter idea of our
goals.
> > 
> > Thanks
> > 
> > > Eric,
> > >
> > > If you can give us some more information about your end goal, 
> > > independent
> > of the implementation, maybe we can propose an alternate technique to 
> > achieve the same thing.
> > >
> > > Doug
> > >
> > > On Aug 12, 2014, at 6:21 PM, Ryan Petrello 
> > > <ryan.petrello at dreamhost.com>
> > wrote:
> > >
> > > > Yep, you're right, this doesn't seem to work.  The issue is that 
> > > > security is enforced at routing time (while the controller is 
> > > > still actually being discovered).  In order to do this sort of 
> > > > thing with the `check_permissions`, we'd probably need to add a
feature to pecan.
> > > >
> > > > On 08/12/14 06:38 PM, Pendergrass, Eric wrote:
> > > > > Sure, here's the decorated method from v2.py:
> > > > >
> > > > >    class MetersController(rest.RestController):
> > > > >        """Works on meters."""
> > > > >
> > > > >        @pecan.expose()
> > > > >        def _lookup(self, meter_name, *remainder):
> > > > >            return MeterController(meter_name), remainder
> > > > >
> > > > >        @wsme_pecan.wsexpose([Meter], [Query])
> > > > >        @secure(RBACController.check_permissions)
> > > > >        def get_all(self, q=None):
> > > > >
> > > > > and here's the decorator called by the secure tag:
> > > > >
> > > > >    class RBACController(object):
> > > > >        global _ENFORCER
> > > > >        if not _ENFORCER:
> > > > >            _ENFORCER = policy.Enforcer()
> > > > >
> > > > >
> > > > >        @classmethod
> > > > >        def check_permissions(cls):
> > > > >            # do some stuff
> > > > >
> > > > > In check_permissions I'd like to know the class and method with 
> > > > > the
> > @secure tag that caused check_permissions to be invoked.  In this 
> > case, that would be MetersController.get_all.
> > > > >
> > > > > Thanks
> > > > >
> > > > >
> > > > > > Can you share some code?  What do you mean by, "is there a way 
> > > > > > for the
> > decorator code to know it was called by MetersController.get_all"
> > > > > >
> > > > > > On 08/12/14 04:46 PM, Pendergrass, Eric wrote:
> > > > > > > Thanks Ryan, but for some reason the controller attribute is
None:
> > > > > > >
> > > > > > > (Pdb) from pecan.core import state
> > > > > > > (Pdb) state.__dict__
> > > > > > > {'hooks': [<ceilometer.api.hooks.ConfigHook object at 
> > > > > > > 0x31894d0>, <ceilometer.api.hooks.DBHook object at 0x3189650>,

> > > > > > > <ceilometer.api.hooks.PipelineHook object at 0x39871d0>, 
> > > > > > > <ceilometer.api.hooks.TranslationHook object at 0x3aa5510>],
'app':
> > > > > > > <pecan.core.Pecan object at 0x2e76390>, 'request': <Request at
> > > > > > > 0x3ed7390 GET http://localhost:8777/v2/meters>, 'controller': 
> > > > > > > None,
> > > > > > > 'response': <Response at 0x3ed74d0 200 OK>}
> > > > > > >
> > > > > > > > -----Original Message-----
> > > > > > > > From: Ryan Petrello [mailto:ryan.petrello at dreamhost.com]
> > > > > > > > Sent: Tuesday, August 12, 2014 10:34 AM
> > > > > > > > To: OpenStack Development Mailing List (not for usage 
> > > > > > > > questions)
> > > > > > > > Subject: Re: [openstack-dev] [Ceilometer] Way to get wrapped
> > method's name/class using Pecan secure decorators?
> > > > > > > >
> > > > > > > > This should give you what you need:
> > > > > > > >
> > > > > > > > from pecan.core import state
> > > > > > > > state.controller
> > > > > > > >
> > > > > > > > On 08/12/14 04:08 PM, Pendergrass, Eric wrote:
> > > > > > > > > Hi, I'm trying to use the built in secure decorator in
Pecan 
> > > > > > > > > for
> > access control, and I'ld like to get the name of the method that is 
> > wrapped from within the decorator.
> > > > > > > > >
> > > > > > > > > For instance, if I'm wrapping MetersController.get_all
with 
> > > > > > > > > an
> > @secure decorator, is there a way for the decorator code to know it 
> > was called by MetersController.get_all?
> > > > > > > > >
> > > > > > > > > I don't see any global objects that provide this
information.  
> > > > > > > > > I
> > can get the endpoint, v2/meters, with pecan.request.path, but that's 
> > not as elegant.
> > > > > > > > >
> > > > > > > > > Is there a way to derive the caller or otherwise pass this
> > information to the decorator?
> > > > > > > > >
> > > > > > > > > Thanks
> > > > > > > > > Eric Pendergrass
> > > > > > > >
> > > > > > > > > _______________________________________________
> > > > > > > > > OpenStack-dev mailing list
> > > > > > > > > OpenStack-dev at lists.openstack.org 
> > > > > > > > >
http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack
> > > > > > > > > -dev
> > > > > > > >
> > > > > > > >
> > > > > > > > --
> > > > > > > > Ryan Petrello
> > > > > > > > Senior Developer, DreamHost
> > > > > > > > ryan.petrello at dreamhost.com
> > > > >
> > > > > _______________________________________________
> > > > > OpenStack-dev mailing list
> > > > > OpenStack-dev at lists.openstack.org 
> > > > > http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
> > > >
> > > > --
> > > > Ryan Petrello
> > > > Senior Developer, DreamHost
> > > > ryan.petrello at dreamhost.com
> > > >
> > > > _______________________________________________
> > > > OpenStack-dev mailing list
> > > > OpenStack-dev at lists.openstack.org
> > > > http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
> > >
> > >
> > > _______________________________________________
> > > OpenStack-dev mailing list
> > > OpenStack-dev at lists.openstack.org
> > > http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
>
>
>
> > _______________________________________________
> > OpenStack-dev mailing list
> > OpenStack-dev at lists.openstack.org
> > http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
>
>
>--
>Ryan Petrello
>Senior Developer, DreamHost
>ryan.petrello at dreamhost.com
>
>_______________________________________________
>OpenStack-dev mailing list
>OpenStack-dev at lists.openstack.org
>http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 6242 bytes
Desc: not available
URL: <http://lists.openstack.org/pipermail/openstack-dev/attachments/20140820/5de908e2/attachment-0001.bin>


More information about the OpenStack-dev mailing list