需求:
#4372
新用户按环境授权,无法直接作用于集群,只能作用于集群的namespace。
支持按环境给用户授权集群管理权限,如查看、更改和发布。
** 实际上集群就是跟着环境走的,集群 = App 在某个 Env 下的一种划分 **
现状
实际上,从Permission这张表里面可以看得到,对于一个应用(App)的对应权限有如下权限的划分

-
App 管理员
应用管理员具有以下权限: 1. 创建 Namespace 2. 创建Cluster 3. 管理App、Namespace 权限
-
App-Namespace 维度的Namespace管理员(分为两种权限)
-
App-Namespace-Env 维度的Namespace管理员 (分为两种权限)
方案:
-
Permission 侧:
新增两种PermissionType,ModifyCluster 和 ReleaseCluster。代表在Cluster维度的修改和发布的权利,即可以修改和发布Env-Cluster下所有Namespace。
对应的TargetId格式为 AppId + Env + ClusterName。
-
Role 侧:
新增RoleName:ModifyCluster+TargetId 和 ReleaseCluster+TargetId
Management/Subjective
在Portal新增三个接口,获取、赋予、移除Cluster相关的权限Permission。
OpenApi处暂时没有支持相关管理能力。
Management/Passive
需要在Cluster被创建的时候进行RoleInitialize,Cluster在下面几个场景会被创建:
- 创建App时,默认在每个Env下创建一个default集群
- 指定给某个Env创建App时,默认创建default集群
- 在portal端指定App-Env创建Cluster
第一种创建默认的Cluster的场景,Portal是完全不感知的,只知道自己向对应Env发送了创建App的请求,创建Cluster的逻辑完全在AdminService端,只能在创建完远端App之后,默认Cluster也创建成功。
由于权限系统只存在于Portal,三条创建Cluster的链路在Portal端是没有交集的,完全不同,因此需要在三个地方都加上initializeClusterRole的逻辑。(以后或许是可以优化的点)
Usage/Anno&Api
目前来说,Namespace的权限校验相关功能,现有的系统的调用链路还是比较统一的,比如说ModifyNamespace权限校验基本都是调用的hasModifyNamespacePermission 这个接口。
这对于要新加入的ModifyCluster权限就不太合适了,首先方法的语义就不相同,ModifyNamespace是ModifyCluster的子集。如果要在这个接口里面再做对Cluster权限的校验也不合适,因为参数列表里面没有传递ClusterName。
所以可以得到结论:要实现Cluster级别权限的需求,必定要在原有的代码上进行修改了,也就是这个注解:
@PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env)")
目前来说有两种实现方式:
- 修改参数列表,接收四个String
@PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #env, #clusterNam, #namespaceName)")
- 多加一个方法
hasModifyClusterPermission,在注解表达式中用 or 加进去。
@PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env) "
+ "or @permissionValidator.hasModifyClusterPermission(#appId, #env, #clusterName)")
两种方法其实都对原本代码是破坏性的,所以还是打算先选择第二种方法,**对原本的功能的影响尽可能的少。**如有需要,后续再对权限校验进行重构。
测试报告
后端集成测试
主要写了两个集成测试,从Usage和Management两个方面入手
ItemControllerAuthIntegrationTest:测试是否有权限时,对需鉴权接口的访问情况
/**
* Test cluster permission denied.
*/
@Test
public void testCreateItemPermissionDenied() {
setUserId("xxx");
try {
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type", "application/json");
HttpEntity<String> entity = new HttpEntity<>(GSON.toJson(itemDTO), headers);
restTemplate.postForEntity(
url("/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/item"),
entity, String.class, appId, env, clusterName, namespaceName);
fail("should throw");
} catch (final HttpClientErrorException e) {
assertEquals(HttpStatus.FORBIDDEN, e.getStatusCode());
}
}
PermissionControllerTest:测试Cluster Role的管理端整个生命周期(初始化,assign,get,remove)
@Test
@Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public void testClusterRoleLifeCycle() {
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type", "application/json");
HttpEntity<String> entity = new HttpEntity<>(user, headers);
// check role not assigned
ResponseEntity<ClusterRolesAssignedUsers> beforeAssign = restTemplate.getForEntity(
url("/apps/{appId}/envs/{env}/clusters/{clusterName}/role_users"),
ClusterRolesAssignedUsers.class, appId, env, clusterName);
assertEquals(200, beforeAssign.getStatusCodeValue());
ClusterRolesAssignedUsers body = beforeAssign.getBody();
assertNotNull(body);
assertEquals(appId, body.getAppId());
assertEquals(env, body.getEnv());
assertEquals(clusterName, body.getCluster());
assertTrue(body.getModifyRoleUsers() == null || body.getModifyRoleUsers().isEmpty());
// assign role to user
restTemplate.postForEntity(
url("/apps/{appId}/envs/{env}/clusters/{clusterName}/roles/{roleType}"), entity, Void.class,
appId, env, clusterName, roleType);
// check role assigned
...
// remove role from user
...
// check role removed
...
}
整体Portal端验收测试
- 创建好测试环境和集群
- 给开发账号luke授予boe_feat_123的Modify和Release权限
- 登录luke账号,查看集群Namespace,在boe_feat_123有权限,在default没有权限
- 正常测试创建配置、修改、发布等功能

