Skip to content

Commit 76d9236

Browse files
jirkafajfrJirka Fajfr
andauthored
Adding more granular random password generator options (#136)
Co-authored-by: Jirka Fajfr <fajfr@amazon.com>
1 parent 57fedc4 commit 76d9236

File tree

17 files changed

+1036
-156
lines changed

17 files changed

+1036
-156
lines changed

SecretsManagerMongoDBRotationMultiUser/lambda_function.py

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,8 @@ def create_secret(service_client, arn, token):
119119
except service_client.exceptions.ResourceNotFoundException:
120120
# Get the alternate username swapping between the original user and the user with _clone appended to it
121121
current_dict['username'] = get_alt_username(current_dict['username'])
122-
123-
# Get exclude characters from environment variable
124-
exclude_characters = os.environ['EXCLUDE_CHARACTERS'] if 'EXCLUDE_CHARACTERS' in os.environ else '/@"\'\\'
125122
# Generate a random password
126-
passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters)
127-
current_dict['password'] = passwd['RandomPassword']
123+
current_dict['password'] = get_random_password(service_client)
128124

129125
# Put the secret
130126
service_client.put_secret_value(SecretId=arn, ClientRequestToken=token, SecretString=json.dumps(current_dict), VersionStages=['AWSPENDING'])
@@ -455,3 +451,49 @@ def get_alt_username(current_username):
455451
return current_username[:(len(clone_suffix) * -1)]
456452
else:
457453
return current_username + clone_suffix
454+
455+
456+
def get_environment_bool(variable_name, default_value):
457+
"""Loads the environment variable and converts it to the boolean.
458+
459+
Args:
460+
variable_name (string): Name of environment variable
461+
462+
default_value (bool): The result will fallback to the default_value when the environment variable with the given name doesn't exist.
463+
464+
Returns:
465+
bool: True when the content of environment variable contains either 'true', '1', 'y' or 'yes'
466+
"""
467+
variable = os.environ.get(variable_name, str(default_value))
468+
return variable.lower() in ['true', '1', 'y', 'yes']
469+
470+
471+
def get_random_password(service_client):
472+
""" Generates a random new password. Generator loads parameters that affects the content of the resulting password from the environment
473+
variables. When environment variable is missing sensible defaults are chosen.
474+
475+
Supported environment variables:
476+
- EXCLUDE_CHARACTERS
477+
- PASSWORD_LENGTH
478+
- EXCLUDE_NUMBERS
479+
- EXCLUDE_PUNCTUATION
480+
- EXCLUDE_UPPERCASE
481+
- EXCLUDE_LOWERCASE
482+
- REQUIRE_EACH_INCLUDED_TYPE
483+
484+
Args:
485+
service_client (client): The secrets manager service client
486+
487+
Returns:
488+
string: The randomly generated password.
489+
"""
490+
passwd = service_client.get_random_password(
491+
ExcludeCharacters=os.environ.get('EXCLUDE_CHARACTERS', '/@"\'\\'),
492+
PasswordLength=int(os.environ.get('PASSWORD_LENGTH', 32)),
493+
ExcludeNumbers=get_environment_bool('EXCLUDE_NUMBERS', False),
494+
ExcludePunctuation=get_environment_bool('EXCLUDE_PUNCTUATION', False),
495+
ExcludeUppercase=get_environment_bool('EXCLUDE_UPPERCASE', False),
496+
ExcludeLowercase=get_environment_bool('EXCLUDE_LOWERCASE', False),
497+
RequireEachIncludedType=get_environment_bool('REQUIRE_EACH_INCLUDED_TYPE', True)
498+
)
499+
return passwd['RandomPassword']

SecretsManagerMongoDBRotationSingleUser/lambda_function.py

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,8 @@ def create_secret(service_client, arn, token):
114114
get_secret_dict(service_client, arn, "AWSPENDING", token)
115115
logger.info("createSecret: Successfully retrieved secret for %s." % arn)
116116
except service_client.exceptions.ResourceNotFoundException:
117-
# Get exclude characters from environment variable
118-
exclude_characters = os.environ['EXCLUDE_CHARACTERS'] if 'EXCLUDE_CHARACTERS' in os.environ else '/@"\'\\'
119117
# Generate a random password
120-
passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters)
121-
current_dict['password'] = passwd['RandomPassword']
118+
current_dict['password'] = get_random_password(service_client)
122119

