[LYN-2151] Add argument to override aws profile and config file path (#994)

main
Vincent Liu 5 years ago committed by GitHub
parent 00e860f326
commit 9fb4ce59c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -38,6 +38,11 @@ namespace AWSCore
//! @return The path of AWS resource mapping config file
virtual AZStd::string GetResourceMappingConfigFilePath() const = 0;
//! GetResourceMappingConfigFolderPath
//! Get the path of AWS resource mapping config folder
//! @return The path of AWS resource mapping config folder
virtual AZStd::string GetResourceMappingConfigFolderPath() const = 0;
//! ReloadConfiguration
//! Reload AWSCore configuration without restarting application
virtual void ReloadConfiguration() = 0;

@ -53,6 +53,7 @@ namespace AWSCore
// AWSCoreInternalRequestBus interface implementation
AZStd::string GetResourceMappingConfigFilePath() const override;
AZStd::string GetResourceMappingConfigFolderPath() const override;
AZStd::string GetProfileName() const override;
void ReloadConfiguration() override;

@ -58,6 +58,19 @@ namespace AWSCore
return configFilePath;
}
AZStd::string AWSCoreConfiguration::GetResourceMappingConfigFolderPath() const
{
if (m_sourceProjectFolder.empty())
{
AZ_Warning(AWSCoreConfigurationName, false, ProjectSourceFolderNotFoundErrorMessage);
return "";
}
AZStd::string configFolderPath = AZStd::string::format(
"%s/%s", m_sourceProjectFolder.c_str(), AWSCoreResourceMappingConfigFolderName);
AzFramework::StringFunc::Path::Normalize(configFolderPath);
return configFolderPath;
}
void AWSCoreConfiguration::InitConfig()
{
InitSourceProjectFolderPath();
@ -123,7 +136,7 @@ namespace AWSCore
auto profileNamePath = AZStd::string::format("%s%s",
AZ::SettingsRegistryMergeUtils::OrganizationRootKey, AWSCoreProfileNameKey);
m_settingsRegistry.Remove(profileNamePath);
m_profileName.clear();
m_profileName = AWSCoreDefaultProfileName;
auto resourceMappingConfigFileNamePath = AZStd::string::format("%s%s",
AZ::SettingsRegistryMergeUtils::OrganizationRootKey, AWSCoreResourceMappingConfigFileNameKey);

@ -14,6 +14,7 @@
#include <AzCore/Utils/Utils.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <AWSCoreInternalBus.h>
#include <Editor/UI/AWSCoreResourceMappingToolAction.h>
namespace AWSCore
@ -108,17 +109,24 @@ namespace AWSCore
{
return "";
}
AZStd::string profileName = "default";
AWSCoreInternalRequestBus::BroadcastResult(profileName, &AWSCoreInternalRequests::GetProfileName);
AZStd::string configPath = "";
AWSCoreInternalRequestBus::BroadcastResult(configPath, &AWSCoreInternalRequests::GetResourceMappingConfigFolderPath);
if (m_isDebug)
{
return AZStd::string::format(
"%s debug %s --binaries_path %s --debug",
m_enginePythonEntryPath.c_str(), m_toolScriptPath.c_str(), m_toolQtBinDirectoryPath.c_str());
"%s debug %s --binaries_path %s --debug --profile %s --config_path %s", m_enginePythonEntryPath.c_str(),
m_toolScriptPath.c_str(), m_toolQtBinDirectoryPath.c_str(), profileName.c_str(), configPath.c_str());
}
else
{
return AZStd::string::format(
"%s %s --binaries_path %s",
m_enginePythonEntryPath.c_str(), m_toolScriptPath.c_str(), m_toolQtBinDirectoryPath.c_str());
"%s %s --binaries_path %s --profile %s --config_path %s", m_enginePythonEntryPath.c_str(),
m_toolScriptPath.c_str(), m_toolQtBinDirectoryPath.c_str(), profileName.c_str(), configPath.c_str());
}
}

