Add configuration for mapping access keys

This allows S3Proxy to use multiple local credentials mapping onto
multiple remote credentials.  Credentials properties files have the
form:

local-identity=local-credential:remote-identity:remote-credential
blobstore-locator
Andrew Gaul 2016-08-29 20:22:08 -07:00
rodzic a09c9e1998
commit 6a712d5945
2 zmienionych plików z 115 dodań i 0 usunięć

Wyświetl plik

@ -16,6 +16,8 @@
package org.gaul.s3proxy;
import static com.google.common.base.Preconditions.checkArgument;
import java.io.Console;
import java.io.File;
import java.io.FileInputStream;
@ -24,6 +26,7 @@ import java.io.InputStream;
import java.io.PrintStream;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executors;
@ -31,6 +34,7 @@ import java.util.concurrent.TimeUnit;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Maps;
import com.google.common.io.Files;
import com.google.inject.Module;
@ -59,6 +63,10 @@ public final class Main {
usage = "S3Proxy configuration (required)")
private File propertiesFile;
@Option(name = "--credentials-properties",
usage = "Mapping for multiple credentials")
private File credentialsPropertyFile;
@Option(name = "--version", usage = "display version")
private boolean version;
}
@ -91,6 +99,14 @@ public final class Main {
}
properties.putAll(System.getProperties());
Properties credentialsProperties = new Properties();
if (options.credentialsPropertyFile != null) {
try (InputStream is = new FileInputStream(
options.credentialsPropertyFile)) {
credentialsProperties.load(is);
}
}
String s3ProxyEndpointString = properties.getProperty(
S3ProxyConstants.PROPERTY_ENDPOINT);
String secureEndpoint = properties.getProperty(
@ -238,6 +254,33 @@ public final class Main {
System.exit(1);
throw e;
}
final Map<String, Map.Entry<String, BlobStore>> credentialsMap =
new HashMap<>();
for (Map.Entry<Object, Object> entry :
credentialsProperties.entrySet()) {
String key = (String) entry.getKey();
String[] values = ((String) entry.getValue()).split(":");
checkArgument(values.length == 3, "values must have the form: " +
"frontend_credential:remote_identity:remote_credential");
Properties newProperties = new Properties(properties);
newProperties.setProperty(Constants.PROPERTY_IDENTITY, values[1]);
newProperties.setProperty(Constants.PROPERTY_CREDENTIAL, values[2]);
credentialsMap.put(key, Maps.immutableEntry(values[0],
createBlobStore(newProperties)));
}
if (!credentialsMap.isEmpty()) {
s3Proxy.setBlobStoreLocator(new BlobStoreLocator() {
@Override
public Map.Entry<String, BlobStore> locateBlobStore(
String identity, String container, String blob) {
return credentialsMap.get(identity);
}
});
}
try {
s3Proxy.start();
} catch (Exception e) {

Wyświetl plik

@ -87,10 +87,13 @@ import com.amazonaws.services.s3.model.UploadPartRequest;
import com.amazonaws.services.s3.model.UploadPartResult;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.common.io.ByteSource;
import org.assertj.core.api.Fail;
import org.jclouds.ContextBuilder;
import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.rest.HttpClient;
@ -1379,6 +1382,75 @@ public final class AwsSdkTest {
}
}
@Test
public void testBlobStoreLocator() throws Exception {
final BlobStore blobStore1 = ContextBuilder
.newBuilder("transient")
.credentials("identity1", "credential1")
.build(BlobStoreContext.class)
.getBlobStore();
blobStore1.createContainerInLocation(null, containerName);
final BlobStore blobStore2 = ContextBuilder
.newBuilder("transient")
.credentials("identity2", "credential2")
.build(BlobStoreContext.class)
.getBlobStore();
blobStore2.createContainerInLocation(null, containerName);
s3Proxy.setBlobStoreLocator(new BlobStoreLocator() {
@Override
public Map.Entry<String, BlobStore> locateBlobStore(
String identity, String container, String blob) {
if (identity.equals("identity1")) {
return Maps.immutableEntry("credential1", blobStore1);
} else if (identity.equals("identity2")) {
return Maps.immutableEntry("credential2", blobStore2);
} else {
return null;
}
}
});
client = AmazonS3ClientBuilder.standard()
.withClientConfiguration(V2_SIGNER_CONFIG)
.withCredentials(new AWSStaticCredentialsProvider(
new BasicAWSCredentials("identity1", "credential1")))
.withEndpointConfiguration(s3EndpointConfig).build();
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(BYTE_SOURCE.size());
client.putObject(containerName, "foo",
BYTE_SOURCE.openStream(), metadata);
S3Object object = client.getObject(containerName, "foo");
assertThat(object).isNotNull();
client = AmazonS3ClientBuilder.standard()
.withClientConfiguration(V2_SIGNER_CONFIG)
.withCredentials(new AWSStaticCredentialsProvider(
new BasicAWSCredentials("identity2", "credential2")))
.withEndpointConfiguration(s3EndpointConfig).build();
try {
client.getObject(containerName, "foo");
} catch (AmazonS3Exception e) {
assertThat(e.getErrorCode()).isEqualTo("NoSuchKey");
}
client = AmazonS3ClientBuilder.standard()
.withClientConfiguration(V2_SIGNER_CONFIG)
.withCredentials(new AWSStaticCredentialsProvider(
new BasicAWSCredentials("identity3", "credential3")))
.withEndpointConfiguration(s3EndpointConfig).build();
try {
client.getObject(containerName, "foo");
} catch (AmazonS3Exception e) {
assertThat(e.getErrorCode()).isEqualTo("InvalidAccessKeyId");
}
}
private static final class NullX509TrustManager
implements X509TrustManager {
@Override