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: 6 additions & 0 deletions .changes/next-release/feature-AWSSDKforJavav2-c2d8ec6.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"type": "feature",
"category": "AWS SDK for Java v2",
"contributor": "",
"description": "Adds business metrics tracking for credential providers."
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
* provider via the 'software.amazon.awssdk.services.sts.internal.StsProfileCredentialsProviderFactory', assuming STS is on the
* classpath.
*/
@FunctionalInterface
@SdkProtectedApi
@FunctionalInterface
public interface ChildProfileCredentialsProviderFactory {
/**
* Create a credentials provider for the provided profile, using the provided source credentials provider to authenticate
Expand All @@ -41,4 +41,70 @@ public interface ChildProfileCredentialsProviderFactory {
* @return The credentials provider with permissions derived from the source credentials provider and profile.
*/
AwsCredentialsProvider create(AwsCredentialsProvider sourceCredentialsProvider, Profile profile);

/**
* Create a credentials provider for the provided profile, using the provided source credentials provider to authenticate
* with AWS. In the case of STS, the returned credentials provider is for a role that has been assumed, and the provided
* source credentials provider is the credentials that should be used to authenticate that the user is allowed to assume
* that role.
*
* @param request The request containing all parameters needed to create the child credentials provider.
* @return The credentials provider with permissions derived from the request parameters.
*/
default AwsCredentialsProvider create(ChildProfileCredentialsRequest request) {
return create(request.sourceCredentialsProvider(), request.profile());
}

final class ChildProfileCredentialsRequest {
private final AwsCredentialsProvider sourceCredentialsProvider;
private final Profile profile;
private final String sourceChain;

private ChildProfileCredentialsRequest(Builder builder) {
this.sourceCredentialsProvider = builder.sourceCredentialsProvider;
this.profile = builder.profile;
this.sourceChain = builder.sourceChain;
}

public static Builder builder() {
return new Builder();
}

public AwsCredentialsProvider sourceCredentialsProvider() {
return sourceCredentialsProvider;
}

public Profile profile() {
return profile;
}

public String sourceChain() {
return sourceChain;
}

public static final class Builder {
private AwsCredentialsProvider sourceCredentialsProvider;
private Profile profile;
private String sourceChain;

public Builder sourceCredentialsProvider(AwsCredentialsProvider sourceCredentialsProvider) {
this.sourceCredentialsProvider = sourceCredentialsProvider;
return this;
}

public Builder profile(Profile profile) {
this.profile = profile;
return this;
}

public Builder sourceChain(String sourceChain) {
this.sourceChain = sourceChain;
return this;
}

public ChildProfileCredentialsRequest build() {
return new ChildProfileCredentialsRequest(this);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import software.amazon.awssdk.auth.credentials.internal.HttpCredentialsLoader.LoadedCredentials;
import software.amazon.awssdk.core.SdkSystemSetting;
import software.amazon.awssdk.core.exception.SdkClientException;
import software.amazon.awssdk.core.useragent.BusinessMetricFeatureId;
import software.amazon.awssdk.core.util.SdkUserAgent;
import software.amazon.awssdk.regions.util.ResourcesEndpointProvider;
import software.amazon.awssdk.regions.util.ResourcesEndpointRetryPolicy;
Expand Down Expand Up @@ -72,7 +73,8 @@
public final class ContainerCredentialsProvider
implements HttpCredentialsProvider,
ToCopyableBuilder<ContainerCredentialsProvider.Builder, ContainerCredentialsProvider> {
private static final String PROVIDER_NAME = "ContainerCredentialsProvider";
private static final String CLASS_NAME = "ContainerCredentialsProvider";
private static final String PROVIDER_NAME = BusinessMetricFeatureId.CREDENTIALS_HTTP.value();
private static final Predicate<InetAddress> IS_LOOPBACK_ADDRESS = InetAddress::isLoopbackAddress;
private static final Predicate<InetAddress> ALLOWED_HOSTS_RULES = IS_LOOPBACK_ADDRESS;
private static final String HTTPS = "https";
Expand All @@ -90,6 +92,8 @@ public final class ContainerCredentialsProvider
private final Boolean asyncCredentialUpdateEnabled;

private final String asyncThreadName;
private final String sourceChain;
private final String providerName;

/**
* @see #builder()
Expand All @@ -98,7 +102,11 @@ private ContainerCredentialsProvider(BuilderImpl builder) {
this.endpoint = builder.endpoint;
this.asyncCredentialUpdateEnabled = builder.asyncCredentialUpdateEnabled;
this.asyncThreadName = builder.asyncThreadName;
this.httpCredentialsLoader = HttpCredentialsLoader.create(PROVIDER_NAME);
this.sourceChain = builder.sourceChain;
this.providerName = StringUtils.isEmpty(builder.sourceChain)
? PROVIDER_NAME
: builder.sourceChain + "," + PROVIDER_NAME;
this.httpCredentialsLoader = HttpCredentialsLoader.create(this.providerName);

if (Boolean.TRUE.equals(builder.asyncCredentialUpdateEnabled)) {
Validate.paramNotBlank(builder.asyncThreadName, "asyncThreadName");
Expand Down Expand Up @@ -126,7 +134,7 @@ public static Builder builder() {

@Override
public String toString() {
return ToString.create(PROVIDER_NAME);
return ToString.create(CLASS_NAME);
}

private RefreshResult<AwsCredentials> refreshCredentials() {
Expand Down Expand Up @@ -318,6 +326,7 @@ private static final class BuilderImpl implements Builder {
private String endpoint;
private Boolean asyncCredentialUpdateEnabled;
private String asyncThreadName;
private String sourceChain;

private BuilderImpl() {
asyncThreadName("container-credentials-provider");
Expand All @@ -327,6 +336,7 @@ private BuilderImpl(ContainerCredentialsProvider credentialsProvider) {
this.endpoint = credentialsProvider.endpoint;
this.asyncCredentialUpdateEnabled = credentialsProvider.asyncCredentialUpdateEnabled;
this.asyncThreadName = credentialsProvider.asyncThreadName;
this.sourceChain = credentialsProvider.sourceChain;
}

@Override
Expand Down Expand Up @@ -359,6 +369,21 @@ public void setAsyncThreadName(String asyncThreadName) {
asyncThreadName(asyncThreadName);
}

/**
* An optional string denoting previous credentials providers that are chained with this one.
* <p><b>Note:</b> This method is primarily intended for use by AWS SDK internal components
* and should not be used directly by external users.</p>
*/
@Override
public Builder sourceChain(String sourceChain) {
this.sourceChain = sourceChain;
return this;
}

public void setSourceChain(String sourceChain) {
sourceChain(sourceChain);
}

@Override
public ContainerCredentialsProvider build() {
return new ContainerCredentialsProvider(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import java.util.Optional;
import software.amazon.awssdk.annotations.SdkPublicApi;
import software.amazon.awssdk.auth.credentials.internal.SystemSettingsCredentialsProvider;
import software.amazon.awssdk.core.useragent.BusinessMetricFeatureId;
import software.amazon.awssdk.utils.SystemSetting;
import software.amazon.awssdk.utils.ToString;

Expand All @@ -28,7 +29,8 @@
@SdkPublicApi
public final class EnvironmentVariableCredentialsProvider extends SystemSettingsCredentialsProvider {

private static final String PROVIDER_NAME = "EnvironmentVariableCredentialsProvider";
private static final String CLASS_NAME = "EnvironmentVariableCredentialsProvider";
private static final String PROVIDER_NAME = BusinessMetricFeatureId.CREDENTIALS_ENV_VARS.value();

private EnvironmentVariableCredentialsProvider() {
}
Expand All @@ -52,6 +54,6 @@ protected String provider() {

@Override
public String toString() {
return ToString.create(PROVIDER_NAME);
return ToString.create(CLASS_NAME);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,15 @@ interface Builder<TypeToBuildT extends HttpCredentialsProvider, BuilderT extends
*/
BuilderT endpoint(String endpoint);

/**
* An optional string denoting previous credentials providers that are chained with this one.
* <p><b>Note:</b> This method is primarily intended for use by AWS SDK internal components
* and should not be used directly by external users.</p>
*/
default BuilderT sourceChain(String sourceChain) {
throw new UnsupportedOperationException();
}

/**
* Build the credentials provider based on the configuration on this builder.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,15 @@
import software.amazon.awssdk.core.SdkSystemSetting;
import software.amazon.awssdk.core.exception.SdkClientException;
import software.amazon.awssdk.core.exception.SdkServiceException;
import software.amazon.awssdk.core.useragent.BusinessMetricFeatureId;
import software.amazon.awssdk.profiles.ProfileFile;
import software.amazon.awssdk.profiles.ProfileFileSupplier;
import software.amazon.awssdk.profiles.ProfileFileSystemSetting;
import software.amazon.awssdk.profiles.ProfileProperty;
import software.amazon.awssdk.regions.util.HttpResourcesUtils;
import software.amazon.awssdk.regions.util.ResourcesEndpointProvider;
import software.amazon.awssdk.utils.Logger;
import software.amazon.awssdk.utils.StringUtils;
import software.amazon.awssdk.utils.ToString;
import software.amazon.awssdk.utils.Validate;
import software.amazon.awssdk.utils.builder.CopyableBuilder;
Expand All @@ -67,7 +69,8 @@ public final class InstanceProfileCredentialsProvider
implements HttpCredentialsProvider,
ToCopyableBuilder<InstanceProfileCredentialsProvider.Builder, InstanceProfileCredentialsProvider> {
private static final Logger log = Logger.loggerFor(InstanceProfileCredentialsProvider.class);
private static final String PROVIDER_NAME = "InstanceProfileCredentialsProvider";
private static final String CLASS_NAME = "InstanceProfileCredentialsProvider";
private static final String PROVIDER_NAME = BusinessMetricFeatureId.CREDENTIALS_IMDS.value();
private static final String EC2_METADATA_TOKEN_HEADER = "x-aws-ec2-metadata-token";
private static final String SECURITY_CREDENTIALS_RESOURCE = "/latest/meta-data/iam/security-credentials/";
private static final String TOKEN_RESOURCE = "/latest/api/token";
Expand All @@ -90,6 +93,9 @@ public final class InstanceProfileCredentialsProvider

private final Duration staleTime;

private final String sourceChain;
private final String providerName;

/**
* @see #builder()
*/
Expand All @@ -102,8 +108,12 @@ private InstanceProfileCredentialsProvider(BuilderImpl builder) {
.orElseGet(() -> ProfileFileSupplier.fixedProfileFile(ProfileFile.defaultProfileFile()));
this.profileName = Optional.ofNullable(builder.profileName)
.orElseGet(ProfileFileSystemSetting.AWS_PROFILE::getStringValueOrThrow);
this.sourceChain = builder.sourceChain;
this.providerName = StringUtils.isEmpty(builder.sourceChain)
? PROVIDER_NAME
: builder.sourceChain + "," + PROVIDER_NAME;

this.httpCredentialsLoader = HttpCredentialsLoader.create(PROVIDER_NAME);
this.httpCredentialsLoader = HttpCredentialsLoader.create(this.providerName);
this.configProvider =
Ec2MetadataConfigProvider.builder()
.profileFile(profileFile)
Expand Down Expand Up @@ -204,7 +214,7 @@ public void close() {

@Override
public String toString() {
return ToString.create(PROVIDER_NAME);
return ToString.create(CLASS_NAME);
}

private ResourcesEndpointProvider createEndpointProvider() {
Expand Down Expand Up @@ -372,6 +382,7 @@ static final class BuilderImpl implements Builder {
private Supplier<ProfileFile> profileFile;
private String profileName;
private Duration staleTime;
private String sourceChain;

private BuilderImpl() {
asyncThreadName("instance-profile-credentials-provider");
Expand All @@ -385,6 +396,7 @@ private BuilderImpl(InstanceProfileCredentialsProvider provider) {
this.profileFile = provider.profileFile;
this.profileName = provider.profileName;
this.staleTime = provider.staleTime;
this.sourceChain = provider.sourceChain;
}

Builder clock(Clock clock) {
Expand Down Expand Up @@ -463,6 +475,21 @@ public void setStaleTime(Duration duration) {
staleTime(duration);
}

/**
* An optional string denoting previous credentials providers that are chained with this one.
* <p><b>Note:</b> This method is primarily intended for use by AWS SDK internal components
* and should not be used directly by external users.</p>
*/
@Override
public Builder sourceChain(String sourceChain) {
this.sourceChain = sourceChain;
return this;
}

public void setSourceChain(String sourceChain) {
sourceChain(sourceChain);
}

@Override
public InstanceProfileCredentialsProvider build() {
return new InstanceProfileCredentialsProvider(this);
Expand Down
Loading
Loading