Skip to content

Commit

Permalink
Ensure initial_master_nodes includes only master-eligible nodes (#93212
Browse files Browse the repository at this point in the history
…) (#93216)
  • Loading branch information
mark-vieira authored Jan 25, 2023
1 parent dde306c commit ac60b59
Showing 2 changed files with 57 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -65,8 +65,20 @@ public Map<String, String> get(LocalNodeSpec nodeSpec) {
settings.put("action.destructive_requires_name", "false");

// Setup cluster discovery
String nodeNames = nodeSpec.getCluster().getNodes().stream().map(LocalNodeSpec::getName).collect(Collectors.joining(","));
settings.put("cluster.initial_master_nodes", "[" + nodeNames + "]");
String masterEligibleNodes = nodeSpec.getCluster()
.getNodes()
.stream()
.filter(LocalNodeSpec::isMasterEligible)
.map(LocalNodeSpec::getName)
.collect(Collectors.joining(","));

if (masterEligibleNodes.isEmpty()) {
throw new IllegalStateException(
"Cannot start cluster '" + nodeSpec.getCluster().getName() + "' as it configured with no master-eligible nodes."
);
}

settings.put("cluster.initial_master_nodes", "[" + masterEligibleNodes + "]");
settings.put("discovery.seed_providers", "file");
settings.put("discovery.seed_hosts", "[]");

Original file line number Diff line number Diff line change
@@ -170,9 +170,11 @@ public Map<String, String> getSystemProperties() {
}

public boolean isSecurityEnabled() {
return Boolean.parseBoolean(
resolveSettings().getOrDefault("xpack.security.enabled", getVersion().onOrAfter("8.0.0") ? "true" : "false")
);
return Boolean.parseBoolean(getSetting("xpack.security.enabled", getVersion().onOrAfter("8.0.0") ? "true" : "false"));
}

public boolean isMasterEligible() {
return getSetting("node.roles", "master").contains("master");
}

/**
@@ -204,7 +206,7 @@ public String getSetting(String setting, String defaultValue) {
*/
public Map<String, String> resolveSettings() {
Map<String, String> resolvedSettings = new HashMap<>();
settingsProviders.forEach(p -> resolvedSettings.putAll(p.get(this)));
settingsProviders.forEach(p -> resolvedSettings.putAll(p.get(getFilteredSpec(p))));
resolvedSettings.putAll(settings);
return resolvedSettings;
}
@@ -226,5 +228,42 @@ public Map<String, String> resolveEnvironment() {
resolvedEnvironment.putAll(environment);
return resolvedEnvironment;
}

/**
* Returns a new {@link LocalNodeSpec} without the given {@link SettingsProvider}. This is needed when resolving settings from a
* settings provider to avoid infinite recursion.
*
* @param filteredProvider the provider to omit from the new node spec
* @return a new local node spec
*/
private LocalNodeSpec getFilteredSpec(SettingsProvider filteredProvider) {
LocalClusterSpec newCluster = new LocalClusterSpec(cluster.name, cluster.users, cluster.roleFiles);

List<LocalNodeSpec> nodeSpecs = cluster.nodes.stream()
.map(
n -> new LocalNodeSpec(
newCluster,
n.name,
n.version,
n.settingsProviders.stream().filter(s -> s != filteredProvider).toList(),
n.settings,
n.environmentProviders,
n.environment,
n.modules,
n.plugins,
n.distributionType,
n.features,
n.keystoreSettings,
n.keystorePassword,
n.extraConfigFiles,
n.systemProperties
)
)
.toList();

newCluster.setNodes(nodeSpecs);

return nodeSpecs.stream().filter(n -> n.getName().equals(this.getName())).findFirst().get();
}
}
}

0 comments on commit ac60b59

Please sign in to comment.