Initial commit

This commit is contained in:
spencergibb
2023-09-19 13:10:02 -04:00
parent 2e4d529f30
commit 8a57c69c88
1303 changed files with 8661 additions and 95772 deletions

View File

@@ -0,0 +1,105 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-kubernetes-controllers</artifactId>
<version>3.0.4-SNAPSHOT</version>
</parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-kubernetes-configserver</artifactId>
<version>3.0.4-SNAPSHOT</version>
<description>Spring Cloud parent pom, managing plugins and dependencies for Spring
Cloud projects</description>
<url>https://cloud.spring.io/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configserver</url>
<inceptionYear>2017</inceptionYear>
<organization>
<name>Pivotal Software, Inc.</name>
<url>https://www.spring.io</url>
</organization>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<id>dsyer</id>
<name>Dave Syer</name>
<email>dsyer at pivotal.io</email>
<organization>Pivotal Software, Inc.</organization>
<organizationUrl>https://www.spring.io</organizationUrl>
<roles>
<role>lead</role>
</roles>
</developer>
<developer>
<id>sgibb</id>
<name>Spencer Gibb</name>
<email>sgibb at pivotal.io</email>
<organization>Pivotal Software, Inc.</organization>
<organizationUrl>https://www.spring.io</organizationUrl>
<roles>
<role>lead</role>
</roles>
</developer>
<developer>
<id>mgrzejszczak</id>
<name>Marcin Grzejszczak</name>
<email>mgrzejszczak at pivotal.io</email>
<organization>Pivotal Software, Inc.</organization>
<organizationUrl>https://www.spring.io</organizationUrl>
<roles>
<role>developer</role>
</roles>
</developer>
<developer>
<id>rbaxter</id>
<name>Ryan Baxter</name>
<email>rbaxter at pivotal.io</email>
<organization>Pivotal Software, Inc.</organization>
<organizationUrl>https://www.spring.io</organizationUrl>
<roles>
<role>developer</role>
</roles>
</developer>
<developer>
<id>omaciaszeksharma</id>
<name>Olga Maciaszek-Sharma</name>
<email>omaciaszeksharma at pivotal.io</email>
<organization>Pivotal Software, Inc.</organization>
<organizationUrl>https://www.spring.io</organizationUrl>
<roles>
<role>developer</role>
</roles>
</developer>
</developers>
<scm>
<connection>scm:git:git://github.com/spring-cloud/spring-cloud-kubernetes.git/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configserver</connection>
<developerConnection>scm:git:ssh://git@github.com/spring-cloud/spring-cloud-kubernetes.git/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configserver</developerConnection>
<url>https://github.com/spring-cloud/spring-cloud-kubernetes/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configserver</url>
</scm>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
<version>4.0.4-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>3.0.7</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-client-config</artifactId>
<version>3.0.4-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@@ -1,138 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring-cloud-kubernetes-controllers</artifactId>
<groupId>org.springframework.cloud</groupId>
<version>3.1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-cloud-kubernetes-configserver</artifactId>
<properties>
<docker.registry.organization>springcloud</docker.registry.organization>
<plexus-archiver.version>4.1.0</plexus-archiver.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-client-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<!-- in favor of mockito-inline -->
<exclusions>
<exclusion>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
</exclusion>
</exclusions>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock-jre8-standalone</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-kubernetes-test-support</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<name>${env.IMAGE}</name>
</image>
<goal>build-image</goal>
</configuration>
<executions>
<execution>
<id>build-image</id>
<configuration>
<skip>${skip.build.image}</skip>
</configuration>
<phase>package</phase>
<goals>
<goal>build-image</goal>
</goals>
</execution>
<execution>
<id>repackage</id>
<phase>package</phase>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>dockerpush</id>
<build>
<plugins>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>1.4.12</version>
<configuration>
<repository>${docker.registry.organization}/${artifactId}</repository>
<tag>${project.version}</tag>
<username>${env.DOCKER_HUB_USERNAME}</username>
<password>${env.DOCKER_HUB_PASSWORD}</password>
<build>
<noCache>true</noCache>
</build>
</configuration>
<dependencies>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-archiver</artifactId>
<version>${plexus-archiver.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>imagename</id>
<activation>
<property>
<name>!env.IMAGE</name>
</property>
</activation>
<properties>
<env.IMAGE>springcloud/${project.artifactId}:${project.version}</env.IMAGE>
</properties>
</profile>
</profiles>
</project>

View File

@@ -1,35 +0,0 @@
/*
* 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 org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.config.server.ConfigServerApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
/**
* @author Ryan Baxter
*/
@SpringBootApplication
@EnableConfigServer
public class KubernetesConfigServerApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(ConfigServerApplication.class).run(args);
}
}

View File

