Browse Source

for merge

马佳君 7 years ago
parent
commit
6d64e11c55

+ 6 - 2
config.yml

@@ -24,7 +24,7 @@ moocoder:
     username: root
     token: 113cb5bd4a6fea342892a08c8d2e07dc68
   docker:
-    nexus: 10.1.1.243:10082
+    nexus: 10.1.1.243:18082
   mail:
     from: noreply@moocoder.cn
   storage:
@@ -39,4 +39,8 @@ moocoder:
     public-mysql-url: jdbc:mysql://mysql.group24.svc.cluster.local:3306
     public-mysql-pod: mysql-7b688cf578-l7pxs
     public-mysql-username: root
-    public-mysql-password: password
+    public-mysql-password: password
+  registry:
+    host: http://10.1.1.243:18082
+    username: admin
+    password: admin123

+ 1 - 1
src/main/java/nju/seec/SEECdemo/logic/api/k8s/NamespaceApi.java

@@ -63,5 +63,5 @@ public interface NamespaceApi {
      * @param name
      * @return
      */
-    boolean exists(String name) throws K8sApiException;
+    boolean exists(String name);
 }

+ 39 - 39
src/main/java/nju/seec/SEECdemo/logic/api/k8s/ResourceQuotaApi.java

@@ -6,43 +6,43 @@ import nju.seec.SEECdemo.logic.api.k8s.vo.ResourceQuota;
 
 public interface ResourceQuotaApi {
 
-//    /**
-//     * 新建资源限额,如果该命名空间下的限额已经存在,则更新限额
-//     * @param resourceQuota
-//     * @return
-//     */
-//    void create(ResourceQuota resourceQuota) throws K8sApiException;
-//
-//    /**
-//     * 更新资源限额
-//     * @param resourceQuota
-//     * @return
-//     */
-//    void update(ResourceQuota resourceQuota) throws K8sApiException;
-//
-//    /**
-//     * 删除namespace下名为name的资源限额
-//     * @param namespace
-//     * @param name
-//     * @return
-//     */
-//    void delete(String namespace, String name) throws K8sApiException;
-//
-//
-//    /**
-//     * 获取namespace下名为name的资源
-//     * @param namespace
-//     * @param name
-//     * @return
-//     * @throws K8sApiException
-//     */
-//    ResourceQuota getByName(String namespace, String name) throws K8sApiException;
-//
-//    /**
-//     * 当前的资源限额是否存在
-//     * @param namespace
-//     * @param name
-//     * @throws K8sApiException
-//     */
-//    boolean exist(String namespace, String name) throws K8sApiException;
+    /**
+     * 新建资源限额,如果该命名空间下的限额已经存在,则更新限额
+     * @param resourceQuota
+     * @return
+     */
+    void create(ResourceQuota resourceQuota) throws K8sApiException;
+
+    /**
+     * 更新资源限额
+     * @param resourceQuota
+     * @return
+     */
+    void update(ResourceQuota resourceQuota) throws K8sApiException;
+
+    /**
+     * 删除namespace下名为name的资源限额
+     * @param namespace
+     * @param name
+     * @return
+     */
+    void delete(String namespace, String name) throws K8sApiException;
+
+
+    /**
+     * 获取namespace下名为name的资源
+     * @param namespace
+     * @param name
+     * @return
+     * @throws K8sApiException
+     */
+    ResourceQuota getByName(String namespace, String name) throws K8sApiException;
+
+    /**
+     * 当前的资源限额是否存在
+     * @param namespace
+     * @param name
+     * @throws K8sApiException
+     */
+    boolean exist(String namespace, String name) throws K8sApiException;
 }

+ 9 - 7
src/main/java/nju/seec/SEECdemo/logic/api/k8s/SecretApi.java

@@ -4,7 +4,9 @@ import com.google.protobuf.Api;
 import io.kubernetes.client.ApiException;
 import io.kubernetes.client.models.V1Secret;
 import nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException;
+import nju.seec.SEECdemo.logic.api.k8s.util.SecretTypeEnum;
 import nju.seec.SEECdemo.logic.api.k8s.vo.ApiResult;
+import nju.seec.SEECdemo.logic.api.k8s.vo.SecretVO;
 
 import javax.xml.transform.Result;
 import java.util.List;
