Skip to content

Commit

Permalink
Update logic to read the region when reading non default profiles
Browse files Browse the repository at this point in the history
  • Loading branch information
gcbeattyAWS committed Oct 31, 2024
1 parent d845c36 commit 2565a7a
Show file tree
Hide file tree
Showing 14 changed files with 1,078 additions and 20 deletions.
38 changes: 24 additions & 14 deletions src/AWS.Deploy.CLI/AWSUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using System.Linq;
using System.Threading.Tasks;
using Amazon.Runtime;
using Amazon.Runtime.CredentialManagement;
using AWS.Deploy.CLI.Utilities;
using AWS.Deploy.Common;
using AWS.Deploy.Common.IO;
Expand All @@ -17,7 +16,7 @@ namespace AWS.Deploy.CLI
{
public interface IAWSUtilities
{
Task<AWSCredentials> ResolveAWSCredentials(string? profileName);
Task<Tuple<AWSCredentials, string?>> ResolveAWSCredentials(string? profileName);
string ResolveAWSRegion(string? region, string? lastRegionUsed = null);
}

Expand All @@ -28,26 +27,35 @@ public class AWSUtilities : IAWSUtilities
private readonly IDirectoryManager _directoryManager;
private readonly IOptionSettingHandler _optionSettingHandler;
private readonly IServiceProvider _serviceProvider;
private readonly ICredentialProfileStoreChainFactory _credentialChainFactory;
private readonly ISharedCredentialsFileFactory _sharedCredentialsFileFactory;
private readonly IFallbackCredentialsFactoryFactory _fallbackCredentialsFactory;

public AWSUtilities(
IServiceProvider serviceProvider,
IToolInteractiveService toolInteractiveService,
IConsoleUtilities consoleUtilities,
IDirectoryManager directoryManager,
IOptionSettingHandler optionSettingHandler)
IOptionSettingHandler optionSettingHandler,
ICredentialProfileStoreChainFactory credentialChainFactory,
ISharedCredentialsFileFactory sharedCredentialsFileFactory,
IFallbackCredentialsFactoryFactory fallbackCredentialsFactory)
{
_serviceProvider = serviceProvider;
_toolInteractiveService = toolInteractiveService;
_consoleUtilities = consoleUtilities;
_directoryManager = directoryManager;
_optionSettingHandler = optionSettingHandler;
_credentialChainFactory = credentialChainFactory;
_sharedCredentialsFileFactory = sharedCredentialsFileFactory;
_fallbackCredentialsFactory = fallbackCredentialsFactory;
}

