Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -470,12 +470,12 @@ Consumers should not be directly aware whether a variable is protected or not.

> But your CICD code that uses the **envvars** library will need to specially map the secret data as part of its output generation.

## Define ConfigMaps
## Define References
> Work in Progress

Secrets are private variables having values that are expected to actually be indirect references to protected data stored somewhere else.

ConfigMaps are public variables having values that are expected to actually be indirect references to public data stores somewhere else.
References are public variables having values that are expected to actually be indirect references to public data stores somewhere else.

## Allowing Missing Declarations
Is a missing declaration a defect? Opinions vary. The **envvars* library lets you choose your own side on the "missing means error" vs "missing means default" argument.
Expand Down Expand Up @@ -634,7 +634,7 @@ The constrained features for each node are:
* Remap
* SkipInjectIfNotDefined
* DefineSecrets
* DefineConfigMaps
* DefineReferences


## Schema Variable Constraints
Expand Down
2 changes: 1 addition & 1 deletion envvars-cli/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<parent>
<groupId>com.optum.envvars</groupId>
<artifactId>envvars</artifactId>
<version>2.3.X-SNAPSHOT</version>
<version>3.0.X-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
19 changes: 17 additions & 2 deletions envvars-cli/src/main/java/com/optum/envvars/cli/EnvVars.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.optum.envvars.cli;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.optum.envvars.EnvVar;
import com.optum.envvars.EnvVarsEngine;
import com.optum.envvars.EnvVarsException;
import com.optum.envvars.mapdata.EnvVarsMapDataReader;
Expand All @@ -10,6 +11,8 @@
import com.optum.envvars.mapdata.yaml.YamlLoadWrapper;
import org.yaml.snakeyaml.Yaml;

import java.util.TreeMap;

