summaryrefslogtreecommitdiffstats
path: root/node-admin/src
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorncs@verizonmedia.com>2019-08-02 15:58:22 +0200
committerBjørn Christian Seime <bjorncs@verizonmedia.com>2019-08-02 16:01:25 +0200
commitb4ae9b9a122ab0e9d625eef3fd3b426059fd4175 (patch)
tree480defb6c086b60ff39feb8774d980fe27feaea1 /node-admin/src
parent6544cc5228dc104ebc254de04f9b728e1e5312fc (diff)
Add helper to rewrite default-env.txt files
Diffstat (limited to 'node-admin/src')
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/env/DefaultEnvRewriter.java101
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/env/package-info.java8
-rw-r--r--node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/env/DefaultEnvRewriterTest.java48
-rw-r--r--node-admin/src/test/resources/default-env-example.txt5
-rw-r--r--node-admin/src/test/resources/default-env-rewritten.txt4
5 files changed, 166 insertions, 0 deletions
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/env/DefaultEnvRewriter.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/env/DefaultEnvRewriter.java
new file mode 100644
index 00000000000..7a6c5d23bc1
--- /dev/null
+++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/env/DefaultEnvRewriter.java
@@ -0,0 +1,101 @@
+// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.hosted.node.admin.task.util.env;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+/**
+ * Rewrites default-env.txt files.
+ *
+ * @author bjorncs
+ */
+public class DefaultEnvRewriter {
+
+ private final Map<String, Operation> operations = new TreeMap<>();
+ private final Path defaultEnvFile;
+
+ public DefaultEnvRewriter(Path defaultEnvFile) {
+ this.defaultEnvFile = defaultEnvFile;
+ }
+
+ public DefaultEnvRewriter addOverride(String name, String value) {
+ return addOperation("override", name, value);
+ }
+
+ public DefaultEnvRewriter addFallback(String name, String value) {
+ return addOperation("fallback", name, value);
+ }
+
+ public DefaultEnvRewriter addUnset(String name) {
+ return addOperation("unset", name, null);
+ }
+
+ private DefaultEnvRewriter addOperation(String action, String name, String value) {
+ if (operations.containsKey(name)) {
+ throw new IllegalArgumentException(String.format("Operation on variable '%s' already added", name));
+ }
+ operations.put(name, new Operation(action, name, value));
+ return this;
+ }
+
+ public boolean converge() throws IOException {
+ List<String> defaultEnvLines = Files.readAllLines(defaultEnvFile);
+ List<String> newDefaultEnvLines = new ArrayList<>();
+ Set<String> seenNames = new TreeSet<>();
+ for (String line : defaultEnvLines) {
+ String[] items = line.split(" ");
+ if (items.length < 2) {
+ throw new IllegalArgumentException(String.format("Invalid line in file '%s': %s", defaultEnvFile, line));
+ }
+ String name = items[1];
+ if (!seenNames.contains(name)) { // implicitly removes duplicated variables
+ seenNames.add(name);
+ Operation operation = operations.get(name);
+ if (operation != null) {
+ newDefaultEnvLines.add(operation.toLine());
+ } else {
+ newDefaultEnvLines.add(line);
+ }
+ }
+ }
+ for (var operation : operations.values()) {
+ if (!seenNames.contains(operation.name)) {
+ newDefaultEnvLines.add(operation.toLine());
+ }
+ }
+ if (defaultEnvLines.equals(newDefaultEnvLines)) {
+ return false;
+ } else {
+ Files.write(defaultEnvFile, newDefaultEnvLines);
+ return true;
+ }
+ }
+
+ private static class Operation {
+ final String action;
+ final String name;
+ final String value;
+
+ Operation(String action, String name, String value) {
+ this.action = action;
+ this.name = name;
+ this.value = value;
+ }
+
+ String toLine() {
+ if (action.equals("unset")) {
+ return "unset " + name;
+ }
+ return action + " " + name + " " + value;
+ }
+ }
+}
+
+
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/env/package-info.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/env/package-info.java
new file mode 100644
index 00000000000..cd42fbed899
--- /dev/null
+++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/env/package-info.java
@@ -0,0 +1,8 @@
+// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+/**
+ * @author bjorncs
+ */
+@ExportPackage
+package com.yahoo.vespa.hosted.node.admin.task.util.env;
+
+import com.yahoo.osgi.annotation.ExportPackage; \ No newline at end of file
diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/env/DefaultEnvRewriterTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/env/DefaultEnvRewriterTest.java
new file mode 100644
index 00000000000..2f24af37b71
--- /dev/null
+++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/env/DefaultEnvRewriterTest.java
@@ -0,0 +1,48 @@
+// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.hosted.node.admin.task.util.env;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author bjorncs
+ */
+public class DefaultEnvRewriterTest {
+
+ @Rule
+ public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+ private static final Path EXAMPLE_FILE = Paths.get(DefaultEnvRewriterTest.class.getResource("/default-env-example.txt").getFile());
+ private static final Path EXPECTED_RESULT_FILE = Paths.get(DefaultEnvRewriterTest.class.getResource("/default-env-rewritten.txt").getFile());
+
+ @Test
+ public void default_env_is_correctly_rewritten() throws IOException {
+ Path tempFile = temporaryFolder.newFile().toPath();
+ Files.copy(EXAMPLE_FILE, tempFile, REPLACE_EXISTING);
+
+ DefaultEnvRewriter rewriter = new DefaultEnvRewriter(tempFile);
+ rewriter.addOverride("VESPA_HOSTNAME", "my-new-hostname");
+ rewriter.addFallback("VESPA_CONFIGSERVER", "new-fallback-configserver");
+ rewriter.addOverride("VESPA_TLS_CONFIG_FILE", "/override/path/to/config.file");
+
+ boolean converged = rewriter.converge();
+
+ assertTrue(converged);
+ assertEquals(Files.readString(EXPECTED_RESULT_FILE), Files.readString(tempFile));
+
+ converged = rewriter.converge();
+ assertFalse(converged);
+ assertEquals(Files.readString(EXPECTED_RESULT_FILE), Files.readString(tempFile));
+ }
+} \ No newline at end of file
diff --git a/node-admin/src/test/resources/default-env-example.txt b/node-admin/src/test/resources/default-env-example.txt
new file mode 100644
index 00000000000..debae073271
--- /dev/null
+++ b/node-admin/src/test/resources/default-env-example.txt
@@ -0,0 +1,5 @@
+override VESPA_HOSTNAME myhostname
+fallback VESPA_CONFIGSERVER fallback-configserver
+fallback VESPA_TLS_CONFIG_FILE /fallback/path/to/config.file
+unset VESPA_LEGACY_OPTION
+fallback VESPA_LEGACY_OPTION duplicated-variable \ No newline at end of file
diff --git a/node-admin/src/test/resources/default-env-rewritten.txt b/node-admin/src/test/resources/default-env-rewritten.txt
new file mode 100644
index 00000000000..94a91f4e793
--- /dev/null
+++ b/node-admin/src/test/resources/default-env-rewritten.txt
@@ -0,0 +1,4 @@
+override VESPA_HOSTNAME my-new-hostname
+fallback VESPA_CONFIGSERVER new-fallback-configserver
+override VESPA_TLS_CONFIG_FILE /override/path/to/config.file
+unset VESPA_LEGACY_OPTION