public async Task<AWSCredentials> ResolveAWSCredentials(string? profileName)
public async Task<Tuple<AWSCredentials, string?>> ResolveAWSCredentials(string? profileName)
{
async Task<AWSCredentials> Resolve()
async Task<Tuple<AWSCredentials, string?>> Resolve()
{
var chain = new CredentialProfileStoreChain();
var chain = _credentialChainFactory.Create();

if (!string.IsNullOrEmpty(profileName))
{
Expand All @@ -56,7 +64,8 @@ async Task<AWSCredentials> Resolve()
(profileCredentials is AssumeRoleAWSCredentials || await CanLoadCredentials(profileCredentials)))
{
_toolInteractiveService.WriteLine($"Configuring AWS Credentials from Profile {profileName}.");
return profileCredentials;
chain.TryGetProfile(profileName, out var profile);
return Tuple.Create<AWSCredentials, string?>(profileCredentials, profile.Region?.SystemName);
}
else
{
Expand All @@ -67,12 +76,12 @@ async Task<AWSCredentials> Resolve()

try
{
var fallbackCredentials = FallbackCredentialsFactory.GetCredentials();
var fallbackCredentials = _fallbackCredentialsFactory.Create();

if (await CanLoadCredentials(fallbackCredentials))
{
_toolInteractiveService.WriteLine("Configuring AWS Credentials using AWS SDK credential search.");
return fallbackCredentials;
return Tuple.Create<AWSCredentials, string?>(fallbackCredentials, null);
}
}
catch (AmazonServiceException ex)
Expand All @@ -82,7 +91,7 @@ async Task<AWSCredentials> Resolve()
_toolInteractiveService.WriteDebugLine(ex.PrettyPrint());
}

var sharedCredentials = new SharedCredentialsFile();
var sharedCredentials = _sharedCredentialsFileFactory.Create();
if (sharedCredentials.ListProfileNames().Count == 0)
{
throw new NoAWSCredentialsFoundException(DeployToolErrorCode.UnableToResolveAWSCredentials, "Unable to resolve AWS credentials to access AWS.");
Expand All @@ -93,21 +102,22 @@ async Task<AWSCredentials> Resolve()
if (chain.TryGetAWSCredentials(selectedProfileName, out var selectedProfileCredentials) &&
(await CanLoadCredentials(selectedProfileCredentials)))
{
return selectedProfileCredentials;
chain.TryGetProfile(selectedProfileName, out var profile);
return Tuple.Create<AWSCredentials, string?>(selectedProfileCredentials, profile.Region?.SystemName);
}

throw new NoAWSCredentialsFoundException(DeployToolErrorCode.UnableToCreateAWSCredentials, $"Unable to create AWS credentials for profile {selectedProfileName}.");
}

var credentials = await Resolve();
var credentialsAndRegion = await Resolve();

if (credentials is AssumeRoleAWSCredentials assumeRoleAWSCredentials)
if (credentialsAndRegion.Item1 is AssumeRoleAWSCredentials assumeRoleAWSCredentials)
{
var assumeOptions = assumeRoleAWSCredentials.Options;
assumeOptions.MfaTokenCodeCallback = ActivatorUtilities.CreateInstance<AssumeRoleMfaTokenCodeCallback>(_serviceProvider, assumeOptions).Execute;
}

return credentials;
return credentialsAndRegion;
}

private async Task<bool> CanLoadCredentials(AWSCredentials credentials)
Expand Down
12 changes: 6 additions & 6 deletions src/AWS.Deploy.CLI/Commands/CommandFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,8 @@ private Command BuildDeployCommand()
deploymentSettings = await _deploymentSettingsHandler.ReadSettings(applyPath);
}

var awsCredentials = await _awsUtilities.ResolveAWSCredentials(input.Profile ?? deploymentSettings?.AWSProfile);
var awsRegion = _awsUtilities.ResolveAWSRegion(input.Region ?? deploymentSettings?.AWSRegion);
var (awsCredentials, regionFromProfile) = await _awsUtilities.ResolveAWSCredentials(input.Profile ?? deploymentSettings?.AWSProfile);
var awsRegion = _awsUtilities.ResolveAWSRegion((input.Region ?? deploymentSettings?.AWSRegion) ?? regionFromProfile);

_commandLineWrapper.RegisterAWSContext(awsCredentials, awsRegion);
_awsClientFactory.RegisterAWSContext(awsCredentials, awsRegion);
Expand Down Expand Up @@ -318,8 +318,8 @@ private Command BuildDeleteCommand()
_toolInteractiveService.Diagnostics = input.Diagnostics;
_toolInteractiveService.DisableInteractive = input.Silent;

var awsCredentials = await _awsUtilities.ResolveAWSCredentials(input.Profile);
var awsRegion = _awsUtilities.ResolveAWSRegion(input.Region);
var (awsCredentials, regionFromProfile) = await _awsUtilities.ResolveAWSCredentials(input.Profile);
var awsRegion = _awsUtilities.ResolveAWSRegion(input.Region ?? regionFromProfile);

