Skip to content

Commit

Permalink
EPMRPP-90461 || Support AWS IAM Role (#1063) (#1064)
Browse files Browse the repository at this point in the history
  • Loading branch information
APiankouski authored Jan 17, 2025
1 parent bb8ea46 commit 2d959ce
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 8 deletions.
7 changes: 4 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,10 @@ dependencies {
api 'org.apache.commons:commons-compress:1.26.0'
implementation 'org.flywaydb:flyway-core:6.3.1'

api 'org.apache.jclouds.api:s3:2.5.0'
implementation 'org.apache.jclouds.provider:aws-s3:2.5.0'
implementation 'org.apache.jclouds.api:filesystem:2.5.0'
implementation 'software.amazon.awssdk:aws-core:2.29.50'
implementation 'software.amazon.awssdk:sts:2.29.50'
api 'org.apache.jclouds.provider:aws-s3:2.5.0'
api 'org.apache.jclouds.api:filesystem:2.5.0'

// add lombok support
compileOnly "org.projectlombok:lombok:${lombokVersion}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import com.google.inject.Module;
import java.util.Properties;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.jclouds.ContextBuilder;
import org.jclouds.aws.s3.config.AWSS3HttpApiModule;
import org.jclouds.blobstore.BlobStore;
Expand Down Expand Up @@ -215,14 +216,24 @@ public DataStore minioDataStore(@Autowired BlobStore blobStore,
*/
@Bean
@ConditionalOnProperty(name = "datastore.type", havingValue = "s3")
public BlobStore s3BlobStore(@Value("${datastore.accessKey}") String accessKey,
@Value("${datastore.secretKey}") String secretKey,
public BlobStore s3BlobStore(
@Value("${datastore.accessKey:}") String accessKey,
@Value("${datastore.secretKey:}") String secretKey,
@Value("${datastore.region}") String region) {
Iterable<Module> modules = ImmutableSet.of(new CustomBucketToRegionModule(region));

BlobStoreContext blobStoreContext =
ContextBuilder.newBuilder("aws-s3").modules(modules).credentials(accessKey, secretKey)
.buildView(BlobStoreContext.class);
BlobStoreContext blobStoreContext;
if (StringUtils.isNotEmpty(accessKey) && StringUtils.isNotEmpty(secretKey)) {
blobStoreContext = ContextBuilder.newBuilder("aws-s3")
.modules(modules)
.credentials(accessKey, secretKey)
.buildView(BlobStoreContext.class);
} else {
blobStoreContext = ContextBuilder.newBuilder("aws-s3")
.credentialsSupplier(new IAMCredentialSupplier())
.modules(modules)
.buildView(BlobStoreContext.class);
}

return blobStoreContext.getBlobStore();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Copyright 2025 EPAM Systems
*
* 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 com.epam.ta.reportportal.config;

import com.google.common.base.Supplier;
import java.time.Instant;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.jclouds.aws.domain.SessionCredentials;
import org.jclouds.domain.Credentials;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import software.amazon.awssdk.auth.credentials.AwsCredentials;
import software.amazon.awssdk.auth.credentials.AwsSessionCredentials;
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;

/**
* @author <a href="mailto:[email protected]">Andrei Piankouski</a>
*/
public class IAMCredentialSupplier implements Supplier<Credentials> {

private static final Logger LOGGER = LoggerFactory.getLogger(IAMCredentialSupplier.class);
private volatile SessionCredentials cachedCredentials;
private volatile Instant expirationTime;
private final Lock lock = new ReentrantLock();

@Override
public Credentials get() {
if (credentialsAreExpired()) {
lock.lock();
try {
if (credentialsAreExpired()) {
refreshCredentials();
}
} finally {
lock.unlock();
}
}
return cachedCredentials;
}

private boolean credentialsAreExpired() {
return cachedCredentials == null || Instant.now().isAfter(expirationTime);
}

private void refreshCredentials() {
LOGGER.debug("Refresh IAM Credentials");
AwsSessionCredentials awsCredentials = obtainAwsSessionCredentials();

if (awsCredentials != null) {
cachedCredentials = SessionCredentials.builder()
.accessKeyId(awsCredentials.accessKeyId())
.secretAccessKey(awsCredentials.secretAccessKey())
.sessionToken(awsCredentials.sessionToken())
.build();

expirationTime = Instant.now().plusSeconds(3600);
}
}

private AwsSessionCredentials obtainAwsSessionCredentials() {
DefaultCredentialsProvider defaultCredentialsProvider = DefaultCredentialsProvider.create();
AwsCredentials awsCredentials = defaultCredentialsProvider.resolveCredentials();
if (awsCredentials instanceof AwsSessionCredentials sessionCredentials) {
return sessionCredentials;
}
return null;
}

}

0 comments on commit 2d959ce

Please sign in to comment.