public class EnvVars {

public static void main(String[] args) {
Expand All @@ -28,8 +31,20 @@ public static void main(String[] args) {
}
envVarEngine.add(new ScriptableEnvVarMapDataSource(values, args[i], envVarsMapDataReader));
}
envVarEngine.process();
System.out.println(envVarEngine.toJSON());
TreeMap<String, EnvVar> envvars = envVarEngine.generateResults();
for(EnvVar envvar : envvars.values()) {
StringBuilder sb = new StringBuilder();
sb.append(envvar.getKey());
sb.append("=");
if (envvar.isSecret()) {
sb.append("?");
} else if (envvar.isReference()) {
sb.append(">");
}
sb.append("=");
sb.append(envvar.getKey());
System.out.println(sb.toString());
}
} catch (EnvVarsException e) {
System.out.println(e.getMessage());
Throwable cause = e.getCause();
Expand Down
4 changes: 2 additions & 2 deletions envvars-json/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<parent>
<groupId>com.optum.envvars</groupId>
<artifactId>envvars</artifactId>
<version>2.3.X-SNAPSHOT</version>
<version>3.0.X-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand All @@ -28,7 +28,7 @@
<dependency>
<groupId>com.optum.envvars</groupId>
<artifactId>envvars-lib</artifactId>
<version>2.3.X-SNAPSHOT</version>
<version>3.0.X-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
Expand Down
2 changes: 1 addition & 1 deletion envvars-lib/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<parent>
<groupId>com.optum.envvars</groupId>
<artifactId>envvars</artifactId>
<version>2.3.X-SNAPSHOT</version>
<version>3.0.X-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
4 changes: 2 additions & 2 deletions envvars-lib/src/main/java/com/optum/envvars/EnvVar.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
public interface EnvVar {
String getKey();
String getValue();
String asJSON();
String asConfigMap();
boolean isSecret();
boolean isReference();
}
115 changes: 12 additions & 103 deletions envvars-lib/src/main/java/com/optum/envvars/EnvVarsEngine.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.optum.envvars;

import com.optum.envvars.impl.ConfigMapEnvVar;
import com.optum.envvars.impl.ReferenceEnvVar;
import com.optum.envvars.impl.SecretEnvVar;
import com.optum.envvars.impl.SimpleEnvVar;
import com.optum.envvars.key.KeySourceOfTruth;
Expand All @@ -13,48 +13,12 @@

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;
import java.util.TreeMap;

/**
* This is a Builder Class to control how Environment Variables are gathered
* from various sources and ultimately converted into the JSON format to be injected into the Deployment Configuration
* of a cloud provider.
* <p>
* There is a conceptual state machine for the overall usage flow for EnvVars.
* <p>
* This is the timeline:
* 1) "Pre" phase
* 2) Invoking a "Convert" method
* 3) Normal phase
* <p>
* The "Pre" phase is when EnvVars is gathering a working map.
* The "Convert" phase is when the working map is converted into the final format. This can be done automatically, or
* manually (when data conversion of the working map is desired).
* The Normal phase builds the actual EnvVar set. The EnvVar set is meant to be immutable and write-only (not readable).
* It is not write-once (you can change values) but you can't inspect the Normal phase EnvVar set. This is intentional
* to prevent circular references (for one thing) and generally prevent misuse of the EnvVar set.
* <p>
* NOTE:
* * It is currently possible to call preAdd after the Convert phase, but those changes do not automatically flow
* into the ultimate output.
* * The Convert methods are idempotent, resetting the final data set.
* <p>
* Typical Use Cases
* <p>
* Pre phase is when static-sourced constants are loaded, typically from files. These are layered, with later additions
* overwriting earlier values when keys are the same.
* <p>
* The Normal phase is where dynamically-derived environment variables are added. These can be dynamic based on
* fields from Environment, Component or CloudProvider, as well as based on static-source constants loaded in the
* Pre phase by using the preGet() method to directly inspect the Pre Map.
*/
public class EnvVarsEngine {
private final KeySourceOfTruth keySourceOfTruth;
private final EnvVarsMapData envVarMapData;
private TreeSet<EnvVar> results;
private final TemplEngine templEngine;

public EnvVarsEngine() {
Expand All @@ -72,7 +36,6 @@ public EnvVarsEngine(KeySourceOfTruth keySourceOfTruth) {
public EnvVarsEngine(KeySourceOfTruth keySourceOfTruth, EnvVarsStaticSets envVarsStaticSets) {
this.keySourceOfTruth = keySourceOfTruth;
this.envVarMapData = new EnvVarsMapData(envVarsStaticSets);
this.results = null;
this.templEngine = new TemplEngine(envVarMapData);
}

Expand All @@ -86,11 +49,6 @@ public void add(EnvVarsMapData envVarMapData) throws EnvVarsException {
throwExceptionIfForeignKeysNotDefined();
}

public void process() throws EnvVarsException {
initNormalPhase();
resolveInjectAndRemap();
}

public Set<String> getForeignKeysFor(String context, boolean required) throws EnvVarsException {
return envVarMapData.getForeignKeysFor(context, required);
}
Expand Down Expand Up @@ -151,16 +109,9 @@ public String generateBridgeValue(String key) throws EnvVarsException {
return null;
}

private void initNormalPhase() {
results = new TreeSet<>();
}
public TreeMap<String, EnvVar> generateResults() throws EnvVarsException {
final TreeMap<String, EnvVar> results = new TreeMap<>();

/**
* This method is the first part of the Convert process. It iterates over all the Refs and add the corresponding
* Defs to the final map set.
* Exception is thrown if a Ref cannot find its matching Def.
*/
private void resolveInjectAndRemap() throws EnvVarsException {
// Local copy of remaps.
Map<String, String> remainingRemaps = new HashMap<>();
remainingRemaps.putAll(envVarMapData.getEnvVarsRemapSet());
Expand All @@ -172,13 +123,14 @@ private void resolveInjectAndRemap() throws EnvVarsException {
final String remapQualifier = remainingRemaps.remove(key);
EnvVar envVar = resolveFromQualifier(key, qualifier, remapQualifier);
if (envVar!=null) {
add(envVar);
results.put(envVar.getKey(), envVar);
}
}

if (!remainingRemaps.isEmpty()) {
throw new EnvVarsException("The following variables were listed in remap blocks but never injected: " + remainingRemaps.keySet());
}
return results;
}

/**
Expand Down Expand Up @@ -224,16 +176,16 @@ private EnvVar resolveFromQualifier(final String reference, final String qualifi
return new SecretEnvVar(reference, val);
}

String configMapValue;
String referenceValue;
if (qualifierToUse != null) {
effectiveReference = reference + " from " + qualifierToUse;
configMapValue = envVarMapData.getEnvVarsDefineConfigMapSet().get(qualifierToUse);
referenceValue = envVarMapData.getEnvVarsDefineReferenceSet().get(qualifierToUse);
} else {
configMapValue = envVarMapData.getEnvVarsDefineConfigMapSet().get(reference);
referenceValue = envVarMapData.getEnvVarsDefineReferenceSet().get(reference);
}
if (configMapValue != null) {
final String val = templEngine.processTemplate(configMapValue);
return new ConfigMapEnvVar(reference, val);
if (referenceValue != null) {
final String val = templEngine.processTemplate(referenceValue);
return new ReferenceEnvVar(reference, val);
}
} catch (MissingKeyTemplException e) {
throw new EnvVarsException("Value is missing for template: {{" + e.getKey() + "}}. If you want it to be optional, an empty value is needed instead of a missing value.");
Expand All @@ -247,47 +199,4 @@ private EnvVar resolveFromQualifier(final String reference, final String qualifi
throw new EnvVarsException("Unable to find " + effectiveReference);
}

public void add(String key, String value) throws EnvVarsException {
add(new SimpleEnvVar(key, value));
}

public TreeSet<EnvVar> getResults() throws EnvVarsException {
validateState();
return results;
}

public String toJSON() throws EnvVarsException {
validateState();
return results.stream()
.map(EnvVar::asJSON)
.collect(Collectors.joining(",\n"));
}

public String toConfigMap() throws EnvVarsException {
validateState();
return results.stream()
.map(EnvVar::asConfigMap)
.filter(Objects::nonNull)
.sorted()
.collect(Collectors.joining("\n"));
}

private void add(EnvVar envVar) throws EnvVarsException {
validateState();
validateContents(envVar);
results.add(envVar);
}

private void validateState() throws EnvVarsException {
if (results == null) {
throw new EnvVarsException("Method not supported before process method is invoked.");
}
}

private void validateContents(EnvVar envVar) throws EnvVarsException {
if (results.contains(envVar)) {
throw new EnvVarsException("EnvVar " + envVar.getKey() + " already exists. Updating is only allowed in Pre phase.");
}
}

}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.optum.envvars.impl;

import com.optum.envvars.EnvVarsException;

public class ReferenceEnvVar extends AbstractEnvVar {

public ReferenceEnvVar(String key, String value) throws EnvVarsException {
super(key, value);
}

@Override
public boolean isSecret() {
return false;
}

@Override
public boolean isReference() {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ public SecretEnvVar(String key, String value) throws EnvVarsException {
super(key, value);
}

public String asJSON() {
return "{ \"name\" : \"" + key + "\", \"valueFrom\" : { \"secretKeyRef\" : { \"name\" : \"secretdata\", \"key\" : \"" + getValueAsJSON() + "\"}}}";
@Override
public boolean isSecret() {
return true;
}

@Override
public String asConfigMap() {
return null;
public boolean isReference() {
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ public SimpleEnvVar(String key, String value) throws EnvVarsException {
super(key, value);
}

public String asJSON() {
return "{ \"name\" : \"" + key + "\", \"value\" : \"" + getValueAsJSON() + "\" }";
@Override
public boolean isSecret() {
return false;
}

@Override
public String asConfigMap() {
return key + "=" + value;
public boolean isReference() {
return false;
}
}
Loading
Loading