瀏覽代碼

Validate monitoring password at parse time (#47740)

Dan Hermann 6 年之前
父節點
當前提交
9159af5dd9

+ 39 - 12
x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/exporter/http/HttpExporter.java

@@ -223,7 +223,45 @@ public class HttpExporter extends Exporter {
      */
     public static final Setting.AffixSetting<String> 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<String>() {
+                            @Override
+                            public void validate(String password) {
+                                // no password validation that is independent of other settings
+                            }
+
+                            @Override
+                            public void validate(String password, Map<Setting<?>, 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<Setting<?>> settings() {
+                                final String namespace =
+                                    HttpExporter.AUTH_PASSWORD_SETTING.getNamespace(
+                                        HttpExporter.AUTH_PASSWORD_SETTING.getConcreteSetting(key));
+                                final List<Setting<?>> 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 @@ public class HttpExporter extends Exporter {
         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));
 

+ 10 - 10
x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/exporter/http/HttpExporterTests.java

@@ -225,17 +225,17 @@ public class HttpExporterTests extends ESTestCase {
     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() {