Add AWS credentials profile name parameter Some Gerrit setups shares the AWS dynamodb tables between AWS Regions, for example multi-site setup in multiple regions. For security reason access to the other regions should be limited to necessary services. Add configuration param which allows to specify AWS credentials profile to be used only by the aws-dynamodb-refdb plugin when connecting to the dynamoDb. This profile allows us to setup credentials or IAM Role with access to the dynamoDb setup on the other region. Bug: Issue 16877 Change-Id: Ifc60162f747bc3fdf810f23e67ef8c6a04d957c7
diff --git a/src/main/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/AmazonDynamoDBProvider.java b/src/main/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/AmazonDynamoDBProvider.java index 76ec8c0..eb13649 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/AmazonDynamoDBProvider.java +++ b/src/main/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/AmazonDynamoDBProvider.java
@@ -14,7 +14,9 @@ package com.googlesource.gerrit.plugins.validation.dfsrefdb.dynamodb; +import com.amazonaws.auth.AWSCredentialsProvider; import com.amazonaws.auth.DefaultAWSCredentialsProviderChain; +import com.amazonaws.auth.profile.ProfileCredentialsProvider; import com.amazonaws.client.builder.AwsClientBuilder; import com.amazonaws.regions.DefaultAwsRegionProviderChain; import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; @@ -48,6 +50,13 @@ endpoint -> builder.withEndpointConfiguration( new AwsClientBuilder.EndpointConfiguration(endpoint.toASCIIString(), region))); - return builder.withCredentials(new DefaultAWSCredentialsProviderChain()).build(); + return builder.withCredentials(getCredentialsProvider()).build(); + } + + private AWSCredentialsProvider getCredentialsProvider() { + return configuration + .getAwsConfigurationProfileName() + .<AWSCredentialsProvider>map(ProfileCredentialsProvider::new) + .orElse(new DefaultAWSCredentialsProviderChain()); } }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/Configuration.java b/src/main/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/Configuration.java index 791e1c7..01e2f4f 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/Configuration.java +++ b/src/main/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/Configuration.java
@@ -34,6 +34,7 @@ private final Optional<URI> endpoint; private final String refsDbTableName; private final String locksTableName; + private final Optional<String> awsConfigurationProfileName; @Inject Configuration(PluginConfigFactory configFactory, @PluginName String pluginName) { @@ -44,12 +45,14 @@ // TODO: add prefix this.refsDbTableName = pluginConfig.getString("refsDbTableName", DEFAULT_REFS_DB_TABLE_NAME); this.locksTableName = pluginConfig.getString("locksTableName", DEFAULT_LOCKS_TABLE_NAME); + this.awsConfigurationProfileName = Optional.ofNullable(pluginConfig.getString("profileName")); logger.atInfo().log( - "dynamodb-refdb configuration: refsDbTableName: %s|locksTableName:%s%s%s", + "dynamodb-refdb configuration: refsDbTableName: %s|locksTableName:%s%s%s%s", refsDbTableName, locksTableName, region.map(r -> String.format("|region: %s", r.id())).orElse(""), - endpoint.map(e -> String.format("|endpoint: %s", e.toASCIIString())).orElse("")); + endpoint.map(e -> String.format("|endpoint: %s", e.toASCIIString())).orElse(""), + awsConfigurationProfileName.map(p -> String.format("|profile: %s", p)).orElse("")); } Optional<Region> getRegion() { @@ -73,4 +76,8 @@ String getLocksTableName() { return locksTableName; } + + Optional<String> getAwsConfigurationProfileName() { + return awsConfigurationProfileName; + } }
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md index ca94b64..0d871cc 100644 --- a/src/main/resources/Documentation/config.md +++ b/src/main/resources/Documentation/config.md
@@ -10,6 +10,7 @@ endpoint = http://localhost:4566 locksTableName = lockTable refsDbTableName = refsDb + profileName = aws-dynamodb-refdb ``` `plugin.aws-dynamodb-refdb.region` @@ -33,4 +34,11 @@ : Optional. The name of the dynamoDB table used to store git refs and their associated sha1. +`plugin.aws-dynamodb-refdb.profileName` +: Optional. The name of the aws configuration and credentials profile used to +connect to the DynamoDb. See [Configuration and credential file settings](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html) +Default: When not specified credentials are provided via the Default Credentials +Provider Chain, as explained [here](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/credentials.html) + +
diff --git a/src/test/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/ConfigurationTest.java b/src/test/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/ConfigurationTest.java index 5195c01..6b961d7 100644 --- a/src/test/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/ConfigurationTest.java +++ b/src/test/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/ConfigurationTest.java
@@ -101,6 +101,26 @@ } @Test + public void shouldReadEmptyAwsConfigurationProfileNameByDefault() { + when(pluginConfigFactoryMock.getFromGerritConfig(PLUGIN_NAME)) + .thenReturn(pluginConfig.asPluginConfig()); + + Configuration configuration = new Configuration(pluginConfigFactoryMock, PLUGIN_NAME); + assertThat(configuration.getAwsConfigurationProfileName().isPresent()).isFalse(); + } + + @Test + public void shouldReadConfiguredAwsConfigurationProfileName() { + String profileName = "aws-dynamodb-refdb"; + pluginConfig.setString("profileName", profileName); + when(pluginConfigFactoryMock.getFromGerritConfig(PLUGIN_NAME)) + .thenReturn(pluginConfig.asPluginConfig()); + + Configuration configuration = new Configuration(pluginConfigFactoryMock, PLUGIN_NAME); + assertThat(configuration.getAwsConfigurationProfileName().get()).isEqualTo(profileName); + } + + @Test public void shouldReadEmptyRegionByDefault() { when(pluginConfigFactoryMock.getFromGerritConfig(PLUGIN_NAME)) .thenReturn(pluginConfig.asPluginConfig());