From b84205de8ca39adb2b4428c0d96ead5732c830cc Mon Sep 17 00:00:00 2001 From: Ioannis Canellos Date: Tue, 24 Jan 2023 12:04:09 +0200 Subject: [PATCH 1/4] feat: allow configuring port of http probes --- .../deployment/KubernetesCommonHelper.java | 23 +++++++ .../deployment/OpenshiftProcessor.java | 5 +- .../kubernetes/deployment/ProbeConfig.java | 13 ++++ .../VanillaKubernetesProcessor.java | 5 +- .../KubernetesWithProbePortTest.java | 65 +++++++++++++++++++ 5 files changed, 105 insertions(+), 6 deletions(-) create mode 100644 integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithProbePortTest.java diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesCommonHelper.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesCommonHelper.java index 9f6838391ae96..8f622e9c87119 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesCommonHelper.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesCommonHelper.java @@ -2,6 +2,7 @@ package io.quarkus.kubernetes.deployment; import static io.dekorate.kubernetes.decorator.AddServiceResourceDecorator.distinct; +import static io.quarkus.kubernetes.deployment.Constants.DEFAULT_HTTP_PORT; import static io.quarkus.kubernetes.deployment.Constants.QUARKUS_ANNOTATIONS_BUILD_TIMESTAMP; import static io.quarkus.kubernetes.deployment.Constants.QUARKUS_ANNOTATIONS_COMMIT_ID; import static io.quarkus.kubernetes.deployment.Constants.QUARKUS_ANNOTATIONS_VCS_URL; @@ -687,6 +688,28 @@ private static List createAnnotationDecorators(Optional ports) { + + //1. check if `httpActionPort` is defined + //2. lookup port by `httpPortName` + //3. fallback to DEFAULT_HTTP_PORT + Integer port = probeConfig.httpActionPort + .orElse(ports.stream().filter(p -> probeConfig.httpActionPortName.equals(p.getName())) + .map(KubernetesPortBuildItem::getPort).findFirst().orElse(DEFAULT_HTTP_PORT)); + return new DecoratorBuildItem(target, new ApplyHttpGetActionPortDecorator(name, name, port)); + } + + /** + * Create the decorators needed for setting up probes. + * The method will not create decorators related to ports, as they are not supported by all targets (e.g. knative) + * Port related decorators are created by `applyProbePort` instead. + * + * @return a list of decorators that configure the probes + */ private static List createProbeDecorators(String name, String target, ProbeConfig livenessProbe, ProbeConfig readinessProbe, Optional livenessPath, diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftProcessor.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftProcessor.java index d73924830a867..9a09f2c932b8e 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftProcessor.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftProcessor.java @@ -1,7 +1,6 @@ package io.quarkus.kubernetes.deployment; -import static io.quarkus.kubernetes.deployment.Constants.DEFAULT_HTTP_PORT; import static io.quarkus.kubernetes.deployment.Constants.DEFAULT_S2I_IMAGE_NAME; import static io.quarkus.kubernetes.deployment.Constants.OPENSHIFT; import static io.quarkus.kubernetes.deployment.Constants.OPENSHIFT_APP_RUNTIME; @@ -301,8 +300,8 @@ public List createDecorators(ApplicationInfoBuildItem applic } // Probe port handling - Integer portNumber = port.map(Port::getContainerPort).orElse(DEFAULT_HTTP_PORT); - result.add(new DecoratorBuildItem(OPENSHIFT, new ApplyHttpGetActionPortDecorator(name, name, portNumber))); + result.add(KubernetesCommonHelper.createProbeHttpPortDecorator(name, OPENSHIFT, config.livenessProbe, ports)); + result.add(KubernetesCommonHelper.createProbeHttpPortDecorator(name, OPENSHIFT, config.readinessProbe, ports)); // Handle non-openshift builds if (deploymentKind == DeploymentResourceKind.DeploymentConfig diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ProbeConfig.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ProbeConfig.java index 4bfa91d166a87..c32c119ec55df 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ProbeConfig.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ProbeConfig.java @@ -10,6 +10,19 @@ @ConfigGroup public class ProbeConfig { + /** + * The port number to use when configuring the http get. + * If not configured the port that corresponds to the `httpActionPortName` will be used. + */ + @ConfigItem + Optional httpActionPort; + + /** + * The port name ot use for selecting the port to congiure for the http get. + */ + @ConfigItem(defaultValue = "http") + String httpActionPortName; + /** * The http path to use for the probe For this to work, the container port also * needs to be set. diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/VanillaKubernetesProcessor.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/VanillaKubernetesProcessor.java index 682e806001a56..e614b6e0534f5 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/VanillaKubernetesProcessor.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/VanillaKubernetesProcessor.java @@ -1,7 +1,6 @@ package io.quarkus.kubernetes.deployment; -import static io.quarkus.kubernetes.deployment.Constants.DEFAULT_HTTP_PORT; import static io.quarkus.kubernetes.deployment.Constants.DEPLOYMENT_GROUP; import static io.quarkus.kubernetes.deployment.Constants.DEPLOYMENT_VERSION; import static io.quarkus.kubernetes.deployment.Constants.INGRESS; @@ -241,8 +240,8 @@ public List createDecorators(ApplicationInfoBuildItem applic } // Probe port handling - Integer portNumber = port.map(Port::getContainerPort).orElse(DEFAULT_HTTP_PORT); - result.add(new DecoratorBuildItem(KUBERNETES, new ApplyHttpGetActionPortDecorator(name, name, portNumber))); + result.add(KubernetesCommonHelper.createProbeHttpPortDecorator(name, KUBERNETES, config.livenessProbe, ports)); + result.add(KubernetesCommonHelper.createProbeHttpPortDecorator(name, KUBERNETES, config.readinessProbe, ports)); // Handle remote debug configuration if (config.remoteDebug.enabled) { diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithProbePortTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithProbePortTest.java new file mode 100644 index 0000000000000..07a25a2bf1a7f --- /dev/null +++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithProbePortTest.java @@ -0,0 +1,65 @@ +package io.quarkus.it.kubernetes; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.fabric8.kubernetes.api.model.HasMetadata; +import io.fabric8.kubernetes.api.model.apps.Deployment; +import io.quarkus.builder.Version; +import io.quarkus.maven.dependency.Dependency; +import io.quarkus.test.ProdBuildResults; +import io.quarkus.test.ProdModeTestResults; +import io.quarkus.test.QuarkusProdModeTest; + +public class KubernetesWithProbePortTest { + + @RegisterExtension + static final QuarkusProdModeTest config = new QuarkusProdModeTest() + .withApplicationRoot((jar) -> jar.addClasses(GreetingResource.class)) + .setApplicationName("kubernetes-with-probe-port") + .setApplicationVersion("0.1-SNAPSHOT") + .overrideConfigKey("quarkus.kubernetes.readiness-probe.http-action-port", "9191") + .setLogFileName("k8s.log") + .setForcedDependencies(List.of( + Dependency.of("io.quarkus", "quarkus-kubernetes", Version.getVersion()), + Dependency.of("io.quarkus", "quarkus-smallrye-health", Version.getVersion()))); + + @ProdBuildResults + private ProdModeTestResults prodModeTestResults; + + @Test + public void assertGeneratedResources() throws IOException { + + final Path kubernetesDir = prodModeTestResults.getBuildDir().resolve("kubernetes"); + assertThat(kubernetesDir) + .isDirectoryContaining(p -> p.getFileName().endsWith("kubernetes.json")) + .isDirectoryContaining(p -> p.getFileName().endsWith("kubernetes.yml")); + List kubernetesList = DeserializationUtil + .deserializeAsList(kubernetesDir.resolve("kubernetes.yml")); + assertThat(kubernetesList.get(0)).isInstanceOfSatisfying(Deployment.class, d -> { + assertThat(d.getMetadata()).satisfies(m -> { + assertThat(m.getName()).isEqualTo("kubernetes-with-probe-port"); + }); + + assertThat(d.getSpec()).satisfies(deploymentSpec -> { + assertThat(deploymentSpec.getTemplate()).satisfies(t -> { + assertThat(t.getSpec()).satisfies(podSpec -> { + assertThat(podSpec.getContainers()).singleElement() + .satisfies(container -> { + assertThat(container.getReadinessProbe()).isNotNull().satisfies(p -> { + assertEquals(p.getHttpGet().getPort().getIntVal(), 9191); + }); + }); + }); + }); + }); + }); + } +} From 5145dd1e838d74859ce15585b1dd600503c25ef0 Mon Sep 17 00:00:00 2001 From: Ioannis Canellos Date: Tue, 24 Jan 2023 19:12:40 +0200 Subject: [PATCH 2/4] feat: introduce build item to set port name --- .../spi/KubernetesProbePortNameBuildItem.java | 19 +++++++++++++++++++ .../deployment/KubernetesCommonHelper.java | 16 +++++++++++++++- .../deployment/OpenshiftProcessor.java | 7 +++++-- .../kubernetes/deployment/ProbeConfig.java | 4 ++-- .../VanillaKubernetesProcessor.java | 8 ++++++-- 5 files changed, 47 insertions(+), 7 deletions(-) create mode 100644 extensions/kubernetes/spi/src/main/java/io/quarkus/kubernetes/spi/KubernetesProbePortNameBuildItem.java diff --git a/extensions/kubernetes/spi/src/main/java/io/quarkus/kubernetes/spi/KubernetesProbePortNameBuildItem.java b/extensions/kubernetes/spi/src/main/java/io/quarkus/kubernetes/spi/KubernetesProbePortNameBuildItem.java new file mode 100644 index 0000000000000..54a090ddc92dc --- /dev/null +++ b/extensions/kubernetes/spi/src/main/java/io/quarkus/kubernetes/spi/KubernetesProbePortNameBuildItem.java @@ -0,0 +1,19 @@ +package io.quarkus.kubernetes.spi; + +import io.quarkus.builder.item.SimpleBuildItem; + +/** + * A build item for selecting which port is going + */ +public class KubernetesProbePortNameBuildItem extends SimpleBuildItem { + + private final String name; + + public KubernetesProbePortNameBuildItem(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesCommonHelper.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesCommonHelper.java index 8f622e9c87119..702f4481c3b4f 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesCommonHelper.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesCommonHelper.java @@ -3,6 +3,7 @@ import static io.dekorate.kubernetes.decorator.AddServiceResourceDecorator.distinct; import static io.quarkus.kubernetes.deployment.Constants.DEFAULT_HTTP_PORT; +import static io.quarkus.kubernetes.deployment.Constants.HTTP_PORT; import static io.quarkus.kubernetes.deployment.Constants.QUARKUS_ANNOTATIONS_BUILD_TIMESTAMP; import static io.quarkus.kubernetes.deployment.Constants.QUARKUS_ANNOTATIONS_COMMIT_ID; import static io.quarkus.kubernetes.deployment.Constants.QUARKUS_ANNOTATIONS_VCS_URL; @@ -82,6 +83,7 @@ import io.quarkus.kubernetes.spi.KubernetesJobBuildItem; import io.quarkus.kubernetes.spi.KubernetesLabelBuildItem; import io.quarkus.kubernetes.spi.KubernetesPortBuildItem; +import io.quarkus.kubernetes.spi.KubernetesProbePortNameBuildItem; import io.quarkus.kubernetes.spi.KubernetesRoleBindingBuildItem; import io.quarkus.kubernetes.spi.KubernetesRoleBuildItem; @@ -689,16 +691,28 @@ private static List createAnnotationDecorators(Optional portName, List ports) { //1. check if `httpActionPort` is defined //2. lookup port by `httpPortName` //3. fallback to DEFAULT_HTTP_PORT + String httpPortName = probeConfig.httpActionPortName + .or(() -> portName.map(KubernetesProbePortNameBuildItem::getName)) + .orElse(HTTP_PORT); + Integer port = probeConfig.httpActionPort - .orElse(ports.stream().filter(p -> probeConfig.httpActionPortName.equals(p.getName())) + .orElse(ports.stream().filter(p -> httpPortName.equals(p.getName())) .map(KubernetesPortBuildItem::getPort).findFirst().orElse(DEFAULT_HTTP_PORT)); return new DecoratorBuildItem(target, new ApplyHttpGetActionPortDecorator(name, name, port)); } diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftProcessor.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftProcessor.java index 9a09f2c932b8e..7867622f04775 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftProcessor.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftProcessor.java @@ -60,6 +60,7 @@ import io.quarkus.kubernetes.spi.KubernetesJobBuildItem; import io.quarkus.kubernetes.spi.KubernetesLabelBuildItem; import io.quarkus.kubernetes.spi.KubernetesPortBuildItem; +import io.quarkus.kubernetes.spi.KubernetesProbePortNameBuildItem; import io.quarkus.kubernetes.spi.KubernetesResourceMetadataBuildItem; import io.quarkus.kubernetes.spi.KubernetesRoleBindingBuildItem; import io.quarkus.kubernetes.spi.KubernetesRoleBuildItem; @@ -178,6 +179,7 @@ public List createDecorators(ApplicationInfoBuildItem applic Optional baseImage, Optional image, Optional command, + Optional portName, List ports, Optional livenessPath, Optional readinessPath, @@ -300,8 +302,9 @@ public List createDecorators(ApplicationInfoBuildItem applic } // Probe port handling - result.add(KubernetesCommonHelper.createProbeHttpPortDecorator(name, OPENSHIFT, config.livenessProbe, ports)); - result.add(KubernetesCommonHelper.createProbeHttpPortDecorator(name, OPENSHIFT, config.readinessProbe, ports)); + result.add(KubernetesCommonHelper.createProbeHttpPortDecorator(name, OPENSHIFT, config.livenessProbe, portName, ports)); + result.add( + KubernetesCommonHelper.createProbeHttpPortDecorator(name, OPENSHIFT, config.readinessProbe, portName, ports)); // Handle non-openshift builds if (deploymentKind == DeploymentResourceKind.DeploymentConfig diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ProbeConfig.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ProbeConfig.java index c32c119ec55df..a92e825c1caf5 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ProbeConfig.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ProbeConfig.java @@ -20,8 +20,8 @@ public class ProbeConfig { /** * The port name ot use for selecting the port to congiure for the http get. */ - @ConfigItem(defaultValue = "http") - String httpActionPortName; + @ConfigItem + Optional httpActionPortName; /** * The http path to use for the probe For this to work, the container port also diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/VanillaKubernetesProcessor.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/VanillaKubernetesProcessor.java index e614b6e0534f5..e4998f75fba96 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/VanillaKubernetesProcessor.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/VanillaKubernetesProcessor.java @@ -51,6 +51,7 @@ import io.quarkus.kubernetes.spi.KubernetesJobBuildItem; import io.quarkus.kubernetes.spi.KubernetesLabelBuildItem; import io.quarkus.kubernetes.spi.KubernetesPortBuildItem; +import io.quarkus.kubernetes.spi.KubernetesProbePortNameBuildItem; import io.quarkus.kubernetes.spi.KubernetesResourceMetadataBuildItem; import io.quarkus.kubernetes.spi.KubernetesRoleBindingBuildItem; import io.quarkus.kubernetes.spi.KubernetesRoleBuildItem; @@ -131,6 +132,7 @@ public List createDecorators(ApplicationInfoBuildItem applic List annotations, List labels, List envs, Optional image, Optional command, + Optional portName, List ports, Optional livenessPath, Optional readinessPath, List roles, List roleBindings, Optional customProjectRoot, @@ -240,8 +242,10 @@ public List createDecorators(ApplicationInfoBuildItem applic } // Probe port handling - result.add(KubernetesCommonHelper.createProbeHttpPortDecorator(name, KUBERNETES, config.livenessProbe, ports)); - result.add(KubernetesCommonHelper.createProbeHttpPortDecorator(name, KUBERNETES, config.readinessProbe, ports)); + result.add( + KubernetesCommonHelper.createProbeHttpPortDecorator(name, KUBERNETES, config.livenessProbe, portName, ports)); + result.add( + KubernetesCommonHelper.createProbeHttpPortDecorator(name, KUBERNETES, config.readinessProbe, portName, ports)); // Handle remote debug configuration if (config.remoteDebug.enabled) { From 2dfbe8beb02bf11d399485140acd8e7a62ac4b79 Mon Sep 17 00:00:00 2001 From: Ioannis Canellos Date: Tue, 24 Jan 2023 19:13:14 +0200 Subject: [PATCH 3/4] fix: workaround decorator ordering --- .../kind/deployment/KindProcessor.java | 3 + .../deployment/MinikubeProcessor.java | 3 + .../ApplyHttpGetActionPortDecorator.java | 70 +++++++++++++++++-- .../ChangeDeploymentTriggerDecorator.java | 1 + .../deployment/DevClusterHelper.java | 13 +++- .../deployment/KnativeProcessor.java | 2 +- .../deployment/KubernetesCommonHelper.java | 10 ++- .../deployment/OpenshiftProcessor.java | 8 ++- .../VanillaKubernetesProcessor.java | 9 ++- 9 files changed, 101 insertions(+), 18 deletions(-) diff --git a/extensions/kubernetes/kind/deployment/src/main/java/io/quarkus/kind/deployment/KindProcessor.java b/extensions/kubernetes/kind/deployment/src/main/java/io/quarkus/kind/deployment/KindProcessor.java index 47cba6debd7ba..ce3fca30d6399 100644 --- a/extensions/kubernetes/kind/deployment/src/main/java/io/quarkus/kind/deployment/KindProcessor.java +++ b/extensions/kubernetes/kind/deployment/src/main/java/io/quarkus/kind/deployment/KindProcessor.java @@ -41,6 +41,7 @@ import io.quarkus.kubernetes.spi.KubernetesJobBuildItem; import io.quarkus.kubernetes.spi.KubernetesLabelBuildItem; import io.quarkus.kubernetes.spi.KubernetesPortBuildItem; +import io.quarkus.kubernetes.spi.KubernetesProbePortNameBuildItem; import io.quarkus.kubernetes.spi.KubernetesResourceMetadataBuildItem; import io.quarkus.kubernetes.spi.KubernetesRoleBindingBuildItem; import io.quarkus.kubernetes.spi.KubernetesRoleBuildItem; @@ -104,6 +105,7 @@ public List createDecorators(ApplicationInfoBuildItem applic Optional image, Optional command, List ports, + Optional portName, Optional livenessPath, Optional readinessPath, List roles, @@ -112,6 +114,7 @@ public List createDecorators(ApplicationInfoBuildItem applic return DevClusterHelper.createDecorators(KIND, applicationInfo, outputTarget, config, packageConfig, metricsConfiguration, initContainers, jobs, annotations, labels, envs, baseImage, image, command, ports, + portName, livenessPath, readinessPath, roles, roleBindings, customProjectRoot); diff --git a/extensions/kubernetes/minikube/deployment/src/main/java/io/quarkus/minikube/deployment/MinikubeProcessor.java b/extensions/kubernetes/minikube/deployment/src/main/java/io/quarkus/minikube/deployment/MinikubeProcessor.java index e2fc9e183e7c5..d1d34577a3c66 100644 --- a/extensions/kubernetes/minikube/deployment/src/main/java/io/quarkus/minikube/deployment/MinikubeProcessor.java +++ b/extensions/kubernetes/minikube/deployment/src/main/java/io/quarkus/minikube/deployment/MinikubeProcessor.java @@ -38,6 +38,7 @@ import io.quarkus.kubernetes.spi.KubernetesJobBuildItem; import io.quarkus.kubernetes.spi.KubernetesLabelBuildItem; import io.quarkus.kubernetes.spi.KubernetesPortBuildItem; +import io.quarkus.kubernetes.spi.KubernetesProbePortNameBuildItem; import io.quarkus.kubernetes.spi.KubernetesResourceMetadataBuildItem; import io.quarkus.kubernetes.spi.KubernetesRoleBindingBuildItem; import io.quarkus.kubernetes.spi.KubernetesRoleBuildItem; @@ -100,6 +101,7 @@ public List createDecorators(ApplicationInfoBuildItem applic Optional image, Optional command, List ports, + Optional portName, Optional livenessPath, Optional readinessPath, List roles, @@ -108,6 +110,7 @@ public List createDecorators(ApplicationInfoBuildItem applic return DevClusterHelper.createDecorators(MINIKUBE, applicationInfo, outputTarget, config, packageConfig, metricsConfiguration, initContainers, jobs, annotations, labels, envs, baseImage, image, command, ports, + portName, livenessPath, readinessPath, roles, roleBindings, customProjectRoot); diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ApplyHttpGetActionPortDecorator.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ApplyHttpGetActionPortDecorator.java index 392539aeae077..eb4fa1b1e4ecf 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ApplyHttpGetActionPortDecorator.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ApplyHttpGetActionPortDecorator.java @@ -1,33 +1,89 @@ - package io.quarkus.kubernetes.deployment; +import static io.dekorate.utils.Metadata.getMetadata; + +import java.util.List; +import java.util.Map; +import java.util.Optional; + import io.dekorate.kubernetes.decorator.AddLivenessProbeDecorator; import io.dekorate.kubernetes.decorator.AddReadinessProbeDecorator; import io.dekorate.kubernetes.decorator.AddSidecarDecorator; -import io.dekorate.kubernetes.decorator.ApplicationContainerDecorator; import io.dekorate.kubernetes.decorator.Decorator; import io.dekorate.kubernetes.decorator.ResourceProvidingDecorator; +import io.fabric8.kubernetes.api.builder.Builder; +import io.fabric8.kubernetes.api.model.ContainerBuilder; import io.fabric8.kubernetes.api.model.HTTPGetActionFluent; -public class ApplyHttpGetActionPortDecorator extends ApplicationContainerDecorator> { +public class ApplyHttpGetActionPortDecorator extends Decorator> { + private final String deployment; + private final String container; private final Integer port; + private final String probeKind; public ApplyHttpGetActionPortDecorator(Integer port) { - this(ANY, ANY, port); + this(ANY, ANY, port, ANY); + } + + public ApplyHttpGetActionPortDecorator(Integer port, String probeKind) { + this(ANY, ANY, port, probeKind); } public ApplyHttpGetActionPortDecorator(String deployment, Integer port) { - this(deployment, ANY, port); + this(deployment, ANY, port, ANY); + } + + public ApplyHttpGetActionPortDecorator(String deployment, Integer port, String probeKind) { + this(deployment, ANY, port, probeKind); } public ApplyHttpGetActionPortDecorator(String deployment, String container, Integer port) { - super(deployment, container); + this(deployment, container, port, ANY); + } + + public ApplyHttpGetActionPortDecorator(String deployment, String container, Integer port, String probeKind) { + this.deployment = deployment; + this.container = container; this.port = port; + this.probeKind = probeKind; + } + + @Override + public void visit(List> path, HTTPGetActionFluent action) { + boolean inMatchingProbe = probeKind == ANY || path.stream().map(e -> e.getKey()).anyMatch(i -> i.equals(probeKind)); + if (!inMatchingProbe) { + return; + } + + boolean inMatchingContainer = container == ANY || path.stream() + .map(e -> e.getValue()) + .filter(v -> v instanceof ContainerBuilder) + .map(v -> (ContainerBuilder) v) + .anyMatch(c -> c.getName() != null && c.getName().equals(container)); + + if (!inMatchingContainer) { + return; + } + + boolean inMatchingResource = deployment == ANY || path.stream() + .map(e -> e.getValue()) + .filter(v -> v instanceof Builder) + .map(v -> (Builder) v) + .map(b -> getMetadata(b)) + .filter(m -> m.isPresent()) + .map(Optional::get) + .anyMatch(m -> m.getName() != null && m.getName().equals(deployment)); + + if (!inMatchingResource) { + return; + } + + visit(action); } @Override - public void andThenVisit(HTTPGetActionFluent action) { + public void visit(HTTPGetActionFluent action) { if (port == null) { // workaround to make sure we don't get a NPE action.withNewPort((String) null); diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ChangeDeploymentTriggerDecorator.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ChangeDeploymentTriggerDecorator.java index badd3dd41eb38..8edf073f00e13 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ChangeDeploymentTriggerDecorator.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ChangeDeploymentTriggerDecorator.java @@ -13,4 +13,5 @@ public ChangeDeploymentTriggerDecorator(String containerName, String imageStream public Class[] after() { return new Class[] { ApplyDeploymentTriggerDecorator.class, RemoveDeploymentTriggerDecorator.class }; } + } diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/DevClusterHelper.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/DevClusterHelper.java index a31cb79ff4d74..a7c7c44c2d0dd 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/DevClusterHelper.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/DevClusterHelper.java @@ -1,7 +1,6 @@ package io.quarkus.kubernetes.deployment; -import static io.quarkus.kubernetes.deployment.Constants.DEFAULT_HTTP_PORT; import static io.quarkus.kubernetes.deployment.Constants.KUBERNETES; import static io.quarkus.kubernetes.deployment.Constants.MAX_NODE_PORT_VALUE; import static io.quarkus.kubernetes.deployment.Constants.MAX_PORT_NUMBER; @@ -42,6 +41,7 @@ import io.quarkus.kubernetes.spi.KubernetesJobBuildItem; import io.quarkus.kubernetes.spi.KubernetesLabelBuildItem; import io.quarkus.kubernetes.spi.KubernetesPortBuildItem; +import io.quarkus.kubernetes.spi.KubernetesProbePortNameBuildItem; import io.quarkus.kubernetes.spi.KubernetesRoleBindingBuildItem; import io.quarkus.kubernetes.spi.KubernetesRoleBuildItem; @@ -64,6 +64,7 @@ public static List createDecorators(String clusterKind, Optional image, Optional command, List ports, + Optional portName, Optional livenessPath, Optional readinessPath, List roles, @@ -118,8 +119,14 @@ public static List createDecorators(String clusterKind, } //Probe port handling - Integer portNumber = port.map(Port::getContainerPort).orElse(DEFAULT_HTTP_PORT); - result.add(new DecoratorBuildItem(clusterKind, new ApplyHttpGetActionPortDecorator(name, name, portNumber))); + result.add( + KubernetesCommonHelper.createProbeHttpPortDecorator(name, clusterKind, "livenessProbe", config.livenessProbe, + portName, + ports)); + result.add( + KubernetesCommonHelper.createProbeHttpPortDecorator(name, clusterKind, "readinessProbe", config.readinessProbe, + portName, + ports)); // Handle init Containers result.addAll(KubernetesCommonHelper.createInitContainerDecorators(clusterKind, name, initContainers, result)); diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KnativeProcessor.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KnativeProcessor.java index f5490ee727224..d4d3029bf28c4 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KnativeProcessor.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KnativeProcessor.java @@ -282,7 +282,7 @@ public List createDecorators(ApplicationInfoBuildItem applic result.add(new DecoratorBuildItem(KNATIVE, new ApplyServiceTypeDecorator(name, config.getServiceType().name()))); //In Knative its expected that all http ports in probe are omitted (so we set them to null). - result.add(new DecoratorBuildItem(KNATIVE, new ApplyHttpGetActionPortDecorator(name, null))); + result.add(new DecoratorBuildItem(KNATIVE, new ApplyHttpGetActionPortDecorator(name, (Integer) null))); //Traffic Splitting config.revisionName.ifPresent(r -> { diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesCommonHelper.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesCommonHelper.java index 702f4481c3b4f..959864deab4c1 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesCommonHelper.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesCommonHelper.java @@ -698,9 +698,15 @@ private static List createAnnotationDecorators(Optional portName, List ports) { @@ -714,7 +720,7 @@ public static DecoratorBuildItem createProbeHttpPortDecorator(String name, Strin Integer port = probeConfig.httpActionPort .orElse(ports.stream().filter(p -> httpPortName.equals(p.getName())) .map(KubernetesPortBuildItem::getPort).findFirst().orElse(DEFAULT_HTTP_PORT)); - return new DecoratorBuildItem(target, new ApplyHttpGetActionPortDecorator(name, name, port)); + return new DecoratorBuildItem(target, new ApplyHttpGetActionPortDecorator(name, name, port, probeKind)); } /** diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftProcessor.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftProcessor.java index 7867622f04775..ffe3064fd6672 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftProcessor.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftProcessor.java @@ -302,9 +302,13 @@ public List createDecorators(ApplicationInfoBuildItem applic } // Probe port handling - result.add(KubernetesCommonHelper.createProbeHttpPortDecorator(name, OPENSHIFT, config.livenessProbe, portName, ports)); + result.add(KubernetesCommonHelper.createProbeHttpPortDecorator(name, OPENSHIFT, "livenssProbe", config.livenessProbe, + portName, + ports)); result.add( - KubernetesCommonHelper.createProbeHttpPortDecorator(name, OPENSHIFT, config.readinessProbe, portName, ports)); + KubernetesCommonHelper.createProbeHttpPortDecorator(name, OPENSHIFT, "readinessProbe", config.readinessProbe, + portName, + ports)); // Handle non-openshift builds if (deploymentKind == DeploymentResourceKind.DeploymentConfig diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/VanillaKubernetesProcessor.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/VanillaKubernetesProcessor.java index e4998f75fba96..6119ea9c0ff44 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/VanillaKubernetesProcessor.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/VanillaKubernetesProcessor.java @@ -243,9 +243,13 @@ public List createDecorators(ApplicationInfoBuildItem applic // Probe port handling result.add( - KubernetesCommonHelper.createProbeHttpPortDecorator(name, KUBERNETES, config.livenessProbe, portName, ports)); + KubernetesCommonHelper.createProbeHttpPortDecorator(name, KUBERNETES, "livenessProbe", config.livenessProbe, + portName, + ports)); result.add( - KubernetesCommonHelper.createProbeHttpPortDecorator(name, KUBERNETES, config.readinessProbe, portName, ports)); + KubernetesCommonHelper.createProbeHttpPortDecorator(name, KUBERNETES, "readinessProbe", config.readinessProbe, + portName, + ports)); // Handle remote debug configuration if (config.remoteDebug.enabled) { @@ -277,5 +281,4 @@ void externalizeInitTasks( decorators); } } - } From 02f434584394749d979ce249e8552c5fbd1b5caa Mon Sep 17 00:00:00 2001 From: Ioannis Canellos Date: Thu, 26 Jan 2023 09:08:19 +0200 Subject: [PATCH 4/4] Apply suggestions from code review Co-authored-by: Clement Escoffier --- .../kubernetes/spi/KubernetesProbePortNameBuildItem.java | 2 +- .../java/io/quarkus/kubernetes/deployment/ProbeConfig.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/extensions/kubernetes/spi/src/main/java/io/quarkus/kubernetes/spi/KubernetesProbePortNameBuildItem.java b/extensions/kubernetes/spi/src/main/java/io/quarkus/kubernetes/spi/KubernetesProbePortNameBuildItem.java index 54a090ddc92dc..18b31fd7cced2 100644 --- a/extensions/kubernetes/spi/src/main/java/io/quarkus/kubernetes/spi/KubernetesProbePortNameBuildItem.java +++ b/extensions/kubernetes/spi/src/main/java/io/quarkus/kubernetes/spi/KubernetesProbePortNameBuildItem.java @@ -3,7 +3,7 @@ import io.quarkus.builder.item.SimpleBuildItem; /** - * A build item for selecting which port is going + * A build item for selecting which port to use for probes using an {@literal HTTP get} action. */ public class KubernetesProbePortNameBuildItem extends SimpleBuildItem { diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ProbeConfig.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ProbeConfig.java index a92e825c1caf5..4efdbf7543e75 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ProbeConfig.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ProbeConfig.java @@ -11,14 +11,14 @@ public class ProbeConfig { /** - * The port number to use when configuring the http get. - * If not configured the port that corresponds to the `httpActionPortName` will be used. + * The port number to use when configuring the {@literal http get} action. + * If not configured, the port corresponding to the {@code httpActionPortName} will be used. */ @ConfigItem Optional httpActionPort; /** - * The port name ot use for selecting the port to congiure for the http get. + * The port name for selecting the port of the {@literal HTTP get} action. */ @ConfigItem Optional httpActionPortName;