@ -34,7 +34,8 @@ public:
MOCK_METHOD0(GetAWSCredentials, Aws::Auth::AWSCredentials());
};
class AWSDefaultCredentialHandlerMock : public AWSDefaultCredentialHandler
class AWSDefaultCredentialHandlerMock
: public AWSDefaultCredentialHandler
{
public:
void SetupMocks(
@ -76,6 +77,7 @@ public:
// AWSCoreInternalRequestBus interface implementation
AZStd::string GetProfileName() const override { return m_profileName; }
AZStd::string GetResourceMappingConfigFilePath() const override { return ""; }
AZStd::string GetResourceMappingConfigFolderPath() const override { return ""; }
void ReloadConfiguration() override {}
std::shared_ptr<EnvironmentAWSCredentialsProviderMock> m_environmentCredentialsProviderMock;

@ -119,6 +119,7 @@ public:
// AWSCoreInternalRequestBus interface implementation
AZStd::string GetProfileName() const override { return ""; }
AZStd::string GetResourceMappingConfigFilePath() const override { return m_normalizedConfigFilePath; }
AZStd::string GetResourceMappingConfigFolderPath() const override { return m_normalizedConfigFolderPath; }
void ReloadConfiguration() override { m_reloadConfigurationCounter++; }
AZStd::unique_ptr<AWSCore::AWSResourceMappingManager> m_resourceMappingManager;

@ -48,10 +48,13 @@ class ConfigurationManager(object):
def configuration(self, new_configuration: ConfigurationManager) -> None:
self._configuration = new_configuration
def setup(self) -> None:
def setup(self, config_path: str) -> None:
logger.info("Setting up default configuration ...")
# TODO: remove config directory and files default setup once integrating with user input
try:
normalized_config_path: str = file_utils.normalize_file_path(config_path);
if normalized_config_path:
self._configuration.config_directory = normalized_config_path
else:
self._configuration.config_directory = file_utils.get_current_directory_path()
self._configuration.config_files = \
file_utils.find_files_with_suffix_under_directory(self._configuration.config_directory,

@ -13,13 +13,16 @@ from argparse import (ArgumentParser, Namespace)
import logging
import sys
from utils import aws_utils
from utils import environment_utils
from utils import file_utils
# arguments setup
argument_parser: ArgumentParser = ArgumentParser()
argument_parser.add_argument('--binaries_path', help='Path to QT Binaries necessary for PySide.')
argument_parser.add_argument('--config_path', help='Path to resource mapping config directory.')
argument_parser.add_argument('--debug', action='store_true', help='Execute on debug mode to enable DEBUG logging level')
argument_parser.add_argument('--profile', default='default', help='Named AWS profile to use for querying AWS resources')
arguments: Namespace = argument_parser.parse_args()
# logging setup
@ -70,9 +73,12 @@ if __name__ == "__main__":
except FileNotFoundError:
logger.warning("Failed to load style sheet for resource mapping tool")
logger.info("Initializing boto3 default session ...")
aws_utils.setup_default_session(arguments.profile)
logger.info("Initializing configuration manager ...")
configuration_manager: ConfigurationManager = ConfigurationManager()
configuration_manager.setup()
configuration_manager.setup(arguments.config_path)
logger.info("Initializing thread manager ...")
thread_manager: ThreadManager = ThreadManager()

@ -43,7 +43,7 @@ class TestConfigurationManager(TestCase):
mock_find_files_with_suffix_under_directory: MagicMock,
mock_get_default_account_id: MagicMock,
mock_get_default_region: MagicMock) -> None:
TestConfigurationManager._expected_configuration_manager.setup()
TestConfigurationManager._expected_configuration_manager.setup("")
mock_get_current_directory_path.assert_called_once()
mock_check_path_exists.assert_called_once_with(TestConfigurationManager._expected_directory_path)
mock_find_files_with_suffix_under_directory.assert_called_once_with(
@ -58,3 +58,29 @@ class TestConfigurationManager(TestCase):
TestConfigurationManager._expected_account_id
assert TestConfigurationManager._expected_configuration_manager.configuration.region == \
TestConfigurationManager._expected_region
@patch("utils.aws_utils.get_default_region", return_value=_expected_region)
@patch("utils.aws_utils.get_default_account_id", return_value=_expected_account_id)
@patch("utils.file_utils.find_files_with_suffix_under_directory", return_value=_expected_config_files)
@patch("utils.file_utils.check_path_exists", return_value=True)
@patch("utils.file_utils.normalize_file_path", return_value=_expected_directory_path)
def test_setup_get_configuration_setup_with_path_as_expected(self, mock_normalize_file_path: MagicMock,
mock_check_path_exists: MagicMock,
mock_find_files_with_suffix_under_directory: MagicMock,
mock_get_default_account_id: MagicMock,
mock_get_default_region: MagicMock) -> None:
TestConfigurationManager._expected_configuration_manager.setup(TestConfigurationManager._expected_directory_path)
mock_normalize_file_path.assert_called_once()
mock_check_path_exists.assert_called_once_with(TestConfigurationManager._expected_directory_path)
mock_find_files_with_suffix_under_directory.assert_called_once_with(
TestConfigurationManager._expected_directory_path, constants.RESOURCE_MAPPING_CONFIG_FILE_NAME_SUFFIX)
mock_get_default_account_id.assert_called_once()
mock_get_default_region.assert_called_once()
assert TestConfigurationManager._expected_configuration_manager.configuration.config_directory == \
TestConfigurationManager._expected_directory_path
assert TestConfigurationManager._expected_configuration_manager.configuration.config_files == \
TestConfigurationManager._expected_config_files
assert TestConfigurationManager._expected_configuration_manager.configuration.account_id == \
TestConfigurationManager._expected_account_id
assert TestConfigurationManager._expected_configuration_manager.configuration.region == \
TestConfigurationManager._expected_region

@ -36,7 +36,7 @@ class TestViewManager(TestCase):
main_window_patcher: patch = patch("manager.view_manager.QMainWindow")
cls._mock_main_window = main_window_patcher.start()
window_icon_patcher: patch = patch("manager.view_manager.QPixmap")
window_icon_patcher: patch = patch("manager.view_manager.QIcon")
window_icon_patcher.start()
stacked_pages_patcher: patch = patch("manager.view_manager.QStackedWidget")

@ -37,13 +37,12 @@ class TestAWSUtils(TestCase):
.build()
def setUp(self) -> None:
client_patcher: patch = patch("boto3.client")
self.addCleanup(client_patcher.stop)
self._mock_client: MagicMock = client_patcher.start()
session_patcher: patch = patch("boto3.session.Session")
self.addCleanup(session_patcher.stop)
self._mock_session: MagicMock = session_patcher.start()
self._mock_client: MagicMock = self._mock_session.return_value.client
aws_utils.setup_default_session("default")
def test_get_default_account_id_return_expected_account_id(self) -> None:
mocked_sts_client: MagicMock = self._mock_client.return_value

@ -26,6 +26,8 @@ aws account, region, resources, etc.
_PAGINATION_MAX_ITEMS: int = 10
_PAGINATION_PAGE_SIZE: int = 10
default_session: boto3.session.Session = None
class AWSConstants(object):
CLOUDFORMATION_SERVICE_NAME: str = "cloudformation"
@ -53,15 +55,20 @@ def _close_client_connection(client: BaseClient) -> None:
def _initialize_boto3_aws_client(service: str, region: str = "") -> BaseClient:
if region:
boto3_client: BaseClient = boto3.client(service, region_name=region)
boto3_client: BaseClient = default_session.client(service, region_name=region)
else:
boto3_client: BaseClient = boto3.client(service)
boto3_client: BaseClient = default_session.client(service)
boto3_client.meta.events.register(
f"after-call.{service}.*", lambda **kwargs: _close_client_connection(boto3_client)
)
return boto3_client
def setup_default_session(profile: str) -> None:
global default_session
default_session = boto3.session.Session(profile_name=profile)
def get_default_account_id() -> str:
sts_client: BaseClient = _initialize_boto3_aws_client(AWSConstants.STS_SERVICE_NAME)
try:
@ -72,7 +79,7 @@ def get_default_account_id() -> str:
def get_default_region() -> str:
region: str = boto3.session.Session().region_name
region: str = default_session.region_name
if region:
return region

Loading…
Cancel
Save