Skip to content

Commit

Permalink
Allow setting config values from env variables
Browse files Browse the repository at this point in the history
  • Loading branch information
oneonestar committed Sep 30, 2024
1 parent e86bedf commit 526fb52
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 2 deletions.
19 changes: 19 additions & 0 deletions docs/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,25 @@ directory into the same directory, and update the configuration as needed.
Each component of the Trino Gateway has a corresponding node in the
configuration YAML file.

### Secrets in configuration file

Environment variables can be used as values in the configuration file.
You can manually set an environment variable on the command line.

```shell
export DB_PASSWORD=my-super-secret-pwd
```

To use this variable in the configuration file, you reference it with the
syntax `${ENV:VARIABLE}`. For example:

```yaml
dataStore:
jdbcUrl: jdbc:postgresql://localhost:5432/gateway
user: postgres
password: ${ENV:DB_PASSWORD}
```

### Configure routing rules

Find more information in the [routing rules documentation](routing-rules.md).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,12 @@
import io.trino.gateway.ha.config.HaGatewayConfiguration;
import org.weakref.jmx.guice.MBeanModule;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;

import static io.trino.gateway.baseapp.BaseApp.addModules;
import static io.trino.gateway.ha.util.ConfigurationUtils.replaceEnvironmentVariables;
import static java.lang.String.format;

public class HaGatewayLauncher
Expand Down Expand Up @@ -105,7 +107,8 @@ public static void main(String[] args)
if (args.length != 1) {
throw new IllegalArgumentException("Expected exactly one argument (path of configuration file)");
}
HaGatewayConfiguration haGatewayConfiguration = objectMapper.readValue(new File(args[0]), HaGatewayConfiguration.class);
String config = Files.readString(Path.of(args[0]));
HaGatewayConfiguration haGatewayConfiguration = objectMapper.readValue(replaceEnvironmentVariables(config), HaGatewayConfiguration.class);
List<Module> modules = addModules(haGatewayConfiguration);
new HaGatewayLauncher().start(modules, haGatewayConfiguration);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* 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
*
* http://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 io.trino.gateway.ha.util;

import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static java.lang.String.format;
import static java.util.regex.Matcher.quoteReplacement;

public final class ConfigurationUtils
{
private static final Pattern ENV_PATTERN = Pattern.compile("\\$\\{ENV:([a-zA-Z][a-zA-Z0-9_-]*)}");

private ConfigurationUtils() {}

public static String replaceEnvironmentVariables(String original)
{
return replaceEnvironmentVariables(original, System.getenv());
}

public static String replaceEnvironmentVariables(String original, Map<String, String> environment)
{
StringBuilder result = new StringBuilder();
Matcher matcher = ENV_PATTERN.matcher(original);
while (matcher.find()) {
String envName = matcher.group(1);
String envValue = environment.get(envName);
if (envValue == null) {
throw new IllegalArgumentException(format("Configuration references unset environment variable '%s'", envName));
}
matcher.appendReplacement(result, quoteReplacement(envValue));
}
matcher.appendTail(result);
return result.toString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* 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
*
* http://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 io.trino.gateway.ha.util;

import com.google.common.collect.ImmutableMap;
import org.junit.jupiter.api.Test;

import java.util.Map;

import static io.trino.gateway.ha.util.ConfigurationUtils.replaceEnvironmentVariables;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

final class TestConfigurationUtils
{
private static final String config = """
serverConfig:
http-server.https.keystore.path: certificate.pem
http-server.https.keystore.key: ${ENV:KEYSTORE_KEY}
presetUsers:
api:
password: ${ENV:API_PASSWORD}
privileges: API
""";
private static final String expected = """
serverConfig:
http-server.https.keystore.path: certificate.pem
http-server.https.keystore.key: keystore_12345
presetUsers:
api:
password: api_passw0rd
privileges: API
""";

@Test
void testReplaceEnvironmentVariables()
{
Map<String, String> env = ImmutableMap.<String, String>builder()
.put("KEYSTORE_KEY", "keystore_12345")
.put("API_PASSWORD", "api_passw0rd")
.build();
String result = replaceEnvironmentVariables(config, env);
assertThat(result).isEqualTo(expected);
}

@Test
void testMissingEnvironmentVariables()
{
assertThatThrownBy(() -> replaceEnvironmentVariables(config, ImmutableMap.of()))
.hasMessageStartingWith("Configuration references unset environment variable");
}
}

0 comments on commit 526fb52

Please sign in to comment.