HADOOP-17631. Configuration ${env.VAR:-FALLBACK} to eval FALLBACK when restrictSystemProps=true (#2977)
Contributed by Steve Loughran. Change-Id: I9b82109eddeb659c01896152cf603d458e2a04cd
This commit is contained in:
parent
02249171b1
commit
4ac9123619
@ -1139,36 +1139,37 @@ private String substituteVars(String expr) {
|
|||||||
final String var = eval.substring(varBounds[SUB_START_IDX],
|
final String var = eval.substring(varBounds[SUB_START_IDX],
|
||||||
varBounds[SUB_END_IDX]);
|
varBounds[SUB_END_IDX]);
|
||||||
String val = null;
|
String val = null;
|
||||||
if (!restrictSystemProps) {
|
try {
|
||||||
try {
|
// evaluate system properties or environment variables even when
|
||||||
if (var.startsWith("env.") && 4 < var.length()) {
|
// the configuration is restricted -the restrictions are enforced
|
||||||
String v = var.substring(4);
|
// in the getenv/getProperty calls
|
||||||
int i = 0;
|
if (var.startsWith("env.") && 4 < var.length()) {
|
||||||
for (; i < v.length(); i++) {
|
String v = var.substring(4);
|
||||||
char c = v.charAt(i);
|
int i = 0;
|
||||||
if (c == ':' && i < v.length() - 1 && v.charAt(i + 1) == '-') {
|
for (; i < v.length(); i++) {
|
||||||
val = getenv(v.substring(0, i));
|
char c = v.charAt(i);
|
||||||
if (val == null || val.length() == 0) {
|
if (c == ':' && i < v.length() - 1 && v.charAt(i + 1) == '-') {
|
||||||
val = v.substring(i + 2);
|
val = getenv(v.substring(0, i));
|
||||||
}
|
if (val == null || val.length() == 0) {
|
||||||
break;
|
val = v.substring(i + 2);
|
||||||
} else if (c == '-') {
|
|
||||||
val = getenv(v.substring(0, i));
|
|
||||||
if (val == null) {
|
|
||||||
val = v.substring(i + 1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
} else if (c == '-') {
|
||||||
|
val = getenv(v.substring(0, i));
|
||||||
|
if (val == null) {
|
||||||
|
val = v.substring(i + 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (i == v.length()) {
|
|
||||||
val = getenv(v);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
val = getProperty(var);
|
|
||||||
}
|
}
|
||||||
} catch (SecurityException se) {
|
if (i == v.length()) {
|
||||||
LOG.warn("Unexpected SecurityException in Configuration", se);
|
val = getenv(v);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val = getProperty(var);
|
||||||
}
|
}
|
||||||
|
} catch (SecurityException se) {
|
||||||
|
LOG.warn("Unexpected SecurityException in Configuration", se);
|
||||||
}
|
}
|
||||||
if (val == null) {
|
if (val == null) {
|
||||||
val = getRaw(var);
|
val = getRaw(var);
|
||||||
@ -1194,13 +1195,33 @@ private String substituteVars(String expr) {
|
|||||||
throw new IllegalStateException("Variable substitution depth too large: "
|
throw new IllegalStateException("Variable substitution depth too large: "
|
||||||
+ MAX_SUBST + " " + expr);
|
+ MAX_SUBST + " " + expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the environment variable value if
|
||||||
|
* {@link #restrictSystemProps} does not block this.
|
||||||
|
* @param name environment variable name.
|
||||||
|
* @return the value or null if either it is unset or access forbidden.
|
||||||
|
*/
|
||||||
String getenv(String name) {
|
String getenv(String name) {
|
||||||
return System.getenv(name);
|
if (!restrictSystemProps) {
|
||||||
|
return System.getenv(name);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a system property value if
|
||||||
|
* {@link #restrictSystemProps} does not block this.
|
||||||
|
* @param key property key
|
||||||
|
* @return the value or null if either it is unset or access forbidden.
|
||||||
|
*/
|
||||||
String getProperty(String key) {
|
String getProperty(String key) {
|
||||||
return System.getProperty(key);
|
if (!restrictSystemProps) {
|
||||||
|
return System.getProperty(key);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -490,6 +490,62 @@ public void testEnvDefault() throws IOException {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify that when a configuration is restricted, environment
|
||||||
|
* variables and system properties will be unresolved.
|
||||||
|
* The fallback patterns for the variables are still parsed.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testRestrictedEnv() throws IOException {
|
||||||
|
// this test relies on env.PATH being set on all platforms a
|
||||||
|
// test run will take place on, and the java.version sysprop
|
||||||
|
// set in all JVMs.
|
||||||
|
// Restricted configurations will not get access to these values, so
|
||||||
|
// will either be unresolved or, for env vars with fallbacks: the fallback
|
||||||
|
// values.
|
||||||
|
|
||||||
|
conf.setRestrictSystemProperties(true);
|
||||||
|
|
||||||
|
out = new BufferedWriter(new FileWriter(CONFIG));
|
||||||
|
startConfig();
|
||||||
|
// a simple property to reference
|
||||||
|
declareProperty("d", "D", "D");
|
||||||
|
|
||||||
|
// system property evaluation stops working completely
|
||||||
|
declareProperty("system1", "${java.version}", "${java.version}");
|
||||||
|
|
||||||
|
// the env variable does not resolve
|
||||||
|
declareProperty("secret1", "${env.PATH}", "${env.PATH}");
|
||||||
|
|
||||||
|
// but all the fallback options do work
|
||||||
|
declareProperty("secret2", "${env.PATH-a}", "a");
|
||||||
|
declareProperty("secret3", "${env.PATH:-b}", "b");
|
||||||
|
declareProperty("secret4", "${env.PATH:-}", "");
|
||||||
|
declareProperty("secret5", "${env.PATH-}", "");
|
||||||
|
// special case
|
||||||
|
declareProperty("secret6", "${env.PATH:}", "${env.PATH:}");
|
||||||
|
// safety check
|
||||||
|
declareProperty("secret7", "${env.PATH:--}", "-");
|
||||||
|
|
||||||
|
// recursive eval of the fallback
|
||||||
|
declareProperty("secret8", "${env.PATH:-${d}}", "D");
|
||||||
|
|
||||||
|
// if the fallback doesn't resolve, the result is the whole variable raw.
|
||||||
|
declareProperty("secret9", "${env.PATH:-$d}}", "${env.PATH:-$d}}");
|
||||||
|
|
||||||
|
endConfig();
|
||||||
|
Path fileResource = new Path(CONFIG);
|
||||||
|
conf.addResource(fileResource);
|
||||||
|
|
||||||
|
for (Prop p : props) {
|
||||||
|
System.out.println("p=" + p.name);
|
||||||
|
String gotVal = conf.get(p.name);
|
||||||
|
String gotRawVal = conf.getRaw(p.name);
|
||||||
|
assertEq(p.val, gotRawVal);
|
||||||
|
assertEq(p.expectEval, gotVal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFinalParam() throws IOException {
|
public void testFinalParam() throws IOException {
|
||||||
out=new BufferedWriter(new FileWriter(CONFIG));
|
out=new BufferedWriter(new FileWriter(CONFIG));
|
||||||
|
Loading…
Reference in New Issue
Block a user