Skip to content
This repository has been archived by the owner on Mar 31, 2021. It is now read-only.

Commit

Permalink
Support customer AWS credential providers (#22)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jianfei-Li authored and galkk committed Aug 13, 2019
1 parent 2a3ac84 commit 514d448
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 2 deletions.
49 changes: 49 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ To setup a connection, the driver requires a JDBC connection URL. The connection
| logOutput | location where driver logs should be emitted | a valid file path | `null` (logs are disabled) |
| logLevel | severity level for which driver logs should be emitted | in order from highest(least logging) to lowest(most logging): OFF, FATAL, ERROR, WARN, INFO, DEBUG, TRACE, ALL | OFF (logs are disabled) |
| auth | authentication mechanism to use | `NONE` (no auth), `BASIC` (HTTP Basic), `AWS_SIGV4` (AWS SIGV4) | `basic` if username and/or password is specified, `NONE` otherwise |
| awsCredentialsProvider | The AWS credential provider to be used when authentication mechanism is `AWS_SIGV4` (AWS SIGV4). If not set, the driver will use DefaultAWSCredentialsProviderChain to sign the request. Note that the driver renamed the namespaces of its dependencies, so the value has to be an instance of com.amazonaws.opendistro.elasticsearch.sql.jdbc.shadow.com.amazonaws.auth.AWSCredentialsProvider| Instance of an AWSCredentialProvider | DefaultAWSCredentialsProviderChain |
| region | if authentication type is `aws_sigv4`, then this is the region value to use when signing requests. Only needed if the driver can not determine the region for the host endpoint. The driver will detect the region if the host endpoint matches a known url pattern. | a valid AWS region value e.g. us-east-1 | `null` (auto-detected if possible from the host endpoint) |
| requestCompression | whether to indicate acceptance of compressed (gzip) responses when making server requests | `true` or `false` | `false` |
| useSSL | whether to establish the connection over SSL/TLS | `true` or `false` | `false` if scheme is `http`, `true` if scheme is `https` |
Expand Down Expand Up @@ -254,6 +255,28 @@ Statement st = con.createStatement();
con.close();
```

* Connect to a remote host on default SSL port with AWS Sig V4 authentication, explicitly specifying the AWSCredentialProvider to use

```
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
.
.
String url = "jdbc:elasticsearch://https://remote-host-name";
Properties properties = new Properties();
properties.put("awsCredentialsProvider", new EnvironmentVariableCredentialsProvider());
Connection con = DriverManager.getConnection(url, properties);
Statement st = con.createStatement();
.
// use the connection
.
// close connection
con.close();
```

* Connect to a remote host on default SSL port with AWS Sig V4 authentication, explicitly specifying the region to use in the request signing.

```
Expand Down Expand Up @@ -401,6 +424,32 @@ Statement st = con.createStatement();
con.close();
```

* Connect to a remote host on default SSL port with AWS Sig V4 authentication, explicitly specifying the AWSCredentialProvider to use

```
import java.sql.Connection;
import java.sql.Statement;
import javax.sql.DataSource;
import com.amazon.opendistroforelasticsearch.jdbc.ElasticsearchDataSource;
.
.
String url = "jdbc:elasticsearch://https://remote-host-name?auth=aws_sigv4&region=us-west-1";
ElasticsearchDataSource ds = new ElasticsearchDataSource();
ds.setUrl(url);
ds.setAwsCredentialProvider(new EnvironmentVariableCredentialsProvider());
Connection con = ds.getConnection(url);
Statement st = con.createStatement();
.
// use the connection
.
// close connection
con.close();
```

* Connect to a remote host on default SSL port with AWS Sig V4 authentication, explicitly specifying the region to use in the request signing.

```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@

package com.amazon.opendistroforelasticsearch.jdbc;

import com.amazon.opendistroforelasticsearch.jdbc.config.AwsCredentialsProviderProperty;
import com.amazon.opendistroforelasticsearch.jdbc.config.ConnectionConfig;
import com.amazon.opendistroforelasticsearch.jdbc.config.LoginTimeoutConnectionProperty;
import com.amazon.opendistroforelasticsearch.jdbc.config.PasswordConnectionProperty;
import com.amazon.opendistroforelasticsearch.jdbc.config.UserConnectionProperty;
import com.amazon.opendistroforelasticsearch.jdbc.internal.JdbcWrapper;
import com.amazon.opendistroforelasticsearch.jdbc.internal.util.UrlParser;
import com.amazon.opendistroforelasticsearch.jdbc.logging.LoggingSource;
import com.amazonaws.auth.AWSCredentialsProvider;

import javax.sql.DataSource;
import java.io.PrintWriter;
Expand Down Expand Up @@ -122,6 +124,10 @@ public void setUrl(String url) throws SQLException {
throw new SQLException("Invalid connection URL", e);
}
}

