diff --git a/spring-cloud-deployer-kubernetes/src/main/java/org/springframework/cloud/deployer/spi/kubernetes/DefaultContainerFactory.java b/spring-cloud-deployer-kubernetes/src/main/java/org/springframework/cloud/deployer/spi/kubernetes/DefaultContainerFactory.java index 5968f2bc..74a29787 100644 --- a/spring-cloud-deployer-kubernetes/src/main/java/org/springframework/cloud/deployer/spi/kubernetes/DefaultContainerFactory.java +++ b/spring-cloud-deployer-kubernetes/src/main/java/org/springframework/cloud/deployer/spi/kubernetes/DefaultContainerFactory.java @@ -170,7 +170,8 @@ public Container create(ContainerConfiguration containerConfiguration) { ContainerBuilder container = new ContainerBuilder(); container.withName(containerConfiguration.getAppId()).withImage(image).withEnv(envVars).withEnvFrom(envFromSources) - .withArgs(appArgs).withVolumeMounts(deploymentPropertiesResolver.getVolumeMounts(deploymentProperties)); + .withArgs(appArgs).withImagePullPolicy(deploymentPropertiesResolver.getImagePullPolicy(deploymentProperties)) + .withVolumeMounts(deploymentPropertiesResolver.getVolumeMounts(deploymentProperties)); Set ports = new HashSet<>(); 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 2e5e673e..cd9bd442 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 @@ -380,6 +380,11 @@ Map getNodeSelectors(Map deploymentProperties) { return nodeSelectors; } + String getImagePullPolicy(Map kubernetesDeployerProperties) { + ImagePullPolicy imagePullPolicy = deduceImagePullPolicy(kubernetesDeployerProperties); + return imagePullPolicy != null ? imagePullPolicy.name() : null; + } + String getImagePullSecret(Map kubernetesDeployerProperties) { String imagePullSecret = PropertyParserUtils.getDeploymentPropertyValue(kubernetesDeployerProperties, this.propertyPrefix + ".imagePullSecret", ""); @@ -643,16 +648,16 @@ Collection getInitContainers(Map kubernetesDeployerPr } private @Nullable Container initContainerFromProperties(Map kubeProps, String propertyKey) { - String containerName = PropertyParserUtils.getDeploymentPropertyValue(kubeProps, propertyKey + ".containerName"); - String imageName = PropertyParserUtils.getDeploymentPropertyValue(kubeProps, propertyKey + ".imageName"); - if (StringUtils.hasText(containerName) && StringUtils.hasText(imageName)) { - String commandsStr = PropertyParserUtils.getDeploymentPropertyValue(kubeProps, propertyKey + ".commands"); - List commands = StringUtils.hasText(commandsStr) ? Arrays.asList(commandsStr.split(",")) : Collections.emptyList(); - String envString = PropertyParserUtils.getDeploymentPropertyValue(kubeProps, propertyKey + ".environmentVariables"); + String name = getFirstProperty(kubeProps, propertyKey, ".name", ".containerName"); + String image = getFirstProperty(kubeProps, propertyKey, ".image", ".imageName"); + if (StringUtils.hasText(name) && StringUtils.hasText(image)) { + String commandStr = getFirstProperty(kubeProps, propertyKey, ".command", ".commands"); + List commands = StringUtils.hasText(commandStr) ? Arrays.asList(commandStr.split(",")) : Collections.emptyList(); + String envString = getFirstProperty(kubeProps, propertyKey, ".env", ".environmentVariables"); List vms = this.getInitContainerVolumeMounts(kubeProps, propertyKey); return new ContainerBuilder() - .withName(containerName) - .withImage(imageName) + .withName(name) + .withImage(image) .withCommand(commands) .withEnv(toEnvironmentVariables((envString != null) ? envString.split(",") : new String[0])) .addAllToVolumeMounts(vms) @@ -661,11 +666,21 @@ Collection getInitContainers(Map kubernetesDeployerPr return null; } + public static String getFirstProperty(Map kubeProps, String baseKey, String... suffixes) { + for (String suffix : suffixes) { + String value = PropertyParserUtils.getDeploymentPropertyValue(kubeProps, baseKey + suffix); + if (StringUtils.hasText(value)) { + return value; + } + } + return null; + } + private Container containerFromProps(InitContainer initContainerProps) { return new ContainerBuilder() - .withName(initContainerProps.getContainerName()) - .withImage(initContainerProps.getImageName()) - .withCommand(initContainerProps.getCommands()) + .withName(initContainerProps.getName()) + .withImage(initContainerProps.getImage()) + .withCommand(initContainerProps.getCommand()) .withArgs(initContainerProps.getArgs()) .withEnv(toEnvironmentVariables(initContainerProps.getEnvironmentVariables())) .addAllToVolumeMounts(Optional.ofNullable(initContainerProps.getVolumeMounts()).orElse(Collections.emptyList())) 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 e8f07135..1ac2d968 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 @@ -19,6 +19,8 @@ import java.util.ArrayList; import java.util.List; +import com.fasterxml.jackson.annotation.JsonAlias; +import com.fasterxml.jackson.annotation.JsonProperty; import io.fabric8.kubernetes.api.model.NodeAffinity; import io.fabric8.kubernetes.api.model.PodAffinity; import io.fabric8.kubernetes.api.model.PodAntiAffinity; @@ -980,42 +982,72 @@ static class Container extends io.fabric8.kubernetes.api.model.Container { } public static class ContainerProperties { - private String imageName; - - private String containerName; - - private List commands; - private List args; - private List volumeMounts; + @JsonAlias("imageName") + @JsonProperty("image") + private String image; + @JsonAlias("containerName") + @JsonProperty("name") + private String name; + @JsonProperty("command") + @JsonAlias("commands") + private List command; + private List args; + private List volumeMounts; /** * Environment variables to set for any deployed init container. */ private String[] environmentVariables = new String[]{}; - public String getImageName() { - return imageName; - } + public String getName() { + return name; + } - public void setImageName(String imageName) { - this.imageName = imageName; - } + public void setName(String name) { + this.name = name; + } + @Deprecated + public String getImageName() { + return getImage(); + } + @Deprecated + public void setImageName(String image) { + setImage(image); + } + public String getImage() { + return image; + } - public String getContainerName() { - return containerName; - } + public void setImage(String image) { + this.image = image; + } - public void setContainerName(String containerName) { - this.containerName = containerName; - } + @Deprecated + public String getContainerName() { + return getName(); + } - public List getCommands() { - return commands; - } + @Deprecated + public void setContainerName(String containerName) { + setName(containerName); + } - public void setCommands(List commands) { - this.commands = commands; - } + public List getCommand() { + return command; + } + + public void setCommand(List command) { + this.command = command; + } + @Deprecated + public List getCommands() { + return getCommand(); + } + + @Deprecated + public void setCommands(List commands) { + setCommand(commands); + } public List getArgs() { return args; diff --git a/spring-cloud-deployer-kubernetes/src/test/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesAppDeployerIntegrationIT.java b/spring-cloud-deployer-kubernetes/src/test/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesAppDeployerIntegrationIT.java index a1b72fdd..fd3ae79e 100644 --- a/spring-cloud-deployer-kubernetes/src/test/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesAppDeployerIntegrationIT.java +++ b/spring-cloud-deployer-kubernetes/src/test/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesAppDeployerIntegrationIT.java @@ -1327,9 +1327,9 @@ public void testCreateInitContainerWithEnvVariables() { public void initContainerFromGlobalProps() { // Set up a global initContainer (it should be chosen) KubernetesDeployerProperties.InitContainer globalInitContainerProps = new KubernetesDeployerProperties.InitContainer(); - globalInitContainerProps.setContainerName("test-global"); - globalInitContainerProps.setImageName("busybox:latest"); - globalInitContainerProps.setCommands(Arrays.asList("sh", "-c", "echo hello-global")); + globalInitContainerProps.setName("test-global"); + globalInitContainerProps.setImage("busybox:latest"); + globalInitContainerProps.setCommand(Arrays.asList("sh", "-c", "echo hello-global")); KubernetesDeployerProperties kubernetesDeployerProperties = new KubernetesDeployerProperties(); kubernetesDeployerProperties.setInitContainer(globalInitContainerProps); 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..7476fd78 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 @@ -931,15 +931,21 @@ public void testMultipleInitContainerProperties() { props.put("spring.cloud.deployer.kubernetes.initContainers[1].imageName", "busybox:2"); props.put("spring.cloud.deployer.kubernetes.initContainers[1].containerName", "bb_s2"); props.put("spring.cloud.deployer.kubernetes.initContainers[1].commands", "sh,-c,script2.sh"); - props.put("spring.cloud.deployer.kubernetes.initContainers[2]", "{ \"imageName\": \"busybox:3\", \"containerName\": \"bb_s3\", \"args\": [\"-c\", \"script3.sh\"], \"volumeMounts\": [{\"mountPath\": \"/data\", \"name\": \"s3vol\", \"readOnly\": true}] }"); + props.put("spring.cloud.deployer.kubernetes.initContainers[1].environmentVariables", "foo=baz"); - AppDefinition definition = new AppDefinition("app-test", null); + props.put("spring.cloud.deployer.kubernetes.initContainers[2]", "{ \"image\": \"busybox:3\", \"name\": \"bb_s3\", \"args\": [\"-c\", \"script3.sh\"], \"volumeMounts\": [{\"mountPath\": \"/data\", \"name\": \"s3vol\", \"readOnly\": true}] }"); + props.put("spring.cloud.deployer.kubernetes.initContainers[3].image", "busybox:2"); + props.put("spring.cloud.deployer.kubernetes.initContainers[3].name", "bb_s4"); + props.put("spring.cloud.deployer.kubernetes.initContainers[3].command", "sh,-c,script4.sh"); + props.put("spring.cloud.deployer.kubernetes.initContainers[3].env", "foo=bar"); + + 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(3); + assertThat(podSpec.getInitContainers().size()).isEqualTo(4); Container container0 = podSpec.getInitContainers().get(0); assertThat(container0.getImage()).isEqualTo("busybox:1"); assertThat(container0.getName()).isEqualTo("bb_s1"); @@ -948,7 +954,8 @@ public void testMultipleInitContainerProperties() { assertThat(container1.getImage()).isEqualTo("busybox:2"); assertThat(container1.getName()).isEqualTo("bb_s2"); assertThat(container1.getCommand()).containsExactly("sh", "-c", "script2.sh"); - Container container2 = podSpec.getInitContainers().get(2); + assertThat(container1.getEnv()).isEqualTo(Collections.singletonList(new EnvVar("foo","baz", null))); + Container container2 = podSpec.getInitContainers().get(2); assertThat(container2.getImage()).isEqualTo("busybox:3"); assertThat(container2.getName()).isEqualTo("bb_s3"); assertThat(container2.getArgs()).containsExactly("-c", "script3.sh"); @@ -956,7 +963,12 @@ public void testMultipleInitContainerProperties() { assertThat(container2.getVolumeMounts().get(0).getName()).isEqualTo("s3vol"); assertThat(container2.getVolumeMounts().get(0).getMountPath()).isEqualTo("/data"); assertThat(container2.getVolumeMounts().get(0).getReadOnly()).isTrue(); - } + Container container3 = podSpec.getInitContainers().get(3); + assertThat(container3.getImage()).isEqualTo("busybox:2"); + assertThat(container3.getName()).isEqualTo("bb_s4"); + assertThat(container3.getCommand()).containsExactly("sh", "-c", "script4.sh"); + assertThat(container3.getEnv()).isEqualTo(Collections.singletonList(new EnvVar("foo","bar", null))); + } @Test public void testNodeAffinityProperty() {