@@ -1,109 +0,0 @@
/*
* 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.ArrayList;
import java.util.List;
import io.kubernetes.client.openapi.apis.CoreV1Api;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnCloudPlatform;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.cloud.CloudPlatform;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.config.server.config.ConfigServerAutoConfiguration;
import org.springframework.cloud.config.server.environment.EnvironmentRepository;
import org.springframework.cloud.kubernetes.client.KubernetesClientAutoConfiguration;
import org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigContext;
import org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigMapPropertySource;
import org.springframework.cloud.kubernetes.client.config.KubernetesClientSecretsPropertySource;
import org.springframework.cloud.kubernetes.commons.ConditionalOnKubernetesConfigEnabled;
import org.springframework.cloud.kubernetes.commons.ConditionalOnKubernetesSecretsEnabled;
import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider;
import org.springframework.cloud.kubernetes.commons.config.NamedConfigMapNormalizedSource;
import org.springframework.cloud.kubernetes.commons.config.NamedSecretNormalizedSource;
import org.springframework.cloud.kubernetes.commons.config.NormalizedSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.core.env.MapPropertySource;
import static org.springframework.cloud.kubernetes.configserver.KubernetesPropertySourceSupplier.namespaceSplitter;
/**
* @author Ryan Baxter
*/
@Configuration
@AutoConfigureAfter({ KubernetesClientAutoConfiguration.class })
@AutoConfigureBefore({ ConfigServerAutoConfiguration.class })
@ConditionalOnCloudPlatform(CloudPlatform.KUBERNETES)
@EnableConfigurationProperties(KubernetesConfigServerProperties.class)
public class KubernetesConfigServerAutoConfiguration {
@Bean
@Profile("kubernetes")
public EnvironmentRepository kubernetesEnvironmentRepository(CoreV1Api coreV1Api,
List<KubernetesPropertySourceSupplier> kubernetesPropertySourceSuppliers,
KubernetesNamespaceProvider kubernetesNamespaceProvider) {
return new KubernetesEnvironmentRepository(coreV1Api, kubernetesPropertySourceSuppliers,
kubernetesNamespaceProvider.getNamespace());
}
@Bean
@ConditionalOnKubernetesConfigEnabled
@ConditionalOnProperty(value = "spring.cloud.kubernetes.config.enableApi", matchIfMissing = true)
public KubernetesPropertySourceSupplier configMapPropertySourceSupplier(
KubernetesConfigServerProperties properties) {
return (coreApi, applicationName, namespace, springEnv) -> {
List<String> namespaces = namespaceSplitter(properties.getConfigMapNamespaces(), namespace);
List<MapPropertySource> propertySources = new ArrayList<>();
namespaces.forEach(space -> {
NamedConfigMapNormalizedSource source = new NamedConfigMapNormalizedSource(applicationName, space,
false, true);
KubernetesClientConfigContext context = new KubernetesClientConfigContext(coreApi, source, space,
springEnv);
propertySources.add(new KubernetesClientConfigMapPropertySource(context));
});
return propertySources;
};
}
@Bean
@ConditionalOnKubernetesSecretsEnabled
@ConditionalOnProperty("spring.cloud.kubernetes.secrets.enableApi")
public KubernetesPropertySourceSupplier secretsPropertySourceSupplier(KubernetesConfigServerProperties properties) {
return (coreApi, applicationName, namespace, springEnv) -> {
List<String> namespaces = namespaceSplitter(properties.getSecretsNamespaces(), namespace);
List<MapPropertySource> propertySources = new ArrayList<>();
namespaces.forEach(space -> {
NormalizedSource source = new NamedSecretNormalizedSource(applicationName, space, false, false);
KubernetesClientConfigContext context = new KubernetesClientConfigContext(coreApi, source, space,
springEnv);
propertySources.add(new KubernetesClientSecretsPropertySource(context));
});
return propertySources;
};
}
}

View File

@@ -1,48 +0,0 @@
/*
* 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 org.springframework.boot.context.properties.ConfigurationProperties;
/**
* @author Ryan Baxter
*/
@ConfigurationProperties("spring.cloud.kubernetes.configserver")
public class KubernetesConfigServerProperties {
private String configMapNamespaces = "";
private String secretsNamespaces = "";
public String getConfigMapNamespaces() {
return configMapNamespaces;
}
public void setConfigMapNamespaces(String configMapNamespaces) {
this.configMapNamespaces = configMapNamespaces;
}
public String getSecretsNamespaces() {
return secretsNamespaces;
}
public void setSecretsNamespaces(String secretsNamespaces) {
this.secretsNamespaces = secretsNamespaces;
}
}

View File

