diff --git a/bom/application/pom.xml b/bom/application/pom.xml index 4986767595786..1c181f45cc856 100644 --- a/bom/application/pom.xml +++ b/bom/application/pom.xml @@ -147,7 +147,7 @@ 2.34.0 1.3.0 1.3.72 - 0.12.9 + 0.12.10 0.10.0 2.14.6 3.0.1 diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesConfig.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesConfig.java index 1d866719c9f72..a59cffe5e9251 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesConfig.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesConfig.java @@ -219,6 +219,12 @@ public class KubernetesConfig implements PlatformConfiguration { @ConfigItem boolean expose; + /** + * If true, the 'app.kubernetes.io/version' label will be part of the selectors of Service and Deployment + */ + @ConfigItem(defaultValue = "true") + boolean addVersionToLabelSelectors; + public Optional getPartOf() { return partOf; } diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesProcessor.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesProcessor.java index f4f0e760e1314..34b6b11844c5d 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesProcessor.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesProcessor.java @@ -19,7 +19,7 @@ import static io.quarkus.kubernetes.deployment.Constants.QUARKUS_ANNOTATIONS_COMMIT_ID; import static io.quarkus.kubernetes.deployment.Constants.QUARKUS_ANNOTATIONS_VCS_URL; import static io.quarkus.kubernetes.deployment.Constants.SERVICE; -import static io.quarkus.kubernetes.deployment.ResourceNameUtil.*; +import static io.quarkus.kubernetes.deployment.ResourceNameUtil.getResourceName; import static io.quarkus.kubernetes.spi.KubernetesDeploymentTargetBuildItem.DEFAULT_PRIORITY; import static io.quarkus.kubernetes.spi.KubernetesDeploymentTargetBuildItem.VANILLA_KUBERNETES_PRIORITY; import static io.quarkus.kubernetes.spi.KubernetesDeploymentTargetBuildItem.mergeList; @@ -97,6 +97,9 @@ import io.dekorate.kubernetes.decorator.ApplyServiceAccountNamedDecorator; import io.dekorate.kubernetes.decorator.ApplyWorkingDirDecorator; import io.dekorate.kubernetes.decorator.RemoveAnnotationDecorator; +import io.dekorate.kubernetes.decorator.RemoveFromMatchingLabelsDecorator; +import io.dekorate.kubernetes.decorator.RemoveFromSelectorDecorator; +import io.dekorate.kubernetes.decorator.RemoveLabelDecorator; import io.dekorate.logger.NoopLogger; import io.dekorate.processor.SimpleFileReader; import io.dekorate.processor.SimpleFileWriter; @@ -109,6 +112,7 @@ import io.dekorate.s2i.config.S2iBuildConfigFluent; import io.dekorate.s2i.decorator.AddBuilderImageStreamResourceDecorator; import io.dekorate.utils.Annotations; +import io.dekorate.utils.Labels; import io.dekorate.utils.Maps; import io.quarkus.container.image.deployment.util.ImageUtil; import io.quarkus.container.spi.BaseImageInfoBuildItem; @@ -347,7 +351,9 @@ public void build(ApplicationInfoBuildItem applicationInfo, applyConfig(session, project, KNATIVE, getResourceName(knativeConfig, applicationInfo), knativeConfig, now, determineImagePullPolicy(knativeConfig, needToForceUpdateImagePullPolicy)); - applyKnativeConfig(session, project, getResourceName(knativeConfig, applicationInfo), knativeConfig); + applyVanillaKubernetesSpecificConfig(session, kubernetesConfig); + applyOpenshiftSpecificConfig(session, openshiftConfig); + applyKnativeSpecificConfig(session, getResourceName(knativeConfig, applicationInfo), knativeConfig); if (!capabilities.isCapabilityPresent(Capabilities.CONTAINER_IMAGE_S2I)) { handleNonS2IOpenshift(containerImage, session); @@ -476,9 +482,6 @@ private void applyGlobalConfig(Session session, KubernetesConfig config) { */ private void applyConfig(Session session, Project project, String target, String name, PlatformConfiguration config, ZonedDateTime now, ImagePullPolicy imagePullPolicy) { - if (OPENSHIFT.equals(target)) { - session.resources().decorate(OPENSHIFT, new AddLabelDecorator(new Label(OPENSHIFT_APP_RUNTIME, QUARKUS))); - } if (config.getNamespace().isPresent()) { session.resources().decorate(target, new AddNamespaceDecorator(config.getNamespace().get())); @@ -579,7 +582,27 @@ private void applyAnnotations(Session session, Project project, String target, P } } - private void applyKnativeConfig(Session session, Project project, String name, KnativeConfig config) { + // apply Openshift specific configuration + private void applyVanillaKubernetesSpecificConfig(Session session, KubernetesConfig kubernetesConfig) { + if (!kubernetesConfig.addVersionToLabelSelectors) { + session.resources().decorate(KUBERNETES, new RemoveLabelDecorator(Labels.VERSION)); + session.resources().decorate(KUBERNETES, new RemoveFromSelectorDecorator(Labels.VERSION)); + session.resources().decorate(KUBERNETES, new RemoveFromMatchingLabelsDecorator(Labels.VERSION)); + } + } + + // apply Openshift specific configuration + private void applyOpenshiftSpecificConfig(Session session, OpenshiftConfig openshiftConfig) { + session.resources().decorate(OPENSHIFT, new AddLabelDecorator(new Label(OPENSHIFT_APP_RUNTIME, QUARKUS))); + + if (!openshiftConfig.addVersionToLabelSelectors) { + session.resources().decorate(OPENSHIFT, new RemoveLabelDecorator(Labels.VERSION)); + session.resources().decorate(OPENSHIFT, new RemoveFromSelectorDecorator(Labels.VERSION)); + } + } + + // apply Knative specific configuration + private void applyKnativeSpecificConfig(Session session, String name, KnativeConfig config) { if (config.clusterLocal) { session.resources().decorate(KNATIVE, new AddLabelDecorator(name, new LabelBuilder() diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftConfig.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftConfig.java index a882950319e21..1d829b28d1329 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftConfig.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/OpenshiftConfig.java @@ -220,6 +220,12 @@ public class OpenshiftConfig implements PlatformConfiguration { @ConfigItem boolean expose; + /** + * If true, the 'app.kubernetes.io/version' label will be part of the selectors of Service and DeploymentConfig + */ + @ConfigItem(defaultValue = "true") + boolean addVersionToLabelSelectors; + public Optional getPartOf() { return partOf; } diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/BasicKubernetesTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/BasicKubernetesTest.java index 2410cf2ce0eb2..08f846a8af6d4 100644 --- a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/BasicKubernetesTest.java +++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/BasicKubernetesTest.java @@ -2,6 +2,7 @@ import static io.restassured.RestAssured.given; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; import static org.hamcrest.Matchers.is; import java.io.IOException; @@ -69,6 +70,11 @@ public void assertGeneratedResources() throws IOException { }); assertThat(d.getSpec()).satisfies(deploymentSpec -> { + assertThat(deploymentSpec.getSelector()).isNotNull().satisfies(labelSelector -> { + assertThat(labelSelector.getMatchLabels()).containsOnly(entry("app.kubernetes.io/name", "basic"), + entry("app.kubernetes.io/version", "0.1-SNAPSHOT")); + }); + assertThat(deploymentSpec.getTemplate()).satisfies(t -> { assertThat(t.getSpec()).satisfies(podSpec -> { assertThat(podSpec.getContainers()).singleElement().satisfies(container -> { @@ -87,6 +93,9 @@ public void assertGeneratedResources() throws IOException { assertThat(m.getNamespace()).isNull(); }); assertThat(s.getSpec()).satisfies(spec -> { + assertThat(spec.getSelector()).containsOnly(entry("app.kubernetes.io/name", "basic"), + entry("app.kubernetes.io/version", "0.1-SNAPSHOT")); + assertThat(spec.getPorts()).hasSize(1).singleElement().satisfies(p -> { assertThat(p.getPort()).isEqualTo(8080); }); diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/BasicOpenshiftTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/BasicOpenshiftTest.java index 45cb522fd5551..ce0b9d038049b 100644 --- a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/BasicOpenshiftTest.java +++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/BasicOpenshiftTest.java @@ -1,11 +1,13 @@ package io.quarkus.it.kubernetes; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; import java.io.IOException; import java.nio.file.Path; import java.util.Collection; import java.util.List; +import java.util.Map; import org.assertj.core.api.AbstractObjectAssert; import org.jboss.shrinkwrap.api.ShrinkWrap; @@ -52,6 +54,10 @@ public void assertGeneratedResources() throws IOException { specAssert.extracting("triggers").isInstanceOfSatisfying(Collection.class, c -> { assertThat(c).isEmpty(); }); + specAssert.extracting("selector").isInstanceOfSatisfying(Map.class, selectorsMap -> { + assertThat(selectorsMap).containsOnly(entry("app.kubernetes.io/name", "basic-openshift"), + entry("app.kubernetes.io/version", "0.1-SNAPSHOT")); + }); }); assertThat(openshiftList).filteredOn(h -> "Service".equals(h.getKind())).singleElement().satisfies(h -> { @@ -59,6 +65,11 @@ public void assertGeneratedResources() throws IOException { assertThat(s.getMetadata()).satisfies(m -> { assertThat(m.getNamespace()).isNull(); }); + + assertThat(s.getSpec()).satisfies(spec -> { + assertThat(spec.getSelector()).containsOnly(entry("app.kubernetes.io/name", "basic-openshift"), + entry("app.kubernetes.io/version", "0.1-SNAPSHOT")); + }); }); }); } diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithApplicationPropertiesTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithApplicationPropertiesTest.java index 89cf79e79f4e4..2e7f137e1cc4e 100644 --- a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithApplicationPropertiesTest.java +++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithApplicationPropertiesTest.java @@ -56,6 +56,10 @@ public void assertGeneratedResources() throws IOException { }); assertThat(d.getSpec()).satisfies(deploymentSpec -> { + // ensure that the version is not part of the selector labels + assertThat(deploymentSpec.getSelector()).isNotNull().satisfies(labelSelector -> { + assertThat(labelSelector.getMatchLabels()).containsOnly(entry("app.kubernetes.io/name", "test-it")); + }); assertThat(deploymentSpec.getReplicas()).isEqualTo(3); assertThat(deploymentSpec.getTemplate()).satisfies(t -> { assertThat(t.getSpec()).satisfies(podSpec -> { @@ -89,6 +93,7 @@ public void assertGeneratedResources() throws IOException { assertThat(s.getSpec()).satisfies(spec -> { assertEquals("NodePort", spec.getType()); + assertThat(spec.getSelector()).containsOnly(entry("app.kubernetes.io/name", "test-it")); assertThat(spec.getPorts()).hasSize(1).singleElement().satisfies(p -> { assertThat(p.getPort()).isEqualTo(9090); }); diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/OpenshiftWithApplicationPropertiesTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/OpenshiftWithApplicationPropertiesTest.java index 2d291deb772e2..7320f583ae317 100644 --- a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/OpenshiftWithApplicationPropertiesTest.java +++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/OpenshiftWithApplicationPropertiesTest.java @@ -7,7 +7,9 @@ import java.io.IOException; import java.nio.file.Path; import java.util.List; +import java.util.Map; +import org.assertj.core.api.AbstractObjectAssert; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.junit.jupiter.api.Test; @@ -48,14 +50,18 @@ public void assertGeneratedResources() throws IOException { assertThat(m.getLabels()).contains(entry("foo", "bar")); assertThat(m.getNamespace()).isEqualTo("applications"); }); - assertThat(h).extracting("spec").extracting("replicas").isEqualTo(3); - assertThat(h).extracting("spec").extracting("template").extracting("spec").isInstanceOfSatisfying(PodSpec.class, + AbstractObjectAssert specAssert = assertThat(h).extracting("spec"); + specAssert.extracting("replicas").isEqualTo(3); + specAssert.extracting("template").extracting("spec").isInstanceOfSatisfying(PodSpec.class, podSpec -> { assertThat(podSpec.getContainers()).singleElement().satisfies(container -> { assertThat(container.getEnv()).extracting("name", "value") .contains(tuple("MY_ENV_VAR", "SOMEVALUE")); }); }); + specAssert.extracting("selector").isInstanceOfSatisfying(Map.class, selectorsMap -> { + assertThat(selectorsMap).containsOnly(entry("app.kubernetes.io/name", "test-it")); + }); }); assertThat(openshiftList).filteredOn(h -> "Service".equals(h.getKind())).singleElement().satisfies(h -> { @@ -65,6 +71,7 @@ public void assertGeneratedResources() throws IOException { }); assertThat(s.getSpec()).satisfies(spec -> { + assertThat(spec.getSelector()).containsOnly(entry("app.kubernetes.io/name", "test-it")); assertThat(spec.getPorts()).hasSize(1).singleElement().satisfies(p -> { assertThat(p.getPort()).isEqualTo(9090); }); diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/resources/kubernetes-with-application.properties b/integration-tests/kubernetes/quarkus-standard-way/src/test/resources/kubernetes-with-application.properties index 460d96bedb543..2396cda7aaf14 100644 --- a/integration-tests/kubernetes/quarkus-standard-way/src/test/resources/kubernetes-with-application.properties +++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/resources/kubernetes-with-application.properties @@ -5,6 +5,7 @@ quarkus.kubernetes.labels.foo=bar quarkus.kubernetes.annotations.bar=baz quarkus.kubernetes.env-vars.my-env-var.value=SOMEVALUE quarkus.kubernetes.env-vars.my-name.field=metadata.name +quarkus.kubernetes.add-version-to-label-selectors=false quarkus.container-image.group=grp quarkus.container-image.registry=quay.io quarkus.kubernetes.expose=true diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/resources/openshift-with-application.properties b/integration-tests/kubernetes/quarkus-standard-way/src/test/resources/openshift-with-application.properties index c747176fdaed2..d96b352e85054 100644 --- a/integration-tests/kubernetes/quarkus-standard-way/src/test/resources/openshift-with-application.properties +++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/resources/openshift-with-application.properties @@ -9,3 +9,4 @@ quarkus.openshift.group=grp quarkus.openshift.expose=true quarkus.s2i.registry=quay.io quarkus.openshift.replicas=3 +quarkus.openshift.add-version-to-label-selectors=false