_awsClientFactory.ConfigureAWSOptions(awsOption =>
{
Expand Down Expand Up @@ -401,8 +401,8 @@ private Command BuildListCommand()
{
_toolInteractiveService.Diagnostics = input.Diagnostics;

var awsCredentials = await _awsUtilities.ResolveAWSCredentials(input.Profile);
var awsRegion = _awsUtilities.ResolveAWSRegion(input.Region);
var (awsCredentials, regionFromProfile) = await _awsUtilities.ResolveAWSCredentials(input.Profile);
var awsRegion = _awsUtilities.ResolveAWSRegion(input.Region ?? regionFromProfile);

_awsClientFactory.ConfigureAWSOptions(awsOptions =>
{
Expand Down
21 changes: 21 additions & 0 deletions src/AWS.Deploy.CLI/CredentialProfileStoreChainFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

using Amazon.Runtime.CredentialManagement;

namespace AWS.Deploy.CLI
{
/// <summary>
/// Represents a factory for creating CredentialProfileStoreChain
/// </summary>
public class CredentialProfileStoreChainFactory : ICredentialProfileStoreChainFactory
{
/// <summary>
/// Creates a CredentialProfileStoreChain
/// </summary>
public CredentialProfileStoreChain Create()
{
return new CredentialProfileStoreChain();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ public static void AddCustomServices(this IServiceCollection serviceCollection,
serviceCollection.TryAdd(new ServiceDescriptor(typeof(IEnvironmentVariableManager), typeof(EnvironmentVariableManager), lifetime));
serviceCollection.TryAdd(new ServiceDescriptor(typeof(IDeployToolWorkspaceMetadata), typeof(DeployToolWorkspaceMetadata), lifetime));
serviceCollection.TryAdd(new ServiceDescriptor(typeof(IDeploymentSettingsHandler), typeof(DeploymentSettingsHandler), lifetime));
serviceCollection.TryAdd(new ServiceDescriptor(typeof(ICredentialProfileStoreChainFactory), typeof(CredentialProfileStoreChainFactory), lifetime));
serviceCollection.TryAdd(new ServiceDescriptor(typeof(ISharedCredentialsFileFactory), typeof(SharedCredentialsFileFactory), lifetime));
serviceCollection.TryAdd(new ServiceDescriptor(typeof(IFallbackCredentialsFactoryFactory), typeof(FallbackCredentialsFactoryFactory), lifetime));

var packageJsonTemplate = typeof(PackageJsonGenerator).Assembly.ReadEmbeddedFile(PackageJsonGenerator.TemplateIdentifier);
serviceCollection.TryAdd(new ServiceDescriptor(typeof(IPackageJsonGenerator), (serviceProvider) => new PackageJsonGenerator(packageJsonTemplate), lifetime));
Expand Down
21 changes: 21 additions & 0 deletions src/AWS.Deploy.CLI/FallbackCredentialsFactoryFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

using Amazon.Runtime;

namespace AWS.Deploy.CLI
{
/// <summary>
/// Represents a factory for creating AWSCredentials
/// </summary>
public class FallbackCredentialsFactoryFactory : IFallbackCredentialsFactoryFactory
{
/// <summary>
/// Creates AWSCredentials
/// </summary>
public AWSCredentials Create()
{
return FallbackCredentialsFactory.GetCredentials();
}
}
}
18 changes: 18 additions & 0 deletions src/AWS.Deploy.CLI/ICredentialProfileStoreChainFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

using Amazon.Runtime.CredentialManagement;

namespace AWS.Deploy.CLI
{
/// <summary>
/// Represents a factory for creating CredentialProfileStoreChain
/// </summary>
public interface ICredentialProfileStoreChainFactory
{
/// <summary>
/// Creates a CredentialProfileStoreChain
/// </summary>
CredentialProfileStoreChain Create();
}
}
18 changes: 18 additions & 0 deletions src/AWS.Deploy.CLI/IFallbackCredentialsFactoryFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

using Amazon.Runtime;

namespace AWS.Deploy.CLI
{
/// <summary>
/// Represents a factory for creating AWSCredentials
/// </summary>
public interface IFallbackCredentialsFactoryFactory
{
/// <summary>
/// Creates AWSCredentials
/// </summary>
AWSCredentials Create();
}
}
18 changes: 18 additions & 0 deletions src/AWS.Deploy.CLI/ISharedCredentialsFileFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

using Amazon.Runtime.CredentialManagement;

namespace AWS.Deploy.CLI
{
/// <summary>
/// Represents a factory for creating SharedCredentialsFile
/// </summary>
public interface ISharedCredentialsFileFactory
{
/// <summary>
/// Creates a SharedCredentialsFile
/// </summary>
SharedCredentialsFile Create();
}
}
21 changes: 21 additions & 0 deletions src/AWS.Deploy.CLI/SharedCredentialsFileFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

using Amazon.Runtime.CredentialManagement;

namespace AWS.Deploy.CLI
{
/// <summary>
/// Represents a factory for creating SharedCredentialsFile
/// </summary>
public class SharedCredentialsFileFactory : ISharedCredentialsFileFactory
{
/// <summary>
/// Creates a SharedCredentialsFile
/// </summary>
public SharedCredentialsFile Create()
{
return new SharedCredentialsFile();
}
}
}
Loading

0 comments on commit 2565a7a

Please sign in to comment.