@@ -1,94 +0,0 @@
/*
* 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.List;
import io.kubernetes.client.openapi.apis.CoreV1Api;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.config.environment.Environment;
import org.springframework.cloud.config.environment.PropertySource;
import org.springframework.cloud.config.server.environment.EnvironmentRepository;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.util.StringUtils;
/**
* @author Ryan Baxter
*/
public class KubernetesEnvironmentRepository implements EnvironmentRepository {
private static final Log LOG = LogFactory.getLog(KubernetesEnvironmentRepository.class);
private CoreV1Api coreApi;
private List<KubernetesPropertySourceSupplier> kubernetesPropertySourceSuppliers;
private String namespace;
public KubernetesEnvironmentRepository(CoreV1Api coreApi,
List<KubernetesPropertySourceSupplier> kubernetesPropertySourceSuppliers, String namespace) {
this.coreApi = coreApi;
this.kubernetesPropertySourceSuppliers = kubernetesPropertySourceSuppliers;
this.namespace = namespace;
}
@Override
public Environment findOne(String application, String profile, String label) {
return findOne(application, profile, label, true);
}
@Override
public Environment findOne(String application, String profile, String label, boolean includeOrigin) {
String[] profiles = StringUtils.commaDelimitedListToStringArray(profile);
LOG.info("Profiles: " + profile);
LOG.info("Application: " + application);
LOG.info("Label: " + label);
Environment environment = new Environment(application, profiles, label, null, null);
try {
StandardEnvironment springEnv = new StandardEnvironment();
springEnv.setActiveProfiles(profiles);
if (!"application".equalsIgnoreCase(application)) {
addApplicationConfiguration(environment, springEnv, application);
}
addApplicationConfiguration(environment, springEnv, "application");
return environment;
}
catch (Exception e) {
LOG.warn(e);
}
return environment;
}
private void addApplicationConfiguration(Environment environment, StandardEnvironment springEnv,
String applicationName) {
kubernetesPropertySourceSuppliers.stream().forEach(supplier -> {
List<MapPropertySource> propertySources = supplier.get(coreApi, applicationName, namespace, springEnv);
propertySources.forEach(propertySource -> {
if (propertySource.getPropertyNames().length > 0) {
LOG.debug("Adding PropertySource " + propertySource.getName());
LOG.debug("PropertySource Names: "
+ StringUtils.arrayToCommaDelimitedString(propertySource.getPropertyNames()));
environment.add(new PropertySource(propertySource.getName(), propertySource.getSource()));
}
});
});
}
}

View File

@@ -1,45 +0,0 @@
/*
* 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.Arrays;
import java.util.Collections;
import java.util.List;
import io.kubernetes.client.openapi.apis.CoreV1Api;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.util.StringUtils;
/**
* @author Ryan Baxter
*/
public interface KubernetesPropertySourceSupplier {
List<MapPropertySource> get(CoreV1Api coreV1Api, String name, String namespace, Environment environment);
static List<String> namespaceSplitter(String namespacesString, String currentNamespace) {
List<String> namespaces = Collections.singletonList(currentNamespace);
String[] namespacesArray = StringUtils.commaDelimitedListToStringArray(namespacesString);
if (namespacesArray.length > 0) {
namespaces = Arrays.asList(namespacesArray);
}
return namespaces;
}
}

View File

@@ -1 +0,0 @@
org.springframework.cloud.kubernetes.configserver.KubernetesConfigServerAutoConfiguration

View File

@@ -1,13 +0,0 @@
spring:
application:
name: kubernetesconfigserver
server:
port: 8888
---
spring:
config:
activate:
on-cloud-platform: kubernetes
import: "optional:kubernetes:"

View File

