You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dolphinscheduler.apache.org by ca...@apache.org on 2022/04/20 10:23:34 UTC
[dolphinscheduler] branch dev updated: [Feature][Task] K8s namespace auth manager (#9303)
This is an automated email from the ASF dual-hosted git repository.
caishunfeng pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/dolphinscheduler.git
The following commit(s) were added to refs/heads/dev by this push:
new 165d7aa51f [Feature][Task] K8s namespace auth manager (#9303)
165d7aa51f is described below
commit 165d7aa51f1be5aba86752b27067ec9888582acf
Author: qianli2022 <97...@users.noreply.github.com>
AuthorDate: Wed Apr 20 18:23:23 2022 +0800
[Feature][Task] K8s namespace auth manager (#9303)
* k8s auth
* remove log
* fix test
* use constants
* use constants K8S_LOCAL_TEST_CLUSTER
* simple auth get
* change test
* add namespace authorize in user page
* prettier code
* change test data
Co-authored-by: qianl4 <qi...@cicso.com>
Co-authored-by: William Tong <we...@cisco.com>
---
.../api/controller/K8sNamespaceController.java | 91 +++++++++---
.../api/controller/UsersController.java | 26 ++++
.../apache/dolphinscheduler/api/enums/Status.java | 6 +-
...eSpaceService.java => K8sNamespaceService.java} | 39 ++++-
.../dolphinscheduler/api/service/UsersService.java | 11 ++
...rviceImpl.java => K8SNamespaceServiceImpl.java} | 155 +++++++++++++++----
.../api/service/impl/UsersServiceImpl.java | 53 +++++++
.../api/controller/K8sNamespaceControllerTest.java | 45 +++++-
...rviceTest.java => K8SNamespaceServiceTest.java} | 80 +++++++---
.../api/service/UsersServiceTest.java | 21 +++
.../apache/dolphinscheduler/common/Constants.java | 1 +
.../dolphinscheduler/dao/entity/K8sNamespace.java | 92 +++++++++---
.../dao/entity/K8sNamespaceUser.java | 164 +++++++++++++++++++++
.../dao/mapper/K8sNamespaceMapper.java | 26 ++++
...paceMapper.java => K8sNamespaceUserMapper.java} | 99 +++++++------
.../dao/mapper/K8sNamespaceMapper.xml | 33 ++++-
...espaceMapper.xml => K8sNamespaceUserMapper.xml} | 88 +++++------
.../src/main/resources/sql/dolphinscheduler_h2.sql | 31 +++-
.../main/resources/sql/dolphinscheduler_mysql.sql | 17 ++-
.../resources/sql/dolphinscheduler_postgresql.sql | 19 ++-
.../2.1.0_schema/mysql/dolphinscheduler_ddl.sql | 19 ++-
.../postgresql/dolphinscheduler_ddl.sql | 16 +-
.../src/locales/modules/en_US.ts | 2 +
.../src/locales/modules/zh_CN.ts | 2 +
.../src/service/modules/k8s-namespace/index.ts | 17 +++
.../src/service/modules/users/index.ts | 9 ++
.../src/service/modules/users/types.ts | 5 +
.../user-manage/components/authorize-modal.tsx | 9 ++
.../user-manage/components/use-authorize.ts | 37 ++++-
.../src/views/security/user-manage/types.ts | 1 +
.../src/views/security/user-manage/use-columns.ts | 6 +-
.../pages/namespace/_source/createNamespace.vue | 23 +--
.../security/pages/namespace/_source/list.vue | 2 -
.../pages/security/pages/users/_source/list.vue | 52 ++++++-
.../src/js/module/components/transfer/transfer.vue | 2 +
.../src/js/module/i18n/locale/en_US.js | 7 +-
.../src/js/module/i18n/locale/zh_CN.js | 3 +-
37 files changed, 1074 insertions(+), 235 deletions(-)
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/K8sNamespaceController.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/K8sNamespaceController.java
index ddae560d67..ac2e29534d 100644
--- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/K8sNamespaceController.java
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/K8sNamespaceController.java
@@ -19,18 +19,23 @@ package org.apache.dolphinscheduler.api.controller;
import static org.apache.dolphinscheduler.api.enums.Status.CREATE_K8S_NAMESPACE_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.DELETE_K8S_NAMESPACE_BY_ID_ERROR;
+import static org.apache.dolphinscheduler.api.enums.Status.QUERY_AUTHORIZED_NAMESPACE_ERROR;
+import static org.apache.dolphinscheduler.api.enums.Status.QUERY_CAN_USE_K8S_CLUSTER_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.QUERY_K8S_NAMESPACE_LIST_PAGING_ERROR;
+import static org.apache.dolphinscheduler.api.enums.Status.QUERY_UNAUTHORIZED_NAMESPACE_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.UPDATE_K8S_NAMESPACE_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.VERIFY_K8S_NAMESPACE_ERROR;
import org.apache.dolphinscheduler.api.aspect.AccessLogAnnotation;
import org.apache.dolphinscheduler.api.exceptions.ApiException;
-import org.apache.dolphinscheduler.api.service.K8sNameSpaceService;
+import org.apache.dolphinscheduler.api.service.K8sNamespaceService;
import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.Constants;
import org.apache.dolphinscheduler.common.utils.ParameterUtils;
+import org.apache.dolphinscheduler.dao.entity.K8sNamespace;
import org.apache.dolphinscheduler.dao.entity.User;
+import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
@@ -60,7 +65,7 @@ import springfox.documentation.annotations.ApiIgnore;
public class K8sNamespaceController extends BaseController {
@Autowired
- private K8sNameSpaceService k8sNameSpaceService;
+ private K8sNamespaceService k8sNamespaceService;
/**
* query namespace list paging
@@ -92,7 +97,7 @@ public class K8sNamespaceController extends BaseController {
return result;
}
searchVal = ParameterUtils.handleEscapes(searchVal);
- result = k8sNameSpaceService.queryListPaging(loginUser, searchVal, pageNo, pageSize);
+ result = k8sNamespaceService.queryListPaging(loginUser, searchVal, pageNo, pageSize);
return result;
}
@@ -102,8 +107,6 @@ public class K8sNamespaceController extends BaseController {
*
* @param loginUser
* @param namespace k8s namespace
- * @param owner owner
- * @param tag Which type of job is available, can be empty, all available
* @param k8s k8s name
* @param limitsCpu max cpu
* @param limitsMemory max memory
@@ -112,8 +115,6 @@ public class K8sNamespaceController extends BaseController {
@ApiOperation(value = "createK8sNamespace", notes = "CREATE_NAMESPACE_NOTES")
@ApiImplicitParams({
@ApiImplicitParam(name = "namespace", value = "NAMESPACE", required = true, dataType = "String"),
- @ApiImplicitParam(name = "owner", value = "OWNER", required = false, dataType = "String"),
- @ApiImplicitParam(name = "tag", value = "TAG", required = false, dataType = "String"),
@ApiImplicitParam(name = "k8s", value = "K8S", required = true, dataType = "String"),
@ApiImplicitParam(name = "limits_cpu", value = "LIMITS_CPU", required = false, dataType = "Double"),
@ApiImplicitParam(name = "limits_memory", value = "LIMITS_MEMORY", required = false, dataType = "Integer")
@@ -125,12 +126,10 @@ public class K8sNamespaceController extends BaseController {
public Result createNamespace(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
@RequestParam(value = "namespace") String namespace,
@RequestParam(value = "k8s") String k8s,
- @RequestParam(value = "owner", required = false) String owner,
- @RequestParam(value = "tag", required = false) String tag,
@RequestParam(value = "limitsCpu", required = false) Double limitsCpu,
@RequestParam(value = "limitsMemory", required = false) Integer limitsMemory
) {
- Map<String, Object> result = k8sNameSpaceService.createK8sNamespace(loginUser, namespace, k8s, owner, tag, limitsCpu, limitsMemory);
+ Map<String, Object> result = k8sNamespaceService.createK8sNamespace(loginUser, namespace, k8s, limitsCpu, limitsMemory);
return returnDataList(result);
}
@@ -138,8 +137,7 @@ public class K8sNamespaceController extends BaseController {
* update namespace,namespace and k8s not allowed update, because may create on k8s,can delete and create new instead
*
* @param loginUser
- * @param owner owner
- * @param tag Which type of job is available,such as flink,means only flink job can use, can be empty, all available
+ * @param userName owner
* @param limitsCpu max cpu
* @param limitsMemory max memory
* @return
@@ -147,8 +145,7 @@ public class K8sNamespaceController extends BaseController {
@ApiOperation(value = "updateK8sNamespace", notes = "UPDATE_NAMESPACE_NOTES")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "K8S_NAMESPACE_ID", required = true, dataType = "Int", example = "100"),
- @ApiImplicitParam(name = "owner", value = "OWNER", required = false, dataType = "String"),
- @ApiImplicitParam(name = "tag", value = "TAG", required = false, dataType = "String"),
+ @ApiImplicitParam(name = "userName", value = "OWNER", required = false, dataType = "String"),
@ApiImplicitParam(name = "limitsCpu", value = "LIMITS_CPU", required = false, dataType = "Double"),
@ApiImplicitParam(name = "limitsMemory", value = "LIMITS_MEMORY", required = false, dataType = "Integer")})
@PutMapping(value = "/{id}")
@@ -157,11 +154,11 @@ public class K8sNamespaceController extends BaseController {
@AccessLogAnnotation(ignoreRequestArgs = "loginUser")
public Result updateNamespace(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
@PathVariable(value = "id") int id,
- @RequestParam(value = "owner", required = false) String owner,
+ @RequestParam(value = "userName", required = false) String userName,
@RequestParam(value = "tag", required = false) String tag,
@RequestParam(value = "limitsCpu", required = false) Double limitsCpu,
@RequestParam(value = "limitsMemory", required = false) Integer limitsMemory) {
- Map<String, Object> result = k8sNameSpaceService.updateK8sNamespace(loginUser, id, owner, tag, limitsCpu, limitsMemory);
+ Map<String, Object> result = k8sNamespaceService.updateK8sNamespace(loginUser, id, userName, limitsCpu, limitsMemory);
return returnDataList(result);
}
@@ -187,7 +184,7 @@ public class K8sNamespaceController extends BaseController {
@RequestParam(value = "k8s") String k8s
) {
- return k8sNameSpaceService.verifyNamespaceK8s(namespace, k8s);
+ return k8sNamespaceService.verifyNamespaceK8s(namespace, k8s);
}
@@ -208,7 +205,65 @@ public class K8sNamespaceController extends BaseController {
@AccessLogAnnotation
public Result delNamespaceById(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
@RequestParam(value = "id") int id) {
- Map<String, Object> result = k8sNameSpaceService.deleteNamespaceById(loginUser, id);
+ Map<String, Object> result = k8sNamespaceService.deleteNamespaceById(loginUser, id);
+ return returnDataList(result);
+ }
+
+ /**
+ * query unauthorized namespace
+ *
+ * @param loginUser login user
+ * @param userId user id
+ * @return the namespaces which user have not permission to see
+ */
+ @ApiOperation(value = "queryUnauthorizedNamespace", notes = "QUERY_UNAUTHORIZED_NAMESPACE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "userId", value = "USER_ID", dataType = "Int", example = "100")
+ })
+ @GetMapping(value = "/unauth-namespace")
+ @ResponseStatus(HttpStatus.OK)
+ @ApiException(QUERY_UNAUTHORIZED_NAMESPACE_ERROR)
+ @AccessLogAnnotation(ignoreRequestArgs = "loginUser")
+ public Result queryUnauthorizedNamespace(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam("userId") Integer userId) {
+ Map<String, Object> result = k8sNamespaceService.queryUnauthorizedNamespace(loginUser, userId);
return returnDataList(result);
}
+
+ /**
+ * query unauthorized namespace
+ *
+ * @param loginUser login user
+ * @param userId user id
+ * @return namespaces which the user have permission to see
+ */
+ @ApiOperation(value = "queryAuthorizedNamespace", notes = "QUERY_AUTHORIZED_NAMESPACE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "userId", value = "USER_ID", dataType = "Int", example = "100")
+ })
+ @GetMapping(value = "/authed-namespace")
+ @ResponseStatus(HttpStatus.OK)
+ @ApiException(QUERY_AUTHORIZED_NAMESPACE_ERROR)
+ @AccessLogAnnotation(ignoreRequestArgs = "loginUser")
+ public Result queryAuthorizedNamespace(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam("userId") Integer userId) {
+ Map<String, Object> result = k8sNamespaceService.queryAuthorizedNamespace(loginUser, userId);
+ return returnDataList(result);
+ }
+
+ /**
+ * query namespace available
+ *
+ * @param loginUser login user
+ * @return namespace list
+ */
+ @ApiOperation(value = "queryAvailableNamespaceList", notes = "QUERY_AVAILABLE_NAMESPACE_LIST_NOTES")
+ @GetMapping(value = "/available-list")
+ @ResponseStatus(HttpStatus.OK)
+ @ApiException(QUERY_CAN_USE_K8S_CLUSTER_ERROR)
+ @AccessLogAnnotation(ignoreRequestArgs = "loginUser")
+ public Result queryAvailableNamespaceList(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser) {
+ List<K8sNamespace> result = k8sNamespaceService.queryNamespaceAvailable(loginUser);
+ return success(result);
+ }
}
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/UsersController.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/UsersController.java
index 313958b22b..81f0041db0 100644
--- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/UsersController.java
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/UsersController.java
@@ -22,6 +22,7 @@ import static org.apache.dolphinscheduler.api.enums.Status.CREATE_USER_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.DELETE_USER_BY_ID_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.GET_USER_INFO_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.GRANT_DATASOURCE_ERROR;
+import static org.apache.dolphinscheduler.api.enums.Status.GRANT_K8S_NAMESPACE_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.GRANT_PROJECT_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.GRANT_RESOURCE_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.GRANT_UDF_FUNCTION_ERROR;
@@ -334,6 +335,31 @@ public class UsersController extends BaseController {
}
+ /**
+ * grant namespace
+ *
+ * @param loginUser login user
+ * @param userId user id
+ * @param namespaceIds namespace id array
+ * @return grant result code
+ */
+ @ApiOperation(value = "grantNamespace", notes = "GRANT_NAMESPACE_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "userId", value = "USER_ID", required = true, dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "namespaceIds", value = "NAMESPACE_IDS", required = true, type = "String")
+ })
+ @PostMapping(value = "/grant-namespace")
+ @ResponseStatus(HttpStatus.OK)
+ @ApiException(GRANT_K8S_NAMESPACE_ERROR)
+ @AccessLogAnnotation
+ public Result grantNamespace(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "userId") int userId,
+ @RequestParam(value = "namespaceIds") String namespaceIds) {
+ Map<String, Object> result = usersService.grantNamespaces(loginUser, userId, namespaceIds);
+ return returnDataList(result);
+ }
+
+
/**
* grant datasource
*
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.java
index 4954adf431..ff844ad96d 100644
--- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.java
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.java
@@ -394,7 +394,11 @@ public enum Status {
VERIFY_K8S_NAMESPACE_ERROR(1300007, "verify k8s and namespace error", "验证k8s命名空间信息错误"),
DELETE_K8S_NAMESPACE_BY_ID_ERROR(1300008, "delete k8s namespace by id error", "删除命名空间错误"),
VERIFY_PARAMETER_NAME_FAILED(1300009, "The file name verify failed", "文件命名校验失败"),
- STORE_OPERATE_CREATE_ERROR(1300010, "create the resource failed", "存储操作失败");
+ STORE_OPERATE_CREATE_ERROR(1300010, "create the resource failed", "存储操作失败"),
+ GRANT_K8S_NAMESPACE_ERROR(1300011, "grant namespace error", "授权资源错误"),
+ QUERY_UNAUTHORIZED_NAMESPACE_ERROR(1300012, "query unauthorized namespace error", "查询未授权命名空间错误"),
+ QUERY_AUTHORIZED_NAMESPACE_ERROR(1300013, "query authorized namespace error", "查询授权命名空间错误"),
+ QUERY_CAN_USE_K8S_CLUSTER_ERROR(1300014, "login user query can used k8s cluster list error", "查询可用k8s集群错误");
private final int code;
private final String enMsg;
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/K8sNameSpaceService.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/K8sNamespaceService.java
similarity index 71%
rename from dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/K8sNameSpaceService.java
rename to dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/K8sNamespaceService.java
index c9156a38f3..d56c8ab537 100644
--- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/K8sNameSpaceService.java
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/K8sNamespaceService.java
@@ -18,14 +18,16 @@
package org.apache.dolphinscheduler.api.service;
import org.apache.dolphinscheduler.api.utils.Result;
+import org.apache.dolphinscheduler.dao.entity.K8sNamespace;
import org.apache.dolphinscheduler.dao.entity.User;
+import java.util.List;
import java.util.Map;
/**
* k8s namespace service impl
*/
-public interface K8sNameSpaceService {
+public interface K8sNamespaceService {
/**
* query namespace list paging
*
@@ -44,26 +46,23 @@ public interface K8sNameSpaceService {
* @param loginUser login user
* @param namespace namespace
* @param k8s k8s not null
- * @param owner owner can null
- * @param tag can null,if set means just used for one type job,such as flink,spark
* @param limitsCpu limits cpu, can null means not limit
* @param limitsMemory limits memory, can null means not limit
* @return
*/
- Map<String, Object> createK8sNamespace(User loginUser, String namespace, String k8s, String owner, String tag, Double limitsCpu, Integer limitsMemory);
+ Map<String, Object> createK8sNamespace(User loginUser, String namespace, String k8s, Double limitsCpu, Integer limitsMemory);
/**
* update K8s Namespace tag and resource limit
*
* @param loginUser login user
- * @param owner owner
- * @param tag Which type of job is available,such as flink,means only flink job can use, can be empty, all available
+ * @param userName owner
* @param limitsCpu max cpu
* @param limitsMemory max memory
* @return
*/
- Map<String, Object> updateK8sNamespace(User loginUser, int id, String owner, String tag, Double limitsCpu, Integer limitsMemory);
+ Map<String, Object> updateK8sNamespace(User loginUser, int id, String userName, Double limitsCpu, Integer limitsMemory);
/**
* verify namespace and k8s
@@ -82,4 +81,30 @@ public interface K8sNameSpaceService {
* @return
*/
Map<String, Object> deleteNamespaceById(User loginUser, int id);
+
+ /**
+ * query unauthorized namespace
+ *
+ * @param loginUser login user
+ * @param userId user id
+ * @return the namespaces which user have not permission to see
+ */
+ Map<String, Object> queryUnauthorizedNamespace(User loginUser, Integer userId);
+
+ /**
+ * query unauthorized namespace
+ *
+ * @param loginUser login user
+ * @param userId user id
+ * @return namespaces which the user have permission to see
+ */
+ Map<String, Object> queryAuthorizedNamespace(User loginUser, Integer userId);
+
+ /**
+ * query namespace can use
+ *
+ * @param loginUser login user
+ * @return namespace list
+ */
+ List<K8sNamespace> queryNamespaceAvailable(User loginUser);
}
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/UsersService.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/UsersService.java
index 3ae4c689b1..4a2afe547f 100644
--- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/UsersService.java
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/UsersService.java
@@ -194,6 +194,17 @@ public interface UsersService {
Map<String, Object> grantUDFFunction(User loginUser, int userId, String udfIds);
+ /**
+ * grant namespace
+ *
+ * @param loginUser login user
+ * @param userId user id
+ * @param namespaceIds namespace id array
+ * @return grant result code
+ */
+ Map<String, Object> grantNamespaces(User loginUser, int userId, String namespaceIds);
+
+
/**
* grant datasource
*
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/K8sNameSpaceServiceImpl.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/K8SNamespaceServiceImpl.java
similarity index 66%
rename from dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/K8sNameSpaceServiceImpl.java
rename to dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/K8SNamespaceServiceImpl.java
index faa8a24cb3..f6e393f6ab 100644
--- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/K8sNameSpaceServiceImpl.java
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/K8SNamespaceServiceImpl.java
@@ -18,7 +18,7 @@
package org.apache.dolphinscheduler.api.service.impl;
import org.apache.dolphinscheduler.api.enums.Status;
-import org.apache.dolphinscheduler.api.service.K8sNameSpaceService;
+import org.apache.dolphinscheduler.api.service.K8sNamespaceService;
import org.apache.dolphinscheduler.api.utils.PageInfo;
import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.Constants;
@@ -29,15 +29,20 @@ import org.apache.dolphinscheduler.service.k8s.K8sClientService;
import org.apache.commons.lang.StringUtils;
+import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -45,9 +50,9 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
* k8s namespace service impl
*/
@Service
-public class K8sNameSpaceServiceImpl extends BaseServiceImpl implements K8sNameSpaceService {
+public class K8SNamespaceServiceImpl extends BaseServiceImpl implements K8sNamespaceService {
- private static final Logger logger = LoggerFactory.getLogger(K8sNameSpaceServiceImpl.class);
+ private static final Logger logger = LoggerFactory.getLogger(K8SNamespaceServiceImpl.class);
private static String resourceYaml = "apiVersion: v1\n"
+ "kind: ResourceQuota\n"
@@ -100,14 +105,12 @@ public class K8sNameSpaceServiceImpl extends BaseServiceImpl implements K8sNameS
* @param loginUser login user
* @param namespace namespace
* @param k8s k8s not null
- * @param owner owner can null
- * @param tag can null,if set means just used for one type job,such as flink,spark
* @param limitsCpu limits cpu, can null means not limit
* @param limitsMemory limits memory, can null means not limit
* @return
*/
@Override
- public Map<String, Object> createK8sNamespace(User loginUser, String namespace, String k8s, String owner, String tag, Double limitsCpu, Integer limitsMemory) {
+ public Map<String, Object> createK8sNamespace(User loginUser, String namespace, String k8s, Double limitsCpu, Integer limitsMemory) {
Map<String, Object> result = new HashMap<>();
if (isNotAdmin(loginUser, result)) {
return result;
@@ -143,8 +146,7 @@ public class K8sNameSpaceServiceImpl extends BaseServiceImpl implements K8sNameS
k8sNamespaceObj.setNamespace(namespace);
k8sNamespaceObj.setK8s(k8s);
- k8sNamespaceObj.setOwner(owner);
- k8sNamespaceObj.setTag(tag);
+ k8sNamespaceObj.setUserId(loginUser.getId());
k8sNamespaceObj.setLimitsCpu(limitsCpu);
k8sNamespaceObj.setLimitsMemory(limitsMemory);
k8sNamespaceObj.setOnlineJobNum(0);
@@ -154,13 +156,15 @@ public class K8sNameSpaceServiceImpl extends BaseServiceImpl implements K8sNameS
k8sNamespaceObj.setCreateTime(now);
k8sNamespaceObj.setUpdateTime(now);
- try {
- String yamlStr = genDefaultResourceYaml(k8sNamespaceObj);
- k8sClientService.upsertNamespaceAndResourceToK8s(k8sNamespaceObj, yamlStr);
- } catch (Exception e) {
- logger.error("namespace create to k8s error", e);
- putMsg(result, Status.K8S_CLIENT_OPS_ERROR, e.getMessage());
- return result;
+ if (!Constants.K8S_LOCAL_TEST_CLUSTER.equals(k8sNamespaceObj.getK8s())) {
+ try {
+ String yamlStr = genDefaultResourceYaml(k8sNamespaceObj);
+ k8sClientService.upsertNamespaceAndResourceToK8s(k8sNamespaceObj, yamlStr);
+ } catch (Exception e) {
+ logger.error("namespace create to k8s error", e);
+ putMsg(result, Status.K8S_CLIENT_OPS_ERROR, e.getMessage());
+ return result;
+ }
}
k8sNamespaceMapper.insert(k8sNamespaceObj);
@@ -173,14 +177,13 @@ public class K8sNameSpaceServiceImpl extends BaseServiceImpl implements K8sNameS
* update K8s Namespace tag and resource limit
*
* @param loginUser login user
- * @param owner owner
- * @param tag Which type of job is available,such as flink,means only flink job can use, can be empty, all available
+ * @param userName owner
* @param limitsCpu max cpu
* @param limitsMemory max memory
* @return
*/
@Override
- public Map<String, Object> updateK8sNamespace(User loginUser, int id, String owner, String tag, Double limitsCpu, Integer limitsMemory) {
+ public Map<String, Object> updateK8sNamespace(User loginUser, int id, String userName, Double limitsCpu, Integer limitsMemory) {
Map<String, Object> result = new HashMap<>();
if (isNotAdmin(loginUser, result)) {
return result;
@@ -203,18 +206,19 @@ public class K8sNameSpaceServiceImpl extends BaseServiceImpl implements K8sNameS
}
Date now = new Date();
- k8sNamespaceObj.setTag(tag);
k8sNamespaceObj.setLimitsCpu(limitsCpu);
k8sNamespaceObj.setLimitsMemory(limitsMemory);
k8sNamespaceObj.setUpdateTime(now);
- k8sNamespaceObj.setOwner(owner);
- try {
- String yamlStr = genDefaultResourceYaml(k8sNamespaceObj);
- k8sClientService.upsertNamespaceAndResourceToK8s(k8sNamespaceObj, yamlStr);
- } catch (Exception e) {
- logger.error("namespace update to k8s error", e);
- putMsg(result, Status.K8S_CLIENT_OPS_ERROR, e.getMessage());
- return result;
+
+ if (!Constants.K8S_LOCAL_TEST_CLUSTER.equals(k8sNamespaceObj.getK8s())) {
+ try {
+ String yamlStr = genDefaultResourceYaml(k8sNamespaceObj);
+ k8sClientService.upsertNamespaceAndResourceToK8s(k8sNamespaceObj, yamlStr);
+ } catch (Exception e) {
+ logger.error("namespace update to k8s error", e);
+ putMsg(result, Status.K8S_CLIENT_OPS_ERROR, e.getMessage());
+ return result;
+ }
}
// update to db
k8sNamespaceMapper.updateById(k8sNamespaceObj);
@@ -271,8 +275,9 @@ public class K8sNameSpaceServiceImpl extends BaseServiceImpl implements K8sNameS
putMsg(result, Status.K8S_NAMESPACE_NOT_EXIST, id);
return result;
}
-
- k8sClientService.deleteNamespaceToK8s(k8sNamespaceObj.getNamespace(), k8sNamespaceObj.getK8s());
+ if (!Constants.K8S_LOCAL_TEST_CLUSTER.equals(k8sNamespaceObj.getK8s())) {
+ k8sClientService.deleteNamespaceToK8s(k8sNamespaceObj.getNamespace(), k8sNamespaceObj.getK8s());
+ }
k8sNamespaceMapper.deleteById(id);
putMsg(result, Status.SUCCESS);
return result;
@@ -323,4 +328,96 @@ public class K8sNameSpaceServiceImpl extends BaseServiceImpl implements K8sNameS
}
return result;
}
+
+
+ /**
+ * query unauthorized namespace
+ *
+ * @param loginUser login user
+ * @param userId user id
+ * @return the namespaces which user have not permission to see
+ */
+ @Override
+ public Map<String, Object> queryUnauthorizedNamespace(User loginUser, Integer userId) {
+ Map<String, Object> result = new HashMap<>();
+ if (loginUser.getId() != userId && isNotAdmin(loginUser, result)) {
+ return result;
+ }
+ // query all namespace list,this auth does not like project
+ List<K8sNamespace> namespaceList = k8sNamespaceMapper.selectList(null);
+ List<K8sNamespace> resultList = new ArrayList<>();
+ Set<K8sNamespace> namespaceSet;
+ if (namespaceList != null && !namespaceList.isEmpty()) {
+ namespaceSet = new HashSet<>(namespaceList);
+ List<K8sNamespace> authedProjectList = k8sNamespaceMapper.queryAuthedNamespaceListByUserId(userId);
+ resultList = getUnauthorizedNamespaces(namespaceSet, authedProjectList);
+ }
+ result.put(Constants.DATA_LIST, resultList);
+ putMsg(result, Status.SUCCESS);
+ return result;
+ }
+
+ /**
+ * query authorized namespace
+ *
+ * @param loginUser login user
+ * @param userId user id
+ * @return namespaces which the user have permission to see
+ */
+ @Override
+ public Map<String, Object> queryAuthorizedNamespace(User loginUser, Integer userId) {
+ Map<String, Object> result = new HashMap<>();
+
+ if (loginUser.getId() != userId && isNotAdmin(loginUser, result)) {
+ return result;
+ }
+
+ List<K8sNamespace> namespaces = k8sNamespaceMapper.queryAuthedNamespaceListByUserId(userId);
+ result.put(Constants.DATA_LIST, namespaces);
+ putMsg(result, Status.SUCCESS);
+
+ return result;
+ }
+
+ /**
+ * query namespace can use
+ *
+ * @param loginUser login user
+ * @return namespace list
+ */
+ @Override
+ public List<K8sNamespace> queryNamespaceAvailable(User loginUser) {
+ if (isAdmin(loginUser)) {
+ return k8sNamespaceMapper.selectList(null);
+ } else {
+ return k8sNamespaceMapper.queryNamespaceAvailable(loginUser.getId());
+ }
+ }
+
+ /**
+ * get unauthorized namespace
+ *
+ * @param namespaceSet namespace set
+ * @param authedNamespaceList authed namespace list
+ * @return namespace list that authorization
+ */
+ private List<K8sNamespace> getUnauthorizedNamespaces(Set<K8sNamespace> namespaceSet, List<K8sNamespace> authedNamespaceList) {
+ List<K8sNamespace> resultList = new ArrayList<>();
+ for (K8sNamespace k8sNamespace : namespaceSet) {
+ boolean existAuth = false;
+ if (authedNamespaceList != null && !authedNamespaceList.isEmpty()) {
+ for (K8sNamespace k8sNamespaceAuth : authedNamespaceList) {
+ if (k8sNamespace.equals(k8sNamespaceAuth)) {
+ existAuth = true;
+ }
+ }
+ }
+
+ if (!existAuth) {
+ resultList.add(k8sNamespace);
+ }
+ }
+ return resultList;
+ }
+
}
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/UsersServiceImpl.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/UsersServiceImpl.java
index f83ffbfba7..ac6b38adcc 100644
--- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/UsersServiceImpl.java
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/UsersServiceImpl.java
@@ -36,6 +36,7 @@ import org.apache.dolphinscheduler.common.utils.EncryptionUtils;
import org.apache.dolphinscheduler.common.utils.PropertyUtils;
import org.apache.dolphinscheduler.dao.entity.AlertGroup;
import org.apache.dolphinscheduler.dao.entity.DatasourceUser;
+import org.apache.dolphinscheduler.dao.entity.K8sNamespaceUser;
import org.apache.dolphinscheduler.dao.entity.Project;
import org.apache.dolphinscheduler.dao.entity.ProjectUser;
import org.apache.dolphinscheduler.dao.entity.Resource;
@@ -46,6 +47,7 @@ import org.apache.dolphinscheduler.dao.entity.User;
import org.apache.dolphinscheduler.dao.mapper.AccessTokenMapper;
import org.apache.dolphinscheduler.dao.mapper.AlertGroupMapper;
import org.apache.dolphinscheduler.dao.mapper.DataSourceUserMapper;
+import org.apache.dolphinscheduler.dao.mapper.K8sNamespaceUserMapper;
import org.apache.dolphinscheduler.dao.mapper.ProcessDefinitionMapper;
import org.apache.dolphinscheduler.dao.mapper.ProjectMapper;
import org.apache.dolphinscheduler.dao.mapper.ProjectUserMapper;
@@ -117,6 +119,9 @@ public class UsersServiceImpl extends BaseServiceImpl implements UsersService {
@Autowired(required = false)
private StorageOperate storageOperate;
+ @Autowired
+ private K8sNamespaceUserMapper k8sNamespaceUserMapper;
+
/**
* create user, only system admin have permission
*
@@ -798,6 +803,54 @@ public class UsersServiceImpl extends BaseServiceImpl implements UsersService {
return result;
}
+
+ /**
+ * grant namespace
+ *
+ * @param loginUser login user
+ * @param userId user id
+ * @param namespaceIds namespace id array
+ * @return grant result code
+ */
+ @Override
+ @Transactional(rollbackFor = RuntimeException.class)
+ public Map<String, Object> grantNamespaces(User loginUser, int userId, String namespaceIds) {
+ Map<String, Object> result = new HashMap<>();
+ result.put(Constants.STATUS, false);
+
+ //only admin can operate
+ if (check(result, !isAdmin(loginUser), Status.USER_NO_OPERATION_PERM)) {
+ return result;
+ }
+
+ //check exist
+ User tempUser = userMapper.selectById(userId);
+ if (tempUser == null) {
+ putMsg(result, Status.USER_NOT_EXIST, userId);
+ return result;
+ }
+
+ k8sNamespaceUserMapper.deleteNamespaceRelation(0, userId);
+ if (StringUtils.isNotEmpty(namespaceIds)) {
+ String[] namespaceIdArr = namespaceIds.split(",");
+ for (String namespaceId : namespaceIdArr) {
+ Date now = new Date();
+ K8sNamespaceUser namespaceUser = new K8sNamespaceUser();
+ namespaceUser.setUserId(userId);
+ namespaceUser.setNamespaceId(Integer.parseInt(namespaceId));
+ namespaceUser.setPerm(7);
+ namespaceUser.setCreateTime(now);
+ namespaceUser.setUpdateTime(now);
+ k8sNamespaceUserMapper.insert(namespaceUser);
+ }
+ }
+
+ putMsg(result, Status.SUCCESS);
+
+ return result;
+ }
+
+
/**
* grant datasource
*
diff --git a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/K8sNamespaceControllerTest.java b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/K8sNamespaceControllerTest.java
index 830943ba0d..d265ebb118 100644
--- a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/K8sNamespaceControllerTest.java
+++ b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/K8sNamespaceControllerTest.java
@@ -28,8 +28,12 @@ import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.utils.JSONUtils;
import org.apache.dolphinscheduler.dao.entity.User;
+import java.util.HashMap;
+import java.util.Map;
+
import org.junit.Assert;
import org.junit.Test;
+import org.mockito.Mockito;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
@@ -96,7 +100,7 @@ public class K8sNamespaceControllerTest extends AbstractControllerTest {
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
- Assert.assertEquals(Status.K8S_CLIENT_OPS_ERROR.getCode(), result.getCode().intValue());
+ Assert.assertEquals(Status.SUCCESS.getCode(), result.getCode().intValue());
logger.info("update queue return result:{}", mvcResult.getResponse().getContentAsString());
}
@@ -137,7 +141,7 @@ public class K8sNamespaceControllerTest extends AbstractControllerTest {
}
@Test
- public void delNamespaceById() throws Exception {
+ public void deleteNamespaceById() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("id", "1");
@@ -149,7 +153,42 @@ public class K8sNamespaceControllerTest extends AbstractControllerTest {
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
- Assert.assertEquals(Status.DELETE_K8S_NAMESPACE_BY_ID_ERROR.getCode(), result.getCode().intValue());//there is no k8s cluster in test env
+ Assert.assertEquals(Status.SUCCESS.getCode(), result.getCode().intValue());//there is no k8s cluster in test env
+ logger.info(mvcResult.getResponse().getContentAsString());
+ }
+
+ @Test
+ public void testQueryUnauthorizedNamespace() throws Exception {
+
+ MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
+ paramsMap.add("userId", "1");
+
+ MvcResult mvcResult = mockMvc.perform(get("/k8s-namespace/unauth-namespace")
+ .header(SESSION_ID, sessionId)
+ .params(paramsMap))
+ .andExpect(status().isOk())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON))
+ .andReturn();
+
+ Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
+ Assert.assertEquals(Status.SUCCESS.getCode(), result.getCode().intValue());
+ logger.info(mvcResult.getResponse().getContentAsString());
+ }
+
+ @Test
+ public void testQueryAuthorizedNamespace() throws Exception {
+ MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
+ paramsMap.add("userId", "1");
+
+ MvcResult mvcResult = mockMvc.perform(get("/k8s-namespace/authed-namespace")
+ .header(SESSION_ID, sessionId)
+ .params(paramsMap))
+ .andExpect(status().isOk())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON))
+ .andReturn();
+
+ Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
+ Assert.assertEquals(Status.SUCCESS.getCode(), result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
}
\ No newline at end of file
diff --git a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/K8sNameSpaceServiceTest.java b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/K8SNamespaceServiceTest.java
similarity index 64%
rename from dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/K8sNameSpaceServiceTest.java
rename to dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/K8SNamespaceServiceTest.java
index 26735565d1..3ab626c5a0 100644
--- a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/K8sNameSpaceServiceTest.java
+++ b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/K8SNamespaceServiceTest.java
@@ -18,7 +18,7 @@
package org.apache.dolphinscheduler.api.service;
import org.apache.dolphinscheduler.api.enums.Status;
-import org.apache.dolphinscheduler.api.service.impl.K8sNameSpaceServiceImpl;
+import org.apache.dolphinscheduler.api.service.impl.K8SNamespaceServiceImpl;
import org.apache.dolphinscheduler.api.utils.PageInfo;
import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.Constants;
@@ -51,12 +51,12 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@RunWith(MockitoJUnitRunner.class)
-public class K8sNameSpaceServiceTest {
+public class K8SNamespaceServiceTest {
- private static final Logger logger = LoggerFactory.getLogger(K8sNameSpaceServiceTest.class);
+ private static final Logger logger = LoggerFactory.getLogger(K8SNamespaceServiceTest.class);
@InjectMocks
- private K8sNameSpaceServiceImpl k8sNameSpaceService;
+ private K8SNamespaceServiceImpl k8sNamespaceService;
@Mock
private K8sNamespaceMapper k8sNamespaceMapper;
@@ -86,7 +86,7 @@ public class K8sNameSpaceServiceTest {
page.setTotal(1L);
page.setRecords(getNamespaceList());
Mockito.when(k8sNamespaceMapper.queryK8sNamespacePaging(Mockito.any(Page.class), Mockito.eq(namespace))).thenReturn(page);
- Result result = k8sNameSpaceService.queryListPaging(getLoginUser(), namespace, 1, 10);
+ Result result = k8sNamespaceService.queryListPaging(getLoginUser(), namespace, 1, 10);
logger.info(result.toString());
PageInfo<K8sNamespace> pageInfo = (PageInfo<K8sNamespace>) result.getData();
Assert.assertTrue(CollectionUtils.isNotEmpty(pageInfo.getTotalList()));
@@ -95,19 +95,19 @@ public class K8sNameSpaceServiceTest {
@Test
public void createK8sNamespace() {
// namespace is null
- Map<String, Object> result = k8sNameSpaceService.createK8sNamespace(getLoginUser(), null, k8s, null, "tag", 10.0, 100);
+ Map<String, Object> result = k8sNamespaceService.createK8sNamespace(getLoginUser(), null, k8s, 10.0, 100);
logger.info(result.toString());
Assert.assertEquals(Status.REQUEST_PARAMS_NOT_VALID_ERROR, result.get(Constants.STATUS));
// k8s is null
- result = k8sNameSpaceService.createK8sNamespace(getLoginUser(), namespace, null, null, "tag", 10.0, 100);
+ result = k8sNamespaceService.createK8sNamespace(getLoginUser(), namespace, null, 10.0, 100);
logger.info(result.toString());
Assert.assertEquals(Status.REQUEST_PARAMS_NOT_VALID_ERROR, result.get(Constants.STATUS));
// correct
- result = k8sNameSpaceService.createK8sNamespace(getLoginUser(), namespace, k8s, null, "tag", 10.0, 100);
+ result = k8sNamespaceService.createK8sNamespace(getLoginUser(), namespace, k8s, 10.0, 100);
logger.info(result.toString());
Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS));
//null limit cpu and mem
- result = k8sNameSpaceService.createK8sNamespace(getLoginUser(), namespace, k8s, null, "tag", null, null);
+ result = k8sNamespaceService.createK8sNamespace(getLoginUser(), namespace, k8s, null, null);
logger.info(result.toString());
Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS));
}
@@ -116,15 +116,15 @@ public class K8sNameSpaceServiceTest {
public void updateK8sNamespace() {
Mockito.when(k8sNamespaceMapper.selectById(1)).thenReturn(getNamespace());
- Map<String, Object> result = k8sNameSpaceService.updateK8sNamespace(getLoginUser(), 1, null, "tag", null, null);
+ Map<String, Object> result = k8sNamespaceService.updateK8sNamespace(getLoginUser(), 1, null, null, null);
logger.info(result.toString());
Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS));
- result = k8sNameSpaceService.updateK8sNamespace(getLoginUser(), 1, null, "tag", -1.0, 100);
+ result = k8sNamespaceService.updateK8sNamespace(getLoginUser(), 1, null, -1.0, 100);
logger.info(result.toString());
Assert.assertEquals(Status.REQUEST_PARAMS_NOT_VALID_ERROR, result.get(Constants.STATUS));
- result = k8sNameSpaceService.updateK8sNamespace(getLoginUser(), 1, null, "tag", 1.0, 100);
+ result = k8sNamespaceService.updateK8sNamespace(getLoginUser(), 1, null, 1.0, 100);
logger.info(result.toString());
Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS));
}
@@ -135,22 +135,22 @@ public class K8sNameSpaceServiceTest {
Mockito.when(k8sNamespaceMapper.existNamespace(namespace, k8s)).thenReturn(true);
//namespace null
- Result result = k8sNameSpaceService.verifyNamespaceK8s(null, k8s);
+ Result result = k8sNamespaceService.verifyNamespaceK8s(null, k8s);
logger.info(result.toString());
Assert.assertEquals(result.getCode().intValue(), Status.REQUEST_PARAMS_NOT_VALID_ERROR.getCode());
//k8s null
- result = k8sNameSpaceService.verifyNamespaceK8s(namespace, null);
+ result = k8sNamespaceService.verifyNamespaceK8s(namespace, null);
logger.info(result.toString());
Assert.assertEquals(result.getCode().intValue(), Status.REQUEST_PARAMS_NOT_VALID_ERROR.getCode());
//exist
- result = k8sNameSpaceService.verifyNamespaceK8s(namespace, k8s);
+ result = k8sNamespaceService.verifyNamespaceK8s(namespace, k8s);
logger.info(result.toString());
Assert.assertEquals(result.getCode().intValue(), Status.K8S_NAMESPACE_EXIST.getCode());
//not exist
- result = k8sNameSpaceService.verifyNamespaceK8s(namespace, "other k8s");
+ result = k8sNamespaceService.verifyNamespaceK8s(namespace, "other k8s");
logger.info(result.toString());
Assert.assertEquals(result.getCode().intValue(), Status.SUCCESS.getCode());
}
@@ -160,11 +160,57 @@ public class K8sNameSpaceServiceTest {
Mockito.when(k8sNamespaceMapper.deleteById(Mockito.any())).thenReturn(1);
Mockito.when(k8sNamespaceMapper.selectById(1)).thenReturn(getNamespace());
- Map<String, Object> result = k8sNameSpaceService.deleteNamespaceById(getLoginUser(), 1);
+ Map<String, Object> result = k8sNamespaceService.deleteNamespaceById(getLoginUser(), 1);
logger.info(result.toString());
Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS));
}
+ @Test
+ public void testQueryAuthorizedNamespace() {
+ Mockito.when(k8sNamespaceMapper.queryAuthedNamespaceListByUserId(2)).thenReturn(getNamespaceList());
+
+ User loginUser = getLoginUser();
+
+ // test admin user
+ loginUser.setUserType(UserType.ADMIN_USER);
+ Map<String, Object> result = k8sNamespaceService.queryAuthorizedNamespace(loginUser, 2);
+ logger.info(result.toString());
+ List<K8sNamespace> namespaces = (List<K8sNamespace>) result.get(Constants.DATA_LIST);
+ Assert.assertTrue(CollectionUtils.isNotEmpty(namespaces));
+
+ // test non-admin user
+ loginUser.setUserType(UserType.GENERAL_USER);
+ loginUser.setId(3);
+ result = k8sNamespaceService.queryAuthorizedNamespace(loginUser, 2);
+ Assert.assertEquals(Status.USER_NO_OPERATION_PERM, result.get(Constants.STATUS));
+ namespaces = (List<K8sNamespace>) result.get(Constants.DATA_LIST);
+ Assert.assertTrue(CollectionUtils.isEmpty(namespaces));
+ }
+
+ @Test
+ public void testQueryUnAuthorizedNamespace() {
+ Mockito.when(k8sNamespaceMapper.queryAuthedNamespaceListByUserId(2)).thenReturn(new ArrayList<>());
+ Mockito.when(k8sNamespaceMapper.selectList(Mockito.any())).thenReturn(getNamespaceList());
+
+ // test admin user
+ User loginUser = new User();
+ loginUser.setUserType(UserType.ADMIN_USER);
+ Map<String, Object> result = k8sNamespaceService.queryUnauthorizedNamespace(loginUser, 2);
+ logger.info(result.toString());
+ List<K8sNamespace> namespaces = (List<K8sNamespace>) result.get(Constants.DATA_LIST);
+ Assert.assertTrue(CollectionUtils.isNotEmpty(namespaces));
+
+ // test non-admin user
+ loginUser.setId(2);
+ loginUser.setUserType(UserType.GENERAL_USER);
+ result = k8sNamespaceService.queryUnauthorizedNamespace(loginUser, 3);
+ logger.info(result.toString());
+ Assert.assertEquals(Status.USER_NO_OPERATION_PERM, result.get(Constants.STATUS));
+ namespaces = (List<K8sNamespace>) result.get(Constants.DATA_LIST);
+ Assert.assertTrue(CollectionUtils.isEmpty(namespaces));
+ }
+
+
private User getLoginUser() {
User loginUser = new User();
diff --git a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/UsersServiceTest.java b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/UsersServiceTest.java
index 596eba4d75..8eaba04c60 100644
--- a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/UsersServiceTest.java
+++ b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/UsersServiceTest.java
@@ -90,6 +90,9 @@ public class UsersServiceTest {
@Mock
private UDFUserMapper udfUserMapper;
+ @Mock
+ private K8sNamespaceUserMapper k8sNamespaceUserMapper;
+
@Mock
private ProjectMapper projectMapper;
@@ -434,6 +437,24 @@ public class UsersServiceTest {
Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS));
}
+ @Test
+ public void testGrantNamespaces() {
+ String namespaceIds = "100000,120000";
+ when(userMapper.selectById(1)).thenReturn(getUser());
+ User loginUser = new User();
+
+ //user not exist
+ loginUser.setUserType(UserType.ADMIN_USER);
+ Map<String, Object> result = usersService.grantNamespaces(loginUser, 2, namespaceIds);
+ logger.info(result.toString());
+ Assert.assertEquals(Status.USER_NOT_EXIST, result.get(Constants.STATUS));
+ //success
+ when(k8sNamespaceUserMapper.deleteNamespaceRelation(0,1)).thenReturn(1);
+ result = usersService.grantNamespaces(loginUser, 1, namespaceIds);
+ logger.info(result.toString());
+ Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS));
+ }
+
@Test
public void testGrantDataSource() {
String datasourceIds = "100000,120000";
diff --git a/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/Constants.java b/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/Constants.java
index 4199627f71..3d87af5ea8 100644
--- a/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/Constants.java
+++ b/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/Constants.java
@@ -816,4 +816,5 @@ public final class Constants {
public static final String K8S = "k8s";
public static final String LIMITS_CPU = "limitsCpu";
public static final String LIMITS_MEMORY = "limitsMemory";
+ public static final String K8S_LOCAL_TEST_CLUSTER = "ds_null_k8s";
}
diff --git a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/K8sNamespace.java b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/K8sNamespace.java
index d22e7bd520..e6864a58bd 100644
--- a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/K8sNamespace.java
+++ b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/K8sNamespace.java
@@ -37,54 +37,66 @@ public class K8sNamespace {
*/
@TableField(value = "namespace")
private String namespace;
+
/**
* total cpu limit
*/
@TableField(value = "limits_cpu")
private Double limitsCpu;
+
/**
* total memory limit,mi
*/
private Integer limitsMemory;
+
/**
* owner
*/
- @TableField(value = "owner")
- private String owner;
+ @TableField(value = "user_id")
+ private int userId;
+
+ /**
+ * user name
+ */
+ @TableField(exist = false)
+ private String userName;
/**
* create_time
*/
@TableField("create_time")
private Date createTime;
+
/**
* update_time
*/
@TableField("update_time")
private Date updateTime;
+
/**
- * tag use for set this namespace allow run which type
+ * 1.00 = 1 cpu
*/
- @TableField("tag")
- private String tag;
-
@TableField("pod_request_cpu")
private Double podRequestCpu = 0.0;
+
/**
* Mi
*/
@TableField("pod_request_memory")
private Integer podRequestMemory = 0;
+
/**
- *
+ * replicas
*/
@TableField("pod_replicas")
private Integer podReplicas = 0;
+
/**
* online job
*/
@TableField("online_job_num")
private Integer onlineJobNum = 0;
+
/**
* k8s name
*/
@@ -123,12 +135,12 @@ public class K8sNamespace {
this.limitsMemory = limitsMemory;
}
- public String getOwner() {
- return owner;
+ public int getUserId() {
+ return userId;
}
- public void setOwner(String owner) {
- this.owner = owner;
+ public void setUserId(int userId) {
+ this.userId = userId;
}
public Date getCreateTime() {
@@ -147,14 +159,6 @@ public class K8sNamespace {
this.updateTime = updateTime;
}
- public String getTag() {
- return tag;
- }
-
- public void setTag(String tag) {
- this.tag = tag;
- }
-
public Integer getPodRequestMemory() {
return podRequestMemory;
}
@@ -194,4 +198,54 @@ public class K8sNamespace {
public void setPodRequestCpu(Double podRequestCpu) {
this.podRequestCpu = podRequestCpu;
}
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ @Override
+ public String toString() {
+ return "K8sNamespace{" +
+ "id=" + id +
+ ", namespace=" + namespace +
+ ", limitsCpu=" + limitsCpu +
+ ", limitsMemory=" + limitsMemory +
+ ", userId=" + userId +
+ ", podRequestCpu=" + podRequestCpu +
+ ", podRequestMemory=" + podRequestMemory +
+ ", podReplicas=" + podReplicas +
+ ", k8s=" + k8s +
+ ", createTime=" + createTime +
+ ", updateTime=" + updateTime +
+ '}';
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ K8sNamespace k8sNamespace = (K8sNamespace) o;
+
+ if (id.equals(k8sNamespace.id)) {
+ return true;
+ }
+
+ return namespace.equals(k8sNamespace.namespace) && k8s.equals(k8sNamespace.k8s);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = id;
+ result = 31 * result + (k8s+namespace).hashCode();
+ return result;
+ }
}
diff --git a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/K8sNamespaceUser.java b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/K8sNamespaceUser.java
new file mode 100644
index 0000000000..87a7a3ecc4
--- /dev/null
+++ b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/K8sNamespaceUser.java
@@ -0,0 +1,164 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.dolphinscheduler.dao.entity;
+
+import java.util.Date;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+
+/**
+ * k8s namespace and user relation
+ */
+@TableName("t_ds_relation_namespace_user")
+public class K8sNamespaceUser {
+ /**
+ * id
+ */
+ @TableId(value = "id", type = IdType.AUTO)
+ private int id;
+
+ /**
+ * user id
+ */
+ @TableField("user_id")
+ private int userId;
+
+ /**
+ * namespace id
+ */
+ @TableField("namespace_id")
+ private int namespaceId;
+
+ /**
+ * k8s cluster
+ */
+ @TableField(exist = false)
+ private String k8s;
+
+ /**
+ * namespace name
+ */
+ @TableField(exist = false)
+ private String namespaceName;
+
+ /**
+ * user name
+ */
+ @TableField(exist = false)
+ private String userName;
+
+ /**
+ * permission
+ */
+ private int perm;
+
+ @TableField("create_time")
+ private Date createTime;
+
+ @TableField("update_time")
+ private Date updateTime;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public int getUserId() {
+ return userId;
+ }
+
+ public void setUserId(int userId) {
+ this.userId = userId;
+ }
+
+ public int getNamespaceId() {
+ return namespaceId;
+ }
+
+ public void setNamespaceId(int namespaceId) {
+ this.namespaceId = namespaceId;
+ }
+
+ public String getK8s() {
+ return k8s;
+ }
+
+ public void setK8s(String k8s) {
+ this.k8s = k8s;
+ }
+
+ public String getNamespaceName() {
+ return namespaceName;
+ }
+
+ public void setNamespaceName(String namespaceName) {
+ this.namespaceName = namespaceName;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public int getPerm() {
+ return perm;
+ }
+
+ public void setPerm(int perm) {
+ this.perm = perm;
+ }
+
+ public Date getCreateTime() {
+ return createTime;
+ }
+
+ public void setCreateTime(Date createTime) {
+ this.createTime = createTime;
+ }
+
+ public Date getUpdateTime() {
+ return updateTime;
+ }
+
+ public void setUpdateTime(Date updateTime) {
+ this.updateTime = updateTime;
+ }
+
+ @Override
+ public String toString() {
+ return "K8sNamespaceUser{" +
+ "id=" + id +
+ ", userId=" + userId +
+ ", namespaceId=" + namespaceId +
+ ", k8s=" + k8s +
+ ", namespaceName=" + namespaceName +
+ ", perm=" + perm +
+ ", createTime=" + createTime +
+ ", updateTime=" + updateTime +
+ '}';
+ }
+}
diff --git a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/K8sNamespaceMapper.java b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/K8sNamespaceMapper.java
index e804d55402..e8f80ebf3f 100644
--- a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/K8sNamespaceMapper.java
+++ b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/K8sNamespaceMapper.java
@@ -21,6 +21,8 @@ import org.apache.dolphinscheduler.dao.entity.K8sNamespace;
import org.apache.ibatis.annotations.Param;
+import java.util.List;
+
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -46,4 +48,28 @@ public interface K8sNamespaceMapper extends BaseMapper<K8sNamespace> {
* @return true if exist else return null
*/
Boolean existNamespace(@Param("namespace") String namespace, @Param("k8s") String k8s);
+
+ /**
+ * query namespace except userId
+ *
+ * @param userId userId
+ * @return namespace list
+ */
+ List<K8sNamespace> queryNamespaceExceptUserId(@Param("userId") int userId);
+
+ /**
+ * query authed namespace list by userId
+ *
+ * @param userId userId
+ * @return namespace list
+ */
+ List<K8sNamespace> queryAuthedNamespaceListByUserId(@Param("userId") int userId);
+
+ /**
+ * query namespace can use
+ *
+ * @param userId userId
+ * @return namespace list
+ */
+ List<K8sNamespace> queryNamespaceAvailable(@Param("userId") Integer userId);
}
diff --git a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/K8sNamespaceMapper.java b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/K8sNamespaceUserMapper.java
similarity index 56%
copy from dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/K8sNamespaceMapper.java
copy to dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/K8sNamespaceUserMapper.java
index e804d55402..46723cc41d 100644
--- a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/K8sNamespaceMapper.java
+++ b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/K8sNamespaceUserMapper.java
@@ -1,49 +1,50 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.dolphinscheduler.dao.mapper;
-
-import org.apache.dolphinscheduler.dao.entity.K8sNamespace;
-
-import org.apache.ibatis.annotations.Param;
-
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.baomidou.mybatisplus.core.metadata.IPage;
-
-/**
- * namespace interface
- */
-public interface K8sNamespaceMapper extends BaseMapper<K8sNamespace> {
- /**
- * k8s namespace page
- *
- * @param page page
- * @param searchVal searchVal
- * @return k8s namespace IPage
- */
- IPage<K8sNamespace> queryK8sNamespacePaging(IPage<K8sNamespace> page,
- @Param("searchVal") String searchVal);
-
- /**
- * check the target namespace exist
- *
- * @param namespace namespace
- * @param k8s k8s name
- * @return true if exist else return null
- */
- Boolean existNamespace(@Param("namespace") String namespace, @Param("k8s") String k8s);
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.dolphinscheduler.dao.mapper;
+
+import org.apache.dolphinscheduler.dao.entity.K8sNamespaceUser;
+
+import org.apache.ibatis.annotations.Param;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * namespace user mapper interface
+ */
+public interface K8sNamespaceUserMapper extends BaseMapper<K8sNamespaceUser> {
+
+ /**
+ * delete namespace user relation
+ *
+ * @param namespaceId namespaceId
+ * @param userId userId
+ * @return delete result
+ */
+ int deleteNamespaceRelation(@Param("namespaceId") int namespaceId,
+ @Param("userId") int userId);
+
+ /**
+ * query namespace relation
+ *
+ * @param namespaceId namespaceId
+ * @param userId userId
+ * @return namespace user relation
+ */
+ K8sNamespaceUser queryNamespaceRelation(@Param("namespaceId") int namespaceId,
+ @Param("userId") int userId);
+}
diff --git a/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/K8sNamespaceMapper.xml b/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/K8sNamespaceMapper.xml
index 9099e0c411..ba32fc2b12 100644
--- a/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/K8sNamespaceMapper.xml
+++ b/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/K8sNamespaceMapper.xml
@@ -20,8 +20,13 @@
<mapper namespace="org.apache.dolphinscheduler.dao.mapper.K8sNamespaceMapper">
<sql id="baseSql">
- id, namespace, k8s, owner, tag, limits_memory, limits_cpu, online_job_num, pod_replicas, pod_request_cpu, pod_request_memory, create_time, update_time
+ id, namespace, k8s, user_id, limits_memory, limits_cpu, online_job_num, pod_replicas, pod_request_cpu, pod_request_memory, create_time, update_time
</sql>
+
+ <sql id="baseSqlV2">
+ ${alias}.id, ${alias}.namespace, ${alias}.k8s, ${alias}.user_id, ${alias}.limits_memory, ${alias}.limits_cpu, ${alias}.online_job_num, ${alias}.pod_replicas, ${alias}.pod_request_cpu, ${alias}.pod_request_memory, ${alias}.create_time, ${alias}.update_time
+ </sql>
+
<select id="queryK8sNamespacePaging" resultType="org.apache.dolphinscheduler.dao.entity.K8sNamespace">
select
<include refid="baseSql"/>
@@ -45,4 +50,30 @@
</if>
</select>
+ <select id="queryNamespaceExceptUserId" resultType="org.apache.dolphinscheduler.dao.entity.K8sNamespace">
+ select
+ <include refid="baseSql"/>
+ from t_ds_k8s_namespace
+ where user_id <![CDATA[ <> ]]> #{userId}
+ </select>
+
+ <select id="queryAuthedNamespaceListByUserId" resultType="org.apache.dolphinscheduler.dao.entity.K8sNamespace">
+ select
+ <include refid="baseSqlV2">
+ <property name="alias" value="p"/>
+ </include>
+ from t_ds_k8s_namespace p,t_ds_relation_namespace_user rel
+ where p.id = rel.namespace_id and rel.user_id= #{userId}
+ </select>
+
+ <select id="queryNamespaceAvailable" resultType="org.apache.dolphinscheduler.dao.entity.K8sNamespace">
+ select
+ <include refid="baseSqlV2">
+ <property name="alias" value="b"/>
+ </include>
+ from ( select namespace_id from t_ds_relation_namespace_user where user_id= #{userId} ) a
+ left join t_ds_k8s_namespace b
+ on b.id = a.namespace_id
+ where b.id is not null
+ </select>
</mapper>
diff --git a/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/K8sNamespaceMapper.xml b/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/K8sNamespaceUserMapper.xml
similarity index 51%
copy from dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/K8sNamespaceMapper.xml
copy to dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/K8sNamespaceUserMapper.xml
index 9099e0c411..7e26039b99 100644
--- a/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/K8sNamespaceMapper.xml
+++ b/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/K8sNamespaceUserMapper.xml
@@ -1,48 +1,40 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one or more
- ~ contributor license agreements. See the NOTICE file distributed with
- ~ this work for additional information regarding copyright ownership.
- ~ The ASF licenses this file to You 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.
- -->
-
-<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="org.apache.dolphinscheduler.dao.mapper.K8sNamespaceMapper">
-
- <sql id="baseSql">
- id, namespace, k8s, owner, tag, limits_memory, limits_cpu, online_job_num, pod_replicas, pod_request_cpu, pod_request_memory, create_time, update_time
- </sql>
- <select id="queryK8sNamespacePaging" resultType="org.apache.dolphinscheduler.dao.entity.K8sNamespace">
- select
- <include refid="baseSql"/>
- from t_ds_k8s_namespace
- where 1= 1
- <if test="searchVal != null and searchVal != ''">
- and namespace like concat('%', #{searchVal}, '%')
- </if>
- order by update_time desc
- </select>
-
- <select id="existNamespace" resultType="java.lang.Boolean">
- select 1 = 1
- from t_ds_k8s_namespace
- where 1 = 1
- <if test="namespace != null and namespace != ''">
- and namespace = #{namespace}
- </if>
- <if test="k8s != null and k8s != ''">
- and k8s =#{k8s}
- </if>
- </select>
-
-</mapper>
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You 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.
+ -->
+
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="org.apache.dolphinscheduler.dao.mapper.K8sNamespaceUserMapper">
+ <sql id="baseSql">
+ id, user_id, namespace_id, perm, create_time, update_time
+ </sql>
+ <delete id="deleteNamespaceRelation">
+ delete from t_ds_relation_namespace_user
+ where 1=1
+ and user_id = #{userId}
+ <if test="namespaceId != 0 ">
+ and namespace_id = #{namespaceId}
+ </if>
+ </delete>
+ <select id="queryNamespaceRelation" resultType="org.apache.dolphinscheduler.dao.entity.K8sNamespaceUser">
+ select
+ <include refid="baseSql"/>
+ from t_ds_relation_namespace_user
+ where namespace_id = #{namespaceId}
+ and user_id = #{userId}
+ limit 1
+ </select>
+</mapper>
\ No newline at end of file
diff --git a/dolphinscheduler-dao/src/main/resources/sql/dolphinscheduler_h2.sql b/dolphinscheduler-dao/src/main/resources/sql/dolphinscheduler_h2.sql
index 7fd9dc8256..f6cfae00e0 100644
--- a/dolphinscheduler-dao/src/main/resources/sql/dolphinscheduler_h2.sql
+++ b/dolphinscheduler-dao/src/main/resources/sql/dolphinscheduler_h2.sql
@@ -1898,11 +1898,10 @@ CREATE TABLE t_ds_k8s_namespace (
limits_memory int(11) DEFAULT NULL,
namespace varchar(100) DEFAULT NULL,
online_job_num int(11) DEFAULT NULL,
- owner varchar(100) DEFAULT NULL,
+ user_id int(11) DEFAULT NULL,
pod_replicas int(11) DEFAULT NULL,
pod_request_cpu decimal(14,3) DEFAULT NULL,
pod_request_memory int(11) DEFAULT NULL,
- tag varchar(100) DEFAULT NULL,
limits_cpu decimal(14,3) DEFAULT NULL,
k8s varchar(100) DEFAULT NULL,
create_time datetime DEFAULT NULL ,
@@ -1914,8 +1913,32 @@ CREATE TABLE t_ds_k8s_namespace (
-- ----------------------------
-- Records of t_ds_k8s_namespace
-- ----------------------------
-INSERT INTO t_ds_k8s_namespace
-VALUES (1, 10000, 'default', 99, 'owner',1,NULL,1,'test',NULL,'default',null,null);
+INSERT INTO `t_ds_k8s_namespace`
+(`id`,`limits_memory`,`namespace`,`online_job_num`,`user_id`,`pod_replicas`,`pod_request_cpu`,`pod_request_memory`,`limits_cpu`,`k8s`,`create_time`,`update_time`)
+VALUES (1, 1000, 'flink_test', 99, 1, 1, 0.1, 1, NULL, 'ds_null_k8s', '2022-03-03 11:31:24.0', '2022-03-03 11:31:24.0');
+
+INSERT INTO `t_ds_k8s_namespace`
+(`id`,`limits_memory`,`namespace`,`online_job_num`,`user_id`,`pod_replicas`,`pod_request_cpu`,`pod_request_memory`,`limits_cpu`,`k8s`,`create_time`,`update_time`)
+VALUES (2, 500, 'spark_test', 90, 2,1,10000,1, NULL, 'ds_null_k8s', '2021-03-03 11:31:24.0', '2021-03-03 11:31:24.0');
+
+INSERT INTO `t_ds_k8s_namespace`
+(`id`,`limits_memory`,`namespace`,`online_job_num`,`user_id`,`pod_replicas`,`pod_request_cpu`,`pod_request_memory`,`limits_cpu`,`k8s`,`create_time`,`update_time`)
+VALUES (3, 200, 'auth_test', 68, 3,1,100,1, 10000, 'ds_null_k8s', '2020-03-03 11:31:24.0', '2020-03-03 11:31:24.0');
+
+-- ----------------------------
+-- Table structure for t_ds_relation_namespace_user
+-- ----------------------------
+DROP TABLE IF EXISTS t_ds_relation_namespace_user;
+CREATE TABLE t_ds_relation_namespace_user (
+ id int(11) NOT NULL AUTO_INCREMENT ,
+ user_id int(11) NOT NULL ,
+ namespace_id int(11) NOT NULL ,
+ perm int(11) DEFAULT '1' ,
+ create_time datetime DEFAULT NULL ,
+ update_time datetime DEFAULT NULL ,
+ PRIMARY KEY (id) ,
+ UNIQUE KEY namespace_user_unique (user_id,namespace_id)
+);
-- ----------------------------
-- Table structure for t_ds_alert_send_status
diff --git a/dolphinscheduler-dao/src/main/resources/sql/dolphinscheduler_mysql.sql b/dolphinscheduler-dao/src/main/resources/sql/dolphinscheduler_mysql.sql
index 051ea1d006..197173a1b8 100644
--- a/dolphinscheduler-dao/src/main/resources/sql/dolphinscheduler_mysql.sql
+++ b/dolphinscheduler-dao/src/main/resources/sql/dolphinscheduler_mysql.sql
@@ -1891,11 +1891,10 @@ CREATE TABLE `t_ds_k8s_namespace` (
`limits_memory` int(11) DEFAULT NULL,
`namespace` varchar(100) DEFAULT NULL,
`online_job_num` int(11) DEFAULT NULL,
- `owner` varchar(100) DEFAULT NULL,
+ `user_id` int(11) DEFAULT NULL,
`pod_replicas` int(11) DEFAULT NULL,
`pod_request_cpu` decimal(14,3) DEFAULT NULL,
`pod_request_memory` int(11) DEFAULT NULL,
- `tag` varchar(100) DEFAULT NULL,
`limits_cpu` decimal(14,3) DEFAULT NULL,
`k8s` varchar(100) DEFAULT NULL,
`create_time` datetime DEFAULT NULL COMMENT 'create time',
@@ -1904,6 +1903,20 @@ CREATE TABLE `t_ds_k8s_namespace` (
UNIQUE KEY `k8s_namespace_unique` (`namespace`,`k8s`)
) ENGINE= INNODB AUTO_INCREMENT= 1 DEFAULT CHARSET= utf8;
+-- ----------------------------
+-- Table structure for t_ds_relation_namespace_user
+-- ----------------------------
+DROP TABLE IF EXISTS `t_ds_relation_namespace_user`;
+CREATE TABLE `t_ds_relation_namespace_user` (
+ `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'key',
+ `user_id` int(11) NOT NULL COMMENT 'user id',
+ `namespace_id` int(11) DEFAULT NULL COMMENT 'namespace id',
+ `perm` int(11) DEFAULT '1' COMMENT 'limits of authority',
+ `create_time` datetime DEFAULT NULL COMMENT 'create time',
+ `update_time` datetime DEFAULT NULL COMMENT 'update time',
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `namespace_user_unique` (`user_id`,`namespace_id`)
+) ENGINE=InnoDB AUTO_INCREMENT= 1 DEFAULT CHARSET= utf8;
-- ----------------------------
-- Table structure for t_ds_alert_send_status
diff --git a/dolphinscheduler-dao/src/main/resources/sql/dolphinscheduler_postgresql.sql b/dolphinscheduler-dao/src/main/resources/sql/dolphinscheduler_postgresql.sql
index 9e9c64d089..7e5526976f 100644
--- a/dolphinscheduler-dao/src/main/resources/sql/dolphinscheduler_postgresql.sql
+++ b/dolphinscheduler-dao/src/main/resources/sql/dolphinscheduler_postgresql.sql
@@ -1889,11 +1889,10 @@ CREATE TABLE t_ds_k8s_namespace (
limits_memory int DEFAULT NULL ,
namespace varchar(100) DEFAULT NULL ,
online_job_num int DEFAULT '0' ,
- owner varchar(100) DEFAULT NULL,
+ user_id int DEFAULT NULL,
pod_replicas int DEFAULT NULL,
pod_request_cpu NUMERIC(13,4) NULL,
pod_request_memory int DEFAULT NULL,
- tag varchar(100) DEFAULT NULL,
limits_cpu NUMERIC(13,4) NULL,
k8s varchar(100) DEFAULT NULL,
create_time timestamp DEFAULT NULL ,
@@ -1902,6 +1901,22 @@ CREATE TABLE t_ds_k8s_namespace (
CONSTRAINT k8s_namespace_unique UNIQUE (namespace,k8s)
);
+--
+-- Table structure for table t_ds_relation_namespace_user
+--
+
+DROP TABLE IF EXISTS t_ds_relation_namespace_user;
+CREATE TABLE t_ds_relation_namespace_user (
+ id serial NOT NULL,
+ user_id int DEFAULT NULL ,
+ namespace_id int DEFAULT NULL ,
+ perm int DEFAULT NULL ,
+ create_time timestamp DEFAULT NULL ,
+ update_time timestamp DEFAULT NULL ,
+ PRIMARY KEY (id) ,
+ CONSTRAINT namespace_user_unique UNIQUE (user_id,namespace_id)
+);
+
-- ----------------------------
-- Table structure for t_ds_alert_send_status
-- ----------------------------
diff --git a/dolphinscheduler-dao/src/main/resources/sql/upgrade/2.1.0_schema/mysql/dolphinscheduler_ddl.sql b/dolphinscheduler-dao/src/main/resources/sql/upgrade/2.1.0_schema/mysql/dolphinscheduler_ddl.sql
index ac08027dd6..4f0dacaf9d 100644
--- a/dolphinscheduler-dao/src/main/resources/sql/upgrade/2.1.0_schema/mysql/dolphinscheduler_ddl.sql
+++ b/dolphinscheduler-dao/src/main/resources/sql/upgrade/2.1.0_schema/mysql/dolphinscheduler_ddl.sql
@@ -199,11 +199,10 @@ CREATE TABLE `t_ds_k8s_namespace` (
`limits_memory` int(11) DEFAULT NULL,
`namespace` varchar(100) DEFAULT NULL,
`online_job_num` int(11) DEFAULT NULL,
- `owner` varchar(100) DEFAULT NULL,
+ `user_id` int(11) DEFAULT NULL,
`pod_replicas` int(11) DEFAULT NULL,
`pod_request_cpu` decimal(14,3) DEFAULT NULL,
`pod_request_memory` int(11) DEFAULT NULL,
- `tag` varchar(100) DEFAULT NULL,
`limits_cpu` decimal(14,3) DEFAULT NULL,
`k8s` varchar(100) DEFAULT NULL,
`create_time` datetime DEFAULT NULL COMMENT 'create time',
@@ -211,3 +210,19 @@ CREATE TABLE `t_ds_k8s_namespace` (
PRIMARY KEY (`id`),
UNIQUE KEY `k8s_namespace_unique` (`namespace`,`k8s`)
) ENGINE= INNODB AUTO_INCREMENT= 1 DEFAULT CHARSET= utf8;
+
+-- ----------------------------
+-- Table structure for t_ds_relation_namespace_user
+-- ----------------------------
+DROP TABLE IF EXISTS `t_ds_relation_namespace_user`;
+CREATE TABLE `t_ds_relation_namespace_user` (
+ `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'key',
+ `user_id` int(11) NOT NULL COMMENT 'user id',
+ `namespace_id` int(11) DEFAULT NULL COMMENT 'namespace id',
+ `perm` int(11) DEFAULT '1' COMMENT 'limits of authority',
+ `create_time` datetime DEFAULT NULL COMMENT 'create time',
+ `update_time` datetime DEFAULT NULL COMMENT 'update time',
+ PRIMARY KEY (`id`),
+ KEY `user_id_index` (`user_id`),
+ UNIQUE KEY `namespace_user_unique` (`user_id`,`namespace_id`)
+) ENGINE=InnoDB AUTO_INCREMENT= 1 DEFAULT CHARSET= utf8;
\ No newline at end of file
diff --git a/dolphinscheduler-dao/src/main/resources/sql/upgrade/2.1.0_schema/postgresql/dolphinscheduler_ddl.sql b/dolphinscheduler-dao/src/main/resources/sql/upgrade/2.1.0_schema/postgresql/dolphinscheduler_ddl.sql
index 9e2459f82d..e3d7b8c568 100644
--- a/dolphinscheduler-dao/src/main/resources/sql/upgrade/2.1.0_schema/postgresql/dolphinscheduler_ddl.sql
+++ b/dolphinscheduler-dao/src/main/resources/sql/upgrade/2.1.0_schema/postgresql/dolphinscheduler_ddl.sql
@@ -180,12 +180,11 @@ EXECUTE 'CREATE TABLE IF NOT EXISTS '|| quote_ident(v_schema) ||'."t_ds_k8s_name
id serial NOT NULL,
limits_memory int DEFAULT NULL ,
namespace varchar(100) DEFAULT NULL ,
- online_job_num int DEFAULT ''0'' ,
- owner varchar(100) DEFAULT NULL,
+ online_job_num int DEFAULT NULL,
+ user_id int DEFAULT NULL,
pod_replicas int DEFAULT NULL,
pod_request_cpu NUMERIC(13,4) NULL,
pod_request_memory int DEFAULT NULL,
- tag varchar(100) DEFAULT NULL,
limits_cpu NUMERIC(13,4) NULL,
k8s varchar(100) DEFAULT NULL,
create_time timestamp DEFAULT NULL ,
@@ -194,6 +193,17 @@ EXECUTE 'CREATE TABLE IF NOT EXISTS '|| quote_ident(v_schema) ||'."t_ds_k8s_name
CONSTRAINT k8s_namespace_unique UNIQUE (namespace,k8s)
)';
+EXECUTE 'CREATE TABLE IF NOT EXISTS '|| quote_ident(v_schema) ||'."t_ds_relation_namespace_user" (
+ id serial NOT NULL,
+ user_id int DEFAULT NULL ,
+ namespace_id int DEFAULT NULL ,
+ perm int DEFAULT NULL ,
+ create_time timestamp DEFAULT NULL ,
+ update_time timestamp DEFAULT NULL ,
+ PRIMARY KEY (id) ,
+ CONSTRAINT namespace_user_unique UNIQUE (user_id,namespace_id)
+)';
+
return 'Success!';
exception when others then
---Raise EXCEPTION '(%)',SQLERRM;
diff --git a/dolphinscheduler-ui-next/src/locales/modules/en_US.ts b/dolphinscheduler-ui-next/src/locales/modules/en_US.ts
index 1f00751a79..c785a70170 100644
--- a/dolphinscheduler-ui-next/src/locales/modules/en_US.ts
+++ b/dolphinscheduler-ui-next/src/locales/modules/en_US.ts
@@ -1045,8 +1045,10 @@ const security = {
udf_resource: 'UDF Resource',
datasource: 'Datasource',
udf: 'UDF Function',
+ namespace: 'Namespace',
authorize_project: 'Project Authorize',
authorize_resource: 'Resource Authorize',
+ authorize_namespace: 'Namespace Authorize',
authorize_datasource: 'Datasource Authorize',
authorize_udf: 'UDF Function Authorize',
username: 'Username',
diff --git a/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts b/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts
index e590d67524..c8a3d47aa7 100644
--- a/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts
+++ b/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts
@@ -1032,8 +1032,10 @@ const security = {
udf_resource: 'UDF资源',
datasource: '数据源',
udf: 'UDF函数',
+ namespace: '命名空间',
authorize_project: '项目授权',
authorize_resource: '资源授权',
+ authorize_namespace: '命名空间授权',
authorize_datasource: '数据源授权',
authorize_udf: 'UDF函数授权',
username: '用户名',
diff --git a/dolphinscheduler-ui-next/src/service/modules/k8s-namespace/index.ts b/dolphinscheduler-ui-next/src/service/modules/k8s-namespace/index.ts
index 69aaae9684..2df1d5f703 100644
--- a/dolphinscheduler-ui-next/src/service/modules/k8s-namespace/index.ts
+++ b/dolphinscheduler-ui-next/src/service/modules/k8s-namespace/index.ts
@@ -17,6 +17,7 @@
import { axios } from '@/service/service'
import { ListReq, K8SReq } from './types'
+import { UserIdReq } from '@/service/modules/resources/types'
export function queryNamespaceListPaging(params: ListReq): any {
return axios({
@@ -60,3 +61,19 @@ export function delNamespaceById(id: number): any {
params: { id }
})
}
+
+export function authNamespaceFunc(params: UserIdReq): any {
+ return axios({
+ url: '/k8s-namespace/authed-namespace',
+ method: 'get',
+ params
+ })
+}
+
+export function unAuthNamespaceFunc(params: UserIdReq): any {
+ return axios({
+ url: '/k8s-namespace/unauth-namespace',
+ method: 'get',
+ params
+ })
+}
diff --git a/dolphinscheduler-ui-next/src/service/modules/users/index.ts b/dolphinscheduler-ui-next/src/service/modules/users/index.ts
index bd42f40a65..9a1313cbfb 100644
--- a/dolphinscheduler-ui-next/src/service/modules/users/index.ts
+++ b/dolphinscheduler-ui-next/src/service/modules/users/index.ts
@@ -28,6 +28,7 @@ import {
GrantProject,
ProjectCodeReq,
GrantUDFReq,
+ GrantNamespaceReq,
ListAllReq,
ListReq,
RegisterUserReq
@@ -120,6 +121,14 @@ export function grantUDFFunc(data: GrantUDFReq & UserIdReq) {
})
}
+export function grantNamespaceFunc(data: GrantNamespaceReq & UserIdReq) {
+ return axios({
+ url: '/users/grant-namespace',
+ method: 'post',
+ data
+ })
+}
+
export function listUser(): any {
return axios({
url: '/users/list',
diff --git a/dolphinscheduler-ui-next/src/service/modules/users/types.ts b/dolphinscheduler-ui-next/src/service/modules/users/types.ts
index 3768d22b14..a49370560c 100644
--- a/dolphinscheduler-ui-next/src/service/modules/users/types.ts
+++ b/dolphinscheduler-ui-next/src/service/modules/users/types.ts
@@ -66,6 +66,10 @@ interface GrantUDFReq {
udfIds: string
}
+interface GrantNamespaceReq {
+ namespaceIds: string
+}
+
interface ListAllReq extends UserReq {
alertGroup?: string
createTime?: string
@@ -127,6 +131,7 @@ export {
GrantProject,
ProjectCodeReq,
GrantUDFReq,
+ GrantNamespaceReq,
ListAllReq,
ListReq,
RegisterUserReq,
diff --git a/dolphinscheduler-ui-next/src/views/security/user-manage/components/authorize-modal.tsx b/dolphinscheduler-ui-next/src/views/security/user-manage/components/authorize-modal.tsx
index 0118299f40..bce9c567c6 100644
--- a/dolphinscheduler-ui-next/src/views/security/user-manage/components/authorize-modal.tsx
+++ b/dolphinscheduler-ui-next/src/views/security/user-manage/components/authorize-modal.tsx
@@ -151,6 +151,15 @@ export const AuthorizeModal = defineComponent({
/>
</NSpace>
)}
+ {type === 'authorize_namespace' && (
+ <NTransfer
+ virtualScroll
+ options={this.unauthorizedNamespaces}
+ filterable
+ v-model:value={this.authorizedNamespaces}
+ class={styles.transfer}
+ />
+ )}
</Modal>
)
}
diff --git a/dolphinscheduler-ui-next/src/views/security/user-manage/components/use-authorize.ts b/dolphinscheduler-ui-next/src/views/security/user-manage/components/use-authorize.ts
index f12b6a3219..819a7a444f 100644
--- a/dolphinscheduler-ui-next/src/views/security/user-manage/components/use-authorize.ts
+++ b/dolphinscheduler-ui-next/src/views/security/user-manage/components/use-authorize.ts
@@ -29,11 +29,16 @@ import {
authUDFFunc,
unAuthUDFFunc
} from '@/service/modules/resources'
+import {
+ authNamespaceFunc,
+ unAuthNamespaceFunc
+} from '@/service/modules/k8s-namespace'
import {
grantProject,
grantResource,
grantDataSource,
- grantUDFFunc
+ grantUDFFunc,
+ grantNamespaceFunc
} from '@/service/modules/users'
import { removeUselessChildren } from '@/utils/tree-format'
import type { TAuthType, IResourceOption, IOption } from '../types'
@@ -48,6 +53,8 @@ export function useAuthorize() {
unauthorizedDatasources: [] as IOption[],
authorizedUdfs: [] as number[],
unauthorizedUdfs: [] as IOption[],
+ authorizedNamespaces: [] as number[],
+ unauthorizedNamespaces: [] as IOption[],
resourceType: 'file',
fileResources: [] as IResourceOption[],
udfResources: [] as IResourceOption[],
@@ -139,6 +146,25 @@ export function useAuthorize() {
state.authorizedUdfResources = udfTargets
}
+ const getNamespaces = async (userId: number) => {
+ if (state.loading) return
+ state.loading = true
+ const namespaces = await Promise.all([
+ authNamespaceFunc({ userId }),
+ unAuthNamespaceFunc({ userId })
+ ])
+ state.loading = false
+ state.authorizedNamespaces = namespaces[0].map(
+ (item: { id: number }) => item.id
+ )
+ state.unauthorizedNamespaces = [...namespaces[0], ...namespaces[1]].map(
+ (item: { namespace: string; id: number }) => ({
+ label: item.namespace,
+ value: item.id
+ })
+ )
+ }
+
const onInit = (type: TAuthType, userId: number) => {
if (type === 'authorize_project') {
getProjects(userId)
@@ -152,6 +178,9 @@ export function useAuthorize() {
if (type === 'authorize_resource') {
getResources(userId)
}
+ if (type === 'authorize_namespace') {
+ getNamespaces(userId)
+ }
}
/*
@@ -242,6 +271,12 @@ export function useAuthorize() {
resourceIds: allPathId.join(',')
})
}
+ if (type === 'authorize_namespace') {
+ await grantNamespaceFunc({
+ userId,
+ namespaceIds: state.authorizedNamespaces.join(',')
+ })
+ }
state.saving = false
return true
}
diff --git a/dolphinscheduler-ui-next/src/views/security/user-manage/types.ts b/dolphinscheduler-ui-next/src/views/security/user-manage/types.ts
index ac8c1fc8a6..8c98d222fa 100644
--- a/dolphinscheduler-ui-next/src/views/security/user-manage/types.ts
+++ b/dolphinscheduler-ui-next/src/views/security/user-manage/types.ts
@@ -27,6 +27,7 @@ type TAuthType =
| 'authorize_resource'
| 'authorize_datasource'
| 'authorize_udf'
+ | 'authorize_namespace'
interface IRecord {
id: number
diff --git a/dolphinscheduler-ui-next/src/views/security/user-manage/use-columns.ts b/dolphinscheduler-ui-next/src/views/security/user-manage/use-columns.ts
index 288b2b6343..f0af7aec9c 100644
--- a/dolphinscheduler-ui-next/src/views/security/user-manage/use-columns.ts
+++ b/dolphinscheduler-ui-next/src/views/security/user-manage/use-columns.ts
@@ -137,7 +137,11 @@ export function useColumns(onCallback: Function) {
label: t('security.user.datasource'),
key: 'authorize_datasource'
},
- { label: t('security.user.udf'), key: 'authorize_udf' }
+ { label: t('security.user.udf'), key: 'authorize_udf' },
+ {
+ label: t('security.user.namespace'),
+ key: 'authorize_namespace'
+ }
],
onSelect: (key) =>
void onCallback({ rowData, key }, 'authorize')
diff --git a/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/namespace/_source/createNamespace.vue b/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/namespace/_source/createNamespace.vue
index 3d0903e85d..42e2459307 100644
--- a/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/namespace/_source/createNamespace.vue
+++ b/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/namespace/_source/createNamespace.vue
@@ -48,18 +48,6 @@
</el-input>
</template>
</m-list-box-f>
- <m-list-box-f>
- <template slot="name">{{$t('K8s Tag')}}</template>
- <template slot="content">
- <el-input
- type="input"
- v-model="tag"
- maxlength="60"
- size="mini"
- :placeholder="$t('Please enter k8s cluster')">
- </el-input>
- </template>
- </m-list-box-f>
<m-list-box-f>
<template slot="name">{{$t('Limits Cpu')}}</template>
@@ -90,7 +78,7 @@
<template slot="content">
<el-input
type="input"
- v-model="owner"
+ v-model="userName"
maxlength="60"
size="mini"
:placeholder="$t('Please enter owner')">
@@ -116,8 +104,7 @@
store,
namespace: '',
k8s: '',
- owner: '',
- tag: '',
+ userName: '',
limitsCpu: '',
limitsMemory: ''
}
@@ -134,8 +121,7 @@
let param = {
namespace: _.trim(this.namespace),
k8s: _.trim(this.k8s),
- owner: _.trim(this.owner),
- tag: _.trim(this.tag),
+ userName: _.trim(this.userName),
limitsCpu: _.trim(this.limitsCpu),
limitsMemory: _.trim(this.limitsMemory)
}
@@ -205,8 +191,7 @@
if (this.item) {
this.namespace = this.item.namespace
this.k8s = this.item.k8s
- this.owner = this.item.owner
- this.tag = this.item.tag
+ this.userName = this.item.userName
this.limitsCpu = this.item.limitsCpu
this.limitsMemory = this.item.limitsMemory
}
diff --git a/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/namespace/_source/list.vue b/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/namespace/_source/list.vue
index 73153b8851..ee4e571b7c 100644
--- a/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/namespace/_source/list.vue
+++ b/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/namespace/_source/list.vue
@@ -21,8 +21,6 @@
<el-table-column type="index" :label="$t('#')" width="50"></el-table-column>
<el-table-column prop="namespace" :label="$t('K8s Namespace')"></el-table-column>
<el-table-column prop="k8s" :label="$t('K8s Cluster')"></el-table-column>
- <el-table-column prop="owner" :label="$t('Namespace Owner')"></el-table-column>
- <el-table-column prop="tag" :label="$t('K8s Tag')"></el-table-column>
<el-table-column prop="limitsCpu" :label="$t('Limits Cpu')"></el-table-column>
<el-table-column prop="limitsMemory" :label="$t('Limits Memory')"></el-table-column>
diff --git a/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/users/_source/list.vue b/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/users/_source/list.vue
index 212060bb7b..4978a27289 100644
--- a/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/users/_source/list.vue
+++ b/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/users/_source/list.vue
@@ -58,6 +58,7 @@
<el-dropdown-item @click.native="_authFile(scope.row,scope.$index)">{{$t('Resources')}}</el-dropdown-item>
<el-dropdown-item @click.native="_authDataSource(scope.row,scope.$index)">{{$t('Datasource')}}</el-dropdown-item>
<el-dropdown-item @click.native="_authUdfFunc(scope.row,scope.$index)">{{$t('UDF Function')}}</el-dropdown-item>
+ <el-dropdown-item @click.native="_authNamespace(scope.row,scope.$index)">{{$t('K8s Namespace')}}</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-tooltip>
@@ -107,6 +108,13 @@
width="auto">
<m-resource :resourceData="resourceData" @onUpdateAuthResource="onUpdateAuthResource" @closeAuthResource="closeAuthResource"></m-resource>
</el-dialog>
+
+ <el-dialog
+ v-if="authNamespaceDialog"
+ :visible.sync="authNamespaceDialog"
+ width="auto">
+ <m-transfer :transferData="transferData" @onUpdateAuthNamespace="onUpdateAuthNamespace" @closeAuthNamespace="closeAuthNamespace"></m-transfer>
+ </el-dialog>
</div>
</template>
<script>
@@ -141,7 +149,8 @@
name: ''
}
},
- resourceDialog: false
+ resourceDialog: false,
+ authNamespaceDialog: false
}
},
props: {
@@ -348,6 +357,35 @@
this.$message.error(e.msg || '')
})
},
+
+ _authNamespace (item, i) {
+ this.getAuthList({
+ id: item.id,
+ type: 'namespace',
+ category: 'k8s-namespace'
+ }).then(data => {
+ let sourceListPrs = _.map(data[0], v => {
+ return {
+ id: v.id,
+ name: v.namespace
+ }
+ })
+ let targetListPrs = _.map(data[1], v => {
+ return {
+ id: v.id,
+ name: v.namespace
+ }
+ })
+ this.item = item
+ this.transferData.sourceListPrs = sourceListPrs
+ this.transferData.targetListPrs = targetListPrs
+ this.transferData.type.name = i18n.$t('K8s Namespace')
+ this.authNamespaceDialog = true
+ }).catch(e => {
+ this.$message.error(e.msg || '')
+ })
+ },
+
onUpdateAuthUdfFunc (udfIds) {
this._grantAuthorization('users/grant-udf-func', {
userId: this.item.id,
@@ -360,6 +398,18 @@
this.authUdfFuncDialog = false
},
+ onUpdateAuthNamespace (namespaceIds) {
+ this._grantAuthorization('users/grant-namespace', {
+ userId: this.item.id,
+ namespaceIds: namespaceIds
+ })
+ this.authNamespaceDialog = false
+ },
+
+ closeAuthNamespace () {
+ this.authNamespaceDialog = false
+ },
+
_grantAuthorization (api, param) {
this.grantAuthorization({
api: api,
diff --git a/dolphinscheduler-ui/src/js/module/components/transfer/transfer.vue b/dolphinscheduler-ui/src/js/module/components/transfer/transfer.vue
index 3cb29f77ac..b671b6c5b6 100644
--- a/dolphinscheduler-ui/src/js/module/components/transfer/transfer.vue
+++ b/dolphinscheduler-ui/src/js/module/components/transfer/transfer.vue
@@ -81,6 +81,8 @@
this.$emit('onUpdateAuthDataSource', _.map(this.targetList, v => v.id).join(','))
} else if (this.transferData.type.name === `${i18n.$t('UDF Function')}`) {
this.$emit('onUpdateAuthUdfFunc', _.map(this.targetList, v => v.id).join(','))
+ } else if (this.transferData.type.name === `${i18n.$t('K8s Namespace')}`) {
+ this.$emit('onUpdateAuthNamespace', _.map(this.targetList, v => v.id).join(','))
}
}, 800)
},
diff --git a/dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js b/dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js
index 515d16be07..4c330f6d7f 100755
--- a/dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js
+++ b/dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js
@@ -906,14 +906,13 @@ export default {
'Create namespace': 'Create namespace',
'Edit namespace': 'Edit namespace',
'Namespace manage': 'K8s namespace manage',
- 'K8s Namespace': 'k8s Namespace',
+ 'K8s Namespace': 'K8s Namespace',
'Limits Cpu': 'Limit Cpu',
'Limits Memory': 'Limit Memory',
- 'K8s Cluster': 'k8s',
+ 'K8s Cluster': 'k8s Cluster',
'Namespace Owner': 'Owner',
'Please enter k8s cluster': 'Please enter k8s cluster',
'Please enter namespace': 'Please enter namespace',
'Please enter namespace tag': 'Please enter namespace tag can null',
- 'Please enter owner': 'Please enter owner can null',
- 'K8s Tag': 'tag'
+ 'Please enter owner': 'Please enter owner can null'
}
diff --git a/dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js b/dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js
index fe1fba85db..8fd53fc298 100755
--- a/dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js
+++ b/dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js
@@ -914,6 +914,5 @@ export default {
'Please enter k8s cluster': '请输入k8s集群值',
'Please enter namespace': '请输入命名空间',
'Please enter namespace tag': '请输入命名空间标签可空',
- 'Please enter owner': '请输入owner可空',
- 'K8s Tag': '标签'
+ 'Please enter owner': '请输入owner可空'
}