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 3ee2d39260..8008c47cde 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 @@ -68,15 +68,18 @@ public class KubernetesIaas extends Iaas { 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"; + public static final String IMAGE_PULL_SECRETS = "IMAGE_PULL_SECRETS"; private PartitionValidator partitionValidator; private List payload; private Long podActivationTimeout; + private List imagePullSecrets; public KubernetesIaas(IaasProvider iaasProvider) { super(iaasProvider); partitionValidator = new KubernetesPartitionValidator(); - payload = new ArrayList(); + payload = new ArrayList<>(); + imagePullSecrets = new ArrayList<>(); podActivationTimeout = Long.getLong("stratos.pod.activation.timeout"); if (podActivationTimeout == null) { @@ -104,19 +107,17 @@ public void setDynamicPayload(byte[] payloadByteArray) { if (payloadByteArray != null) { String payloadString = new String(payloadByteArray); String[] parameterArray = payloadString.split(PAYLOAD_PARAMETER_SEPARATOR); - if (parameterArray != null) { - for (String parameter : parameterArray) { - if (parameter != null) { - String[] nameValueArray = parameter.split(PAYLOAD_PARAMETER_NAME_VALUE_SEPARATOR, 2); - if ((nameValueArray != null) && (nameValueArray.length == 2)) { - NameValuePair nameValuePair = new NameValuePair(nameValueArray[0], nameValueArray[1]); - payload.add(nameValuePair); - } + for (String parameter : parameterArray) { + if (parameter != null) { + String[] nameValueArray = parameter.split(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()); } } } @@ -209,6 +210,10 @@ public MemberContext startContainer(MemberContext memberContext) throws Cartridg if (property.getName().startsWith(PAYLOAD_PARAMETER_PREFIX)) { String name = property.getName().replace(PAYLOAD_PARAMETER_PREFIX, ""); payload.add(new NameValuePair(name, property.getValue())); + }else{ + if (property.getName().equals(IMAGE_PULL_SECRETS)){ + imagePullSecrets.add(property.getValue()); + } } } } @@ -449,7 +454,7 @@ private void createPod(ClusterContext clusterContext, MemberContext memberContex podAnnotations.put(CloudControllerConstants.MEMBER_ID_LABEL, memberContext.getMemberId()); kubernetesApi.createPod(podId, podName, podLabels, podAnnotations, dockerImage, cpu, memory, ports, - environmentVariables); + environmentVariables, imagePullSecrets); log.info(String.format("Pod started successfully: [application] %s [cartridge] %s [member] %s " + "[pod] %s [pod-label] %s [cpu] %s [memory] %s", memberContext.getApplicationId(), 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 b231736fb4..7818a33e99 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 @@ -54,12 +54,13 @@ public KubernetesApiClient(String endpointUrl) { * @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 * @throws KubernetesClientException */ @Override public void createPod(String podId, String podName, Map podLabels, Map annotations, - String dockerImage, String cpu, - String memory, List ports, List environmentVariables) + String dockerImage, String cpu, String memory, List ports, + List environmentVariables, List imagePullSecrets) throws KubernetesClientException { try { @@ -88,6 +89,19 @@ public void createPod(String podId, String podName, Map podLabel containerTemplates.add(containerTemplate); pod.getSpec().setContainers(containerTemplates); + // set imagePullSecrets + if ((imagePullSecrets != null) && (imagePullSecrets.size() > 0)) { + List 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 limits = new HashMap(); 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 2a4a8dd2ed..08bdfbcf9f 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 @@ -35,4 +35,5 @@ 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"; } 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 9b42966e24..17759c2057 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 @@ -44,11 +44,12 @@ public interface KubernetesAPIClientInterface { * @param memory memory allocation in mega bytes * @param ports ports to be opened * @param environmentVariables environment variables + * @param imagePullSecrets Image Pull Secret to be passed to the pod * @throws KubernetesClientException */ public void createPod(String podId, String podName, Map podLabels, Map annotations, String dockerImage, String cpu, String memory, List ports, - List environmentVariables) + List environmentVariables, List imagePullSecrets) throws KubernetesClientException; /** 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 842c6721d0..765bec2a23 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 @@ -125,12 +125,12 @@ public void tearDown() { } protected void createPod(String podId, String podName, Map labelMap, Map - annotations, String containerPortName, String cpu, String memory) + annotations, String containerPortName, String cpu, String memory, List imagePullSecrets) throws KubernetesClientException { log.info("Creating pod: [pod] " + podId); List 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); podIdList.add(podId); sleep(2000); 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 ea10c97b70..343dead93b 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 void testPodCreation() throws Exception { podLabels1.put("applicationId", "my-application-1"); Map 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); Map podLabels2 = new HashMap<>(); podLabels2.put("applicationId", "my-application-2"); Map 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); deletePod("stratos-test-pod-1"); deletePod("stratos-test-pod-2"); @@ -95,13 +95,13 @@ public void testServiceCreation() throws Exception { podLabels3.put("applicationId", "my-application-3"); Map 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); Map podLabels4 = new HashMap<>(); podLabels4.put("applicationId", "my-application-4"); Map 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); if (testServiceSocket) { // test service accessibility diff --git a/samples/kubernetes-clusters/kubernetes-cluster-secret.json b/samples/kubernetes-clusters/kubernetes-cluster-secret.json new file mode 100644 index 0000000000..18b1697157 --- /dev/null +++ b/samples/kubernetes-clusters/kubernetes-cluster-secret.json @@ -0,0 +1,64 @@ +{ + "clusterId": "kubernetes-cluster-1", + "description": "Kubernetes Cluster 1", + "kubernetesMaster": { + "hostId": "master", + "hostname": "master.dev.kubernetes.org", + "privateIPAddress": "172.17.8.101", + "publicIPAddress": "172.17.8.101", + "property": [ + ] + }, + "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": [ + ] + }, + { + "hostId": "minion-2", + "hostname": "minion-2.dev.kubernetes.org", + "privateIPAddress": "172.17.8.103", + "publicIPAddress": "172.17.8.103", + "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" + }, + { + "name": "IMAGE_PULL_SECRETS", + "value": "privateDockerSecret" + } + ] +}