Add describe_endpoint and register_certificate_without_ca in iot_mock module with unittest (#3279)

Co-authored-by: Zhi Li <zhi_li@trendmicro.com>
This commit is contained in:
zhil3 2020-09-04 04:11:17 -04:00 committed by GitHub
parent d2e16ecc2e
commit 8854fd06e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 148 additions and 2 deletions

View File

@ -4447,7 +4447,7 @@
- [ ] describe_default_authorizer
- [ ] describe_dimension
- [ ] describe_domain_configuration
- [ ] describe_endpoint
- [X] describe_endpoint
- [ ] describe_event_configurations
- [ ] describe_index
- [X] describe_job
@ -4533,7 +4533,7 @@
- [ ] list_violation_events
- [ ] register_ca_certificate
- [X] register_certificate
- [ ] register_certificate_without_ca
- [X] register_certificate_without_ca
- [ ] register_thing
- [ ] reject_certificate_transfer
- [ ] remove_thing_from_billing_group

View File

@ -20,6 +20,7 @@ from .exceptions import (
InvalidStateTransitionException,
VersionConflictException,
)
from moto.utilities.utils import random_string
class FakeThing(BaseModel):
@ -374,6 +375,55 @@ class FakeJobExecution(BaseModel):
return obj
class FakeEndpoint(BaseModel):
def __init__(self, endpoint_type, region_name):
if endpoint_type not in [
"iot:Data",
"iot:Data-ATS",
"iot:CredentialProvider",
"iot:Jobs",
]:
raise InvalidRequestException(
" An error occurred (InvalidRequestException) when calling the DescribeEndpoint "
"operation: Endpoint type %s not recognized." % endpoint_type
)
self.region_name = region_name
data_identifier = random_string(14)
if endpoint_type == "iot:Data":
self.endpoint = "{i}.iot.{r}.amazonaws.com".format(
i=data_identifier, r=self.region_name
)
elif "iot:Data-ATS" in endpoint_type:
self.endpoint = "{i}-ats.iot.{r}.amazonaws.com".format(
i=data_identifier, r=self.region_name
)
elif "iot:CredentialProvider" in endpoint_type:
identifier = random_string(14)
self.endpoint = "{i}.credentials.iot.{r}.amazonaws.com".format(
i=identifier, r=self.region_name
)
elif "iot:Jobs" in endpoint_type:
identifier = random_string(14)
self.endpoint = "{i}.jobs.iot.{r}.amazonaws.com".format(
i=identifier, r=self.region_name
)
self.endpoint_type = endpoint_type
def to_get_dict(self):
obj = {
"endpointAddress": self.endpoint,
}
return obj
def to_dict(self):
obj = {
"endpointAddress": self.endpoint,
}
return obj
class IoTBackend(BaseBackend):
def __init__(self, region_name=None):
super(IoTBackend, self).__init__()
@ -387,6 +437,7 @@ class IoTBackend(BaseBackend):
self.policies = OrderedDict()
self.principal_policies = OrderedDict()
self.principal_things = OrderedDict()
self.endpoint = None
def reset(self):
region_name = self.region_name
@ -495,6 +546,10 @@ class IoTBackend(BaseBackend):
raise ResourceNotFoundException()
return thing_types[0]
def describe_endpoint(self, endpoint_type):
self.endpoint = FakeEndpoint(endpoint_type, self.region_name)
return self.endpoint
def delete_thing(self, thing_name, expected_version):
# TODO: handle expected_version
@ -625,6 +680,11 @@ class IoTBackend(BaseBackend):
self.certificates[certificate.certificate_id] = certificate
return certificate
def register_certificate_without_ca(self, certificate_pem, status):
certificate = FakeCertificate(certificate_pem, status, self.region_name)
self.certificates[certificate.certificate_id] = certificate
return certificate
def update_certificate(self, certificate_id, new_status):
cert = self.describe_certificate(certificate_id)
# TODO: validate new_status

View File

@ -88,6 +88,11 @@ class IoTResponse(BaseResponse):
)
return json.dumps(thing_type.to_dict())
def describe_endpoint(self):
endpoint_type = self._get_param("endpointType")
endpoint = self.iot_backend.describe_endpoint(endpoint_type=endpoint_type)
return json.dumps(endpoint.to_dict())
def delete_thing(self):
thing_name = self._get_param("thingName")
expected_version = self._get_param("expectedVersion")
@ -330,6 +335,17 @@ class IoTResponse(BaseResponse):
dict(certificateId=cert.certificate_id, certificateArn=cert.arn)
)
def register_certificate_without_ca(self):
certificate_pem = self._get_param("certificatePem")
status = self._get_param("status")
cert = self.iot_backend.register_certificate_without_ca(
certificate_pem=certificate_pem, status=status,
)
return json.dumps(
dict(certificateId=cert.certificate_id, certificateArn=cert.arn)
)
def update_certificate(self):
certificate_id = self._get_param("certificateId")
new_status = self._get_param("newStatus")

