ConfigMap additional namespaces don't work in ConfigServer (#892)

The typo in the property "spring.cloud.kubernetes.configserver.config-map-namespaces"
property is now fixed. Also, the property is now used correctly in the autoconfiguration
in the context of the ConfigMaps monitoring configuration.

Fixes gh-891
This commit is contained in:
Thomas Vitale
2021-10-28 01:20:02 +02:00
committed by GitHub
parent 1842568163
commit ecf3560512
3 changed files with 190 additions and 6 deletions

View File

@@ -67,7 +67,7 @@ public class KubernetesConfigServerAutoConfiguration {
public KubernetesPropertySourceSupplier configMapPropertySourceSupplier(
KubernetesConfigServerProperties properties) {
return (coreApi, applicationName, namespace, springEnv) -> {
List<String> namespaces = namespaceSplitter(properties.getSecretsNamespaces(), namespace);
List<String> namespaces = namespaceSplitter(properties.getConfigMapNamespaces(), namespace);
List<MapPropertySource> propertySources = new ArrayList<>();
namespaces.forEach(space -> propertySources.add(new KubernetesClientConfigMapPropertySource(coreApi,
applicationName, space, springEnv, "", true, false)));

View File

@@ -25,16 +25,16 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties("spring.cloud.kubernetes.configserver")
public class KubernetesConfigServerProperties {
private String conigMapNamespaces = "";
private String configMapNamespaces = "";
private String secretsNamespaces = "";
public String getConigMapNamespaces() {
return conigMapNamespaces;
public String getConfigMapNamespaces() {
return configMapNamespaces;
}
public void setConigMapNamespaces(String conigMapNamespaces) {
this.conigMapNamespaces = conigMapNamespaces;
public void setConfigMapNamespaces(String configMapNamespaces) {
this.configMapNamespaces = configMapNamespaces;
}
public String getSecretsNamespaces() {

View File

@@ -0,0 +1,184 @@
/*
* Copyright 2013-2021 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.configserver;
import java.util.Collections;
import io.kubernetes.client.openapi.ApiException;
import io.kubernetes.client.openapi.apis.CoreV1Api;
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.openapi.models.V1SecretListBuilder;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.springframework.cloud.config.environment.Environment;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
* Tests for verifying the behavior of the {@link KubernetesPropertySourceSupplier} beans
* for ConfigMaps and Secrets created by the auto-configuration.
*
* @author Thomas Vitale
*/
class KubernetesPropertySourceSupplierTests {
private static final CoreV1Api coreApi = mock(CoreV1Api.class);
private static final V1ConfigMapList CONFIGMAP_DEFAULT_LIST = new V1ConfigMapList()
.addItemsItem(buildConfigMap("gateway", "tdefault"));
private static final V1ConfigMapList CONFIGMAP_TEAM_A_LIST = new V1ConfigMapList()
.addItemsItem(buildConfigMap("stores", "team-a"));
private static final V1ConfigMapList CONFIGMAP_TEAM_B_LIST = new V1ConfigMapList()
.addItemsItem(buildConfigMap("orders", "team-b"));
private static final V1SecretList SECRET_DEFAULT_LIST = new V1SecretListBuilder()
.addToItems(buildSecret("gateway", "default")).build();
private static final V1SecretList SECRET_TEAM_A_LIST = new V1SecretListBuilder()
.addToItems(buildSecret("stores", "team-a")).build();
private static final V1SecretList SECRET_TEAM_B_LIST = new V1SecretListBuilder()
.addToItems(buildSecret("orders", "team-b")).build();
@BeforeAll
public static void before() throws ApiException {
when(coreApi.listNamespacedConfigMap(eq("default"), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null),
eq(null), eq(null), eq(null), eq(null))).thenReturn(CONFIGMAP_DEFAULT_LIST);
when(coreApi.listNamespacedConfigMap(eq("team-a"), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null),
eq(null), eq(null), eq(null), eq(null))).thenReturn(CONFIGMAP_TEAM_A_LIST);
when(coreApi.listNamespacedConfigMap(eq("team-b"), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null),
eq(null), eq(null), eq(null), eq(null))).thenReturn(CONFIGMAP_TEAM_B_LIST);
when(coreApi.listNamespacedSecret(eq("default"), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null),
eq(null), eq(null), eq(null), eq(null))).thenReturn(SECRET_DEFAULT_LIST);
when(coreApi.listNamespacedSecret(eq("team-a"), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null),
eq(null), eq(null), eq(null), eq(null))).thenReturn(SECRET_TEAM_A_LIST);
when(coreApi.listNamespacedSecret(eq("team-b"), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null),
eq(null), eq(null), eq(null), eq(null))).thenReturn(SECRET_TEAM_B_LIST);
}
@Test
void whenCurrentAndExtraNamespacesAddedThenAllConfigMapsAreIncluded() {
KubernetesConfigServerProperties kubernetesConfigServerProperties = new KubernetesConfigServerProperties();
kubernetesConfigServerProperties.setConfigMapNamespaces("default,team-a,team-b");
KubernetesPropertySourceSupplier kubernetesPropertySourceSupplier = new KubernetesConfigServerAutoConfiguration()
.configMapPropertySourceSupplier(kubernetesConfigServerProperties);
KubernetesEnvironmentRepository environmentRepository = new KubernetesEnvironmentRepository(coreApi,
Collections.singletonList(kubernetesPropertySourceSupplier), "default");
Environment environmentGateway = environmentRepository.findOne("gateway", "", "");
assertThat(environmentGateway.getPropertySources().size()).isEqualTo(1);
Environment environmentStores = environmentRepository.findOne("stores", "", "");
assertThat(environmentStores.getPropertySources().size()).isEqualTo(1);
Environment environmentOrders = environmentRepository.findOne("orders", "", "");
assertThat(environmentOrders.getPropertySources().size()).isEqualTo(1);
}
@Test
void whenExtraNamespacesAddedThenConfigMapsInCurrentNamespaceAreNotIncluded() {
KubernetesConfigServerProperties kubernetesConfigServerProperties = new KubernetesConfigServerProperties();
kubernetesConfigServerProperties.setConfigMapNamespaces("team-a,team-b");
KubernetesPropertySourceSupplier kubernetesPropertySourceSupplier = new KubernetesConfigServerAutoConfiguration()
.configMapPropertySourceSupplier(kubernetesConfigServerProperties);
KubernetesEnvironmentRepository environmentRepository = new KubernetesEnvironmentRepository(coreApi,
Collections.singletonList(kubernetesPropertySourceSupplier), "default");
Environment environmentGateway = environmentRepository.findOne("gateway", "", "");
assertThat(environmentGateway.getPropertySources().size()).isEqualTo(0);
Environment environmentStores = environmentRepository.findOne("stores", "", "");
assertThat(environmentStores.getPropertySources().size()).isEqualTo(1);
Environment environmentOrders = environmentRepository.findOne("orders", "", "");
assertThat(environmentOrders.getPropertySources().size()).isEqualTo(1);
}
@Test
void whenCurrentAndExtraNamespacesAddedThenAllSecretsAreIncluded() {
KubernetesConfigServerProperties kubernetesConfigServerProperties = new KubernetesConfigServerProperties();
kubernetesConfigServerProperties.setSecretsNamespaces("default,team-a,team-b");
KubernetesPropertySourceSupplier kubernetesPropertySourceSupplier = new KubernetesConfigServerAutoConfiguration()
.secretsPropertySourceSupplier(kubernetesConfigServerProperties);
KubernetesEnvironmentRepository environmentRepository = new KubernetesEnvironmentRepository(coreApi,
Collections.singletonList(kubernetesPropertySourceSupplier), "default");
Environment environmentGateway = environmentRepository.findOne("gateway", "", "");
assertThat(environmentGateway.getPropertySources().size()).isEqualTo(1);
Environment environmentStores = environmentRepository.findOne("stores", "", "");
assertThat(environmentStores.getPropertySources().size()).isEqualTo(1);
Environment environmentOrders = environmentRepository.findOne("orders", "", "");
assertThat(environmentOrders.getPropertySources().size()).isEqualTo(1);
}
@Test
void whenExtraNamespacesAddedThenSecretsInCurrentNamespaceAreNotIncluded() {
KubernetesConfigServerProperties kubernetesConfigServerProperties = new KubernetesConfigServerProperties();
kubernetesConfigServerProperties.setSecretsNamespaces("team-a,team-b");
KubernetesPropertySourceSupplier kubernetesPropertySourceSupplier = new KubernetesConfigServerAutoConfiguration()
.secretsPropertySourceSupplier(kubernetesConfigServerProperties);
KubernetesEnvironmentRepository environmentRepository = new KubernetesEnvironmentRepository(coreApi,
Collections.singletonList(kubernetesPropertySourceSupplier), "default");
Environment environmentGateway = environmentRepository.findOne("gateway", "", "");
assertThat(environmentGateway.getPropertySources().size()).isEqualTo(0);
Environment environmentStores = environmentRepository.findOne("stores", "", "");
assertThat(environmentStores.getPropertySources().size()).isEqualTo(1);
Environment environmentOrders = environmentRepository.findOne("orders", "", "");
assertThat(environmentOrders.getPropertySources().size()).isEqualTo(1);
}
private static V1ConfigMap buildConfigMap(String name, String namespace) {
return new V1ConfigMapBuilder()
.withMetadata(new V1ObjectMetaBuilder().withName(name).withNamespace(namespace).withResourceVersion("1")
.build())
.addToData("application.yaml", "dummy:\n property:\n string: \"" + name + "\"\n").build();
}
private static V1Secret buildSecret(String name, String namespace) {
return new V1SecretBuilder()
.withMetadata(new V1ObjectMetaBuilder().withName(name).withResourceVersion("0").withNamespace(namespace)
.build())
.addToData("password", "p455w0rd".getBytes()).addToData("username", "user".getBytes()).build();
}
}