diff --git a/spring-cloud-deployer-kubernetes/src/main/java/org/springframework/cloud/deployer/spi/kubernetes/DeploymentPropertiesResolver.java b/spring-cloud-deployer-kubernetes/src/main/java/org/springframework/cloud/deployer/spi/kubernetes/DeploymentPropertiesResolver.java index 5aea716c..df40d9d1 100644 --- a/spring-cloud-deployer-kubernetes/src/main/java/org/springframework/cloud/deployer/spi/kubernetes/DeploymentPropertiesResolver.java +++ b/spring-cloud-deployer-kubernetes/src/main/java/org/springframework/cloud/deployer/spi/kubernetes/DeploymentPropertiesResolver.java @@ -38,7 +38,11 @@ import io.fabric8.kubernetes.api.model.ContainerBuilder; import io.fabric8.kubernetes.api.model.EnvFromSource; import io.fabric8.kubernetes.api.model.EnvVar; +import io.fabric8.kubernetes.api.model.EnvVarBuilder; import io.fabric8.kubernetes.api.model.EnvVarSource; +import io.fabric8.kubernetes.api.model.EnvVarSourceBuilder; +import io.fabric8.kubernetes.api.model.ObjectFieldSelector; +import io.fabric8.kubernetes.api.model.ObjectFieldSelectorBuilder; import io.fabric8.kubernetes.api.model.PodSecurityContext; import io.fabric8.kubernetes.api.model.PodSecurityContextBuilder; import io.fabric8.kubernetes.api.model.Quantity; @@ -663,12 +667,21 @@ Collection getInitContainers(Map kubernetesDeployerPr } private Container containerFromProps(InitContainer initContainerProps) { + List envVarList = new ArrayList<>(); + envVarList.addAll(toEnvironmentVariables(initContainerProps.getEnvironmentVariables())); + envVarList.addAll(toEnvironmentVariablesFromFieldRef(initContainerProps.getEnvironmentVariablesFromFieldRefs())); + + List envFromSourceList = new ArrayList<>(); + envFromSourceList.addAll(Arrays.stream(initContainerProps.getConfigMapRefEnvVars()).map(this::buildConfigMapRefEnvVar).collect(Collectors.toList())); + envFromSourceList.addAll(Arrays.stream(initContainerProps.getSecretRefEnvVars()).map(this::buildSecretRefEnvVar).collect(Collectors.toList())); + return new ContainerBuilder() .withName(initContainerProps.getContainerName()) .withImage(initContainerProps.getImageName()) .withCommand(initContainerProps.getCommands()) .withArgs(initContainerProps.getArgs()) - .withEnv(toEnvironmentVariables(initContainerProps.getEnvironmentVariables())) + .withEnv(envVarList) + .withEnvFrom(envFromSourceList) .addAllToVolumeMounts(Optional.ofNullable(initContainerProps.getVolumeMounts()).orElse(Collections.emptyList())) .build(); } @@ -690,6 +703,22 @@ private List toEnvironmentVariables(String[] environmentVariables) { return envVars; } + private List toEnvironmentVariablesFromFieldRef(String[] environmentVariablesFromFieldRef) { + Map envVarsMap = new HashMap<>(); + if (environmentVariablesFromFieldRef != null) { + for (String envVar : environmentVariablesFromFieldRef) { + String[] strings = envVar.split("=", 2); + Assert.isTrue(strings.length == 2, "Invalid environment variable declared from field ref: " + envVar); + envVarsMap.put(strings[0], strings[1]); + } + } + return envVarsMap.entrySet().stream() + .map(e -> { + ObjectFieldSelector fieldSelector = new ObjectFieldSelectorBuilder().withFieldPath(e.getValue()).build(); + return new EnvVar(e.getKey(), null, new EnvVarSourceBuilder().withFieldRef(fieldSelector).build()); + }).collect(Collectors.toList()); + } + List getAdditionalContainers(Map deploymentProperties) { List containers = new ArrayList<>(); diff --git a/spring-cloud-deployer-kubernetes/src/main/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesDeployerProperties.java b/spring-cloud-deployer-kubernetes/src/main/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesDeployerProperties.java index 089adcf4..3ff10b05 100755 --- a/spring-cloud-deployer-kubernetes/src/main/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesDeployerProperties.java +++ b/spring-cloud-deployer-kubernetes/src/main/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesDeployerProperties.java @@ -1005,6 +1005,9 @@ public static class ContainerProperties { * Environment variables to set for any deployed init container. */ private String[] environmentVariables = new String[]{}; + private String[] environmentVariablesFromFieldRefs = new String[]{}; + private String[] configMapRefEnvVars = new String[]{}; + private String[] secretRefEnvVars = new String[]{}; public String getImageName() { return imageName; @@ -1052,6 +1055,30 @@ public String[] getEnvironmentVariables() { public void setEnvironmentVariables(String[] environmentVariables) { this.environmentVariables = environmentVariables; + } + + public String[] getEnvironmentVariablesFromFieldRefs() { + return environmentVariablesFromFieldRefs; + } + + public void setEnvironmentVariablesFromFieldRefs(String[] environmentVariablesFromFieldRefs) { + this.environmentVariablesFromFieldRefs = environmentVariablesFromFieldRefs; + } + + public String[] getConfigMapRefEnvVars() { + return configMapRefEnvVars; + } + + public void setConfigMapRefEnvVars(String[] configMapRefEnvVars) { + this.configMapRefEnvVars = configMapRefEnvVars; + } + + public String[] getSecretRefEnvVars() { + return secretRefEnvVars; + } + + public void setSecretRefEnvVars(String[] secretRefEnvVars) { + this.secretRefEnvVars = secretRefEnvVars; } } diff --git a/spring-cloud-deployer-kubernetes/src/test/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesAppDeployerTests.java b/spring-cloud-deployer-kubernetes/src/test/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesAppDeployerTests.java index eb736990..60d5eaf8 100644 --- a/spring-cloud-deployer-kubernetes/src/test/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesAppDeployerTests.java +++ b/spring-cloud-deployer-kubernetes/src/test/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesAppDeployerTests.java @@ -28,11 +28,14 @@ import io.fabric8.kubernetes.api.model.AffinityBuilder; import io.fabric8.kubernetes.api.model.Capabilities; +import io.fabric8.kubernetes.api.model.ConfigMapEnvSourceBuilder; import io.fabric8.kubernetes.api.model.ConfigMapKeySelector; import io.fabric8.kubernetes.api.model.ConfigMapVolumeSource; import io.fabric8.kubernetes.api.model.ConfigMapVolumeSourceBuilder; import io.fabric8.kubernetes.api.model.Container; +import io.fabric8.kubernetes.api.model.EnvFromSource; import io.fabric8.kubernetes.api.model.EnvVar; +import io.fabric8.kubernetes.api.model.EnvVarSourceBuilder; import io.fabric8.kubernetes.api.model.HostPathVolumeSource; import io.fabric8.kubernetes.api.model.HostPathVolumeSourceBuilder; import io.fabric8.kubernetes.api.model.KeyToPath; @@ -41,6 +44,7 @@ import io.fabric8.kubernetes.api.model.NodeAffinity; import io.fabric8.kubernetes.api.model.NodeSelectorRequirementBuilder; import io.fabric8.kubernetes.api.model.NodeSelectorTerm; +import io.fabric8.kubernetes.api.model.ObjectFieldSelectorBuilder; import io.fabric8.kubernetes.api.model.PodAffinity; import io.fabric8.kubernetes.api.model.PodAffinityTerm; import io.fabric8.kubernetes.api.model.PodAntiAffinity; @@ -50,6 +54,7 @@ import io.fabric8.kubernetes.api.model.PreferredSchedulingTerm; import io.fabric8.kubernetes.api.model.SELinuxOptions; import io.fabric8.kubernetes.api.model.SeccompProfile; +import io.fabric8.kubernetes.api.model.SecretEnvSourceBuilder; import io.fabric8.kubernetes.api.model.SecretKeySelector; import io.fabric8.kubernetes.api.model.SecurityContext; import io.fabric8.kubernetes.api.model.SecurityContextBuilder; @@ -924,6 +929,30 @@ public void testInitContainerJsonArrayProperties() { assertThat(container.getName()).isEqualTo("bb_s1"); assertThat(container.getCommand()).containsExactly("sh", "-c", "script1.sh"); } + + @Test + public void testInitContainerEnvironmentVariables() { + Map props = new HashMap<>(); + props.put("spring.cloud.deployer.kubernetes.initContainers[0]", "{ \"imageName\": \"busybox:1\", \"environmentVariablesFromFieldRefs\": [\"POD_UID=metadata.uid\"] }"); + props.put("spring.cloud.deployer.kubernetes.initContainers[1]", "{ \"imageName\": \"busybox:2\", \"configMapRefEnvVars\": [\"myConfigMap\"], \"secretRefEnvVars\": [\"mySecret\"] }"); + + AppDefinition definition = new AppDefinition("app-test", null); + AppDeploymentRequest appDeploymentRequest = new AppDeploymentRequest(definition, getResource(), props); + + deployer = k8sAppDeployer(new KubernetesDeployerProperties()); + PodSpec podSpec = deployer.createPodSpec(appDeploymentRequest); + assertThat(podSpec.getInitContainers()).isNotEmpty(); + assertThat(podSpec.getInitContainers().size()).isEqualTo(2); + Container container0 = podSpec.getInitContainers().get(0); + assertThat(container0.getImage()).isEqualTo("busybox:1"); + assertThat(container0.getEnv().get(0).getName()).isEqualTo("POD_UID"); + assertThat(container0.getEnv().get(0).getValueFrom().getFieldRef().getFieldPath()).isEqualTo("metadata.uid"); + Container container1 = podSpec.getInitContainers().get(1); + assertThat(container1.getImage()).isEqualTo("busybox:2"); + assertThat(container1.getEnvFrom().get(0).getConfigMapRef().getName()).isEqualTo("myConfigMap"); + assertThat(container1.getEnvFrom().get(0).getSecretRef().getName()).isEqualTo("mySecret"); + } + @Test public void testMultipleInitContainerProperties() { Map props = new HashMap<>();