diff --git a/docs/src/main/asciidoc/kubernetes.adoc b/docs/src/main/asciidoc/kubernetes.adoc index b42f74deb539f3..359705ca712f08 100644 --- a/docs/src/main/asciidoc/kubernetes.adoc +++ b/docs/src/main/asciidoc/kubernetes.adoc @@ -8,7 +8,7 @@ https://github.com/quarkusio/quarkus/tree/master/docs/src/main/asciidoc include::./attributes.adoc[] This guide covers generating and deploying Kubernetes resources based on sane defaults and user supplied configuration. -In detail, it supports generating resources for <>, <> and <>. Also it supports automatically <> these resources to the target platform. +In detail, it supports generating resources for <>, <> and <. Also it supports automatically <> these resources to the target platform. == Prerequisites @@ -59,7 +59,7 @@ By using the following configuration for example: [source] ---- -kubernetes.group=yourDockerUsername # this is optional and defaults to your username if not set. +quarkus.kubernetes.group=yourDockerUsername # this is optional and defaults to your username if not set. quarkus.application.name=test-quarkus-app # this is also optional and defaults to the project name if not set ---- @@ -169,7 +169,7 @@ To change the number of replicas from 1 to 3: [source] ---- -kubernetes.replicas=3 +quarkus.kubernetes.replicas=3 ---- === Defining a docker registry and repository @@ -178,8 +178,8 @@ The docker registry and the user of the docker image can be specified, with the [source] ---- -kubernetes.group=myUser -docker.registry=http://my.docker-registry.net +quarkus.kubernetes.group=myUser +quarkus.docker.registry=http://my.docker-registry.net ---- Note: These options used to be `quarkus.kubernetes.docker.registry` and `quarkus.kubernetes.group` respectively. @@ -189,8 +189,7 @@ To add a new label to all generated resources, say `foo=bar`: [source] ---- -kubernetes.labels[0].key=foo -kubernetes.labels[0].value=bar +quarkus.kubernetes.labels.foo=bar ---- === Customizing the readiness probe: @@ -198,8 +197,8 @@ To set the initial delay of the probe to 20 seconds and the period to 45: [source] ---- -kubernetes.readiness-probe.initial-delay-seconds=20 -kubernetes.readiness-probe.period-seconds=45 +quarkus.kubernetes.readiness-probe.initial-delay-seconds=20 +quarkus.kubernetes.readiness-probe.period-seconds=45 ---- Here you can find a complete reference to all the available configuration options: @@ -210,38 +209,37 @@ The table below describe all the available configuration options. .Kubernetes |==== -| Property | Type | Description | Default Value -| kubernetes.group | String | | -| kubernetes.name | String | | -| kubernetes.version | String | | -| kubernetes.init-containers | Container[] | | -| kubernetes.labels | Label[] | | -| kubernetes.annotations | Annotation[] | | -| kubernetes.env-vars | Env[] | | -| kubernetes.working-dir | String | | -| kubernetes.command | String[] | | -| kubernetes.arguments | String[] | | -| kubernetes.replicas | int | | 1 -| kubernetes.service-account | String | | -| kubernetes.host | String | | -| kubernetes.ports | Port[] | | -| kubernetes.service-type | ServiceType | | ClusterIP -| kubernetes.pvc-volumes | PersistentVolumeClaimVolume[] | | -| kubernetes.secret-volumes | SecretVolume[] | | -| kubernetes.config-map-volumes | ConfigMapVolume[] | | -| kubernetes.git-repo-volumes | GitRepoVolume[] | | -| kubernetes.aws-elastic-block-store-volumes | AwsElasticBlockStoreVolume[] | | -| kubernetes.azure-disk-volumes | AzureDiskVolume[] | | -| kubernetes.azure-file-volumes | AzureFileVolume[] | | -| kubernetes.mounts | Mount[] | | -| kubernetes.image-pull-policy | ImagePullPolicy | | IfNotPresent -| kubernetes.image-pull-secrets | String[] | | -| kubernetes.liveness-probe | Probe | | ( see Probe ) -| kubernetes.readiness-probe | Probe | | ( see Probe ) -| kubernetes.sidecars | Container[] | | -| kubernetes.expose | boolean | | false -| kubernetes.headless | boolean | | false -| kubernetes.auto-deploy-enabled | boolean | | false +| Property | Type | Description | Default Value +| quarkus.kubernetes.group | String | | +| quarkus.kubernetes.name | String | | +| quarkus.kubernetes.version | String | | +| quarkus.kubernetes.init-containers | Map | | +| quarkus.kubernetes.labels | Map | | +| quarkus.kubernetes.annotations | Map | | +| quarkus.kubernetes.env-vars | Map | | +| quarkus.kubernetes.working-dir | String | | +| quarkus.kubernetes.command | String[] | | +| quarkus.kubernetes.arguments | String[] | | +| quarkus.kubernetes.replicas | int | | 1 +| quarkus.kubernetes.service-account | String | | +| quarkus.kubernetes.host | String | | +| quarkus.kubernetes.ports | Map | | +| quarkus.kubernetes.service-type | ServiceType | | ClusterIP +| quarkus.kubernetes.pvc-volumes | Map | | +| quarkus.kubernetes.secret-volumes | Map | | +| quarkus.kubernetes.config-map-volumes | Map | | +| quarkus.kubernetes.git-repo-volumes | Map | | +| quarkus.kubernetes.aws-elastic-block-store-volumes | Map | | +| quarkus.kubernetes.azure-disk-volumes | Map | | +| quarkus.kubernetes.azure-file-volumes | Map | | +| quarkus.kubernetes.mounts | Map | | +| quarkus.kubernetes.image-pull-policy | ImagePullPolicy | | IfNotPresent +| quarkus.kubernetes.image-pull-secrets | String[] | | +| quarkus.kubernetes.liveness-probe | Probe | | ( see Probe ) +| quarkus.kubernetes.readiness-probe | Probe | | ( see Probe ) +| quarkus.kubernetes.sidecars | Map | | +| quarkus.kubernetes.expose | boolean | | false +| quarkus.kubernetes.headless | boolean | | false |==== Properties that use non standard types, can be referenced by expanding the property. @@ -249,8 +247,8 @@ For example to define a `kubernetes-readiness-probe` which is of type `Probe`: [source] ---- -kubernetes.readiness-probe.initial-delay-seconds=20 -kubernetes.readiness-probe.period-seconds=45 +quarkus.kubernetes.readiness-probe.initial-delay-seconds=20 +quarkus.kubernetes.readiness-probe.period-seconds=45 ---- In this example `initial-delay` and `period-seconds` are fields of the type `Probe`. @@ -259,27 +257,10 @@ Below you will find tables describing all available types. ===== Basic Types -.Annotation -|==== -| Property | Type | Description | Default Value -| key | String | | -| value | String | | -|==== - - -.Label -|==== -| Property | Type | Description | Default Value -| key | String | | -| value | String | | -|==== - - .Env |==== | Property | Type | Description | Default Value -| name | String | | -| value | String | | +| value | String | | | secret | String | | | configmap | String | | | field | String | | @@ -299,7 +280,6 @@ Below you will find tables describing all available types. .Port |==== | Property | Type | Description | Default Value -| name | String | | | container-port | int | | | host-port | int | | 0 | path | String | | / @@ -310,8 +290,7 @@ Below you will find tables describing all available types. |==== | Property | Type | Description | Default Value | image | String | | -| name | String | | -| env-vars | Env[] | | +| env-vars | Env[] | | | working-dir | String | | | command | String[] | | | arguments | String[] | | @@ -328,7 +307,6 @@ Below you will find tables describing all available types. .Mount |==== | Property | Type | Description | Default Value -| name | String | | | path | String | | | sub-path | String | | | read-only | boolean | | false @@ -337,8 +315,7 @@ Below you will find tables describing all available types. .ConfigMapVolume |==== | Property | Type | Description | Default Value -| volume-name | String | | -| config-map-name | String | | +| config-map-name | String | | | default-mode | int | | 384 | optional | boolean | | false |==== @@ -346,8 +323,7 @@ Below you will find tables describing all available types. .SecretVolume |==== | Property | Type | Description | Default Value -| volume-name | String | | -| secret-name | String | | +| secret-name | String | | | default-mode | int | | 384 | optional | boolean | | false |==== @@ -356,8 +332,7 @@ Below you will find tables describing all available types. .AzureDiskVolume |==== | Property | Type | Description | Default Value -| volume-name | String | | -| disk-name | String | | +| disk-name | String | | | disk-uri | String | | | kind | String | | Managed | caching-mode | String | | ReadWrite @@ -368,8 +343,7 @@ Below you will find tables describing all available types. .AwsElasticBlockStoreVolume |==== | Property | Type | Description | Default Value -| volume-name | String | | -| volume-id | String | | +| volume-id | String | | | partition | int | | | fs-type | String | | ext4 | read-only | boolean | | false @@ -378,7 +352,6 @@ Below you will find tables describing all available types. .GitRepoVolume |==== | Property | Type | Description | Default Value -| volume-name | String | | | repository | String | | | directory | String | | | revision | String | | @@ -387,112 +360,85 @@ Below you will find tables describing all available types. .PersistentVolumeClaimVolume |==== | Property | Type | Description | Default Value -| volume-name | String | | -| claim-name | String | | +| claim-name | String | | | read-only | boolean | | false |==== .AzureFileVolume |==== | Property | Type | Description | Default Value -| volume-name | String | | -| share-name | String | | +| share-name | String | | | secret-name | String | | | read-only | boolean | | false |==== -== Docker - -.Docker -|==== -| Property | Type | Description | Default Value -| docker.docker-file | String | | Dockerfile -| docker.registry | String | | -| docker.auto-push-enabled | boolean | | false -| docker.auto-build-enabled | boolean | | false -|==== - === OpenShift To enable the generation of OpenShift resources, you need to include OpenShift in the target platforms: [source] ---- -kubernetes.deployment.target=openshift +quarkus.kubernetes.deployment-target=openshift ---- If you need to generate resources for both platforms (vanilla Kubernetes and OpenShift), then you need to include both (coma separated). [source] ---- -kubernetes.deployment.target=kubernetes, openshift +quarkus.kubernetes.deployment-target=kubernetes, openshift ---- The OpenShift resources can be customized in a similar approach with Kubernetes. .Openshift |==== -| Property | Type | Description | Default Value -| openshift.group | String | | -| openshift.name | String | | -| openshift.version | String | | -| openshift.init-containers | Container[] | | -| openshift.labels | Label[] | | -| openshift.annotations | Annotation[] | | -| openshift.env-vars | Env[] | | -| openshift.working-dir | String | | -| openshift.command | String[] | | -| openshift.arguments | String[] | | -| openshift.replicas | int | | 1 -| openshift.service-account | String | | -| openshift.host | String | | -| openshift.ports | Port[] | | -| openshift.service-type | ServiceType | | ClusterIP -| openshift.pvc-volumes | PersistentVolumeClaimVolume[] | | -| openshift.secret-volumes | SecretVolume[] | | -| openshift.config-map-volumes | ConfigMapVolume[] | | -| openshift.git-repo-volumes | GitRepoVolume[] | | -| openshift.aws-elastic-block-store-volumes | AwsElasticBlockStoreVolume[] | | -| openshift.azure-disk-volumes | AzureDiskVolume[] | | -| openshift.azure-file-volumes | AzureFileVolume[] | | -| openshift.mounts | Mount[] | | -| openshift.image-pull-policy | ImagePullPolicy | | IfNotPresent -| openshift.image-pull-secrets | String[] | | -| openshift.liveness-probe | Probe | | ( see Probe ) -| openshift.readiness-probe | Probe | | ( see Probe ) -| openshift.sidecars | Container[] | | -| openshift.expose | boolean | | false -| openshift.headless | boolean | | false -| openshift.auto-deploy-enabled | boolean | | false -|==== - -.S2i -|==== -| Property | Type | Description | Default Value -| s2i.enabled | boolean | | true -| s2i.docker-file | String | | Dockerfile -| s2i.registry | String | | -| s2i.builder-image | String | | fabric8/s2i-java:2.3 -| s2i.build-env-vars | Env[] | | -| s2i.auto-push-enabled | boolean | | false -| s2i.auto-build-enabled | boolean | | false -| s2i.auto-deploy-enabled | boolean | | false +| Property | Type | Description | Default Value +| quarkus.openshift.group | String | | +| quarkus.openshift.name | String | | +| quarkus.openshift.version | String | | +| quarkus.openshift.init-containers | Map | | +| quarkus.openshift.labels | Map | | +| quarkus.openshift.annotations | Map | | +| quarkus.openshift.env-vars | Map | | +| quarkus.openshift.working-dir | String | | +| quarkus.openshift.command | String[] | | +| quarkus.openshift.arguments | String[] | | +| quarkus.openshift.replicas | int | | 1 +| quarkus.openshift.service-account | String | | +| quarkus.openshift.host | String | | +| quarkus.openshift.ports | Map | | +| quarkus.openshift.service-type | ServiceType | | ClusterIP +| quarkus.openshift.pvc-volumes | Map | | +| quarkus.openshift.secret-volumes | Map | | +| quarkus.openshift.config-map-volumes | Map | | +| quarkus.openshift.git-repo-volumes | Map | | +| quarkus.openshift.aws-elastic-block-store-volumes | Map | | +| quarkus.openshift.azure-disk-volumes | Map | | +| quarkus.openshift.azure-file-volumes | Map | | +| quarkus.openshift.mounts | Map | | +| quarkus.openshift.image-pull-policy | ImagePullPolicy | | IfNotPresent +| quarkus.openshift.image-pull-secrets | String[] | | +| quarkus.openshift.liveness-probe | Probe | | ( see Probe ) +| quarkus.openshift.readiness-probe | Probe | | ( see Probe ) +| quarkus.openshift.sidecars | Map | | +| quarkus.openshift.expose | boolean | | false +| quarkus.openshift.headless | boolean | | false |==== === Knative -To enable the generation of Knative resources, you need to include Knative in the target platforms: +To enable the generation of Quarkus.Knative.resources, you need to include Knative in the target platforms: [source] ---- -kubernetes.deployment.target=knative +quarkus.kubernetes.deployment.target=knative ---- Following the execution of `./mvnw package` you will notice amongst the other files that are created, two files named -`knative.json` and `knative.yml` in the `target/kubernetes/` directory. +`quarkus.knative.json` and `knative.yml` in the `target/kubernetes/` directory. -If you look at either file you will see that it contains a Knative `Service`. +If you look at either file you will see that it contains a Quarkus.Knative.`Service`. -The full source of the `knative.json` file looks something like this: +The full source of the `quarkus.knative.json` file looks something like this: [source,json] ---- @@ -500,7 +446,7 @@ The full source of the `knative.json` file looks something like this: "apiVersion" : "v1", "kind" : "List", "items" : [ { - "apiVersion" : "serving.knative.dev/v1alpha1", + "apiVersion" : "serving.quarkus.knative.dev/v1alpha1", "kind" : "Service", "metadata" : { "labels" : { @@ -508,7 +454,7 @@ The full source of the `knative.json` file looks something like this: "version" : "0.1-SNAPSHOT", "group" : "yourDockerUsername" }, - "name" : "knative" + "name" : "quarkus.knative. }, "spec" : { "runLatest" : { @@ -532,36 +478,79 @@ The generated service can be customized using the following properties: .Knative |==== -| Property | Type | Description | Default Value -| knative.group | String | | -| knative.name | String | | -| knative.version | String | | -| knative.labels | Label[] | | -| knative.annotations | Annotation[] | | -| knative.env-vars | Env[] | | -| knative.working-dir | String | | -| knative.command | String[] | | -| knative.arguments | String[] | | -| knative.service-account | String | | -| knative.host | String | | -| knative.ports | Port[] | | -| knative.service-type | ServiceType | | ClusterIP -| knative.pvc-volumes | PersistentVolumeClaimVolume[] | | -| knative.secret-volumes | SecretVolume[] | | -| knative.config-map-volumes | ConfigMapVolume[] | | -| knative.git-repo-volumes | GitRepoVolume[] | | -| knative.aws-elastic-block-store-volumes | AwsElasticBlockStoreVolume[] | | -| knative.azure-disk-volumes | AzureDiskVolume[] | | -| knative.azure-file-volumes | AzureFileVolume[] | | -| knative.mounts | Mount[] | | -| knative.image-pull-policy | ImagePullPolicy | | IfNotPresent -| knative.image-pull-secrets | String[] | | -| knative.liveness-probe | Probe | | ( see Probe ) -| knative.readiness-probe | Probe | | ( see Probe ) -| knative.sidecars | Container[] | | -| knative.expose | boolean | | false +| Property | Type | Description | Default Value +| quarkus.knative.group | String | | +| quarkus.knative.name | String | | +| quarkus.knative.version | String | | +| quarkus.knative.init-containers | Map | | +| quarkus.knative.labels | Map | | +| quarkus.knative.annotations | Map | | +| quarkus.knative.env-vars | Map | | +| quarkus.knative.working-dir | String | | +| quarkus.knative.command | String[] | | +| quarkus.knative.arguments | String[] | | +| quarkus.knative.replicas | int | | 1 +| quarkus.knative.service-account | String | | +| quarkus.knative.host | String | | +| quarkus.knative.ports | Map | | +| quarkus.knative.service-type | ServiceType | | ClusterIP +| quarkus.knative.pvc-volumes | Map | | +| quarkus.knative.secret-volumes | Map | | +| quarkus.knative.config-map-volumes | Map | | +| quarkus.knative.git-repo-volumes | Map | | +| quarkus.knative.aws-elastic-block-store-volumes | Map | | +| quarkus.knative.azure-disk-volumes | Map | | +| quarkus.knative.azure-file-volumes | Map | | +| quarkus.knative.mounts | Map | | +| quarkus.knative.image-pull-policy | ImagePullPolicy | | IfNotPresent +| quarkus.knative.image-pull-secrets | String[] | | +| quarkus.knative.liveness-probe | Probe | | ( see Probe ) +| quarkus.knative.readiness-probe | Probe | | ( see Probe ) +| quarkus.knative.sidecars | Map | | |==== + +=== Deprecated configuration + +The following categories of configuration properties have been deprecated. + +==== Properties without the quarkus prefix + +In earlier versions of the extension, the `quarkus.` was missing from those properties. These properties are now deprecated. + +==== Docker and S2i properties + +The properties for configuring `docker` and `s2i` are also deprecated in favor of the new container-image extensions. + +==== Config group arrays + +Properties refering to config group arrays (e.g. kubernetes.labels[0], kubernetes.env-vars[0] etc) have been converted to maps, to align with the rest of the quarkus ecosystem. + +The code below demonstrates the change in `labels` config: + +[source] +---- +# Old labels config: +kubernetes.labels[0].name=foo +kubernetes.labels[0].name=bar + +# New labels +quarkus.kubernetes.labels.foo=bar +---- + +The code below demonstrates the change in `env-vars` config: + +[source] +---- +# Old env-vars config: +kubernetes.env-vars[0].name=foo +kubernetes.env-vars[0].configmap=my-configmap + +# New env-vars +quarkus.kubernetes.env-vars.foo.configmap=myconfigmap +---- + + == Deployment To trigger building and deploying a container image you need to enable the `quarkus.container.deploy` flag. @@ -584,7 +573,7 @@ Each time deployment is requested, a container build will be implicitly triggere === Deploying -When deployment is enabled, the kubernetes extension will selected the resources specified by `kubernetes.deployment.target` and deploy them. +When deployment is enabled, the kubernetes extension will selected the resources specified by `quarkus.kubernetes.deployment.target` and deploy them. This assumes that a `.kube/config` is available in your user directory that points to a real kubernetes cluster. In other words the extension will use whatever cluster `kubectl` uses. The same applies to credentials. diff --git a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/Constants.java b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/Constants.java index 2be32c91797756..5b45d201d68c72 100644 --- a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/Constants.java +++ b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/Constants.java @@ -3,6 +3,9 @@ public class Constants { static final String KUBERNETES = "kubernetes"; + static final String OPENSHIFT = "openshift"; + static final String KNATIVE = "knative"; + static final String DEPLOYMENT_TARGET = "kubernetes.deployment.target"; static final String DEPLOY = "quarkus.kubernetes.deploy"; } diff --git a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesConfig.java b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesConfig.java deleted file mode 100644 index 7ceefccf7e84c9..00000000000000 --- a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesConfig.java +++ /dev/null @@ -1,22 +0,0 @@ - -package io.quarkus.kubernetes.deployment; - -import java.util.List; - -import io.quarkus.runtime.annotations.ConfigItem; -import io.quarkus.runtime.annotations.ConfigRoot; - -@ConfigRoot -public class KubernetesConfig { - - /** - * The target deployment platform. - * Defaults to kubernetes. Can be kubernetes, openshift, knative or any combination of the above as comma separated list. - */ - @ConfigItem(defaultValue = "kubernetes") - List deploymentTarget; - - public List getDeploymentTarget() { - return this.deploymentTarget; - } -} diff --git a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesConfigUtil.java b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesConfigUtil.java new file mode 100644 index 00000000000000..75abb474abef75 --- /dev/null +++ b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesConfigUtil.java @@ -0,0 +1,121 @@ +package io.quarkus.kubernetes.deployment; + +import static io.quarkus.kubernetes.deployment.Constants.*; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; + +import org.eclipse.microprofile.config.Config; +import org.eclipse.microprofile.config.ConfigProvider; + +import io.dekorate.utils.Strings; + +public class KubernetesConfigUtil { + + private static final String DEKORATE_PREFIX = "dekorate."; + private static final String QUARKUS_PREFIX = "quarkus."; + + //Most of quarkus prefixed properties are handling directly by the config items (KubenretesConfig, OpenshiftConfig, KnativeConfig) + //We just need group, name & version parsed here, as we don't have decorators for these (low level properties). + private static final Set QUARKUS_PREFIX_WHITELIST = new HashSet(Arrays.asList("group", "name", "version")); + + private static final Set ALLOWED_GENERATORS = new HashSet( + Arrays.asList("kubernetes", "openshift", "knative", "docker", "s2i")); + private static final Set IMAGE_GENERATORS = new HashSet(Arrays.asList("docker", "s2i")); + + public static List getDeploymentTargets() { + return getDeploymentTargets(toMap()); + } + + public static List getDeploymentTargets(Map map) { + return Arrays.stream(map.getOrDefault(DEKORATE_PREFIX + DEPLOYMENT_TARGET, KUBERNETES).toString().split(",")) + .map(String::trim) + .map(String::toLowerCase) + .collect(Collectors.toList()); + } + + public static Optional getDockerRegistry(Map map) { + return IMAGE_GENERATORS.stream().map(g -> map.get(DEKORATE_PREFIX + g + ".registry")).filter(p -> p != null) + .map(String::valueOf).findFirst(); + } + + public static Optional getGroup(Map map) { + return ALLOWED_GENERATORS.stream().map(g -> map.get(DEKORATE_PREFIX + g + ".group")).filter(p -> p != null) + .map(String::valueOf).findFirst(); + } + + public static Optional getName(Map map) { + return ALLOWED_GENERATORS.stream().map(g -> map.get(DEKORATE_PREFIX + g + ".name")).filter(p -> p != null) + .map(String::valueOf).findFirst(); + } + + /* + * Collects configuration properties for Kubernetes. Reads all properties and + * matches properties that match known dekorate generators. These properties may + * or may not be prefixed with `quarkus.` though the prefixed ones take + * precedence. + * + * @return A map containing the properties. + */ + public static Map toMap() { + Config config = ConfigProvider.getConfig(); + Map result = new HashMap<>(); + + Map quarkusPrefixed = StreamSupport.stream(config.getPropertyNames().spliterator(), false) + .filter(s -> s.startsWith(QUARKUS_PREFIX)) + .map(s -> s.replaceFirst(QUARKUS_PREFIX, "")) + .filter(k -> ALLOWED_GENERATORS.contains(generatorName(k))) + .filter(k -> QUARKUS_PREFIX_WHITELIST.contains(propertyName(k))) + .filter(k -> config.getOptionalValue(QUARKUS_PREFIX + k, String.class).isPresent()) + .collect(Collectors.toMap(k -> DEKORATE_PREFIX + k, + k -> config.getValue(QUARKUS_PREFIX + k, String.class))); + + Map UnPrefixed = StreamSupport.stream(config.getPropertyNames().spliterator(), false) + .filter(k -> ALLOWED_GENERATORS.contains(generatorName(k))) + .filter(k -> config.getOptionalValue(k, String.class).isPresent()) + .collect(Collectors.toMap(k -> DEKORATE_PREFIX + k, k -> config.getValue(k, String.class))); + + result.putAll(UnPrefixed); + result.putAll(quarkusPrefixed); + return result; + } + + /** + * Returns the name of the generators that can handle the specified key. + * + * @param key The key. + * @return The generator name or null if the key format is unexpected. + */ + private static String generatorName(String key) { + if (Strings.isNullOrEmpty(key) || !key.contains(".")) { + return null; + } + return key.substring(0, key.indexOf(".")); + } + + /** + * Returns the name of the property stripped of all prefixes. + * + * @param key The key. + * @return The property name. + */ + private static String propertyName(String key) { + if (Strings.isNullOrEmpty(key) || !key.contains(".")) { + return key; + } + return key.substring(key.lastIndexOf(".") + 1); + } + + private T[] toArray(List list) { + Class clazz = list.get(0).getClass(); + T[] array = (T[]) java.lang.reflect.Array.newInstance(clazz, list.size()); + return list.toArray(array); + } +} diff --git a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesDeploy.java b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesDeploy.java index cf1cacbf5bd568..c73df36efb094c 100644 --- a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesDeploy.java +++ b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesDeploy.java @@ -20,6 +20,7 @@ import io.quarkus.container.image.deployment.ContainerImageConfig; import io.quarkus.deployment.util.ExecUtil; +import io.quarkus.kubernetes.deployment.config.KubernetesConfig; public class KubernetesDeploy implements BooleanSupplier { diff --git a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesDeployer.java b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesDeployer.java index 1653632ad32371..b189bc2385c2bb 100644 --- a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesDeployer.java +++ b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesDeployer.java @@ -1,23 +1,19 @@ package io.quarkus.kubernetes.deployment; -import static io.quarkus.kubernetes.deployment.Constants.DEPLOYMENT_TARGET; -import static io.quarkus.kubernetes.deployment.Constants.KUBERNETES; - import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.file.Path; -import java.util.Arrays; -import java.util.List; +import java.util.HashSet; +import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.stream.Collectors; import javax.net.ssl.SSLHandshakeException; -import org.eclipse.microprofile.config.Config; -import org.eclipse.microprofile.config.ConfigProvider; import org.jboss.logging.Logger; import io.dekorate.deps.kubernetes.api.model.HasMetadata; @@ -34,13 +30,15 @@ import io.quarkus.deployment.pkg.builditem.DeploymentResultBuildItem; import io.quarkus.deployment.pkg.builditem.OutputTargetBuildItem; import io.quarkus.kubernetes.client.spi.KubernetesClientBuildItem; +import io.quarkus.kubernetes.deployment.config.KubernetesConfig; public class KubernetesDeployer { private static final Logger LOG = Logger.getLogger(KubernetesDeployer.class); @BuildStep(onlyIf = { IsNormal.class, KubernetesDeploy.class }) - public void deploy(KubernetesClientBuildItem kubernetesClient, + public void deploy(KubernetesConfig kubernetesConfig, + KubernetesClientBuildItem kubernetesClient, ApplicationInfoBuildItem applicationInfo, Optional containerImage, OutputTargetBuildItem outputTarget, @@ -51,10 +49,14 @@ public void deploy(KubernetesClientBuildItem kubernetesClient, "A Kubernetes deployment was requested but no extension was found to build a container image. Consider adding one of following extensions: \"quarkus-container-image-jib\", \"quarkus-container-image-docker\" or \"quarkus-container-image-s2i\"."); } - Config config = ConfigProvider.getConfig(); - List deploymentTargets = Arrays - .stream(config.getOptionalValue(DEPLOYMENT_TARGET, String.class).orElse(KUBERNETES).split(",")) - .map(String::trim).map(String::toUpperCase).map(DeploymentTarget::valueOf).collect(Collectors.toList()); + Map config = KubernetesConfigUtil.toMap(); + Set deploymentTargets = new HashSet<>(); + deploymentTargets.addAll(KubernetesConfigUtil.getDeploymentTargets(config).stream() + .map(String::toUpperCase) + .map(DeploymentTarget::valueOf) + .collect(Collectors.toList())); + + deploymentTargets.addAll(kubernetesConfig.getDeploymentTarget()); final KubernetesClient client = Clients.fromConfig(kubernetesClient.getClient().getConfiguration()); DeploymentTarget target = deploymentTargets.stream().findFirst().orElse(DeploymentTarget.KUBERNETES); diff --git a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesProcessor.java b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesProcessor.java index a6bd62b2e16a1d..32083e56a9b383 100644 --- a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesProcessor.java +++ b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/KubernetesProcessor.java @@ -16,26 +16,38 @@ import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; -import java.util.stream.StreamSupport; - -import org.eclipse.microprofile.config.Config; -import org.eclipse.microprofile.config.ConfigProvider; import io.dekorate.Session; import io.dekorate.SessionWriter; +import io.dekorate.kubernetes.config.Annotation; import io.dekorate.kubernetes.config.EnvBuilder; +import io.dekorate.kubernetes.config.Label; import io.dekorate.kubernetes.config.PortBuilder; import io.dekorate.kubernetes.config.ProbeBuilder; import io.dekorate.kubernetes.configurator.AddPort; +import io.dekorate.kubernetes.decorator.AddAnnotationDecorator; +import io.dekorate.kubernetes.decorator.AddAwsElasticBlockStoreVolumeDecorator; +import io.dekorate.kubernetes.decorator.AddAzureDiskVolumeDecorator; +import io.dekorate.kubernetes.decorator.AddAzureFileVolumeDecorator; +import io.dekorate.kubernetes.decorator.AddConfigMapVolumeDecorator; import io.dekorate.kubernetes.decorator.AddEnvVarDecorator; +import io.dekorate.kubernetes.decorator.AddImagePullSecretDecorator; +import io.dekorate.kubernetes.decorator.AddInitContainerDecorator; +import io.dekorate.kubernetes.decorator.AddLabelDecorator; import io.dekorate.kubernetes.decorator.AddLivenessProbeDecorator; +import io.dekorate.kubernetes.decorator.AddMountDecorator; +import io.dekorate.kubernetes.decorator.AddPvcVolumeDecorator; import io.dekorate.kubernetes.decorator.AddReadinessProbeDecorator; import io.dekorate.kubernetes.decorator.AddRoleBindingResourceDecorator; +import io.dekorate.kubernetes.decorator.AddSecretVolumeDecorator; import io.dekorate.kubernetes.decorator.AddServiceAccountResourceDecorator; +import io.dekorate.kubernetes.decorator.AddSidecarDecorator; import io.dekorate.kubernetes.decorator.ApplyArgsDecorator; import io.dekorate.kubernetes.decorator.ApplyCommandDecorator; import io.dekorate.kubernetes.decorator.ApplyImageDecorator; +import io.dekorate.kubernetes.decorator.ApplyImagePullPolicyDecorator; import io.dekorate.kubernetes.decorator.ApplyServiceAccountNamedDecorator; +import io.dekorate.kubernetes.decorator.ApplyWorkingDirDecorator; import io.dekorate.processor.SimpleFileWriter; import io.dekorate.project.BuildInfo; import io.dekorate.project.FileProjectFactory; @@ -44,7 +56,6 @@ import io.dekorate.s2i.config.S2iBuildConfigBuilder; import io.dekorate.s2i.decorator.AddBuilderImageStreamResourceDecorator; import io.dekorate.utils.Maps; -import io.dekorate.utils.Strings; import io.quarkus.container.spi.BaseImageInfoBuildItem; import io.quarkus.container.spi.ContainerImageInfoBuildItem; import io.quarkus.deployment.IsNormal; @@ -56,6 +67,8 @@ import io.quarkus.deployment.builditem.GeneratedFileSystemResourceBuildItem; import io.quarkus.deployment.pkg.PackageConfig; import io.quarkus.deployment.pkg.builditem.OutputTargetBuildItem; +import io.quarkus.kubernetes.deployment.config.*; +import io.quarkus.kubernetes.deployment.convert.*; import io.quarkus.kubernetes.spi.KubernetesCommandBuildItem; import io.quarkus.kubernetes.spi.KubernetesEnvVarBuildItem; import io.quarkus.kubernetes.spi.KubernetesHealthLivenessPathBuildItem; @@ -80,6 +93,9 @@ public void build(ApplicationInfoBuildItem applicationInfo, ArchiveRootBuildItem archiveRootBuildItem, OutputTargetBuildItem outputTargetBuildItem, PackageConfig packageConfig, + KubernetesConfig kubernetesConfig, + OpenshiftConfig openshiftConfig, + KnativeConfig knativeConfig, List kubernetesEnvBuildItems, List kubernetesRoleBuildItems, List kubernetesPortBuildItems, @@ -104,35 +120,24 @@ public void build(ApplicationInfoBuildItem applicationInfo, throw new RuntimeException("Unable to setup environment for generating Kubernetes resources", e); } - Config config = ConfigProvider.getConfig(); - List deploymentTargets = Arrays - .stream(config.getOptionalValue(DEPLOYMENT_TARGET, String.class) - .orElse(KUBERNETES).split(",")) - .map(String::trim) - .map(String::toLowerCase) - .collect(Collectors.toList()); + Map config = KubernetesConfigUtil.toMap(); + config.entrySet().forEach(e -> System.out.println(e.getKey() + "=" + e.getValue())); - Map configAsMap = StreamSupport.stream(config.getPropertyNames().spliterator(), false) - .filter(k -> ALLOWED_GENERATORS.contains(generatorName(k))) - .collect(Collectors.toMap(k -> PROPERTY_PREFIX + k, k -> config.getValue(k, String.class))); + Set deploymentTargets = new HashSet<>(); + deploymentTargets.addAll(KubernetesConfigUtil.getDeploymentTargets(config)); + deploymentTargets.addAll(kubernetesConfig.getDeploymentTarget().stream().map(Enum::name).map(String::toLowerCase) + .collect(Collectors.toList())); // this is a hack to get kubernetes.registry working because currently it's not supported as is in Dekorate - Optional dockerRegistry = IMAGE_GENERATORS.stream() - .map(g -> config.getOptionalValue(g + ".registry", String.class)) - .filter(Optional::isPresent) - .map(Optional::get) - .findFirst(); - + Optional dockerRegistry = KubernetesConfigUtil.getDockerRegistry(config); dockerRegistry.ifPresent(v -> System.setProperty(DOCKER_REGISTRY_PROPERTY, v)); // this is a hack to work around Dekorate using the default group for some of the properties - Optional kubernetesGroup = ALLOWED_GENERATORS.stream() - .map(g -> config.getOptionalValue(g + ".group", String.class)) - .filter(Optional::isPresent) - .map(Optional::get) - .findFirst(); + Optional kubernetesGroup = KubernetesConfigUtil.getGroup(config); kubernetesGroup.ifPresent(v -> System.setProperty(APP_GROUP_PROPERTY, v)); + String name = KubernetesConfigUtil.getName(config).orElse(applicationInfo.getName()); + Path artifactPath = archiveRootBuildItem.getArchiveRoot().resolve( String.format(OUTPUT_ARTIFACT_FORMAT, outputTargetBuildItem.getBaseName(), packageConfig.runnerSuffix)); final Map generatedResourcesMap; @@ -143,12 +148,18 @@ public void build(ApplicationInfoBuildItem applicationInfo, final Session session = Session.getSession(); session.setWriter(sessionWriter); - session.feed(Maps.fromProperties(configAsMap)); + session.feed(Maps.fromProperties(config)); + + //Apply configuration + applyGlobalConfig(session, kubernetesConfig); + applyConfig(session, KUBERNETES, name, kubernetesConfig); + applyConfig(session, OPENSHIFT, name, openshiftConfig); + applyConfig(session, KNATIVE, name, knativeConfig); //apply build item configurations to the dekorate session. applyBuildItems(session, + name, deploymentTargets, - applicationInfo, kubernetesEnvBuildItems, kubernetesRoleBuildItems, kubernetesPortBuildItems, @@ -195,9 +206,120 @@ public void build(ApplicationInfoBuildItem applicationInfo, featureProducer.produce(new FeatureBuildItem(FeatureBuildItem.KUBERNETES)); } + /** + * Apply global changes + * + * @param session The session to apply the changes + * @param config The {@link KubernetesConfig} instance + */ + private void applyGlobalConfig(Session session, KubernetesConfig config) { + //Ports + config.getPorts().entrySet().stream().forEach(e -> session.configurators().add(new AddPort(PortConverter.convert(e)))); + } + + /** + * Apply changes to the target resource group + * + * @param session The session to apply the changes + * @param target The deployment target (e.g. kubernetes, openshift, knative) + * @param name The name of the resource to accept the configuration + * @param config The {@link PlatformConfiguration} instance + */ + private void applyConfig(Session session, String target, String name, PlatformConfiguration config) { + //Labels + config.getLabels().entrySet().stream().forEach(e -> { + session.resources().decorate(target, new AddLabelDecorator(new Label(e.getKey(), e.getValue()))); + }); + + //Annotations + config.getAnnotations().entrySet().stream().forEach(e -> { + session.resources().decorate(target, new AddAnnotationDecorator(new Annotation(e.getKey(), e.getValue()))); + }); + + //EnvVars + config.getEnvVars().entrySet().stream().forEach(e -> { + session.resources().decorate(target, new AddEnvVarDecorator(EnvConverter.convert(e))); + }); + + config.getWorkingDir().ifPresent(w -> { + session.resources().decorate(target, new ApplyWorkingDirDecorator(name, DEPLOY)); + }); + + config.getCommand().ifPresent(c -> { + session.resources().decorate(target, + new ApplyCommandDecorator(name, c.toArray(new String[c.size()]))); + }); + + config.getArguments().ifPresent(a -> { + session.resources().decorate(target, new ApplyArgsDecorator(name, a.toArray(new String[a.size()]))); + }); + + config.getServiceAccount().ifPresent(s -> { + session.resources().decorate(target, new ApplyServiceAccountNamedDecorator(name, s)); + }); + + //Image Pull + session.resources().decorate(new ApplyImagePullPolicyDecorator(config.getImagePullPolicy())); + config.getImagePullSecrets().ifPresent(l -> { + l.forEach(s -> session.resources().decorate(target, new AddImagePullSecretDecorator(name, s))); + }); + + //Probes + config.getLivenessProbe().ifPresent(p -> { + session.resources().decorate(target, new AddLivenessProbeDecorator(name, ProbeConverter.convert(p))); + }); + + config.getReadinessProbe().ifPresent(p -> { + session.resources().decorate(target, + new AddReadinessProbeDecorator(name, ProbeConverter.convert(p))); + }); + + // Mounts and Volumes + config.getMounts().entrySet().forEach(e -> { + session.resources().decorate(target, new AddMountDecorator(MountConverter.convert(e))); + }); + + config.getSecretVolumes().entrySet().forEach(e -> { + session.resources().decorate(target, new AddSecretVolumeDecorator(SecretVolumeConverter.convert(e))); + }); + + config.getConfigMapVolumes().entrySet().forEach(e -> { + session.resources().decorate(target, new AddConfigMapVolumeDecorator(ConfigMapVolumeConverter.convert(e))); + }); + + //config.getGitRepoVolumes().entrySet().forEach(e -> { + // session.resources().decorate(target, new AddGitRepoVoluemDecorator(GitRepoVolumeConverter.convert(e))); + //}); + + config.getPvcVolumes().entrySet().forEach(e -> { + session.resources().decorate(target, new AddPvcVolumeDecorator(PvcVolumeConverter.convert(e))); + }); + + config.getAwsElasticBlockStoreVolumes().entrySet().forEach(e -> { + session.resources().decorate(target, + new AddAwsElasticBlockStoreVolumeDecorator(AwsElasticBlockStoreVolumeConverter.convert(e))); + }); + + config.getAzureFileVolumes().entrySet().forEach(e -> { + session.resources().decorate(target, new AddAzureFileVolumeDecorator(AzureFileVolumeConverter.convert(e))); + }); + + config.getAzureDiskVolumes().entrySet().forEach(e -> { + session.resources().decorate(target, new AddAzureDiskVolumeDecorator(AzureDiskVolumeConverter.convert(e))); + }); + + config.getInitContainers().entrySet().forEach(e -> { + session.resources().decorate(target, new AddInitContainerDecorator(name, ContainerConverter.convert(e))); + }); + + config.getContainers().entrySet().forEach(e -> { + session.resources().decorate(target, new AddSidecarDecorator(name, ContainerConverter.convert(e))); + }); + } + private void applyBuildItems(Session session, - List deploymentTargets, - ApplicationInfoBuildItem applicationInfo, + String name, + Set deploymentTargets, List kubernetesEnvBuildItems, List kubernetesRoleBuildItems, List kubernetesPortBuildItems, @@ -208,7 +330,7 @@ private void applyBuildItems(Session session, Optional kubernetesHealthReadinessPathBuildItem) { containerImageBuildItem.ifPresent(c -> session.resources() - .decorate(new ApplyImageDecorator(applicationInfo.getName(), c.getImage()))); + .decorate(new ApplyImageDecorator(name, c.getImage()))); //Handle env variables kubernetesEnvBuildItems.forEach(e -> session.resources() @@ -216,8 +338,8 @@ private void applyBuildItems(Session session, //Handle Command and arguments commandBuildItem.ifPresent(c -> { - session.resources().decorate(new ApplyCommandDecorator(applicationInfo.getName(), new String[] { c.getCommand() })); - session.resources().decorate(new ApplyArgsDecorator(applicationInfo.getName(), c.getArgs())); + session.resources().decorate(new ApplyCommandDecorator(name, new String[] { c.getCommand() })); + session.resources().decorate(new ApplyArgsDecorator(name, c.getArgs())); }); //Handle ports @@ -241,19 +363,19 @@ private void applyBuildItems(Session session, session.resources().decorate(DeploymentTarget.OPENSHIFT.name().toLowerCase(), new AddBuilderImageStreamResourceDecorator(s2iBuildConfig)); - session.resources().decorate(new ApplyBuilderImageDecorator(applicationInfo.getName(), builderImage)); + session.resources().decorate(new ApplyBuilderImageDecorator(name, builderImage)); }); } //Handle probes kubernetesHealthLivenessPathBuildItem .ifPresent(l -> session.resources() - .decorate(new AddLivenessProbeDecorator(applicationInfo.getName(), new ProbeBuilder() + .decorate(new AddLivenessProbeDecorator(name, new ProbeBuilder() .withHttpActionPath(l.getPath()) .build()))); kubernetesHealthReadinessPathBuildItem .ifPresent(r -> session.resources() - .decorate(new AddReadinessProbeDecorator(applicationInfo.getName(), new ProbeBuilder() + .decorate(new AddReadinessProbeDecorator(name, new ProbeBuilder() .withHttpActionPath(r.getPath()) .build()))); } @@ -290,17 +412,4 @@ private Project createProject(ApplicationInfoBuildItem app, Path artifactPath) { return new Project(project.getRoot(), buildInfo, project.getScmInfo()); } - /** - * Returns the name of the generators that can handle the specified key. - * - * @param key The key. - * @return The generator name or null if the key format is unexpected. - */ - private static String generatorName(String key) { - if (Strings.isNullOrEmpty(key) || !key.contains(".")) { - return null; - } - return key.substring(0, key.indexOf(".")); - } - } diff --git a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/AwsElasticBlockStoreVolumeConfig.java b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/AwsElasticBlockStoreVolumeConfig.java new file mode 100644 index 00000000000000..238e820daa6850 --- /dev/null +++ b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/AwsElasticBlockStoreVolumeConfig.java @@ -0,0 +1,68 @@ + +package io.quarkus.kubernetes.deployment.config; + +import java.util.Optional; + +import io.quarkus.runtime.annotations.ConfigGroup; +import io.quarkus.runtime.annotations.ConfigItem; + +@ConfigGroup +public class AwsElasticBlockStoreVolumeConfig { + + /** + * The name of the disk to mount. + */ + @ConfigItem + String volumeId; + + /** + * The partition. + */ + @ConfigItem + Optional partition; + + /** + * Filesystem type. + */ + @ConfigItem(defaultValue = "ext4") + String fsType; + + /** + * Wether the volumeName is read only or not. + */ + @ConfigItem(defaultValue = "false") + boolean readOnly; + + public String getVolumeId() { + return volumeId; + } + + public void setVolumeId(String volumeId) { + this.volumeId = volumeId; + } + + public Optional getPartition() { + return partition; + } + + public void setPartition(Optional partition) { + this.partition = partition; + } + + public String getFsType() { + return fsType; + } + + public void setFsType(String fsType) { + this.fsType = fsType; + } + + public boolean isReadOnly() { + return readOnly; + } + + public void setReadOnly(boolean readOnly) { + this.readOnly = readOnly; + } + +} diff --git a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/AzureDiskVolumeConfig.java b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/AzureDiskVolumeConfig.java new file mode 100644 index 00000000000000..d4f51084a73375 --- /dev/null +++ b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/AzureDiskVolumeConfig.java @@ -0,0 +1,105 @@ + +package io.quarkus.kubernetes.deployment.config; + +import io.quarkus.runtime.annotations.ConfigGroup; +import io.quarkus.runtime.annotations.ConfigItem; + +@ConfigGroup +public class AzureDiskVolumeConfig { + + public enum CachingMode { + ReadWrite, + ReadOnly, + None + } + + public enum Kind { + Managed, + Shared + } + + /** + * The name of the disk to mount. + */ + @ConfigItem + String diskName; + + /** + * The URI of the vhd blob object OR the resourceID of an Azure managed data disk if Kind is Managed + */ + @ConfigItem + String diskURI; + + /** + * Kind of disk. + */ + @ConfigItem(defaultValue = "Managed") + Kind kind; + + /** + * Disk caching mode. + */ + @ConfigItem(defaultValue = "ReadWrite") + CachingMode cachingMode; + + /** + * File system type. + */ + @ConfigItem(defaultValue = "ext4") + String fsType; + + /** + * Wether the volumeName is read only or not. + */ + @ConfigItem(defaultValue = "false") + boolean readOnly; + + public String getDiskName() { + return diskName; + } + + public void setDiskName(String diskName) { + this.diskName = diskName; + } + + public String getDiskURI() { + return diskURI; + } + + public void setDiskURI(String diskURI) { + this.diskURI = diskURI; + } + + public Kind getKind() { + return kind; + } + + public void setKind(Kind kind) { + this.kind = kind; + } + + public CachingMode getCachingMode() { + return cachingMode; + } + + public void setCachingMode(CachingMode cachingMode) { + this.cachingMode = cachingMode; + } + + public String getFsType() { + return fsType; + } + + public void setFsType(String fsType) { + this.fsType = fsType; + } + + public boolean isReadOnly() { + return readOnly; + } + + public void setReadOnly(boolean readOnly) { + this.readOnly = readOnly; + } + +} diff --git a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/AzureFileVolumeConfig.java b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/AzureFileVolumeConfig.java new file mode 100644 index 00000000000000..cfccb2b076c3b3 --- /dev/null +++ b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/AzureFileVolumeConfig.java @@ -0,0 +1,51 @@ + +package io.quarkus.kubernetes.deployment.config; + +import io.quarkus.runtime.annotations.ConfigGroup; +import io.quarkus.runtime.annotations.ConfigItem; + +@ConfigGroup +public class AzureFileVolumeConfig { + + /** + * The share name. + */ + @ConfigItem + String shareName; + + /** + * The secret name. + */ + @ConfigItem + String secretName; + + /** + * Wether the volumeName is read only or not. + */ + @ConfigItem(defaultValue = "false") + boolean readOnly; + + public String getShareName() { + return shareName; + } + + public void setShareName(String shareName) { + this.shareName = shareName; + } + + public String getSecretName() { + return secretName; + } + + public void setSecretName(String secretName) { + this.secretName = secretName; + } + + public boolean isReadOnly() { + return readOnly; + } + + public void setReadOnly(boolean readOnly) { + this.readOnly = readOnly; + } +} diff --git a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/ConfigMapVolumeConfig.java b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/ConfigMapVolumeConfig.java new file mode 100644 index 00000000000000..b11707a84b44cf --- /dev/null +++ b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/ConfigMapVolumeConfig.java @@ -0,0 +1,53 @@ +package io.quarkus.kubernetes.deployment.config; + +import io.quarkus.runtime.annotations.ConfigGroup; +import io.quarkus.runtime.annotations.ConfigItem; + +@ConfigGroup +public class ConfigMapVolumeConfig { + + /** + * The name of the ConfigMap to mount. + */ + @ConfigItem + String configMapName; + + /** + * Default mode. + * + * @return The default mode. + */ + @ConfigItem(defaultValue = "0600") + Integer defaultMode; + + /** + * Optional + */ + @ConfigItem(defaultValue = "false") + boolean optional; + + public String getConfigMapName() { + return configMapName; + } + + public void setConfigMapName(String configMapName) { + this.configMapName = configMapName; + } + + public Integer getDefaultMode() { + return defaultMode; + } + + public void setDefaultMode(Integer defaultMode) { + this.defaultMode = defaultMode; + } + + public boolean isOptional() { + return optional; + } + + public void setOptional(boolean optional) { + this.optional = optional; + } + +} diff --git a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/ContainerConfig.java b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/ContainerConfig.java new file mode 100644 index 00000000000000..a8b665e998a355 --- /dev/null +++ b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/ContainerConfig.java @@ -0,0 +1,200 @@ + +package io.quarkus.kubernetes.deployment.config; + +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import io.dekorate.kubernetes.annotation.ImagePullPolicy; +import io.quarkus.runtime.annotations.ConfigGroup; +import io.quarkus.runtime.annotations.ConfigItem; + +@ConfigGroup +public class ContainerConfig { + + /** + * The container image. + */ + @ConfigItem + Optional image; + + /** + * Environment variables to add to all containers. + */ + @ConfigItem + Map envVars; + + /** + * Working directory. + */ + @ConfigItem + Optional workingDir; + + /** + * The commands + */ + @ConfigItem + Optional> command; + + /** + * The arguments + * + * @return The arguments. + */ + @ConfigItem + Optional> arguments; + + /** + * The service account. + */ + @ConfigItem + Optional serviceAccount; + + /** + * The host under which the application is going to be exposed. + * + */ + @ConfigItem + Optional host; + + /** + * The application ports. + */ + @ConfigItem + Map ports; + + /** + * Image pull policy. + */ + @ConfigItem(defaultValue = "IfNotPresent") + ImagePullPolicy imagePullPolicy; + + /** + * The image pull secret + */ + @ConfigItem + Optional> imagePullSecrets; + + /** + * The liveness probe. + */ + @ConfigItem + Optional livenessProbe; + + /** + * The readiness probe. + */ + @ConfigItem + Optional readinessProbe; + + /** + * Volume mounts. + */ + @ConfigItem + Map mounts; + + public Optional getImage() { + return image; + } + + public void setImage(Optional image) { + this.image = image; + } + + public Map getEnvVars() { + return envVars; + } + + public void setEnvVars(Map envVars) { + this.envVars = envVars; + } + + public Optional getWorkingDir() { + return workingDir; + } + + public void setWorkingDir(Optional workingDir) { + this.workingDir = workingDir; + } + + public Optional> getCommand() { + return command; + } + + public void setCommand(Optional> command) { + this.command = command; + } + + public Optional> getArguments() { + return arguments; + } + + public void setArguments(Optional> arguments) { + this.arguments = arguments; + } + + public Optional getServiceAccount() { + return serviceAccount; + } + + public void setServiceAccount(Optional serviceAccount) { + this.serviceAccount = serviceAccount; + } + + public Optional getHost() { + return host; + } + + public void setHost(Optional host) { + this.host = host; + } + + public Map getPorts() { + return ports; + } + + public void setPorts(Map ports) { + this.ports = ports; + } + + public ImagePullPolicy getImagePullPolicy() { + return imagePullPolicy; + } + + public void setImagePullPolicy(ImagePullPolicy imagePullPolicy) { + this.imagePullPolicy = imagePullPolicy; + } + + public Optional> getImagePullSecrets() { + return imagePullSecrets; + } + + public void setImagePullSecrets(Optional> imagePullSecrets) { + this.imagePullSecrets = imagePullSecrets; + } + + public Optional getLivenessProbe() { + return livenessProbe; + } + + public void setLivenessProbe(Optional livenessProbe) { + this.livenessProbe = livenessProbe; + } + + public Optional getReadinessProbe() { + return readinessProbe; + } + + public void setReadinessProbe(Optional readinessProbe) { + this.readinessProbe = readinessProbe; + } + + public Map getMounts() { + return mounts; + } + + public void setMounts(Map mounts) { + this.mounts = mounts; + } + +} diff --git a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/EnvConfig.java b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/EnvConfig.java new file mode 100644 index 00000000000000..7278b133c3e7fa --- /dev/null +++ b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/EnvConfig.java @@ -0,0 +1,80 @@ +package io.quarkus.kubernetes.deployment.config; + +import java.util.Optional; + +import io.quarkus.runtime.annotations.ConfigGroup; +import io.quarkus.runtime.annotations.ConfigItem; + +@ConfigGroup +public class EnvConfig { + + /** + * The environment variable name. + */ + @ConfigItem + Optional name; + + /** + * The environment variable value. + */ + @ConfigItem + Optional value; + + /** + * The environment variable secret. + */ + @ConfigItem + Optional secret; + + /** + * The environment variable config map. + */ + @ConfigItem + Optional configmap; + + /** + * The environment variable field. + */ + @ConfigItem + Optional field; + + public Optional getName() { + return name; + } + + public void setName(Optional name) { + this.name = name; + } + + public Optional getValue() { + return value; + } + + public void setValue(Optional value) { + this.value = value; + } + + public Optional getSecret() { + return secret; + } + + public void setSecret(Optional secret) { + this.secret = secret; + } + + public Optional getConfigmap() { + return configmap; + } + + public void setConfigmap(Optional configmap) { + this.configmap = configmap; + } + + public Optional getField() { + return field; + } + + public void setField(Optional field) { + this.field = field; + } +} diff --git a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/GitRepoVolumeConfig.java b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/GitRepoVolumeConfig.java new file mode 100644 index 00000000000000..4d759745e889db --- /dev/null +++ b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/GitRepoVolumeConfig.java @@ -0,0 +1,53 @@ + +package io.quarkus.kubernetes.deployment.config; + +import java.util.Optional; + +import io.quarkus.runtime.annotations.ConfigGroup; +import io.quarkus.runtime.annotations.ConfigItem; + +@ConfigGroup +public class GitRepoVolumeConfig { + + /** + * Git repoistory URL. + */ + @ConfigItem + String repository; + + /** + * The directory of the repository to mount. + */ + @ConfigItem + Optional directory; + + /** + * The commit hash to use. + */ + @ConfigItem + Optional revision; + + public String getRepository() { + return repository; + } + + public void setRepository(String repository) { + this.repository = repository; + } + + public Optional getDirectory() { + return directory; + } + + public void setDirectory(Optional directory) { + this.directory = directory; + } + + public Optional getRevision() { + return revision; + } + + public void setRevision(Optional revision) { + this.revision = revision; + } +} diff --git a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/KnativeConfig.java b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/KnativeConfig.java new file mode 100644 index 00000000000000..0aa4a72bd4a6a5 --- /dev/null +++ b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/KnativeConfig.java @@ -0,0 +1,404 @@ + +package io.quarkus.kubernetes.deployment.config; + +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import io.dekorate.kubernetes.annotation.ImagePullPolicy; +import io.dekorate.kubernetes.annotation.ServiceType; +import io.quarkus.runtime.annotations.ConfigItem; +import io.quarkus.runtime.annotations.ConfigRoot; + +@ConfigRoot +public class KnativeConfig implements PlatformConfiguration { + /** + * The group of the application. This value will be use as: - docker image repo + * - labeling resources + */ + @ConfigItem + Optional group; + + /** + * The name of the application. This value will be used for naming Kubernetes + * resources like: - Deployment - Service and so on ... If no value is specified + * it will attempt to determine the name using the following rules: If its a + * maven/gradle project use the artifact id. Else if its a bazel project use the + * name. Else if the system property app.name is present it will be used. Else + * find the project root folder and use its name (root folder detection is done + * by moving to the parent folder until .git is found). + */ + @ConfigItem + Optional name; + + /** + * The version of the application. This value be used for things like: - The + * docker image tag. If no value specified it will attempt to determine the name + * using the following rules: + */ + @ConfigItem + Optional version; + + /** + * Custom labels to add to all resources + */ + @ConfigItem + Map labels; + + /** + * Custom annotations to add to all resources + */ + @ConfigItem + Map annotations; + + /** + * Environment variables to add to all containers + */ + @ConfigItem + Map envVars; + + /** + * Working directory + */ + @ConfigItem + Optional workingDir; + + /** + * The commands + */ + @ConfigItem + Optional> command; + + /** + * The arguments + * + * @return The arguments + */ + @ConfigItem + Optional> arguments; + + /** + * The service account + */ + @ConfigItem + Optional serviceAccount; + + /** + * The host under which the application is going to be exposed + */ + @ConfigItem + Optional host; + + /** + * The application ports + */ + @ConfigItem + Map ports; + + /** + * The type of service that will be generated for the application + */ + @ConfigItem(defaultValue = "ClusterIP") + ServiceType serviceType; + + /** + * Image pull policy + */ + @ConfigItem(defaultValue = "IfNotPresent") + ImagePullPolicy imagePullPolicy; + + /** + * The image pull secret + */ + @ConfigItem + Optional> imagePullSecrets; + + /** + * The liveness probe + */ + @ConfigItem + Optional livenessProbe; + + /** + * The readiness probe + */ + @ConfigItem + Optional readinessProbe; + + /** + * Volume mounts + */ + @ConfigItem + Map mounts; + + /** + * Secret volumes + */ + @ConfigItem + Map secretVolumes; + + /** + * ConfigMap volumes + */ + @ConfigItem + Map configMapVolumes; + + /** + * Git Repository volumes + */ + @ConfigItem + Map gitRepoVolumes; + + /** + * PVC volumes + */ + @ConfigItem + Map pvcVolumes; + + /** + * AWS Elastic BlockStore volumes + */ + @ConfigItem + Map awsElasticBlockStoreVolumes; + + /** + * Azure file volumes + */ + @ConfigItem + Map azureFileVolumes; + + /** + * Azure disk volumes + */ + @ConfigItem + Map azureDiskVolumes; + + /** + * Init containers + */ + @ConfigItem + Map initContainers; + + /** + * Sidecar containers + */ + @ConfigItem + Map containers; + + public Optional getGroup() { + return group; + } + + public void setGroup(Optional group) { + this.group = group; + } + + public Optional getName() { + return name; + } + + public void setName(Optional name) { + this.name = name; + } + + public Optional getVersion() { + return version; + } + + public void setVersion(Optional version) { + this.version = version; + } + + public Map getLabels() { + return labels; + } + + public void setLabels(Map labels) { + this.labels = labels; + } + + public Map getAnnotations() { + return annotations; + } + + public void setAnnotations(Map annotations) { + this.annotations = annotations; + } + + public Map getEnvVars() { + return envVars; + } + + public void setEnvVars(Map envVars) { + this.envVars = envVars; + } + + public Optional getWorkingDir() { + return workingDir; + } + + public void setWorkingDir(Optional workingDir) { + this.workingDir = workingDir; + } + + public Optional> getCommand() { + return command; + } + + public void setCommand(Optional> command) { + this.command = command; + } + + public Optional> getArguments() { + return arguments; + } + + public void setArguments(Optional> arguments) { + this.arguments = arguments; + } + + public Optional getServiceAccount() { + return serviceAccount; + } + + public void setServiceAccount(Optional serviceAccount) { + this.serviceAccount = serviceAccount; + } + + public Optional getHost() { + return host; + } + + public void setHost(Optional host) { + this.host = host; + } + + public Map getPorts() { + return ports; + } + + public void setPorts(Map ports) { + this.ports = ports; + } + + public ServiceType getServiceType() { + return serviceType; + } + + public void setServiceType(ServiceType serviceType) { + this.serviceType = serviceType; + } + + public ImagePullPolicy getImagePullPolicy() { + return imagePullPolicy; + } + + public void setImagePullPolicy(ImagePullPolicy imagePullPolicy) { + this.imagePullPolicy = imagePullPolicy; + } + + public Optional> getImagePullSecrets() { + return imagePullSecrets; + } + + public void setImagePullSecrets(Optional> imagePullSecrets) { + this.imagePullSecrets = imagePullSecrets; + } + + public Optional getLivenessProbe() { + return livenessProbe; + } + + public void setLivenessProbe(Optional livenessProbe) { + this.livenessProbe = livenessProbe; + } + + public Optional getReadinessProbe() { + return readinessProbe; + } + + public void setReadinessProbe(Optional readinessProbe) { + this.readinessProbe = readinessProbe; + } + + public Map getMounts() { + return mounts; + } + + public void setMounts(Map mounts) { + this.mounts = mounts; + } + + public Map getSecretVolumes() { + return secretVolumes; + } + + public void setSecretVolumes(Map secretVolumes) { + this.secretVolumes = secretVolumes; + } + + public Map getConfigMapVolumes() { + return configMapVolumes; + } + + public void setConfigMapVolumes(Map configMapVolumes) { + this.configMapVolumes = configMapVolumes; + } + + public Map getGitRepoVolumes() { + return gitRepoVolumes; + } + + public void setGitRepoVolumes(Map gitRepoVolumes) { + this.gitRepoVolumes = gitRepoVolumes; + } + + public Map getPvcVolumes() { + return pvcVolumes; + } + + public void setPvcVolumes(Map pvcVolumes) { + this.pvcVolumes = pvcVolumes; + } + + public Map getAwsElasticBlockStoreVolumes() { + return awsElasticBlockStoreVolumes; + } + + public void setAwsElasticBlockStoreVolumes(Map awsElasticBlockStoreVolumes) { + this.awsElasticBlockStoreVolumes = awsElasticBlockStoreVolumes; + } + + public Map getAzureFileVolumes() { + return azureFileVolumes; + } + + public void setAzureFileVolumes(Map azureFileVolumes) { + this.azureFileVolumes = azureFileVolumes; + } + + public Map getAzureDiskVolumes() { + return azureDiskVolumes; + } + + public void setAzureDiskVolumes(Map azureDiskVolumes) { + this.azureDiskVolumes = azureDiskVolumes; + } + + public Map getInitContainers() { + return initContainers; + } + + public void setInitContainers(Map initContainers) { + this.initContainers = initContainers; + } + + public Map getContainers() { + return containers; + } + + public void setContainers(Map containers) { + this.containers = containers; + } + +} diff --git a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/KubernetesConfig.java b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/KubernetesConfig.java new file mode 100644 index 00000000000000..a24ddaf49f3884 --- /dev/null +++ b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/KubernetesConfig.java @@ -0,0 +1,421 @@ +package io.quarkus.kubernetes.deployment.config; + +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import io.dekorate.kubernetes.annotation.ImagePullPolicy; +import io.dekorate.kubernetes.annotation.ServiceType; +import io.quarkus.kubernetes.deployment.DeploymentTarget; +import io.quarkus.runtime.annotations.ConfigItem; +import io.quarkus.runtime.annotations.ConfigRoot; + +@ConfigRoot +public class KubernetesConfig implements PlatformConfiguration { + + /** + * The group of the application. This value will be use as: - docker image repo + * - labeling resources + */ + @ConfigItem + Optional group; + + /** + * The name of the application. This value will be used for naming Kubernetes + * resources like: - Deployment - Service and so on ... If no value is specified + * it will attempt to determine the name using the following rules: If its a + * maven/gradle project use the artifact id. Else if its a bazel project use the + * name. Else if the system property app.name is present it will be used. Else + * find the project root folder and use its name (root folder detection is done + * by moving to the parent folder until .git is found). + */ + @ConfigItem + Optional name; + + /** + * The version of the application. This value be used for things like: - The + * docker image tag. If no value specified it will attempt to determine the name + * using the following rules: + */ + @ConfigItem + Optional version; + + /** + * Custom labels to add to all resources + */ + @ConfigItem + Map labels; + + /** + * Custom annotations to add to all resources + */ + @ConfigItem + Map annotations; + + /** + * Environment variables to add to all containers + */ + @ConfigItem + Map envVars; + + /** + * Working directory + */ + @ConfigItem + Optional workingDir; + + /** + * The commands + */ + @ConfigItem + Optional> command; + + /** + * The arguments + * + * @return The arguments + */ + @ConfigItem + Optional> arguments; + + /** + * The service account + */ + @ConfigItem + Optional serviceAccount; + + /** + * The host under which the application is going to be exposed + */ + @ConfigItem + Optional host; + + /** + * The application ports + */ + @ConfigItem + Map ports; + + /** + * The type of service that will be generated for the application + */ + @ConfigItem(defaultValue = "ClusterIP") + ServiceType serviceType; + + /** + * Image pull policy + */ + @ConfigItem(defaultValue = "IfNotPresent") + ImagePullPolicy imagePullPolicy; + + /** + * The image pull secret + */ + @ConfigItem + Optional> imagePullSecrets; + + /** + * The liveness probe + */ + @ConfigItem + Optional livenessProbe; + + /** + * The readiness probe + */ + @ConfigItem + Optional readinessProbe; + + /** + * Volume mounts + */ + @ConfigItem + Map mounts; + + /** + * Secret volumes + */ + @ConfigItem + Map secretVolumes; + + /** + * ConfigMap volumes + */ + @ConfigItem + Map configMapVolumes; + + /** + * Git Repository volumes + */ + @ConfigItem + Map gitRepoVolumes; + + /** + * PVC volumes + */ + @ConfigItem + Map pvcVolumes; + + /** + * AWS Elastic BlockStore volumes + */ + @ConfigItem + Map awsElasticBlockStoreVolumes; + + /** + * Azure file volumes + */ + @ConfigItem + Map azureFileVolumes; + + /** + * Azure disk volumes + */ + @ConfigItem + Map azureDiskVolumes; + + /** + * Init containers + */ + @ConfigItem + Map initContainers; + + /** + * Sidecar containers + */ + @ConfigItem + Map containers; + + /** + * The target deployment platform. Defaults to kubernetes. Can be kubernetes, + * openshift, knative or any combination of the above as comma separated list. + */ + @ConfigItem(defaultValue = "kubernetes") + List deploymentTarget; + + public Optional getGroup() { + return group; + } + + public void setGroup(Optional group) { + this.group = group; + } + + public Optional getName() { + return name; + } + + public void setName(Optional name) { + this.name = name; + } + + public Optional getVersion() { + return version; + } + + public void setVersion(Optional version) { + this.version = version; + } + + public Map getLabels() { + return labels; + } + + public void setLabels(Map labels) { + this.labels = labels; + } + + public Map getAnnotations() { + return annotations; + } + + public void setAnnotations(Map annotations) { + this.annotations = annotations; + } + + public Map getEnvVars() { + return envVars; + } + + public void setEnvVars(Map envVars) { + this.envVars = envVars; + } + + public Optional getWorkingDir() { + return workingDir; + } + + public void setWorkingDir(Optional workingDir) { + this.workingDir = workingDir; + } + + public Optional> getCommand() { + return command; + } + + public void setCommand(Optional> command) { + this.command = command; + } + + public Optional> getArguments() { + return arguments; + } + + public void setArguments(Optional> arguments) { + this.arguments = arguments; + } + + public Optional getServiceAccount() { + return serviceAccount; + } + + public void setServiceAccount(Optional serviceAccount) { + this.serviceAccount = serviceAccount; + } + + public Optional getHost() { + return host; + } + + public void setHost(Optional host) { + this.host = host; + } + + public Map getPorts() { + return ports; + } + + public void setPorts(Map ports) { + this.ports = ports; + } + + public ServiceType getServiceType() { + return serviceType; + } + + public void setServiceType(ServiceType serviceType) { + this.serviceType = serviceType; + } + + public ImagePullPolicy getImagePullPolicy() { + return imagePullPolicy; + } + + public void setImagePullPolicy(ImagePullPolicy imagePullPolicy) { + this.imagePullPolicy = imagePullPolicy; + } + + public Optional> getImagePullSecrets() { + return imagePullSecrets; + } + + public void setImagePullSecrets(Optional> imagePullSecrets) { + this.imagePullSecrets = imagePullSecrets; + } + + public Optional getLivenessProbe() { + return livenessProbe; + } + + public void setLivenessProbe(Optional livenessProbe) { + this.livenessProbe = livenessProbe; + } + + public Optional getReadinessProbe() { + return readinessProbe; + } + + public void setReadinessProbe(Optional readinessProbe) { + this.readinessProbe = readinessProbe; + } + + public Map getMounts() { + return mounts; + } + + public void setMounts(Map mounts) { + this.mounts = mounts; + } + + public Map getSecretVolumes() { + return secretVolumes; + } + + public void setSecretVolumes(Map secretVolumes) { + this.secretVolumes = secretVolumes; + } + + public Map getConfigMapVolumes() { + return configMapVolumes; + } + + public void setConfigMapVolumes(Map configMapVolumes) { + this.configMapVolumes = configMapVolumes; + } + + public Map getGitRepoVolumes() { + return gitRepoVolumes; + } + + public void setGitRepoVolumes(Map gitRepoVolumes) { + this.gitRepoVolumes = gitRepoVolumes; + } + + public Map getPvcVolumes() { + return pvcVolumes; + } + + public void setPvcVolumes(Map pvcVolumes) { + this.pvcVolumes = pvcVolumes; + } + + public Map getAwsElasticBlockStoreVolumes() { + return awsElasticBlockStoreVolumes; + } + + public void setAwsElasticBlockStoreVolumes( + Map awsElasticBlockStoreVolumes) { + this.awsElasticBlockStoreVolumes = awsElasticBlockStoreVolumes; + } + + public Map getAzureFileVolumes() { + return azureFileVolumes; + } + + public void setAzureFileVolumes(Map azureFileVolumes) { + this.azureFileVolumes = azureFileVolumes; + } + + public Map getAzureDiskVolumes() { + return azureDiskVolumes; + } + + public void setAzureDiskVolumes(Map azureDiskVolumes) { + this.azureDiskVolumes = azureDiskVolumes; + } + + public Map getInitContainers() { + return initContainers; + } + + public void setInitContainers(Map initContainers) { + this.initContainers = initContainers; + } + + public Map getContainers() { + return containers; + } + + public void setContainers(Map containers) { + this.containers = containers; + } + + public List getDeploymentTarget() { + return deploymentTarget; + } + + public void setDeploymentTarget(List deploymentTarget) { + this.deploymentTarget = deploymentTarget; + } + +} diff --git a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/MountConfig.java b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/MountConfig.java new file mode 100644 index 00000000000000..27ebc8cd7c18a8 --- /dev/null +++ b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/MountConfig.java @@ -0,0 +1,77 @@ + +package io.quarkus.kubernetes.deployment.config; + +import java.util.Optional; + +import io.quarkus.runtime.annotations.ConfigGroup; +import io.quarkus.runtime.annotations.ConfigItem; + +@ConfigGroup +public class MountConfig { + + /** + * The name of the volumeName to mount. + * + * @return The name. + */ + @ConfigItem + Optional name; + + /** + * The path to mount. + * + * @return The path. + */ + @ConfigItem + Optional path; + + /** + * Path within the volumeName from which the container's volumeName should be + * mounted. + * + * @return The subPath. + */ + @ConfigItem + Optional subPath; + + /** + * ReadOnly + * + * @return True if mount is readonly, False otherwise. + */ + @ConfigItem(defaultValue = "false") + boolean readOnly; + + public Optional getName() { + return name; + } + + public void setName(Optional name) { + this.name = name; + } + + public Optional getPath() { + return path; + } + + public void setPath(Optional path) { + this.path = path; + } + + public Optional getSubPath() { + return subPath; + } + + public void setSubPath(Optional subPath) { + this.subPath = subPath; + } + + public boolean isReadOnly() { + return readOnly; + } + + public void setReadOnly(boolean readOnly) { + this.readOnly = readOnly; + } + +} diff --git a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/OpenshiftConfig.java b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/OpenshiftConfig.java new file mode 100644 index 00000000000000..657eebfafa1c68 --- /dev/null +++ b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/OpenshiftConfig.java @@ -0,0 +1,406 @@ + +package io.quarkus.kubernetes.deployment.config; + +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import io.dekorate.kubernetes.annotation.ImagePullPolicy; +import io.dekorate.kubernetes.annotation.ServiceType; +import io.quarkus.runtime.annotations.ConfigItem; +import io.quarkus.runtime.annotations.ConfigRoot; + +@ConfigRoot +public class OpenshiftConfig implements PlatformConfiguration { + + /** + * The group of the application. This value will be use as: - docker image repo + * - labeling resources + */ + @ConfigItem + Optional group; + + /** + * The name of the application. This value will be used for naming Kubernetes + * resources like: - Deployment - Service and so on ... If no value is specified + * it will attempt to determine the name using the following rules: If its a + * maven/gradle project use the artifact id. Else if its a bazel project use the + * name. Else if the system property app.name is present it will be used. Else + * find the project root folder and use its name (root folder detection is done + * by moving to the parent folder until .git is found). + */ + @ConfigItem + Optional name; + + /** + * The version of the application. This value be used for things like: - The + * docker image tag. If no value specified it will attempt to determine the name + * using the following rules: + */ + @ConfigItem + Optional version; + + /** + * Custom labels to add to all resources + */ + @ConfigItem + Map labels; + + /** + * Custom annotations to add to all resources + */ + @ConfigItem + Map annotations; + + /** + * Environment variables to add to all containers + */ + @ConfigItem + Map envVars; + + /** + * Working directory + */ + @ConfigItem + Optional workingDir; + + /** + * The commands + */ + @ConfigItem + Optional> command; + + /** + * The arguments + * + * @return The arguments + */ + @ConfigItem + Optional> arguments; + + /** + * The service account + */ + @ConfigItem + Optional serviceAccount; + + /** + * The host under which the application is going to be exposed + */ + @ConfigItem + Optional host; + + /** + * The application ports + */ + @ConfigItem + Map ports; + + /** + * The type of service that will be generated for the application + */ + @ConfigItem(defaultValue = "ClusterIP") + ServiceType serviceType; + + /** + * Image pull policy + */ + @ConfigItem(defaultValue = "IfNotPresent") + ImagePullPolicy imagePullPolicy; + + /** + * The image pull secret + */ + @ConfigItem + Optional> imagePullSecrets; + + /** + * The liveness probe + */ + @ConfigItem + Optional livenessProbe; + + /** + * The readiness probe + */ + @ConfigItem + Optional readinessProbe; + + /** + * Volume mounts + */ + @ConfigItem + Map mounts; + + /** + * Secret volumes + */ + @ConfigItem + Map secretVolumes; + + /** + * ConfigMap volumes + */ + @ConfigItem + Map configMapVolumes; + + /** + * Git Repository volumes + */ + @ConfigItem + Map gitRepoVolumes; + + /** + * PVC volumes + */ + @ConfigItem + Map pvcVolumes; + + /** + * AWS Elastic BlockStore volumes + */ + @ConfigItem + Map awsElasticBlockStoreVolumes; + + /** + * Azure file volumes + */ + @ConfigItem + Map azureFileVolumes; + + /** + * Azure disk volumes + */ + @ConfigItem + Map azureDiskVolumes; + + /** + * Init containers + */ + @ConfigItem + Map initContainers; + + /** + * Sidecar containers + */ + @ConfigItem + Map containers; + + public Optional getGroup() { + return group; + } + + public void setGroup(Optional group) { + this.group = group; + } + + public Optional getName() { + return name; + } + + public void setName(Optional name) { + this.name = name; + } + + public Optional getVersion() { + return version; + } + + public void setVersion(Optional version) { + this.version = version; + } + + public Map getLabels() { + return labels; + } + + public void setLabels(Map labels) { + this.labels = labels; + } + + public Map getAnnotations() { + return annotations; + } + + public void setAnnotations(Map annotations) { + this.annotations = annotations; + } + + public Map getEnvVars() { + return envVars; + } + + public void setEnvVars(Map envVars) { + this.envVars = envVars; + } + + public Optional getWorkingDir() { + return workingDir; + } + + public void setWorkingDir(Optional workingDir) { + this.workingDir = workingDir; + } + + public Optional> getCommand() { + return command; + } + + public void setCommand(Optional> command) { + this.command = command; + } + + public Optional> getArguments() { + return arguments; + } + + public void setArguments(Optional> arguments) { + this.arguments = arguments; + } + + public Optional getServiceAccount() { + return serviceAccount; + } + + public void setServiceAccount(Optional serviceAccount) { + this.serviceAccount = serviceAccount; + } + + public Optional getHost() { + return host; + } + + public void setHost(Optional host) { + this.host = host; + } + + public Map getPorts() { + return ports; + } + + public void setPorts(Map ports) { + this.ports = ports; + } + + public ServiceType getServiceType() { + return serviceType; + } + + public void setServiceType(ServiceType serviceType) { + this.serviceType = serviceType; + } + + public ImagePullPolicy getImagePullPolicy() { + return imagePullPolicy; + } + + public void setImagePullPolicy(ImagePullPolicy imagePullPolicy) { + this.imagePullPolicy = imagePullPolicy; + } + + public Optional> getImagePullSecrets() { + return imagePullSecrets; + } + + public void setImagePullSecrets(Optional> imagePullSecrets) { + this.imagePullSecrets = imagePullSecrets; + } + + public Optional getLivenessProbe() { + return livenessProbe; + } + + public void setLivenessProbe(Optional livenessProbe) { + this.livenessProbe = livenessProbe; + } + + public Optional getReadinessProbe() { + return readinessProbe; + } + + public void setReadinessProbe(Optional readinessProbe) { + this.readinessProbe = readinessProbe; + } + + public Map getMounts() { + return mounts; + } + + public void setMounts(Map mounts) { + this.mounts = mounts; + } + + public Map getSecretVolumes() { + return secretVolumes; + } + + public void setSecretVolumes(Map secretVolumes) { + this.secretVolumes = secretVolumes; + } + + public Map getConfigMapVolumes() { + return configMapVolumes; + } + + public void setConfigMapVolumes(Map configMapVolumes) { + this.configMapVolumes = configMapVolumes; + } + + public Map getGitRepoVolumes() { + return gitRepoVolumes; + } + + public void setGitRepoVolumes(Map gitRepoVolumes) { + this.gitRepoVolumes = gitRepoVolumes; + } + + public Map getPvcVolumes() { + return pvcVolumes; + } + + public void setPvcVolumes(Map pvcVolumes) { + this.pvcVolumes = pvcVolumes; + } + + public Map getAwsElasticBlockStoreVolumes() { + return awsElasticBlockStoreVolumes; + } + + public void setAwsElasticBlockStoreVolumes( + Map awsElasticBlockStoreVolumes) { + this.awsElasticBlockStoreVolumes = awsElasticBlockStoreVolumes; + } + + public Map getAzureFileVolumes() { + return azureFileVolumes; + } + + public void setAzureFileVolumes(Map azureFileVolumes) { + this.azureFileVolumes = azureFileVolumes; + } + + public Map getAzureDiskVolumes() { + return azureDiskVolumes; + } + + public void setAzureDiskVolumes(Map azureDiskVolumes) { + this.azureDiskVolumes = azureDiskVolumes; + } + + public Map getInitContainers() { + return initContainers; + } + + public void setInitContainers(Map initContainers) { + this.initContainers = initContainers; + } + + public Map getContainers() { + return containers; + } + + public void setContainers(Map containers) { + this.containers = containers; + } + +} diff --git a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/PlatformConfiguration.java b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/PlatformConfiguration.java new file mode 100644 index 00000000000000..6984b62a175b0d --- /dev/null +++ b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/PlatformConfiguration.java @@ -0,0 +1,67 @@ + +package io.quarkus.kubernetes.deployment.config; + +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import io.dekorate.kubernetes.annotation.ImagePullPolicy; +import io.dekorate.kubernetes.annotation.ServiceType; + +public interface PlatformConfiguration { + + Optional getGroup(); + + Optional getName(); + + Optional getVersion(); + + Map getLabels(); + + Map getAnnotations(); + + Map getEnvVars(); + + Optional getWorkingDir(); + + Optional> getCommand(); + + Optional> getArguments(); + + Optional getServiceAccount(); + + Optional getHost(); + + Map getPorts(); + + ServiceType getServiceType(); + + ImagePullPolicy getImagePullPolicy(); + + Optional> getImagePullSecrets(); + + Optional getLivenessProbe(); + + Optional getReadinessProbe(); + + Map getMounts(); + + Map getSecretVolumes(); + + Map getConfigMapVolumes(); + + Map getGitRepoVolumes(); + + Map getPvcVolumes(); + + Map getAwsElasticBlockStoreVolumes(); + + Map getAzureFileVolumes(); + + Map getAzureDiskVolumes(); + + Map getInitContainers(); + + Map getContainers(); + +} diff --git a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/PortConfig.java b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/PortConfig.java new file mode 100644 index 00000000000000..e0af06de822202 --- /dev/null +++ b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/PortConfig.java @@ -0,0 +1,71 @@ + +package io.quarkus.kubernetes.deployment.config; + +import java.util.Optional; + +import io.dekorate.kubernetes.annotation.Protocol; +import io.quarkus.runtime.annotations.ConfigGroup; +import io.quarkus.runtime.annotations.ConfigItem; + +@ConfigGroup +public class PortConfig { + + /** + * The port number. Refers to the container port. + */ + @ConfigItem + Optional containerPort; + + /** + * The host port. + */ + @ConfigItem + Optional hostPort; + + /** + * The application path (refers to web application path). + * + * @return The path, defaults to /. + */ + @ConfigItem(defaultValue = "/") + Optional path; + + /** + * The protocol. + */ + @ConfigItem(defaultValue = "TCP") + Protocol protocol; + + public Optional getContainerPort() { + return containerPort; + } + + public void setContainerPort(Optional containerPort) { + this.containerPort = containerPort; + } + + public Optional getHostPort() { + return hostPort; + } + + public void setHostPort(Optional hostPort) { + this.hostPort = hostPort; + } + + public Optional getPath() { + return path; + } + + public void setPath(Optional path) { + this.path = path; + } + + public Protocol getProtocol() { + return protocol; + } + + public void setProtocol(Protocol protocol) { + this.protocol = protocol; + } + +} diff --git a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/ProbeConfig.java b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/ProbeConfig.java new file mode 100644 index 00000000000000..6aff6fc205c311 --- /dev/null +++ b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/ProbeConfig.java @@ -0,0 +1,130 @@ + +package io.quarkus.kubernetes.deployment.config; + +import java.util.Optional; + +import io.quarkus.runtime.annotations.ConfigGroup; +import io.quarkus.runtime.annotations.ConfigItem; + +@ConfigGroup +public class ProbeConfig { + + /** + * The http path to use for the probe For this to work, the container port also + * needs to be set + * + * Assuming the container port has been set (as per above comment), if + * execAction or tcpSocketAction are not set, an http probe will be used + * automatically even if no path is set (which will result in the root path + * being used) + */ + @ConfigItem + Optional httpActionPath; + + /** + * The command to use for the probe. + */ + @ConfigItem + Optional execAction; + + /** + * The tcp socket to use for the probe (the format is host:port). + */ + @ConfigItem + Optional tcpSocketAction; + + /** + * The amount of time to wait in seconds before starting to probe. + */ + @ConfigItem(defaultValue = "0") + Integer initialDelaySeconds; + + /** + * The period in which the action should be called. + */ + @ConfigItem(defaultValue = "30") + Integer periodSeconds; + + /** + * The amount of time to wait for each action. + */ + @ConfigItem(defaultValue = "10") + Integer timeoutSeconds; + + /** + * The success threshold to use. + */ + @ConfigItem(defaultValue = "1") + Integer successThreshold; + + /** + * The failure threshold to use. + */ + @ConfigItem(defaultValue = "3") + Integer failureThreshold; + + public Optional getHttpActionPath() { + return httpActionPath; + } + + public void setHttpActionPath(Optional httpActionPath) { + this.httpActionPath = httpActionPath; + } + + public Optional getExecAction() { + return execAction; + } + + public void setExecAction(Optional execAction) { + this.execAction = execAction; + } + + public Optional getTcpSocketAction() { + return tcpSocketAction; + } + + public void setTcpSocketAction(Optional tcpSocketAction) { + this.tcpSocketAction = tcpSocketAction; + } + + public Integer getInitialDelaySeconds() { + return initialDelaySeconds; + } + + public void setInitialDelaySeconds(Integer initialDelaySeconds) { + this.initialDelaySeconds = initialDelaySeconds; + } + + public Integer getPeriodSeconds() { + return periodSeconds; + } + + public void setPeriodSeconds(Integer periodSeconds) { + this.periodSeconds = periodSeconds; + } + + public Integer getTimeoutSeconds() { + return timeoutSeconds; + } + + public void setTimeoutSeconds(Integer timeoutSeconds) { + this.timeoutSeconds = timeoutSeconds; + } + + public Integer getSuccessThreshold() { + return successThreshold; + } + + public void setSuccessThreshold(Integer successThreshold) { + this.successThreshold = successThreshold; + } + + public Integer getFailureThreshold() { + return failureThreshold; + } + + public void setFailureThreshold(Integer failureThreshold) { + this.failureThreshold = failureThreshold; + } + +} diff --git a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/PvcVolumeConfig.java b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/PvcVolumeConfig.java new file mode 100644 index 00000000000000..92d006ffd00b1b --- /dev/null +++ b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/PvcVolumeConfig.java @@ -0,0 +1,53 @@ + +package io.quarkus.kubernetes.deployment.config; + +import io.quarkus.runtime.annotations.ConfigGroup; +import io.quarkus.runtime.annotations.ConfigItem; + +@ConfigGroup +public class PvcVolumeConfig { + + /** + * The name of the claim to mount. + */ + @ConfigItem + String claimName; + + /** + * Default mode. + * + * @return The default mode. + */ + @ConfigItem(defaultValue = "0600") + Integer defaultMode; + + /** + * Optional + */ + @ConfigItem(defaultValue = "false") + boolean optional; + + public String getClaimName() { + return claimName; + } + + public void setClaimName(String claimName) { + this.claimName = claimName; + } + + public Integer getDefaultMode() { + return defaultMode; + } + + public void setDefaultMode(Integer defaultMode) { + this.defaultMode = defaultMode; + } + + public boolean isOptional() { + return optional; + } + + public void setOptional(boolean optional) { + this.optional = optional; + } +} diff --git a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/SecretVolumeConfig.java b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/SecretVolumeConfig.java new file mode 100644 index 00000000000000..e6507b70f4631b --- /dev/null +++ b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/config/SecretVolumeConfig.java @@ -0,0 +1,49 @@ +package io.quarkus.kubernetes.deployment.config; + +import io.quarkus.runtime.annotations.ConfigItem; + +public class SecretVolumeConfig { + + /** + * The name of the secret to mount. + */ + String secretName; + + /** + * Default mode. + * + * @return The default mode. + */ + @ConfigItem(defaultValue = "0600") + Integer defaultMode; + + /** + * Optional + */ + @ConfigItem(defaultValue = "false") + boolean optional; + + public String getSecretName() { + return secretName; + } + + public void setSecretName(String secretName) { + this.secretName = secretName; + } + + public Integer getDefaultMode() { + return defaultMode; + } + + public void setDefaultMode(Integer defaultMode) { + this.defaultMode = defaultMode; + } + + public boolean isOptional() { + return optional; + } + + public void setOptional(boolean optional) { + this.optional = optional; + } +} diff --git a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/convert/AwsElasticBlockStoreVolumeConverter.java b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/convert/AwsElasticBlockStoreVolumeConverter.java new file mode 100644 index 00000000000000..d0bc2f9f47bc15 --- /dev/null +++ b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/convert/AwsElasticBlockStoreVolumeConverter.java @@ -0,0 +1,24 @@ + +package io.quarkus.kubernetes.deployment.convert; + +import java.util.Map; + +import io.dekorate.kubernetes.config.AwsElasticBlockStoreVolume; +import io.dekorate.kubernetes.config.AwsElasticBlockStoreVolumeBuilder; +import io.quarkus.kubernetes.deployment.config.AwsElasticBlockStoreVolumeConfig; + +public class AwsElasticBlockStoreVolumeConverter { + + public static AwsElasticBlockStoreVolume convert(Map.Entry e) { + return convert(e.getValue()).withVolumeName(e.getKey()).build(); + } + + public static AwsElasticBlockStoreVolumeBuilder convert(AwsElasticBlockStoreVolumeConfig c) { + AwsElasticBlockStoreVolumeBuilder b = new AwsElasticBlockStoreVolumeBuilder(); + b.withVolumeId(c.getVolumeId()); + b.withFsType(c.getFsType()); + b.withReadOnly(c.isReadOnly()); + c.getPartition().ifPresent(p -> b.withPartition(p)); + return b; + } +} diff --git a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/convert/AzureDiskVolumeConverter.java b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/convert/AzureDiskVolumeConverter.java new file mode 100644 index 00000000000000..011c101c04f73b --- /dev/null +++ b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/convert/AzureDiskVolumeConverter.java @@ -0,0 +1,27 @@ + +package io.quarkus.kubernetes.deployment.convert; + +import java.util.Map; + +import io.dekorate.kubernetes.config.AzureDiskVolume; +import io.dekorate.kubernetes.config.AzureDiskVolumeBuilder; +import io.quarkus.kubernetes.deployment.config.AzureDiskVolumeConfig; + +public class AzureDiskVolumeConverter { + + public static AzureDiskVolume convert(Map.Entry e) { + return convert(e.getValue()).withVolumeName(e.getKey()).build(); + } + + public static AzureDiskVolumeBuilder convert(AzureDiskVolumeConfig c) { + AzureDiskVolumeBuilder b = new AzureDiskVolumeBuilder(); + b.withNewDiskName(c.getDiskName()); + b.withDiskURI(c.getDiskURI()); + b.withKind(c.getKind().name()); + b.withCachingMode(c.getCachingMode().name()); + b.withFsType(c.getFsType()); + b.withReadOnly(c.isReadOnly()); + return b; + } + +} diff --git a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/convert/AzureFileVolumeConverter.java b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/convert/AzureFileVolumeConverter.java new file mode 100644 index 00000000000000..5dbf51ecbb52ad --- /dev/null +++ b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/convert/AzureFileVolumeConverter.java @@ -0,0 +1,23 @@ + +package io.quarkus.kubernetes.deployment.convert; + +import java.util.Map; + +import io.dekorate.kubernetes.config.AzureFileVolume; +import io.dekorate.kubernetes.config.AzureFileVolumeBuilder; +import io.quarkus.kubernetes.deployment.config.AzureFileVolumeConfig; + +public class AzureFileVolumeConverter { + + public static AzureFileVolume convert(Map.Entry e) { + return convert(e.getValue()).withVolumeName(e.getKey()).build(); + } + + public static AzureFileVolumeBuilder convert(AzureFileVolumeConfig c) { + AzureFileVolumeBuilder b = new AzureFileVolumeBuilder(); + b.withSecretName(c.getSecretName()); + b.withShareName(c.getShareName()); + b.withReadOnly(c.isReadOnly()); + return b; + } +} diff --git a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/convert/ConfigMapVolumeConverter.java b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/convert/ConfigMapVolumeConverter.java new file mode 100644 index 00000000000000..55958f65546487 --- /dev/null +++ b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/convert/ConfigMapVolumeConverter.java @@ -0,0 +1,24 @@ + +package io.quarkus.kubernetes.deployment.convert; + +import java.util.Map; + +import io.dekorate.kubernetes.config.ConfigMapVolume; +import io.dekorate.kubernetes.config.ConfigMapVolumeBuilder; +import io.quarkus.kubernetes.deployment.config.ConfigMapVolumeConfig; + +public class ConfigMapVolumeConverter { + + public static ConfigMapVolume convert(Map.Entry e) { + return convert(e.getValue()).withVolumeName(e.getKey()).build(); + } + + public static ConfigMapVolumeBuilder convert(ConfigMapVolumeConfig cm) { + ConfigMapVolumeBuilder b = new ConfigMapVolumeBuilder(); + b.withConfigMapName(cm.getConfigMapName()); + b.withDefaultMode(cm.getDefaultMode()); + b.withOptional(cm.isOptional()); + return b; + } + +} diff --git a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/convert/ContainerConverter.java b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/convert/ContainerConverter.java new file mode 100644 index 00000000000000..7bb8841caaa6bc --- /dev/null +++ b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/convert/ContainerConverter.java @@ -0,0 +1,27 @@ + +package io.quarkus.kubernetes.deployment.convert; + +import java.util.Map; + +import io.dekorate.kubernetes.config.Container; +import io.dekorate.kubernetes.config.ContainerBuilder; +import io.quarkus.kubernetes.deployment.config.ContainerConfig; + +public class ContainerConverter { + + public static Container convert(Map.Entry e) { + return convert(e.getValue()).withName(e.getKey()).build(); + } + + public static ContainerBuilder convert(ContainerConfig c) { + ContainerBuilder b = new ContainerBuilder(); + c.getImage().ifPresent(i -> b.withImage(i)); + c.getWorkingDir().ifPresent(w -> b.withWorkingDir(w)); + c.getReadinessProbe().ifPresent(p -> b.withReadinessProbe(ProbeConverter.convert(p))); + c.getLivenessProbe().ifPresent(p -> b.withLivenessProbe(ProbeConverter.convert(p))); + c.getEnvVars().entrySet().forEach(e -> b.addToEnvVars(EnvConverter.convert(e))); + c.getPorts().entrySet().forEach(e -> b.addToPorts(PortConverter.convert(e))); + c.getMounts().entrySet().forEach(e -> b.addToMounts(MountConverter.convert(e))); + return b; + } +} diff --git a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/convert/EnvConverter.java b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/convert/EnvConverter.java new file mode 100644 index 00000000000000..d31f8530d01798 --- /dev/null +++ b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/convert/EnvConverter.java @@ -0,0 +1,26 @@ + +package io.quarkus.kubernetes.deployment.convert; + +import java.util.Map; +import java.util.regex.Pattern; + +import io.dekorate.kubernetes.config.Env; +import io.dekorate.kubernetes.config.EnvBuilder; +import io.quarkus.kubernetes.deployment.config.EnvConfig; + +public class EnvConverter { + + public static Env convert(Map.Entry e) { + return convert(e.getValue()).withName(e.getKey().toUpperCase().replaceAll(Pattern.quote("-"), "_")).build(); + } + + public static EnvBuilder convert(EnvConfig env) { + EnvBuilder b = new EnvBuilder(); + env.getName().ifPresent(v -> b.withName(v)); + env.getValue().ifPresent(v -> b.withValue(v)); + env.getSecret().ifPresent(v -> b.withSecret(v)); + env.getConfigmap().ifPresent(v -> b.withConfigmap(v)); + env.getField().ifPresent(v -> b.withField(v)); + return b; + } +} diff --git a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/convert/GitRepoVolumeConverter.java b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/convert/GitRepoVolumeConverter.java new file mode 100644 index 00000000000000..25dfa580f48963 --- /dev/null +++ b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/convert/GitRepoVolumeConverter.java @@ -0,0 +1,6 @@ + +package io.quarkus.kubernetes.deployment.convert; + +public class GitRepoVolumeConverter { + +} diff --git a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/convert/MountConverter.java b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/convert/MountConverter.java new file mode 100644 index 00000000000000..9521fcb4f122e9 --- /dev/null +++ b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/convert/MountConverter.java @@ -0,0 +1,23 @@ + +package io.quarkus.kubernetes.deployment.convert; + +import java.util.Map; + +import io.dekorate.kubernetes.config.Mount; +import io.dekorate.kubernetes.config.MountBuilder; +import io.quarkus.kubernetes.deployment.config.MountConfig; + +public class MountConverter { + + public static Mount convert(Map.Entry e) { + return convert(e.getValue()).withName(e.getKey()).build(); + } + + public static MountBuilder convert(MountConfig mount) { + MountBuilder b = new MountBuilder(); + mount.getPath().ifPresent(v -> b.withPath(v)); + mount.getSubPath().ifPresent(v -> b.withSubPath(v)); + b.withReadOnly(mount.isReadOnly()); + return b; + } +} diff --git a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/convert/PortConverter.java b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/convert/PortConverter.java new file mode 100644 index 00000000000000..4b9a6ff8a5789e --- /dev/null +++ b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/convert/PortConverter.java @@ -0,0 +1,23 @@ + +package io.quarkus.kubernetes.deployment.convert; + +import java.util.Map; + +import io.dekorate.kubernetes.config.Port; +import io.dekorate.kubernetes.config.PortBuilder; +import io.quarkus.kubernetes.deployment.config.PortConfig; + +public class PortConverter { + + public static Port convert(Map.Entry e) { + return convert(e.getValue()).withName(e.getKey()).build(); + } + + public static PortBuilder convert(PortConfig port) { + PortBuilder b = new PortBuilder(); + port.getPath().ifPresent(v -> b.withPath(v)); + port.getHostPort().ifPresent(v -> b.withHostPort(v)); + port.getContainerPort().ifPresent(v -> b.withContainerPort(v)); + return b; + } +} diff --git a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/convert/ProbeConverter.java b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/convert/ProbeConverter.java new file mode 100644 index 00000000000000..8c5f7c1178faeb --- /dev/null +++ b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/convert/ProbeConverter.java @@ -0,0 +1,22 @@ + +package io.quarkus.kubernetes.deployment.convert; + +import io.dekorate.kubernetes.config.Probe; +import io.dekorate.kubernetes.config.ProbeBuilder; +import io.quarkus.kubernetes.deployment.config.ProbeConfig; + +public class ProbeConverter { + + public static Probe convert(ProbeConfig probe) { + ProbeBuilder b = new ProbeBuilder(); + probe.getHttpActionPath().ifPresent(v -> b.withHttpActionPath(v)); + probe.getExecAction().ifPresent(v -> b.withExecAction(v)); + probe.getTcpSocketAction().ifPresent(v -> b.withTcpSocketAction(v)); + b.withInitialDelaySeconds(probe.getInitialDelaySeconds()); + b.withPeriodSeconds(probe.getPeriodSeconds()); + b.withTimeoutSeconds(probe.getTimeoutSeconds()); + b.withSuccessThreshold(probe.getSuccessThreshold()); + b.withFailureThreshold(probe.getFailureThreshold()); + return b.build(); + } +} diff --git a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/convert/PvcVolumeConverter.java b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/convert/PvcVolumeConverter.java new file mode 100644 index 00000000000000..138dcc0c37d62b --- /dev/null +++ b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/convert/PvcVolumeConverter.java @@ -0,0 +1,22 @@ + +package io.quarkus.kubernetes.deployment.convert; + +import java.util.Map; + +import io.dekorate.kubernetes.config.PersistentVolumeClaimVolume; +import io.dekorate.kubernetes.config.PersistentVolumeClaimVolumeBuilder; +import io.quarkus.kubernetes.deployment.config.PvcVolumeConfig; + +public class PvcVolumeConverter { + + public static PersistentVolumeClaimVolume convert(Map.Entry e) { + return convert(e.getValue()).withVolumeName(e.getKey()).build(); + } + + public static PersistentVolumeClaimVolumeBuilder convert(PvcVolumeConfig c) { + PersistentVolumeClaimVolumeBuilder b = new PersistentVolumeClaimVolumeBuilder(); + b.withClaimName(c.getClaimName()); + b.withReadOnly(c.isOptional()); + return b; + } +} diff --git a/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/convert/SecretVolumeConverter.java b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/convert/SecretVolumeConverter.java new file mode 100644 index 00000000000000..281e84f3e37008 --- /dev/null +++ b/extensions/kubernetes/deployment/src/main/java/io/quarkus/kubernetes/deployment/convert/SecretVolumeConverter.java @@ -0,0 +1,23 @@ +package io.quarkus.kubernetes.deployment.convert; + +import java.util.Map; + +import io.dekorate.kubernetes.config.SecretVolume; +import io.dekorate.kubernetes.config.SecretVolumeBuilder; +import io.quarkus.kubernetes.deployment.config.SecretVolumeConfig; + +public class SecretVolumeConverter { + + public static SecretVolume convert(Map.Entry e) { + return convert(e.getValue()).withVolumeName(e.getKey()).build(); + } + + public static SecretVolumeBuilder convert(SecretVolumeConfig sv) { + SecretVolumeBuilder b = new SecretVolumeBuilder(); + b.withSecretName(sv.getSecretName()); + b.withDefaultMode(sv.getDefaultMode()); + b.withOptional(sv.isOptional()); + return b; + } + +} diff --git a/integration-tests/kubernetes/invoker/src/it/openshift-s2i-build-and-deploy/src/main/resources/application.properties b/integration-tests/kubernetes/invoker/src/it/openshift-s2i-build-and-deploy/src/main/resources/application.properties index 06aab08e2c369b..cdd463e8dca45a 100644 --- a/integration-tests/kubernetes/invoker/src/it/openshift-s2i-build-and-deploy/src/main/resources/application.properties +++ b/integration-tests/kubernetes/invoker/src/it/openshift-s2i-build-and-deploy/src/main/resources/application.properties @@ -1,4 +1,4 @@ # Configuration file # key = value -kubernetes.deployment.target=openshift +quarkus.kubernetes.deployment-target=openshift quarkus.kubernetes-client.trust-certs=true diff --git a/integration-tests/kubernetes/src/it/openshift-s2i-build-and-deploy/src/main/resources/application.properties b/integration-tests/kubernetes/src/it/openshift-s2i-build-and-deploy/src/main/resources/application.properties index 06aab08e2c369b..3d0cdee0c4c107 100644 --- a/integration-tests/kubernetes/src/it/openshift-s2i-build-and-deploy/src/main/resources/application.properties +++ b/integration-tests/kubernetes/src/it/openshift-s2i-build-and-deploy/src/main/resources/application.properties @@ -1,4 +1,4 @@ # Configuration file # key = value -kubernetes.deployment.target=openshift +quarkus.kubernetes.deployment.target=openshift quarkus.kubernetes-client.trust-certs=true diff --git a/integration-tests/kubernetes/standard/src/test/resources/knative.properties b/integration-tests/kubernetes/standard/src/test/resources/knative.properties index a5c9db4bc1a0f9..64bd7cf2283ff6 100644 --- a/integration-tests/kubernetes/standard/src/test/resources/knative.properties +++ b/integration-tests/kubernetes/standard/src/test/resources/knative.properties @@ -1,2 +1,2 @@ # Configuration file -kubernetes.deployment.target=knative \ No newline at end of file +quarkus.kubernetes.deployment-target=knative diff --git a/integration-tests/kubernetes/standard/src/test/resources/kubernetes-with-application.properties b/integration-tests/kubernetes/standard/src/test/resources/kubernetes-with-application.properties index afe5aca7881b2c..9f4ba363bb6cd8 100644 --- a/integration-tests/kubernetes/standard/src/test/resources/kubernetes-with-application.properties +++ b/integration-tests/kubernetes/standard/src/test/resources/kubernetes-with-application.properties @@ -1,8 +1,6 @@ quarkus.http.port=9090 -kubernetes.name=test-it -kubernetes.labels[0].key=foo -kubernetes.labels[0].value=bar -kubernetes.env-vars[0].name=MY_ENV_VAR -kubernetes.env-vars[0].value=SOMEVALUE -kubernetes.group=grp -docker.registry=quay.io \ No newline at end of file +quarkus.kubernetes.name=test-it +quarkus.kubernetes.labels.foo=bar +quarkus.kubernetes.env-vars.my-env-var.value=SOMEVALUE +quarkus.container-image.group=grp +quarkus.container-image.registry=quay.io diff --git a/integration-tests/kubernetes/standard/src/test/resources/kubernetes-with-quarkus-app-name.properties b/integration-tests/kubernetes/standard/src/test/resources/kubernetes-with-quarkus-app-name.properties index ada7e29dcd2717..1b8332079406fd 100644 --- a/integration-tests/kubernetes/standard/src/test/resources/kubernetes-with-quarkus-app-name.properties +++ b/integration-tests/kubernetes/standard/src/test/resources/kubernetes-with-quarkus-app-name.properties @@ -1,11 +1,11 @@ quarkus.application.name=test -kubernetes.deployment.target=kubernetes,openshift -kubernetes.name=foo -kubernetes.group=bar -kubernetes.version=1.0-kube +quarkus.kubernetes.deployment-target=kubernetes,openshift +quarkus.kubernetes.name=foo +quarkus.kubernetes.group=bar +quarkus.kubernetes.version=1.0-kube -openshift.name=ofoo -openshift.group=obar -openshift.version=1.0-openshift +quarkus.openshift.name=ofoo +quarkus.openshift.group=obar +quarkus.openshift.version=1.0-openshift -s2i.name=s2ifoo +quarkus.s2i.name=s2ifoo diff --git a/integration-tests/kubernetes/standard/src/test/resources/kubernetes-with-sys-group.properties b/integration-tests/kubernetes/standard/src/test/resources/kubernetes-with-sys-group.properties index 24d056be8af0d7..d56967af3aa40b 100644 --- a/integration-tests/kubernetes/standard/src/test/resources/kubernetes-with-sys-group.properties +++ b/integration-tests/kubernetes/standard/src/test/resources/kubernetes-with-sys-group.properties @@ -1 +1 @@ -kubernetes.group=grp \ No newline at end of file +quarkus.kubernetes.group=grp diff --git a/integration-tests/kubernetes/standard/src/test/resources/openshift-with-application.properties b/integration-tests/kubernetes/standard/src/test/resources/openshift-with-application.properties index de5dbd770a6241..2251f34e2c7c73 100644 --- a/integration-tests/kubernetes/standard/src/test/resources/openshift-with-application.properties +++ b/integration-tests/kubernetes/standard/src/test/resources/openshift-with-application.properties @@ -1,9 +1,7 @@ quarkus.http.port=9090 -kubernetes.deployment.target=openshift -openshift.name=test-it -openshift.labels[0].key=foo -openshift.labels[0].value=bar -openshift.env-vars[0].name=MY_ENV_VAR -openshift.env-vars[0].value=SOMEVALUE -openshift.group=grp -s2i.registry=quay.io \ No newline at end of file +quarkus.kubernetes.deployment-target=openshift +quarkus.openshift.name=test-it +quarkus.openshift.labels.foo=bar +quarkus.openshift.env-vars.my-env-var.value=SOMEVALUE +quarkus.openshift.group=grp +quarkus.s2i.registry=quay.io diff --git a/integration-tests/kubernetes/standard/src/test/resources/openshift.properties b/integration-tests/kubernetes/standard/src/test/resources/openshift.properties index 8d388b375415c0..f03130f42b7e8d 100644 --- a/integration-tests/kubernetes/standard/src/test/resources/openshift.properties +++ b/integration-tests/kubernetes/standard/src/test/resources/openshift.properties @@ -1 +1 @@ -kubernetes.deployment.target=openshift \ No newline at end of file +quarkus.kubernetes.deployment-target=openshift