diff --git a/bom/application/pom.xml b/bom/application/pom.xml
index 61c05821253c14..958ed651fcf6e6 100644
--- a/bom/application/pom.xml
+++ b/bom/application/pom.xml
@@ -152,7 +152,7 @@
2.37.1
1.3.0
1.4.20
- 0.13.6
+ 0.14.1
0.10.0
2.14.6
3.0.1
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 ee325f97321818..7609d7d0ceeeb5 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
@@ -9,6 +9,14 @@
import java.util.Optional;
import java.util.stream.Stream;
+import io.dekorate.knative.decorator.AddAwsElasticBlockStoreVolumeToRevisionDecorator;
+import io.dekorate.knative.decorator.AddAzureDiskVolumeToRevisionDecorator;
+import io.dekorate.knative.decorator.AddAzureFileVolumeToRevisionDecorator;
+import io.dekorate.knative.decorator.AddConfigMapVolumeToRevisionDecorator;
+import io.dekorate.knative.decorator.AddHostAliasesToRevisionDecorator;
+import io.dekorate.knative.decorator.AddPvcVolumeToRevisionDecorator;
+import io.dekorate.knative.decorator.AddSecretVolumeToRevisionDecorator;
+import io.dekorate.knative.decorator.AddSidecarToRevisionDecorator;
import io.dekorate.knative.decorator.ApplyGlobalAutoscalingClassDecorator;
import io.dekorate.knative.decorator.ApplyGlobalContainerConcurrencyDecorator;
import io.dekorate.knative.decorator.ApplyGlobalRequestsPerSecondTargetDecorator;
@@ -211,6 +219,52 @@ public List createDecorators(ApplicationInfoBuildItem applic
result.add(new DecoratorBuildItem(KNATIVE,
new ApplyTrafficDecorator(name, revisionName, latestRevision, percent, tag)));
});
+
+ //Add revision decorators
+ result.addAll(createVolumeDecorators(project, name, config));
+ config.getHostAliases().entrySet().forEach(e -> {
+ result.add(new DecoratorBuildItem(KNATIVE,
+ new AddHostAliasesToRevisionDecorator(name, HostAliasConverter.convert(e))));
+ });
+ config.getSidecars().entrySet().forEach(e -> {
+ result.add(new DecoratorBuildItem(KNATIVE, new AddSidecarToRevisionDecorator(name, ContainerConverter.convert(e))));
+ });
+
+ return result;
+ }
+
+ private static List createVolumeDecorators(Optional project, String name,
+ PlatformConfiguration config) {
+ List result = new ArrayList<>();
+
+ config.getSecretVolumes().entrySet().forEach(e -> {
+ result.add(
+ new DecoratorBuildItem(KNATIVE, new AddSecretVolumeToRevisionDecorator(SecretVolumeConverter.convert(e))));
+ });
+
+ config.getConfigMapVolumes().entrySet().forEach(e -> {
+ result.add(new DecoratorBuildItem(KNATIVE,
+ new AddConfigMapVolumeToRevisionDecorator(ConfigMapVolumeConverter.convert(e))));
+ });
+
+ config.getPvcVolumes().entrySet().forEach(e -> {
+ result.add(new DecoratorBuildItem(KNATIVE, new AddPvcVolumeToRevisionDecorator(PvcVolumeConverter.convert(e))));
+ });
+
+ config.getAwsElasticBlockStoreVolumes().entrySet().forEach(e -> {
+ result.add(new DecoratorBuildItem(KNATIVE,
+ new AddAwsElasticBlockStoreVolumeToRevisionDecorator(AwsElasticBlockStoreVolumeConverter.convert(e))));
+ });
+
+ config.getAzureFileVolumes().entrySet().forEach(e -> {
+ result.add(new DecoratorBuildItem(KNATIVE,
+ new AddAzureFileVolumeToRevisionDecorator(AzureFileVolumeConverter.convert(e))));
+ });
+
+ config.getAzureDiskVolumes().entrySet().forEach(e -> {
+ result.add(new DecoratorBuildItem(KNATIVE,
+ new AddAzureDiskVolumeToRevisionDecorator(AzureDiskVolumeConverter.convert(e))));
+ });
return result;
}
}
diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KnativeWithVolumesTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KnativeWithVolumesTest.java
new file mode 100644
index 00000000000000..6e216642070785
--- /dev/null
+++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KnativeWithVolumesTest.java
@@ -0,0 +1,77 @@
+package io.quarkus.it.kubernetes;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.List;
+
+import org.assertj.core.api.Condition;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.JavaArchive;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import io.fabric8.knative.serving.v1.Service;
+import io.fabric8.kubernetes.api.model.HasMetadata;
+import io.fabric8.kubernetes.api.model.Volume;
+import io.fabric8.kubernetes.api.model.VolumeMount;
+import io.quarkus.test.ProdBuildResults;
+import io.quarkus.test.ProdModeTestResults;
+import io.quarkus.test.QuarkusProdModeTest;
+
+public class KnativeWithVolumesTest {
+
+ @RegisterExtension
+ static final QuarkusProdModeTest config = new QuarkusProdModeTest()
+ .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClasses(GreetingResource.class))
+ .setApplicationName("knative-with-volumes-properties")
+ .setApplicationVersion("0.1-SNAPSHOT")
+ .withConfigurationResource("knative-with-volumes.properties");
+
+ @ProdBuildResults
+ private ProdModeTestResults prodModeTestResults;
+
+ @Test
+ public void assertGeneratedResources() throws IOException {
+ Path kubernetesDir = prodModeTestResults.getBuildDir().resolve("kubernetes");
+ assertThat(kubernetesDir)
+ .isDirectoryContaining(p -> p.getFileName().endsWith("knative.json"))
+ .isDirectoryContaining(p -> p.getFileName().endsWith("knative.yml"))
+ .satisfies(p -> assertThat(p.toFile().listFiles()).hasSize(2));
+
+ List kubernetesList = DeserializationUtil
+ .deserializeAsList(kubernetesDir.resolve("knative.yml"));
+
+ assertThat(kubernetesList).filteredOn(i -> "Service".equals(i.getKind())).singleElement().satisfies(i -> {
+ assertThat(i).isInstanceOfSatisfying(Service.class, s -> {
+ assertThat(s.getSpec()).satisfies(spec -> {
+
+ assertThat(spec.getTemplate()).satisfies(template -> {
+ assertThat(template.getSpec()).satisfies(revisionSpec -> {
+ assertThat(revisionSpec.getVolumes()).haveAtLeastOne(new Condition(
+ v -> v.getName().equals("client-crts")
+ && v.getSecret().getSecretName().equals("clientcerts"),
+ "Has secret volume named client-crts referencing secert clientcerts"));
+ assertThat(revisionSpec.getVolumes()).haveAtLeastOne(new Condition(
+ v -> v.getName().equals("client-cfg") && v.getConfigMap().getName().equals("clientconfig"),
+ "Has config-map named client-cfg referencing configmap clientconfig"));
+
+ assertThat(revisionSpec.getContainers()).hasSize(1).singleElement().satisfies(c -> {
+
+ assertThat(c.getVolumeMounts()).haveAtLeastOne(new Condition(
+ m -> m.getName().equals("client-crts"), "Has client-crts mount"));
+ assertThat(c.getVolumeMounts()).haveAtLeastOne(new Condition(
+ m -> m.getName().equals("client-cfg"), "Has client-cfg mount"));
+
+ assertThat(c.getPorts()).hasSize(1).singleElement().satisfies(p -> {
+ assertThat(p.getName()).isEqualTo("http1");
+ });
+ });
+ });
+ });
+ });
+ });
+ });
+ }
+}
diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/resources/knative-with-volumes.properties b/integration-tests/kubernetes/quarkus-standard-way/src/test/resources/knative-with-volumes.properties
new file mode 100644
index 00000000000000..a3c617cbae577e
--- /dev/null
+++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/resources/knative-with-volumes.properties
@@ -0,0 +1,8 @@
+# Configuration file
+quarkus.kubernetes.deployment-target=knative
+
+quarkus.knative.mounts.client-crts.path=/mnt/clientcerts
+quarkus.knative.secret-volumes.client-crts.secret-name=clientcerts
+
+quarkus.knative.mounts.client-cfg.path=/mnt/clientconfig
+quarkus.knative.config-map-volumes.client-cfg.config-map-name=clientconfig
\ No newline at end of file