public void setAwsCredentialProvider(AWSCredentialsProvider awsCredentialProvider) {
connectionProperties.put(AwsCredentialsProviderProperty.KEY, awsCredentialProvider);
}

/**
* Updates DataSource configuration properties from the specified
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.amazon.opendistroforelasticsearch.jdbc.config;

import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.auth.DefaultAWSCredentialsProviderChain;

public class AwsCredentialsProviderProperty extends ConnectionProperty<AWSCredentialsProvider> {

public static final String KEY = "awsCredentialsProvider";

public AwsCredentialsProviderProperty() {
super(KEY);
}

@Override
public AWSCredentialsProvider getDefault() {
return new DefaultAWSCredentialsProviderChain();
}

@Override
protected AWSCredentialsProvider parseValue(Object rawValue) throws ConnectionPropertyException {
if (null == rawValue) {
return null;
} else if (rawValue instanceof AWSCredentialsProvider) {
return (AWSCredentialsProvider) rawValue;
}

throw new ConnectionPropertyException(getKey(),
String.format("Property \"%s\" requires a valid AWSCredentialsProvider instance. " +
"Invalid value of type: %s specified.", getKey(), rawValue.getClass().getName()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.amazon.opendistroforelasticsearch.jdbc.logging.LogLevel;
import com.amazon.opendistroforelasticsearch.jdbc.internal.util.AwsHostNameUtil;
import com.amazon.opendistroforelasticsearch.jdbc.internal.util.UrlParser;
import com.amazonaws.auth.AWSCredentialsProvider;

import java.io.PrintWriter;
import java.net.URISyntaxException;
Expand All @@ -42,6 +43,7 @@ public class ConnectionConfig {
private String password;
private boolean requestCompression;
private AuthenticationType authenticationType;
private AWSCredentialsProvider awsCredentialsProvider;
private String region;
private LogLevel logLevel;

Expand Down Expand Up @@ -72,6 +74,7 @@ private ConnectionConfig(Builder builder) {

this.requestCompression = builder.getRequestCompressionProperty().getValue();
this.authenticationType = builder.getAuthConnectionProperty().getValue();
this.awsCredentialsProvider = builder.getAwsCredentialProvider().getValue();
this.region = builder.getRegionConnectionProperty().getValue();

this.keyStoreLocation = builder.getKeyStoreLocationConnectionProperty().getValue();
Expand Down Expand Up @@ -139,6 +142,10 @@ public AuthenticationType getAuthenticationType() {
return authenticationType;
}

public AWSCredentialsProvider getAwsCredentialsProvider() {
return awsCredentialsProvider;
}

public String getRegion() {
return region;
}
Expand Down Expand Up @@ -194,6 +201,7 @@ public String toString() {
", password='" + mask(password) + '\'' +
", requestCompression=" + requestCompression +
", authenticationType=" + authenticationType +
", awsCredentialsProvider=" + awsCredentialsProvider +
", region='" + region + '\'' +
", logLevel=" + logLevel +
", keyStoreLocation='" + keyStoreLocation + '\'' +
Expand Down Expand Up @@ -244,6 +252,9 @@ public static class Builder {
private TrustSelfSignedConnectionProperty trustSelfSignedConnectionProperty
= new TrustSelfSignedConnectionProperty();

private AwsCredentialsProviderProperty awsCredentialsProviderProperty
= new AwsCredentialsProviderProperty();

private HostnameVerificationConnectionProperty hostnameVerificationConnectionProperty
= new HostnameVerificationConnectionProperty();

Expand All @@ -259,6 +270,7 @@ public static class Builder {
passwordProperty,
requestCompressionProperty,
authConnectionProperty,
awsCredentialsProviderProperty,
regionConnectionProperty,
keyStoreLocationConnectionProperty,
keyStorePasswordConnectionProperty,
Expand Down Expand Up @@ -322,6 +334,10 @@ public AuthConnectionProperty getAuthConnectionProperty() {
return authConnectionProperty;
}

public AwsCredentialsProviderProperty getAwsCredentialProvider() {
return awsCredentialsProviderProperty;
}

public RegionConnectionProperty getRegionConnectionProperty() {
return regionConnectionProperty;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.amazon.opendistroforelasticsearch.jdbc.transport.TransportException;
import com.amazon.opendistroforelasticsearch.jdbc.transport.http.auth.aws.AWSRequestSigningApacheInterceptor;
import com.amazonaws.auth.AWS4Signer;
import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.auth.DefaultAWSCredentialsProviderChain;
import org.apache.http.Header;
import org.apache.http.auth.AuthScope;
Expand Down Expand Up @@ -73,7 +74,6 @@ public class ApacheHttpTransport implements HttpTransport, LoggingSource {
private RequestConfig requestConfig;
private CloseableHttpClient httpClient;


public ApacheHttpTransport(ConnectionConfig connectionConfig, Logger log, String userAgent) throws TransportException {
this.host = connectionConfig.getHost();
this.port = connectionConfig.getPort();
Expand Down Expand Up @@ -122,11 +122,13 @@ public ApacheHttpTransport(ConnectionConfig connectionConfig, Logger log, String
signer.setServiceName("es");
signer.setRegionName(connectionConfig.getRegion());

AWSCredentialsProvider provider = connectionConfig.getAwsCredentialsProvider() != null ?
connectionConfig.getAwsCredentialsProvider() : new DefaultAWSCredentialsProviderChain();
httpClientBuilder.addInterceptorLast(
new AWSRequestSigningApacheInterceptor(
"es",
signer,
new DefaultAWSCredentialsProviderChain()));
provider));
}

// TODO - can apply settings retry & backoff
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ void testDataSourceConfig() throws SQLException {
assertNull(config.getUser());
assertNull(config.getPassword());
Assertions.assertEquals(AuthenticationType.NONE, config.getAuthenticationType());
assertNull(config.getAwsCredentialsProvider());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.amazon.opendistroforelasticsearch.jdbc.auth.AuthenticationType;
import com.amazon.opendistroforelasticsearch.jdbc.internal.util.UrlParser;
import com.amazon.opendistroforelasticsearch.jdbc.logging.LogLevel;
import com.amazonaws.auth.EnvironmentVariableCredentialsProvider;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
Expand Down Expand Up @@ -271,6 +272,17 @@ void testRegionConfig() {
"ap-southeast-2");
}

@Test
void testAwsCredentialsProviderConfig() {
assertPropertyRejectsValue(AwsCredentialsProviderProperty.KEY, "Invalid AWS Credentials Provider");

// The property accepts null and valid AWSCredentialProvider
assertPropertyAcceptsValue(AwsCredentialsProviderProperty.KEY, ConnectionConfig::getAwsCredentialsProvider,
null);
assertPropertyAcceptsValue(AwsCredentialsProviderProperty.KEY, ConnectionConfig::getAwsCredentialsProvider,
new EnvironmentVariableCredentialsProvider());
}

@Test
void testHostnameVerificationConfig() {
assertCommonBooleanPropertyTests(HostnameVerificationConnectionProperty.KEY, ConnectionConfig::hostnameVerification);
Expand Down

0 comments on commit 514d448

Please sign in to comment.