1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
- import json
- import logging
- from super_gradients.common import AWSConnector
- from super_gradients.common import explicit_params_validation
- class AWSSecretsManagerConnector:
- """
- AWSSecretsManagerConnector - This class handles the AWS Secrets Manager connection
- """
- __slots__ = [] # Making the class immutable for runtime safety
- current_environment_client = None
- DECI_ENVIRONMENTS = ['research', 'development', 'staging', 'production']
- @staticmethod
- @explicit_params_validation(validation_type='NoneOrEmpty')
- def get_secret_value_for_secret_key(aws_env: str, secret_name: str, secret_key: str) -> str:
- """
- get_secret_value_for_secret_key - Gets a Secret Value from AWS Secrets Manager for the Provided Key
- :param aws_env: The environment to get the secret for
- :param secret_name: The Secret Name stored in Secrets Manager
- :param secret_key: The Secret Key To retrieve it's value from AWS
- :return: str: The Secret Value
- """
- current_class_name = __class__.__name__
- logger = logging.getLogger(current_class_name)
- secret_key = secret_key.upper()
- aws_secrets_dict = AWSSecretsManagerConnector.__get_secrets_manager_dict_for_secret_name(
- aws_env=aws_env, secret_name=secret_name)
- secret_key = '.'.join([aws_env.upper(), secret_key])
- if secret_key not in aws_secrets_dict.keys():
- error = f'[{current_class_name}] - Secret Key ({secret_key}) not Found in AWS Secret: ' + secret_name
- logger.error(error)
- raise EnvironmentError(error)
- else:
- return aws_secrets_dict[secret_key]
- @staticmethod
- @explicit_params_validation(validation_type='NoneOrEmpty')
- def get_secret_values_dict_for_secret_key_properties(env: str, secret_key: str, secret_name: str,
- db_properties_set: set = None) -> dict:
- """
- get_config_dict - Returns the config dict of the properties from the properties dict
- :param env: The environment to open the dict for
- :param secret_key: The Secret Key
- :param secret_name: The Secret to Retrieve to from AWS secrets manager (usually project name)
- :param db_properties_set: The set of the properties to get secrets values for
- :return: dict The secrets dict for the requested property
- """
- current_class_name = __class__.__name__
- logger = logging.getLogger(current_class_name)
- aws_secrets_dict = AWSSecretsManagerConnector.__get_secrets_manager_dict_for_secret_name(
- aws_env=env, secret_name=secret_name)
- aws_env_safe_secrets = {}
- # FILL THE DICT VALUES FROM THE AWS SECRETS RESPONSE
- if db_properties_set:
- for secret_key_property in db_properties_set:
- secret_key_to_retrieve = '.'.join([env.upper(), secret_key, secret_key_property])
- if secret_key_to_retrieve not in aws_secrets_dict:
- error = f'[{current_class_name}] - Error retrieving data from AWS Secrets Manager for Secret Key "{secret_name}": The secret property "{secret_key_property}" Does Not Exist'
- logger.error(error)
- raise EnvironmentError(error)
- else:
- env_stripped_key_name = secret_key_to_retrieve.lstrip(env.upper()).lstrip('.')
- aws_env_safe_secrets[env_stripped_key_name] = aws_secrets_dict[secret_key_to_retrieve]
- else:
- # "db_properties_set" is not specified - validating and returning all the secret keys and values for the secret name.
- for secret_key_name, secret_value in aws_secrets_dict.items():
- secret_key_to_retrieve = '.'.join([env.upper(), secret_key])
- assert secret_key_name.startswith(
- env.upper()), f'The secret key property "{secret_key_name}", found in secret named {secret_name},' \
- f' is not following the convention of environment prefix. please add the environment prefix "{env.upper()}" to property "{secret_key_name}"'
- if secret_key_name.startswith(secret_key_to_retrieve):
- env_stripped_key_name = secret_key_name.lstrip(env.upper()).lstrip('.')
- aws_env_safe_secrets[env_stripped_key_name] = secret_value
- return aws_env_safe_secrets
- @staticmethod
- def __get_secrets_manager_dict_for_secret_name(aws_env: str, secret_name: str) -> dict:
- """
- __get_secrets_manager_dict_for_secret_name
- :param aws_env: The environment to open the dict for
- :param secret_name: The Secret to Retrieve to from AWS secrets manager (usually project name)
- :return: python Dictionary with the key/value pairs stored in AWS Secrets Manager
- """
- current_class_name = __class__.__name__
- logger = logging.getLogger(current_class_name)
- secrets_path = AWSSecretsManagerConnector.__get_secrets_path_from_secret_name(aws_env, secret_name)
- try:
- if not AWSSecretsManagerConnector.current_environment_client:
- logger.debug('Initializing a new secrets manager client...')
- AWSSecretsManagerConnector.current_environment_client = AWSConnector.get_aws_client_for_service_name(
- profile_name=aws_env,
- service_name='secretsmanager')
- logger.debug(f'Fetching the secret "{secret_name}" in env "{aws_env}"')
- aws_secrets = AWSSecretsManagerConnector.current_environment_client.get_secret_value(SecretId=secrets_path)
- aws_secrets_dict = json.loads(aws_secrets['SecretString'])
- return aws_secrets_dict
- except Exception as ex:
- error = '[' + current_class_name + '] - Caught Exception while trying to connect to aws to get credentials from secrets manager: ' + '"' + str(
- ex) + '"' + ' for ' + str(secrets_path)
- logger.error(error)
- raise EnvironmentError(error)
- @staticmethod
- def __get_secrets_path_from_secret_name(aws_env: str, secret_name: str) -> str:
- """
- __get_secrets_path_from_secret_name - Extracts the full secret path based on the Environment
- :param aws_env: Env
- :param secret_name: Secret Name
- :return: str: The full secret path
- """
- current_class_name = __class__.__name__
- logger = logging.getLogger(current_class_name)
- # Checking for lowercase exact match, in order to prevent any implicit usage of the environments.
- if aws_env not in AWSSecretsManagerConnector.DECI_ENVIRONMENTS:
- logger.critical('[' + current_class_name + ' ] - wrong environment param... Exiting')
- raise Exception('[' + current_class_name + '] - wrong environment param')
- secrets_path = '/'.join([aws_env, secret_name])
- return secrets_path
|