Initial commit
This commit is contained in:
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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()));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
org.springframework.cloud.kubernetes.configserver.KubernetesConfigServerAutoConfiguration
|
||||
@@ -1,13 +0,0 @@
|
||||
spring:
|
||||
application:
|
||||
name: kubernetesconfigserver
|
||||
|
||||
server:
|
||||
port: 8888
|
||||
|
||||
---
|
||||
spring:
|
||||
config:
|
||||
activate:
|
||||
on-cloud-platform: kubernetes
|
||||
import: "optional:kubernetes:"
|
||||
@@ -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 {
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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");
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
|
||||
org.springframework.cloud.kubernetes.configserver.TestBootstrapConfig
|
||||
@@ -1 +0,0 @@
|
||||
org.springframework.cloud.kubernetes.configserver.KubernetesConfigServerAutoConfiguration
|
||||
Reference in New Issue
Block a user