123120
# Put the secret
124121
service_client.put_secret_value(SecretId=arn, ClientRequestToken=token, SecretString=json.dumps(current_dict), VersionStages=['AWSPENDING'])
@@ -427,3 +424,49 @@ def get_secret_dict(service_client, arn, stage, token=None):
427424

428425
# Parse and return the secret JSON string
429426
return secret_dict
427+
428+
429+
def get_environment_bool(variable_name, default_value):
430+
"""Loads the environment variable and converts it to the boolean.
431+
432+
Args:
433+
variable_name (string): Name of environment variable
434+
435+
default_value (bool): The result will fallback to the default_value when the environment variable with the given name doesn't exist.
436+
437+
Returns:
438+
bool: True when the content of environment variable contains either 'true', '1', 'y' or 'yes'
439+
"""
440+
variable = os.environ.get(variable_name, str(default_value))
441+
return variable.lower() in ['true', '1', 'y', 'yes']
442+
443+
444+
def get_random_password(service_client):
445+
""" Generates a random new password. Generator loads parameters that affects the content of the resulting password from the environment
446+
variables. When environment variable is missing sensible defaults are chosen.
447+
448+
Supported environment variables:
449+
- EXCLUDE_CHARACTERS
450+
- PASSWORD_LENGTH
451+
- EXCLUDE_NUMBERS
452+
- EXCLUDE_PUNCTUATION
453+
- EXCLUDE_UPPERCASE
454+
- EXCLUDE_LOWERCASE
455+
- REQUIRE_EACH_INCLUDED_TYPE
456+
457+
Args:
458+
service_client (client): The secrets manager service client
459+
460+
Returns:
461+
string: The randomly generated password.
462+
"""
463+
passwd = service_client.get_random_password(
464+
ExcludeCharacters=os.environ.get('EXCLUDE_CHARACTERS', '/@"\'\\'),
465+
PasswordLength=int(os.environ.get('PASSWORD_LENGTH', 32)),
466+
ExcludeNumbers=get_environment_bool('EXCLUDE_NUMBERS', False),
467+
ExcludePunctuation=get_environment_bool('EXCLUDE_PUNCTUATION', False),
468+
ExcludeUppercase=get_environment_bool('EXCLUDE_UPPERCASE', False),
469+
ExcludeLowercase=get_environment_bool('EXCLUDE_LOWERCASE', False),
470+
RequireEachIncludedType=get_environment_bool('REQUIRE_EACH_INCLUDED_TYPE', True)
471+
)
472+
return passwd['RandomPassword']

SecretsManagerRDSDb2RotationMultiUser/lambda_function.py

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,7 @@ def create_secret(service_client, arn, token):
119119
except service_client.exceptions.ResourceNotFoundException:
120120
# Get the alternate username swapping between the original user and the user with _clone appended to it
121121
current_dict['username'] = get_alt_username(current_dict['username'])
122-
123-
# Get exclude characters from environment variable
124-
exclude_characters = os.environ['EXCLUDE_CHARACTERS'] if 'EXCLUDE_CHARACTERS' in os.environ else '/@"\'\\;'
125-
# Generate a random password
126-
passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters)
127-
current_dict['password'] = passwd['RandomPassword']
122+
current_dict['password'] = get_random_password(service_client)
128123

129124
# Put the secret
130125
service_client.put_secret_value(SecretId=arn, ClientRequestToken=token, SecretString=json.dumps(current_dict), VersionStages=['AWSPENDING'])
@@ -604,3 +599,49 @@ def get_connection_params_from_rds_api(master_dict, master_instance_arn):
604599
master_dict['dbname'] = "rdsadmin"
605600

