def test_handling_delete(self):
        handler = CleanupResourceHandler(route53_client=mock.Mock(), monitor_interval=0)
        record_set_accessor = mock.Mock()
        record_set_accessor.delete = mock.Mock(return_value=True)  # True = Deleted

        exists_count = 0

        def exists_side_effect(*args):
            nonlocal exists_count
            exists_count += 1
            return True if exists_count < 3 else False

        record_set_accessor.exists = mock.Mock(side_effect=exists_side_effect)

        handler.record_set_accessor = record_set_accessor

        event = {
            'RequestType': 'Delete',
            'ResourceProperties': {
                'ServiceToken': 'Something',
                'HostedZoneId': 'ZONE',
                'RecordName': 'something.mydomain.com'
            }
        }

        # WHEN
        handler.handle_event(event, {})

        # THEN
        expected_locator = Route53RecordSetLocator(hosted_zone_id='ZONE', record_name='something.mydomain.com')
        record_set_accessor.delete.assert_called_with(locator=expected_locator)
        record_set_accessor.exists.assert_called()
        self.assertEqual(record_set_accessor.exists.call_count, 3)
Exemplo n.º 2
0
    def test_deleting_records(self):
        # GIVEN
        route53_client = self.get_route53_client_mock()
        locator = Route53RecordSetLocator(hosted_zone_id='foo',
                                          record_name='foo.myexample.com')
        record_set = Route53RecordSetAccessor(route53_client)

        # Set up the mock with a record.
        record_set.update(locator, ipv4s={'1.1.1.1'})

        # WHEN
        record_set.update(locator, ipv4s=set())

        # THEN
        route53_client.change_resource_record_sets.assert_called_with(
            HostedZoneId='foo',
            ChangeBatch={
                'Comment':
                'Automatic',
                'Changes': [{
                    'Action': 'DELETE',
                    'ResourceRecordSet': {
                        'Name': 'foo.myexample.com.',
                        'Type': 'A',
                        'ResourceRecords': [
                            {
                                'Value': '1.1.1.1'
                            },
                        ],
                        'TTL': 60
                    }
                }]
            })
Exemplo n.º 3
0
    def test_update_record_sets(self):
        # GIVEN
        ddb_record = DdbRecord(
            key=DdbRecordKey(cluster_arn='a', service_name='b'))
        ord1 = [
            Route53RecordSetLocator('a', 'b'),
            Route53RecordSetLocator('a', 'c'),
        ]
        ord2 = [
            Route53RecordSetLocator('a', 'b'),
        ]

        # WHEN
        update_ddb_record(ddb_record, RecordUpdate(record_sets_added=ord1))
        update_ddb_record(ddb_record, RecordUpdate(record_sets_removed=ord2))

        # THEN
        self.assertEqual(len(ddb_record.record_sets), 1)
        self.assertTrue(
            Route53RecordSetLocator('a', 'c') in ddb_record.record_sets)
Exemplo n.º 4
0
    def test_creating_empty_records(self):
        # GIVEN
        route53_client = self.get_route53_client_mock()
        locator = Route53RecordSetLocator(hosted_zone_id='foo',
                                          record_name='foo.myexample.com')
        merger = Route53RecordSetAccessor(route53_client)

        # WHEN
        merger.update(locator, ipv4s=set())

        # THEN
        route53_client.change_resource_record_sets.assert_not_called()
Exemplo n.º 5
0
    def test_checks_not_exists(self):
        # GIVEN
        route53_client = self.get_route53_client_mock()
        locator = Route53RecordSetLocator(hosted_zone_id='foo',
                                          record_name='foo.myexample.com')
        record_set = Route53RecordSetAccessor(route53_client)

        # WHEN
        exists = record_set.exists(locator)

        # THEN
        self.assertTrue(not exists)
Exemplo n.º 6
0
    def test_deleting_no_records_with_frontend(self):
        # GIVEN
        route53_client = self.get_route53_client_mock()
        locator = Route53RecordSetLocator(hosted_zone_id='foo',
                                          record_name='foo.myexample.com')
        record_set = Route53RecordSetAccessor(route53_client)

        # WHEN
        record_set.delete(locator)

        # THEN
        self.assertEqual(route53_client.list_resource_record_sets.call_count,
                         1)
        route53_client.change_resource_record_sets.assert_not_called()
Exemplo n.º 7
0
    def on_delete(self, resource_properties: CleanupResourceProperties):
        locator = Route53RecordSetLocator(
            hosted_zone_id=resource_properties.HostedZoneId,
            record_name=resource_properties.RecordName)

        deleted = self.record_set_accessor.delete(locator=locator)

        if deleted:
            logging.info(f'Monitoring for the record deletion')
            for interval_number in range(1, 10):
                if not self.record_set_accessor.exists(locator):
                    logging.info(f'The record has been deleted')
                    return
                else:
                    logging.info(f'The record still exists')
                    if self.monitor_interval > 0:
                        time.sleep(self.monitor_interval)
Exemplo n.º 8
0
    def test_find_locator_record_set_ignores_irrelevant_records(self):
        # GIVEN
        locator = Route53RecordSetLocator(
            hosted_zone_id='foo', record_name='test-record.myexample.com')
        record_sets = [{
            'Name': 'u-record.myexample.com.',
            'Type': 'A',
            'TTL': 60,
            'ResourceRecords': [{
                'Value': '1.1.1.1'
            }]
        }]

        # WHEN
        result = find_locator_record_set(locator, 'A', record_sets)

        # THEN
        self.assertIsNone(result)
Exemplo n.º 9
0
    def test_find_locator_record_set_finds_it(self):
        # GIVEN
        locator = Route53RecordSetLocator(
            hosted_zone_id='foo', record_name='test-record.myexample.com')
        matching_record = {
            'Name': 'test-record.myexample.com.',
            'Type': 'A',
            'TTL': 60,
            'ResourceRecords': [{
                'Value': '1.1.1.1'
            }]
        }
        record_sets = [matching_record]

        # WHEN
        result = find_locator_record_set(locator, 'A', record_sets)

        # THEN
        self.assertEqual(result, matching_record)
Exemplo n.º 10
0
    def __init__(self, ec2_client, route53_client, dynamodb_resource, environ):
        self.ec2_client = ec2_client
        self.route53_client = route53_client

        hosted_zone_id = environ['HOSTED_ZONE_ID']
        record_name = environ['RECORD_NAME']
        records_table = environ['RECORDS_TABLE']

        cluster_arn = environ['CLUSTER_ARN']
        self.service_name = environ['SERVICE_NAME']

        self.records_table_key = DdbRecordKey(cluster_arn=cluster_arn,
                                              service_name=self.service_name)
        self.records_table_accessor = RecordsTableAccessor(
            table_client=dynamodb_resource.Table(records_table))

        self.record_set_locator = Route53RecordSetLocator(
            hosted_zone_id=hosted_zone_id, record_name=record_name)
        self.record_set_accessor = Route53RecordSetAccessor(
            route53_client=self.route53_client)
Exemplo n.º 11
0
    def decode_record_set(self, data) -> Route53RecordSetLocator:
        hosted_zone_id = data[self.ATTR_RECORD_SET_ZONE]
        record_name = data[self.ATTR_RECORD_SET_NAME]

        return Route53RecordSetLocator(hosted_zone_id=hosted_zone_id, record_name=record_name)