Skip to content

Commit

Permalink
feat: support extracting var from key from secret/configmap
Browse files Browse the repository at this point in the history
  • Loading branch information
metacosm authored and johnaohara committed Jun 29, 2020
1 parent 57907cf commit 352dd72
Show file tree
Hide file tree
Showing 21 changed files with 679 additions and 252 deletions.
120 changes: 96 additions & 24 deletions docs/src/main/asciidoc/deploying-to-kubernetes.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ NOTE: When using the `quarkus-container-image-jib` extension to build a containe

Out of the box, the generated resources will be annotated with version control related information that can be used either by tooling, or by the user for troubleshooting purposes.

[source, json]
[source,json]
----
"annotations": {
"app.quarkus.io/vcs-url" : "<some url>",
Expand All @@ -224,29 +224,29 @@ Out of the box, the generated resources will be annotated with version control r

==== Custom Annotations

Custom annotations can be added in a way similar to labels. For example to add the annotation `foo=bar` and `app.quarkus/id=42` just apply the following configuration:

Custom annotations can be added in a way similar to labels.For example to add the annotation `foo=bar` and `app.quarkus/id=42` just apply the following configuration:

[source]
----
quarkus.kubernetes.annotations.foo=bar
quarkus."app.quarkus/id"=42
----

[#env-vars]
==== Environment variables

Kubernetes provides multiple ways of defining environment variables:

- key/value pairs
- from a Secret
- from a ConfigMap
- from fields
- import all values from a Secret or ConfigMap
- interpolate a single value identified by a given field in a Secret or ConfigMap
- interpolate a value from a field within the same resource

===== Environment variables from key/value pairs

To add a key/value pair as an environment variable in the generated resources:

[source]
[source,properties]
----
quarkus.kubernetes.env.vars.my-env-var=foobar
----
Expand All @@ -259,25 +259,93 @@ Please note that the key `my-env-var` will be converted to uppercase and dashes
To add all key/value pairs of `Secret` as environment variables just apply the following configuration, separating each `Secret`
to be used as source by a comma (`,`):

[source]
[source,properties]
----
quarkus.kubernetes.env.secrets=my-secret,my-other-secret
----

which would generate the following in the container definition:

[source,yaml]
----
envFrom:
- secretRef:
name: my-secret
optional: false
- secretRef:
name: my-other-secret
optional: false
----

The following extracts a value identified by the `keyName` field from the `my-secret` Secret into a `foo` environment variable:

[source,properties]
----
quarkus.kubernetes.env.mapping.foo.from-secret=my-secret
quarkus.kubernetes.env.mapping.foo.with-key=keyName
----

This would generate the following in the `env` section of your container:

[source,yaml]
----
- env:
- name: FOO
valueFrom:
secretKeyRef:
key: keyName
name: my-secret
optional: false
----

===== Environment variables from ConfigMap

To add all key/value pairs from `ConfigMap` as environment variables just apply the following configuration, separating each
`ConfigMap` to be used as source by a comma (`,`):

[source]
[source,properties]
----
quarkus.kubernetes.env.configmaps=my-config-map,another-config-map
----

which would generate the following in the container definition:

[source,yaml]
----
envFrom:
- configMapRef:
name: my-config-map
optional: false
- configMapRef:
name: another-config-map
optional: false
----

The following extracts a value identified by the `keyName` field from the `my-config-map` ConfigMap into a `foo`
environment variable:

[source,properties]
----
quarkus.kubernetes.env.mapping.foo.from-configmap=my-configmap
quarkus.kubernetes.env.mapping.foo.with-key=keyName
----

This would generate the following in the `env` section of your container:

[source,yaml]
----
- env:
- name: FOO
valueFrom:
configMapRefKey:
key: keyName
name: my-configmap
optional: false
----

===== Environment variables from fields

It's also possible to use the value from another field to add a new environment variable by specifying the path of the field to
be used as a source, as follows:
It's also possible to use the value from another field to add a new environment variable by specifying the path of the field to be used as a source, as follows:

[source]
----
Expand All @@ -286,29 +354,30 @@ quarkus.kubernetes.env.fields.foo=metadata.name

===== Validation

A conflict between two definitions, e.g. mistakenly assigning both a value and specifying that a variable is derived
from a field, will result in an error being thrown at build time so that you get the opportunity to fix the issue before you
deploy your application to your cluster where it might be more difficult to diagnose the source of the issue.
A conflict between two definitions, e.g. mistakenly assigning both a value and specifying that a variable is derived from a field, will result in an error being thrown at build time so that you get the opportunity to fix the issue before you deploy your application to your cluster where it might be more difficult to diagnose the source of the issue.

Similarly, two redundant definitions, e.g. defining an injection from the same secret twice, will not cause an issue but will
indeed report a warning to let you know that you might not have intended to duplicate that definition.
Similarly, two redundant definitions, e.g. defining an injection from the same secret twice, will not cause an issue but will indeed report a warning to let you know that you might not have intended to duplicate that definition.

[#env-vars-backwards]
===== Backwards compatibility

Previous versions of the Kubernetes extension supported a different syntax to add environment variables. The older syntax is
still supported but is deprecated and it's advised that you migrate to the new syntax.
Previous versions of the Kubernetes extension supported a different syntax to add environment variables.The older syntax is still supported but is deprecated and it's advised that you migrate to the new syntax.

.Old vs. new syntax
|====
| |Old | New |
| Plain variable |`quarkus.kubernetes.env-vars.my-env-var.value=foobar` | `quarkus.kubernetes.env.vars.my-env-var=foobar` |
| From field |`quarkus.kubernetes.env-vars.my-env-var.field=foobar` | `quarkus.kubernetes.env.fields.my-env-var=foobar` |
| All from `ConfigMap` |`quarkus.kubernetes.env-vars.xxx.configmap=foobar` | `quarkus.kubernetes.env.configmaps=foobar` |
| All from `Secret` |`quarkus.kubernetes.env-vars.xxx.secret=foobar` | `quarkus.kubernetes.env.secrets=foobar` |
| |Old | New |
| Plain variable |`quarkus.kubernetes.env-vars.my-env-var.value=foobar` | `quarkus.kubernetes.env.vars.my-env-var=foobar` |
| From field |`quarkus.kubernetes.env-vars.my-env-var.field=foobar` | `quarkus.kubernetes.env.fields.my-env-var=foobar` |
| All from `ConfigMap` |`quarkus.kubernetes.env-vars.xxx.configmap=foobar` | `quarkus.kubernetes.env.configmaps=foobar` |
| All from `Secret` |`quarkus.kubernetes.env-vars.xxx.secret=foobar` | `quarkus.kubernetes.env.secrets=foobar` |
| From one `Secret` field |`quarkus.kubernetes.env-vars.foo.secret=foobar` | `quarkus.kubernetes.env.mapping.foo.from-secret=foobar` |
| |`quarkus.kubernetes.env-vars.foo.value=field` | `quarkus.kubernetes.env.mapping.foo.with-key=field` |
| From one `ConfigMap` field |`quarkus.kubernetes.env-vars.foo.configmap=foobar` | `quarkus.kubernetes.env.mapping.foo.from-configmap=foobar` |
| |`quarkus.kubernetes.env-vars.foo.value=field` | `quarkus.kubernetes.env.mapping.foo.with-key=field` |
|====

NOTE: If you redefine the same variable using the new syntax while keeping the old syntax, **ONLY** the new version will be kept
and a warning will be issued to alert you of the problem. For example, if you define both
and a warning will be issued to alert you of the problem.For example, if you define both
`quarkus.kubernetes.env-vars.my-env-var.value=foobar` and `quarkus.kubernetes.env.vars.my-env-var=newValue`, the extension will
only generate an environment variable `MY_ENV_VAR=newValue` and issue a warning.

Expand Down Expand Up @@ -829,7 +898,10 @@ kubernetes.env-vars[0].configmap=my-configmap
quarkus.kubernetes.env-vars.foo.configmap=myconfigmap
----

==== `env-vars` properties

`quarkus.kubernetes.env-vars` are deprecated (though still currently supported as of this writing) and the new declaration style should be used instead.
See <<#env-vars>> and more specifically <<env-vars-backwards>> for more details.

== Deployment

Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,10 @@
package io.quarkus.container.image.s2i.deployment;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
Expand Down Expand Up @@ -55,11 +44,7 @@
import io.quarkus.deployment.builditem.CapabilityBuildItem;
import io.quarkus.deployment.builditem.GeneratedFileSystemResourceBuildItem;
import io.quarkus.deployment.pkg.PackageConfig;
import io.quarkus.deployment.pkg.builditem.ArtifactResultBuildItem;
import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem;
import io.quarkus.deployment.pkg.builditem.JarBuildItem;
import io.quarkus.deployment.pkg.builditem.NativeImageBuildItem;
import io.quarkus.deployment.pkg.builditem.OutputTargetBuildItem;
import io.quarkus.deployment.pkg.builditem.*;
import io.quarkus.deployment.pkg.steps.NativeBuild;
import io.quarkus.kubernetes.client.deployment.KubernetesClientErrorHanlder;
import io.quarkus.kubernetes.client.spi.KubernetesClientBuildItem;
Expand Down Expand Up @@ -108,11 +93,11 @@ public void s2iRequirementsJvm(S2iConfig s2iConfig,
builderImageProducer.produce(new BaseImageInfoBuildItem(s2iConfig.baseJvmImage));
Optional<S2iBaseJavaImage> baseImage = S2iBaseJavaImage.findMatching(s2iConfig.baseJvmImage);
baseImage.ifPresent(b -> {
envProducer.produce(new KubernetesEnvBuildItem(b.getJarEnvVar(), pathToJar, OPENSHIFT));
envProducer.produce(new KubernetesEnvBuildItem(b.getJarLibEnvVar(),
envProducer.produce(KubernetesEnvBuildItem.createSimpleVar(b.getJarEnvVar(), pathToJar, OPENSHIFT));
envProducer.produce(KubernetesEnvBuildItem.createSimpleVar(b.getJarLibEnvVar(),
concatUnixPaths(jarDirectory, "lib"), OPENSHIFT));
envProducer.produce(new KubernetesEnvBuildItem(b.getClasspathEnvVar(), classpath, OPENSHIFT));
envProducer.produce(new KubernetesEnvBuildItem(b.getJvmOptionsEnvVar(),
envProducer.produce(KubernetesEnvBuildItem.createSimpleVar(b.getClasspathEnvVar(), classpath, OPENSHIFT));
envProducer.produce(KubernetesEnvBuildItem.createSimpleVar(b.getJvmOptionsEnvVar(),
String.join(" ", s2iConfig.jvmArguments), OPENSHIFT));
});

Expand Down Expand Up @@ -150,9 +135,11 @@ public void s2iRequirementsNative(S2iConfig s2iConfig,
builderImageProducer.produce(new BaseImageInfoBuildItem(s2iConfig.baseNativeImage));
Optional<S2iBaseNativeImage> baseImage = S2iBaseNativeImage.findMatching(s2iConfig.baseNativeImage);
baseImage.ifPresent(b -> {
envProducer.produce(new KubernetesEnvBuildItem(b.getHomeDirEnvVar(), s2iConfig.nativeBinaryDirectory, OPENSHIFT));
envProducer.produce(new KubernetesEnvBuildItem(b.getOptsEnvVar(),
String.join(" ", s2iConfig.nativeArguments), OPENSHIFT));
envProducer.produce(
KubernetesEnvBuildItem.createSimpleVar(b.getHomeDirEnvVar(), s2iConfig.nativeBinaryDirectory, OPENSHIFT));
envProducer.produce(
KubernetesEnvBuildItem.createSimpleVar(b.getOptsEnvVar(), String.join(" ", s2iConfig.nativeArguments),
OPENSHIFT));
});

if (!baseImage.isPresent()) {
Expand Down
Loading

0 comments on commit 352dd72

Please sign in to comment.