由于用户需要操作kubernetes,所以权限分类起码需要2套,即平台的权限和集群的权限管理,前者用于管理平台,如用户的添加,报表的查看,日志的审计等等,后者用于集群管理,需要和kubernetes的rbac进行关联.
平台的权限管理使用的方法比较多,如基于url进行授权,基于Priority进行属性授权等等,方法很多,由于该平台对于基本权限的需求并不复杂,所以使用基本的RBAC的逻辑进行权限划分,即基于资源和角色进行权限划分。
每个用户绑定多个 role, 每个role是 多个资源+动作的集合,如url是xxx.com/platform/cluster/update, 其中cluster就是资源,update就是动作,基于这种组合方式,实现平台的权限划分。
众所周知,kubernetes的RBAC权限很经典,但同时也挺复杂,传统的dashboard做法是提供一个管理员token或者kubeconfig进行直连,所有人都是这个权限,重一点的 ,比如rancher,会基于kubernetes的rbac 创建权限,颗粒度很细,但是代价就是每个用户会独享一个service account,假设一家公司运维人员成百上千,集群内就会有一堆service account,偶尔再来个离职入职,不敢想不敢想,所以,在设计集群权限的时候,我们将复杂的权限分类抽象出3大类,即viewer, ops, admin权限,并创建好对应的clusterrole 和service account,最终将用户绑定到service account上
基于jwt的概念,将两者的权限分为2个字段,存入profile, 然后基于jwt的原理, 将权限信息转换成token,作为接口的权限认证。
因为前端可以看到的菜单信息和需要和后端绑定的,所以基于前端进行静态配置不太合理,基于这个考虑,需要在后端开发一个接口,用于获取前端的菜单,然后由前端对返回进行渲染,实现不同权限看到不同的菜单的效果。
上述权限的核心其实就是Profile,用户的实时权限都是存在Profile里的,所以在设计Proflie的时候需要谨慎。
// 基础用户属性
type ResourceBase struct {
Description string `json:"description"`
CreateAt string `json:"createat"`
UpdateAt string `json:"updateat"`
BuiltIn bool `json:"builtin"`
UUID string `json:"uuid"`
}
// 平台策略
type PlatFormRulePolicy struct {
ResourceName string `json:"resourcename"`
Verbs []string `json:"verbs"`
}
// 平台角色
type PlatFormRole struct {
RoleName string `json:"rolename"`
CreatedBy string `json:"createdby"`
Rules []*PlatFormRulePolicy `json:"rules"`
v1.ResourceBase
}
// 集群绑定关系
type ClusterRoleBinding struct {
UserName string `json:"username"`
UserUUID string `json:"useruuid"`
ClusterRoleUUID string `json:"clusterroleuuid"`
ClusterRoleName string `json:"clusterrolename"`
ClusterUUID string `json:"clusteruuid"`
Namespaces []string `json:"namespaces"`
}
// 用户Profile
type UserProfile struct {
Name string `json:"name"`
UUID string `json:"uuid"`
NickName string `json:"nickname"`
Email string `json:"email"`
Language string `json:"language"`
ResourcePermissions []*v1RoleStruct.PlatFormRole `json:"resourcePermissions"`
KubernetesPermissions []*v1ClusterRoleBindingStruct.ClusterRoleBinding `json:"kubernetespermissions"`
Token string `json:"token"`
LoginTime string `json:"logintime"`
jwt.RegisteredClaims
}
上述profile保存了用户的基本信息,权限信息,以及jwt签名后的token,一个用户对于平台和集群的所有权限,均会通过上述profile进行保存。
To Be Continued …
在梳理完权限如何设计后,便可以构建出最初版本的后端框架了。