需求:
#4372
新用户按环境授权,无法直接作用于集群,只能作用于集群的namespace。
支持按环境给用户授权集群管理权限,如查看、更改和发布。
** 实际上集群就是跟着环境走的,集群 = App 在某个 Env 下的一种划分 **
现状
实际上,从Permission这张表里面可以看得到,对于一个应用(App)的对应权限有如下权限的划分
App 管理员
应用管理员具有以下权限: 1. 创建 Namespace 2. 创建Cluster 3. 管理App、Namespace 权限
App-Namespace 维度的Namespace管理员(分为两种权限)
App-Namespace-Env 维度的Namespace管理员 (分为两种权限)
方案:
Permission 侧:
新增两种
PermissionType,ModifyCluster 和 ReleaseCluster。代表在Cluster维度的修改和发布的权利,即可以修改和发布Env-Cluster下所有Namespace。对应的
TargetId格式为 AppId + Env + ClusterName。Role 侧:
新增
RoleName:ModifyCluster+TargetId 和 ReleaseCluster+TargetIdManagement/Subjective
在Portal新增三个接口,获取、赋予、移除Cluster相关的权限Permission。
OpenApi处暂时没有支持相关管理能力。
Management/Passive
需要在Cluster被创建的时候进行RoleInitialize,Cluster在下面几个场景会被创建:
第一种创建默认的Cluster的场景,Portal是完全不感知的,只知道自己向对应Env发送了创建App的请求,创建Cluster的逻辑完全在AdminService端,只能在创建完远端App之后,默认Cluster也创建成功。
由于权限系统只存在于Portal,三条创建Cluster的链路在Portal端是没有交集的,完全不同,因此需要在三个地方都加上
initializeClusterRole的逻辑。(以后或许是可以优化的点)Usage/Anno&Api
目前来说,Namespace的权限校验相关功能,现有的系统的调用链路还是比较统一的,比如说ModifyNamespace权限校验基本都是调用的
hasModifyNamespacePermission这个接口。这对于要新加入的ModifyCluster权限就不太合适了,首先方法的语义就不相同,ModifyNamespace是ModifyCluster的子集。如果要在这个接口里面再做对Cluster权限的校验也不合适,因为参数列表里面没有传递ClusterName。
所以可以得到结论:要实现Cluster级别权限的需求,必定要在原有的代码上进行修改了,也就是这个注解:
目前来说有两种实现方式:
hasModifyClusterPermission,在注解表达式中用or加进去。两种方法其实都对原本代码是破坏性的,所以还是打算先选择第二种方法,**对原本的功能的影响尽可能的少。**如有需要,后续再对权限校验进行重构。
测试报告
后端集成测试
主要写了两个集成测试,从Usage和Management两个方面入手
ItemControllerAuthIntegrationTest:测试是否有权限时,对需鉴权接口的访问情况PermissionControllerTest:测试Cluster Role的管理端整个生命周期(初始化,assign,get,remove)整体Portal端验收测试