Skip to content
Merged
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
6 changes: 3 additions & 3 deletions examples/examples-release-latest/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-sts</artifactId>
<groupId>software.amazon.awssdk</groupId>
<artifactId>sts</artifactId>
</dependency>

</dependencies>
Expand All @@ -116,4 +116,4 @@
</plugins>
</build>

</project>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
*/
package io.kubernetes.client.examples;

import com.amazonaws.auth.DefaultAWSCredentialsProviderChain;
import com.amazonaws.auth.STSAssumeRoleSessionCredentialsProvider;
import io.kubernetes.client.openapi.ApiClient;
import io.kubernetes.client.openapi.ApiException;
import io.kubernetes.client.openapi.models.VersionInfo;
Expand All @@ -22,6 +20,9 @@
import io.kubernetes.client.util.version.Version;

import java.io.IOException;
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
import software.amazon.awssdk.services.sts.StsClient;
import software.amazon.awssdk.services.sts.auth.StsAssumeRoleCredentialsProvider;

public class EKSAuthenticationExample {
public static void main(String[] args) throws IOException, ApiException {
Expand All @@ -37,10 +38,14 @@ public static void main(String[] args) throws IOException, ApiException {
// EKS cluster name.
String clusterName = "test-2";

STSAssumeRoleSessionCredentialsProvider credProvider = new STSAssumeRoleSessionCredentialsProvider(
new DefaultAWSCredentialsProviderChain().getCredentials(),
roleArn,
roleSessionName);
StsClient stsClient = StsClient.builder()
.credentialsProvider(DefaultCredentialsProvider.builder().build())
.build();

StsAssumeRoleCredentialsProvider credProvider = StsAssumeRoleCredentialsProvider.builder()
.stsClient(stsClient)
.refreshRequest(r -> r.roleArn(roleArn).roleSessionName(roleSessionName))
.build();

ApiClient apiClient = ClientBuilder.standard()
.setAuthentication(new EKSAuthentication(credProvider, region, clusterName))
Expand Down
8 changes: 4 additions & 4 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
https://issues.apache.org/jira/browse/MNG-5632. Therefore, we specify
optional dependencies here to manage them in a single location. -->
<prometheus.client.optional>true</prometheus.client.optional>
<com.amazonaws.aws-java-sdk-sts.optional>true</com.amazonaws.aws-java-sdk-sts.optional>
<software.amazon.awssdk.sts.optional>true</software.amazon.awssdk.sts.optional>
<com.google.auth.google-auth-library-oauth2-http.optional>true</com.google.auth.google-auth-library-oauth2-http.optional>
<org.springframework.boot.spring-boot-actuator.optional>true</org.springframework.boot.spring-boot-actuator.optional>

Expand Down Expand Up @@ -150,9 +150,9 @@
<version>${bouncycastle.version}</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-sts</artifactId>
<version>1.12.787</version>
<groupId>software.amazon.awssdk</groupId>
<artifactId>sts</artifactId>
<version>2.31.70</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
Expand Down
6 changes: 3 additions & 3 deletions util/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@
<artifactId>bcpkix-jdk18on</artifactId>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-sts</artifactId>
<optional>${com.amazonaws.aws-java-sdk-sts.optional}</optional>
<groupId>software.amazon.awssdk</groupId>
<artifactId>sts</artifactId>
<optional>${software.amazon.awssdk.sts.optional}</optional>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,23 @@
*/
package io.kubernetes.client.util.credentials;

import com.amazonaws.DefaultRequest;
import com.amazonaws.auth.AWS4Signer;
import com.amazonaws.auth.AWSSessionCredentialsProvider;
import com.amazonaws.http.HttpMethodName;
import com.amazonaws.services.securitytoken.model.GetCallerIdentityRequest;
import com.amazonaws.util.RuntimeHttpUtils;
import io.kubernetes.client.openapi.ApiClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.http.SdkHttpMethod;
import software.amazon.awssdk.http.SdkHttpRequest;
import software.amazon.awssdk.http.auth.aws.signer.AwsV4FamilyHttpSigner;
import software.amazon.awssdk.http.auth.aws.signer.AwsV4HttpSigner;
import software.amazon.awssdk.http.auth.spi.signer.SignedRequest;
import software.amazon.awssdk.utils.http.SdkHttpUtils;

import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.time.Clock;
import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Base64;
import java.util.Date;

/**
* EKS cluster authentication which generates a bearer token from AWS AK/SK. It doesn't require an "aws"
Expand All @@ -45,11 +45,11 @@ public class EKSAuthentication implements Authentication {
* @param region the region where EKS cluster at
* @param clusterName the EKS cluster name
*/
public EKSAuthentication(AWSSessionCredentialsProvider provider, String region, String clusterName) {
public EKSAuthentication(AwsCredentialsProvider provider, String region, String clusterName) {
this(provider, region, clusterName, MAX_EXPIRY_SECONDS);
}

public EKSAuthentication(AWSSessionCredentialsProvider provider, String region, String clusterName, int expirySeconds) {
public EKSAuthentication(AwsCredentialsProvider provider, String region, String clusterName, int expirySeconds) {
this.provider = provider;
this.region = region;
this.clusterName = clusterName;
Expand All @@ -61,7 +61,7 @@ public EKSAuthentication(AWSSessionCredentialsProvider provider, String region,
}

private static final int MAX_EXPIRY_SECONDS = 60 * 15;
private final AWSSessionCredentialsProvider provider;
private final AwsCredentialsProvider provider;
private final String region;
private final String clusterName;
private final URI stsEndpoint;
Expand All @@ -70,30 +70,41 @@ public EKSAuthentication(AWSSessionCredentialsProvider provider, String region,

@Override
public void provide(ApiClient client) {
DefaultRequest<GetCallerIdentityRequest> defaultRequest =
new DefaultRequest<>(new GetCallerIdentityRequest(), "sts");
defaultRequest.setResourcePath("/");
defaultRequest.setEndpoint(stsEndpoint);
defaultRequest.setHttpMethod(HttpMethodName.GET);
defaultRequest.addParameter("Action", "GetCallerIdentity");
defaultRequest.addParameter("Version", "2011-06-15");
defaultRequest.addHeader("x-k8s-aws-id", clusterName);
AWS4Signer signer = new AWS4Signer();
Date expirationTime = new Date(Clock.systemDefaultZone().millis() + 60 * 1000);
signer.setServiceName("sts");
signer.presignRequest(
defaultRequest,
this.provider.getCredentials(),
expirationTime);
String encodedUrl =
Base64.getUrlEncoder()
.withoutPadding()
.encodeToString( RuntimeHttpUtils.convertRequestToUrl(
defaultRequest, true, false).toString()
.getBytes(StandardCharsets.UTF_8));
SdkHttpRequest httpRequest = generateStsRequest();
String presignedUrl = requestToPresignedUrl(httpRequest);
String encodedUrl = presignedUrlToEncodedUrl(presignedUrl);
String token = "k8s-aws-v1." + encodedUrl;
client.setApiKeyPrefix("Bearer");
client.setApiKey(token);
log.info("Generated BEARER token for ApiClient, expiring at {}", Instant.now().plus(expirySeconds, ChronoUnit.SECONDS));
}

private static String presignedUrlToEncodedUrl(String presignedUrl) {
return Base64.getUrlEncoder()
.withoutPadding()
.encodeToString(SdkHttpUtils.urlEncodeIgnoreSlashes(presignedUrl).getBytes(StandardCharsets.UTF_8));
}

private SdkHttpRequest generateStsRequest() {
return SdkHttpRequest.builder()
.uri(stsEndpoint)
.putRawQueryParameter("Version", "2011-06-15")
.putRawQueryParameter("Action", "GetCallerIdentity")
.method(SdkHttpMethod.GET)
.putHeader("x-k8s-aws-id", clusterName)
.build();
}

private String requestToPresignedUrl(SdkHttpRequest httpRequest) {
AwsV4HttpSigner signer = AwsV4HttpSigner.create();
SignedRequest signedRequest =
signer.sign(r -> r.identity(this.provider.resolveCredentials())
.request(httpRequest)
.putProperty(AwsV4HttpSigner.SERVICE_SIGNING_NAME, "sts")
.putProperty(AwsV4HttpSigner.REGION_NAME, region)
.putProperty(AwsV4HttpSigner.AUTH_LOCATION, AwsV4HttpSigner.AuthLocation.QUERY_STRING)
.putProperty(AwsV4HttpSigner.EXPIRATION_DURATION, Duration.of(60, ChronoUnit.SECONDS)));
SdkHttpRequest request = signedRequest.request();
return request.getUri().toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@
*/
package io.kubernetes.client.util.credentials;

import com.amazonaws.auth.AWSSessionCredentialsProvider;
import com.amazonaws.auth.BasicSessionCredentials;
import io.kubernetes.client.openapi.ApiClient;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.auth.credentials.AwsSessionCredentials;

import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.verify;
Expand All @@ -28,7 +28,7 @@
class EKSAuthenticationTest {

@Mock
private AWSSessionCredentialsProvider provider;
private AwsCredentialsProvider provider;

@Mock
private ApiClient apiClient;
Expand All @@ -39,7 +39,7 @@ class EKSAuthenticationTest {

@Test
void provideApiClient() {
when(provider.getCredentials()).thenReturn(new BasicSessionCredentials("ak", "sk", "session"));
when(provider.resolveCredentials()).thenReturn(AwsSessionCredentials.create("ak", "sk", "session"));
EKSAuthentication authentication = new EKSAuthentication(provider, region, clusterName);
authentication.provide(apiClient);
verify(apiClient).setApiKey(anyString());
Expand Down
Loading