606601
return master_dict
602+
603+
604+
def get_environment_bool(variable_name, default_value):
605+
"""Loads the environment variable and converts it to the boolean.
606+
607+
Args:
608+
variable_name (string): Name of environment variable
609+
610+
default_value (bool): The result will fallback to the default_value when the environment variable with the given name doesn't exist.
611+
612+
Returns:
613+
bool: True when the content of environment variable contains either 'true', '1', 'y' or 'yes'
614+
"""
615+
variable = os.environ.get(variable_name, str(default_value))
616+
return variable.lower() in ['true', '1', 'y', 'yes']
617+
618+
619+
def get_random_password(service_client):
620+
""" Generates a random new password. Generator loads parameters that affects the content of the resulting password from the environment
621+
variables. When environment variable is missing sensible defaults are chosen.
622+
623+
Supported environment variables:
624+
- EXCLUDE_CHARACTERS
625+
- PASSWORD_LENGTH
626+
- EXCLUDE_NUMBERS
627+
- EXCLUDE_PUNCTUATION
628+
- EXCLUDE_UPPERCASE
629+
- EXCLUDE_LOWERCASE
630+
- REQUIRE_EACH_INCLUDED_TYPE
631+
632+
Args:
633+
service_client (client): The secrets manager service client
634+
635+
Returns:
636+
string: The randomly generated password.
637+
"""
638+
passwd = service_client.get_random_password(
639+
ExcludeCharacters=os.environ.get('EXCLUDE_CHARACTERS', '/@"\'\\;'),
640+
PasswordLength=int(os.environ.get('PASSWORD_LENGTH', 32)),
641+
ExcludeNumbers=get_environment_bool('EXCLUDE_NUMBERS', False),
642+
ExcludePunctuation=get_environment_bool('EXCLUDE_PUNCTUATION', False),
643+
ExcludeUppercase=get_environment_bool('EXCLUDE_UPPERCASE', False),
644+
ExcludeLowercase=get_environment_bool('EXCLUDE_LOWERCASE', False),
645+
RequireEachIncludedType=get_environment_bool('REQUIRE_EACH_INCLUDED_TYPE', True)
646+
)
647+
return passwd['RandomPassword']

SecretsManagerRDSDb2RotationSingleUser/lambda_function.py

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,11 +115,8 @@ def create_secret(service_client, arn, token):
115115
get_secret_dict(service_client, arn, "AWSPENDING", token)
116116
logger.info("createSecret: Successfully retrieved secret for %s." % arn)
117117
except service_client.exceptions.ResourceNotFoundException:
118-
# Get exclude characters from environment variable
119-
exclude_characters = os.environ['EXCLUDE_CHARACTERS'] if 'EXCLUDE_CHARACTERS' in os.environ else '/@"\'\\;'
120118
# Generate a random password
121-
passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters)
122-
current_dict['password'] = passwd['RandomPassword']
119+
current_dict['password'] = get_random_password(service_client)
123120

124121
# Put the secret
125122
service_client.put_secret_value(SecretId=arn, ClientRequestToken=token, SecretString=json.dumps(current_dict), VersionStages=['AWSPENDING'])
@@ -503,3 +500,49 @@ def get_connection_params_from_rds_api(master_dict, master_instance_arn):
503500
master_dict['dbname'] = "rdsadmin"
504501