@@ -19,7 +21,7 @@ public interface SecretApi {
      * @param data
      * @return ApiResult
      */
-    V1Secret createGenericSecret(String namespace, String name, Map<String, byte[]> data) throws K8sApiException;
+    SecretVO createGenericSecret(String namespace, String name, Map<String, byte[]> data) throws K8sApiException;
 
     /**
      * 创建通用密钥,自己定义Secret的type,如Service Account、Opaque、kubernetes.io/dockerconfigjson.
@@ -29,7 +31,7 @@ public interface SecretApi {
      * @param type
      * @return ApiResult
      */
-    V1Secret createGenericSecret(String namespace, String name, Map<String, byte[]> data, String type) throws K8sApiException;
+    SecretVO createGenericSecret(String namespace, String name, Map<String, byte[]> data, SecretTypeEnum type) throws K8sApiException;
 
     /**
      * 在namespace下生成私有仓库server的密钥
@@ -39,7 +41,7 @@ public interface SecretApi {
      * @param user
      * @param password
      */
-    V1Secret createPrivateRegistrySecret(String namespace, String server, String user, String password) throws K8sApiException;
+    SecretVO createPrivateRegistrySecret(String namespace, String server, String user, String password) throws K8sApiException;
 
 
     /**
@@ -51,13 +53,13 @@ public interface SecretApi {
      * @param user
      * @param password
      */
-    V1Secret createPrivateRegistrySecret(String namespace, String name, String server, String user, String password) throws K8sApiException;
+    SecretVO createPrivateRegistrySecret(String namespace, String name, String server, String user, String password) throws K8sApiException;
 
     /**
      * 获取指定namespace下的Secret列表
      * @param namespace
      */
-    List<V1Secret> getSecretList(String namespace) throws K8sApiException;
+    List<SecretVO> getSecretList(String namespace) throws K8sApiException;
 
     /**
      * 获取指定namespace下的指定type的Secret列表
@@ -65,7 +67,7 @@ public interface SecretApi {
      * @param namespace
      * @param type
      */
-    List<V1Secret> getSecretListByType(String namespace, String type) throws K8sApiException;
+    List<SecretVO> getSecretListByType(String namespace, SecretTypeEnum type) throws K8sApiException;
 
 
     /**
@@ -74,7 +76,7 @@ public interface SecretApi {
      * @param namespace
      * @param name
      */
-    V1Secret getSecretByName(String namespace, String name) throws K8sApiException;
+    SecretVO getSecretByName(String namespace, String name) throws K8sApiException;
 
     /**
      * 删除指定namespace下指定名字的Secret

+ 4 - 1
src/main/java/nju/seec/SEECdemo/logic/api/k8s/exception/K8sApiException.java

@@ -8,7 +8,7 @@ import java.util.Map;
 
 @Data
 @NoArgsConstructor
-public class K8sApiException extends Exception{
+public class K8sApiException extends RuntimeException{
 
     private int code;
 
@@ -25,6 +25,7 @@ public class K8sApiException extends Exception{
     public static final int INVALID_VALUE = 422;
 
     public static final int NAMESPACE_ALREADY_EXIST = 500;
+    public static final int RESOURCE_QUOTA_ALREADY_EXIST = 501;
 
     public static final int ILLEGAL_PARAMETER = 100;
 
@@ -32,6 +33,7 @@ public class K8sApiException extends Exception{
 
     public static final int COMMAND_FAIL = 300;
 
+
     public static final K8sApiException K8s_SYSTEM_ERROR_EXCEPTION = new K8sApiException(SYSTEM_ERROR);
     //系统故障
     static {
@@ -42,6 +44,7 @@ public class K8sApiException extends Exception{
         codeMap.put(ALREADY_EXIST, "资源已存在");
         codeMap.put(INVALID_VALUE, "参数设置无效");
         codeMap.put(NAMESPACE_ALREADY_EXIST, "命名空间已经存在");
+        codeMap.put(RESOURCE_QUOTA_ALREADY_EXIST, "资源限额已经存在");
 
         codeMap.put(ILLEGAL_PARAMETER, "非法参数");
 

+ 2 - 2
src/main/java/nju/seec/SEECdemo/logic/api/k8s/impl/NamespaceApiImpl.java

@@ -45,7 +45,7 @@ public class NamespaceApiImpl implements NamespaceApi{
         try {
             coreV1Api.createNamespace(v1Namespace, "true");
         } catch (ApiException e) {
-            LoggerUtil.error(logger, e, "Namespace创建失败,namespace={}, v1Namespace={}", namespace, v1Namespace);
+            LoggerUtil.error(logger, e, "Namespace创建失败,namespace={}, v1Namespace={}, response={}", namespace, v1Namespace, e.getResponseBody());
             throw new K8sApiException(K8sApiException.SYSTEM_ERROR);
         }
     }
@@ -155,7 +155,7 @@ public class NamespaceApiImpl implements NamespaceApi{
     }
 
     @Override
-    public boolean exists(String name) throws K8sApiException {
+    public boolean exists(String name) {
         if (StringUtils.isBlank(name)) throw new K8sApiException(K8sApiException.ILLEGAL_PARAMETER, "名称不能为空");
         try {
             V1NamespaceList v1NamespaceList = coreV1Api.listNamespace(PRETTY_FORMAT,

+ 158 - 205
src/main/java/nju/seec/SEECdemo/logic/api/k8s/impl/ResourceQuotaImpl.java

@@ -2,211 +2,164 @@ package nju.seec.SEECdemo.logic.api.k8s.impl;
 
 import nju.seec.SEECdemo.logic.api.k8s.ResourceQuotaApi;
 
-//
-//import io.kubernetes.client.ApiException;
-//import io.kubernetes.client.apis.CoreV1Api;
-//import io.kubernetes.client.models.V1DeleteOptions;
-//import io.kubernetes.client.models.V1DeleteOptionsBuilder;
-//import io.kubernetes.client.models.V1ResourceQuotaList;
-//import nju.seec.SEECdemo.logic.api.k8s.NamespaceApi;
-//import nju.seec.SEECdemo.logic.api.k8s.ResourceQuotaApi;
-//import nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException;
-//import nju.seec.SEECdemo.logic.api.k8s.vo.ApiResult;
-//import nju.seec.SEECdemo.logic.api.k8s.vo.Namespace;
-//import nju.seec.SEECdemo.logic.api.k8s.vo.ResourceQuota;
-//import nju.seec.SEECdemo.util.LoggerUtil;
-//import org.slf4j.Logger;
-//import org.springframework.beans.factory.annotation.Autowired;
-//import org.springframework.stereotype.Service;
-//import org.springframework.util.CollectionUtils;
-//
-//
-//import java.awt.*;
-//import java.util.List;
-//import java.util.stream.Collectors;
-//
-//import static nju.seec.SEECdemo.util.Constants.FOREGROUND_PROPAGATION_POLICY;
-//import static nju.seec.SEECdemo.util.Constants.PRETTY_FORMAT;
-//
-//@Service
+
+import io.kubernetes.client.ApiException;
+import io.kubernetes.client.apis.CoreV1Api;
+import io.kubernetes.client.models.V1DeleteOptions;
+import io.kubernetes.client.models.V1DeleteOptionsBuilder;
+import io.kubernetes.client.models.V1ResourceQuotaList;
+import nju.seec.SEECdemo.logic.api.k8s.NamespaceApi;
+import nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException;
+import nju.seec.SEECdemo.logic.api.k8s.vo.ResourceQuota;
+import nju.seec.SEECdemo.util.LoggerUtil;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+
+import static nju.seec.SEECdemo.util.Constants.FOREGROUND_PROPAGATION_POLICY;
+import static nju.seec.SEECdemo.util.Constants.PRETTY_FORMAT;
+
+@Service
 public class ResourceQuotaImpl implements ResourceQuotaApi {
-//
-//    private static final Logger logger = LoggerUtil.getLogger(ResourceQuotaApi.class);
-//
-//    @Autowired
-//    private CoreV1Api coreV1Api;
-//
-//    @Autowired
-//    private NamespaceApi namespaceApi;
-//
-//    /**
-//     * @see ResourceQuotaApi#create(ResourceQuota)
-//     * @param resourceQuota
-//     * @return
-//     */
-//    @Override
-//    public void create(ResourceQuota resourceQuota) throws K8sApiException{
-//        ApiResult<Namespace> namespaceRequest = namespaceApi.getByName(resourceQuota.getName());
-//        //Namespace不存在
-//        if (namespaceRequest.getErrorCode() == ApiResult.NOT_EXIST) {
-//            return new ApiResult<>( ApiResult.NOT_EXIST, "该命名空间不存在");
-//        }
-//        ApiResult<Boolean> resourceQuotaExistRequest = this.exist(resourceQuota.getNamespace(), resourceQuota.getName());
-//        if (!resourceQuotaExistRequest.isSuccess()) {
-//            return new ApiResult<>(ApiResult.SYSTEM_ERROR, "resource quota查询失败");
-//        }
-//
-//        //该资源限额已经存在,直接更新资源限额
-//        if (resourceQuotaExistRequest.getValue()) {
-//            return update(resourceQuota);
-//        }
-//
-//        try {
-//            coreV1Api.createNamespacedResourceQuota(
-//                    resourceQuota.getNamespace(),
-//                    resourceQuota.toV1ResourceQuota(),
-//                    PRETTY_FORMAT);
-//        } catch (ApiException e) {
-//            LoggerUtil.error(logger, e, "创建resource quota失败, resourceQuota={}, response={}",
-//                    resourceQuota, e.getResponseBody());
-//            return new ApiResult<>(e.getCode(), e.getMessage());
-//        }
-//        return new ApiResult<>(null);
-//    }
-//
-//    /**
-//     * @see ResourceQuotaApi#update(ResourceQuota)
-//     * @param resourceQuota
-//     * @return
-//     */
-//    @Override
-//    public ApiResult<Void> update(ResourceQuota resourceQuota) {
-//        ApiResult<Namespace> namespaceRequest = namespaceApi.getByName(resourceQuota.getName());
-//        //Namespace不存在
-//        if (namespaceRequest.getErrorCode() == ApiResult.NOT_EXIST) {
-//            return new ApiResult<>( ApiResult.NOT_EXIST, "该命名空间不存在");
-//        }
-//
-//        ApiResult<Boolean> resourceQuotaExistRequest = this.exist(resourceQuota.getNamespace(), resourceQuota.getName());
-//        if (!resourceQuotaExistRequest.isSuccess()) {
-//            return new ApiResult<>(ApiResult.SYSTEM_ERROR, "resource quota查询失败");
-//        }
-//        if (!resourceQuotaExistRequest.getValue()) {
-//            return new ApiResult<>(ApiResult.NOT_EXIST, "名称为" + resourceQuota.getName() + "的资源限额不存在");
-//        }
-//
-//        try {
-//            coreV1Api.patchNamespacedResourceQuota(
-//                    resourceQuota.getNamespace(),
-//                    resourceQuota.getNamespace(),
-//                    resourceQuota.toV1ResourceQuota(),
-//                    PRETTY_FORMAT);
-//        } catch (ApiException e) {
-//            LoggerUtil.error(logger, e, "更新Resource Quota失败, resourceQuota={}, response={}", resourceQuota, e.getResponseBody());
-//            return new ApiResult<>(e.getCode(), e.getMessage());
-//        }
-//        return new ApiResult<>(null);
-//    }
-//
-//    @Override
-//    public ApiResult<Void> delete(String namespace, String name) {
-//        ApiResult<Namespace> namespaceRequest = namespaceApi.getByName(namespace);
-//        //系统错误
-//        if (!namespaceRequest.isSuccess()) {
-//            return new ApiResult<>(namespaceRequest.getErrorCode(), namespaceRequest.getErrorDescription());
-//        }
-//        //Namespace不存在
-//        if (namespaceRequest.getErrorCode() == ApiResult.NOT_EXIST) {
-//            return new ApiResult<>( ApiResult.NOT_EXIST, "该命名空间不存在");
-//        }
-//
-//
-//        ApiResult<Boolean> resourceQuotaExistRequest = this.exist(namespace, name);
-//        //系统错误
-//        if (!resourceQuotaExistRequest.isSuccess()) {
-//            return new ApiResult<>(ApiResult.SYSTEM_ERROR, "resource quota查询失败");
-//        }
-//        //该资源限额不存在
-//        if (!resourceQuotaExistRequest.getValue()) {
-//            return new ApiResult<>(ApiResult.NOT_EXIST, "该资源限额不存在");
-//        }
-//
-//        V1DeleteOptions deleteOptions = new V1DeleteOptionsBuilder()
-//                .withApiVersion(ResourceQuota.API_VERSION)
-//                .withApiVersion(ResourceQuota.KIND)
-//                .withPropagationPolicy(FOREGROUND_PROPAGATION_POLICY)
-//                .build();
-//
-//        try {
-//            coreV1Api.deleteNamespacedResourceQuota(
-//                    name,
-//                    namespace,
-//                    deleteOptions,
-//                    PRETTY_FORMAT,
-//                    null,
-//                    null,
-//                    FOREGROUND_PROPAGATION_POLICY);
-//        } catch (ApiException e) {
-//            LoggerUtil.error(logger, e, "删除resource quota异常,namespace={}, name={}, response={}",
-//                    namespace, name, e.getResponseBody());
-//        }
-//        return new ApiResult<>(null);
-//    }
-//
-//    @Override
-//    public ResourceQuota getByName(String namespace, String name) throws K8sApiException {
-//        return null;
-//    }
-//
-//    @Override
-//    public boolean exist(String namespace, String name) throws K8sApiException {
-//        try {
-//
-//            V1ResourceQuotaList resourceQuotaList = coreV1Api.listNamespacedResourceQuota(namespace,
-//                    PRETTY_FORMAT,
-//                    null,
-//                    "metadata.name="+name,
-//                    null,
-//                    null,
-//                    null,
-//                    null,
-//                    null,
-//                    null);
-//            return resourceQuotaList.getItems().size() > 0;
-//        } catch (ApiException e) {
-//            LoggerUtil.error(logger, e, "查找resource quota失败, namespace={}, response={}", namespace, e.getResponseBody());
-//            return false;
-//        }
-//    }
-//
-//    /**
-//     * @see ResourceQuotaApi#getByNamespace(String)
-//     * @param namespace
-//     * @return
-//     */
-//    @Override
-//    public ApiResult<ResourceQuota> getByNamespace(String namespace) {
-//        try {
-//            V1ResourceQuotaList resourceQuotaList = coreV1Api.listNamespacedResourceQuota(namespace,
-//                    PRETTY_FORMAT,
-//                    null,
-//                    null,
-//                    null,
-//                    null,
-//                    null,
-//                    null,
-//                    null,
-//                    null);
-//            if (resourceQuotaList != null && !CollectionUtils.isEmpty(resourceQuotaList.getItems())) {
-//                List<ResourceQuota> result = resourceQuotaList.getItems().stream().map(ResourceQuota::new).collect(Collectors.toList());
-//                return new ApiResult<>(result.get(0));
-//            }
-//        } catch (ApiException e) {
-//            LoggerUtil.error(logger, e, "查找Resource Quota失败, namespace={}, response={}", namespace, e.getResponseBody());
-//            return new ApiResult<>(e.getCode(), e.getMessage());
-//        }
-//        return new ApiResult<>(null);
-//    }
-//
+
+    private static final Logger logger = LoggerUtil.getLogger(ResourceQuotaApi.class);
+
+    @Autowired
+    private CoreV1Api coreV1Api;
+
+    @Autowired
+    private NamespaceApi namespaceApi;
+
+    /**
+     * @see ResourceQuotaApi#create(ResourceQuota)
+     * @param resourceQuota
+     * @return
+     */
+    @Override
+    public void create(ResourceQuota resourceQuota) throws K8sApiException{
+        if (!namespaceApi.exists(resourceQuota.getNamespace())) {
+            throw new K8sApiException(K8sApiException.NAMESPACE_NOT_EXIST);
+        }
+
+        if (this.exist(resourceQuota.getNamespace(), resourceQuota.getName())) {
+            throw new K8sApiException(K8sApiException.RESOURCE_QUOTA_ALREADY_EXIST);
+        }
+
+        try {
+            coreV1Api.createNamespacedResourceQuota(
+                    resourceQuota.getNamespace(),
+                    resourceQuota.toV1ResourceQuota(),
+                    PRETTY_FORMAT);
+        } catch (ApiException e) {
+            LoggerUtil.error(logger, e, "创建resource quota失败, resourceQuota={}, response={}",
+                    resourceQuota, e.getResponseBody());
+            throw K8sApiException.K8s_SYSTEM_ERROR_EXCEPTION;
+        }
+    }
+
+    /**
+     * @see ResourceQuotaApi#update(ResourceQuota)
+     * @param resourceQuota
+     * @return
+     */
+    @Override
+    public void update(ResourceQuota resourceQuota) throws K8sApiException{
+        if (!namespaceApi.exists(resourceQuota.getNamespace())) {
+            throw new K8sApiException(K8sApiException.NAMESPACE_NOT_EXIST);
+        }
+
+        if (!this.exist(resourceQuota.getNamespace(), resourceQuota.getName())) {
+            throw new K8sApiException(K8sApiException.RESOURCE_QUOTA_NOT_EXIST);
+        }
+        try {
+            coreV1Api.patchNamespacedResourceQuota(
+                    resourceQuota.getNamespace(),
+                    resourceQuota.getNamespace(),
+                    resourceQuota.toV1ResourceQuota(),
+                    PRETTY_FORMAT);
+        } catch (ApiException e) {
+            LoggerUtil.error(logger, e, "更新Resource Quota失败, resourceQuota={}, response={}", resourceQuota, e.getResponseBody());
+            throw K8sApiException.K8s_SYSTEM_ERROR_EXCEPTION;
+        }
+    }
+
+    @Override
+    public void delete(String namespace, String name) throws K8sApiException{
+        if (!namespaceApi.exists(namespace)) {
+            throw new K8sApiException(K8sApiException.NAMESPACE_NOT_EXIST);
+        }
+        if (!this.exist(namespace, name)) {
+            throw new K8sApiException(K8sApiException.RESOURCE_QUOTA_NOT_EXIST);
+        }
+
+        V1DeleteOptions deleteOptions = new V1DeleteOptionsBuilder()
+                .withApiVersion(ResourceQuota.API_VERSION)
+                .withApiVersion(ResourceQuota.KIND)
+                .withPropagationPolicy(FOREGROUND_PROPAGATION_POLICY)
+                .build();
+
+        try {
+            coreV1Api.deleteNamespacedResourceQuota(
+                    name,
+                    namespace,
+                    deleteOptions,
+                    PRETTY_FORMAT,
+                    null,
+                    null,
+                    FOREGROUND_PROPAGATION_POLICY);
+        } catch (ApiException e) {
+            LoggerUtil.error(logger, e, "删除resource quota异常,namespace={}, name={}, response={}",
+                    namespace, name, e.getResponseBody());
+            throw K8sApiException.K8s_SYSTEM_ERROR_EXCEPTION;
+        }
+    }
+
+    @Override
+    public ResourceQuota getByName(String namespace, String name) throws K8sApiException {
+        if (exist(namespace, name)) {
+            return null;
+        }
+        try {
+
+            V1ResourceQuotaList resourceQuotaList = coreV1Api.listNamespacedResourceQuota(namespace,
+                    PRETTY_FORMAT,
+                    null,
+                    "metadata.name="+name,
+                    null,
+                    null,
+                    null,
+                    null,
+                    null,
+                    null);
+            return new ResourceQuota(resourceQuotaList.getItems().get(0));
+        } catch (ApiException e) {
+            LoggerUtil.error(logger, e, "查找resource quota失败, namespace={}, response={}", namespace, e.getResponseBody());
+            throw K8sApiException.K8s_SYSTEM_ERROR_EXCEPTION;
+        }
+
+    }
+
+    @Override
+    public boolean exist(String namespace, String name) throws K8sApiException {
+        try {
+
+            V1ResourceQuotaList resourceQuotaList = coreV1Api.listNamespacedResourceQuota(namespace,
+                    PRETTY_FORMAT,
+                    null,
+                    "metadata.name="+name,
+                    null,
+                    null,
+                    null,
+                    null,
+                    null,
+                    null);
+            return resourceQuotaList.getItems().size() > 0;
+        } catch (ApiException e) {
+            LoggerUtil.error(logger, e, "查找resource quota失败, namespace={}, response={}", namespace, e.getResponseBody());
+            return false;
+        }
+    }
+
 
 }

