Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add RemoteS3ConnectionProvider plugin implementations #191

Open
wants to merge 2 commits into
base: feat/refactor-remote
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public TrinoGlueResource(ObjectMapper objectMapper, GlueRequestHandler requestHa
@Produces(MediaType.APPLICATION_JSON)
public Response gluePost(@Context Request request, @Context SigningMetadata signingMetadata, @Context RequestLoggingSession requestLoggingSession)
{
requestLoggingSession.logProperty("request.glue.emulated.key", signingMetadata.credentials().emulated().secretKey());
requestLoggingSession.logProperty("request.glue.emulated.key", signingMetadata.credential().secretKey());

String target = request.requestHeaders().unmodifiedHeaders().getFirst("x-amz-target")
.orElseThrow(() -> InvalidInputException.builder().statusCode(BAD_REQUEST.getStatusCode()).build());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
*/
package io.trino.aws.proxy.glue;

import io.trino.aws.proxy.spi.credentials.Credentials;
import io.trino.aws.proxy.spi.credentials.IdentityCredential;
import jakarta.annotation.PreDestroy;
import jakarta.ws.rs.core.UriBuilder;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -64,7 +64,7 @@ public abstract class TestGlueBase<T extends TestingGlueContext>
protected final GlueClient glueClient;
protected final T context;

protected TestGlueBase(TrinoGlueConfig config, Credentials testingCredentials, T context)
protected TestGlueBase(TrinoGlueConfig config, IdentityCredential testingCredentials, T context)
{
this.context = requireNonNull(context, "context is null");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import io.trino.aws.proxy.server.testing.TestingUtil.ForTesting;
import io.trino.aws.proxy.server.testing.harness.BuilderFilter;
import io.trino.aws.proxy.server.testing.harness.TrinoAwsProxyTest;
import io.trino.aws.proxy.spi.credentials.Credentials;
import io.trino.aws.proxy.spi.credentials.IdentityCredential;

import java.net.URI;

Expand Down Expand Up @@ -51,7 +51,7 @@ public record Context(URI baseUrl)
}

@Inject
public TestGlueInS3Proxy(TestingHttpServer httpServer, TrinoGlueConfig config, @ForTesting Credentials testingCredentials)
public TestGlueInS3Proxy(TestingHttpServer httpServer, TrinoGlueConfig config, @ForTesting IdentityCredential testingCredentials)
{
super(config, testingCredentials, new Context(httpServer.getBaseUrl()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,19 @@
package io.trino.aws.proxy.glue;

import io.trino.aws.proxy.spi.credentials.Credential;
import io.trino.aws.proxy.spi.credentials.Credentials;
import io.trino.aws.proxy.spi.credentials.CredentialsProvider;
import io.trino.aws.proxy.spi.credentials.IdentityCredential;

import java.util.Optional;
import java.util.UUID;

public class TestingCredentialsProvider
implements CredentialsProvider
{
public static final Credentials CREDENTIALS = Credentials.build(new Credential(UUID.randomUUID().toString(), UUID.randomUUID().toString()));
public static final IdentityCredential CREDENTIALS = new IdentityCredential(new Credential(UUID.randomUUID().toString(), UUID.randomUUID().toString()));

@Override
public Optional<Credentials> credentials(String emulatedAccessKey, Optional<String> session)
public Optional<IdentityCredential> credentials(String emulatedAccessKey, Optional<String> session)
{
return Optional.of(CREDENTIALS);
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,5 @@ public interface CredentialsProvider
* Your implementation should have a centralized credentials mechanism, likely
* some type of database along with a way of registering credentials, etc.
*/
Optional<Credentials> credentials(String emulatedAccessKey, Optional<String> session);
Optional<IdentityCredential> credentials(String emulatedAccessKey, Optional<String> session);
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public record EmulatedAssumedRole(Credential emulatedCredential, String arn, Str
{
public EmulatedAssumedRole
{
requireNonNull(emulatedCredential, "emulatedCredential is null");
requireNonNull(emulatedCredential, "credential is null");
requireNonNull(arn, "arn is null");
requireNonNull(roleId, "roleId is null");
requireNonNull(expiration, "expiration is null");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.trino.aws.proxy.spi.credentials;

import java.util.Optional;

import static java.util.Objects.requireNonNull;

public record IdentityCredential(Credential emulated, Optional<Identity> identity)
{
public IdentityCredential
{
requireNonNull(emulated, "emulated is null");
requireNonNull(identity, "identity is null");
}

public IdentityCredential(Credential emulatedCredential, Identity identity)
{
this(emulatedCredential, Optional.of(identity));
}

public IdentityCredential(Credential emulatedCredential)
{
this(emulatedCredential, Optional.empty());
}

public static IdentityCredential of(Credential emulatedCredential)
{
return new IdentityCredential(emulatedCredential, Optional.empty());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@
import io.trino.aws.proxy.spi.plugin.config.CredentialsProviderConfig;
import io.trino.aws.proxy.spi.plugin.config.PluginIdentifierConfig;
import io.trino.aws.proxy.spi.plugin.config.RemoteS3Config;
import io.trino.aws.proxy.spi.plugin.config.RemoteS3ConnectionProviderConfig;
import io.trino.aws.proxy.spi.plugin.config.S3RequestRewriterConfig;
import io.trino.aws.proxy.spi.plugin.config.S3SecurityFacadeProviderConfig;
import io.trino.aws.proxy.spi.remote.RemoteS3ConnectionProvider;
import io.trino.aws.proxy.spi.remote.RemoteS3Facade;
import io.trino.aws.proxy.spi.rest.S3RequestRewriter;
import io.trino.aws.proxy.spi.security.S3SecurityFacadeProvider;
Expand All @@ -49,6 +51,11 @@ static Module assumedRoleProviderModule(String identifier, Class<? extends Assum
return optionalPluginModule(AssumedRoleProviderConfig.class, identifier, AssumedRoleProvider.class, implementationClass, module);
}

static Module remoteS3ConnectionProviderModule(String identifier, Class<? extends RemoteS3ConnectionProvider> implementationClass, Module module)
{
return optionalPluginModule(RemoteS3ConnectionProviderConfig.class, identifier, RemoteS3ConnectionProvider.class, implementationClass, module);
}

static Module s3SecurityFacadeProviderModule(String identifier, Class<? extends S3SecurityFacadeProvider> implementationClass, Module module)
{
return optionalPluginModule(S3SecurityFacadeProviderConfig.class, identifier, S3SecurityFacadeProvider.class, implementationClass, module);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.trino.aws.proxy.spi.plugin.config;

import io.airlift.configuration.Config;
import jakarta.validation.constraints.NotNull;

import java.util.Optional;

public class RemoteS3ConnectionProviderConfig
implements PluginIdentifierConfig
{
private Optional<String> identifier = Optional.empty();

@NotNull
@Override
public Optional<String> getPluginIdentifier()
{
return identifier;
}

@Config("remote-s3-connection-provider.type")
public void setPluginIdentifier(String identifier)
{
this.identifier = Optional.ofNullable(identifier);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.trino.aws.proxy.spi.remote;

import com.google.common.collect.ImmutableMap;
import io.trino.aws.proxy.spi.credentials.Credential;

import java.util.Map;
import java.util.Optional;

import static java.util.Objects.requireNonNull;

public record RemoteS3Connection(
Credential remoteCredential,
Optional<RemoteSessionRole> remoteSessionRole,
Optional<Map<String, String>> remoteS3FacadeConfiguration)
{
public RemoteS3Connection
{
requireNonNull(remoteCredential, "remoteCredential is null");
requireNonNull(remoteSessionRole, "remoteSessionRole is null");
remoteS3FacadeConfiguration = requireNonNull(remoteS3FacadeConfiguration, "remoteS3FacadeConfiguration is null").map(ImmutableMap::copyOf);
}

public RemoteS3Connection(Credential remoteCredential)
{
this(remoteCredential, Optional.empty(), Optional.empty());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.trino.aws.proxy.spi.remote;

import io.trino.aws.proxy.spi.credentials.Identity;
import io.trino.aws.proxy.spi.rest.ParsedS3Request;
import io.trino.aws.proxy.spi.signing.SigningMetadata;

import java.util.Optional;

// TODO: This should have a config implementation (hard-coding a single set of Remote Credentials) and an HTTP implementation
public interface RemoteS3ConnectionProvider
{
RemoteS3ConnectionProvider NOOP = (_, _, _) -> Optional.empty();

Optional<RemoteS3Connection> remoteConnection(SigningMetadata signingMetadata, Optional<Identity> identity, ParsedS3Request request);
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@
*/
package io.trino.aws.proxy.spi.remote;

import java.net.URI;
import java.util.Optional;

import static java.util.Objects.requireNonNull;

public record RemoteSessionRole(String region, String roleArn, Optional<String> externalId)
public record RemoteSessionRole(String region, String roleArn, Optional<String> externalId, Optional<URI> stsEndpoint)
{
public RemoteSessionRole
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,25 @@
*/
package io.trino.aws.proxy.spi.rest;

import io.trino.aws.proxy.spi.credentials.Credentials;
import io.trino.aws.proxy.spi.credentials.Identity;
import io.trino.aws.proxy.spi.signing.SigningMetadata;

import java.util.Optional;

import static java.util.Objects.requireNonNull;

public interface S3RequestRewriter
{
S3RequestRewriter NOOP = (_, _) -> Optional.empty();
S3RequestRewriter NOOP = (_, _, _) -> Optional.empty();

record S3RewriteResult(String finalRequestBucket, String finalRequestKey)
{
public S3RewriteResult {
public S3RewriteResult
{
requireNonNull(finalRequestBucket, "finalRequestBucket is null");
requireNonNull(finalRequestKey, "finalRequestKey is null");
}
}

Optional<S3RewriteResult> rewrite(Credentials credentials, ParsedS3Request request);
Optional<S3RewriteResult> rewrite(Optional<Identity> identity, SigningMetadata signingMetadata, ParsedS3Request request);
}
Loading
Loading