505502
return master_dict
503+
504+
505+
def get_environment_bool(variable_name, default_value):
506+
"""Loads the environment variable and converts it to the boolean.
507+
508+
Args:
509+
variable_name (string): Name of environment variable
510+
511+
default_value (bool): The result will fallback to the default_value when the environment variable with the given name doesn't exist.
512+
513+
Returns:
514+
bool: True when the content of environment variable contains either 'true', '1', 'y' or 'yes'
515+
"""
516+
variable = os.environ.get(variable_name, str(default_value))
517+
return variable.lower() in ['true', '1', 'y', 'yes']
518+
519+
520+
def get_random_password(service_client):
521+
""" Generates a random new password. Generator loads parameters that affects the content of the resulting password from the environment
522+
variables. When environment variable is missing sensible defaults are chosen.
523+
524+
Supported environment variables:
525+
- EXCLUDE_CHARACTERS
526+
- PASSWORD_LENGTH
527+
- EXCLUDE_NUMBERS
528+
- EXCLUDE_PUNCTUATION
529+
- EXCLUDE_UPPERCASE
530+
- EXCLUDE_LOWERCASE
531+
- REQUIRE_EACH_INCLUDED_TYPE
532+
533+
Args:
534+
service_client (client): The secrets manager service client
535+
536+
Returns:
537+
string: The randomly generated password.
538+
"""
539+
passwd = service_client.get_random_password(
540+
ExcludeCharacters=os.environ.get('EXCLUDE_CHARACTERS', '/@"\'\\;'),
541+
PasswordLength=int(os.environ.get('PASSWORD_LENGTH', 32)),
542+
ExcludeNumbers=get_environment_bool('EXCLUDE_NUMBERS', False),
543+
ExcludePunctuation=get_environment_bool('EXCLUDE_PUNCTUATION', False),
544+
ExcludeUppercase=get_environment_bool('EXCLUDE_UPPERCASE', False),
545+
ExcludeLowercase=get_environment_bool('EXCLUDE_LOWERCASE', False),
546+
RequireEachIncludedType=get_environment_bool('REQUIRE_EACH_INCLUDED_TYPE', True)
547+
)
548+
return passwd['RandomPassword']

SecretsManagerRDSMariaDBRotationMultiUser/lambda_function.py

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,7 @@ def create_secret(service_client, arn, token):
119119
except service_client.exceptions.ResourceNotFoundException:
120120
# Get the alternate username swapping between the original user and the user with _clone appended to it
121121
current_dict['username'] = get_alt_username(current_dict['username'])
122-
123-
# Get exclude characters from environment variable
124-
exclude_characters = os.environ['EXCLUDE_CHARACTERS'] if 'EXCLUDE_CHARACTERS' in os.environ else '/@"\'\\'
125-
# Generate a random password
126-
passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters)
127-
current_dict['password'] = passwd['RandomPassword']
122+
current_dict['password'] = get_random_password(service_client)
128123

129124
# Put the secret
130125
service_client.put_secret_value(SecretId=arn, ClientRequestToken=token, SecretString=json.dumps(current_dict), VersionStages=['AWSPENDING'])
@@ -612,4 +607,50 @@ def get_connection_params_from_rds_api(master_dict, master_instance_arn):
612607
master_dict['port'] = primary_instance['Endpoint']['Port']
613608
master_dict['engine'] = primary_instance['Engine']
614609

615-
return master_dict
610+
return master_dict
611+
612+
613+
def get_environment_bool(variable_name, default_value):
614+
"""Loads the environment variable and converts it to the boolean.
615+
616+
Args:
617+
variable_name (string): Name of environment variable
618+
619+
default_value (bool): The result will fallback to the default_value when the environment variable with the given name doesn't exist.
620+
621+
Returns:
622+
bool: True when the content of environment variable contains either 'true', '1', 'y' or 'yes'
623+
"""
624+
variable = os.environ.get(variable_name, str(default_value))
625+
return variable.lower() in ['true', '1', 'y', 'yes']
626+
627+
628+
def get_random_password(service_client):
629+
""" Generates a random new password. Generator loads parameters that affects the content of the resulting password from the environment
630+
variables. When environment variable is missing sensible defaults are chosen.
631+
632+
Supported environment variables:
633+
- EXCLUDE_CHARACTERS
634+
- PASSWORD_LENGTH
635+
- EXCLUDE_NUMBERS
636+
- EXCLUDE_PUNCTUATION
637+
- EXCLUDE_UPPERCASE
638+
- EXCLUDE_LOWERCASE
639+
- REQUIRE_EACH_INCLUDED_TYPE
640+
641+
Args:
642+
service_client (client): The secrets manager service client
643+
644+
Returns:
645+
string: The randomly generated password.
646+
"""
647+
passwd = service_client.get_random_password(
648+
ExcludeCharacters=os.environ.get('EXCLUDE_CHARACTERS', '/@"\'\\'),
649+
PasswordLength=int(os.environ.get('PASSWORD_LENGTH', 32)),
650+
ExcludeNumbers=get_environment_bool('EXCLUDE_NUMBERS', False),
651+
ExcludePunctuation=get_environment_bool('EXCLUDE_PUNCTUATION', False),
652+
ExcludeUppercase=get_environment_bool('EXCLUDE_UPPERCASE', False),
653+
ExcludeLowercase=get_environment_bool('EXCLUDE_LOWERCASE', False),
654+
RequireEachIncludedType=get_environment_bool('REQUIRE_EACH_INCLUDED_TYPE', True)
655+
)
656+
return passwd['RandomPassword']

