kopia lustrzana https://github.com/gaul/s3proxy
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-credentialblobstore-locator
rodzic
a09c9e1998
commit
6a712d5945
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
package org.gaul.s3proxy;
|
package org.gaul.s3proxy;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
|
||||||
import java.io.Console;
|
import java.io.Console;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
|
@ -24,6 +26,7 @@ import java.io.InputStream;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
@ -31,6 +34,7 @@ import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.io.Files;
|
import com.google.common.io.Files;
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
|
|
||||||
|
@ -59,6 +63,10 @@ public final class Main {
|
||||||
usage = "S3Proxy configuration (required)")
|
usage = "S3Proxy configuration (required)")
|
||||||
private File propertiesFile;
|
private File propertiesFile;
|
||||||
|
|
||||||
|
@Option(name = "--credentials-properties",
|
||||||
|
usage = "Mapping for multiple credentials")
|
||||||
|
private File credentialsPropertyFile;
|
||||||
|
|
||||||
@Option(name = "--version", usage = "display version")
|
@Option(name = "--version", usage = "display version")
|
||||||
private boolean version;
|
private boolean version;
|
||||||
}
|
}
|
||||||
|
@ -91,6 +99,14 @@ public final class Main {
|
||||||
}
|
}
|
||||||
properties.putAll(System.getProperties());
|
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(
|
String s3ProxyEndpointString = properties.getProperty(
|
||||||
S3ProxyConstants.PROPERTY_ENDPOINT);
|
S3ProxyConstants.PROPERTY_ENDPOINT);
|
||||||
String secureEndpoint = properties.getProperty(
|
String secureEndpoint = properties.getProperty(
|
||||||
|
@ -238,6 +254,33 @@ public final class Main {
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
throw e;
|
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 {
|
try {
|
||||||
s3Proxy.start();
|
s3Proxy.start();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
|
@ -87,10 +87,13 @@ import com.amazonaws.services.s3.model.UploadPartRequest;
|
||||||
import com.amazonaws.services.s3.model.UploadPartResult;
|
import com.amazonaws.services.s3.model.UploadPartResult;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.io.ByteSource;
|
import com.google.common.io.ByteSource;
|
||||||
|
|
||||||
import org.assertj.core.api.Fail;
|
import org.assertj.core.api.Fail;
|
||||||
|
|
||||||
|
import org.jclouds.ContextBuilder;
|
||||||
|
import org.jclouds.blobstore.BlobStore;
|
||||||
import org.jclouds.blobstore.BlobStoreContext;
|
import org.jclouds.blobstore.BlobStoreContext;
|
||||||
import org.jclouds.rest.HttpClient;
|
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
|
private static final class NullX509TrustManager
|
||||||
implements X509TrustManager {
|
implements X509TrustManager {
|
||||||
@Override
|
@Override
|
||||||
|
|
Ładowanie…
Reference in New Issue