Repository: stratos Updated Branches: refs/heads/stratos-4.1.x a4c516eaa -> 4b04a518a
Adding kubernetes namespace support Project: http://git-wip-us.apache.org/repos/asf/stratos/repo Commit: http://git-wip-us.apache.org/repos/asf/stratos/commit/4b04a518 Tree: http://git-wip-us.apache.org/repos/asf/stratos/tree/4b04a518 Diff: http://git-wip-us.apache.org/repos/asf/stratos/diff/4b04a518 Branch: refs/heads/stratos-4.1.x Commit: 4b04a518aba754869a60847403c2e666534a7deb Parents: a4c516e Author: anuruddhal <[email protected]> Authored: Thu May 12 10:11:14 2016 +0530 Committer: anuruddhal <[email protected]> Committed: Thu May 12 10:11:14 2016 +0530 ---------------------------------------------------------------------- .../kubernetes/KubernetesClusterContext.java | 23 +++-- .../iaases/kubernetes/KubernetesIaas.java | 97 ++++++++++---------- .../controller/util/CloudControllerUtil.java | 58 +++++++++--- .../kubernetes/client/KubernetesApiClient.java | 83 ++++++++++++----- .../kubernetes/client/KubernetesConstants.java | 21 ++++- .../KubernetesAPIClientInterface.java | 4 +- .../client/live/AbstractLiveTest.java | 11 ++- .../live/KubernetesApiClientLiveTest.java | 8 +- ...pleteApplicationSignUpsMessageProcessor.java | 8 +- .../rest/endpoint/api/StratosApiV41Utils.java | 42 +++++++++ .../kubernetes-cluster-1.json | 4 + .../kubernetes-cluster-2.json | 4 + .../kubernetes-cluster-3.json | 60 ++++++++++++ 13 files changed, 316 insertions(+), 107 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/stratos/blob/4b04a518/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/domain/kubernetes/KubernetesClusterContext.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/domain/kubernetes/KubernetesClusterContext.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/domain/kubernetes/KubernetesClusterContext.java index cc2c1a4..b61470a 100644 --- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/domain/kubernetes/KubernetesClusterContext.java +++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/domain/kubernetes/KubernetesClusterContext.java @@ -18,10 +18,6 @@ */ package org.apache.stratos.cloud.controller.domain.kubernetes; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.stratos.kubernetes.client.KubernetesApiClient; - import java.io.Serializable; import java.net.MalformedURLException; import java.net.URL; @@ -32,6 +28,9 @@ import java.util.concurrent.atomic.AtomicLong; import org.apache.stratos.cloud.controller.util.CloudControllerUtil; import org.apache.stratos.common.constants.StratosConstants; +import org.apache.stratos.kubernetes.client.KubernetesApiClient; +import org.apache.stratos.kubernetes.client.KubernetesConstants; +import org.apache.stratos.kubernetes.client.exceptions.KubernetesClientException; /** * Holds information about a Kubernetes Cluster. @@ -46,6 +45,7 @@ public class KubernetesClusterContext implements Serializable { private String masterIp; private String masterPort; private String endpoint; + private String namespace; private List<Integer> servicePortSequence; private AtomicLong serviceSeqNo; @@ -55,7 +55,7 @@ public class KubernetesClusterContext implements Serializable { public static final long MAX_SERVICE_ID = 99999999999999L; public KubernetesClusterContext(String id, String masterIp, String masterPort, int lowerPort, int upperPort, - String endpoint) { + String endpoint, String namespace) throws KubernetesClientException { this.servicePortSequence = new ArrayList<>(); serviceSeqNo = new AtomicLong(0); podSeqNo = new AtomicLong(0); @@ -68,7 +68,8 @@ public class KubernetesClusterContext implements Serializable { this.masterIp = masterIp; this.masterPort = masterPort; this.endpoint = endpoint; - this.setKubApi(new KubernetesApiClient(prepareEndpoint())); + this.namespace = namespace; + this.setKubApi(new KubernetesApiClient(prepareEndpoint(), namespace)); } private String prepareEndpoint() { @@ -148,9 +149,9 @@ public class KubernetesClusterContext implements Serializable { this.masterIp = masterIp; } - public KubernetesApiClient getKubApi() { + public KubernetesApiClient getKubApi() throws KubernetesClientException { if (kubApi == null) { - kubApi = new KubernetesApiClient(prepareEndpoint()); + kubApi = new KubernetesApiClient(prepareEndpoint(), namespace); } return kubApi; } @@ -191,13 +192,15 @@ public class KubernetesClusterContext implements Serializable { return podSeqNo.incrementAndGet(); } - public void updateKubClusterContextParams(KubernetesCluster kubernetesCluster) { + public void updateKubClusterContextParams(KubernetesCluster kubernetesCluster) throws KubernetesClientException { this.masterIp = kubernetesCluster.getKubernetesMaster().getPrivateIPAddress(); this.masterPort = CloudControllerUtil .getProperty(kubernetesCluster.getKubernetesMaster().getProperties(), StratosConstants.KUBERNETES_MASTER_PORT); + this.namespace = CloudControllerUtil.getProperty(kubernetesCluster.getKubernetesMaster().getProperties(), + KubernetesConstants.KUBERNETES_NAMESPACE, KubernetesConstants.DEFAULT_NAMESPACE); this.endpoint = kubernetesCluster.getKubernetesMaster().getEndpoint(); - this.kubApi = new KubernetesApiClient(prepareEndpoint()); + this.kubApi = new KubernetesApiClient(prepareEndpoint(), this.namespace); } @Override http://git-wip-us.apache.org/repos/asf/stratos/blob/4b04a518/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/kubernetes/KubernetesIaas.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/kubernetes/KubernetesIaas.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/kubernetes/KubernetesIaas.java index 55533e6..dcec07a 100644 --- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/kubernetes/KubernetesIaas.java +++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/kubernetes/KubernetesIaas.java @@ -20,6 +20,7 @@ package org.apache.stratos.cloud.controller.iaases.kubernetes; import com.google.common.collect.Lists; +import io.fabric8.kubernetes.api.Kubernetes; import io.fabric8.kubernetes.api.model.*; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.lang.NotImplementedException; @@ -55,20 +56,6 @@ import java.util.concurrent.locks.Lock; public class KubernetesIaas extends Iaas { private static final Log log = LogFactory.getLog(KubernetesIaas.class); - - private static final long DEFAULT_POD_ACTIVATION_TIMEOUT = 60000; // 1 min - private static final String PAYLOAD_PARAMETER_SEPARATOR = ","; - private static final String PAYLOAD_PARAMETER_NAME_VALUE_SEPARATOR = "="; - private static final String PAYLOAD_PARAMETER_PREFIX = "payload_parameter."; - private static final String PORT_MAPPINGS = "PORT_MAPPINGS"; - private static final String KUBERNETES_CONTAINER_CPU = "KUBERNETES_CONTAINER_CPU"; - private static final String KUBERNETES_CONTAINER_MEMORY = "KUBERNETES_CONTAINER_MEMORY"; - private static final String KUBERNETES_SERVICE_SESSION_AFFINITY = "KUBERNETES_SERVICE_SESSION_AFFINITY"; - private static final String KUBERNETES_CONTAINER_CPU_DEFAULT = "kubernetes.container.cpu.default"; - private static final String KUBERNETES_CONTAINER_MEMORY_DEFAULT = "kubernetes.container.memory.default"; - public static final String POD_ID_PREFIX = "pod"; - public static final String SERVICE_NAME_PREFIX = "service"; - private PartitionValidator partitionValidator; private List<NameValuePair> payload; private Long podActivationTimeout; @@ -80,7 +67,7 @@ public class KubernetesIaas extends Iaas { podActivationTimeout = Long.getLong("stratos.pod.activation.timeout"); if (podActivationTimeout == null) { - podActivationTimeout = DEFAULT_POD_ACTIVATION_TIMEOUT; + podActivationTimeout = KubernetesConstants.DEFAULT_POD_ACTIVATION_TIMEOUT; if (log.isInfoEnabled()) { log.info("Pod activation timeout was set: " + podActivationTimeout); } @@ -103,18 +90,18 @@ public class KubernetesIaas extends Iaas { if (payloadByteArray != null) { String payloadString = new String(payloadByteArray); - String[] parameterArray = payloadString.split(PAYLOAD_PARAMETER_SEPARATOR); + String[] parameterArray = payloadString.split(KubernetesConstants.PAYLOAD_PARAMETER_SEPARATOR); for (String parameter : parameterArray) { if (parameter != null) { - String[] nameValueArray = parameter.split(PAYLOAD_PARAMETER_NAME_VALUE_SEPARATOR, 2); + String[] nameValueArray = parameter.split(KubernetesConstants.PAYLOAD_PARAMETER_NAME_VALUE_SEPARATOR, 2); if (nameValueArray.length == 2) { NameValuePair nameValuePair = new NameValuePair(nameValueArray[0], nameValueArray[1]); payload.add(nameValuePair); } } - if (log.isDebugEnabled()) { - log.debug("Dynamic payload is set: " + payload.toString()); - } + } + if (log.isDebugEnabled()) { + log.debug("Dynamic payload is set: " + payload.toString()); } } } @@ -199,14 +186,17 @@ public class KubernetesIaas extends Iaas { String kubernetesMasterPort = CloudControllerUtil .getProperty(kubernetesCluster.getKubernetesMaster().getProperties(), StratosConstants.KUBERNETES_MASTER_PORT); + String kubernetesNamespace = CloudControllerUtil + .getProperty(kubernetesCluster.getKubernetesMaster().getProperties(), + KubernetesConstants.KUBERNETES_NAMESPACE, KubernetesConstants.DEFAULT_NAMESPACE); // Add kubernetes cluster payload parameters to payload if ((kubernetesCluster.getProperties() != null) && (kubernetesCluster.getProperties().getProperties() != null)) { for (Property property : kubernetesCluster.getProperties().getProperties()) { if (property != null) { - if (property.getName().startsWith(PAYLOAD_PARAMETER_PREFIX)) { - String name = property.getName().replace(PAYLOAD_PARAMETER_PREFIX, ""); + if (property.getName().startsWith(KubernetesConstants.PAYLOAD_PARAMETER_PREFIX)) { + String name = property.getName().replace(KubernetesConstants.PAYLOAD_PARAMETER_PREFIX, ""); payload.add(new NameValuePair(name, property.getValue())); } } @@ -215,7 +205,7 @@ public class KubernetesIaas extends Iaas { KubernetesClusterContext kubernetesClusterContext = getKubernetesClusterContext(kubernetesClusterId, kubernetesMasterIp, kubernetesMasterPort, kubernetesPortRange.getUpper(), - kubernetesPortRange.getLower(), kuberneteEndPoint); + kubernetesPortRange.getLower(), kuberneteEndPoint, kubernetesNamespace); // Generate kubernetes service ports and update port mappings in cartridge generateKubernetesServicePorts(clusterContext.getApplicationId(), clusterContext.getClusterId(), @@ -355,9 +345,12 @@ public class KubernetesIaas extends Iaas { * @throws KubernetesClientException */ private void createPod(ClusterContext clusterContext, MemberContext memberContext, - KubernetesApiClient kubernetesApi, KubernetesClusterContext kubernetesClusterContext) + KubernetesApiClient kubernetesApi, KubernetesClusterContext kubernetesClusterContext) throws KubernetesClientException, RegistryException { + List<String> imagePullSecrets = new ArrayList<>(); + String imagePullPolicy = null; + String applicationId = memberContext.getApplicationId(); String cartridgeType = memberContext.getCartridgeType(); String clusterId = memberContext.getClusterId(); @@ -386,17 +379,27 @@ public class KubernetesIaas extends Iaas { } // Set default values to zero to avoid cpu and memory restrictions - String cpu = System.getProperty(KUBERNETES_CONTAINER_CPU_DEFAULT, "0"); - String memory = System.getProperty(KUBERNETES_CONTAINER_MEMORY_DEFAULT, "0"); - Property cpuProperty = cartridge.getProperties().getProperty(KUBERNETES_CONTAINER_CPU); + String cpu = System.getProperty(KubernetesConstants.KUBERNETES_CONTAINER_CPU_DEFAULT, "0"); + String memory = System.getProperty(KubernetesConstants.KUBERNETES_CONTAINER_MEMORY_DEFAULT, "0"); + Property cpuProperty = cartridge.getProperties().getProperty(KubernetesConstants.KUBERNETES_CONTAINER_CPU); if (cpuProperty != null) { cpu = cpuProperty.getValue(); } - Property memoryProperty = cartridge.getProperties().getProperty(KUBERNETES_CONTAINER_MEMORY); + Property memoryProperty = cartridge.getProperties().getProperty(KubernetesConstants.KUBERNETES_CONTAINER_MEMORY); if (memoryProperty != null) { memory = memoryProperty.getValue(); } + Property imagePullSecretsProperty = cartridge.getProperties().getProperty(KubernetesConstants.IMAGE_PULL_SECRETS); + if (imagePullSecretsProperty != null) { + imagePullSecrets.add(imagePullSecretsProperty.getValue()); + } + + Property imagePullPolicyProperty = cartridge.getProperties().getProperty(KubernetesConstants.IMAGE_PULL_POLICY); + if (imagePullPolicyProperty != null) { + imagePullPolicy = imagePullPolicyProperty.getValue(); + } + IaasProvider iaasProvider = CloudControllerContext.getInstance() .getIaasProviderOfPartition(cartridge.getType(), partition.getId()); if (iaasProvider == null) { @@ -448,7 +451,7 @@ public class KubernetesIaas extends Iaas { podAnnotations.put(CloudControllerConstants.MEMBER_ID_LABEL, memberContext.getMemberId()); kubernetesApi.createPod(podId, podName, podLabels, podAnnotations, dockerImage, cpu, memory, ports, - environmentVariables); + environmentVariables, imagePullSecrets, imagePullPolicy); log.info(String.format("Pod started successfully: [application] %s [cartridge] %s [member] %s " + "[pod] %s [pod-label] %s [cpu] %s [memory] %s", memberContext.getApplicationId(), @@ -470,7 +473,7 @@ public class KubernetesIaas extends Iaas { } private String preparePodId(long podSeqNo) { - return POD_ID_PREFIX + "-" + podSeqNo; + return KubernetesConstants.POD_ID_PREFIX + "-" + podSeqNo; } /** @@ -483,8 +486,8 @@ public class KubernetesIaas extends Iaas { * @throws KubernetesClientException */ private void createKubernetesServices(KubernetesApiClient kubernetesApi, ClusterContext clusterContext, - KubernetesCluster kubernetesCluster, KubernetesClusterContext kubernetesClusterContext, - MemberContext memberContext) throws KubernetesClientException, RegistryException { + KubernetesCluster kubernetesCluster, KubernetesClusterContext kubernetesClusterContext, + MemberContext memberContext) throws KubernetesClientException, RegistryException { String clusterId = clusterContext.getClusterId(); String cartridgeType = clusterContext.getCartridgeType(); Cartridge cartridge = CloudControllerContext.getInstance().getCartridge(cartridgeType); @@ -495,7 +498,7 @@ public class KubernetesIaas extends Iaas { } String sessionAffinity = null; - Property sessionAffinityProperty = cartridge.getProperties().getProperty(KUBERNETES_SERVICE_SESSION_AFFINITY); + Property sessionAffinityProperty = cartridge.getProperties().getProperty(KubernetesConstants.KUBERNETES_SERVICE_SESSION_AFFINITY); if (sessionAffinityProperty != null) { sessionAffinity = sessionAffinityProperty.getValue(); } @@ -634,7 +637,7 @@ public class KubernetesIaas extends Iaas { * @throws KubernetesClientException */ private boolean serviceExistsInCluster(String serviceId, KubernetesClusterContext kubernetesClusterContext, - MemberContext memberContext, String portName) throws KubernetesClientException { + MemberContext memberContext, String portName) throws KubernetesClientException { KubernetesApiClient kubernetesApi = kubernetesClusterContext.getKubApi(); Service service = kubernetesApi.getService(serviceId); @@ -666,7 +669,7 @@ public class KubernetesIaas extends Iaas { } private String prepareServiceName(long serviceSeqNo) { - return SERVICE_NAME_PREFIX + "-" + (serviceSeqNo); + return KubernetesConstants.SERVICE_NAME_PREFIX + "-" + (serviceSeqNo); } private List<String> prepareMinionIPAddresses(KubernetesCluster kubernetesCluster) { @@ -692,7 +695,7 @@ public class KubernetesIaas extends Iaas { * @return */ private KubernetesService findKubernetesService(Collection<KubernetesService> kubernetesServices, - int containerPort) { + int containerPort) { if (kubernetesServices != null) { for (KubernetesService kubernetesService : kubernetesServices) { @@ -712,7 +715,7 @@ public class KubernetesIaas extends Iaas { * @param cartridge */ private void generateKubernetesServicePorts(String applicationId, String clusterId, - KubernetesClusterContext kubernetesClusterContext, Cartridge cartridge) + KubernetesClusterContext kubernetesClusterContext, Cartridge cartridge) throws KubernetesClientException, RegistryException { synchronized (KubernetesIaas.class) { if (cartridge != null) { @@ -789,7 +792,7 @@ public class KubernetesIaas extends Iaas { } } - NameValuePair nameValuePair = new NameValuePair(PORT_MAPPINGS, portMappingStrBuilder.toString()); + NameValuePair nameValuePair = new NameValuePair(KubernetesConstants.PORT_MAPPINGS, portMappingStrBuilder.toString()); payload.add(nameValuePair); // Persist service ports added to cluster port mappings @@ -859,12 +862,13 @@ public class KubernetesIaas extends Iaas { KubernetesClusterContext kubernetesClusterContext = CloudControllerContext.getInstance() .getKubernetesClusterContext(kubernetesClusterId); handleNullObject(kubernetesClusterContext, String.format( - "Could not terminate container, kubernetes cluster " - + "context not found: [partition-id] %s [member-id] %s", partition.getId(), - memberContext.getMemberId())); - KubernetesApiClient kubApi = kubernetesClusterContext.getKubApi(); + "Could not terminate container, kubernetes cluster " + + "context not found: [partition-id] %s [member-id] %s", partition.getId(), + memberContext.getMemberId())); + try { + KubernetesApiClient kubApi = kubernetesClusterContext.getKubApi(); log.info(String.format("Removing kubernetes pod: [application] %s [cartridge] %s [member] %s [pod] %s", memberContext.getApplicationId(), memberContext.getCartridgeType(), memberContext.getMemberId(), memberContext.getKubernetesPodId())); @@ -901,7 +905,8 @@ public class KubernetesIaas extends Iaas { * @return */ private KubernetesClusterContext getKubernetesClusterContext(String kubernetesClusterId, String kubernetesMasterIp, - String kubernetesMasterPort, int upperPort, int lowerPort, String kubernetesEndpoint) { + String kubernetesMasterPort, int upperPort, int lowerPort, String kubernetesEndpoint, String namespace) + throws KubernetesClientException { KubernetesClusterContext kubernetesClusterContext = CloudControllerContext.getInstance(). getKubernetesClusterContext(kubernetesClusterId); @@ -913,7 +918,7 @@ public class KubernetesIaas extends Iaas { log.info("[Kuberentes master port]" + kubernetesMasterPort); log.info("[Kuberentes master endpoint]" + kubernetesEndpoint); kubernetesClusterContext = new KubernetesClusterContext(kubernetesClusterId, kubernetesMasterIp, - kubernetesMasterPort, lowerPort, upperPort, kubernetesEndpoint); + kubernetesMasterPort, lowerPort, upperPort, kubernetesEndpoint, namespace); CloudControllerContext.getInstance().addKubernetesClusterContext(kubernetesClusterContext); return kubernetesClusterContext; } @@ -992,12 +997,12 @@ public class KubernetesIaas extends Iaas { for (KubernetesService kubernetesService : kubernetesServices) { KubernetesClusterContext kubernetesClusterContext = CloudControllerContext.getInstance() .getKubernetesClusterContext(kubernetesService.getKubernetesClusterId()); - KubernetesApiClient kubernetesApiClient = kubernetesClusterContext.getKubApi(); + String serviceId = kubernetesService.getId(); log.info(String.format("Deleting kubernetes service: [application-id] %s " + "[service-id] %s", clusterContext.getApplicationId(), serviceId)); - try { + KubernetesApiClient kubernetesApiClient = kubernetesClusterContext.getKubApi(); kubernetesApiClient.deleteService(serviceId); kubernetesClusterContext.deallocatePort(kubernetesService.getPort()); clusterContext.removeKubernetesService(clusterInstanceId, serviceId); http://git-wip-us.apache.org/repos/asf/stratos/blob/4b04a518/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/util/CloudControllerUtil.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/util/CloudControllerUtil.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/util/CloudControllerUtil.java index 873c127..e177a5b 100644 --- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/util/CloudControllerUtil.java +++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/util/CloudControllerUtil.java @@ -18,13 +18,24 @@ */ package org.apache.stratos.cloud.controller.util; -import com.google.common.net.InetAddresses; +import java.lang.reflect.Constructor; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Properties; + import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.stratos.cloud.controller.config.CloudControllerConfig; import org.apache.stratos.cloud.controller.context.CloudControllerContext; -import org.apache.stratos.cloud.controller.domain.*; +import org.apache.stratos.cloud.controller.domain.Cartridge; +import org.apache.stratos.cloud.controller.domain.IaasConfig; +import org.apache.stratos.cloud.controller.domain.IaasProvider; +import org.apache.stratos.cloud.controller.domain.NetworkInterface; +import org.apache.stratos.cloud.controller.domain.NetworkInterfaces; +import org.apache.stratos.cloud.controller.domain.Partition; import org.apache.stratos.cloud.controller.domain.kubernetes.KubernetesCluster; import org.apache.stratos.cloud.controller.domain.kubernetes.KubernetesHost; import org.apache.stratos.cloud.controller.domain.kubernetes.KubernetesMaster; @@ -36,15 +47,9 @@ import org.apache.stratos.cloud.controller.iaases.Iaas; import org.apache.stratos.cloud.controller.registry.RegistryManager; import org.apache.stratos.common.Property; import org.apache.stratos.common.domain.LoadBalancingIPType; +import org.apache.stratos.kubernetes.client.KubernetesConstants; import org.apache.stratos.messaging.domain.topology.Topology; -import java.lang.reflect.Constructor; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Properties; - public class CloudControllerUtil { private static final Log log = LogFactory.getLog(CloudControllerUtil.class); @@ -213,7 +218,7 @@ public class CloudControllerUtil { try { validateKubernetesMaster(kubernetesCluster.getKubernetesMaster()); validateKubernetesHosts(kubernetesCluster.getKubernetesHosts()); - + validateNameSpace(kubernetesCluster); // Check for duplicate hostIds if (kubernetesCluster.getKubernetesHosts() != null) { List<String> hostIds = new ArrayList<>(); @@ -276,6 +281,37 @@ public class CloudControllerUtil { } + public static void validateNameSpace(KubernetesCluster kubernetesCluster) throws InvalidKubernetesMasterException { + // validate namespace + KubernetesCluster[] kubernetesClusters = CloudControllerContext.getInstance().getKubernetesClusters(); + String namespace = CloudControllerUtil.getProperty(kubernetesCluster.getKubernetesMaster().getProperties(), + KubernetesConstants.KUBERNETES_NAMESPACE, KubernetesConstants.DEFAULT_NAMESPACE); + for (KubernetesCluster kubCluster : kubernetesClusters) { + if (!kubCluster.getClusterId().equals(kubernetesCluster.getClusterId()) && + CloudControllerUtil.getProperty(kubCluster.getKubernetesMaster().getProperties(), + KubernetesConstants.KUBERNETES_NAMESPACE).equals(namespace)) { + //check the same namespace is used in a different kubernetes cluster + if (StringUtils.isNotEmpty(kubCluster.getKubernetesMaster().getEndpoint()) && + StringUtils.isNotEmpty(kubernetesCluster.getKubernetesMaster().getEndpoint()) && + kubernetesCluster.getKubernetesMaster().getEndpoint().equals + (kubCluster.getKubernetesMaster().getEndpoint())) { + //Another Kuberenetes cluster with similar endpoint use the same namespace + throw new InvalidKubernetesMasterException(" Namespace [namespace] " + namespace + " is already " + + "used in another kubernetes cluster [kubernetes-cluster-id] " + kubCluster.getClusterId()); + + } else if (StringUtils.isNotEmpty(kubCluster.getKubernetesMaster().getPrivateIPAddress()) && + StringUtils.isNotEmpty(kubernetesCluster.getKubernetesMaster().getPrivateIPAddress()) && + kubernetesCluster.getKubernetesMaster().getPrivateIPAddress().equals + (kubCluster.getKubernetesMaster().getPrivateIPAddress())) { + //Another Kuberenetes cluster with similar private IP address use the same namespace + throw new InvalidKubernetesMasterException(" Namespace [namespace] " + namespace + " is already " + + "used in another kubernetes cluster [kubernetes-cluster-id] " + kubCluster.getClusterId()); + } + } + + } + } + public static LoadBalancingIPType getLoadBalancingIPTypeEnumFromString(String loadBalancingIPType) { if (CloudControllerConstants.LOADBALANCING_IP_TYPE_PUBLIC.equals(loadBalancingIPType)) { return LoadBalancingIPType.Public; @@ -444,4 +480,4 @@ public class CloudControllerUtil { } } } -} +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/stratos/blob/4b04a518/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/KubernetesApiClient.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/KubernetesApiClient.java b/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/KubernetesApiClient.java index b231736..8ab9d48 100644 --- a/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/KubernetesApiClient.java +++ b/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/KubernetesApiClient.java @@ -38,8 +38,19 @@ public class KubernetesApiClient implements KubernetesAPIClientInterface { private KubernetesClient kubernetesClient; - public KubernetesApiClient(String endpointUrl) { + public KubernetesApiClient(String endpointUrl, String namespace) throws KubernetesClientException { kubernetesClient = new KubernetesClient(endpointUrl); + if (!namespace.equals(KubernetesConstants.DEFAULT_NAMESPACE)) { + try { + setNamespace(namespace); + } catch (Exception e) { + throw new KubernetesClientException(e); + } + } + } + + private void setNamespace(String namespace) throws Exception { + kubernetesClient.setNamespace(namespace); } /** @@ -54,12 +65,14 @@ public class KubernetesApiClient implements KubernetesAPIClientInterface { * @param memory Memory allocation in megabytes * @param ports Ports exposed by the pod * @param environmentVariables Environment variables to be passed to the pod + * @param imagePullSecrets Image Pull Secret to be passed to the pod + * @param imagePullPolicy Image Pull policy to be passed to the pod * @throws KubernetesClientException */ @Override public void createPod(String podId, String podName, Map<String, String> podLabels, Map<String, String> annotations, - String dockerImage, String cpu, - String memory, List<ContainerPort> ports, List<EnvVar> environmentVariables) + String dockerImage, String cpu, String memory, List<ContainerPort> ports, + List<EnvVar> environmentVariables, List<String> imagePullSecrets, String imagePullPolicy) throws KubernetesClientException { try { @@ -84,20 +97,47 @@ public class KubernetesApiClient implements KubernetesAPIClientInterface { containerTemplate.setName(podName); containerTemplate.setImage(dockerImage); containerTemplate.setEnv(environmentVariables); - List<Container> containerTemplates = new ArrayList<Container>(); + List<Container> containerTemplates = new ArrayList<>(); containerTemplates.add(containerTemplate); pod.getSpec().setContainers(containerTemplates); + // set imagePullSecrets + if ((imagePullSecrets != null) && (imagePullSecrets.size() > 0)) { + List<LocalObjectReference> imagePullSecretsRefs = new ArrayList<>(); + for (String pullSecret : imagePullSecrets) { + if (pullSecret != null) { + imagePullSecretsRefs.add(new LocalObjectReference(pullSecret)); + } + } + if (imagePullSecretsRefs.size() > 0) { + pod.getSpec().setImagePullSecrets(imagePullSecretsRefs); + } + } + // Set resource limits ResourceRequirements resources = new ResourceRequirements(); - Map<String, Quantity> limits = new HashMap<String, Quantity>(); + Map<String, Quantity> limits = new HashMap<>(); limits.put(KubernetesConstants.RESOURCE_CPU, new Quantity(cpu)); limits.put(KubernetesConstants.RESOURCE_MEMORY, new Quantity(memory)); resources.setLimits(limits); containerTemplate.setResources(resources); containerTemplate.setPorts(ports); - containerTemplate.setImagePullPolicy(KubernetesConstants.POLICY_PULL_IF_NOT_PRESENT); + + if (imagePullPolicy == null) { + // default pull policy + imagePullPolicy = KubernetesConstants.POLICY_PULL_IF_NOT_PRESENT; + } else if ( + !imagePullPolicy.equals(KubernetesConstants.POLICY_PULL_ALWAYS) && + !imagePullPolicy.equals(KubernetesConstants.POLICY_PULL_NEVER) && + !imagePullPolicy.equals(KubernetesConstants.POLICY_PULL_IF_NOT_PRESENT)) { + + // pull policy validation failed + throw new KubernetesClientException("Invalid Image Pull Policy defined : " + imagePullPolicy); + } + + containerTemplate.setImagePullPolicy(imagePullPolicy); + if (environmentVariables != null) { containerTemplate.setEnv(environmentVariables); } @@ -108,8 +148,7 @@ public class KubernetesApiClient implements KubernetesAPIClientInterface { if (log.isDebugEnabled()) { log.debug(String.format("Kubernetes pod created successfully: [pod-id] %s", podId)); } - } - catch (Exception e) { + } catch (Exception e) { String msg = String.format("Could not create kubernetes pod: [pod-id] %s", podId); log.error(msg, e); throw new KubernetesClientException(msg, e); @@ -120,8 +159,7 @@ public class KubernetesApiClient implements KubernetesAPIClientInterface { public Pod getPod(String podId) throws KubernetesClientException { try { return kubernetesClient.getPod(podId); - } - catch (Exception e) { + } catch (Exception e) { String msg = String.format("Could not retrieve kubernetes pod: [pod-id] %s", podId); log.error(msg, e); throw new KubernetesClientException(msg, e); @@ -132,8 +170,7 @@ public class KubernetesApiClient implements KubernetesAPIClientInterface { public List<Pod> getPods() throws KubernetesClientException { try { return kubernetesClient.getPods().getItems(); - } - catch (Exception e) { + } catch (Exception e) { String msg = "Error while retrieving kubernetes pods."; log.error(msg, e); throw new KubernetesClientException(msg, e); @@ -144,8 +181,7 @@ public class KubernetesApiClient implements KubernetesAPIClientInterface { public void deletePod(String podId) throws KubernetesClientException { try { kubernetesClient.deletePod(podId); - } - catch (Exception e) { + } catch (Exception e) { String message = String.format("Could not delete kubernetes pod: [pod-id] %s", podId); log.error(message, e); throw new KubernetesClientException(message, e); @@ -197,7 +233,7 @@ public class KubernetesApiClient implements KubernetesAPIClientInterface { } // Set port - List<ServicePort> ports = new ArrayList<ServicePort>(); + List<ServicePort> ports = new ArrayList<>(); ServicePort port = new ServicePort(); port.setName(containerPortName); port.setPort(containerPort); @@ -212,7 +248,7 @@ public class KubernetesApiClient implements KubernetesAPIClientInterface { service.getMetadata().setLabels(serviceLabels); // Set service selector - Map<String, String> selector = new HashMap<String, String>(); + Map<String, String> selector = new HashMap<>(); selector.put(KubernetesConstants.SERVICE_SELECTOR_LABEL, serviceName); service.getSpec().setSelector(selector); @@ -224,8 +260,7 @@ public class KubernetesApiClient implements KubernetesAPIClientInterface { "[node-port] %d [container-port-name] %s [container-port] %d", serviceId, serviceName, servicePort, containerPortName, containerPort)); } - } - catch (Exception e) { + } catch (Exception e) { String message = String.format("Could not create kubernetes service: [service-id] %s [service-name] %s " + "[node-port] %d [container-port-name] %s [container-port] %d", serviceId, serviceName, servicePort, containerPortName, containerPort); @@ -239,8 +274,7 @@ public class KubernetesApiClient implements KubernetesAPIClientInterface { throws KubernetesClientException { try { return kubernetesClient.getService(serviceId); - } - catch (Exception e) { + } catch (Exception e) { String msg = String.format("Could not retrieve kubernetes service: [service-id] %s", serviceId); log.error(msg, e); throw new KubernetesClientException(msg, e); @@ -251,8 +285,7 @@ public class KubernetesApiClient implements KubernetesAPIClientInterface { public List<Service> getServices() throws KubernetesClientException { try { return kubernetesClient.getServices().getItems(); - } - catch (Exception e) { + } catch (Exception e) { String msg = "Could not retrieve kubernetes services"; log.error(msg, e); throw new KubernetesClientException(msg, e); @@ -273,11 +306,11 @@ public class KubernetesApiClient implements KubernetesAPIClientInterface { if (log.isDebugEnabled()) { log.debug(String.format("Kubernetes service deleted successfully: [service-id] %s", serviceId)); } - } - catch (Exception e) { + } catch (Exception e) { String msg = String.format("Could not delete kubernetes service: [service-id] %s", serviceId); log.error(msg, e); throw new KubernetesClientException(msg, e); } } -} + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/stratos/blob/4b04a518/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/KubernetesConstants.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/KubernetesConstants.java b/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/KubernetesConstants.java index 2a4a8dd..08843f3 100644 --- a/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/KubernetesConstants.java +++ b/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/KubernetesConstants.java @@ -26,6 +26,8 @@ public class KubernetesConstants { public static final String POD_STATUS_RUNNING = "Running"; public static final String POLICY_PULL_IF_NOT_PRESENT = "IfNotPresent"; + public static final String POLICY_PULL_ALWAYS = "Always"; + public static final String POLICY_PULL_NEVER = "Never"; public static final String SESSION_AFFINITY_CLIENT_IP = "ClientIP"; public static final String KIND_POD = "Pod"; public static final String KIND_SERVICE = "Service"; @@ -35,4 +37,21 @@ public class KubernetesConstants { public static final String NODE_PORT = "NodePort"; public static final String CLUSTER_IP = "ClusterIP"; public static final int MAX_LABEL_LENGTH = 63; -} + public static final String SECRET_TYPE_DOCKERCFG = "kubernetes.io/dockercfg"; + public static final String DEFAULT_NAMESPACE = "default"; + public static final String PAYLOAD_PARAMETER_PREFIX = "payload_parameter."; + public static final String PORT_MAPPINGS = "PORT_MAPPINGS"; + public static final String KUBERNETES_CONTAINER_CPU = "KUBERNETES_CONTAINER_CPU"; + public static final String KUBERNETES_CONTAINER_MEMORY = "KUBERNETES_CONTAINER_MEMORY"; + public static final String KUBERNETES_SERVICE_SESSION_AFFINITY = "KUBERNETES_SERVICE_SESSION_AFFINITY"; + public static final String KUBERNETES_CONTAINER_CPU_DEFAULT = "kubernetes.container.cpu.default"; + public static final String KUBERNETES_CONTAINER_MEMORY_DEFAULT = "kubernetes.container.memory.default"; + public static final String POD_ID_PREFIX = "pod"; + public static final String SERVICE_NAME_PREFIX = "service"; + public static final String IMAGE_PULL_SECRETS = "IMAGE_PULL_SECRETS"; + public static final String IMAGE_PULL_POLICY = "IMAGE_PULL_POLICY"; + public static final long DEFAULT_POD_ACTIVATION_TIMEOUT = 60000; // 1 min + public static final String PAYLOAD_PARAMETER_SEPARATOR = ","; + public static final String KUBERNETES_NAMESPACE = "KUBERNETES_NAMESPACE"; + public static final String PAYLOAD_PARAMETER_NAME_VALUE_SEPARATOR = "="; +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/stratos/blob/4b04a518/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/interfaces/KubernetesAPIClientInterface.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/interfaces/KubernetesAPIClientInterface.java b/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/interfaces/KubernetesAPIClientInterface.java index 9b42966..b3f1aa9 100644 --- a/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/interfaces/KubernetesAPIClientInterface.java +++ b/components/org.apache.stratos.kubernetes.client/src/main/java/org/apache/stratos/kubernetes/client/interfaces/KubernetesAPIClientInterface.java @@ -48,8 +48,8 @@ public interface KubernetesAPIClientInterface { */ public void createPod(String podId, String podName, Map<String, String> podLabels, Map<String, String> annotations, String dockerImage, String cpu, String memory, List<ContainerPort> ports, - List<EnvVar> environmentVariables) - throws KubernetesClientException; + List<EnvVar> environmentVariables, List<String> imagePullSecrets, String imagePullPolicy) + throws KubernetesClientException ; /** * Get information of a Pod given the PodID http://git-wip-us.apache.org/repos/asf/stratos/blob/4b04a518/components/org.apache.stratos.kubernetes.client/src/test/java/org/apache/stratos/kubernetes/client/live/AbstractLiveTest.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.kubernetes.client/src/test/java/org/apache/stratos/kubernetes/client/live/AbstractLiveTest.java b/components/org.apache.stratos.kubernetes.client/src/test/java/org/apache/stratos/kubernetes/client/live/AbstractLiveTest.java index 842c672..0a7a2d2 100644 --- a/components/org.apache.stratos.kubernetes.client/src/test/java/org/apache/stratos/kubernetes/client/live/AbstractLiveTest.java +++ b/components/org.apache.stratos.kubernetes.client/src/test/java/org/apache/stratos/kubernetes/client/live/AbstractLiveTest.java @@ -71,14 +71,14 @@ public class AbstractLiveTest extends TestCase { protected List<String> serviceIdList = new CopyOnWriteArrayList<String>(); @BeforeClass - public void setUp() { + public void setUp() throws KubernetesClientException { log.info("Setting up live test..."); endpoint = System.getProperty(KUBERNETES_API_ENDPOINT); if (endpoint == null) { endpoint = "http://" + DEFAULT_KUBERNETES_MASTER_IP + ":" + KUBERNETES_API_PORT; } log.info(KUBERNETES_API_ENDPOINT + ": " + endpoint); - client = new KubernetesApiClient(endpoint); + client = new KubernetesApiClient(endpoint,"default"); dockerImage = System.getProperty(DOCKER_IMAGE); if (dockerImage == null) { @@ -125,12 +125,13 @@ public class AbstractLiveTest extends TestCase { } protected void createPod(String podId, String podName, Map<String, String> labelMap, Map<String, String> - annotations, String containerPortName, String cpu, String memory) + annotations, String containerPortName, String cpu, String memory, List<String> imagePullSecrets, + String imagePullPolicy) throws KubernetesClientException { log.info("Creating pod: [pod] " + podId); List<ContainerPort> ports = createPorts(containerPortName); - client.createPod(podId, podName, annotations, labelMap, dockerImage, cpu, memory, ports, null); + client.createPod(podId, podName, annotations, labelMap, dockerImage, cpu, memory, ports, null, imagePullSecrets, imagePullPolicy); podIdList.add(podId); sleep(2000); @@ -256,4 +257,4 @@ public class AbstractLiveTest extends TestCase { ports.add(port); return ports; } -} +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/stratos/blob/4b04a518/components/org.apache.stratos.kubernetes.client/src/test/java/org/apache/stratos/kubernetes/client/live/KubernetesApiClientLiveTest.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.kubernetes.client/src/test/java/org/apache/stratos/kubernetes/client/live/KubernetesApiClientLiveTest.java b/components/org.apache.stratos.kubernetes.client/src/test/java/org/apache/stratos/kubernetes/client/live/KubernetesApiClientLiveTest.java index ea10c97..36bed87 100644 --- a/components/org.apache.stratos.kubernetes.client/src/test/java/org/apache/stratos/kubernetes/client/live/KubernetesApiClientLiveTest.java +++ b/components/org.apache.stratos.kubernetes.client/src/test/java/org/apache/stratos/kubernetes/client/live/KubernetesApiClientLiveTest.java @@ -52,13 +52,13 @@ public class KubernetesApiClientLiveTest extends AbstractLiveTest { podLabels1.put("applicationId", "my-application-1"); Map<String, String> podAnnocations1 = new HashMap<>(); podAnnocations1.put("test", "test"); - createPod("stratos-test-pod-1", "stratos-test-pod", podLabels1, podAnnocations1, "http-1", "1", "512Mi"); + createPod("stratos-test-pod-1", "stratos-test-pod", podLabels1, podAnnocations1, "http-1", "1", "512Mi", null, null); Map<String, String> podLabels2 = new HashMap<>(); podLabels2.put("applicationId", "my-application-2"); Map<String, String> podAnnocations2 = new HashMap<>(); podAnnocations2.put("test", "test"); - createPod("stratos-test-pod-2", "stratos-test-pod", podLabels2, podAnnocations2, "http-1", "2", "4Gi"); + createPod("stratos-test-pod-2", "stratos-test-pod", podLabels2, podAnnocations2, "http-1", "2", "4Gi", null, null); deletePod("stratos-test-pod-1"); deletePod("stratos-test-pod-2"); @@ -95,13 +95,13 @@ public class KubernetesApiClientLiveTest extends AbstractLiveTest { podLabels3.put("applicationId", "my-application-3"); Map<String, String> podAnnocations3 = new HashMap<>(); podAnnocations3.put("test", "test"); - createPod("stratos-test-pod-3", serviceName, podLabels3, podAnnocations3, containerPortName, "1", "512"); + createPod("stratos-test-pod-3", serviceName, podLabels3, podAnnocations3, containerPortName, "1", "512", null, null); Map<String, String> podLabels4 = new HashMap<>(); podLabels4.put("applicationId", "my-application-4"); Map<String, String> podAnnocations4 = new HashMap<>(); podAnnocations4.put("test", "test"); - createPod("stratos-test-pod-4", serviceName, podLabels4, podAnnocations4, containerPortName, "2", "512"); + createPod("stratos-test-pod-4", serviceName, podLabels4, podAnnocations4, containerPortName, "2", "512", null, null); if (testServiceSocket) { // test service accessibility http://git-wip-us.apache.org/repos/asf/stratos/blob/4b04a518/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/message/processor/application/signup/CompleteApplicationSignUpsMessageProcessor.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/message/processor/application/signup/CompleteApplicationSignUpsMessageProcessor.java b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/message/processor/application/signup/CompleteApplicationSignUpsMessageProcessor.java index c838d67..831aea1 100644 --- a/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/message/processor/application/signup/CompleteApplicationSignUpsMessageProcessor.java +++ b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/message/processor/application/signup/CompleteApplicationSignUpsMessageProcessor.java @@ -72,12 +72,14 @@ public class CompleteApplicationSignUpsMessageProcessor extends MessageProcessor } } - if(!DomainMappingManager.getInstance().isInitialized()) { + if (!DomainMappingManager.getInstance().isInitialized()) { try { DomainMappingManager.acquireWriteLock(); for (ApplicationSignUp applicationSignUp : event.getApplicationSignUps()) { - DomainMappingManager.getInstance().addDomainMappings( - Arrays.asList(applicationSignUp.getDomainMappings())); + if (applicationSignUp.getDomainMappings() != null) { + DomainMappingManager.getInstance().addDomainMappings( + Arrays.asList(applicationSignUp.getDomainMappings())); + } } DomainMappingManager.getInstance().setInitialized(true); log.info("Domain mappings initialized"); http://git-wip-us.apache.org/repos/asf/stratos/blob/4b04a518/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41Utils.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41Utils.java b/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41Utils.java index ffe2a24..565a2fb 100644 --- a/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41Utils.java +++ b/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41Utils.java @@ -28,6 +28,9 @@ import org.apache.stratos.autoscaler.stub.pojo.ApplicationContext; import org.apache.stratos.autoscaler.stub.pojo.ServiceGroup; import org.apache.stratos.cloud.controller.stub.*; import org.apache.stratos.cloud.controller.stub.domain.Cartridge; +import org.apache.stratos.cloud.controller.stub.Property; +import org.apache.stratos.cloud.controller.stub.domain.NetworkPartition; +import org.apache.stratos.cloud.controller.stub.domain.Partition; import org.apache.stratos.common.beans.IaasProviderInfoBean; import org.apache.stratos.common.beans.PropertyBean; import org.apache.stratos.common.beans.TenantInfoBean; @@ -2101,11 +2104,50 @@ public class StratosApiV41Utils { = ObjectConverter.convertToCCKubernetesClusterPojo(kubernetesClusterBean); try { + ApplicationContext[] applicationContexts = AutoscalerServiceClient.getInstance().getApplications(); + if (applicationContexts != null) { + for (ApplicationContext applicationContext : applicationContexts) { + if (applicationContext != null && applicationContext.getStatus(). + equals(APPLICATION_STATUS_DEPLOYED)) { + String[] networkPartitions = AutoscalerServiceClient.getInstance(). + getApplicationNetworkPartitions(applicationContext.getApplicationId()); + if (isKubernetesClusterUsedInNetworkPartition(networkPartitions, + kubernetesCluster.getClusterId())) { + throw new RestAPIException("Kubernetes cluster cannot be updated." + + "Kubernetes cluster already in use by running application [applicationid]" + + applicationContext.getApplicationId() + ". Please undeploy the application to " + + "update Kubernetes cluster."); + } + } + } + } return cloudControllerServiceClient.deployKubernetesCluster(kubernetesCluster); } catch (RemoteException e) { log.error(e.getMessage(), e); throw new RestAPIException(e.getMessage(), e); + } catch (AutoscalerServiceAutoScalerExceptionException e) { + log.error(e.getMessage(), e); + throw new RestAPIException(e.getMessage(), e); + } + } + return false; + } + + public static boolean isKubernetesClusterUsedInNetworkPartition(String networkPartitions[], String kubernetesClusterID) + throws RemoteException { + for (String networkPartition : networkPartitions) { + NetworkPartition networkPartitionsContext + = CloudControllerServiceClient.getInstance().getNetworkPartition(networkPartition); + Partition partitions[] = networkPartitionsContext.getPartitions(); + for (Partition partition : partitions) { + Property[] properties = partition.getProperties().getProperties(); + for (Property property : properties) { + if (property.getValue().equals(kubernetesClusterID)) { + return true; + } + } } + } return false; } http://git-wip-us.apache.org/repos/asf/stratos/blob/4b04a518/samples/kubernetes-clusters/kubernetes-cluster-1.json ---------------------------------------------------------------------- diff --git a/samples/kubernetes-clusters/kubernetes-cluster-1.json b/samples/kubernetes-clusters/kubernetes-cluster-1.json index 6862106..268209a 100644 --- a/samples/kubernetes-clusters/kubernetes-cluster-1.json +++ b/samples/kubernetes-clusters/kubernetes-cluster-1.json @@ -7,6 +7,10 @@ "privateIPAddress": "172.17.8.101", "publicIPAddress": "172.17.8.101", "property": [ + { + "name": "KUBERNETES_MASTER_PORT", + "value": "8080" + } ] }, "portRange": { http://git-wip-us.apache.org/repos/asf/stratos/blob/4b04a518/samples/kubernetes-clusters/kubernetes-cluster-2.json ---------------------------------------------------------------------- diff --git a/samples/kubernetes-clusters/kubernetes-cluster-2.json b/samples/kubernetes-clusters/kubernetes-cluster-2.json index ebc7613..c62cc32 100644 --- a/samples/kubernetes-clusters/kubernetes-cluster-2.json +++ b/samples/kubernetes-clusters/kubernetes-cluster-2.json @@ -7,6 +7,10 @@ "privateIPAddress": "172.17.8.101", "publicIPAddress": "172.17.8.101", "property": [ + { + "name": "KUBERNETES_MASTER_PORT", + "value": "8080" + } ] }, "portRange": { http://git-wip-us.apache.org/repos/asf/stratos/blob/4b04a518/samples/kubernetes-clusters/kubernetes-cluster-3.json ---------------------------------------------------------------------- diff --git a/samples/kubernetes-clusters/kubernetes-cluster-3.json b/samples/kubernetes-clusters/kubernetes-cluster-3.json new file mode 100644 index 0000000..e29a70c --- /dev/null +++ b/samples/kubernetes-clusters/kubernetes-cluster-3.json @@ -0,0 +1,60 @@ +{ + "clusterId": "kubernetes-cluster-3", + "description": "Kubernetes Cluster 3", + "kubernetesMaster": { + "hostId": "master", + "hostname": "master.dev.kubernetes.org", + "privateIPAddress": "172.17.8.101", + "publicIPAddress": "172.17.8.101", + "property": [ + { + "name": "KUBERNETES_MASTER_PORT", + "value": "8080" + }, + { + "name": "KUBERNETES_NAMESPACE", + "value": "namespace-1" + } + ] + }, + "portRange": { + "upper": "32767", + "lower": "30000" + }, + "kubernetesHosts": [ + { + "hostId": "minion-1", + "hostname": "minion-1.dev.kubernetes.org", + "privateIPAddress": "172.17.8.102", + "publicIPAddress": "172.17.8.102", + "property": [ + ] + } + ], + "property": [ + { + "name": "payload_parameter.MB_URLS", + "value": "172.17.8.1:1883" + }, + { + "name": "payload_parameter.MB_USERNAME", + "value": "system" + }, + { + "name": "payload_parameter.MB_PASSWORD", + "value": "manager" + }, + { + "name": "payload_parameter.CEP_URLS", + "value": "172.17.8.1:7711" + }, + { + "name": "payload_parameter.LOG_LEVEL", + "value": "DEBUG" + }, + { + "name": "payload_parameter.METADATA_SERVICE_URL", + "value": "https://172.17.8.1:9443" + } + ] +} \ No newline at end of file