@@ -1,31 +0,0 @@
/*
* 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 org.springframework.boot.test.context.SpringBootTest;
/**
* @author Ryan Baxter
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = { "spring.main.cloud-platform=KUBERNETES", "spring.cloud.kubernetes.client.namespace=default",
"spring.profiles.include=kubernetes", "spring.cloud.kubernetes.secrets.enableApi=true",
"spring.cloud.bootstrap.enabled=true" },
classes = { KubernetesConfigServerApplication.class })
public class BootstrapConfigServerIntegrationTest extends ConfigServerIntegrationTest {
}

View File

@@ -1,68 +0,0 @@
/*
* 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 com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.client.WireMock;
import io.kubernetes.client.util.ClientBuilder;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.mockito.MockedStatic;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.client.KubernetesClientUtils;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
import static org.mockito.Mockito.mockStatic;
/**
* @author Ryan Baxter
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = { "spring.main.cloud-platform=KUBERNETES", "spring.cloud.kubernetes.client.namespace=default",
"spring.profiles.include=kubernetes", "spring.cloud.kubernetes.secrets.enableApi=true" },
classes = { KubernetesConfigServerApplication.class })
public class ConfigDataConfigServerIntegrationTest extends ConfigServerIntegrationTest {
private static WireMockServer wireMockServer;
private static MockedStatic<KubernetesClientUtils> clientUtilsMock;
@BeforeAll
static void setup() {
wireMockServer = new WireMockServer(options().dynamicPort());
wireMockServer.start();
WireMock.configureFor(wireMockServer.port());
clientUtilsMock = mockStatic(KubernetesClientUtils.class);
clientUtilsMock.when(KubernetesClientUtils::kubernetesApiClient)
.thenReturn(new ClientBuilder().setBasePath(wireMockServer.baseUrl()).build());
}
@AfterAll
static void teardown() {
wireMockServer.stop();
clientUtilsMock.close();
}
@AfterEach
void afterEach() {
WireMock.reset();
}
}

View File

@@ -1,43 +0,0 @@
/*
* Copyright 2013-2022 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 org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ConfigurableApplicationContext;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Ryan Baxter
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = { "spring.profiles.include=kubernetes,kubernetesdisabled" },
classes = { KubernetesConfigServerApplication.class, MockConfig.class })
class ConfigServerAutoConfigurationKubernetesDisabled {
@Autowired
private ConfigurableApplicationContext context;
@Test
void runTest() {
assertThat(context.getBeanNamesForType(KubernetesEnvironmentRepository.class)).hasSize(0);
}
}

View File

@@ -1,44 +0,0 @@
/*
* Copyright 2013-2022 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 org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ConfigurableApplicationContext;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Ryan Baxter
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
classes = { KubernetesConfigServerApplication.class }, properties = { "spring.main.cloud-platform=KUBERNETES",
"spring.profiles.include=kubernetes", "spring.cloud.kubernetes.client.namespace=default" })
class ConfigServerAutoConfigurationKubernetesEnabledProfileIncluded {
@Autowired
private ConfigurableApplicationContext context;
@Test
void runTest() {
assertThat(context.getBeanNamesForType(KubernetesEnvironmentRepository.class)).hasSize(1);
assertThat(context.getBeanNamesForType(KubernetesPropertySourceSupplier.class)).hasSize(1);
}
}

View File

@@ -1,45 +0,0 @@
/*
* Copyright 2013-2022 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 org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ConfigurableApplicationContext;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Ryan Baxter
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
classes = { KubernetesConfigServerApplication.class },
properties = { "spring.main.cloud-platform=KUBERNETES", "spring.profiles.include=kubernetes",
"spring.cloud.kubernetes.client.namespace=default", "spring.cloud.kubernetes.config.enableApi=false" })
class ConfigServerAutoConfigurationKubernetesEnabledProfileIncludedConfigApiDisabled {
@Autowired
private ConfigurableApplicationContext context;
@Test
void runTest() {
assertThat(context.getBeanNamesForType(KubernetesEnvironmentRepository.class)).hasSize(1);
assertThat(context.getBeanNamesForType(KubernetesPropertySourceSupplier.class)).hasSize(0);
}
}

View File

@@ -1,44 +0,0 @@
/*
* Copyright 2013-2022 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 org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ConfigurableApplicationContext;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Ryan Baxter
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
classes = { KubernetesConfigServerApplication.class }, properties = { "spring.main.cloud-platform=KUBERNETES",
"spring.profiles.include=kubernetes", "spring.cloud.kubernetes.config.enabled=false" })
class ConfigServerAutoConfigurationKubernetesEnabledProfileIncludedConfigMapDisabled {
@Autowired
private ConfigurableApplicationContext context;
@Test
void runTest() {
assertThat(context.getBeanNamesForType(KubernetesEnvironmentRepository.class)).hasSize(1);
assertThat(context.getBeanNamesForType(KubernetesPropertySourceSupplier.class)).hasSize(0);
}
}

View File

@@ -1,46 +0,0 @@
/*
* Copyright 2013-2022 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 org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ConfigurableApplicationContext;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Ryan Baxter
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
classes = { KubernetesConfigServerApplication.class }, properties = { "spring.main.cloud-platform=KUBERNETES",
"spring.profiles.include=kubernetes", "spring.cloud.kubernetes.client.namespace=default" })
class ConfigServerAutoConfigurationKubernetesEnabledProfileIncludedSecretsApiDisabled {
@Autowired
private ConfigurableApplicationContext context;
@Test
void runTest() {
assertThat(context.getBeanNamesForType(KubernetesEnvironmentRepository.class)).hasSize(1);
assertThat(context.getBeanNamesForType(KubernetesPropertySourceSupplier.class)).hasSize(1);
assertThat(context.getBeanNamesForType(KubernetesPropertySourceSupplier.class)[0])
.isEqualTo("configMapPropertySourceSupplier");
}
}

View File

@@ -1,45 +0,0 @@
/*
* Copyright 2013-2022 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 org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ConfigurableApplicationContext;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Ryan Baxter
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
classes = { KubernetesConfigServerApplication.class },
properties = { "spring.profiles.include=kubernetes", "spring.main.cloud-platform=KUBERNETES",
"spring.cloud.kubernetes.client.namespace=default", "spring.cloud.kubernetes.secrets.enableApi=true" })
class ConfigServerAutoConfigurationKubernetesEnabledProfileIncludedSecretsApiEnabled {
@Autowired
private ConfigurableApplicationContext context;
@Test
void runTest() {
assertThat(context.getBeanNamesForType(KubernetesEnvironmentRepository.class)).hasSize(1);
assertThat(context.getBeanNamesForType(KubernetesPropertySourceSupplier.class)).hasSize(2);
}
}

View File

@@ -1,43 +0,0 @@
/*
* Copyright 2013-2022 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 org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ConfigurableApplicationContext;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Ryan Baxter
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
classes = { KubernetesConfigServerApplication.class, MockConfig.class },
properties = { "spring.profiles.include=kubernetes,kubernetesdisabled" })
class ConfigServerAutoConfigurationKubernetesProfileMissing {
@Autowired
private ConfigurableApplicationContext context;
@Test
void runTest() {
assertThat(context.getBeanNamesForType(KubernetesEnvironmentRepository.class)).hasSize(0);
}
}

View File

@@ -1,80 +0,0 @@
/*
* 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 com.github.tomakehurst.wiremock.client.WireMock;
import io.kubernetes.client.openapi.JSON;
import io.kubernetes.client.openapi.models.V1ConfigMapBuilder;
import io.kubernetes.client.openapi.models.V1ConfigMapList;
import io.kubernetes.client.openapi.models.V1ListMetaBuilder;
import io.kubernetes.client.openapi.models.V1ObjectMetaBuilder;
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.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.cloud.config.environment.Environment;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Ryan Baxter
*/
abstract class ConfigServerIntegrationTest {
@Autowired
private TestRestTemplate testRestTemplate;
@BeforeEach
public void beforeEach() {
V1ConfigMapList TEST_CONFIGMAP = new V1ConfigMapList().addItemsItem(new V1ConfigMapBuilder().withMetadata(
new V1ObjectMetaBuilder().withName("test-cm").withNamespace("default").withResourceVersion("1").build())
.addToData("app.name", "test").build());
V1SecretList TEST_SECRET = new V1SecretListBuilder()
.withMetadata(new V1ListMetaBuilder().withResourceVersion("1").build())
.addToItems(new V1SecretBuilder()
.withMetadata(new V1ObjectMetaBuilder().withName("test-cm").withResourceVersion("0")
.withNamespace("default").build())
.addToData("password", "p455w0rd".getBytes()).addToData("username", "user".getBytes()).build())
.build();
WireMock.stubFor(get(urlMatching("^/api/v1/namespaces/default/configmaps.*"))
.willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(TEST_CONFIGMAP))));
WireMock.stubFor(get(urlMatching("^/api/v1/namespaces/default/secrets.*"))
.willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(TEST_SECRET))));
}
@Test
public void enabled() {
Environment env = testRestTemplate.getForObject("/test-cm/default", Environment.class);
assertThat(env.getPropertySources().size()).isEqualTo(2);
assertThat(env.getPropertySources().get(0).getName().equals("configmap.test-cm.default")).isTrue();
assertThat(env.getPropertySources().get(0).getSource().get("app.name")).isEqualTo("test");
assertThat(env.getPropertySources().get(1).getName().equals("secret.test-cm.default")).isTrue();
assertThat(env.getPropertySources().get(1).getSource().get("password")).isEqualTo("p455w0rd");
assertThat(env.getPropertySources().get(1).getSource().get("username")).isEqualTo("user");
}
}

