def test_get_change_batch(self):
     patch.stopall()
     cv = CertificateValidator(self.request, self.response)
     resource_record = {
         'Name': '_x1.certificate-validator.com.',
         'Type': 'CNAME',
         'Value': '_x2.acm-validations.aws.'
     }
     actual = cv.get_change_batch(
         action='CREATE', resource_record=resource_record
     )
     expected = {
         'Changes': [{
             'Action': 'CREATE',
             'ResourceRecordSet': {
                 'Name': '_x1.certificate-validator.com.',
                 'Type': 'CNAME',
                 'TTL': 300,
                 'ResourceRecords': [{
                     'Value': '_x2.acm-validations.aws.'
                 }]
             }
         }]
     }
     self.assertEqual(expected, actual)
예제 #2
0
def handler(event: dict, context: object) -> dict:
    """
    Handle AWS Lambda function event.

    :param event: event data
    :type event: dict
    :param context: runtime information of the AWS Lambda function
    :type context: LambdaContext object
    """
    logger.debug('Request: {}'.format(event))

    request = Request(**event)

    response = Response(
        request_id=request.request_id,
        stack_id=request.stack_id,
        logical_resource_id=request.logical_resource_id,
        physical_resource_id=request.physical_resource_id
    )

    if request.resource_type == 'Custom::Certificate':
        certificate = Certificate(request, response)
        certificate.handler()
        logger.debug('Response: {}'.format(certificate.response.dict()))

    if request.resource_type == 'Custom::CertificateValidator':
        certificate_validator = CertificateValidator(request, response)
        certificate_validator.handler()
        logger.debug(
            'Response: {}'.format(certificate_validator.response.dict())
        )
 def test_get_domain_validation_options(self):
     patch.stopall()
     mock_describe_certificate = patch.object(
         resources.ACM, 'describe_certificate'
     ).start()
     mock_describe_certificate.return_value = {
         'Certificate': {
             'DomainName': 'certificate-validator.com',
             'DomainValidationOptions': [{
                 'DomainName': 'certificate-validator.com',
                 'ResourceRecord': {
                     'Name': '_x1.certificate-validator.com.',
                     'Type': 'CNAME',
                     'Value': '_x2.acm-validations.aws.'
                 }
             }]
         }
     }
     cv = CertificateValidator(self.request, self.response)
     actual = cv.get_domain_validation_options(
         certificate_arn='arn:aws:acm:us-east-1:123:certificate/1337'
     )
     expected = [{
         'DomainName': 'certificate-validator.com',
         'ResourceRecord': {
             'Name': '_x1.certificate-validator.com.',
             'Type': 'CNAME',
             'Value': '_x2.acm-validations.aws.'
         }
     }]
     self.assertEqual(expected, actual)
 def test_change_resource_record_sets_delete_success(self):
     self.mock_request.resource_properties = {
         'CertificateArn': self.certificate_arn
     }
     cv = CertificateValidator(self.mock_request, self.mock_response)
     cv.change_resource_record_sets(self.certificate_arn, Action.DELETE)
     self.mock_get_hosted_zone_id.assert_called_with(
         'certificate-validator.com'
     )
     self.mock_get_domain_validation_options.assert_called_with(
         'arn:aws:acm:us-east-1:123:certificate/1337'
     )
     self.mock_get_change_batch.assert_called_with(
         'DELETE', {
             'Name': '_x1.certificate-validator.com.',
             'Type': 'CNAME',
             'Value': '_x2.acm-validations.aws.'
         }
     )
     self.mock_change_resource_record_sets.assert_called_with(
         hosted_zone_id='Z23ABC4XYZL05B',
         change_batch={
             'Changes': {
                 'ResourceRecordSet': {
                     'Name': '_x1.certificate-validator.com.',
                     'Type': 'CNAME',
                     'TTL': 300,
                     'ResourceRecords': [{
                         'Value': '_x2.acm-validations.aws.'
                     }]
                 }
             }
         }
     )
     self.mock_response.set_status.assert_called_with(success=True)
 def test_delete(self):
     mock_change_resource_record_sets = \
         patch.object(resources.CertificateValidator,
                      'change_resource_record_sets').start()
     cv = CertificateValidator(self.request, self.mock_response)
     cv.delete()
     mock_change_resource_record_sets.assert_called_with(
         'arn:aws:acm:us-east-1:123:certificate/1', Action.DELETE
     )
 def test_change_resource_record_sets_failed_certificate_arn_is_invalid(
     self
 ):
     cv = CertificateValidator(self.mock_request, self.mock_response)
     cv.change_resource_record_sets('invalid', Action.CREATE)
     self.mock_response.set_status.assert_called_with(success=False)
     self.mock_response.set_reason.assert_called_with(
         reason='Certificate ARN is invalid.'
     )
 def test_update(self):
     mock_change_resource_record_sets = \
         patch.object(resources.CertificateValidator,
                      'change_resource_record_sets').start()
     cv = CertificateValidator(self.request, self.mock_response)
     cv.update()
     mock_change_resource_record_sets.assert_has_calls([
         call('arn:aws:acm:us-east-1:123:certificate/0', Action.DELETE),
         call('arn:aws:acm:us-east-1:123:certificate/1', Action.UPSERT)
     ])
 def test_create(self):
     mock_wait = patch.object(resources.ACM, 'wait').start()
     mock_change_resource_record_sets = \
         patch.object(resources.CertificateValidator,
                      'change_resource_record_sets').start()
     cv = CertificateValidator(self.request, self.mock_response)
     cv.create()
     self.mock_response.set_physical_resource_id.assert_called_with('1337')
     mock_change_resource_record_sets.assert_called_with(
         'arn:aws:acm:us-east-1:123:certificate/1', Action.UPSERT
     )
     mock_wait.assert_called_once_with(
         'arn:aws:acm:us-east-1:123:certificate/1'
     )
 def test_get_hosted_zone_id(self):
     patch.stopall()
     mock_list_hosted_zones_by_name = patch.object(
         resources.Route53, 'list_hosted_zones_by_name'
     ).start()
     mock_list_hosted_zones_by_name.return_value = {
         'HostedZones': [{
             'Id': '/hostedzone/Z23ABC4XYZL05B',
             'Name': 'certificate-validator.com.',
         }]
     }
     cv = CertificateValidator(self.request, self.response)
     actual = cv.get_hosted_zone_id(domain_name='certificate-validator.com')
     expected = 'Z23ABC4XYZL05B'
     self.assertEqual(expected, actual)
 def test_change_resource_record_sets_delete_failed_cert_not_found(self):
     self.mock_request.resource_properties = {
         'CertificateArn': self.certificate_arn
     }
     self.mock_get_domain_validation_options.side_effect = \
         exceptions.ClientError(
             error_response={'Error': {
                 'Code': 'ResourceNotFoundException',
                 'Message': 'Message'
             }},
             operation_name='Operation'
         )
     cv = CertificateValidator(self.mock_request, self.mock_response)
     cv.change_resource_record_sets(self.certificate_arn, Action.DELETE)
     self.mock_response.set_status.assert_called_with(success=True)
     self.mock_response.set_reason.assert_called_with(
         reason='Certificate not found.'
     )
 def test_change_resource_record_sets_delete_failed(self):
     self.mock_request.resource_properties = {
         'CertificateArn': self.certificate_arn
     }
     self.mock_get_domain_validation_options.side_effect = \
         exceptions.ClientError(
             error_response={'Error': {
                 'Code': 'Code',
                 'Message': 'Message'
             }},
             operation_name='Operation'
         )
     cv = CertificateValidator(self.mock_request, self.mock_response)
     cv.change_resource_record_sets(self.certificate_arn, Action.DELETE)
     self.mock_response.set_status.assert_called_with(success=False)
     reason = \
         'An error occurred (Code) when calling the Operation operation: ' \
         'Message'
     self.mock_response.set_reason.assert_called_with(reason=reason)
 def test_change_resource_record_sets_delete_failed_rrset_not_found(self):
     self.mock_request.resource_properties = {
         'CertificateArn': self.certificate_arn
     }
     message = \
         'Tried to delete resource record set ' \
         '[name=\'_x1.certificate-validator.com.\', type=\'CNAME\'] but ' \
         'it was not found'
     self.mock_get_domain_validation_options.side_effect = \
         exceptions.ClientError(
             error_response={'Error': {
                 'Code': 'InvalidChangeBatch',
                 'Message': message
             }},
             operation_name='Operation'
         )
     cv = CertificateValidator(self.mock_request, self.mock_response)
     cv.change_resource_record_sets(self.certificate_arn, Action.DELETE)
     self.mock_response.set_status.assert_called_with(success=True)
     self.mock_response.set_reason.assert_called_with(
         reason='Resource Record Set not found.'
     )
 def test_init(self):
     cv = CertificateValidator(self.request, self.response)
     self.assertEqual(self.request, cv.request)
     self.assertEqual(self.response, cv.response)