moto/moto/acm/responses.py

295 lines
9.6 KiB
Python
Raw Normal View History

2017-09-21 20:44:34 +00:00
import json
import base64
2017-09-21 20:44:34 +00:00
from moto.core.responses import BaseResponse
from .models import acm_backends, AWSError, AWSValidationException
2017-09-21 20:44:34 +00:00
class AWSCertificateManagerResponse(BaseResponse):
@property
def acm_backend(self):
"""
ACM Backend
:return: ACM Backend object
:rtype: moto.acm.models.AWSCertificateManagerBackend
"""
2017-09-21 20:44:34 +00:00
return acm_backends[self.region]
@property
def request_params(self):
try:
return json.loads(self.body)
except ValueError:
return {}
def _get_param(self, param, default=None):
return self.request_params.get(param, default)
def add_tags_to_certificate(self):
2019-10-31 15:44:26 +00:00
arn = self._get_param("CertificateArn")
tags = self._get_param("Tags")
if arn is None:
2019-10-31 15:44:26 +00:00
msg = "A required parameter for the specified action is not supplied."
return (
json.dumps({"__type": "MissingParameter", "message": msg}),
dict(status=400),
)
try:
self.acm_backend.add_tags_to_certificate(arn, tags)
except AWSError as err:
return err.response()
2019-10-31 15:44:26 +00:00
return ""
2017-09-21 20:44:34 +00:00
def delete_certificate(self):
2019-10-31 15:44:26 +00:00
arn = self._get_param("CertificateArn")
if arn is None:
2019-10-31 15:44:26 +00:00
msg = "A required parameter for the specified action is not supplied."
return (
json.dumps({"__type": "MissingParameter", "message": msg}),
dict(status=400),
)
try:
self.acm_backend.delete_certificate(arn)
except AWSError as err:
return err.response()
2019-10-31 15:44:26 +00:00
return ""
2017-09-21 20:44:34 +00:00
def describe_certificate(self):
2019-10-31 15:44:26 +00:00
arn = self._get_param("CertificateArn")
if arn is None:
2019-10-31 15:44:26 +00:00
msg = "A required parameter for the specified action is not supplied."
return (
json.dumps({"__type": "MissingParameter", "message": msg}),
dict(status=400),
)
try:
cert_bundle = self.acm_backend.get_certificate(arn)
except AWSError as err:
return err.response()
return json.dumps(cert_bundle.describe())
2017-09-21 20:44:34 +00:00
def get_certificate(self):
2019-10-31 15:44:26 +00:00
arn = self._get_param("CertificateArn")
if arn is None:
2019-10-31 15:44:26 +00:00
msg = "A required parameter for the specified action is not supplied."
return (
json.dumps({"__type": "MissingParameter", "message": msg}),
dict(status=400),
)
try:
cert_bundle = self.acm_backend.get_certificate(arn)
except AWSError as err:
return err.response()
result = {
2019-10-31 15:44:26 +00:00
"Certificate": cert_bundle.cert.decode(),
"CertificateChain": cert_bundle.chain.decode(),
}
return json.dumps(result)
2017-09-21 20:44:34 +00:00
def import_certificate(self):
"""
Returns errors on:
Certificate, PrivateKey or Chain not being properly formatted
Arn not existing if its provided
PrivateKey size > 2048
Certificate expired or is not yet in effect
Does not return errors on:
Checking Certificate is legit, or a selfsigned chain is provided
:return: str(JSON) for response
"""
2019-10-31 15:44:26 +00:00
certificate = self._get_param("Certificate")
private_key = self._get_param("PrivateKey")
chain = self._get_param("CertificateChain") # Optional
current_arn = self._get_param("CertificateArn") # Optional
tags = self._get_param("Tags") # Optional
# Simple parameter decoding. Rather do it here as its a data transport decision not part of the
# actual data
try:
certificate = base64.standard_b64decode(certificate)
except Exception:
2019-10-31 15:44:26 +00:00
return AWSValidationException(
"The certificate is not PEM-encoded or is not valid."
).response()
try:
private_key = base64.standard_b64decode(private_key)
except Exception:
2019-10-31 15:44:26 +00:00
return AWSValidationException(
"The private key is not PEM-encoded or is not valid."
).response()
if chain is not None:
try:
chain = base64.standard_b64decode(chain)
except Exception:
2019-10-31 15:44:26 +00:00
return AWSValidationException(
"The certificate chain is not PEM-encoded or is not valid."
).response()
try:
2019-10-31 15:44:26 +00:00
arn = self.acm_backend.import_cert(
certificate, private_key, chain=chain, arn=current_arn, tags=tags
2019-10-31 15:44:26 +00:00
)
except AWSError as err:
return err.response()
2019-10-31 15:44:26 +00:00
return json.dumps({"CertificateArn": arn})
2017-09-21 20:44:34 +00:00
def list_certificates(self):
certs = []
2019-10-31 15:44:26 +00:00
statuses = self._get_param("CertificateStatuses")
2019-08-20 00:29:14 +00:00
for cert_bundle in self.acm_backend.get_certificates_list(statuses):
2019-10-31 15:44:26 +00:00
certs.append(
{
"CertificateArn": cert_bundle.arn,
"DomainName": cert_bundle.common_name,
}
)
result = {"CertificateSummaryList": certs}
return json.dumps(result)
2017-09-21 20:44:34 +00:00
def list_tags_for_certificate(self):
2019-10-31 15:44:26 +00:00
arn = self._get_param("CertificateArn")
if arn is None:
2019-10-31 15:44:26 +00:00
msg = "A required parameter for the specified action is not supplied."
return {"__type": "MissingParameter", "message": msg}, dict(status=400)
try:
cert_bundle = self.acm_backend.get_certificate(arn)
except AWSError as err:
return err.response()
2019-10-31 15:44:26 +00:00
result = {"Tags": []}
# Tag "objects" can not contain the Value part
for key, value in cert_bundle.tags.items():
2019-10-31 15:44:26 +00:00
tag_dict = {"Key": key}
if value is not None:
2019-10-31 15:44:26 +00:00
tag_dict["Value"] = value
result["Tags"].append(tag_dict)
return json.dumps(result)
2017-09-21 20:44:34 +00:00
def remove_tags_from_certificate(self):
2019-10-31 15:44:26 +00:00
arn = self._get_param("CertificateArn")
tags = self._get_param("Tags")
if arn is None:
2019-10-31 15:44:26 +00:00
msg = "A required parameter for the specified action is not supplied."
return (
json.dumps({"__type": "MissingParameter", "message": msg}),
dict(status=400),
)
try:
self.acm_backend.remove_tags_from_certificate(arn, tags)
except AWSError as err:
return err.response()
2019-10-31 15:44:26 +00:00
return ""
2017-09-21 20:44:34 +00:00
def request_certificate(self):
2019-10-31 15:44:26 +00:00
domain_name = self._get_param("DomainName")
domain_validation_options = self._get_param(
"DomainValidationOptions"
) # is ignored atm
idempotency_token = self._get_param("IdempotencyToken")
subject_alt_names = self._get_param("SubjectAlternativeNames")
tags = self._get_param("Tags") # Optional
2017-09-22 13:26:05 +00:00
if subject_alt_names is not None and len(subject_alt_names) > 10:
2017-09-22 13:26:05 +00:00
# There is initial AWS limit of 10
2019-10-31 15:44:26 +00:00
msg = (
"An ACM limit has been exceeded. Need to request SAN limit to be raised"
)
return (
json.dumps({"__type": "LimitExceededException", "message": msg}),
dict(status=400),
)
2017-09-22 13:26:05 +00:00
try:
2019-10-31 15:44:26 +00:00
arn = self.acm_backend.request_certificate(
domain_name,
domain_validation_options,
idempotency_token,
subject_alt_names,
tags,
2019-10-31 15:44:26 +00:00
)
2017-09-22 13:26:05 +00:00
except AWSError as err:
return err.response()
2019-10-31 15:44:26 +00:00
return json.dumps({"CertificateArn": arn})
2017-09-21 20:44:34 +00:00
def resend_validation_email(self):
2019-10-31 15:44:26 +00:00
arn = self._get_param("CertificateArn")
domain = self._get_param("Domain")
2017-09-22 13:26:05 +00:00
# ValidationDomain not used yet.
# Contains domain which is equal to or a subset of Domain
# that AWS will send validation emails to
# https://docs.aws.amazon.com/acm/latest/APIReference/API_ResendValidationEmail.html
# validation_domain = self._get_param('ValidationDomain')
if arn is None:
2019-10-31 15:44:26 +00:00
msg = "A required parameter for the specified action is not supplied."
return (
json.dumps({"__type": "MissingParameter", "message": msg}),
dict(status=400),
)
2017-09-22 13:26:05 +00:00
try:
cert_bundle = self.acm_backend.get_certificate(arn)
if cert_bundle.common_name != domain:
2019-10-31 15:44:26 +00:00
msg = "Parameter Domain does not match certificate domain"
_type = "InvalidDomainValidationOptionsException"
return json.dumps({"__type": _type, "message": msg}), dict(status=400)
2017-09-22 13:26:05 +00:00
except AWSError as err:
return err.response()
2019-10-31 15:44:26 +00:00
return ""
def export_certificate(self):
certificate_arn = self._get_param("CertificateArn")
passphrase = self._get_param("Passphrase")
if certificate_arn is None:
msg = "A required parameter for the specified action is not supplied."
return (
json.dumps({"__type": "MissingParameter", "message": msg}),
dict(status=400),
)
try:
(
certificate,
certificate_chain,
private_key,
) = self.acm_backend.export_certificate(
certificate_arn=certificate_arn, passphrase=passphrase,
)
return json.dumps(
dict(
Certificate=certificate,
CertificateChain=certificate_chain,
PrivateKey=private_key,
)
)
except AWSError as err:
return err.response()