This is an automated email from the ASF dual-hosted git repository. dlmarion pushed a commit to branch 2.1 in repository https://gitbox.apache.org/repos/asf/accumulo.git
The following commit(s) were added to refs/heads/2.1 by this push: new ed4161ea21 Restrict group names in cluster.yaml to valid bash var name characters (#5038) ed4161ea21 is described below commit ed4161ea21dd9b7293be0ca72bc3651d65513440 Author: Dave Marion <dlmar...@apache.org> AuthorDate: Thu Nov 7 16:10:07 2024 -0500 Restrict group names in cluster.yaml to valid bash var name characters (#5038) Closes #5033 --- .../core/conf/cluster/ClusterConfigParser.java | 33 +++++++++++++++++----- .../core/conf/cluster/ClusterConfigParserTest.java | 17 +++++++++++ 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/org/apache/accumulo/core/conf/cluster/ClusterConfigParser.java b/core/src/main/java/org/apache/accumulo/core/conf/cluster/ClusterConfigParser.java index 9f904d5b1c..dcc3d469e2 100644 --- a/core/src/main/java/org/apache/accumulo/core/conf/cluster/ClusterConfigParser.java +++ b/core/src/main/java/org/apache/accumulo/core/conf/cluster/ClusterConfigParser.java @@ -30,6 +30,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.Predicate; +import java.util.regex.Pattern; import java.util.stream.Collectors; import org.yaml.snakeyaml.Yaml; @@ -38,6 +39,17 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; public class ClusterConfigParser { + private static final Pattern GROUP_NAME_PATTERN = + Pattern.compile("^[a-zA-Z_]{1,}[a-zA-Z0-9_]{0,}$"); + + public static void validateGroupNames(Set<String> names) { + for (String name : names) { + if (!GROUP_NAME_PATTERN.matcher(name).matches()) { + throw new RuntimeException("Group name: " + name + " contains invalid characters"); + } + } + } + private static final String PROPERTY_FORMAT = "%s=\"%s\"%n"; private static final String[] SECTIONS = new String[] {"manager", "monitor", "gc", "tserver"}; @@ -123,6 +135,7 @@ public class ClusterConfigParser { Set<String> compactorQueues = config.keySet().stream().filter(k -> k.startsWith(compactorPrefix)) .map(k -> k.substring(compactorPrefix.length())).collect(Collectors.toSet()); + validateGroupNames(compactorQueues); if (!compactorQueues.isEmpty()) { out.printf(PROPERTY_FORMAT, "COMPACTION_QUEUES", @@ -138,6 +151,7 @@ public class ClusterConfigParser { String sserverPrefix = "sserver."; Set<String> sserverGroups = config.keySet().stream().filter(k -> k.startsWith(sserverPrefix)) .map(k -> k.substring(sserverPrefix.length())).collect(Collectors.toSet()); + validateGroupNames(sserverGroups); if (!sserverGroups.isEmpty()) { out.printf(PROPERTY_FORMAT, "SSERVER_GROUPS", @@ -162,14 +176,19 @@ public class ClusterConfigParser { System.exit(1); } - if (args.length == 2) { - // Write to a file instead of System.out if provided as an argument - try (OutputStream os = Files.newOutputStream(Paths.get(args[1]), StandardOpenOption.CREATE); - PrintStream out = new PrintStream(os)) { - outputShellVariables(parseConfiguration(args[0]), new PrintStream(out)); + try { + if (args.length == 2) { + // Write to a file instead of System.out if provided as an argument + try (OutputStream os = Files.newOutputStream(Paths.get(args[1]), StandardOpenOption.CREATE); + PrintStream out = new PrintStream(os)) { + outputShellVariables(parseConfiguration(args[0]), new PrintStream(out)); + } + } else { + outputShellVariables(parseConfiguration(args[0]), System.out); } - } else { - outputShellVariables(parseConfiguration(args[0]), System.out); + } catch (Exception e) { + System.err.println("Processing error: " + e.getMessage()); + System.exit(1); } } diff --git a/core/src/test/java/org/apache/accumulo/core/conf/cluster/ClusterConfigParserTest.java b/core/src/test/java/org/apache/accumulo/core/conf/cluster/ClusterConfigParserTest.java index f0f27e629f..9777abc9b9 100644 --- a/core/src/test/java/org/apache/accumulo/core/conf/cluster/ClusterConfigParserTest.java +++ b/core/src/test/java/org/apache/accumulo/core/conf/cluster/ClusterConfigParserTest.java @@ -35,6 +35,7 @@ import java.nio.file.Files; import java.nio.file.Paths; import java.util.HashMap; import java.util.Map; +import java.util.Set; import java.util.function.Function; import org.junit.jupiter.api.Test; @@ -271,4 +272,20 @@ public class ClusterConfigParserTest { assertTrue(exception.getMessage().contains("vserver")); } } + + @Test + public void testGroupNamePattern() { + ClusterConfigParser.validateGroupNames(Set.of("a")); + ClusterConfigParser.validateGroupNames(Set.of("a", "b")); + ClusterConfigParser.validateGroupNames(Set.of("default", "reg_ular")); + ClusterConfigParser.validateGroupNames(Set.of("a1b2c3d4__")); + assertThrows(RuntimeException.class, + () -> ClusterConfigParser.validateGroupNames(Set.of("0abcde"))); + assertThrows(RuntimeException.class, + () -> ClusterConfigParser.validateGroupNames(Set.of("a-b"))); + assertThrows(RuntimeException.class, + () -> ClusterConfigParser.validateGroupNames(Set.of("a*b"))); + assertThrows(RuntimeException.class, + () -> ClusterConfigParser.validateGroupNames(Set.of("a?b"))); + } }