support Tags parameter in ACM import_certificate() and request_certificate() methods (#3373)

* ACM: support `tags` parameter in import_certificate()

* ACM: support tags parameter in  request_certificate()

* ACM: better tag operations with more unit tests

Co-authored-by: nom3ad <nom3ad@gmail.com>
This commit is contained in:
nom3ad 2020-10-12 12:25:14 +05:30 committed by GitHub
commit ea0ba91f63
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 247 additions and 23 deletions

View file

@ -11,6 +11,7 @@ from botocore.exceptions import ClientError
from moto import mock_acm
from moto.core import ACCOUNT_ID
from nose.tools import assert_raises
RESOURCE_FOLDER = os.path.join(os.path.dirname(__file__), "resources")
_GET_RESOURCE = lambda x: open(os.path.join(RESOURCE_FOLDER, x), "rb").read()
@ -46,6 +47,30 @@ def test_import_certificate():
resp.should.contain("CertificateChain")
@mock_acm
def test_import_certificate_with_tags():
client = boto3.client("acm", region_name="eu-central-1")
resp = client.import_certificate(
Certificate=SERVER_CRT,
PrivateKey=SERVER_KEY,
CertificateChain=CA_CRT,
Tags=[{"Key": "Environment", "Value": "QA"}, {"Key": "KeyOnly"},],
)
arn = resp["CertificateArn"]
resp = client.get_certificate(CertificateArn=arn)
resp["Certificate"].should.equal(SERVER_CRT.decode())
resp.should.contain("CertificateChain")
resp = client.list_tags_for_certificate(CertificateArn=arn)
tags = {item["Key"]: item.get("Value", "__NONE__") for item in resp["Tags"]}
tags.should.contain("Environment")
tags.should.contain("KeyOnly")
tags["Environment"].should.equal("QA")
tags["KeyOnly"].should.equal("__NONE__")
@mock_acm
def test_import_bad_certificate():
client = boto3.client("acm", region_name="eu-central-1")
@ -313,6 +338,150 @@ def test_request_certificate():
resp["CertificateArn"].should.equal(arn)
@mock_acm
def test_request_certificate_with_tags():
client = boto3.client("acm", region_name="eu-central-1")
token = str(uuid.uuid4())
resp = client.request_certificate(
DomainName="google.com",
IdempotencyToken=token,
SubjectAlternativeNames=["google.com", "www.google.com", "mail.google.com"],
Tags=[
{"Key": "Environment", "Value": "QA"},
{"Key": "WithEmptyStr", "Value": ""},
],
)
resp.should.contain("CertificateArn")
arn_1 = resp["CertificateArn"]
resp = client.list_tags_for_certificate(CertificateArn=arn_1)
tags = {item["Key"]: item.get("Value", "__NONE__") for item in resp["Tags"]}
tags.should.have.length_of(2)
tags["Environment"].should.equal("QA")
tags["WithEmptyStr"].should.equal("")
# Request certificate for "google.com" with same IdempotencyToken but with different Tags
resp = client.request_certificate(
DomainName="google.com",
IdempotencyToken=token,
SubjectAlternativeNames=["google.com", "www.google.com", "mail.google.com"],
Tags=[{"Key": "Environment", "Value": "Prod"}, {"Key": "KeyOnly"},],
)
arn_2 = resp["CertificateArn"]
assert arn_1 != arn_2 # if tags are matched, ACM would have returned same arn
resp = client.list_tags_for_certificate(CertificateArn=arn_2)
tags = {item["Key"]: item.get("Value", "__NONE__") for item in resp["Tags"]}
tags.should.have.length_of(2)
tags["Environment"].should.equal("Prod")
tags["KeyOnly"].should.equal("__NONE__")
resp = client.request_certificate(
DomainName="google.com",
IdempotencyToken=token,
SubjectAlternativeNames=["google.com", "www.google.com", "mail.google.com"],
Tags=[
{"Key": "Environment", "Value": "QA"},
{"Key": "WithEmptyStr", "Value": ""},
],
)
@mock_acm
def test_operations_with_invalid_tags():
client = boto3.client("acm", region_name="eu-central-1")
# request certificate with invalid tags
with assert_raises(ClientError) as ex:
client.request_certificate(
DomainName="example.com", Tags=[{"Key": "X" * 200, "Value": "Valid"}],
)
ex.exception.response["Error"]["Code"].should.equal("ValidationException")
ex.exception.response["Error"]["Message"].should.contain(
"Member must have length less than or equal to 128"
)
# import certificate with invalid tags
with assert_raises(ClientError) as ex:
client.import_certificate(
Certificate=SERVER_CRT,
PrivateKey=SERVER_KEY,
CertificateChain=CA_CRT,
Tags=[
{"Key": "Valid", "Value": "X" * 300},
{"Key": "aws:xx", "Value": "Valid"},
],
)
ex.exception.response["Error"]["Code"].should.equal("ValidationException")
ex.exception.response["Error"]["Message"].should.contain(
"Member must have length less than or equal to 256"
)
arn = _import_cert(client)
# add invalid tags to existing certificate
with assert_raises(ClientError) as ex:
client.add_tags_to_certificate(
CertificateArn=arn,
Tags=[{"Key": "aws:xxx", "Value": "Valid"}, {"Key": "key2"}],
)
ex.exception.response["Error"]["Code"].should.equal("ValidationException")
ex.exception.response["Error"]["Message"].should.contain(
"AWS internal tags cannot be changed with this API"
)
# try removing invalid tags from existing certificate
with assert_raises(ClientError) as ex:
client.remove_tags_from_certificate(
CertificateArn=arn, Tags=[{"Key": "aws:xxx", "Value": "Valid"}]
)
ex.exception.response["Error"]["Code"].should.equal("ValidationException")
ex.exception.response["Error"]["Message"].should.contain(
"AWS internal tags cannot be changed with this API"
)
@mock_acm
def test_add_too_many_tags():
client = boto3.client("acm", region_name="eu-central-1")
arn = _import_cert(client)
# Add 51 tags
with assert_raises(ClientError) as ex:
client.add_tags_to_certificate(
CertificateArn=arn,
Tags=[{"Key": "a-%d" % i, "Value": "abcd"} for i in range(1, 52)],
)
ex.exception.response["Error"]["Code"].should.equal("TooManyTagsException")
ex.exception.response["Error"]["Message"].should.contain("contains too many Tags")
client.list_tags_for_certificate(CertificateArn=arn)["Tags"].should.have.empty
# Add 49 tags first, then try to add 2 more.
client.add_tags_to_certificate(
CertificateArn=arn,
Tags=[{"Key": "p-%d" % i, "Value": "pqrs"} for i in range(1, 50)],
)
client.list_tags_for_certificate(CertificateArn=arn)["Tags"].should.have.length_of(
49
)
with assert_raises(ClientError) as ex:
client.add_tags_to_certificate(
CertificateArn=arn,
Tags=[{"Key": "x-1", "Value": "xyz"}, {"Key": "x-2", "Value": "xyz"}],
)
ex.exception.response["Error"]["Code"].should.equal("TooManyTagsException")
ex.exception.response["Error"]["Message"].should.contain("contains too many Tags")
ex.exception.response["Error"]["Message"].count("pqrs").should.equal(49)
ex.exception.response["Error"]["Message"].count("xyz").should.equal(2)
client.list_tags_for_certificate(CertificateArn=arn)["Tags"].should.have.length_of(
49
)
@mock_acm
def test_request_certificate_no_san():
client = boto3.client("acm", region_name="eu-central-1")