Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -549,29 +549,6 @@ for individual ones; the latter having a higher priority.
NOTE: You should check the security configuration section. To access config maps from inside a pod you need to have the correct
Kubernetes service accounts, roles and role bindings.

Another option for using `ConfigMap` instances is to mount them into the Pod by running the Spring Cloud Kubernetes application
and having Spring Cloud Kubernetes read them from the file system.

NOTE: This feature is deprecated and will be removed in a future release (Use `spring.config.import` instead).
This behavior is controlled by the `spring.cloud.kubernetes.config.paths` property. You can use it in
addition to or instead of the mechanism described earlier.
`spring.cloud.kubernetes.config.paths` expects a List of full paths to each property file, because directories are not being recursively parsed. For example:

[source,yaml]
----
spring:
cloud:
kubernetes:
config:
paths:
- /tmp/application.properties
- /var/application.yaml
----

NOTE: If you use `spring.cloud.kubernetes.config.paths` or `spring.cloud.kubernetes.secrets.path` the automatic reload
functionality will not work. You will need to make a `POST` request to the `/actuator/refresh` endpoint or
restart/redeploy the application.

[#config-map-fail-fast]
In some cases, your application may be unable to load some of your `ConfigMaps` using the Kubernetes API.
If you want your application to fail the start-up process in such cases, you can set
Expand All @@ -598,7 +575,6 @@ NOTE: Since version `5.0.0`, we have introduced the possibility to read sources
| `spring.cloud.kubernetes.config.enabled` | `Boolean` | `true` | Enable ConfigMaps `PropertySource`
| `spring.cloud.kubernetes.config.name` | `String` | `${spring.application.name}` | Sets the name of `ConfigMap` to look up
| `spring.cloud.kubernetes.config.namespace` | `String` | Client namespace | Sets the Kubernetes namespace where to lookup
| `spring.cloud.kubernetes.config.paths` | `List` | `null` | Sets the paths where `ConfigMap` instances are mounted
| `spring.cloud.kubernetes.config.enableApi` | `Boolean` | `true` | Enable or disable consuming `ConfigMap` instances through APIs
| `spring.cloud.kubernetes.config.fail-fast` | `Boolean` | `false` | Enable or disable failing the application start-up when an error occurred while loading a `ConfigMap`
| `spring.cloud.kubernetes.config.retry.enabled` | `Boolean` | `true` | Enable or disable config retry.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,20 +77,6 @@ spec:

You can select the Secrets to consume in a number of ways:

. By listing the directories where secrets are mapped:
+
[source,bash]
----
-Dspring.cloud.kubernetes.secrets.paths=/etc/secrets/db-secret,etc/secrets/postgresql
----
+
If you have all the secrets mapped to a common root, you can set them like:
+
[source,bash]
----
-Dspring.cloud.kubernetes.secrets.paths=/etc/secrets
----

. By setting a named secret:
+
[source,bash]
Expand Down Expand Up @@ -165,7 +151,6 @@ This setting is supported since `3.0.6` and upwards.
| `spring.cloud.kubernetes.secrets.name` | `String` | `${spring.application.name}` | Sets the name of the secret to look up
| `spring.cloud.kubernetes.secrets.namespace` | `String` | Client namespace | Sets the Kubernetes namespace where to look up
| `spring.cloud.kubernetes.secrets.labels` | `Map` | `null` | Sets the labels used to lookup secrets
| `spring.cloud.kubernetes.secrets.paths` | `List` | `null` | Sets the paths where secrets are mounted (example 1)
| `spring.cloud.kubernetes.secrets.enableApi` | `Boolean` | `false` | Enables or disables consuming secrets through APIs (examples 2 and 3)
| `spring.cloud.kubernetes.secrets.fail-fast` | `Boolean` | `false` | Enable or disable failing the application start-up when an error occurred while loading a `Secret`
| `spring.cloud.kubernetes.secrets.retry.enabled` | `Boolean` | `true` | Enable or disable secrets retry.
Expand All @@ -179,8 +164,6 @@ Notes:

* The `spring.cloud.kubernetes.secrets.labels` property behaves as defined by
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-Configuration-Binding#map-based-binding[Map-based binding].
* The `spring.cloud.kubernetes.secrets.paths` property behaves as defined by
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-Configuration-Binding#collection-based-binding[Collection-based binding].
* Access to secrets through the API may be restricted for security reasons. The preferred way is to mount secrets to the Pod.

You can find an example of an application that uses secrets (though it has not been updated to use the new `spring-cloud-kubernetes` project) at
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ SPRING_CLOUD_KUBERNETES_CONFIG_INFORMER_ENABLED=TRUE

This will tell watcher to only monitor sources that have a label: `spring.cloud.kubernetes.config.informer.enabled=true`.

One more important configuration, especially for configmaps and secrets that are mounted as volumes (via `spring.cloud.kubernetes.config.paths`/`spring.cloud.kubernetes.secrets.paths` or using `spring.config.import`) is:
One more important configuration, especially for configmaps and secrets that are mounted as volumes (via `spring.config.import`) is:

[source]
----
Expand Down
8 changes: 3 additions & 5 deletions docs/modules/ROOT/partials/_configprops.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,7 @@
|spring.cloud.kubernetes.config.labels | |
|spring.cloud.kubernetes.config.name | |
|spring.cloud.kubernetes.config.namespace | |
|spring.cloud.kubernetes.config.paths | |
|spring.cloud.kubernetes.config.retry | |
|spring.cloud.kubernetes.config.retry | |
|spring.cloud.kubernetes.config.sources | |
|spring.cloud.kubernetes.config.use-name-as-prefix | `+++false+++` |
|spring.cloud.kubernetes.discovery.all-namespaces | `+++false+++` | if discovery is enabled for all namespaces
Expand Down Expand Up @@ -108,9 +107,8 @@
|spring.cloud.kubernetes.secrets.labels | |
|spring.cloud.kubernetes.secrets.name | |
|spring.cloud.kubernetes.secrets.namespace | |
|spring.cloud.kubernetes.secrets.paths | |
|spring.cloud.kubernetes.secrets.retry | |
|spring.cloud.kubernetes.secrets.retry | |
|spring.cloud.kubernetes.secrets.sources | |
|spring.cloud.kubernetes.secrets.use-name-as-prefix | `+++false+++` |

|===
|===
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ void namedSingleConfigMapFails(CapturedOutput output) {

stubFor(get(path).willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));

ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties(true, List.of(), List.of(),
Map.of(), true, name, namespace, false, true, false, RetryProperties.DEFAULT, ReadType.BATCH);
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties(true, List.of(), Map.of(),
true, name, namespace, false, true, false, RetryProperties.DEFAULT, ReadType.BATCH);

CoreV1Api api = new CoreV1Api();
KubernetesClientConfigMapPropertySourceLocator locator = new KubernetesClientConfigMapPropertySourceLocator(api,
Expand Down Expand Up @@ -142,7 +142,7 @@ void namedTwoConfigMapsOneFails(CapturedOutput output) {
.inScenario("started")
.willSetStateTo("go-to-next"));

stubFor(get(path).willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(SINGLE_CONFIGMAP_LIST)))
stubFor(get(path).willReturn(aResponse().withStatus(200).withBody(JSON.serialize(SINGLE_CONFIGMAP_LIST)))
.inScenario("started")
.whenScenarioStateIs("go-to-next")
.willSetStateTo("done"));
Expand All @@ -152,7 +152,7 @@ void namedTwoConfigMapsOneFails(CapturedOutput output) {
ConfigMapConfigProperties.Source sourceTwo = new ConfigMapConfigProperties.Source(configMapNameTwo, namespace,
Map.of(), null, null, null);

ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties(true, List.of(),
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties(true,
List.of(sourceOne, sourceTwo), Map.of(), true, null, namespace, false, true, false,
RetryProperties.DEFAULT, ReadType.BATCH);

Expand Down Expand Up @@ -199,7 +199,7 @@ void namedTwoConfigMapsBothFail(CapturedOutput output) {
ConfigMapConfigProperties.Source sourceTwo = new ConfigMapConfigProperties.Source(configMapNameTwo, namespace,
Map.of(), null, null, null);

ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties(true, List.of(),
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties(true,
List.of(sourceOne, sourceTwo), Map.of(), true, null, namespace, false, true, false,
RetryProperties.DEFAULT, ReadType.BATCH);

Expand Down Expand Up @@ -243,7 +243,7 @@ void labeledSingleConfigMapFails(CapturedOutput output) {
ConfigMapConfigProperties.Source configMapSource = new ConfigMapConfigProperties.Source(null, namespace, labels,
null, null, null);

ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties(true, List.of(),
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties(true,
List.of(configMapSource), labels, true, null, namespace, false, true, false, RetryProperties.DEFAULT,
ReadType.BATCH);

Expand Down Expand Up @@ -285,7 +285,7 @@ void labeledTwoConfigMapsOneFails(CapturedOutput output) {
.willSetStateTo("second"));

// one that passes
stubFor(get(path).willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(DOUBLE_CONFIGMAP_LIST)))
stubFor(get(path).willReturn(aResponse().withStatus(200).withBody(JSON.serialize(DOUBLE_CONFIGMAP_LIST)))
.inScenario("started")
.whenScenarioStateIs("second")
.willSetStateTo("done"));
Expand All @@ -295,7 +295,7 @@ void labeledTwoConfigMapsOneFails(CapturedOutput output) {
ConfigMapConfigProperties.Source sourceTwo = new ConfigMapConfigProperties.Source(null, namespace,
configMapTwoLabels, null, null, null);

ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties(true, List.of(),
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties(true,
List.of(sourceOne, sourceTwo), Map.of("one", "1", "two", "2"), true, null, namespace, false, true,
false, RetryProperties.DEFAULT, ReadType.BATCH);

Expand Down Expand Up @@ -349,7 +349,7 @@ void labeledTwoConfigMapsBothFail(CapturedOutput output) {
ConfigMapConfigProperties.Source sourceTwo = new ConfigMapConfigProperties.Source(null, namespace,
configMapTwoLabels, null, null, null);

ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties(true, List.of(),
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties(true,
List.of(sourceOne, sourceTwo), Map.of("one", "1", "two", "2"), true, null, namespace, false, true,
false, RetryProperties.DEFAULT, ReadType.BATCH);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@ void locateWithoutSources() {
CoreV1Api api = new CoreV1Api();
stubFor(get("/api/v1/namespaces/default/configmaps")
.willReturn(aResponse().withStatus(200).withBody(JSON.serialize(PROPERTIES_CONFIGMAP_LIST))));
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties(true, List.of(), List.of(),
Map.of(), true, "bootstrap-640", null, false, false, false, RetryProperties.DEFAULT, ReadType.BATCH);
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties(true, List.of(), Map.of(),
true, "bootstrap-640", null, false, false, false, RetryProperties.DEFAULT, ReadType.BATCH);
MockEnvironment mockEnvironment = new MockEnvironment();
mockEnvironment.setProperty("spring.cloud.kubernetes.client.namespace", "default");
PropertySource<?> propertySource = new KubernetesClientConfigMapPropertySourceLocator(api,
Expand All @@ -125,9 +125,8 @@ void locateWithSources() {

ConfigMapConfigProperties.Source source = new ConfigMapConfigProperties.Source("bootstrap-640", "default",
Collections.emptyMap(), null, null, null);
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties(true, List.of(),
List.of(source), Map.of(), true, "fake-name", null, false, false, false, RetryProperties.DEFAULT,
ReadType.BATCH);
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties(true, List.of(source),
Map.of(), true, "fake-name", null, false, false, false, RetryProperties.DEFAULT, ReadType.BATCH);

PropertySource<?> propertySource = new KubernetesClientConfigMapPropertySourceLocator(api,
configMapConfigProperties, new KubernetesNamespaceProvider(new MockEnvironment()))
Expand All @@ -149,8 +148,8 @@ void testLocateWithoutNamespaceConstructor() {
stubFor(get("/api/v1/namespaces/default/configmaps")
.willReturn(aResponse().withStatus(200).withBody(JSON.serialize(PROPERTIES_CONFIGMAP_LIST))));

ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties(true, List.of(), List.of(),
Map.of(), true, "bootstrap-640", null, false, false, false, RetryProperties.DEFAULT, ReadType.BATCH);
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties(true, List.of(), Map.of(),
true, "bootstrap-640", null, false, false, false, RetryProperties.DEFAULT, ReadType.BATCH);

assertThatThrownBy(() -> new KubernetesClientConfigMapPropertySourceLocator(api, configMapConfigProperties,
new KubernetesNamespaceProvider(new MockEnvironment()))
Expand All @@ -169,8 +168,8 @@ void testLocateWithoutNamespace() {
CoreV1Api api = new CoreV1Api();
stubFor(get("/api/v1/namespaces/default/configmaps")
.willReturn(aResponse().withStatus(200).withBody(JSON.serialize(PROPERTIES_CONFIGMAP_LIST))));
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties(true, List.of(), List.of(),
Map.of(), true, "bootstrap-640", null, false, false, false, RetryProperties.DEFAULT, ReadType.BATCH);
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties(true, List.of(), Map.of(),
true, "bootstrap-640", null, false, false, false, RetryProperties.DEFAULT, ReadType.BATCH);
assertThatThrownBy(() -> new KubernetesClientConfigMapPropertySourceLocator(api, configMapConfigProperties,
new KubernetesNamespaceProvider(ENV))
.locate(ENV)).isInstanceOf(NamespaceResolutionFailedException.class);
Expand All @@ -182,9 +181,8 @@ public void locateShouldThrowExceptionOnFailureWhenFailFastIsEnabled() {
stubFor(get("/api/v1/namespaces/default/configmaps")
.willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));

ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties(true, List.of(), List.of(),
Map.of(), true, "bootstrap-640", "default", false, false, true, RetryProperties.DEFAULT,
ReadType.BATCH);
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties(true, List.of(), Map.of(),
true, "bootstrap-640", "default", false, false, true, RetryProperties.DEFAULT, ReadType.BATCH);

KubernetesClientConfigMapPropertySourceLocator locator = new KubernetesClientConfigMapPropertySourceLocator(api,
configMapConfigProperties, new KubernetesNamespaceProvider(new MockEnvironment()));
Expand All @@ -199,9 +197,8 @@ public void locateShouldNotThrowExceptionOnFailureWhenFailFastIsDisabled(Capture
stubFor(get("/api/v1/namespaces/default/configmaps")
.willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));

ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties(true, List.of(), List.of(),
Map.of(), true, "bootstrap-640", "default", false, false, false, RetryProperties.DEFAULT,
ReadType.BATCH);
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties(true, List.of(), Map.of(),
true, "bootstrap-640", "default", false, false, false, RetryProperties.DEFAULT, ReadType.BATCH);

KubernetesClientConfigMapPropertySourceLocator locator = new KubernetesClientConfigMapPropertySourceLocator(api,
configMapConfigProperties, new KubernetesNamespaceProvider(new MockEnvironment()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ void getLocateWithSources() {
SecretsConfigProperties.Source source2 = new SecretsConfigProperties.Source("rabbit-password", "",
Collections.emptyMap(), null, null, null);

SecretsConfigProperties secretsConfigProperties = new SecretsConfigProperties(true, Map.of(), List.of(),
SecretsConfigProperties secretsConfigProperties = new SecretsConfigProperties(true, Map.of(),
List.of(source1, source2), true, "app", "default", false, true, false, RetryProperties.DEFAULT,
ReadType.BATCH);

Expand All @@ -162,8 +162,8 @@ void getLocateWithSources() {
void getLocateWithOutSources() {
CoreV1Api api = new CoreV1Api();
stubFor(get(LIST_API).willReturn(aResponse().withStatus(200).withBody(LIST_BODY)));
SecretsConfigProperties secretsConfigProperties = new SecretsConfigProperties(true, Map.of(), List.of(),
List.of(), true, "db-secret", "default", false, true, false, RetryProperties.DEFAULT, ReadType.BATCH);
SecretsConfigProperties secretsConfigProperties = new SecretsConfigProperties(true, Map.of(), List.of(), true,
"db-secret", "default", false, true, false, RetryProperties.DEFAULT, ReadType.BATCH);

PropertySource<?> propertySource = new KubernetesClientSecretsPropertySourceLocator(api,
new KubernetesNamespaceProvider(new MockEnvironment()), secretsConfigProperties)
Expand All @@ -184,8 +184,8 @@ void testLocateWithoutNamespaceConstructor() {
CoreV1Api api = new CoreV1Api();
stubFor(get(LIST_API).willReturn(aResponse().withStatus(200).withBody(LIST_BODY)));

SecretsConfigProperties secretsConfigProperties = new SecretsConfigProperties(true, Map.of(), List.of(),
List.of(), true, "db-secret", "", false, true, false, RetryProperties.DEFAULT, ReadType.BATCH);
SecretsConfigProperties secretsConfigProperties = new SecretsConfigProperties(true, Map.of(), List.of(), true,
"db-secret", "", false, true, false, RetryProperties.DEFAULT, ReadType.BATCH);

assertThatThrownBy(() -> new KubernetesClientSecretsPropertySourceLocator(api,
new KubernetesNamespaceProvider(new MockEnvironment()), secretsConfigProperties)
Expand All @@ -197,8 +197,8 @@ void locateShouldThrowExceptionOnFailureWhenFailFastIsEnabled() {
CoreV1Api api = new CoreV1Api();
stubFor(get(LIST_API).willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));

SecretsConfigProperties secretsConfigProperties = new SecretsConfigProperties(true, Map.of(), List.of(),
List.of(), true, "db-secret", "default", false, true, true, RetryProperties.DEFAULT, ReadType.BATCH);
SecretsConfigProperties secretsConfigProperties = new SecretsConfigProperties(true, Map.of(), List.of(), true,
"db-secret", "default", false, true, true, RetryProperties.DEFAULT, ReadType.BATCH);

KubernetesClientSecretsPropertySourceLocator locator = new KubernetesClientSecretsPropertySourceLocator(api,
new KubernetesNamespaceProvider(new MockEnvironment()), secretsConfigProperties);
Expand All @@ -212,8 +212,8 @@ void locateShouldNotThrowExceptionOnFailureWhenFailFastIsDisabled(CapturedOutput
CoreV1Api api = new CoreV1Api();
stubFor(get(LIST_API).willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));

SecretsConfigProperties secretsConfigProperties = new SecretsConfigProperties(true, Map.of(), List.of(),
List.of(), true, "db-secret", "default", false, true, false, RetryProperties.DEFAULT, ReadType.BATCH);
SecretsConfigProperties secretsConfigProperties = new SecretsConfigProperties(true, Map.of(), List.of(), true,
"db-secret", "default", false, true, false, RetryProperties.DEFAULT, ReadType.BATCH);

KubernetesClientSecretsPropertySourceLocator locator = new KubernetesClientSecretsPropertySourceLocator(api,
new KubernetesNamespaceProvider(new MockEnvironment()), secretsConfigProperties);
Expand Down
Loading
Loading