Merge branch '2.1.x'
This commit is contained in:
@@ -867,6 +867,11 @@ such a method. This, in turn, could be configured via environment properties. Fo
|
||||
|
||||
Failure to find a namespace from the above steps will result in an Exception being raised.
|
||||
|
||||
[[order_of_configMaps_and_secrets]]
|
||||
=== Order of ConfigMaps and Secrets
|
||||
|
||||
If, for whatever reason, you enabled both configmaps and secrets, and there is a common property between them, the value from the ConfigMap will have a higher precedence. That is: it will override whatever values are found in secrets.
|
||||
|
||||
=== `PropertySource` Reload
|
||||
|
||||
WARNING: This functionality has been deprecated in the 2020.0 release. Please see
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider;
|
||||
import org.springframework.cloud.kubernetes.commons.config.ConfigMapConfigProperties;
|
||||
import org.springframework.cloud.kubernetes.commons.config.ConfigMapPropertySourceLocator;
|
||||
import org.springframework.cloud.kubernetes.commons.config.NormalizedSource;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.MapPropertySource;
|
||||
|
||||
@@ -31,6 +32,7 @@ import static org.springframework.cloud.kubernetes.client.KubernetesClientUtils.
|
||||
* @author Ryan Baxter
|
||||
* @author Isik Erhan
|
||||
*/
|
||||
@Order(0)
|
||||
public class KubernetesClientConfigMapPropertySourceLocator extends ConfigMapPropertySourceLocator {
|
||||
|
||||
private final CoreV1Api coreV1Api;
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.springframework.cloud.kubernetes.commons.config.NormalizedSource;
|
||||
import org.springframework.cloud.kubernetes.commons.config.SecretsConfigProperties;
|
||||
import org.springframework.cloud.kubernetes.commons.config.SecretsPropertySource;
|
||||
import org.springframework.cloud.kubernetes.commons.config.SecretsPropertySourceLocator;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
|
||||
import static org.springframework.cloud.kubernetes.client.KubernetesClientUtils.getApplicationNamespace;
|
||||
@@ -31,6 +32,7 @@ import static org.springframework.cloud.kubernetes.client.KubernetesClientUtils.
|
||||
* @author Ryan Baxter
|
||||
* @author Isik Erhan
|
||||
*/
|
||||
@Order(1)
|
||||
public class KubernetesClientSecretsPropertySourceLocator extends SecretsPropertySourceLocator {
|
||||
|
||||
private final CoreV1Api coreV1Api;
|
||||
|
||||
@@ -22,6 +22,7 @@ import io.kubernetes.client.openapi.apis.CoreV1Api;
|
||||
|
||||
import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider;
|
||||
import org.springframework.cloud.kubernetes.commons.config.ConfigMapConfigProperties;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.retry.annotation.Retryable;
|
||||
@@ -31,8 +32,8 @@ import org.springframework.retry.annotation.Retryable;
|
||||
*
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
public class RetryableKubernetesClientConfigMapPropertySourceLocator
|
||||
extends KubernetesClientConfigMapPropertySourceLocator {
|
||||
@Order(0)
|
||||
class RetryableKubernetesClientConfigMapPropertySourceLocator extends KubernetesClientConfigMapPropertySourceLocator {
|
||||
|
||||
RetryableKubernetesClientConfigMapPropertySourceLocator(CoreV1Api coreV1Api, ConfigMapConfigProperties properties,
|
||||
KubernetesNamespaceProvider kubernetesNamespaceProvider) {
|
||||
|
||||
@@ -22,6 +22,7 @@ import io.kubernetes.client.openapi.apis.CoreV1Api;
|
||||
|
||||
import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider;
|
||||
import org.springframework.cloud.kubernetes.commons.config.SecretsConfigProperties;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.retry.annotation.Retryable;
|
||||
@@ -31,8 +32,8 @@ import org.springframework.retry.annotation.Retryable;
|
||||
*
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
public class RetryableKubernetesClientSecretsPropertySourceLocator
|
||||
extends KubernetesClientSecretsPropertySourceLocator {
|
||||
@Order(1)
|
||||
class RetryableKubernetesClientSecretsPropertySourceLocator extends KubernetesClientSecretsPropertySourceLocator {
|
||||
|
||||
RetryableKubernetesClientSecretsPropertySourceLocator(CoreV1Api coreV1Api,
|
||||
KubernetesNamespaceProvider kubernetesNamespaceProvider, SecretsConfigProperties secretsConfigProperties) {
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.kubernetes.client.config;
|
||||
|
||||
import com.github.tomakehurst.wiremock.client.WireMock;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.kubernetes.client.config.applications.sources_order.SourcesOrderApp;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
|
||||
/**
|
||||
* The stub data for this test is in :
|
||||
* {@link org.springframework.cloud.kubernetes.client.config.boostrap.stubs.SourcesOrderConfigurationStub}
|
||||
*
|
||||
* @author wind57
|
||||
*/
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = SourcesOrderApp.class,
|
||||
properties = { "spring.cloud.bootstrap.name=sources-order", "sources.order.stub=true" })
|
||||
@AutoConfigureWebTestClient
|
||||
class KubernetesClientSourcesOrderTests {
|
||||
|
||||
@Autowired
|
||||
private WebTestClient webClient;
|
||||
|
||||
@AfterEach
|
||||
void afterEach() {
|
||||
WireMock.reset();
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
static void afterAll() {
|
||||
WireMock.shutdownServer();
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 1. There is one secret deployed: my-secret. It has two properties: {my.one=one, my.key=from-secret}
|
||||
* 2. There is one configmap deployed: my-configmap. It has two properties: {my.two=two, my.key=from-configmap}
|
||||
*
|
||||
* We invoke three endpoints: /one, /two, /key.
|
||||
* The first two prove that both the secret and configmap have been read, the last one proves that
|
||||
* config maps have a higher precedence.
|
||||
* </pre>
|
||||
*/
|
||||
@Test
|
||||
void test() {
|
||||
this.webClient.get().uri("/one").exchange().expectStatus().isOk().expectBody(String.class)
|
||||
.value(Matchers.equalTo("one"));
|
||||
this.webClient.get().uri("/two").exchange().expectStatus().isOk().expectBody(String.class)
|
||||
.value(Matchers.equalTo("two"));
|
||||
|
||||
this.webClient.get().uri("/key").exchange().expectStatus().isOk().expectBody(String.class)
|
||||
.value(Matchers.equalTo("from-configmap"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.kubernetes.client.config;
|
||||
|
||||
import com.github.tomakehurst.wiremock.client.WireMock;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.kubernetes.client.config.applications.sources_order.SourcesOrderApp;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
|
||||
/**
|
||||
* The stub data for this test is in :
|
||||
* {@link org.springframework.cloud.kubernetes.client.config.boostrap.stubs.SourcesOrderConfigurationStub}
|
||||
*
|
||||
* @author wind57
|
||||
*/
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = SourcesOrderApp.class,
|
||||
properties = { "spring.cloud.bootstrap.name=retryable-sources-order", "sources.order.stub=true" })
|
||||
@AutoConfigureWebTestClient
|
||||
class RetryableKubernetesClientSourcesOrderTests {
|
||||
|
||||
@Autowired
|
||||
private WebTestClient webClient;
|
||||
|
||||
@AfterEach
|
||||
void afterEach() {
|
||||
WireMock.reset();
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
static void afterAll() {
|
||||
WireMock.shutdownServer();
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 1. There is one secret deployed: my-secret. It has two properties: {my.one=one, my.key=from-secret}
|
||||
* 2. There is one configmap deployed: my-configmap. It has two properties: {my.two=two, my.key=from-configmap}
|
||||
*
|
||||
* We invoke three endpoints: /one, /two, /key.
|
||||
* The first two prove that both the secret and configmap have been read, the last one proves that
|
||||
* config maps have a higher precedence.
|
||||
* </pre>
|
||||
*/
|
||||
@Test
|
||||
void test() {
|
||||
this.webClient.get().uri("/one").exchange().expectStatus().isOk().expectBody(String.class)
|
||||
.value(Matchers.equalTo("one"));
|
||||
this.webClient.get().uri("/two").exchange().expectStatus().isOk().expectBody(String.class)
|
||||
.value(Matchers.equalTo("two"));
|
||||
|
||||
this.webClient.get().uri("/key").exchange().expectStatus().isOk().expectBody(String.class)
|
||||
.value(Matchers.equalTo("from-configmap"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.kubernetes.client.config.applications.sources_order;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.kubernetes.client.config.applications.sources_order.properties.Properties;
|
||||
|
||||
/**
|
||||
* @author wind57
|
||||
*/
|
||||
@SpringBootApplication
|
||||
@EnableConfigurationProperties(Properties.class)
|
||||
public class SourcesOrderApp {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SourcesOrderApp.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.kubernetes.client.config.applications.sources_order.controller;
|
||||
|
||||
import org.springframework.cloud.kubernetes.client.config.applications.sources_order.properties.Properties;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @author wind57
|
||||
*/
|
||||
@RestController
|
||||
public class SourcesOrderController {
|
||||
|
||||
private final Properties properties;
|
||||
|
||||
SourcesOrderController(Properties properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
@GetMapping("/key")
|
||||
String key() {
|
||||
return properties.getKey();
|
||||
}
|
||||
|
||||
@GetMapping("/one")
|
||||
String one() {
|
||||
return properties.getOne();
|
||||
}
|
||||
|
||||
@GetMapping("/two")
|
||||
String two() {
|
||||
return properties.getTwo();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.kubernetes.client.config.applications.sources_order.properties;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* @author wind57
|
||||
*/
|
||||
@ConfigurationProperties("my")
|
||||
public class Properties {
|
||||
|
||||
private String key;
|
||||
|
||||
private String one;
|
||||
|
||||
private String two;
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public String getOne() {
|
||||
return one;
|
||||
}
|
||||
|
||||
public void setOne(String one) {
|
||||
this.one = one;
|
||||
}
|
||||
|
||||
public String getTwo() {
|
||||
return two;
|
||||
}
|
||||
|
||||
public void setTwo(String two) {
|
||||
this.two = two;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.kubernetes.client.config.boostrap.stubs;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.github.tomakehurst.wiremock.WireMockServer;
|
||||
import com.github.tomakehurst.wiremock.client.WireMock;
|
||||
import io.kubernetes.client.openapi.ApiClient;
|
||||
import io.kubernetes.client.openapi.JSON;
|
||||
import io.kubernetes.client.openapi.models.V1ConfigMap;
|
||||
import io.kubernetes.client.openapi.models.V1ConfigMapBuilder;
|
||||
import io.kubernetes.client.openapi.models.V1ConfigMapList;
|
||||
import io.kubernetes.client.openapi.models.V1ObjectMetaBuilder;
|
||||
import io.kubernetes.client.openapi.models.V1Secret;
|
||||
import io.kubernetes.client.openapi.models.V1SecretBuilder;
|
||||
import io.kubernetes.client.openapi.models.V1SecretList;
|
||||
import io.kubernetes.client.util.ClientBuilder;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.annotation.Order;
|
||||
|
||||
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
|
||||
|
||||
@Order(0)
|
||||
@Configuration
|
||||
@ConditionalOnProperty("sources.order.stub")
|
||||
public class SourcesOrderConfigurationStub {
|
||||
|
||||
@Bean
|
||||
public WireMockServer wireMock() {
|
||||
WireMockServer server = new WireMockServer(options().dynamicPort());
|
||||
server.start();
|
||||
WireMock.configureFor("localhost", server.port());
|
||||
return server;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ApiClient apiClient(WireMockServer wireMockServer) {
|
||||
ApiClient apiClient = new ClientBuilder().setBasePath("http://localhost:" + wireMockServer.port()).build();
|
||||
io.kubernetes.client.openapi.Configuration.setDefaultApiClient(apiClient);
|
||||
apiClient.setDebugging(true);
|
||||
stubConfigMapData();
|
||||
stubSecretsData();
|
||||
return apiClient;
|
||||
}
|
||||
|
||||
private void stubConfigMapData() {
|
||||
|
||||
Map<String, String> configMapData = new HashMap<>();
|
||||
configMapData.put("my.key", "from-configmap");
|
||||
configMapData.put("my.two", "two");
|
||||
|
||||
V1ConfigMap myConfigMap = new V1ConfigMapBuilder().withMetadata(new V1ObjectMetaBuilder()
|
||||
.withName("my-configmap").withNamespace("spring-k8s").withResourceVersion("1").build())
|
||||
.addToData(configMapData).build();
|
||||
|
||||
V1ConfigMapList allConfigMaps = new V1ConfigMapList();
|
||||
allConfigMaps.setItems(Collections.singletonList(myConfigMap));
|
||||
|
||||
// the actual stub for CoreV1Api calls
|
||||
WireMock.stubFor(WireMock.get("/api/v1/namespaces/spring-k8s/configmaps")
|
||||
.willReturn(WireMock.aResponse().withStatus(200).withBody(new JSON().serialize(allConfigMaps))));
|
||||
}
|
||||
|
||||
private void stubSecretsData() {
|
||||
|
||||
Map<String, byte[]> secretData = new HashMap<>();
|
||||
secretData.put("my.key", "from-secret".getBytes(StandardCharsets.UTF_8));
|
||||
secretData.put("my.one", "one".getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
V1Secret mySecret = new V1SecretBuilder().withMetadata(new V1ObjectMetaBuilder().withName("my-secret")
|
||||
.withNamespace("spring-k8s").withResourceVersion("1").build()).addToData(secretData).build();
|
||||
|
||||
V1SecretList allConfigMaps = new V1SecretList();
|
||||
allConfigMaps.setItems(Collections.singletonList(mySecret));
|
||||
|
||||
// the actual stub for CoreV1Api calls
|
||||
WireMock.stubFor(WireMock.get("/api/v1/namespaces/spring-k8s/secrets")
|
||||
.willReturn(WireMock.aResponse().withStatus(200).withBody(new JSON().serialize(allConfigMaps))));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,4 +8,7 @@ org.springframework.cloud.kubernetes.client.config.boostrap.stubs.LabeledSecretW
|
||||
org.springframework.cloud.kubernetes.client.config.boostrap.stubs.LabeledConfigMapWithPrefixConfigurationStub, \
|
||||
org.springframework.cloud.kubernetes.client.config.boostrap.stubs.LabeledConfigMapWithProfileConfigurationStub, \
|
||||
org.springframework.cloud.kubernetes.client.config.boostrap.stubs.SingleSourceMultipleFilesConfigurationStub, \
|
||||
org.springframework.cloud.kubernetes.client.config.boostrap.stubs.IncludeProfileSpecificSourcesConfigurationStub, \
|
||||
org.springframework.cloud.kubernetes.client.config.boostrap.stubs.ConfigMapNameAsPrefixConfigurationStub, \
|
||||
org.springframework.cloud.kubernetes.client.config.boostrap.stubs.SourcesOrderConfigurationStub, \
|
||||
org.springframework.cloud.kubernetes.client.config.EnableRetryBootstrapConfiguration
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
spring:
|
||||
application:
|
||||
name: sources-order
|
||||
cloud:
|
||||
kubernetes:
|
||||
secrets:
|
||||
fail-fast: true
|
||||
enabled: true
|
||||
enableApi: true
|
||||
namespace: spring-k8s
|
||||
sources:
|
||||
- name: my-secret
|
||||
config:
|
||||
fail-fast: true
|
||||
namespace: spring-k8s
|
||||
sources:
|
||||
- name: my-configmap
|
||||
@@ -0,0 +1,15 @@
|
||||
spring:
|
||||
application:
|
||||
name: sources-order
|
||||
cloud:
|
||||
kubernetes:
|
||||
secrets:
|
||||
enabled: true
|
||||
enableApi: true
|
||||
namespace: spring-k8s
|
||||
sources:
|
||||
- name: my-secret
|
||||
config:
|
||||
namespace: spring-k8s
|
||||
sources:
|
||||
- name: my-configmap
|
||||
@@ -32,7 +32,7 @@ import org.springframework.retry.annotation.Retryable;
|
||||
*
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
@Order(1)
|
||||
@Order(0)
|
||||
class RetryableFabric8ConfigMapPropertySourceLocator extends Fabric8ConfigMapPropertySourceLocator {
|
||||
|
||||
RetryableFabric8ConfigMapPropertySourceLocator(KubernetesClient client, ConfigMapConfigProperties properties,
|
||||
|
||||
@@ -22,6 +22,7 @@ import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
|
||||
import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider;
|
||||
import org.springframework.cloud.kubernetes.commons.config.SecretsConfigProperties;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.retry.annotation.Retryable;
|
||||
@@ -31,6 +32,7 @@ import org.springframework.retry.annotation.Retryable;
|
||||
*
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
@Order(1)
|
||||
class RetryableFabric8SecretsPropertySourceLocator extends Fabric8SecretsPropertySourceLocator {
|
||||
|
||||
RetryableFabric8SecretsPropertySourceLocator(KubernetesClient client, SecretsConfigProperties properties,
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.kubernetes.fabric8.config.retryable_sources_order;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* @author wind57
|
||||
*/
|
||||
@ConfigurationProperties("my")
|
||||
class Properties {
|
||||
|
||||
private String key;
|
||||
|
||||
private String one;
|
||||
|
||||
private String two;
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public String getOne() {
|
||||
return one;
|
||||
}
|
||||
|
||||
public void setOne(String one) {
|
||||
this.one = one;
|
||||
}
|
||||
|
||||
public String getTwo() {
|
||||
return two;
|
||||
}
|
||||
|
||||
public void setTwo(String two) {
|
||||
this.two = two;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.kubernetes.fabric8.config.retryable_sources_order;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
|
||||
/**
|
||||
* @author wind57
|
||||
*/
|
||||
@SpringBootApplication
|
||||
@EnableConfigurationProperties(Properties.class)
|
||||
class RetryableSourcesOrderApp {
|
||||
|
||||
static void main(String[] args) {
|
||||
SpringApplication.run(RetryableSourcesOrderApp.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.kubernetes.fabric8.config.retryable_sources_order;
|
||||
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @author wind57
|
||||
*/
|
||||
@RestController
|
||||
class RetryableSourcesOrderController {
|
||||
|
||||
private final Properties properties;
|
||||
|
||||
RetryableSourcesOrderController(Properties properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
@GetMapping("/retryable-key")
|
||||
String key() {
|
||||
return properties.getKey();
|
||||
}
|
||||
|
||||
@GetMapping("/retryable-one")
|
||||
String one() {
|
||||
return properties.getOne();
|
||||
}
|
||||
|
||||
@GetMapping("/retryable-two")
|
||||
String two() {
|
||||
return properties.getTwo();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.kubernetes.fabric8.config.retryable_sources_order;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import io.fabric8.kubernetes.api.model.ConfigMapBuilder;
|
||||
import io.fabric8.kubernetes.api.model.SecretBuilder;
|
||||
import io.fabric8.kubernetes.client.Config;
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
|
||||
/**
|
||||
* @author wind57
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = RetryableSourcesOrderApp.class,
|
||||
properties = { "spring.cloud.bootstrap.name=retryable-sources-order" })
|
||||
@EnableKubernetesMockClient(crud = true, https = false)
|
||||
class RetryableSourcesOrderTests {
|
||||
|
||||
private static KubernetesClient mockClient;
|
||||
|
||||
@Autowired
|
||||
private WebTestClient webClient;
|
||||
|
||||
@BeforeAll
|
||||
static void setUpBeforeClass() {
|
||||
|
||||
// Configure the kubernetes master url to point to the mock server
|
||||
System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, mockClient.getConfiguration().getMasterUrl());
|
||||
System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false");
|
||||
System.setProperty(Config.KUBERNETES_NAMESPACE_SYSTEM_PROPERTY, "test");
|
||||
System.setProperty(Config.KUBERNETES_HTTP2_DISABLE, "true");
|
||||
|
||||
Map<String, String> secretData = new HashMap<>();
|
||||
secretData.put("my.key", Base64.getEncoder().encodeToString("from-secret".getBytes(StandardCharsets.UTF_8)));
|
||||
secretData.put("my.one", Base64.getEncoder().encodeToString("one".getBytes(StandardCharsets.UTF_8)));
|
||||
createSecret("my-secret", secretData);
|
||||
|
||||
Map<String, String> configMapData = new HashMap<>();
|
||||
configMapData.put("my.key", "from-configmap");
|
||||
configMapData.put("my.two", "two");
|
||||
createConfigmap("my-configmap", configMapData);
|
||||
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
static void afterAll() {
|
||||
System.clearProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY);
|
||||
}
|
||||
|
||||
private static void createSecret(String name, Map<String, String> data) {
|
||||
mockClient.secrets().inNamespace("spring-k8s")
|
||||
.create(new SecretBuilder().withNewMetadata().withName(name).endMetadata().addToData(data).build());
|
||||
}
|
||||
|
||||
private static void createConfigmap(String name, Map<String, String> data) {
|
||||
mockClient.configMaps().inNamespace("spring-k8s")
|
||||
.create(new ConfigMapBuilder().withNewMetadata().withName(name).endMetadata().addToData(data).build());
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 1. There is one secret deployed: my-secret. It has two properties: {my.one=one, my.key=from-secret}
|
||||
* 2. There is one configmap deployed: my-configmap. It has two properties: {my.two=two, my.key=from-configmap}
|
||||
*
|
||||
* We invoke three endpoints: /one, /two, /key.
|
||||
* The first two prove that both the secret and configmap have been read, the last one proves that
|
||||
* config maps have a higher precedence.
|
||||
* </pre>
|
||||
*/
|
||||
@Test
|
||||
void test() {
|
||||
this.webClient.get().uri("/retryable-one").exchange().expectStatus().isOk().expectBody(String.class)
|
||||
.value(Matchers.equalTo("one"));
|
||||
this.webClient.get().uri("/retryable-two").exchange().expectStatus().isOk().expectBody(String.class)
|
||||
.value(Matchers.equalTo("two"));
|
||||
|
||||
this.webClient.get().uri("/retryable-key").exchange().expectStatus().isOk().expectBody(String.class)
|
||||
.value(Matchers.equalTo("from-configmap"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.kubernetes.fabric8.config.sources_order;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* @author wind57
|
||||
*/
|
||||
@ConfigurationProperties("my")
|
||||
class Properties {
|
||||
|
||||
private String key;
|
||||
|
||||
private String one;
|
||||
|
||||
private String two;
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public String getOne() {
|
||||
return one;
|
||||
}
|
||||
|
||||
public void setOne(String one) {
|
||||
this.one = one;
|
||||
}
|
||||
|
||||
public String getTwo() {
|
||||
return two;
|
||||
}
|
||||
|
||||
public void setTwo(String two) {
|
||||
this.two = two;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.kubernetes.fabric8.config.sources_order;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
|
||||
/**
|
||||
* @author wind57
|
||||
*/
|
||||
@SpringBootApplication
|
||||
@EnableConfigurationProperties(Properties.class)
|
||||
class SourcesOrderApp {
|
||||
|
||||
static void main(String[] args) {
|
||||
SpringApplication.run(SourcesOrderApp.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.kubernetes.fabric8.config.sources_order;
|
||||
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @author wind57
|
||||
*/
|
||||
@RestController
|
||||
class SourcesOrderController {
|
||||
|
||||
private final Properties properties;
|
||||
|
||||
SourcesOrderController(Properties properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
@GetMapping("/key")
|
||||
String key() {
|
||||
return properties.getKey();
|
||||
}
|
||||
|
||||
@GetMapping("/one")
|
||||
String one() {
|
||||
return properties.getOne();
|
||||
}
|
||||
|
||||
@GetMapping("/two")
|
||||
String two() {
|
||||
return properties.getTwo();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.kubernetes.fabric8.config.sources_order;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import io.fabric8.kubernetes.api.model.ConfigMapBuilder;
|
||||
import io.fabric8.kubernetes.api.model.SecretBuilder;
|
||||
import io.fabric8.kubernetes.client.Config;
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
|
||||
/**
|
||||
* @author wind57
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = SourcesOrderApp.class,
|
||||
properties = { "spring.cloud.bootstrap.name=sources-order" })
|
||||
@EnableKubernetesMockClient(crud = true, https = false)
|
||||
class SourcesOrderTests {
|
||||
|
||||
private static KubernetesClient mockClient;
|
||||
|
||||
@Autowired
|
||||
private WebTestClient webClient;
|
||||
|
||||
@BeforeAll
|
||||
static void setUpBeforeClass() {
|
||||
|
||||
// Configure the kubernetes master url to point to the mock server
|
||||
System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, mockClient.getConfiguration().getMasterUrl());
|
||||
System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false");
|
||||
System.setProperty(Config.KUBERNETES_NAMESPACE_SYSTEM_PROPERTY, "test");
|
||||
System.setProperty(Config.KUBERNETES_HTTP2_DISABLE, "true");
|
||||
|
||||
Map<String, String> secretData = new HashMap<>();
|
||||
secretData.put("my.key", Base64.getEncoder().encodeToString("from-secret".getBytes(StandardCharsets.UTF_8)));
|
||||
secretData.put("my.one", Base64.getEncoder().encodeToString("one".getBytes(StandardCharsets.UTF_8)));
|
||||
createSecret("my-secret", secretData);
|
||||
|
||||
Map<String, String> configMapData = new HashMap<>();
|
||||
configMapData.put("my.key", "from-configmap");
|
||||
configMapData.put("my.two", "two");
|
||||
createConfigmap("my-configmap", configMapData);
|
||||
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
static void afterAll() {
|
||||
System.clearProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY);
|
||||
}
|
||||
|
||||
private static void createSecret(String name, Map<String, String> data) {
|
||||
mockClient.secrets().inNamespace("spring-k8s")
|
||||
.create(new SecretBuilder().withNewMetadata().withName(name).endMetadata().addToData(data).build());
|
||||
}
|
||||
|
||||
private static void createConfigmap(String name, Map<String, String> data) {
|
||||
mockClient.configMaps().inNamespace("spring-k8s")
|
||||
.create(new ConfigMapBuilder().withNewMetadata().withName(name).endMetadata().addToData(data).build());
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 1. There is one secret deployed: my-secret. It has two properties: {my.one=one, my.key=from-secret}
|
||||
* 2. There is one configmap deployed: my-configmap. It has two properties: {my.two=two, my.key=from-configmap}
|
||||
*
|
||||
* We invoke three endpoints: /one, /two, /key.
|
||||
* The first two prove that both the secret and configmap have been read, the last one proves that
|
||||
* config maps have a higher precedence.
|
||||
* </pre>
|
||||
*/
|
||||
@Test
|
||||
void test() {
|
||||
this.webClient.get().uri("/one").exchange().expectStatus().isOk().expectBody(String.class)
|
||||
.value(Matchers.equalTo("one"));
|
||||
this.webClient.get().uri("/two").exchange().expectStatus().isOk().expectBody(String.class)
|
||||
.value(Matchers.equalTo("two"));
|
||||
|
||||
this.webClient.get().uri("/key").exchange().expectStatus().isOk().expectBody(String.class)
|
||||
.value(Matchers.equalTo("from-configmap"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
spring:
|
||||
application:
|
||||
name: sources-order
|
||||
cloud:
|
||||
kubernetes:
|
||||
secrets:
|
||||
fail-fast: true
|
||||
enabled: true
|
||||
enableApi: true
|
||||
namespace: spring-k8s
|
||||
sources:
|
||||
- name: my-secret
|
||||
config:
|
||||
fail-fast: true
|
||||
namespace: spring-k8s
|
||||
sources:
|
||||
- name: my-configmap
|
||||
@@ -0,0 +1,15 @@
|
||||
spring:
|
||||
application:
|
||||
name: sources-order
|
||||
cloud:
|
||||
kubernetes:
|
||||
secrets:
|
||||
enabled: true
|
||||
enableApi: true
|
||||
namespace: spring-k8s
|
||||
sources:
|
||||
- name: my-secret
|
||||
config:
|
||||
namespace: spring-k8s
|
||||
sources:
|
||||
- name: my-configmap
|
||||
Reference in New Issue
Block a user