Run black on moto & test directories.

This commit is contained in:
Asher Foa 2019-10-31 08:44:26 -07:00
commit 96e5b1993d
507 changed files with 52541 additions and 47814 deletions

View file

@ -2,5 +2,5 @@ from __future__ import unicode_literals
from .models import secretsmanager_backends
from ..core.models import base_decorator
secretsmanager_backend = secretsmanager_backends['us-east-1']
secretsmanager_backend = secretsmanager_backends["us-east-1"]
mock_secretsmanager = base_decorator(secretsmanager_backends)

View file

@ -10,8 +10,7 @@ class ResourceNotFoundException(SecretsManagerClientError):
def __init__(self, message):
self.code = 404
super(ResourceNotFoundException, self).__init__(
"ResourceNotFoundException",
message,
"ResourceNotFoundException", message
)
@ -21,7 +20,7 @@ class SecretNotFoundException(SecretsManagerClientError):
self.code = 404
super(SecretNotFoundException, self).__init__(
"ResourceNotFoundException",
message=u"Secrets Manager can\u2019t find the specified secret."
message="Secrets Manager can\u2019t find the specified secret.",
)
@ -31,35 +30,32 @@ class SecretHasNoValueException(SecretsManagerClientError):
self.code = 404
super(SecretHasNoValueException, self).__init__(
"ResourceNotFoundException",
message=u"Secrets Manager can\u2019t find the specified secret "
u"value for staging label: {}".format(version_stage)
message="Secrets Manager can\u2019t find the specified secret "
"value for staging label: {}".format(version_stage),
)
class ClientError(SecretsManagerClientError):
def __init__(self, message):
super(ClientError, self).__init__(
'InvalidParameterValue',
message)
super(ClientError, self).__init__("InvalidParameterValue", message)
class InvalidParameterException(SecretsManagerClientError):
def __init__(self, message):
super(InvalidParameterException, self).__init__(
'InvalidParameterException',
message)
"InvalidParameterException", message
)
class ResourceExistsException(SecretsManagerClientError):
def __init__(self, message):
super(ResourceExistsException, self).__init__(
'ResourceExistsException',
message
"ResourceExistsException", message
)
class InvalidRequestException(SecretsManagerClientError):
def __init__(self, message):
super(InvalidRequestException, self).__init__(
'InvalidRequestException',
message)
"InvalidRequestException", message
)

View file