SecretsManagerRDSMariaDBRotationSingleUser/lambda_function.py

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,8 @@ def create_secret(service_client, arn, token):
112112
get_secret_dict(service_client, arn, "AWSPENDING", token)
113113
logger.info("createSecret: Successfully retrieved secret for %s." % arn)
114114
except service_client.exceptions.ResourceNotFoundException:
115-
# Get exclude characters from environment variable
116-
exclude_characters = os.environ['EXCLUDE_CHARACTERS'] if 'EXCLUDE_CHARACTERS' in os.environ else '/@"\'\\'
117115
# Generate a random password
118-
passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters)
119-
current_dict['password'] = passwd['RandomPassword']
116+
current_dict['password'] = get_random_password(service_client)
120117

121118
# Put the secret
122119
service_client.put_secret_value(SecretId=arn, ClientRequestToken=token, SecretString=json.dumps(current_dict), VersionStages=['AWSPENDING'])
@@ -423,3 +420,49 @@ def get_secret_dict(service_client, arn, stage, token=None):
423420

424421
# Parse and return the secret JSON string
425422
return secret_dict
423+
424+
425+
def get_environment_bool(variable_name, default_value):
426+
"""Loads the environment variable and converts it to the boolean.
427+
428+
Args:
429+
variable_name (string): Name of environment variable
430+
431+
default_value (bool): The result will fallback to the default_value when the environment variable with the given name doesn't exist.
432+
433+
Returns:
434+
bool: True when the content of environment variable contains either 'true', '1', 'y' or 'yes'
435+
"""
436+
variable = os.environ.get(variable_name, str(default_value))
437+
return variable.lower() in ['true', '1', 'y', 'yes']
438+
439+
440+
def get_random_password(service_client):
441+
""" Generates a random new password. Generator loads parameters that affects the content of the resulting password from the environment
442+
variables. When environment variable is missing sensible defaults are chosen.
443+
444+
Supported environment variables:
445+
- EXCLUDE_CHARACTERS
446+
- PASSWORD_LENGTH
447+
- EXCLUDE_NUMBERS
448+
- EXCLUDE_PUNCTUATION
449+
- EXCLUDE_UPPERCASE
450+
- EXCLUDE_LOWERCASE
451+
- REQUIRE_EACH_INCLUDED_TYPE
452+
453+
Args:
454+
service_client (client): The secrets manager service client
455+
456+
Returns:
457+
string: The randomly generated password.
458+
"""
459+
passwd = service_client.get_random_password(
460+
ExcludeCharacters=os.environ.get('EXCLUDE_CHARACTERS', '/@"\'\\'),
461+
PasswordLength=int(os.environ.get('PASSWORD_LENGTH', 32)),
462+
ExcludeNumbers=get_environment_bool('EXCLUDE_NUMBERS', False),
463+
ExcludePunctuation=get_environment_bool('EXCLUDE_PUNCTUATION', False),
464+
ExcludeUppercase=get_environment_bool('EXCLUDE_UPPERCASE', False),
465+
ExcludeLowercase=get_environment_bool('EXCLUDE_LOWERCASE', False),
466+
RequireEachIncludedType=get_environment_bool('REQUIRE_EACH_INCLUDED_TYPE', True)
467+
)
468+
return passwd['RandomPassword']

0 commit comments

Comments
 (0)