10
moto/utilities/utils.py Normal file
View File

@ -0,0 +1,10 @@
import random
import string
def random_string(length=None):
n = length or 20
random_str = "".join(
[random.choice(string.ascii_letters + string.digits) for i in range(n)]
)
return random_str

View File

@ -463,6 +463,46 @@ def test_list_things_with_attribute_and_thing_type_filter_and_next_token():
)
@mock_iot
def test_endpoints():
region_name = "ap-northeast-1"
client = boto3.client("iot", region_name=region_name)
# iot:Data
endpoint = client.describe_endpoint(endpointType="iot:Data")
endpoint.should.have.key("endpointAddress").which.should_not.contain("ats")
endpoint.should.have.key("endpointAddress").which.should.contain(
"iot.{}.amazonaws.com".format(region_name)
)
# iot:Data-ATS
endpoint = client.describe_endpoint(endpointType="iot:Data-ATS")
endpoint.should.have.key("endpointAddress").which.should.contain(
"ats.iot.{}.amazonaws.com".format(region_name)
)
# iot:Data-ATS
endpoint = client.describe_endpoint(endpointType="iot:CredentialProvider")
endpoint.should.have.key("endpointAddress").which.should.contain(
"credentials.iot.{}.amazonaws.com".format(region_name)
)
# iot:Data-ATS
endpoint = client.describe_endpoint(endpointType="iot:Jobs")
endpoint.should.have.key("endpointAddress").which.should.contain(
"jobs.iot.{}.amazonaws.com".format(region_name)
)
# raise InvalidRequestException
try:
client.describe_endpoint(endpointType="iot:Abc")
except client.exceptions.InvalidRequestException as exc:
error_code = exc.response["Error"]["Code"]
error_code.should.equal("InvalidRequestException")
else:
raise Exception("Should have raised error")
@mock_iot
def test_certs():
client = boto3.client("iot", region_name="us-east-1")
@ -523,6 +563,26 @@ def test_certs():
res = client.list_certificates()
res.should.have.key("certificates")
# Test register_certificate without CA flow
cert = client.register_certificate_without_ca(
certificatePem=cert_pem, status="INACTIVE"
)
cert.should.have.key("certificateId").which.should_not.be.none
cert.should.have.key("certificateArn").which.should_not.be.none
cert_id = cert["certificateId"]
res = client.list_certificates()
res.should.have.key("certificates").which.should.have.length_of(1)
for cert in res["certificates"]:
cert.should.have.key("certificateArn").which.should_not.be.none
cert.should.have.key("certificateId").which.should_not.be.none
cert.should.have.key("status").which.should_not.be.none
cert.should.have.key("creationDate").which.should_not.be.none
client.delete_certificate(certificateId=cert_id)
res = client.list_certificates()
res.should.have.key("certificates")
@mock_iot
def test_delete_policy_validation():