diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/component/PermissionValidator.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/component/PermissionValidator.java index 494dba648e7..56d681656c7 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/component/PermissionValidator.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/component/PermissionValidator.java @@ -48,42 +48,75 @@ public PermissionValidator( this.systemRoleManagerService = systemRoleManagerService; } - public boolean hasModifyNamespacePermission(String appId, String namespaceName) { + private boolean hasModifyNamespacePermission(String appId, String namespaceName) { return rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(), PermissionType.MODIFY_NAMESPACE, RoleUtils.buildNamespaceTargetId(appId, namespaceName)); } - public boolean hasModifyNamespacePermission(String appId, String namespaceName, String env) { - return hasModifyNamespacePermission(appId, namespaceName) || - rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(), - PermissionType.MODIFY_NAMESPACE, RoleUtils.buildNamespaceTargetId(appId, namespaceName, env)); + private boolean hasModifyNamespacePermission(String appId, String namespaceName, String env) { + return rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(), + PermissionType.MODIFY_NAMESPACE, + RoleUtils.buildNamespaceTargetId(appId, namespaceName, env)); } - public boolean hasReleaseNamespacePermission(String appId, String namespaceName) { + private boolean hasModifyNamespacesInClusterPermission(String appId, String env, String clusterName) { + return rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(), + PermissionType.MODIFY_NAMESPACES_IN_CLUSTER, + RoleUtils.buildClusterTargetId(appId, env, clusterName)); + } + + public boolean hasModifyNamespacePermission(String appId, String env, String clusterName, String namespaceName) { + if (hasModifyNamespacePermission(appId, namespaceName)) { + return true; + } + if (hasModifyNamespacePermission(appId, namespaceName, env)) { + return true; + } + if (hasModifyNamespacesInClusterPermission(appId, env, clusterName)) { + return true; + } + return false; + } + + private boolean hasReleaseNamespacePermission(String appId, String namespaceName) { return rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(), PermissionType.RELEASE_NAMESPACE, RoleUtils.buildNamespaceTargetId(appId, namespaceName)); } - public boolean hasReleaseNamespacePermission(String appId, String namespaceName, String env) { - return hasReleaseNamespacePermission(appId, namespaceName) || - rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(), - PermissionType.RELEASE_NAMESPACE, RoleUtils.buildNamespaceTargetId(appId, namespaceName, env)); + private boolean hasReleaseNamespacePermission(String appId, String namespaceName, String env) { + return rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(), + PermissionType.RELEASE_NAMESPACE, + RoleUtils.buildNamespaceTargetId(appId, namespaceName, env)); + } + + private boolean hasReleaseNamespacesInClusterPermission(String appId, String env, String clusterName) { + return rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(), + PermissionType.RELEASE_NAMESPACES_IN_CLUSTER, + RoleUtils.buildClusterTargetId(appId, env, clusterName)); } - public boolean hasDeleteNamespacePermission(String appId) { - return hasAssignRolePermission(appId) || isSuperAdmin(); + public boolean hasReleaseNamespacePermission(String appId, String env, String clusterName, String namespaceName) { + if (hasReleaseNamespacePermission(appId, namespaceName)) { + return true; + } + if (hasReleaseNamespacePermission(appId, namespaceName, env)) { + return true; + } + if (hasReleaseNamespacesInClusterPermission(appId, env, clusterName)) { + return true; + } + return false; } - public boolean hasOperateNamespacePermission(String appId, String namespaceName) { - return hasModifyNamespacePermission(appId, namespaceName) || hasReleaseNamespacePermission(appId, namespaceName); + public boolean hasDeleteNamespacePermission(String appId) { + return hasAssignRolePermission(appId) || isSuperAdmin(); } - public boolean hasOperateNamespacePermission(String appId, String namespaceName, String env) { - return hasOperateNamespacePermission(appId, namespaceName) || - hasModifyNamespacePermission(appId, namespaceName, env) || - hasReleaseNamespacePermission(appId, namespaceName, env); + public boolean hasOperateNamespacePermission(String appId, String env, String clusterName, String namespaceName) { + return hasModifyNamespacePermission(appId, env, clusterName, namespaceName) + || hasReleaseNamespacePermission(appId, env, clusterName, namespaceName); } public boolean hasAssignRolePermission(String appId) { @@ -124,7 +157,8 @@ public boolean isSuperAdmin() { return rolePermissionService.isSuperAdmin(userInfoHolder.getUser().getUserId()); } - public boolean shouldHideConfigToCurrentUser(String appId, String env, String namespaceName) { + public boolean shouldHideConfigToCurrentUser(String appId, String env, String clusterName, + String namespaceName) { // 1. check whether the current environment enables member only function if (!portalConfig.isConfigViewMemberOnly(env)) { return false; @@ -137,7 +171,7 @@ public boolean shouldHideConfigToCurrentUser(String appId, String env, String na } // 3. check app admin and operate permissions - return !isAppAdmin(appId) && !hasOperateNamespacePermission(appId, namespaceName, env); + return !isAppAdmin(appId) && !hasOperateNamespacePermission(appId, env, clusterName, namespaceName); } public boolean hasCreateApplicationPermission() { diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/constant/PermissionType.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/constant/PermissionType.java index 85aa1d75806..85ec0ded21b 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/constant/PermissionType.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/constant/PermissionType.java @@ -45,5 +45,8 @@ public interface PermissionType { String RELEASE_NAMESPACE = "ReleaseNamespace"; + String MODIFY_NAMESPACES_IN_CLUSTER = "ModifyNamespacesInCluster"; + + String RELEASE_NAMESPACES_IN_CLUSTER = "ReleaseNamespacesInCluster"; } diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/constant/RoleType.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/constant/RoleType.java index 802eafe5185..d0bd413d0ff 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/constant/RoleType.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/constant/RoleType.java @@ -24,8 +24,13 @@ public class RoleType { public static final String RELEASE_NAMESPACE = "ReleaseNamespace"; + public static final String MODIFY_NAMESPACES_IN_CLUSTER = "ModifyNamespacesInCluster"; + + public static final String RELEASE_NAMESPACES_IN_CLUSTER = "ReleaseNamespacesInCluster"; + public static boolean isValidRoleType(String roleType) { - return MASTER.equals(roleType) || MODIFY_NAMESPACE.equals(roleType) || RELEASE_NAMESPACE.equals(roleType); + return MASTER.equals(roleType) || MODIFY_NAMESPACE.equals(roleType) || RELEASE_NAMESPACE.equals( + roleType) || MODIFY_NAMESPACES_IN_CLUSTER.equals(roleType) || RELEASE_NAMESPACES_IN_CLUSTER.equals(roleType); } } diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/CommitController.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/CommitController.java index f1e030536e3..c9cb5ba3efd 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/CommitController.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/CommitController.java @@ -51,7 +51,7 @@ public List find(@PathVariable String appId, @PathVariable String env @RequestParam(required = false) String key, @Valid @PositiveOrZero(message = "page should be positive or 0") @RequestParam(defaultValue = "0") int page, @Valid @Positive(message = "size should be positive number") @RequestParam(defaultValue = "10") int size) { - if (permissionValidator.shouldHideConfigToCurrentUser(appId, env, namespaceName)) { + if (permissionValidator.shouldHideConfigToCurrentUser(appId, env, clusterName, namespaceName)) { return Collections.emptyList(); } diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ConfigsExportController.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ConfigsExportController.java index fc6ae086f4d..565959fc0e6 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ConfigsExportController.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ConfigsExportController.java @@ -78,7 +78,7 @@ public ConfigsExportController( * application.json * */ - @PreAuthorize(value = "!@permissionValidator.shouldHideConfigToCurrentUser(#appId, #env, #namespaceName)") + @PreAuthorize(value = "!@permissionValidator.shouldHideConfigToCurrentUser(#appId, #env, #clusterName, #namespaceName)") @GetMapping("/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/items/export") public void exportItems(@PathVariable String appId, @PathVariable String env, @PathVariable String clusterName, @PathVariable String namespaceName, diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ConfigsImportController.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ConfigsImportController.java index 88ecfba5a69..60e8b74f5ea 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ConfigsImportController.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ConfigsImportController.java @@ -61,7 +61,7 @@ public ConfigsImportController( * etc. * @throws IOException */ - @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env)") + @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #env, #clusterName, #namespaceName)") @PostMapping("/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/items/import") public void importConfigFile(@PathVariable String appId, @PathVariable String env, @PathVariable String clusterName, @PathVariable String namespaceName, diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ItemController.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ItemController.java index e0c985b1035..d4becc38e7b 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ItemController.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ItemController.java @@ -73,7 +73,7 @@ public ItemController(final ItemService configService, final UserInfoHolder user this.namespaceService = namespaceService; } - @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env)") + @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #env, #clusterName, #namespaceName)") @PutMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/items", consumes = { "application/json"}) public void modifyItemsByText(@PathVariable String appId, @PathVariable String env, @@ -87,7 +87,7 @@ public void modifyItemsByText(@PathVariable String appId, @PathVariable String e configService.updateConfigItemByText(model); } - @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env)") + @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #env, #clusterName, #namespaceName)") @PostMapping("/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/item") public ItemDTO createItem(@PathVariable String appId, @PathVariable String env, @PathVariable String clusterName, @PathVariable String namespaceName, @@ -106,7 +106,7 @@ public ItemDTO createItem(@PathVariable String appId, @PathVariable String env, return configService.createItem(appId, Env.valueOf(env), clusterName, namespaceName, item); } - @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env)") + @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #env, #clusterName, #namespaceName)") @PutMapping("/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/item") public void updateItem(@PathVariable String appId, @PathVariable String env, @PathVariable String clusterName, @PathVariable String namespaceName, @@ -120,7 +120,7 @@ public void updateItem(@PathVariable String appId, @PathVariable String env, } - @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env) ") + @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #env, #clusterName, #namespaceName)") @DeleteMapping("/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/items/{itemId}") public void deleteItem(@PathVariable String appId, @PathVariable String env, @PathVariable String clusterName, @PathVariable String namespaceName, @@ -142,7 +142,7 @@ public List findItems(@PathVariable String appId, @PathVariable String @PathVariable String clusterName, @PathVariable String namespaceName, @RequestParam(defaultValue = "lineNum") String orderBy) { - if (permissionValidator.shouldHideConfigToCurrentUser(appId, env, namespaceName)) { + if (permissionValidator.shouldHideConfigToCurrentUser(appId, env, clusterName, namespaceName)) { return Collections.emptyList(); } @@ -183,9 +183,10 @@ public List diff(@RequestBody NamespaceSyncModel model) { } if (permissionValidator - .shouldHideConfigToCurrentUser(namespace.getAppId(), namespace.getEnv().getName(), namespace.getNamespaceName())) { + .shouldHideConfigToCurrentUser(namespace.getAppId(), namespace.getEnv().getName(), + namespace.getClusterName(), namespace.getNamespaceName())) { diff.setDiffs(new ItemChangeSets()); - diff.setExtInfo("You are not this project's administrator, nor you have edit or release permission for the namespace in environment: " + namespace.getEnv()); + diff.setExtInfo("You are not this project's administrator, nor you have edit or release permission for the namespace: " + namespace); } } @@ -196,29 +197,30 @@ public List diff(@RequestBody NamespaceSyncModel model) { public ResponseEntity update(@PathVariable String appId, @PathVariable String namespaceName, @RequestBody NamespaceSyncModel model) { checkModel(!model.isInvalid() && model.syncToNamespacesValid(appId, namespaceName)); - boolean hasPermission = permissionValidator.hasModifyNamespacePermission(appId, namespaceName); - Env envNoPermission = null; - // if uses has ModifyNamespace permission then he has permission - if (!hasPermission) { - // else check if user has every env's ModifyNamespace permission - hasPermission = true; - for (NamespaceIdentifier namespaceIdentifier : model.getSyncToNamespaces()) { - // once user has not one of the env's ModifyNamespace permission, then break the loop - hasPermission &= permissionValidator.hasModifyNamespacePermission(namespaceIdentifier.getAppId(), namespaceIdentifier.getNamespaceName(), namespaceIdentifier.getEnv().toString()); - if (!hasPermission) { - envNoPermission = namespaceIdentifier.getEnv(); - break; - } + NamespaceIdentifier noPermissionNamespace = null; + // check if user has every namespace's ModifyNamespace permission + boolean hasPermission = true; + for (NamespaceIdentifier namespaceIdentifier : model.getSyncToNamespaces()) { + // once user has not one of the namespace's ModifyNamespace permission, then break the loop + hasPermission = permissionValidator.hasModifyNamespacePermission( + namespaceIdentifier.getAppId(), + namespaceIdentifier.getEnv().getName(), + namespaceIdentifier.getClusterName(), + namespaceIdentifier.getNamespaceName() + ); + if (!hasPermission) { + noPermissionNamespace = namespaceIdentifier; + break; } } if (hasPermission) { configService.syncItems(model.getSyncToNamespaces(), model.getSyncItems()); return ResponseEntity.status(HttpStatus.OK).build(); } - throw new AccessDeniedException(String.format("You don't have the permission to modify environment: %s", envNoPermission)); + throw new AccessDeniedException(String.format("You don't have the permission to modify namespace: %s", noPermissionNamespace)); } - @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env)") + @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #env, #clusterName, #namespaceName)") @PostMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/syntax-check", consumes = { "application/json"}) public ResponseEntity syntaxCheckText(@PathVariable String appId, @PathVariable String env, @@ -229,7 +231,7 @@ public ResponseEntity syntaxCheckText(@PathVariable String appId, @PathVar return ResponseEntity.ok().build(); } - @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env)") + @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #env, #clusterName, #namespaceName)") @PutMapping("/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/revoke-items") public void revokeItems(@PathVariable String appId, @PathVariable String env, @PathVariable String clusterName, @PathVariable String namespaceName) { diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/NamespaceBranchController.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/NamespaceBranchController.java index 8daa6b68a87..95cb5d9fb17 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/NamespaceBranchController.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/NamespaceBranchController.java @@ -71,14 +71,14 @@ public NamespaceBO findBranch(@PathVariable String appId, @PathVariable String namespaceName) { NamespaceBO namespaceBO = namespaceBranchService.findBranch(appId, Env.valueOf(env), clusterName, namespaceName); - if (namespaceBO != null && permissionValidator.shouldHideConfigToCurrentUser(appId, env, namespaceName)) { + if (namespaceBO != null && permissionValidator.shouldHideConfigToCurrentUser(appId, env, clusterName, namespaceName)) { namespaceBO.hideItems(); } return namespaceBO; } - @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env)") + @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #env, #clusterName, #namespaceName)") @PostMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/branches") @ApolloAuditLog(type = OpType.CREATE, name = "NamespaceBranch.create") public NamespaceDTO createBranch(@PathVariable String appId, @@ -97,9 +97,10 @@ public void deleteBranch(@PathVariable String appId, @PathVariable String namespaceName, @PathVariable String branchName) { - boolean canDelete = permissionValidator.hasReleaseNamespacePermission(appId, namespaceName, env) || - (permissionValidator.hasModifyNamespacePermission(appId, namespaceName, env) && - releaseService.loadLatestRelease(appId, Env.valueOf(env), branchName, namespaceName) == null); + boolean hasModifyPermission = permissionValidator.hasModifyNamespacePermission(appId, env, clusterName, namespaceName); + boolean hasReleasePermission = permissionValidator.hasReleaseNamespacePermission(appId, env, clusterName, namespaceName); + boolean canDelete = hasReleasePermission + || (hasModifyPermission && releaseService.loadLatestRelease(appId, Env.valueOf(env), branchName, namespaceName) == null); if (!canDelete) { @@ -115,7 +116,7 @@ public void deleteBranch(@PathVariable String appId, - @PreAuthorize(value = "@permissionValidator.hasReleaseNamespacePermission(#appId, #namespaceName, #env)") + @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #env, #clusterName, #namespaceName)") @PostMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/branches/{branchName}/merge") @ApolloAuditLog(type = OpType.UPDATE, name = "NamespaceBranch.merge") public ReleaseDTO merge(@PathVariable String appId, @PathVariable String env, @@ -155,7 +156,7 @@ public GrayReleaseRuleDTO getBranchGrayRules(@PathVariable String appId, @PathVa } - @PreAuthorize(value = "@permissionValidator.hasOperateNamespacePermission(#appId, #namespaceName, #env)") + @PreAuthorize(value = "@permissionValidator.hasOperateNamespacePermission(#appId, #env, #clusterName, #namespaceName)") @PutMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/branches/{branchName}/rules") @ApolloAuditLog(type = OpType.UPDATE, name = "NamespaceBranch.updateBranchRules") public void updateBranchRules(@PathVariable String appId, @PathVariable String env, diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/NamespaceController.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/NamespaceController.java index ee2515d99ff..ed362bf8542 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/NamespaceController.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/NamespaceController.java @@ -111,7 +111,7 @@ public List findNamespaces(@PathVariable String appId, @PathVariabl List namespaceBOs = namespaceService.findNamespaceBOs(appId, Env.valueOf(env), clusterName); for (NamespaceBO namespaceBO : namespaceBOs) { - if (permissionValidator.shouldHideConfigToCurrentUser(appId, env, namespaceBO.getBaseInfo().getNamespaceName())) { + if (permissionValidator.shouldHideConfigToCurrentUser(appId, env, clusterName, namespaceBO.getBaseInfo().getNamespaceName())) { namespaceBO.hideItems(); } } @@ -125,7 +125,7 @@ public NamespaceBO findNamespace(@PathVariable String appId, @PathVariable Strin NamespaceBO namespaceBO = namespaceService.loadNamespaceBO(appId, Env.valueOf(env), clusterName, namespaceName); - if (namespaceBO != null && permissionValidator.shouldHideConfigToCurrentUser(appId, env, namespaceName)) { + if (namespaceBO != null && permissionValidator.shouldHideConfigToCurrentUser(appId, env, clusterName, namespaceName)) { namespaceBO.hideItems(); } diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/PermissionController.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/PermissionController.java index 8cc166ce26d..9d56e5d6fc2 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/PermissionController.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/PermissionController.java @@ -25,6 +25,7 @@ import com.ctrip.framework.apollo.portal.constant.RoleType; import com.ctrip.framework.apollo.portal.entity.bo.UserInfo; import com.ctrip.framework.apollo.portal.entity.vo.AppRolesAssignedUsers; +import com.ctrip.framework.apollo.portal.entity.vo.ClusterNamespaceRolesAssignedUsers; import com.ctrip.framework.apollo.portal.entity.vo.NamespaceEnvRolesAssignedUsers; import com.ctrip.framework.apollo.portal.entity.vo.NamespaceRolesAssignedUsers; import com.ctrip.framework.apollo.portal.entity.vo.PermissionCondition; @@ -37,7 +38,6 @@ import com.ctrip.framework.apollo.portal.util.RoleUtils; import com.google.common.collect.Sets; import com.google.gson.JsonObject; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.util.CollectionUtils; @@ -80,6 +80,12 @@ public ResponseEntity initAppPermission(@PathVariable String appId, @Reque return ResponseEntity.ok().build(); } + @PostMapping("/apps/{appId}/envs/{env}/clusters/{clusterName}/initNsPermission") + public ResponseEntity initClusterNamespacePermission(@PathVariable String appId, @PathVariable String env, @PathVariable String clusterName) { + roleInitializationService.initClusterNamespaceRoles(appId, env, clusterName, userInfoHolder.getUser().getUserId()); + return ResponseEntity.ok().build(); + } + @GetMapping("/apps/{appId}/permissions/{permissionType}") public ResponseEntity hasPermission(@PathVariable String appId, @PathVariable String permissionType) { PermissionCondition permissionCondition = new PermissionCondition(); @@ -114,6 +120,18 @@ public ResponseEntity hasPermission(@PathVariable String ap return ResponseEntity.ok().body(permissionCondition); } + @GetMapping("/apps/{appId}/envs/{env}/clusters/{clusterName}/ns_permissions/{permissionType}") + public ResponseEntity hasClusterNamespacePermission(@PathVariable String appId, @PathVariable String env, @PathVariable String clusterName, + @PathVariable String permissionType) { + PermissionCondition permissionCondition = new PermissionCondition(); + + permissionCondition.setHasPermission( + rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(), permissionType, + RoleUtils.buildClusterTargetId(appId, env, clusterName))); + + return ResponseEntity.ok().body(permissionCondition); + } + @GetMapping("/permissions/root") public ResponseEntity hasRootPermission() { PermissionCondition permissionCondition = new PermissionCondition(); @@ -192,6 +210,72 @@ public ResponseEntity removeNamespaceEnvRoleFromUser(@PathVariable String return ResponseEntity.ok().build(); } + @GetMapping("/apps/{appId}/envs/{env}/clusters/{clusterName}/ns_role_users") + public ClusterNamespaceRolesAssignedUsers getClusterNamespaceRoles(@PathVariable String appId, @PathVariable String env, @PathVariable String clusterName) { + + // validate env parameter + if (Env.UNKNOWN == Env.transformEnv(env)) { + throw BadRequestException.invalidEnvFormat(env); + } + + ClusterNamespaceRolesAssignedUsers assignedUsers = new ClusterNamespaceRolesAssignedUsers(); + assignedUsers.setAppId(appId); + assignedUsers.setEnv(env); + assignedUsers.setCluster(clusterName); + + Set releaseNamespacesInClusterUsers = + rolePermissionService.queryUsersWithRole(RoleUtils.buildReleaseNamespacesInClusterRoleName(appId, env, clusterName)); + assignedUsers.setReleaseRoleUsers(releaseNamespacesInClusterUsers); + + Set modifyNamespacesInClusterUsers = + rolePermissionService.queryUsersWithRole(RoleUtils.buildModifyNamespacesInClusterRoleName(appId, env, clusterName)); + assignedUsers.setModifyRoleUsers(modifyNamespacesInClusterUsers); + + return assignedUsers; + } + + @PreAuthorize(value = "@permissionValidator.hasAssignRolePermission(#appId)") + @PostMapping("/apps/{appId}/envs/{env}/clusters/{clusterName}/ns_roles/{roleType}") + public ResponseEntity assignClusterNamespaceRoleToUser(@PathVariable String appId, @PathVariable String env, @PathVariable String clusterName, + @PathVariable String roleType, @RequestBody String user) { + checkUserExists(user); + RequestPrecondition.checkArgumentsNotEmpty(user); + + if (!RoleType.isValidRoleType(roleType)) { + throw BadRequestException.invalidRoleTypeFormat(roleType); + } + + // validate env parameter + if (Env.UNKNOWN == Env.transformEnv(env)) { + throw BadRequestException.invalidEnvFormat(env); + } + Set assignedUser = rolePermissionService.assignRoleToUsers(RoleUtils.buildClusterRoleName(appId, env, clusterName, roleType), + Sets.newHashSet(user), userInfoHolder.getUser().getUserId()); + if (CollectionUtils.isEmpty(assignedUser)) { + throw BadRequestException.userAlreadyAuthorized(user); + } + + return ResponseEntity.ok().build(); + } + + @PreAuthorize(value = "@permissionValidator.hasAssignRolePermission(#appId)") + @DeleteMapping("/apps/{appId}/envs/{env}/clusters/{clusterName}/ns_roles/{roleType}") + public ResponseEntity removeClusterNamespaceRoleFromUser(@PathVariable String appId, @PathVariable String env, @PathVariable String clusterName, + @PathVariable String roleType, @RequestParam String user) { + RequestPrecondition.checkArgumentsNotEmpty(user); + + if (!RoleType.isValidRoleType(roleType)) { + throw BadRequestException.invalidRoleTypeFormat(roleType); + } + // validate env parameter + if (Env.UNKNOWN == Env.transformEnv(env)) { + throw BadRequestException.invalidEnvFormat(env); + } + rolePermissionService.removeRoleFromUsers(RoleUtils.buildClusterRoleName(appId, env, clusterName, roleType), + Sets.newHashSet(user), userInfoHolder.getUser().getUserId()); + return ResponseEntity.ok().build(); + } + @GetMapping("/apps/{appId}/namespaces/{namespaceName}/role_users") public NamespaceRolesAssignedUsers getNamespaceRoles(@PathVariable String appId, @PathVariable String namespaceName) { diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ReleaseController.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ReleaseController.java index 06e303f18fe..8a1e9127a6f 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ReleaseController.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ReleaseController.java @@ -69,7 +69,7 @@ public ReleaseController( this.userInfoHolder = userInfoHolder; } - @PreAuthorize(value = "@permissionValidator.hasReleaseNamespacePermission(#appId, #namespaceName, #env)") + @PreAuthorize(value = "@permissionValidator.hasReleaseNamespacePermission(#appId, #env, #clusterName, #namespaceName)") @PostMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/releases") public ReleaseDTO createRelease(@PathVariable String appId, @PathVariable String env, @PathVariable String clusterName, @@ -98,7 +98,7 @@ public ReleaseDTO createRelease(@PathVariable String appId, return createdRelease; } - @PreAuthorize(value = "@permissionValidator.hasReleaseNamespacePermission(#appId, #namespaceName, #env)") + @PreAuthorize(value = "@permissionValidator.hasReleaseNamespacePermission(#appId, #env, #clusterName, #namespaceName)") @PostMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/branches/{branchName}/releases") public ReleaseDTO createGrayRelease(@PathVariable String appId, @PathVariable String env, @PathVariable String clusterName, @@ -146,7 +146,7 @@ public List findAllReleases(@PathVariable String appId, @PathVariable String namespaceName, @Valid @PositiveOrZero(message = "page should be positive or 0") @RequestParam(defaultValue = "0") int page, @Valid @Positive(message = "size should be positive number") @RequestParam(defaultValue = "5") int size) { - if (permissionValidator.shouldHideConfigToCurrentUser(appId, env, namespaceName)) { + if (permissionValidator.shouldHideConfigToCurrentUser(appId, env, clusterName, namespaceName)) { return Collections.emptyList(); } @@ -161,7 +161,7 @@ public List findActiveReleases(@PathVariable String appId, @Valid @PositiveOrZero(message = "page should be positive or 0") @RequestParam(defaultValue = "0") int page, @Valid @Positive(message = "size should be positive number") @RequestParam(defaultValue = "5") int size) { - if (permissionValidator.shouldHideConfigToCurrentUser(appId, env, namespaceName)) { + if (permissionValidator.shouldHideConfigToCurrentUser(appId, env, clusterName, namespaceName)) { return Collections.emptyList(); } @@ -187,7 +187,7 @@ public void rollback(@PathVariable String env, throw NotFoundException.releaseNotFound(releaseId); } - if (!permissionValidator.hasReleaseNamespacePermission(release.getAppId(), release.getNamespaceName(), env)) { + if (!permissionValidator.hasReleaseNamespacePermission(release.getAppId(), env, release.getClusterName(), release.getNamespaceName())) { throw new AccessDeniedException("Access is denied"); } diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ReleaseHistoryController.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ReleaseHistoryController.java index da391666836..39f1f7f4db8 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ReleaseHistoryController.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ReleaseHistoryController.java @@ -48,7 +48,7 @@ public List findReleaseHistoriesByNamespace(@PathVariable Stri @RequestParam(value = "page", defaultValue = "0") int page, @RequestParam(value = "size", defaultValue = "10") int size) { - if (permissionValidator.shouldHideConfigToCurrentUser(appId, env, namespaceName)) { + if (permissionValidator.shouldHideConfigToCurrentUser(appId, env, clusterName, namespaceName)) { return Collections.emptyList(); } diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/entity/vo/ClusterNamespaceRolesAssignedUsers.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/entity/vo/ClusterNamespaceRolesAssignedUsers.java new file mode 100644 index 00000000000..8a3e5053ded --- /dev/null +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/entity/vo/ClusterNamespaceRolesAssignedUsers.java @@ -0,0 +1,80 @@ +/* + * Copyright 2024 Apollo Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package com.ctrip.framework.apollo.portal.entity.vo; + +import com.ctrip.framework.apollo.portal.entity.bo.UserInfo; +import java.util.Set; + +public class ClusterNamespaceRolesAssignedUsers { + + private String appId; + private String env; + private String cluster; + private Set modifyRoleUsers; + private Set releaseRoleUsers; + + public String getEnv() { + return env; + } + + public void setEnv(String env) { + this.env = env; + } + + public String getAppId() { + return appId; + } + + public void setAppId(String appId) { + this.appId = appId; + } + + public String getCluster() { + return cluster; + } + + public void setCluster(String cluster) { + this.cluster = cluster; + } + + public Set getModifyRoleUsers() { + return modifyRoleUsers; + } + + public void setModifyRoleUsers(Set modifyRoleUsers) { + this.modifyRoleUsers = modifyRoleUsers; + } + + public Set getReleaseRoleUsers() { + return releaseRoleUsers; + } + + public void setReleaseRoleUsers(Set releaseRoleUsers) { + this.releaseRoleUsers = releaseRoleUsers; + } + + @Override + public String toString() { + return "ClusterNamespaceRolesAssignedUsers{" + + "appId='" + appId + '\'' + + ", env='" + env + '\'' + + ", cluster='" + cluster + '\'' + + ", modifyRoleUsers=" + modifyRoleUsers + + ", releaseRoleUsers=" + releaseRoleUsers + + '}'; + } +} diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/AppService.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/AppService.java index df68039f292..6a596f41fb7 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/AppService.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/AppService.java @@ -17,7 +17,6 @@ package com.ctrip.framework.apollo.portal.service; import com.ctrip.framework.apollo.audit.annotation.ApolloAuditLog; -import com.ctrip.framework.apollo.audit.annotation.ApolloAuditLogDataInfluence; import com.ctrip.framework.apollo.audit.annotation.OpType; import com.ctrip.framework.apollo.audit.api.ApolloAuditLogApi; import com.ctrip.framework.apollo.common.dto.AppDTO; @@ -25,8 +24,10 @@ import com.ctrip.framework.apollo.common.entity.App; import com.ctrip.framework.apollo.common.exception.BadRequestException; import com.ctrip.framework.apollo.common.utils.BeanUtils; +import com.ctrip.framework.apollo.core.ConfigConsts; import com.ctrip.framework.apollo.core.utils.StringUtils; import com.ctrip.framework.apollo.portal.api.AdminServiceAPI.AppAPI; +import com.ctrip.framework.apollo.portal.component.PortalSettings; import com.ctrip.framework.apollo.portal.environment.Env; import com.ctrip.framework.apollo.portal.api.AdminServiceAPI; import com.ctrip.framework.apollo.portal.constant.TracerEventType; @@ -63,6 +64,7 @@ public class AppService { private final FavoriteService favoriteService; private final UserService userService; private final ApolloAuditLogApi apolloAuditLogApi; + private final PortalSettings portalSettings; private final ApplicationEventPublisher publisher; @@ -76,7 +78,7 @@ public AppService( final RolePermissionService rolePermissionService, final FavoriteService favoriteService, final UserService userService, ApplicationEventPublisher publisher, - final ApolloAuditLogApi apolloAuditLogApi) { + final ApolloAuditLogApi apolloAuditLogApi, PortalSettings portalSettings) { this.userInfoHolder = userInfoHolder; this.appAPI = appAPI; this.appRepository = appRepository; @@ -88,6 +90,7 @@ public AppService( this.userService = userService; this.apolloAuditLogApi = apolloAuditLogApi; this.publisher = publisher; + this.portalSettings = portalSettings; } @@ -138,6 +141,9 @@ public void createAppInRemote(Env env, App app) { AppDTO appDTO = BeanUtils.transform(AppDTO.class, app); appAPI.createApp(env, appDTO); + + roleInitializationService.initClusterNamespaceRoles(app.getAppId(), ConfigConsts.CLUSTER_NAME_DEFAULT, + env.getName(), userInfoHolder.getUser().getUserId()); } private App createAppInLocal(App app) { @@ -162,6 +168,11 @@ private App createAppInLocal(App app) { appNamespaceService.createDefaultAppNamespace(appId); roleInitializationService.initAppRoles(createdApp); + List envs = portalSettings.getActiveEnvs(); + for (Env env : envs) { + roleInitializationService.initClusterNamespaceRoles(appId, ConfigConsts.CLUSTER_NAME_DEFAULT, + env.getName(), userInfoHolder.getUser().getUserId()); + } Tracer.logEvent(TracerEventType.CREATE_APP, appId); diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/ClusterService.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/ClusterService.java index b0ee27f2e86..a01c26201b3 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/ClusterService.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/ClusterService.java @@ -32,10 +32,13 @@ public class ClusterService { private final UserInfoHolder userInfoHolder; private final AdminServiceAPI.ClusterAPI clusterAPI; + private final RoleInitializationService roleInitializationService; - public ClusterService(final UserInfoHolder userInfoHolder, final AdminServiceAPI.ClusterAPI clusterAPI) { + public ClusterService(final UserInfoHolder userInfoHolder, final AdminServiceAPI.ClusterAPI clusterAPI, + RoleInitializationService roleInitializationService) { this.userInfoHolder = userInfoHolder; this.clusterAPI = clusterAPI; + this.roleInitializationService = roleInitializationService; } public List findClusters(Env env, String appId) { @@ -48,6 +51,9 @@ public ClusterDTO createCluster(Env env, ClusterDTO cluster) { } ClusterDTO clusterDTO = clusterAPI.create(env, cluster); + roleInitializationService.initClusterNamespaceRoles(cluster.getAppId(), env.getName(), cluster.getName(), + userInfoHolder.getUser().getUserId()); + Tracer.logEvent(TracerEventType.CREATE_CLUSTER, cluster.getAppId(), "0", cluster.getName()); return clusterDTO; diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/RoleInitializationService.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/RoleInitializationService.java index 1ccb5f9081d..f99e9638399 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/RoleInitializationService.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/RoleInitializationService.java @@ -33,4 +33,6 @@ void initNamespaceSpecificEnvRoles(String appId, String namespaceName, String en void initManageAppMasterRole(String appId, String operator); + void initClusterNamespaceRoles(String appId, String env, String clusterName, String operator); + } diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/defaultimpl/DefaultRoleInitializationService.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/defaultimpl/DefaultRoleInitializationService.java index b54d20b50ab..391fb78b89b 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/defaultimpl/DefaultRoleInitializationService.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/defaultimpl/DefaultRoleInitializationService.java @@ -174,6 +174,20 @@ public void initManageAppMasterRole(String appId, String operator) { } } + @Transactional + @Override + public void initClusterNamespaceRoles(String appId, String env, String clusterName, String operator) { + String modifyNamespacesInClusterRoleName = RoleUtils.buildModifyNamespacesInClusterRoleName(appId, env, clusterName); + if (rolePermissionService.findRoleByRoleName(modifyNamespacesInClusterRoleName) == null) { + createClusterRole(appId, env, clusterName, PermissionType.MODIFY_NAMESPACES_IN_CLUSTER, modifyNamespacesInClusterRoleName, operator); + } + + String releaseNamespacesInClusterRoleName = RoleUtils.buildReleaseNamespacesInClusterRoleName(appId, env, clusterName); + if (rolePermissionService.findRoleByRoleName(releaseNamespacesInClusterRoleName) == null) { + createClusterRole(appId, env, clusterName, PermissionType.RELEASE_NAMESPACES_IN_CLUSTER, releaseNamespacesInClusterRoleName, operator); + } + } + private void createAppMasterRole(String appId, String operator) { Set appPermissions = Stream.of(PermissionType.CREATE_CLUSTER, PermissionType.CREATE_NAMESPACE, PermissionType.ASSIGN_ROLE) @@ -228,4 +242,15 @@ private void createNamespaceEnvRole(String appId, String namespaceName, String p rolePermissionService .createRoleWithPermissions(role, Sets.newHashSet(createdPermission.getId())); } + + private void createClusterRole(String appId, String env, String clusterName, String permissionType, + String roleName, String operator) { + Permission permission = + createPermission(RoleUtils.buildClusterTargetId(appId, env, clusterName), permissionType, operator); + Permission createdPermission = rolePermissionService.createPermission(permission); + + Role role = createRole(roleName, operator); + rolePermissionService + .createRoleWithPermissions(role, Sets.newHashSet(createdPermission.getId())); + } } diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/util/RoleUtils.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/util/RoleUtils.java index a02473fbe99..1101fa4ebff 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/util/RoleUtils.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/util/RoleUtils.java @@ -66,6 +66,10 @@ public static String buildModifyNamespaceRoleName(String appId, String namespace return STRING_JOINER.join(RoleType.MODIFY_NAMESPACE, appId, namespaceName, env); } + public static String buildModifyNamespacesInClusterRoleName(String appId, String env, String clusterName) { + return STRING_JOINER.join(RoleType.MODIFY_NAMESPACES_IN_CLUSTER, appId, env, clusterName); + } + public static String buildModifyDefaultNamespaceRoleName(String appId) { return STRING_JOINER.join(RoleType.MODIFY_NAMESPACE, appId, ConfigConsts.NAMESPACE_APPLICATION); } @@ -78,6 +82,10 @@ public static String buildReleaseNamespaceRoleName(String appId, String namespac return STRING_JOINER.join(RoleType.RELEASE_NAMESPACE, appId, namespaceName, env); } + public static String buildReleaseNamespacesInClusterRoleName(String appId, String env, String clusterName) { + return STRING_JOINER.join(RoleType.RELEASE_NAMESPACES_IN_CLUSTER, appId, env, clusterName); + } + public static String buildNamespaceRoleName(String appId, String namespaceName, String roleType) { return buildNamespaceRoleName(appId, namespaceName, roleType, null); } @@ -86,6 +94,10 @@ public static String buildNamespaceRoleName(String appId, String namespaceName, return STRING_JOINER.join(roleType, appId, namespaceName, env); } + public static String buildClusterRoleName(String appId, String env, String clusterName, String roleType) { + return STRING_JOINER.join(roleType, appId, env, clusterName); + } + public static String buildReleaseDefaultNamespaceRoleName(String appId) { return STRING_JOINER.join(RoleType.RELEASE_NAMESPACE, appId, ConfigConsts.NAMESPACE_APPLICATION); } @@ -98,6 +110,10 @@ public static String buildNamespaceTargetId(String appId, String namespaceName, return STRING_JOINER.join(appId, namespaceName, env); } + public static String buildClusterTargetId(String appId, String env, String clusterName) { + return STRING_JOINER.join(appId, env, clusterName); + } + public static String buildDefaultNamespaceTargetId(String appId) { return STRING_JOINER.join(appId, ConfigConsts.NAMESPACE_APPLICATION); } diff --git a/apollo-portal/src/main/resources/static/app/manage_cluster.html b/apollo-portal/src/main/resources/static/app/manage_cluster.html new file mode 100644 index 00000000000..d54245667ad --- /dev/null +++ b/apollo-portal/src/main/resources/static/app/manage_cluster.html @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + {{'Config.ManageCluster' | translate }} + + + + + + +
+
+
+
+
+ +
+ +
+
+ +
+ +
+ + +
+
+

{{'Common.Environment' | translate }}: {{env.name}} +

+
+
+
+
+ + {{'Common.Cluster' | translate }}: {{cluster.name}} + +
+ +
+
+
+ +
+
+ +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apollo-portal/src/main/resources/static/cluster/ns_role.html b/apollo-portal/src/main/resources/static/cluster/ns_role.html new file mode 100644 index 00000000000..5ccf4647d8c --- /dev/null +++ b/apollo-portal/src/main/resources/static/cluster/ns_role.html @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + {{'Cluster.Role.Title' | translate }} + + + + + + +
+
+
+
+
+ +
+ +
+
+
+
+
+
+ +
+
+
+ +
+ +
+ +
+
+ + +
+
+
+
+
+
+ +
+
+
+ +
+
+
+
+ +
+ +
+ +
+
+ + +
+
+
+
+ +
+ +
+ + +
+
+

{{'Cluster.Role.NoPermission' | translate }}

+
+ +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apollo-portal/src/main/resources/static/config.html b/apollo-portal/src/main/resources/static/config.html index cc47fc0c6da..6a15f60f385 100644 --- a/apollo-portal/src/main/resources/static/config.html +++ b/apollo-portal/src/main/resources/static/config.html @@ -140,6 +140,10 @@ apollo-img-src="'accesskey-manage'" apollo-href="'app/access_key.html?#/appid=' + pageContext.appId"> + +

{{'Config.CreateAppMissEnv' | translate }}

@@ -187,10 +191,6 @@
-

- {{'Config.CurrentlyOperatorEnv' | translate }}:{{pageContext.env}}, - {{'Common.Cluster' | translate }}:{{pageContext.clusterName}} -