Merge pull request #2920 from lukaszpierog/handle-tags-and-description-in-secrets

Do not remove tags after secret update, handle description
This commit is contained in:
Bert Blommers 2020-04-26 10:29:02 +01:00 committed by GitHub
commit 6a41573eb8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 143 additions and 6 deletions

View File

@ -121,8 +121,16 @@ class SecretsManagerBackend(BaseBackend):
"You can't perform this operation on the secret because it was marked for deletion." "You can't perform this operation on the secret because it was marked for deletion."
) )
secret = self.secrets[secret_id]
tags = secret["tags"]
description = secret["description"]
version_id = self._add_secret( version_id = self._add_secret(
secret_id, secret_string=secret_string, secret_binary=secret_binary secret_id,
secret_string=secret_string,
secret_binary=secret_binary,
description=description,
tags=tags,
) )
response = json.dumps( response = json.dumps(
@ -136,7 +144,13 @@ class SecretsManagerBackend(BaseBackend):
return response return response
def create_secret( def create_secret(
self, name, secret_string=None, secret_binary=None, tags=[], **kwargs self,
name,
secret_string=None,
secret_binary=None,
description=None,
tags=[],
**kwargs
): ):
# error if secret exists # error if secret exists
@ -146,7 +160,11 @@ class SecretsManagerBackend(BaseBackend):
) )
version_id = self._add_secret( version_id = self._add_secret(
name, secret_string=secret_string, secret_binary=secret_binary, tags=tags name,
secret_string=secret_string,
secret_binary=secret_binary,
description=description,
tags=tags,
) )
response = json.dumps( response = json.dumps(
@ -164,6 +182,7 @@ class SecretsManagerBackend(BaseBackend):
secret_id, secret_id,
secret_string=None, secret_string=None,
secret_binary=None, secret_binary=None,
description=None,
tags=[], tags=[],
version_id=None, version_id=None,
version_stages=None, version_stages=None,
@ -216,13 +235,27 @@ class SecretsManagerBackend(BaseBackend):
secret["rotation_lambda_arn"] = "" secret["rotation_lambda_arn"] = ""
secret["auto_rotate_after_days"] = 0 secret["auto_rotate_after_days"] = 0
secret["tags"] = tags secret["tags"] = tags
secret["description"] = description
return version_id return version_id
def put_secret_value(self, secret_id, secret_string, secret_binary, version_stages): def put_secret_value(self, secret_id, secret_string, secret_binary, version_stages):
if secret_id in self.secrets.keys():
secret = self.secrets[secret_id]
tags = secret["tags"]
description = secret["description"]
else:
tags = []
description = ""
version_id = self._add_secret( version_id = self._add_secret(
secret_id, secret_string, secret_binary, version_stages=version_stages secret_id,
secret_string,
secret_binary,
description=description,
tags=tags,
version_stages=version_stages,
) )
response = json.dumps( response = json.dumps(
@ -246,7 +279,7 @@ class SecretsManagerBackend(BaseBackend):
{ {
"ARN": secret_arn(self.region, secret["secret_id"]), "ARN": secret_arn(self.region, secret["secret_id"]),
"Name": secret["name"], "Name": secret["name"],
"Description": "", "Description": secret.get("description", ""),
"KmsKeyId": "", "KmsKeyId": "",
"RotationEnabled": secret["rotation_enabled"], "RotationEnabled": secret["rotation_enabled"],
"RotationLambdaARN": secret["rotation_lambda_arn"], "RotationLambdaARN": secret["rotation_lambda_arn"],
@ -310,6 +343,7 @@ class SecretsManagerBackend(BaseBackend):
self._add_secret( self._add_secret(
secret_id, secret_id,
old_secret_version["secret_string"], old_secret_version["secret_string"],
secret["description"],
secret["tags"], secret["tags"],
version_id=new_version_id, version_id=new_version_id,
version_stages=["AWSCURRENT"], version_stages=["AWSCURRENT"],
@ -416,7 +450,7 @@ class SecretsManagerBackend(BaseBackend):
{ {
"ARN": secret_arn(self.region, secret["secret_id"]), "ARN": secret_arn(self.region, secret["secret_id"]),
"DeletedDate": secret.get("deleted_date", None), "DeletedDate": secret.get("deleted_date", None),
"Description": "", "Description": secret.get("description", ""),
"KmsKeyId": "", "KmsKeyId": "",
"LastAccessedDate": None, "LastAccessedDate": None,
"LastChangedDate": None, "LastChangedDate": None,

View File

@ -21,11 +21,13 @@ class SecretsManagerResponse(BaseResponse):
name = self._get_param("Name") name = self._get_param("Name")
secret_string = self._get_param("SecretString") secret_string = self._get_param("SecretString")
secret_binary = self._get_param("SecretBinary") secret_binary = self._get_param("SecretBinary")
description = self._get_param("Description", if_none="")
tags = self._get_param("Tags", if_none=[]) tags = self._get_param("Tags", if_none=[])
return secretsmanager_backends[self.region].create_secret( return secretsmanager_backends[self.region].create_secret(
name=name, name=name,
secret_string=secret_string, secret_string=secret_string,
secret_binary=secret_binary, secret_binary=secret_binary,
description=description,
tags=tags, tags=tags,
) )

View File

@ -137,6 +137,45 @@ def test_create_secret_with_tags():
] ]
@mock_secretsmanager
def test_create_secret_with_description():
conn = boto3.client("secretsmanager", region_name="us-east-1")
secret_name = "test-secret-with-tags"
result = conn.create_secret(
Name=secret_name, SecretString="foosecret", Description="desc"
)
assert result["ARN"]
assert result["Name"] == secret_name
secret_value = conn.get_secret_value(SecretId=secret_name)
assert secret_value["SecretString"] == "foosecret"
secret_details = conn.describe_secret(SecretId=secret_name)
assert secret_details["Description"] == "desc"
@mock_secretsmanager
def test_create_secret_with_tags_and_description():
conn = boto3.client("secretsmanager", region_name="us-east-1")
secret_name = "test-secret-with-tags"
result = conn.create_secret(
Name=secret_name,
SecretString="foosecret",
Description="desc",
Tags=[{"Key": "Foo", "Value": "Bar"}, {"Key": "Mykey", "Value": "Myvalue"}],
)
assert result["ARN"]
assert result["Name"] == secret_name
secret_value = conn.get_secret_value(SecretId=secret_name)
assert secret_value["SecretString"] == "foosecret"
secret_details = conn.describe_secret(SecretId=secret_name)
assert secret_details["Tags"] == [
{"Key": "Foo", "Value": "Bar"},
{"Key": "Mykey", "Value": "Myvalue"},
]
assert secret_details["Description"] == "desc"
@mock_secretsmanager @mock_secretsmanager
def test_delete_secret(): def test_delete_secret():
conn = boto3.client("secretsmanager", region_name="us-west-2") conn = boto3.client("secretsmanager", region_name="us-west-2")
@ -690,6 +729,31 @@ def test_put_secret_value_versions_differ_if_same_secret_put_twice():
assert first_version_id != second_version_id assert first_version_id != second_version_id
@mock_secretsmanager
def test_put_secret_value_maintains_description_and_tags():
conn = boto3.client("secretsmanager", region_name="us-west-2")
conn.create_secret(
Name=DEFAULT_SECRET_NAME,
SecretString="foosecret",
Description="desc",
Tags=[{"Key": "Foo", "Value": "Bar"}, {"Key": "Mykey", "Value": "Myvalue"}],
)
conn = boto3.client("secretsmanager", region_name="us-west-2")
conn.put_secret_value(
SecretId=DEFAULT_SECRET_NAME,
SecretString="dupe_secret",
VersionStages=["AWSCURRENT"],
)
secret_details = conn.describe_secret(SecretId=DEFAULT_SECRET_NAME)
assert secret_details["Tags"] == [
{"Key": "Foo", "Value": "Bar"},
{"Key": "Mykey", "Value": "Myvalue"},
]
assert secret_details["Description"] == "desc"
@mock_secretsmanager @mock_secretsmanager
def test_can_list_secret_version_ids(): def test_can_list_secret_version_ids():
conn = boto3.client("secretsmanager", region_name="us-west-2") conn = boto3.client("secretsmanager", region_name="us-west-2")
@ -739,6 +803,43 @@ def test_update_secret():
assert created_secret["VersionId"] != updated_secret["VersionId"] assert created_secret["VersionId"] != updated_secret["VersionId"]
@mock_secretsmanager
def test_update_secret_with_tags_and_description():
conn = boto3.client("secretsmanager", region_name="us-west-2")
created_secret = conn.create_secret(
Name="test-secret",
SecretString="foosecret",
Description="desc",
Tags=[{"Key": "Foo", "Value": "Bar"}, {"Key": "Mykey", "Value": "Myvalue"}],
)
assert created_secret["ARN"]
assert created_secret["Name"] == "test-secret"
assert created_secret["VersionId"] != ""
secret = conn.get_secret_value(SecretId="test-secret")
assert secret["SecretString"] == "foosecret"
updated_secret = conn.update_secret(
SecretId="test-secret", SecretString="barsecret"
)
assert updated_secret["ARN"]
assert updated_secret["Name"] == "test-secret"
assert updated_secret["VersionId"] != ""
secret = conn.get_secret_value(SecretId="test-secret")
assert secret["SecretString"] == "barsecret"
assert created_secret["VersionId"] != updated_secret["VersionId"]
secret_details = conn.describe_secret(SecretId="test-secret")
assert secret_details["Tags"] == [
{"Key": "Foo", "Value": "Bar"},
{"Key": "Mykey", "Value": "Myvalue"},
]
assert secret_details["Description"] == "desc"
@mock_secretsmanager @mock_secretsmanager
def test_update_secret_which_does_not_exit(): def test_update_secret_which_does_not_exit():
conn = boto3.client("secretsmanager", region_name="us-west-2") conn = boto3.client("secretsmanager", region_name="us-west-2")