针对openstack kilo版本
几乎大部分跟用户相关的系统中都需要对用户相关的权限进行管理,当然也包括云平台系统。 比如:在Openstack中,只有具有管理员角色的用户才能管理aggregate,才能创建和更改flavor。普通租户只能查看和管理本租户内的虚拟机及相关资源等等, 这些都需要通过一套权限管理机制来实现。
社区的Openstack中对权限管理的设计比较简单,只分成admin和member两个角色。理论上具有admin角色的用户拥有所有的云平台操作权限,而member角色的用户的权限会得到限制。
Openstack Keystone的出现会让人觉得Openstack中的权限控制都会由Keystone来完成,其实不是这样,Keystone只维护了用户,租户和角色的关系,并且根据这个关系生成token和验证token,它不会做具体权限的认证。
Openstack各个组件中实现权限管理的方式类似,一般都是通过两种粒度来实现: api级别和db级别
-
api级别
这个级别通过policy.json文件来实现, 它控制着哪些api能够被哪些用户call。大部分的组件在根目录或者api目录里面都有一个policy.py, 里面会调用oslo.policy的方法,其中对policy.json文件中语法判断都封装在oslo.policy模块中。
比如: nova中对policy的实现:
https://github.com/openstack/nova/blob/kilo-eol/nova/api/openstack/extensions.py#L338-L354
extension中提供一个共有方法来判断权限
https://github.com/openstack/nova/blob/kilo-eol/nova/api/openstack/compute/contrib/admin_actions.py#L39-L41
admin action中定义个admin action相关的方法,里面会定义相应的key
https://github.com/openstack/nova/blob/kilo-eol/nova/api/openstack/compute/contrib/admin_actions.py#L52-L55
pause方法中调用authorize(ctxt, 'pause') 来判断权限, 这条和policy.json的下面这一行对应
https://github.com/openstack/nova/blob/kilo-eol/etc/nova/policy.json#L33
这条表示只有admin角色的用户或者和该虚拟机所属租户下的用户才能暂停虚拟机。所有其他租户的普通用户的暂停请求将会被拒绝。
-
db级别
Openstack的db对权限的控制体现在context上。一般情况下,Openstack的各个组件都会维护一个context对象(RequestContext),这个对象的生命周期一般会跟随一个api请求的开始到结束, context中保持着一些请求的基本信息如: token,userid,projectid,is_admin等等。
在nova中,context通过api-paste.ini 注册进来,
https://github.com/openstack/nova/blob/kilo-eol/etc/nova/api-paste.ini#L72
里面的keystonecontext负责生成context对象。其中context又简单分成admincontext和usercontext,分别对应admin和member 两个role。 其中有些db的操作需要admin权限,所以会加上标签@requireadmincontext, 比如列出所有的计算节点:
https://github.com/openstack/nova/blob/kilo-eol/nova/db/sqlalchemy/api.py#L615-L617
而有些db的操作会根据usercontext来加上对应的过滤条件,比如sqlalchemy/api.py里面有个model_query方法
https://github.com/openstack/nova/blob/kilo-eol/nova/db/sqlalchemy/api.py#L330-L334