diff --git a/x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/exporter/http/HttpExporter.java b/x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/exporter/http/HttpExporter.java index 84e008bd8db0b..dd9041ffd070c 100644 --- a/x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/exporter/http/HttpExporter.java +++ b/x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/exporter/http/HttpExporter.java @@ -223,7 +223,45 @@ public Iterator> settings() { */ public static final Setting.AffixSetting AUTH_PASSWORD_SETTING = Setting.affixKeySetting("xpack.monitoring.exporters.","auth.password", - (key) -> Setting.simpleString(key, Property.Dynamic, Property.NodeScope, Property.Filtered)); + (key) -> Setting.simpleString(key, + new Setting.Validator() { + @Override + public void validate(String password) { + // no password validation that is independent of other settings + } + + @Override + public void validate(String password, Map, Object> settings) { + final String namespace = + HttpExporter.AUTH_PASSWORD_SETTING.getNamespace( + HttpExporter.AUTH_PASSWORD_SETTING.getConcreteSetting(key)); + final String username = + (String) settings.get(AUTH_USERNAME_SETTING.getConcreteSettingForNamespace(namespace)); + + // username is required for any auth + if (Strings.isNullOrEmpty(username)) { + if (Strings.isNullOrEmpty(password) == false) { + throw new IllegalArgumentException( + "[" + AUTH_PASSWORD_SETTING.getConcreteSettingForNamespace(namespace).getKey() + "] without [" + + AUTH_USERNAME_SETTING.getConcreteSettingForNamespace(namespace).getKey() + "]"); + } + } + } + + @Override + public Iterator> settings() { + final String namespace = + HttpExporter.AUTH_PASSWORD_SETTING.getNamespace( + HttpExporter.AUTH_PASSWORD_SETTING.getConcreteSetting(key)); + final List> settings = List.of( + HttpExporter.AUTH_USERNAME_SETTING.getConcreteSettingForNamespace(namespace)); + return settings.iterator(); + } + + }, + Property.Dynamic, + Property.NodeScope, + Property.Filtered)); /** * The SSL settings. * @@ -634,17 +672,6 @@ private static CredentialsProvider createCredentialsProvider(final Config config final String username = AUTH_USERNAME_SETTING.getConcreteSettingForNamespace(config.name()).get(config.settings()); final String password = AUTH_PASSWORD_SETTING.getConcreteSettingForNamespace(config.name()).get(config.settings()); - // username is required for any auth - if (Strings.isNullOrEmpty(username)) { - if (Strings.isNullOrEmpty(password) == false) { - throw new SettingsException( - "[" + AUTH_PASSWORD_SETTING.getConcreteSettingForNamespace(config.name()).getKey() + "] without [" + - AUTH_USERNAME_SETTING.getConcreteSettingForNamespace(config.name()).getKey() + "]"); - } - // nothing to configure; default situation for most users - return null; - } - final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password)); diff --git a/x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/exporter/http/HttpExporterTests.java b/x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/exporter/http/HttpExporterTests.java index c8f4fb6958aa7..bfa1e16d860b0 100644 --- a/x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/exporter/http/HttpExporterTests.java +++ b/x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/exporter/http/HttpExporterTests.java @@ -225,17 +225,17 @@ public void testExporterWithEmptyHeaders() { public void testExporterWithPasswordButNoUsername() { final String expected = "[xpack.monitoring.exporters._http.auth.password] without [xpack.monitoring.exporters._http.auth.username]"; - final Settings.Builder builder = Settings.builder() - .put("xpack.monitoring.exporters._http.type", HttpExporter.TYPE) - .put("xpack.monitoring.exporters._http.host", "localhost:9200") - .put("xpack.monitoring.exporters._http.auth.password", "_pass"); - - final Config config = createConfig(builder.build()); - - final SettingsException exception = expectThrows(SettingsException.class, - () -> new HttpExporter(config, sslService, threadContext)); + final String prefix = "xpack.monitoring.exporters._http"; + final Settings settings = Settings.builder() + .put(prefix + ".type", HttpExporter.TYPE) + .put(prefix + ".host", "localhost:9200") + .put(prefix + ".auth.password", "_pass") + .build(); - assertThat(exception.getMessage(), equalTo(expected)); + final IllegalArgumentException e = expectThrows( + IllegalArgumentException.class, + () -> HttpExporter.AUTH_PASSWORD_SETTING.getConcreteSetting(prefix + ".auth.password").get(settings)); + assertThat(e, hasToString(containsString(expected))); } public void testExporterWithUsernameButNoPassword() {