@ -15,19 +15,17 @@ from .exceptions import (
InvalidParameterException,
ResourceExistsException,
InvalidRequestException,
ClientError
ClientError,
)
from .utils import random_password, secret_arn
class SecretsManager(BaseModel):
def __init__(self, region_name, **kwargs):
self.region = region_name
class SecretsManagerBackend(BaseBackend):
def __init__(self, region_name=None, **kwargs):
super(SecretsManagerBackend, self).__init__()
self.region = region_name
@ -52,123 +50,148 @@ class SecretsManagerBackend(BaseBackend):
if not version_id and version_stage:
# set version_id to match version_stage
versions_dict = self.secrets[secret_id]['versions']
versions_dict = self.secrets[secret_id]["versions"]
for ver_id, ver_val in versions_dict.items():
if version_stage in ver_val['version_stages']:
if version_stage in ver_val["version_stages"]:
version_id = ver_id
break
if not version_id:
raise SecretNotFoundException()
# TODO check this part
if 'deleted_date' in self.secrets[secret_id]:
if "deleted_date" in self.secrets[secret_id]:
raise InvalidRequestException(
"An error occurred (InvalidRequestException) when calling the GetSecretValue operation: You tried to \
perform the operation on a secret that's currently marked deleted."
)
secret = self.secrets[secret_id]
version_id = version_id or secret['default_version_id']
version_id = version_id or secret["default_version_id"]
secret_version = secret['versions'][version_id]
secret_version = secret["versions"][version_id]
response_data = {
"ARN": secret_arn(self.region, secret['secret_id']),
"Name": secret['name'],
"VersionId": secret_version['version_id'],
"VersionStages": secret_version['version_stages'],
"CreatedDate": secret_version['createdate'],
"ARN": secret_arn(self.region, secret["secret_id"]),
"Name": secret["name"],
"VersionId": secret_version["version_id"],
"VersionStages": secret_version["version_stages"],
"CreatedDate": secret_version["createdate"],
}
if 'secret_string' in secret_version:
response_data["SecretString"] = secret_version['secret_string']
if "secret_string" in secret_version:
response_data["SecretString"] = secret_version["secret_string"]
if 'secret_binary' in secret_version:
response_data["SecretBinary"] = secret_version['secret_binary']
if "secret_binary" in secret_version:
response_data["SecretBinary"] = secret_version["secret_binary"]
if 'secret_string' not in secret_version and 'secret_binary' not in secret_version:
raise SecretHasNoValueException(version_stage or u"AWSCURRENT")
if (
"secret_string" not in secret_version
and "secret_binary" not in secret_version
):
raise SecretHasNoValueException(version_stage or "AWSCURRENT")
response = json.dumps(response_data)
return response
def create_secret(self, name, secret_string=None, secret_binary=None, tags=[], **kwargs):
def create_secret(
self, name, secret_string=None, secret_binary=None, tags=[], **kwargs
):
# error if secret exists
if name in self.secrets.keys():
raise ResourceExistsException('A resource with the ID you requested already exists.')
raise ResourceExistsException(
"A resource with the ID you requested already exists."
)
version_id = self._add_secret(name, secret_string=secret_string, secret_binary=secret_binary, tags=tags)
version_id = self._add_secret(
name, secret_string=secret_string, secret_binary=secret_binary, tags=tags
)
response = json.dumps({
"ARN": secret_arn(self.region, name),
"Name": name,
"VersionId": version_id,
})
response = json.dumps(
{
"ARN": secret_arn(self.region, name),
"Name": name,
"VersionId": version_id,
}
)
return response
def _add_secret(self, secret_id, secret_string=None, secret_binary=None, tags=[], version_id=None, version_stages=None):
def _add_secret(
self,
secret_id,
secret_string=None,
secret_binary=None,
tags=[],
version_id=None,
version_stages=None,
):
if version_stages is None:
version_stages = ['AWSCURRENT']
version_stages = ["AWSCURRENT"]
if not version_id:
version_id = str(uuid.uuid4())
secret_version = {
'createdate': int(time.time()),
'version_id': version_id,
'version_stages': version_stages,
"createdate": int(time.time()),
"version_id": version_id,
"version_stages": version_stages,
}
if secret_string is not None:
secret_version['secret_string'] = secret_string
secret_version["secret_string"] = secret_string
if secret_binary is not None:
secret_version['secret_binary'] = secret_binary
secret_version["secret_binary"] = secret_binary
if secret_id in self.secrets:
# remove all old AWSPREVIOUS stages
for secret_verion_to_look_at in self.secrets[secret_id]['versions'].values():
if 'AWSPREVIOUS' in secret_verion_to_look_at['version_stages']:
secret_verion_to_look_at['version_stages'].remove('AWSPREVIOUS')
for secret_verion_to_look_at in self.secrets[secret_id][
"versions"
].values():
if "AWSPREVIOUS" in secret_verion_to_look_at["version_stages"]:
secret_verion_to_look_at["version_stages"].remove("AWSPREVIOUS")
# set old AWSCURRENT secret to AWSPREVIOUS
previous_current_version_id = self.secrets[secret_id]['default_version_id']
self.secrets[secret_id]['versions'][previous_current_version_id]['version_stages'] = ['AWSPREVIOUS']
previous_current_version_id = self.secrets[secret_id]["default_version_id"]
self.secrets[secret_id]["versions"][previous_current_version_id][
"version_stages"
] = ["AWSPREVIOUS"]
self.secrets[secret_id]['versions'][version_id] = secret_version
self.secrets[secret_id]['default_version_id'] = version_id
self.secrets[secret_id]["versions"][version_id] = secret_version
self.secrets[secret_id]["default_version_id"] = version_id
else:
self.secrets[secret_id] = {
'versions': {
version_id: secret_version
},
'default_version_id': version_id,
"versions": {version_id: secret_version},
"default_version_id": version_id,
}
secret = self.secrets[secret_id]
secret['secret_id'] = secret_id
secret['name'] = secret_id
secret['rotation_enabled'] = False
secret['rotation_lambda_arn'] = ''
secret['auto_rotate_after_days'] = 0
secret['tags'] = tags
secret["secret_id"] = secret_id
secret["name"] = secret_id
secret["rotation_enabled"] = False
secret["rotation_lambda_arn"] = ""
secret["auto_rotate_after_days"] = 0
secret["tags"] = tags
return version_id
def put_secret_value(self, secret_id, secret_string, secret_binary, version_stages):
version_id = self._add_secret(secret_id, secret_string, secret_binary, version_stages=version_stages)
version_id = self._add_secret(
secret_id, secret_string, secret_binary, version_stages=version_stages
)
response = json.dumps({
'ARN': secret_arn(self.region, secret_id),
'Name': secret_id,
'VersionId': version_id,
'VersionStages': version_stages
})
response = json.dumps(
{
"ARN": secret_arn(self.region, secret_id),
"Name": secret_id,
"VersionId": version_id,
"VersionStages": version_stages,
}
)
return response
@ -178,34 +201,41 @@ class SecretsManagerBackend(BaseBackend):
secret = self.secrets[secret_id]
response = json.dumps({
"ARN": secret_arn(self.region, secret['secret_id']),
"Name": secret['name'],
"Description": "",
"KmsKeyId": "",
"RotationEnabled": secret['rotation_enabled'],
"RotationLambdaARN": secret['rotation_lambda_arn'],
"RotationRules": {
"AutomaticallyAfterDays": secret['auto_rotate_after_days']
},
"LastRotatedDate": None,
"LastChangedDate": None,
"LastAccessedDate": None,
"DeletedDate": secret.get('deleted_date', None),
"Tags": secret['tags']
})
response = json.dumps(
{
"ARN": secret_arn(self.region, secret["secret_id"]),
"Name": secret["name"],
"Description": "",
"KmsKeyId": "",
"RotationEnabled": secret["rotation_enabled"],
"RotationLambdaARN": secret["rotation_lambda_arn"],
"RotationRules": {
"AutomaticallyAfterDays": secret["auto_rotate_after_days"]
},
"LastRotatedDate": None,
"LastChangedDate": None,
"LastAccessedDate": None,
"DeletedDate": secret.get("deleted_date", None),
"Tags": secret["tags"],
}
)
return response
def rotate_secret(self, secret_id, client_request_token=None,
rotation_lambda_arn=None, rotation_rules=None):
def rotate_secret(
self,
secret_id,
client_request_token=None,
rotation_lambda_arn=None,
rotation_rules=None,
):
rotation_days = 'AutomaticallyAfterDays'
rotation_days = "AutomaticallyAfterDays"
if not self._is_valid_identifier(secret_id):
raise SecretNotFoundException()
if 'deleted_date' in self.secrets[secret_id]:
if "deleted_date" in self.secrets[secret_id]:
raise InvalidRequestException(
"An error occurred (InvalidRequestException) when calling the RotateSecret operation: You tried to \
perform the operation on a secret that's currently marked deleted."
@ -214,18 +244,12 @@ class SecretsManagerBackend(BaseBackend):
if client_request_token:
token_length = len(client_request_token)
if token_length < 32 or token_length > 64:
msg = (
'ClientRequestToken '
'must be 32-64 characters long.'
)
msg = "ClientRequestToken " "must be 32-64 characters long."
raise InvalidParameterException(msg)
if rotation_lambda_arn:
if len(rotation_lambda_arn) > 2048:
msg = (
'RotationLambdaARN '
'must <= 2048 characters long.'
)
msg = "RotationLambdaARN " "must <= 2048 characters long."
raise InvalidParameterException(msg)
if rotation_rules:
@ -233,61 +257,82 @@ class SecretsManagerBackend(BaseBackend):
rotation_period = rotation_rules[rotation_days]
if rotation_period < 1 or rotation_period > 1000:
msg = (
'RotationRules.AutomaticallyAfterDays '
'must be within 1-1000.'
"RotationRules.AutomaticallyAfterDays " "must be within 1-1000."
)
raise InvalidParameterException(msg)
secret = self.secrets[secret_id]
old_secret_version = secret['versions'][secret['default_version_id']]
old_secret_version = secret["versions"][secret["default_version_id"]]
new_version_id = client_request_token or str(uuid.uuid4())
self._add_secret(secret_id, old_secret_version['secret_string'], secret['tags'], version_id=new_version_id, version_stages=['AWSCURRENT'])
self._add_secret(
secret_id,
old_secret_version["secret_string"],
secret["tags"],
version_id=new_version_id,
version_stages=["AWSCURRENT"],
)
secret['rotation_lambda_arn'] = rotation_lambda_arn or ''
secret["rotation_lambda_arn"] = rotation_lambda_arn or ""
if rotation_rules:
secret['auto_rotate_after_days'] = rotation_rules.get(rotation_days, 0)
if secret['auto_rotate_after_days'] > 0:
secret['rotation_enabled'] = True
secret["auto_rotate_after_days"] = rotation_rules.get(rotation_days, 0)
if secret["auto_rotate_after_days"] > 0:
secret["rotation_enabled"] = True
if 'AWSCURRENT' in old_secret_version['version_stages']:
old_secret_version['version_stages'].remove('AWSCURRENT')
if "AWSCURRENT" in old_secret_version["version_stages"]:
old_secret_version["version_stages"].remove("AWSCURRENT")
response = json.dumps({
"ARN": secret_arn(self.region, secret['secret_id']),
"Name": secret['name'],
"VersionId": new_version_id
})
response = json.dumps(
{
"ARN": secret_arn(self.region, secret["secret_id"]),
"Name": secret["name"],
"VersionId": new_version_id,
}
)
return response
def get_random_password(self, password_length,
exclude_characters, exclude_numbers,
exclude_punctuation, exclude_uppercase,
exclude_lowercase, include_space,
require_each_included_type):
def get_random_password(
self,
password_length,
exclude_characters,
exclude_numbers,
exclude_punctuation,
exclude_uppercase,
exclude_lowercase,
include_space,
require_each_included_type,
):
# password size must have value less than or equal to 4096
if password_length > 4096:
raise ClientError(
"ClientError: An error occurred (ValidationException) \
when calling the GetRandomPassword operation: 1 validation error detected: Value '{}' at 'passwordLength' \
failed to satisfy constraint: Member must have value less than or equal to 4096".format(password_length))
failed to satisfy constraint: Member must have value less than or equal to 4096".format(
password_length
)
)
if password_length < 4:
raise InvalidParameterException(
"InvalidParameterException: An error occurred (InvalidParameterException) \
when calling the GetRandomPassword operation: Password length is too short based on the required types.")
when calling the GetRandomPassword operation: Password length is too short based on the required types."
)
response = json.dumps({
"RandomPassword": random_password(password_length,
exclude_characters,
exclude_numbers,
exclude_punctuation,
exclude_uppercase,
exclude_lowercase,
include_space,
require_each_included_type)
})
response = json.dumps(
{
"RandomPassword": random_password(
password_length,
exclude_characters,
exclude_numbers,
exclude_punctuation,
exclude_uppercase,
exclude_lowercase,
include_space,
require_each_included_type,
)
}
)
return response
@ -295,20 +340,24 @@ class SecretsManagerBackend(BaseBackend):
secret = self.secrets[secret_id]
version_list = []
for version_id, version in secret['versions'].items():
version_list.append({
'CreatedDate': int(time.time()),
'LastAccessedDate': int(time.time()),
'VersionId': version_id,
'VersionStages': version['version_stages'],
})
for version_id, version in secret["versions"].items():
version_list.append(
{
"CreatedDate": int(time.time()),
"LastAccessedDate": int(time.time()),
"VersionId": version_id,
"VersionStages": version["version_stages"],
}
)
response = json.dumps({
'ARN': secret['secret_id'],
'Name': secret['name'],
'NextToken': '',
'Versions': version_list,
})
response = json.dumps(
{
"ARN": secret["secret_id"],
"Name": secret["name"],
"NextToken": "",
"Versions": version_list,
}
)
return response
@ -319,35 +368,39 @@ class SecretsManagerBackend(BaseBackend):
for secret in self.secrets.values():
versions_to_stages = {}
for version_id, version in secret['versions'].items():
versions_to_stages[version_id] = version['version_stages']
for version_id, version in secret["versions"].items():
versions_to_stages[version_id] = version["version_stages"]
secret_list.append({
"ARN": secret_arn(self.region, secret['secret_id']),
"DeletedDate": secret.get('deleted_date', None),
"Description": "",
"KmsKeyId": "",
"LastAccessedDate": None,
"LastChangedDate": None,
"LastRotatedDate": None,
"Name": secret['name'],
"RotationEnabled": secret['rotation_enabled'],
"RotationLambdaARN": secret['rotation_lambda_arn'],
"RotationRules": {
"AutomaticallyAfterDays": secret['auto_rotate_after_days']
},
"SecretVersionsToStages": versions_to_stages,
"Tags": secret['tags']
})
secret_list.append(
{
"ARN": secret_arn(self.region, secret["secret_id"]),
"DeletedDate": secret.get("deleted_date", None),
"Description": "",
"KmsKeyId": "",
"LastAccessedDate": None,
"LastChangedDate": None,
"LastRotatedDate": None,
"Name": secret["name"],
"RotationEnabled": secret["rotation_enabled"],
"RotationLambdaARN": secret["rotation_lambda_arn"],
"RotationRules": {
"AutomaticallyAfterDays": secret["auto_rotate_after_days"]
},
"SecretVersionsToStages": versions_to_stages,
"Tags": secret["tags"],
}
)
return secret_list, None
def delete_secret(self, secret_id, recovery_window_in_days, force_delete_without_recovery):
def delete_secret(
self, secret_id, recovery_window_in_days, force_delete_without_recovery
):
if not self._is_valid_identifier(secret_id):
raise SecretNotFoundException()
if 'deleted_date' in self.secrets[secret_id]:
if "deleted_date" in self.secrets[secret_id]:
raise InvalidRequestException(
"An error occurred (InvalidRequestException) when calling the DeleteSecret operation: You tried to \
perform the operation on a secret that's currently marked deleted."
@ -359,7 +412,9 @@ class SecretsManagerBackend(BaseBackend):
use ForceDeleteWithoutRecovery in conjunction with RecoveryWindowInDays."
)
if recovery_window_in_days and (recovery_window_in_days < 7 or recovery_window_in_days > 30):
if recovery_window_in_days and (
recovery_window_in_days < 7 or recovery_window_in_days > 30
):
raise InvalidParameterException(
"An error occurred (InvalidParameterException) when calling the DeleteSecret operation: The \
RecoveryWindowInDays value must be between 7 and 30 days (inclusive)."
@ -371,14 +426,16 @@ class SecretsManagerBackend(BaseBackend):
secret = self.secrets.pop(secret_id, None)
else:
deletion_date += datetime.timedelta(days=recovery_window_in_days or 30)
self.secrets[secret_id]['deleted_date'] = self._unix_time_secs(deletion_date)
self.secrets[secret_id]["deleted_date"] = self._unix_time_secs(
deletion_date
)
secret = self.secrets.get(secret_id, None)
if not secret:
raise SecretNotFoundException()
arn = secret_arn(self.region, secret['secret_id'])
name = secret['name']
arn = secret_arn(self.region, secret["secret_id"])
name = secret["name"]
return arn, name, self._unix_time_secs(deletion_date)
@ -387,18 +444,17 @@ class SecretsManagerBackend(BaseBackend):
if not self._is_valid_identifier(secret_id):
raise SecretNotFoundException()
self.secrets[secret_id].pop('deleted_date', None)
self.secrets[secret_id].pop("deleted_date", None)
secret = self.secrets[secret_id]
arn = secret_arn(self.region, secret['secret_id'])
name = secret['name']
arn = secret_arn(self.region, secret["secret_id"])
name = secret["name"]
return arn, name
available_regions = (
boto3.session.Session().get_available_regions("secretsmanager")
)
secretsmanager_backends = {region: SecretsManagerBackend(region_name=region)
for region in available_regions}
available_regions = boto3.session.Session().get_available_regions("secretsmanager")
secretsmanager_backends = {
region: SecretsManagerBackend(region_name=region) for region in available_regions
}

View file

@ -9,38 +9,37 @@ import json
class SecretsManagerResponse(BaseResponse):
def get_secret_value(self):
secret_id = self._get_param('SecretId')
version_id = self._get_param('VersionId')
version_stage = self._get_param('VersionStage')
secret_id = self._get_param("SecretId")
version_id = self._get_param("VersionId")
version_stage = self._get_param("VersionStage")
return secretsmanager_backends[self.region].get_secret_value(
secret_id=secret_id,
version_id=version_id,
version_stage=version_stage)
secret_id=secret_id, version_id=version_id, version_stage=version_stage
)
def create_secret(self):
name = self._get_param('Name')
secret_string = self._get_param('SecretString')
secret_binary = self._get_param('SecretBinary')
tags = self._get_param('Tags', if_none=[])
name = self._get_param("Name")
secret_string = self._get_param("SecretString")
secret_binary = self._get_param("SecretBinary")
tags = self._get_param("Tags", if_none=[])
return secretsmanager_backends[self.region].create_secret(
name=name,
secret_string=secret_string,
secret_binary=secret_binary,
tags=tags
tags=tags,
)
def get_random_password(self):
password_length = self._get_param('PasswordLength', if_none=32)
exclude_characters = self._get_param('ExcludeCharacters', if_none='')
exclude_numbers = self._get_param('ExcludeNumbers', if_none=False)
exclude_punctuation = self._get_param('ExcludePunctuation', if_none=False)
exclude_uppercase = self._get_param('ExcludeUppercase', if_none=False)
exclude_lowercase = self._get_param('ExcludeLowercase', if_none=False)
include_space = self._get_param('IncludeSpace', if_none=False)
password_length = self._get_param("PasswordLength", if_none=32)
exclude_characters = self._get_param("ExcludeCharacters", if_none="")
exclude_numbers = self._get_param("ExcludeNumbers", if_none=False)
exclude_punctuation = self._get_param("ExcludePunctuation", if_none=False)
exclude_uppercase = self._get_param("ExcludeUppercase", if_none=False)
exclude_lowercase = self._get_param("ExcludeLowercase", if_none=False)
include_space = self._get_param("IncludeSpace", if_none=False)
require_each_included_type = self._get_param(
'RequireEachIncludedType', if_none=True)
"RequireEachIncludedType", if_none=True
)
return secretsmanager_backends[self.region].get_random_password(
password_length=password_length,
exclude_characters=exclude_characters,
@ -49,34 +48,34 @@ class SecretsManagerResponse(BaseResponse):
exclude_uppercase=exclude_uppercase,
exclude_lowercase=exclude_lowercase,
include_space=include_space,
require_each_included_type=require_each_included_type
require_each_included_type=require_each_included_type,
)
def describe_secret(self):
secret_id = self._get_param('SecretId')
return secretsmanager_backends[self.region].describe_secret(
secret_id=secret_id
)
secret_id = self._get_param("SecretId")
return secretsmanager_backends[self.region].describe_secret(secret_id=secret_id)
def rotate_secret(self):
client_request_token = self._get_param('ClientRequestToken')
rotation_lambda_arn = self._get_param('RotationLambdaARN')
rotation_rules = self._get_param('RotationRules')
secret_id = self._get_param('SecretId')
client_request_token = self._get_param("ClientRequestToken")
rotation_lambda_arn = self._get_param("RotationLambdaARN")
rotation_rules = self._get_param("RotationRules")
secret_id = self._get_param("SecretId")
return secretsmanager_backends[self.region].rotate_secret(
secret_id=secret_id,
client_request_token=client_request_token,
rotation_lambda_arn=rotation_lambda_arn,
rotation_rules=rotation_rules
rotation_rules=rotation_rules,
)
def put_secret_value(self):
secret_id = self._get_param('SecretId', if_none='')
secret_string = self._get_param('SecretString')
secret_binary = self._get_param('SecretBinary')
secret_id = self._get_param("SecretId", if_none="")
secret_string = self._get_param("SecretString")
secret_binary = self._get_param("SecretBinary")
if not secret_binary and not secret_string:
raise InvalidRequestException('You must provide either SecretString or SecretBinary.')
version_stages = self._get_param('VersionStages', if_none=['AWSCURRENT'])
raise InvalidRequestException(
"You must provide either SecretString or SecretBinary."
)
version_stages = self._get_param("VersionStages", if_none=["AWSCURRENT"])
return secretsmanager_backends[self.region].put_secret_value(
secret_id=secret_id,
secret_binary=secret_binary,
@ -85,7 +84,7 @@ class SecretsManagerResponse(BaseResponse):
)
def list_secret_version_ids(self):
secret_id = self._get_param('SecretId', if_none='')
secret_id = self._get_param("SecretId", if_none="")
return secretsmanager_backends[self.region].list_secret_version_ids(
secret_id=secret_id
)
@ -94,8 +93,7 @@ class SecretsManagerResponse(BaseResponse):
max_results = self._get_int_param("MaxResults")
next_token = self._get_param("NextToken")
secret_list, next_token = secretsmanager_backends[self.region].list_secrets(
max_results=max_results,
next_token=next_token,
max_results=max_results, next_token=next_token
)
return json.dumps(dict(SecretList=secret_list, NextToken=next_token))
@ -113,6 +111,6 @@ class SecretsManagerResponse(BaseResponse):
def restore_secret(self):
secret_id = self._get_param("SecretId")
arn, name = secretsmanager_backends[self.region].restore_secret(
secret_id=secret_id,
secret_id=secret_id
)
return json.dumps(dict(ARN=arn, Name=name))