View File

@@ -1,295 +0,0 @@
/*
* 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.ArrayList;
import java.util.List;
import io.kubernetes.client.openapi.ApiException;
import io.kubernetes.client.openapi.apis.CoreV1Api;
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.V1SecretBuilder;
import io.kubernetes.client.openapi.models.V1SecretList;
import io.kubernetes.client.openapi.models.V1SecretListBuilder;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.springframework.cloud.config.environment.Environment;
import org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigContext;
import org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigMapPropertySource;
import org.springframework.cloud.kubernetes.client.config.KubernetesClientSecretsPropertySource;
import org.springframework.cloud.kubernetes.commons.config.NamedConfigMapNormalizedSource;
import org.springframework.cloud.kubernetes.commons.config.NamedSecretNormalizedSource;
import org.springframework.cloud.kubernetes.commons.config.NormalizedSource;
import org.springframework.core.env.MapPropertySource;
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;
/**
* @author Ryan Baxter
*/
class KubernetesEnvironmentRepositoryTests {
private static final List<KubernetesPropertySourceSupplier> KUBERNETES_PROPERTY_SOURCE_SUPPLIER = new ArrayList<>();
private static final String VALUE = "dummy:\n property:\n string2: \"a\"\n int2: 1\n bool2: true\n";
private static final String DEFAULT_NAMESPACE = "default";
private static final V1ConfigMapList CONFIGMAP_DEFAULT_LIST = new V1ConfigMapList()
.addItemsItem(new V1ConfigMapBuilder()
.withMetadata(
new V1ObjectMetaBuilder().withName("application").withNamespace(DEFAULT_NAMESPACE).build())
.addToData("application.yaml", VALUE).build())
.addItemsItem(new V1ConfigMapBuilder()
.withMetadata(new V1ObjectMetaBuilder().withName("stores").withNamespace(DEFAULT_NAMESPACE).build())
.addToData("application.yaml", VALUE).build())
.addItemsItem(new V1ConfigMapBuilder()
.withMetadata(
new V1ObjectMetaBuilder().withName("stores-dev").withNamespace(DEFAULT_NAMESPACE).build())
.addToData("application.yaml",
"dummy:\n property:\n string1: \"a\"\n string2: \"b\"\n int2: 2\n bool2: false\n")
.build());
private static final V1ConfigMapList CONFIGMAP_DEV_LIST = new V1ConfigMapList()
.addItemsItem(new V1ConfigMapBuilder()
.withMetadata(new V1ObjectMetaBuilder().withName("stores").withNamespace("dev")
.withResourceVersion("1").build())
.addToData("application.yaml",
"dummy:\n property:\n string2: \"dev\"\n int2: 1\n bool2: true\n")
.build());
private static final V1SecretList SECRET_LIST = new V1SecretListBuilder()
.addToItems(new V1SecretBuilder()
.withMetadata(new V1ObjectMetaBuilder().withName("application").withResourceVersion("0")
.withNamespace("default").build())
.addToData("password", "p455w0rd".getBytes()).addToData("username", "user".getBytes()).build())
.addToItems(new V1SecretBuilder()
.withMetadata(new V1ObjectMetaBuilder().withName("stores").withResourceVersion("0")
.withNamespace("default").build())
.addToData("password", "password-from-stores".getBytes()).addToData("username", "stores".getBytes())
.build())
.addToItems(new V1SecretBuilder()
.withMetadata(new V1ObjectMetaBuilder().withName("stores-dev").withResourceVersion("0")
.withNamespace("default").build())
.addToData("password", "password-from-stores-dev".getBytes())
.addToData("username", "stores-dev".getBytes()).build())
.build();
@BeforeAll
public static void before() {
KUBERNETES_PROPERTY_SOURCE_SUPPLIER.add((coreApi, applicationName, namespace, springEnv) -> {
List<MapPropertySource> propertySources = new ArrayList<>();
NormalizedSource defaultSource = new NamedConfigMapNormalizedSource(applicationName, "default", false,
true);
KubernetesClientConfigContext defaultContext = new KubernetesClientConfigContext(coreApi, defaultSource,
"default", springEnv);
NormalizedSource devSource = new NamedConfigMapNormalizedSource(applicationName, "dev", false, true);
KubernetesClientConfigContext devContext = new KubernetesClientConfigContext(coreApi, devSource, "dev",
springEnv);
propertySources.add(new KubernetesClientConfigMapPropertySource(defaultContext));
propertySources.add(new KubernetesClientConfigMapPropertySource(devContext));
return propertySources;
});
KUBERNETES_PROPERTY_SOURCE_SUPPLIER.add((coreApi, applicationName, namespace, springEnv) -> {
List<MapPropertySource> propertySources = new ArrayList<>();
NormalizedSource source = new NamedSecretNormalizedSource(applicationName, "default", false, true);
KubernetesClientConfigContext context = new KubernetesClientConfigContext(coreApi, source, "default",
springEnv);
propertySources.add(new KubernetesClientSecretsPropertySource(context));
return propertySources;
});
}
@Test
public void testApplicationCase() throws ApiException {
CoreV1Api coreApi = mock(CoreV1Api.class);
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.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_LIST);
when(coreApi.listNamespacedConfigMap(eq("dev"), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null),
eq(null), eq(null), eq(null), eq(null))).thenReturn(CONFIGMAP_DEV_LIST);
KubernetesEnvironmentRepository environmentRepository = new KubernetesEnvironmentRepository(coreApi,
KUBERNETES_PROPERTY_SOURCE_SUPPLIER, "default");
Environment environment = environmentRepository.findOne("application", "", "");
assertThat(environment.getPropertySources().size()).isEqualTo(2);
environment.getPropertySources().forEach(propertySource -> {
assertThat(propertySource.getName().equals("configmap.application.default")
|| propertySource.getName().equals("secret.application.default")).isTrue();
if (propertySource.getName().equals("configmap.application.default")) {
assertThat(propertySource.getSource().size()).isEqualTo(3);
assertThat(propertySource.getSource().get("dummy.property.int2")).isEqualTo(1);
assertThat(propertySource.getSource().get("dummy.property.bool2")).isEqualTo(true);
assertThat(propertySource.getSource().get("dummy.property.string2")).isEqualTo("a");
}
if (propertySource.getName().equals("secrets.application.default")) {
assertThat(propertySource.getSource().size()).isEqualTo(2);
assertThat(propertySource.getSource().get("username")).isEqualTo("user");
assertThat(propertySource.getSource().get("password")).isEqualTo("p455w0rd");
}
});
}
@Test
public void testStoresCase() throws ApiException {
CoreV1Api coreApi = mock(CoreV1Api.class);
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("dev"), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null),
eq(null), eq(null), eq(null), eq(null))).thenReturn(CONFIGMAP_DEV_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_LIST);
KubernetesEnvironmentRepository environmentRepository = new KubernetesEnvironmentRepository(coreApi,
KUBERNETES_PROPERTY_SOURCE_SUPPLIER, "default");
Environment environment = environmentRepository.findOne("stores", "", "");
assertThat(environment.getPropertySources().size()).isEqualTo(5);
environment.getPropertySources().forEach(propertySource -> {
assertThat(propertySource.getName().equals("configmap.application.default")
|| propertySource.getName().equals("secret.application.default")
|| propertySource.getName().equals("configmap.stores.default")
|| propertySource.getName().equals("configmap.stores.dev")
|| propertySource.getName().equals("secret.stores.default")).isTrue();
if (propertySource.getName().equals("configmap.application.default")) {
assertThat(propertySource.getSource().size()).isEqualTo(3);
assertThat(propertySource.getSource().get("dummy.property.int2")).isEqualTo(1);
assertThat(propertySource.getSource().get("dummy.property.bool2")).isEqualTo(true);
assertThat(propertySource.getSource().get("dummy.property.string2")).isEqualTo("a");
}
if (propertySource.getName().equals("secret.application.default")) {
assertThat(propertySource.getSource().size()).isEqualTo(2);
assertThat(propertySource.getSource().get("username")).isEqualTo("user");
assertThat(propertySource.getSource().get("password")).isEqualTo("p455w0rd");
}
if (propertySource.getName().equals("configmap.stores.default")) {
assertThat(propertySource.getSource().size()).isEqualTo(3);
assertThat(propertySource.getSource().get("dummy.property.int2")).isEqualTo(1);
assertThat(propertySource.getSource().get("dummy.property.bool2")).isEqualTo(true);
assertThat(propertySource.getSource().get("dummy.property.string2")).isEqualTo("a");
}
if (propertySource.getName().equals("configmap.stores.dev")) {
assertThat(propertySource.getSource().size()).isEqualTo(3);
assertThat(propertySource.getSource().get("dummy.property.int2")).isEqualTo(1);
assertThat(propertySource.getSource().get("dummy.property.bool2")).isEqualTo(true);
assertThat(propertySource.getSource().get("dummy.property.string2")).isEqualTo("dev");
}
if (propertySource.getName().equals("secret.stores.default")) {
assertThat(propertySource.getSource().size()).isEqualTo(2);
assertThat(propertySource.getSource().get("username")).isEqualTo("stores");
assertThat(propertySource.getSource().get("password")).isEqualTo("password-from-stores");
}
});
}
@Test
public void testStoresProfileCase() throws ApiException {
CoreV1Api coreApi = mock(CoreV1Api.class);
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.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_LIST);
when(coreApi.listNamespacedConfigMap(eq("dev"), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null),
eq(null), eq(null), eq(null), eq(null))).thenReturn(CONFIGMAP_DEV_LIST);
KubernetesEnvironmentRepository environmentRepository = new KubernetesEnvironmentRepository(coreApi,
KUBERNETES_PROPERTY_SOURCE_SUPPLIER, "default");
Environment environment = environmentRepository.findOne("stores", "dev", "");
assertThat(environment.getPropertySources().size()).isEqualTo(5);
environment.getPropertySources().forEach(propertySource -> {
assertThat(propertySource.getName().equals("configmap.application.default")
|| propertySource.getName().equals("secret.application.default")
|| propertySource.getName().equals("configmap.stores.stores-dev.default")
|| propertySource.getName().equals("configmap.stores.dev")
|| propertySource.getName().equals("secret.stores.stores-dev.default")).isTrue();
if (propertySource.getName().equals("configmap.application.default")) {
assertThat(propertySource.getSource().size()).isEqualTo(3);
assertThat(propertySource.getSource().get("dummy.property.int2")).isEqualTo(1);
assertThat(propertySource.getSource().get("dummy.property.bool2")).isEqualTo(true);
assertThat(propertySource.getSource().get("dummy.property.string2")).isEqualTo("a");
}
else if (propertySource.getName().equals("secret.application.default")) {
assertThat(propertySource.getSource().size()).isEqualTo(2);
assertThat(propertySource.getSource().get("username")).isEqualTo("user");
assertThat(propertySource.getSource().get("password")).isEqualTo("p455w0rd");
}
else if (propertySource.getName().equals("configmap.stores.stores-dev.default")) {
assertThat(propertySource.getSource().size()).isEqualTo(4);
assertThat(propertySource.getSource().get("dummy.property.int2")).isEqualTo(2);
assertThat(propertySource.getSource().get("dummy.property.bool2")).isEqualTo(false);
assertThat(propertySource.getSource().get("dummy.property.string2")).isEqualTo("b");
assertThat(propertySource.getSource().get("dummy.property.string1")).isEqualTo("a");
}
else if (propertySource.getName().equals("configmap.stores.dev")) {
assertThat(propertySource.getSource().size()).isEqualTo(3);
assertThat(propertySource.getSource().get("dummy.property.int2")).isEqualTo(1);
assertThat(propertySource.getSource().get("dummy.property.bool2")).isEqualTo(true);
assertThat(propertySource.getSource().get("dummy.property.string2")).isEqualTo("dev");
}
else if (propertySource.getName().equals("secret.stores.stores-dev.default")) {
assertThat(propertySource.getSource().size()).isEqualTo(2);
assertThat(propertySource.getSource().get("username")).isEqualTo("stores-dev");
assertThat(propertySource.getSource().get("password")).isEqualTo("password-from-stores-dev");
}
else {
Assertions.fail("no match in property source names");
}
});
}
@Test
public void testApplicationPropertiesAnSecretsOverride() throws ApiException {
CoreV1Api coreApi = mock(CoreV1Api.class);
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.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_LIST);
when(coreApi.listNamespacedConfigMap(eq("dev"), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null),
eq(null), eq(null), eq(null), eq(null))).thenReturn(CONFIGMAP_DEV_LIST);
KubernetesEnvironmentRepository environmentRepository = new KubernetesEnvironmentRepository(coreApi,
KUBERNETES_PROPERTY_SOURCE_SUPPLIER, "default");
Environment environment = environmentRepository.findOne("stores-dev", "", "");
environment.getPropertySources().stream()
.filter(propertySource -> propertySource.getName().startsWith("configmap"))
.reduce((first, second) -> second).ifPresent(propertySource -> {
assertThat(propertySource.getName()).isEqualTo("configmap.application.default");
});
environment.getPropertySources().stream()
.filter(propertySource -> propertySource.getName().startsWith("configmap")).findFirst()
.ifPresent(propertySource -> {
assertThat(propertySource.getSource().get("dummy.property.int2")).isEqualTo(2);
assertThat(propertySource.getSource().get("dummy.property.bool2")).isEqualTo(false);
assertThat(propertySource.getSource().get("dummy.property.string2")).isEqualTo("b");
});
environment.getPropertySources().stream()
.filter(propertySource -> propertySource.getName().startsWith("secrets")).findFirst()
.ifPresent(propertySource -> {
assertThat(propertySource.getSource().get("username")).isEqualTo("stores-dev");
assertThat(propertySource.getSource().get("password")).isEqualTo("p455w0rd");
});
}
}

