-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Support Kubernetes ConfigMap and Secrets as configuration/value sources
- Loading branch information
Showing
28 changed files
with
1,140 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<parent> | ||
<artifactId>quarkus-kubernetes-config-parent</artifactId> | ||
<groupId>io.quarkus</groupId> | ||
<version>999-SNAPSHOT</version> | ||
</parent> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<artifactId>quarkus-kubernetes-config-deployment</artifactId> | ||
<name>Quarkus - Kubernetes Config - Deployment</name> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>io.quarkus</groupId> | ||
<artifactId>quarkus-kubernetes-client-deployment</artifactId> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>io.quarkus</groupId> | ||
<artifactId>quarkus-kubernetes-config</artifactId> | ||
</dependency> | ||
</dependencies> | ||
|
||
<build> | ||
<plugins> | ||
<plugin> | ||
<artifactId>maven-compiler-plugin</artifactId> | ||
<configuration> | ||
<annotationProcessorPaths> | ||
<path> | ||
<groupId>io.quarkus</groupId> | ||
<artifactId>quarkus-extension-processor</artifactId> | ||
<version>${project.version}</version> | ||
</path> | ||
</annotationProcessorPaths> | ||
</configuration> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
</project> |
20 changes: 20 additions & 0 deletions
20
...ment/src/main/java/io/quarkus/kubernetes/config/deployment/KubernetesConfigProcessor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package io.quarkus.kubernetes.config.deployment; | ||
|
||
import io.quarkus.deployment.annotations.BuildStep; | ||
import io.quarkus.deployment.annotations.ExecutionTime; | ||
import io.quarkus.deployment.annotations.Record; | ||
import io.quarkus.deployment.builditem.RunTimeConfigurationSourceValueBuildItem; | ||
import io.quarkus.kubernetes.client.runtime.KubernetesClientBuildConfig; | ||
import io.quarkus.kubernetes.client.runtime.KubernetesConfigRecorder; | ||
import io.quarkus.kubernetes.client.runtime.KubernetesConfigSourceConfig; | ||
|
||
public class KubernetesConfigProcessor { | ||
|
||
@BuildStep | ||
@Record(ExecutionTime.RUNTIME_INIT) | ||
public RunTimeConfigurationSourceValueBuildItem configure(KubernetesConfigRecorder recorder, | ||
KubernetesConfigSourceConfig config, KubernetesClientBuildConfig clientConfig) { | ||
return new RunTimeConfigurationSourceValueBuildItem( | ||
recorder.configSources(config, clientConfig)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<parent> | ||
<artifactId>quarkus-build-parent</artifactId> | ||
<groupId>io.quarkus</groupId> | ||
<version>999-SNAPSHOT</version> | ||
<relativePath>../../build-parent/pom.xml</relativePath> | ||
</parent> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<artifactId>quarkus-kubernetes-config-parent</artifactId> | ||
<name>Quarkus - Kubernetes Config</name> | ||
<packaging>pom</packaging> | ||
<modules> | ||
<module>deployment</module> | ||
<module>runtime</module> | ||
</modules> | ||
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<parent> | ||
<groupId>io.quarkus</groupId> | ||
<artifactId>quarkus-kubernetes-config-parent</artifactId> | ||
<version>999-SNAPSHOT</version> | ||
</parent> | ||
|
||
<artifactId>quarkus-kubernetes-config</artifactId> | ||
<name>Quarkus - Kubernetes Config - Runtime</name> | ||
<description>Read runtime configuration from Kubernetes ConfigMaps and Secrets</description> | ||
<dependencies> | ||
<dependency> | ||
<groupId>io.quarkus</groupId> | ||
<artifactId>quarkus-kubernetes-client</artifactId> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>org.junit.jupiter</groupId> | ||
<artifactId>junit-jupiter</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.assertj</groupId> | ||
<artifactId>assertj-core</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
|
||
<build> | ||
<plugins> | ||
<plugin> | ||
<groupId>io.quarkus</groupId> | ||
<artifactId>quarkus-bootstrap-maven-plugin</artifactId> | ||
</plugin> | ||
<plugin> | ||
<artifactId>maven-compiler-plugin</artifactId> | ||
<configuration> | ||
<annotationProcessorPaths> | ||
<path> | ||
<groupId>io.quarkus</groupId> | ||
<artifactId>quarkus-extension-processor</artifactId> | ||
<version>${project.version}</version> | ||
</path> | ||
</annotationProcessorPaths> | ||
</configuration> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
|
||
|
||
</project> |
110 changes: 110 additions & 0 deletions
110
...rc/main/java/io/quarkus/kubernetes/client/runtime/AbstractKubernetesConfigSourceUtil.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
package io.quarkus.kubernetes.client.runtime; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Collections; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
import org.eclipse.microprofile.config.spi.ConfigSource; | ||
import org.jboss.logging.Logger; | ||
|
||
abstract class AbstractKubernetesConfigSourceUtil { | ||
|
||
private static final Logger log = Logger.getLogger(AbstractKubernetesConfigSourceUtil.class); | ||
|
||
private static final String APPLICATION_YML = "application.yml"; | ||
private static final String APPLICATION_YAML = "application.yaml"; | ||
private static final String APPLICATION_PROPERTIES = "application.properties"; | ||
|
||
private static final int ORDINAL = 270; // this is higher than the file system or jar ordinals, but lower than env vars | ||
|
||
abstract String getType(); | ||
|
||
abstract ConfigSource createLiteralDataConfigSource(String kubernetesConfigSourceName, Map<String, String> propertyMap, | ||
int ordinal); | ||
|
||
abstract ConfigSource createPropertiesConfigSource(String kubernetesConfigSourceName, String fileName, String input, | ||
int ordinal); | ||
|
||
abstract ConfigSource createYamlConfigSource(String kubernetesConfigSourceName, String fileName, String input, int ordinal); | ||
|
||
/** | ||
* Returns a list of {@code ConfigSource} for the literal data that is contained in the ConfigMap | ||
* and for the application.{properties|yaml|yml} files that might be contained in it as well | ||
* | ||
* All the {@code ConfigSource} objects use the same ordinal which is higher than the ordinal | ||
* of normal configuration files, but lower than that of environment variables | ||
*/ | ||
List<ConfigSource> toConfigSources(String kubernetesConfigSourceName, Map<String, String> kubernetesConfigSourceDataMap) { | ||
if (log.isDebugEnabled()) { | ||
log.debug("Attempting to convert data in " + getType() + " '" + kubernetesConfigSourceName | ||
+ "' to a list of ConfigSource objects"); | ||
} | ||
|
||
CategorizedConfigSourceData categorizedConfigSourceData = categorize(kubernetesConfigSourceDataMap); | ||
List<ConfigSource> result = new ArrayList<>(categorizedConfigSourceData.fileData.size() + 1); | ||
|
||
if (!categorizedConfigSourceData.literalData.isEmpty()) { | ||
if (log.isDebugEnabled()) { | ||
log.debug( | ||
"Adding a ConfigSource for the literal data of " + getType() + " '" + kubernetesConfigSourceName + "'"); | ||
} | ||
result.add(createLiteralDataConfigSource(kubernetesConfigSourceName + "-literalData", | ||
categorizedConfigSourceData.literalData, | ||
ORDINAL)); | ||
} | ||
for (Map.Entry<String, String> entry : categorizedConfigSourceData.fileData) { | ||
String fileName = entry.getKey(); | ||
String rawFileData = entry.getValue(); | ||
if (APPLICATION_PROPERTIES.equals(fileName)) { | ||
if (log.isDebugEnabled()) { | ||
log.debug("Adding a Properties ConfigSource for file '" + fileName + "' of " + getType() | ||
+ " '" + kubernetesConfigSourceName + "'"); | ||
} | ||
result.add(createPropertiesConfigSource(kubernetesConfigSourceName, fileName, rawFileData, ORDINAL)); | ||
} else if (APPLICATION_YAML.equals(fileName) || APPLICATION_YML.equals(fileName)) { | ||
if (log.isDebugEnabled()) { | ||
log.debug("Adding a YAML ConfigSource for file '" + fileName + "' of " + getType() | ||
+ " '" + kubernetesConfigSourceName + "'"); | ||
} | ||
result.add(createYamlConfigSource(kubernetesConfigSourceName, fileName, rawFileData, ORDINAL)); | ||
} | ||
} | ||
|
||
if (log.isDebugEnabled()) { | ||
log.debug(getType() + " '" + kubernetesConfigSourceName + "' converted into " + result.size() | ||
+ "ConfigSource objects"); | ||
} | ||
return result; | ||
} | ||
|
||
private static CategorizedConfigSourceData categorize(Map<String, String> data) { | ||
if ((data == null) || data.isEmpty()) { | ||
return new CategorizedConfigSourceData(Collections.emptyMap(), Collections.emptyList()); | ||
} | ||
|
||
Map<String, String> literalData = new HashMap<>(); | ||
List<Map.Entry<String, String>> fileData = new ArrayList<>(); | ||
for (Map.Entry<String, String> entry : data.entrySet()) { | ||
String key = entry.getKey(); | ||
if (key.endsWith(".yml") || key.endsWith(".yaml") || key.endsWith(".properties")) { | ||
fileData.add(entry); | ||
} else { | ||
literalData.put(key, entry.getValue()); | ||
} | ||
} | ||
|
||
return new CategorizedConfigSourceData(literalData, fileData); | ||
} | ||
|
||
private static class CategorizedConfigSourceData { | ||
final Map<String, String> literalData; | ||
final List<Map.Entry<String, String>> fileData; | ||
|
||
CategorizedConfigSourceData(Map<String, String> literalData, List<Map.Entry<String, String>> fileData) { | ||
this.literalData = literalData; | ||
this.fileData = fileData; | ||
} | ||
} | ||
} |
74 changes: 74 additions & 0 deletions
74
...runtime/src/main/java/io/quarkus/kubernetes/client/runtime/ConfigMapConfigSourceUtil.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package io.quarkus.kubernetes.client.runtime; | ||
|
||
import java.io.IOException; | ||
import java.io.StringReader; | ||
import java.io.UncheckedIOException; | ||
import java.util.Map; | ||
import java.util.Properties; | ||
|
||
import org.eclipse.microprofile.config.spi.ConfigSource; | ||
|
||
import io.smallrye.config.common.MapBackedConfigSource; | ||
import io.smallrye.config.source.yaml.YamlConfigSource; | ||
|
||
public class ConfigMapConfigSourceUtil extends AbstractKubernetesConfigSourceUtil { | ||
|
||
@Override | ||
String getType() { | ||
return "ConfigMap"; | ||
} | ||
|
||
@Override | ||
ConfigSource createLiteralDataConfigSource(String kubernetesConfigSourceName, Map<String, String> propertyMap, | ||
int ordinal) { | ||
return new ConfigMapLiteralDataPropertiesConfigSource(kubernetesConfigSourceName, propertyMap, ordinal); | ||
} | ||
|
||
@Override | ||
ConfigSource createPropertiesConfigSource(String kubernetesConfigSourceName, String fileName, String input, int ordinal) { | ||
return new ConfigMapStringInputPropertiesConfigSource(kubernetesConfigSourceName, fileName, input, ordinal); | ||
} | ||
|
||
@Override | ||
ConfigSource createYamlConfigSource(String kubernetesConfigSourceName, String fileName, String input, int ordinal) { | ||
return new ConfigMapStringInputYamlConfigSource(kubernetesConfigSourceName, fileName, input, ordinal); | ||
} | ||
|
||
private static final class ConfigMapLiteralDataPropertiesConfigSource extends MapBackedConfigSource { | ||
|
||
private static final String NAME_PREFIX = "ConfigMapLiteralDataPropertiesConfigSource[configMap="; | ||
|
||
public ConfigMapLiteralDataPropertiesConfigSource(String configMapName, Map<String, String> propertyMap, int ordinal) { | ||
super(NAME_PREFIX + configMapName + "]", propertyMap, ordinal); | ||
} | ||
} | ||
|
||
private static class ConfigMapStringInputPropertiesConfigSource extends MapBackedConfigSource { | ||
|
||
private static final String NAME_FORMAT = "ConfigMapStringInputPropertiesConfigSource[configMap=%s,file=%s]"; | ||
|
||
ConfigMapStringInputPropertiesConfigSource(String configMapName, String fileName, String input, int ordinal) { | ||
super(String.format(NAME_FORMAT, configMapName, fileName), readProperties(input), ordinal); | ||
} | ||
|
||
@SuppressWarnings({ "rawtypes", "unchecked" }) | ||
private static Map<String, String> readProperties(String rawData) { | ||
try (StringReader br = new StringReader(rawData)) { | ||
final Properties properties = new Properties(); | ||
properties.load(br); | ||
return (Map<String, String>) (Map) properties; | ||
} catch (IOException e) { | ||
throw new UncheckedIOException(e); | ||
} | ||
} | ||
} | ||
|
||
private static class ConfigMapStringInputYamlConfigSource extends YamlConfigSource { | ||
|
||
private static final String NAME_FORMAT = "ConfigMapStringInputYamlConfigSource[configMap=%s,file=%s]"; | ||
|
||
public ConfigMapStringInputYamlConfigSource(String configMapName, String fileName, String input, int ordinal) { | ||
super(String.format(NAME_FORMAT, configMapName, fileName), input, ordinal); | ||
} | ||
} | ||
} |
Oops, something went wrong.