View file

@ -1,10 +1,6 @@
from __future__ import unicode_literals
from .responses import SecretsManagerResponse
url_bases = [
"https?://secretsmanager.(.+).amazonaws.com",
]
url_bases = ["https?://secretsmanager.(.+).amazonaws.com"]
url_paths = {
'{0}/$': SecretsManagerResponse.dispatch,
}
url_paths = {"{0}/$": SecretsManagerResponse.dispatch}

View file

@ -6,55 +6,70 @@ import six
import re
def random_password(password_length, exclude_characters, exclude_numbers,
exclude_punctuation, exclude_uppercase, exclude_lowercase,
include_space, require_each_included_type):
def random_password(
password_length,
exclude_characters,
exclude_numbers,
exclude_punctuation,
exclude_uppercase,
exclude_lowercase,
include_space,
require_each_included_type,
):
password = ''
required_characters = ''
password = ""
required_characters = ""
if not exclude_lowercase and not exclude_uppercase:
password += string.ascii_letters
required_characters += random.choice(_exclude_characters(
string.ascii_lowercase, exclude_characters))
required_characters += random.choice(_exclude_characters(
string.ascii_uppercase, exclude_characters))
required_characters += random.choice(
_exclude_characters(string.ascii_lowercase, exclude_characters)
)
required_characters += random.choice(
_exclude_characters(string.ascii_uppercase, exclude_characters)
)
elif not exclude_lowercase:
password += string.ascii_lowercase
required_characters += random.choice(_exclude_characters(
string.ascii_lowercase, exclude_characters))
required_characters += random.choice(
_exclude_characters(string.ascii_lowercase, exclude_characters)
)
elif not exclude_uppercase:
password += string.ascii_uppercase
required_characters += random.choice(_exclude_characters(
string.ascii_uppercase, exclude_characters))
required_characters += random.choice(
_exclude_characters(string.ascii_uppercase, exclude_characters)
)
if not exclude_numbers:
password += string.digits
required_characters += random.choice(_exclude_characters(
string.digits, exclude_characters))
required_characters += random.choice(
_exclude_characters(string.digits, exclude_characters)
)
if not exclude_punctuation:
password += string.punctuation
required_characters += random.choice(_exclude_characters(
string.punctuation, exclude_characters))
required_characters += random.choice(
_exclude_characters(string.punctuation, exclude_characters)
)
if include_space:
password += " "
required_characters += " "
password = ''.join(
six.text_type(random.choice(password))
for x in range(password_length))
password = "".join(
six.text_type(random.choice(password)) for x in range(password_length)
)
if require_each_included_type:
password = _add_password_require_each_included_type(
password, required_characters)
password, required_characters
)
password = _exclude_characters(password, exclude_characters)
return password
def secret_arn(region, secret_id):
id_string = ''.join(random.choice(string.ascii_letters) for _ in range(5))
id_string = "".join(random.choice(string.ascii_letters) for _ in range(5))
return "arn:aws:secretsmanager:{0}:1234567890:secret:{1}-{2}".format(
region, secret_id, id_string)
region, secret_id, id_string
)
def _exclude_characters(password, exclude_characters):
@ -62,12 +77,12 @@ def _exclude_characters(password, exclude_characters):
if c in string.punctuation:
# Escape punctuation regex usage
c = "\{0}".format(c)
password = re.sub(c, '', str(password))
password = re.sub(c, "", str(password))
return password
def _add_password_require_each_included_type(password, required_characters):
password_with_required_char = password[:-len(required_characters)]
password_with_required_char = password[: -len(required_characters)]
password_with_required_char += required_characters
return password_with_required_char