View File

@@ -1,184 +0,0 @@
/*
* 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();
}
}

View File

@@ -1,35 +0,0 @@
/*
* Copyright 2013-2022 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 org.springframework.cloud.config.server.environment.EnvironmentRepository;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import static org.mockito.Mockito.mock;
@Configuration
class MockConfig {
@Bean
@Profile("kubernetesdisabled")
public EnvironmentRepository environmentRepository() {
return mock(EnvironmentRepository.class);
}
}

View File

@@ -1,54 +0,0 @@
/*
* 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 com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.client.WireMock;
import io.kubernetes.client.openapi.ApiClient;
import io.kubernetes.client.openapi.apis.CoreV1Api;
import io.kubernetes.client.util.ClientBuilder;
import org.springframework.context.annotation.Bean;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
/**
* @author Ryan Baxter
*/
public class TestBootstrapConfig {
@Bean
WireMockServer wireMockServer() {
WireMockServer wireMockServer = new WireMockServer(options().dynamicPort());
wireMockServer.start();
WireMock.configureFor(wireMockServer.port());
return wireMockServer;
}
@Bean
ApiClient apiClient(WireMockServer wireMockServer) {
ApiClient apiClient = new ClientBuilder().setBasePath(wireMockServer.baseUrl()).build();
apiClient.setDebugging(true);
return apiClient;
}
@Bean
CoreV1Api coreApi(ApiClient apiClient) {
return new CoreV1Api(apiClient);
}
}

View File

@@ -1,2 +0,0 @@
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
org.springframework.cloud.kubernetes.configserver.TestBootstrapConfig

View File

@@ -1 +0,0 @@
org.springframework.cloud.kubernetes.configserver.KubernetesConfigServerAutoConfiguration