+ 41 - 40
src/main/java/nju/seec/SEECdemo/logic/api/k8s/impl/SecretApiImpl.java

@@ -1,15 +1,15 @@
 package nju.seec.SEECdemo.logic.api.k8s.impl;
 
 
-import com.google.protobuf.Api;
 import io.kubernetes.client.ApiException;
 import io.kubernetes.client.apis.CoreV1Api;
 import io.kubernetes.client.models.*;
-import nju.seec.SEECdemo.logic.api.k8s.DeploymentApi;
 import nju.seec.SEECdemo.logic.api.k8s.SecretApi;
 import nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException;
-import nju.seec.SEECdemo.logic.api.k8s.vo.ApiResult;
+import nju.seec.SEECdemo.logic.api.k8s.util.SecretTypeEnum;
+import nju.seec.SEECdemo.logic.api.k8s.vo.SecretVO;
 import nju.seec.SEECdemo.util.LoggerUtil;
+import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -18,6 +18,9 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
+
+import static nju.seec.SEECdemo.util.Constants.PRETTY_FORMAT;
 
 
 @Service
@@ -29,13 +32,12 @@ public class SecretApiImpl implements SecretApi {
     private CoreV1Api coreV1Api;
 
     @Override
-    public V1Secret createGenericSecret(String namespace, String name, Map<String, byte[]> data) throws K8sApiException {
-        String type = "Opaque";
-        return createGenericSecret(namespace, name, data, type);
+    public SecretVO createGenericSecret(String namespace, String name, Map<String, byte[]> data) throws K8sApiException {
+        return createGenericSecret(namespace, name, data, SecretTypeEnum.Generic);
     }
 
     @Override
-    public V1Secret createGenericSecret(String namespace, String name, Map<String, byte[]> data, String type) throws K8sApiException {
+    public SecretVO createGenericSecret(String namespace, String name, Map<String, byte[]> data, SecretTypeEnum type) throws K8sApiException {
 
         //Secret默认创建的Type为Opaque,base64编码格式的Secret,用来储存密码、密钥等。
 
@@ -47,10 +49,10 @@ public class SecretApiImpl implements SecretApi {
         v1Secret.setData(data);
         v1Secret.setKind("Secret");
         v1Secret.setMetadata(meta);
-        v1Secret.setType(type);
+        v1Secret.setType(type.getValue());
 
         try {
-            return coreV1Api.createNamespacedSecret(namespace, v1Secret, "OK");
+            return new SecretVO(coreV1Api.createNamespacedSecret(namespace, v1Secret, PRETTY_FORMAT));
         } catch (ApiException e) {
             LoggerUtil.error(logger, e, "Secret创建失败, Secret={}, response={}", v1Secret, e.getResponseBody());
             switch (e.getCode()) {
@@ -65,7 +67,7 @@ public class SecretApiImpl implements SecretApi {
     }
 
     @Override
-    public V1Secret createPrivateRegistrySecret(String namespace, String server, String user, String password) throws K8sApiException {
+    public SecretVO createPrivateRegistrySecret(String namespace, String server, String user, String password) throws K8sApiException {
         //dockerSecret 统一的名称
         String name = "docker-registry-secret";
         return createPrivateRegistrySecret(namespace, name, server, user, password);
@@ -73,27 +75,33 @@ public class SecretApiImpl implements SecretApi {
     }
 
     @Override
-    public V1Secret createPrivateRegistrySecret(String namespace, String name, String server, String user, String password) throws K8sApiException {
+    public SecretVO createPrivateRegistrySecret(String namespace, String name, String server, String user, String password) throws K8sApiException {
         Map<String, byte[]> data = new HashMap<>();
 
         String dockerConfigJson =
-                "{\"auths\":{\"" + server +"\":{\"username\":\"" + user +
+                "{\"auths\":{\"" + server + "\":{\"username\":\"" + user +
                         "\",\"password\":\"" + password +
                         "\",\"auth\":\"" + user + ":" + password + "\"}}}";
         data.put(".dockerconfigjson", dockerConfigJson.getBytes());
 
-        //dockerSecret 统一的名称
-
-        String type = "kubernetes.io/dockerconfigjson";
-
-        return createGenericSecret(namespace, name, data, type);
+        return createGenericSecret(namespace, name, data, SecretTypeEnum.REGISTRY);
     }
 
     @Override
-    public List<V1Secret> getSecretList(String namespace) throws K8sApiException {
+    public List<SecretVO> getSecretList(String namespace) throws K8sApiException {
         try {
-            V1SecretList v1SecretList = coreV1Api.listNamespacedSecret(namespace, "OK", "", "",false, "", 200, "", 10, false);
-            return v1SecretList.getItems();
+            V1SecretList v1SecretList = coreV1Api.listNamespacedSecret(
+                    namespace,
+                    PRETTY_FORMAT,
+                    "",
+                    "",
+                    false,
+                    "",
+                    200,
+                    "",
+                    10,
+                    false);
+            return v1SecretList.getItems().stream().map(SecretVO::new).collect(Collectors.toList());
         } catch (ApiException e) {
             LoggerUtil.error(logger, e, "Secret列表获取失败, response={}", e.getResponseBody());
             if (e.getCode() == K8sApiException.NAMESPACE_NOT_EXIST) {
@@ -105,28 +113,20 @@ public class SecretApiImpl implements SecretApi {
     }
 
     @Override
-    public List<V1Secret> getSecretListByType(String namespace, String type) throws K8sApiException {
-        List<V1Secret> secretList = getSecretList(namespace);
-        List<V1Secret> resultList = new ArrayList<>();
-        for (V1Secret secret : secretList) {
-            String secretType = secret.getType();
-            if (type.equals(secretType)) {
-                resultList.add(secret);
-            }
-        }
-        return resultList;
+    public List<SecretVO> getSecretListByType(String namespace, SecretTypeEnum type) throws K8sApiException {
+        return getSecretList(namespace)
+                .stream()
+                .filter(secretVO -> type == secretVO.getSecretType())
+                .collect(Collectors.toList());
     }
 
     @Override
-    public V1Secret getSecretByName(String namespace, String name) throws K8sApiException {
-        List<V1Secret> secretList = getSecretList(namespace);
-        for (V1Secret secret : secretList) {
-            V1ObjectMeta meta = secret.getMetadata();
-            if (meta.getName().equals(name)) {
-                return secret;
-            }
-        }
-        throw new K8sApiException(K8sApiException.NOT_FOUND);
+    public SecretVO getSecretByName(String namespace, String name) throws K8sApiException {
+        return getSecretList(namespace)
+                .stream()
+                .filter(secretVO -> StringUtils.equals(secretVO.getName(), name))
+                .findAny()
+                .get();
     }
 
     @Override
@@ -134,7 +134,7 @@ public class SecretApiImpl implements SecretApi {
         V1DeleteOptions body = new V1DeleteOptions();
         try {
             //暂时没有用到deleteNamespacedSecret()中的其他参数。
-            V1Status v1Status = coreV1Api.deleteNamespacedSecret(name, namespace, body, "", 5, false, "");
+            V1Status v1Status = coreV1Api.deleteNamespacedSecret(name, namespace, body, PRETTY_FORMAT, 5, false, "");
         } catch (ApiException e) {
             if (e.getCode() == K8sApiException.NOT_FOUND) {
                 throw new K8sApiException(K8sApiException.NOT_FOUND);
@@ -144,3 +144,4 @@ public class SecretApiImpl implements SecretApi {
         }
     }
 }
+

+ 0 - 1
src/main/java/nju/seec/SEECdemo/logic/api/k8s/vo/ResourceQuota.java

@@ -36,7 +36,6 @@ public class ResourceQuota {
     public ResourceQuota(V1ResourceQuota v1ResourceQuota) {
         this.namespace = v1ResourceQuota.getMetadata().getNamespace();
         this.name = v1ResourceQuota.getMetadata().getName();
-
     }
 
     public V1ResourceQuota toV1ResourceQuota(){

+ 8 - 0
src/main/java/nju/seec/SEECdemo/logic/exception/ServiceException.java

@@ -0,0 +1,8 @@
+package nju.seec.SEECdemo.logic.exception;
+
+/**
+ * author: rale
+ * createdAt: 12/23/18
+ */
+public class ServiceException {
+}

+ 9 - 1
src/main/java/nju/seec/SEECdemo/logic/service/DBService.java

@@ -15,8 +15,16 @@ public interface DBService {
     DBDetailVO createSchemaAndUser(String schema, String username, String password);
 
     /**
-     * 在公用数据库中随机创建schema和用户,并赋予权限s
+     * 在公用数据库中随机创建schema和用户,并赋予权限
      * @return
      */
     DBDetailVO createSchemaAndUserForApplication(String projectId, String applicationName);
+
+    /**
+     * 在公用数据库中随机创建schema和用户,并赋予权限
+     * @warning 用该API创建的schema名称即为projectId, 即一个project下只能有一个schema
+     * @param projectId
+     * @return
+     */
+    DBDetailVO createSchemaAndUserForProject(String projectId);
 }

+ 10 - 0
src/main/java/nju/seec/SEECdemo/logic/service/impl/DBServiceImpl.java

@@ -74,4 +74,14 @@ public class DBServiceImpl implements DBService{
         return createSchemaAndUser(schemaName, userName, password);
     }
 
+    @Override
+    public DBDetailVO createSchemaAndUserForProject(String projectId) {
+        String schemaName = projectId + "_db";
+        String userName = projectId;
+        String password = RandomStringUtil.getRandomString(10);
+        LoggerUtil.info(logger,"创建数据库信息 schema={}, userName={}, password={}",
+                schemaName, userName, password);
+        return createSchemaAndUser(schemaName, userName, password);
+    }
+
 }

+ 25 - 3
src/main/java/nju/seec/SEECdemo/logic/service/impl/project/ProjectServiceImpl.java → src/main/java/nju/seec/SEECdemo/logic/service/impl/ProjectServiceImpl.java

@@ -1,11 +1,14 @@
-package nju.seec.SEECdemo.logic.service.impl.project;
+package nju.seec.SEECdemo.logic.service.impl;
 
 import nju.seec.SEECdemo.logic.api.k8s.NamespaceApi;
+import nju.seec.SEECdemo.logic.api.k8s.SecretApi;
 import nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException;
 import nju.seec.SEECdemo.logic.api.k8s.vo.Namespace;
+import nju.seec.SEECdemo.logic.service.DBService;
 import nju.seec.SEECdemo.logic.service.ProjectService;
 import nju.seec.SEECdemo.logic.vo.ProjectVO;
 import nju.seec.SEECdemo.logic.vo.projecttemplate.ProjectTemplate;
+import nju.seec.SEECdemo.util.ApplicationProperties;
 import nju.seec.SEECdemo.util.DateUtil;
 import nju.seec.SEECdemo.util.LoggerUtil;
 import org.slf4j.Logger;
@@ -27,21 +30,40 @@ public class ProjectServiceImpl implements ProjectService{
     @Autowired
     private ProjectTemplate seecIITemplate;
 
+    @Autowired
+    private SecretApi secretApi;
+
+    @Autowired
+    private DBService dbService;
+
+    @Autowired
+    private ApplicationProperties applicationProperties;
+
     @Override
     public ProjectVO createSeecIIProject(String projectName, String description, LocalDate startsAt, LocalDate endsAt) {
         try {
             if (namespaceApi.exists(projectName)){
-                System.out.println("该项目已经存在");
-                return null;
+                LoggerUtil.error(logger, "该项目已经存在,projectName={}", projectName);
+                //抛出异常
             }
 
             String type = seecIITemplate.getName();
             Namespace namespace = buildNamespace(projectName, type, description, startsAt, endsAt);
             namespaceApi.create(namespace);
 
+            //为命名空间配置私有仓库密钥
+            ApplicationProperties.Registry registry = applicationProperties.getRegistry();
+            secretApi.createPrivateRegistrySecret(projectName, registry.getHost(), registry.getUsername(), registry.getPassword());
 
+            ApplicationProperties.K8s k8s = applicationProperties
         } catch (K8sApiException e) {
+            LoggerUtil.error(logger, e, "创建项目失败,projectName={}, projectType={}", projectName, seecIITemplate.getName());
+
+            if (e.getCode() == K8sApiException.NAMESPACE_NOT_EXIST) {
 
+            }else {
+
+            }
         }
 
 

+ 8 - 3
src/main/java/nju/seec/SEECdemo/logic/vo/ProjectVO.java

@@ -3,20 +3,25 @@ package nju.seec.SEECdemo.logic.vo;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 
+import java.time.LocalDate;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.Map;
 
 @Data
 @EqualsAndHashCode
 public class ProjectVO {
+    public static final String DB = "DB";
 
     private String name;
 
     private String description;
 
-    private Date startsAt;
+    private String startsAt;
+
+    private String endsAt;
+
+    private Map<String, Object> extra = new HashMap<>();
 
-    private Date endsAt;
 
-    private Map<String, String> extra;
 }

+ 14 - 0
src/main/java/nju/seec/SEECdemo/util/ApplicationProperties.java

@@ -34,6 +34,8 @@ public class ApplicationProperties {
 	private Storage storage = new Storage();
 	@Valid
 	private K8s k8s = new K8s();
+    @Valid
+    private Registry registry = new Registry();
 
 	@Data
 	public static class Gitlab {
@@ -108,4 +110,16 @@ public class ApplicationProperties {
 
 		private String publicMysqlPassword;
 	}
+
+	@Data
+    public static class Registry{
+	    @NotEmpty
+	    private String host;
+
+	    @NotEmpty
+	    private String username;
+
+	    @NotEmpty
+	    private String password;
+    }
 }

+ 5 - 0
src/main/java/nju/seec/SEECdemo/util/DateUtil.java

@@ -15,6 +15,11 @@ public class DateUtil {
     public static final String BASE_DATE_TIME_FORMAT = "yyyy-MM-dd hh:MM:ss";
     public static final String BASE_DATE_TIME_FORMAT_WITHOUT_SECONDS = "yyyy-MM-dd HH:mm";
 
+    public static String fromDateToString(LocalDate date) {
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(BASE_DATE_FORMAT);
+        return date.format(formatter);
+    }
+
     public static String fromDateToString(LocalDate date, String format) {
         DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
         return date.format(formatter);

+ 5 - 1
src/main/resources/application-dev.yml

@@ -76,4 +76,8 @@ moocoder:
     public-mysql-url: jdbc:mysql://mysql.group24.svc.cluster.local:3306
     public-mysql-pod: mysql-7b688cf578-l7pxs
     public-mysql-username: root
-    public-mysql-password: password
+    public-mysql-password: password
+  registry:
+    host: http://10.1.1.243:18082
+    username: admin
+    password: admin123

+ 43 - 0
src/test/java/nju/seec/SEECdemo/service/api/SecretApiTest.java

@@ -0,0 +1,43 @@
+package nju.seec.SEECdemo.service.api;
+
+import io.kubernetes.client.models.V1Secret;
+import nju.seec.SEECdemo.logic.api.k8s.SecretApi;
+import nju.seec.SEECdemo.logic.api.k8s.util.SecretTypeEnum;
+import nju.seec.SEECdemo.logic.api.k8s.vo.SecretVO;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+
+/**
+ * author: rale
+ * createdAt: 1/2/19
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class SecretApiTest {
+
+    @Autowired
+    private SecretApi secretApi;
+
+    @Test
+    public void getSecret() {
+        SecretVO v1Secret = secretApi.getSecretByName("group24", "regcred");
+        System.out.println(v1Secret);
+    }
+
+    @Test
+    public void getSecretByType() {
+        List<SecretVO> v1Secret = secretApi.getSecretListByType("demo", SecretTypeEnum.Generic);
+        v1Secret.stream().forEach((v1Secret1 -> {
+            v1Secret1.getData().values().forEach((stringEntry -> {
+                System.out.println(stringEntry);
+            }));
+        }));
+        System.out.println(v1Secret);
+    }
+}