From 62361ceafce4abb735567066d1c4865ca6d7136f Mon Sep 17 00:00:00 2001 From: Andrey Pleskach Date: Tue, 15 Feb 2022 19:40:47 +0100 Subject: [PATCH] Add proxy username and password settings for Azure repository (#2098) Added username/password proxy settings for Azure repository. Security settings: - azure.client.*.proxy.username - Proxy user name - azure.client.*.proxy.password - Proxy user password Signed-off-by: Andrey Pleskach --- .../azure/AzureRepositoryPlugin.java | 10 +- .../azure/AzureStorageService.java | 29 ++--- .../azure/AzureStorageSettings.java | 109 ++++++++++------- .../repositories/azure/ProxySettings.java | 110 ++++++++++++++++++ .../plugin-metadata/plugin-security.policy | 3 + .../azure/AzureStorageServiceTests.java | 65 ++++++----- 6 files changed, 239 insertions(+), 87 deletions(-) create mode 100644 plugins/repository-azure/src/main/java/org/opensearch/repositories/azure/ProxySettings.java diff --git a/plugins/repository-azure/src/main/java/org/opensearch/repositories/azure/AzureRepositoryPlugin.java b/plugins/repository-azure/src/main/java/org/opensearch/repositories/azure/AzureRepositoryPlugin.java index aa419414361..82ab5243a09 100644 --- a/plugins/repository-azure/src/main/java/org/opensearch/repositories/azure/AzureRepositoryPlugin.java +++ b/plugins/repository-azure/src/main/java/org/opensearch/repositories/azure/AzureRepositoryPlugin.java @@ -94,13 +94,15 @@ public class AzureRepositoryPlugin extends Plugin implements RepositoryPlugin, R AzureStorageSettings.ENDPOINT_SUFFIX_SETTING, AzureStorageSettings.TIMEOUT_SETTING, AzureStorageSettings.MAX_RETRIES_SETTING, - AzureStorageSettings.PROXY_TYPE_SETTING, - AzureStorageSettings.PROXY_HOST_SETTING, - AzureStorageSettings.PROXY_PORT_SETTING, AzureStorageSettings.CONNECT_TIMEOUT_SETTING, AzureStorageSettings.WRITE_TIMEOUT_SETTING, AzureStorageSettings.READ_TIMEOUT_SETTING, - AzureStorageSettings.RESPONSE_TIMEOUT_SETTING + AzureStorageSettings.RESPONSE_TIMEOUT_SETTING, + AzureStorageSettings.PROXY_TYPE_SETTING, + AzureStorageSettings.PROXY_HOST_SETTING, + AzureStorageSettings.PROXY_PORT_SETTING, + AzureStorageSettings.PROXY_USERNAME_SETTING, + AzureStorageSettings.PROXY_PASSWORD_SETTING ); } diff --git a/plugins/repository-azure/src/main/java/org/opensearch/repositories/azure/AzureStorageService.java b/plugins/repository-azure/src/main/java/org/opensearch/repositories/azure/AzureStorageService.java index 6cd3a149c69..3800be7c2d2 100644 --- a/plugins/repository-azure/src/main/java/org/opensearch/repositories/azure/AzureStorageService.java +++ b/plugins/repository-azure/src/main/java/org/opensearch/repositories/azure/AzureStorageService.java @@ -43,7 +43,6 @@ import com.azure.core.http.HttpPipelinePosition; import com.azure.core.http.HttpRequest; import com.azure.core.http.HttpResponse; import com.azure.core.http.ProxyOptions; -import com.azure.core.http.ProxyOptions.Type; import com.azure.core.http.netty.NettyAsyncHttpClientBuilder; import com.azure.core.http.policy.HttpPipelinePolicy; import com.azure.core.util.Configuration; @@ -66,12 +65,11 @@ import org.opensearch.common.unit.ByteSizeUnit; import org.opensearch.common.unit.ByteSizeValue; import org.opensearch.common.unit.TimeValue; -import java.net.InetSocketAddress; -import java.net.Proxy; +import java.net.Authenticator; +import java.net.PasswordAuthentication; import java.net.URISyntaxException; import java.security.InvalidKeyException; import java.time.Duration; -import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -169,15 +167,20 @@ public class AzureStorageService implements AutoCloseable { final NioEventLoopGroup eventLoopGroup = new NioEventLoopGroup(new NioThreadFactory()); final NettyAsyncHttpClientBuilder clientBuilder = new NettyAsyncHttpClientBuilder().eventLoopGroup(eventLoopGroup); - final Proxy proxy = azureStorageSettings.getProxy(); - if (proxy != null) { - final Type type = Arrays.stream(Type.values()) - .filter(t -> t.toProxyType().equals(proxy.type())) - .findFirst() - .orElseThrow(() -> new IllegalArgumentException("Unsupported proxy type: " + proxy.type())); - - clientBuilder.proxy(new ProxyOptions(type, (InetSocketAddress) proxy.address())); - } + SocketAccess.doPrivilegedVoidException(() -> { + final ProxySettings proxySettings = azureStorageSettings.getProxySettings(); + if (proxySettings != ProxySettings.NO_PROXY_SETTINGS) { + if (proxySettings.isAuthenticated()) { + Authenticator.setDefault(new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(proxySettings.getUsername(), proxySettings.getPassword().toCharArray()); + } + }); + } + clientBuilder.proxy(new ProxyOptions(proxySettings.getType().toProxyType(), proxySettings.getAddress())); + } + }); final TimeValue connectTimeout = azureStorageSettings.getConnectTimeout(); if (connectTimeout != null) { diff --git a/plugins/repository-azure/src/main/java/org/opensearch/repositories/azure/AzureStorageSettings.java b/plugins/repository-azure/src/main/java/org/opensearch/repositories/azure/AzureStorageSettings.java index 94ec553ab76..c9a031451bc 100644 --- a/plugins/repository-azure/src/main/java/org/opensearch/repositories/azure/AzureStorageSettings.java +++ b/plugins/repository-azure/src/main/java/org/opensearch/repositories/azure/AzureStorageSettings.java @@ -44,8 +44,6 @@ import org.opensearch.common.settings.Settings; import org.opensearch.common.settings.SettingsException; import org.opensearch.common.unit.TimeValue; import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.Proxy; import java.net.UnknownHostException; import java.util.Collections; import java.util.HashMap; @@ -143,10 +141,10 @@ final class AzureStorageSettings { ); /** The type of the proxy to connect to azure through. Can be direct (no proxy, default), http or socks */ - public static final AffixSetting PROXY_TYPE_SETTING = Setting.affixKeySetting( + public static final AffixSetting PROXY_TYPE_SETTING = Setting.affixKeySetting( AZURE_CLIENT_PREFIX_KEY, "proxy.type", - (key) -> new Setting<>(key, "direct", s -> Proxy.Type.valueOf(s.toUpperCase(Locale.ROOT)), Property.NodeScope), + (key) -> new Setting<>(key, "direct", s -> ProxySettings.ProxyType.valueOf(s.toUpperCase(Locale.ROOT)), Property.NodeScope), () -> ACCOUNT_SETTING, () -> KEY_SETTING ); @@ -162,27 +160,50 @@ final class AzureStorageSettings { ); /** The port of a proxy to connect to azure through. */ - public static final Setting PROXY_PORT_SETTING = Setting.affixKeySetting( + public static final AffixSetting PROXY_PORT_SETTING = Setting.affixKeySetting( AZURE_CLIENT_PREFIX_KEY, "proxy.port", (key) -> Setting.intSetting(key, 0, 0, 65535, Setting.Property.NodeScope), - () -> ACCOUNT_SETTING, () -> KEY_SETTING, + () -> ACCOUNT_SETTING, () -> PROXY_TYPE_SETTING, () -> PROXY_HOST_SETTING ); + /** The username of a proxy to connect */ + static final AffixSetting PROXY_USERNAME_SETTING = Setting.affixKeySetting( + AZURE_CLIENT_PREFIX_KEY, + "proxy.username", + key -> SecureSetting.secureString(key, null), + () -> KEY_SETTING, + () -> ACCOUNT_SETTING, + () -> PROXY_TYPE_SETTING, + () -> PROXY_HOST_SETTING + ); + + /** The password of a proxy to connect */ + static final AffixSetting PROXY_PASSWORD_SETTING = Setting.affixKeySetting( + AZURE_CLIENT_PREFIX_KEY, + "proxy.password", + key -> SecureSetting.secureString(key, null), + () -> KEY_SETTING, + () -> ACCOUNT_SETTING, + () -> PROXY_TYPE_SETTING, + () -> PROXY_HOST_SETTING, + () -> PROXY_USERNAME_SETTING + ); + private final String account; private final String connectString; private final String endpointSuffix; private final TimeValue timeout; private final int maxRetries; - private final Proxy proxy; private final LocationMode locationMode; private final TimeValue connectTimeout; private final TimeValue writeTimeout; private final TimeValue readTimeout; private final TimeValue responseTimeout; + private final ProxySettings proxySettings; // copy-constructor private AzureStorageSettings( @@ -191,24 +212,24 @@ final class AzureStorageSettings { String endpointSuffix, TimeValue timeout, int maxRetries, - Proxy proxy, LocationMode locationMode, TimeValue connectTimeout, TimeValue writeTimeout, TimeValue readTimeout, - TimeValue responseTimeout + TimeValue responseTimeout, + ProxySettings proxySettings ) { this.account = account; this.connectString = connectString; this.endpointSuffix = endpointSuffix; this.timeout = timeout; this.maxRetries = maxRetries; - this.proxy = proxy; this.locationMode = locationMode; this.connectTimeout = connectTimeout; this.writeTimeout = writeTimeout; this.readTimeout = readTimeout; this.responseTimeout = responseTimeout; + this.proxySettings = proxySettings; } private AzureStorageSettings( @@ -218,42 +239,23 @@ final class AzureStorageSettings { String endpointSuffix, TimeValue timeout, int maxRetries, - Proxy.Type proxyType, - String proxyHost, - Integer proxyPort, TimeValue connectTimeout, TimeValue writeTimeout, TimeValue readTimeout, - TimeValue responseTimeout + TimeValue responseTimeout, + ProxySettings proxySettings ) { this.account = account; this.connectString = buildConnectString(account, key, sasToken, endpointSuffix); this.endpointSuffix = endpointSuffix; this.timeout = timeout; this.maxRetries = maxRetries; - // Register the proxy if we have any - // Validate proxy settings - if (proxyType.equals(Proxy.Type.DIRECT) && ((proxyPort != 0) || Strings.hasText(proxyHost))) { - throw new SettingsException("Azure Proxy port or host have been set but proxy type is not defined."); - } - if ((proxyType.equals(Proxy.Type.DIRECT) == false) && ((proxyPort == 0) || Strings.isEmpty(proxyHost))) { - throw new SettingsException("Azure Proxy type has been set but proxy host or port is not defined."); - } - - if (proxyType.equals(Proxy.Type.DIRECT)) { - proxy = null; - } else { - try { - proxy = new Proxy(proxyType, new InetSocketAddress(InetAddress.getByName(proxyHost), proxyPort)); - } catch (final UnknownHostException e) { - throw new SettingsException("Azure proxy host is unknown.", e); - } - } this.locationMode = LocationMode.PRIMARY_ONLY; this.connectTimeout = connectTimeout; this.writeTimeout = writeTimeout; this.readTimeout = readTimeout; this.responseTimeout = responseTimeout; + this.proxySettings = proxySettings; } public String getEndpointSuffix() { @@ -268,8 +270,8 @@ final class AzureStorageSettings { return maxRetries; } - public Proxy getProxy() { - return proxy; + public ProxySettings getProxySettings() { + return proxySettings; } public String getConnectString() { @@ -325,7 +327,7 @@ final class AzureStorageSettings { sb.append(", timeout=").append(timeout); sb.append(", endpointSuffix='").append(endpointSuffix).append('\''); sb.append(", maxRetries=").append(maxRetries); - sb.append(", proxy=").append(proxy); + sb.append(", proxySettings=").append(proxySettings != ProxySettings.NO_PROXY_SETTINGS ? "PROXY_SET" : "PROXY_NOT_SET"); sb.append(", locationMode='").append(locationMode).append('\''); sb.append(", connectTimeout='").append(connectTimeout).append('\''); sb.append(", writeTimeout='").append(writeTimeout).append('\''); @@ -371,17 +373,42 @@ final class AzureStorageSettings { getValue(settings, clientName, ENDPOINT_SUFFIX_SETTING), getValue(settings, clientName, TIMEOUT_SETTING), getValue(settings, clientName, MAX_RETRIES_SETTING), - getValue(settings, clientName, PROXY_TYPE_SETTING), - getValue(settings, clientName, PROXY_HOST_SETTING), - getValue(settings, clientName, PROXY_PORT_SETTING), getValue(settings, clientName, CONNECT_TIMEOUT_SETTING), getValue(settings, clientName, WRITE_TIMEOUT_SETTING), getValue(settings, clientName, READ_TIMEOUT_SETTING), - getValue(settings, clientName, RESPONSE_TIMEOUT_SETTING) + getValue(settings, clientName, RESPONSE_TIMEOUT_SETTING), + validateAndCreateProxySettings(settings, clientName) ); } } + static ProxySettings validateAndCreateProxySettings(final Settings settings, final String clientName) { + final ProxySettings.ProxyType proxyType = getConfigValue(settings, clientName, PROXY_TYPE_SETTING); + final String proxyHost = getConfigValue(settings, clientName, PROXY_HOST_SETTING); + final int proxyPort = getConfigValue(settings, clientName, PROXY_PORT_SETTING); + final SecureString proxyUserName = getConfigValue(settings, clientName, PROXY_USERNAME_SETTING); + final SecureString proxyPassword = getConfigValue(settings, clientName, PROXY_PASSWORD_SETTING); + // Validate proxy settings + if (proxyType == ProxySettings.ProxyType.DIRECT + && (proxyPort != 0 || Strings.hasText(proxyHost) || Strings.hasText(proxyUserName) || Strings.hasText(proxyPassword))) { + throw new SettingsException("Azure proxy port or host or username or password have been set but proxy type is not defined."); + } + if (proxyType != ProxySettings.ProxyType.DIRECT && (proxyPort == 0 || Strings.isEmpty(proxyHost))) { + throw new SettingsException("Azure proxy type has been set but proxy host or port is not defined."); + } + + if (proxyType == ProxySettings.ProxyType.DIRECT) { + return ProxySettings.NO_PROXY_SETTINGS; + } + + try { + final InetAddress proxyHostAddress = InetAddress.getByName(proxyHost); + return new ProxySettings(proxyType, proxyHostAddress, proxyPort, proxyUserName.toString(), proxyPassword.toString()); + } catch (final UnknownHostException e) { + throw new SettingsException("Azure proxy host is unknown.", e); + } + } + private static T getConfigValue(Settings settings, String clientName, Setting.AffixSetting clientSetting) { final Setting concreteSetting = clientSetting.getConcreteSettingForNamespace(clientName); return concreteSetting.get(settings); @@ -407,12 +434,12 @@ final class AzureStorageSettings { entry.getValue().endpointSuffix, entry.getValue().timeout, entry.getValue().maxRetries, - entry.getValue().proxy, locationMode, entry.getValue().connectTimeout, entry.getValue().writeTimeout, entry.getValue().readTimeout, - entry.getValue().responseTimeout + entry.getValue().responseTimeout, + entry.getValue().getProxySettings() ) ); } diff --git a/plugins/repository-azure/src/main/java/org/opensearch/repositories/azure/ProxySettings.java b/plugins/repository-azure/src/main/java/org/opensearch/repositories/azure/ProxySettings.java new file mode 100644 index 00000000000..df8c95e69ac --- /dev/null +++ b/plugins/repository-azure/src/main/java/org/opensearch/repositories/azure/ProxySettings.java @@ -0,0 +1,110 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.repositories.azure; + +import com.azure.core.http.ProxyOptions; +import org.opensearch.common.Strings; +import org.opensearch.common.settings.SettingsException; + +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.util.Objects; + +public class ProxySettings { + + public static final ProxySettings NO_PROXY_SETTINGS = new ProxySettings(ProxyType.DIRECT, null, -1, null, null); + + private final ProxyType type; + + private final InetAddress host; + + private final String username; + + private final String password; + + private final int port; + + public static enum ProxyType { + HTTP(ProxyOptions.Type.HTTP.name()), + + /** + * Please use SOCKS4 instead + */ + @Deprecated + SOCKS(ProxyOptions.Type.SOCKS4.name()), + + SOCKS4(ProxyOptions.Type.SOCKS4.name()), + + SOCKS5(ProxyOptions.Type.SOCKS5.name()), + + DIRECT("DIRECT"); + + private final String name; + + private ProxyType(String name) { + this.name = name; + } + + public ProxyOptions.Type toProxyType() { + if (this == DIRECT) { + // We check it in settings, + // the probability that it could be thrown is small, but how knows + throw new SettingsException("Couldn't convert to Azure proxy type"); + } + return ProxyOptions.Type.valueOf(name()); + } + + } + + public ProxySettings(final ProxyType type, final InetAddress host, final int port, final String username, final String password) { + this.type = type; + this.host = host; + this.port = port; + this.username = username; + this.password = password; + } + + public ProxyType getType() { + return this.type; + } + + public InetSocketAddress getAddress() { + return new InetSocketAddress(host, port); + } + + public String getUsername() { + return this.username; + } + + public String getPassword() { + return this.password; + } + + public boolean isAuthenticated() { + return Strings.isNullOrEmpty(username) == false && Strings.isNullOrEmpty(password) == false; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + final ProxySettings that = (ProxySettings) o; + return port == that.port + && type == that.type + && Objects.equals(host, that.host) + && Objects.equals(username, that.username) + && Objects.equals(password, that.password); + } + + @Override + public int hashCode() { + return Objects.hash(type, host, username, password, port); + } + +} diff --git a/plugins/repository-azure/src/main/plugin-metadata/plugin-security.policy b/plugins/repository-azure/src/main/plugin-metadata/plugin-security.policy index f6d0f5fcb08..f3bf52ea465 100644 --- a/plugins/repository-azure/src/main/plugin-metadata/plugin-security.policy +++ b/plugins/repository-azure/src/main/plugin-metadata/plugin-security.policy @@ -38,4 +38,7 @@ grant { permission java.lang.RuntimePermission "accessDeclaredMembers"; permission java.lang.reflect.ReflectPermission "suppressAccessChecks"; permission java.lang.RuntimePermission "setContextClassLoader"; + + // azure client set Authenticator for proxy username/password + permission java.net.NetPermission "setDefaultAuthenticator"; }; diff --git a/plugins/repository-azure/src/test/java/org/opensearch/repositories/azure/AzureStorageServiceTests.java b/plugins/repository-azure/src/test/java/org/opensearch/repositories/azure/AzureStorageServiceTests.java index 785ebef7307..7f5ca73a507 100644 --- a/plugins/repository-azure/src/test/java/org/opensearch/repositories/azure/AzureStorageServiceTests.java +++ b/plugins/repository-azure/src/test/java/org/opensearch/repositories/azure/AzureStorageServiceTests.java @@ -32,6 +32,7 @@ package org.opensearch.repositories.azure; +import org.opensearch.common.Strings; import reactor.core.scheduler.Schedulers; import com.azure.core.http.policy.HttpPipelinePolicy; @@ -50,7 +51,6 @@ import java.io.IOException; import java.io.UncheckedIOException; import java.net.InetAddress; import java.net.InetSocketAddress; -import java.net.Proxy; import java.net.URI; import java.net.URISyntaxException; import java.net.UnknownHostException; @@ -299,9 +299,9 @@ public class AzureStorageServiceTests extends OpenSearchTestCase { public void testNoProxy() { final Settings settings = Settings.builder().setSecureSettings(buildSecureSettings()).build(); final AzureStorageService mock = storageServiceWithSettingsValidation(settings); - assertThat(mock.storageSettings.get("azure1").getProxy(), nullValue()); - assertThat(mock.storageSettings.get("azure2").getProxy(), nullValue()); - assertThat(mock.storageSettings.get("azure3").getProxy(), nullValue()); + assertEquals(mock.storageSettings.get("azure1").getProxySettings(), ProxySettings.NO_PROXY_SETTINGS); + assertEquals(mock.storageSettings.get("azure2").getProxySettings(), ProxySettings.NO_PROXY_SETTINGS); + assertEquals(mock.storageSettings.get("azure3").getProxySettings(), ProxySettings.NO_PROXY_SETTINGS); } public void testProxyHttp() throws UnknownHostException { @@ -312,13 +312,13 @@ public class AzureStorageServiceTests extends OpenSearchTestCase { .put("azure.client.azure1.proxy.type", "http") .build(); final AzureStorageService mock = storageServiceWithSettingsValidation(settings); - final Proxy azure1Proxy = mock.storageSettings.get("azure1").getProxy(); + final ProxySettings azure1Proxy = mock.storageSettings.get("azure1").getProxySettings(); assertThat(azure1Proxy, notNullValue()); - assertThat(azure1Proxy.type(), is(Proxy.Type.HTTP)); - assertThat(azure1Proxy.address(), is(new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 8080))); - assertThat(mock.storageSettings.get("azure2").getProxy(), nullValue()); - assertThat(mock.storageSettings.get("azure3").getProxy(), nullValue()); + assertThat(azure1Proxy.getType(), is(ProxySettings.ProxyType.HTTP)); + assertThat(azure1Proxy.getAddress(), is(new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 8080))); + assertEquals(ProxySettings.NO_PROXY_SETTINGS, mock.storageSettings.get("azure2").getProxySettings()); + assertEquals(ProxySettings.NO_PROXY_SETTINGS, mock.storageSettings.get("azure3").getProxySettings()); } public void testMultipleProxies() throws UnknownHostException { @@ -332,52 +332,59 @@ public class AzureStorageServiceTests extends OpenSearchTestCase { .put("azure.client.azure2.proxy.type", "http") .build(); final AzureStorageService mock = storageServiceWithSettingsValidation(settings); - final Proxy azure1Proxy = mock.storageSettings.get("azure1").getProxy(); + final ProxySettings azure1Proxy = mock.storageSettings.get("azure1").getProxySettings(); assertThat(azure1Proxy, notNullValue()); - assertThat(azure1Proxy.type(), is(Proxy.Type.HTTP)); - assertThat(azure1Proxy.address(), is(new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 8080))); - final Proxy azure2Proxy = mock.storageSettings.get("azure2").getProxy(); + assertThat(azure1Proxy.getType(), is(ProxySettings.ProxyType.HTTP)); + assertThat(azure1Proxy.getAddress(), is(new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 8080))); + final ProxySettings azure2Proxy = mock.storageSettings.get("azure2").getProxySettings(); assertThat(azure2Proxy, notNullValue()); - assertThat(azure2Proxy.type(), is(Proxy.Type.HTTP)); - assertThat(azure2Proxy.address(), is(new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 8081))); - assertThat(mock.storageSettings.get("azure3").getProxy(), nullValue()); + assertThat(azure2Proxy.getType(), is(ProxySettings.ProxyType.HTTP)); + assertThat(azure2Proxy.getAddress(), is(new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 8081))); + assertTrue(Strings.isNullOrEmpty(azure2Proxy.getUsername())); + assertTrue(Strings.isNullOrEmpty(azure2Proxy.getPassword())); + assertEquals(mock.storageSettings.get("azure3").getProxySettings(), ProxySettings.NO_PROXY_SETTINGS); } public void testProxySocks() throws UnknownHostException { + final MockSecureSettings secureSettings = buildSecureSettings(); + secureSettings.setString("azure.client.azure1.proxy.username", "user"); + secureSettings.setString("azure.client.azure1.proxy.password", "pwd"); final Settings settings = Settings.builder() - .setSecureSettings(buildSecureSettings()) .put("azure.client.azure1.proxy.host", "127.0.0.1") .put("azure.client.azure1.proxy.port", 8080) - .put("azure.client.azure1.proxy.type", "socks") + .put("azure.client.azure1.proxy.type", "socks5") + .setSecureSettings(secureSettings) .build(); final AzureStorageService mock = storageServiceWithSettingsValidation(settings); - final Proxy azure1Proxy = mock.storageSettings.get("azure1").getProxy(); + final ProxySettings azure1Proxy = mock.storageSettings.get("azure1").getProxySettings(); assertThat(azure1Proxy, notNullValue()); - assertThat(azure1Proxy.type(), is(Proxy.Type.SOCKS)); - assertThat(azure1Proxy.address(), is(new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 8080))); - assertThat(mock.storageSettings.get("azure2").getProxy(), nullValue()); - assertThat(mock.storageSettings.get("azure3").getProxy(), nullValue()); + assertThat(azure1Proxy.getType(), is(ProxySettings.ProxyType.SOCKS5)); + assertThat(azure1Proxy.getAddress(), is(new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 8080))); + assertEquals("user", azure1Proxy.getUsername()); + assertEquals("pwd", azure1Proxy.getPassword()); + assertEquals(ProxySettings.NO_PROXY_SETTINGS, mock.storageSettings.get("azure2").getProxySettings()); + assertEquals(ProxySettings.NO_PROXY_SETTINGS, mock.storageSettings.get("azure3").getProxySettings()); } public void testProxyNoHost() { final Settings settings = Settings.builder() .setSecureSettings(buildSecureSettings()) .put("azure.client.azure1.proxy.port", 8080) - .put("azure.client.azure1.proxy.type", randomFrom("socks", "http")) + .put("azure.client.azure1.proxy.type", randomFrom("socks", "socks4", "socks5", "http")) .build(); final SettingsException e = expectThrows(SettingsException.class, () -> storageServiceWithSettingsValidation(settings)); - assertEquals("Azure Proxy type has been set but proxy host or port is not defined.", e.getMessage()); + assertEquals("Azure proxy type has been set but proxy host or port is not defined.", e.getMessage()); } public void testProxyNoPort() { final Settings settings = Settings.builder() .setSecureSettings(buildSecureSettings()) .put("azure.client.azure1.proxy.host", "127.0.0.1") - .put("azure.client.azure1.proxy.type", randomFrom("socks", "http")) + .put("azure.client.azure1.proxy.type", randomFrom("socks", "socks4", "socks5", "http")) .build(); final SettingsException e = expectThrows(SettingsException.class, () -> storageServiceWithSettingsValidation(settings)); - assertEquals("Azure Proxy type has been set but proxy host or port is not defined.", e.getMessage()); + assertEquals("Azure proxy type has been set but proxy host or port is not defined.", e.getMessage()); } public void testProxyNoType() { @@ -388,13 +395,13 @@ public class AzureStorageServiceTests extends OpenSearchTestCase { .build(); final SettingsException e = expectThrows(SettingsException.class, () -> storageServiceWithSettingsValidation(settings)); - assertEquals("Azure Proxy port or host have been set but proxy type is not defined.", e.getMessage()); + assertEquals("Azure proxy port or host or username or password have been set but proxy type is not defined.", e.getMessage()); } public void testProxyWrongHost() { final Settings settings = Settings.builder() .setSecureSettings(buildSecureSettings()) - .put("azure.client.azure1.proxy.type", randomFrom("socks", "http")) + .put("azure.client.azure1.proxy.type", randomFrom("socks", "socks4", "socks5", "http")) .put("azure.client.azure1.proxy.host", "thisisnotavalidhostorwehavebeensuperunlucky") .put("azure.client.azure1.proxy.port", 8080) .build();