class ListRecordSetsTestContext(object):
    def __init__(self):
        self.client = VinylDNSClient(VinylDNSTestContext.vinyldns_url, 'listRecordsAccessKey', 'listRecordsSecretKey')
        self.zone = None
        self.all_records = []
        self.group = None
        get_zone = self.client.get_zone_by_name('list-records.', status=(200, 404))
        if get_zone and 'zone' in get_zone:
            self.zone = get_zone['zone']
            self.all_records = self.client.list_recordsets_by_zone(self.zone['id'])['recordSets']
            my_groups = self.client.list_my_groups(group_name_filter='list-records-group')
            if my_groups and 'groups' in my_groups and len(my_groups['groups']) > 0:
                self.group = my_groups['groups'][0]

    def build(self):
        # Only call this if the context needs to be built
        self.tear_down()
        group = {
            'name': 'list-records-group',
            'email': '*****@*****.**',
            'description': 'this is a description',
            'members': [{'id': 'list-records-user'}],
            'admins': [{'id': 'list-records-user'}]
        }
        self.group = self.client.create_group(group, status=200)
        zone_change = self.client.create_zone(
            {
                'name': 'list-records.',
                'email': '*****@*****.**',
                'shared': False,
                'adminGroupId': self.group['id'],
                'isTest': True,
                'backendId': 'func-test-backend'
            }, status=202)
        self.client.wait_until_zone_active(zone_change[u'zone'][u'id'])
        self.zone = zone_change[u'zone']
        self.all_records = self.client.list_recordsets_by_zone(self.zone['id'])['recordSets']

    def tear_down(self):
        clear_zones(self.client)
        clear_groups(self.client)

    def check_recordsets_page_accuracy(self, list_results_page, size, offset, nextId=False, startFrom=False, maxItems=100, recordTypeFilter=False, nameSort="ASC"):
        # validate fields
        if nextId:
            assert_that(list_results_page, has_key('nextId'))
        else:
            assert_that(list_results_page, is_not(has_key('nextId')))
        if startFrom:
            assert_that(list_results_page['startFrom'], is_(startFrom))
        else:
            assert_that(list_results_page, is_not(has_key('startFrom')))
        if recordTypeFilter:
            assert_that(list_results_page, has_key('recordTypeFilter'))
        else:
            assert_that(list_results_page, is_not(has_key('recordTypeFilter')))
        assert_that(list_results_page['maxItems'], is_(maxItems))
        assert_that(list_results_page['nameSort'], is_(nameSort))

        # validate actual page
        list_results_recordsets_page = list_results_page['recordSets']
        assert_that(list_results_recordsets_page, has_length(size))
        for i in range(len(list_results_recordsets_page)):
            assert_that(list_results_recordsets_page[i]['name'], is_(self.all_records[i+offset]['name']))
            verify_recordset(list_results_recordsets_page[i], self.all_records[i+offset])
            assert_that(list_results_recordsets_page[i]['accessLevel'], is_('Delete'))

    def check_recordsets_parameters(self, list_results_page, nextId=False, startFrom=False, maxItems=100, recordTypeFilter=False, nameSort="ASC"):
        # validate fields
        if nextId:
            assert_that(list_results_page, has_key('nextId'))
        else:
            assert_that(list_results_page, is_not(has_key('nextId')))
        if startFrom:
            assert_that(list_results_page['startFrom'], is_(startFrom))
        else:
            assert_that(list_results_page, is_not(has_key('startFrom')))
        if recordTypeFilter:
            assert_that(list_results_page, has_key('recordTypeFilter'))
        else:
            assert_that(list_results_page, is_not(has_key('recordTypeFilter')))
        assert_that(list_results_page['maxItems'], is_(maxItems))
        assert_that(list_results_page['nameSort'], is_(nameSort))
class ListZonesTestContext(object):
    def __init__(self):
        self.client = VinylDNSClient(VinylDNSTestContext.vinyldns_url,
                                     'listZonesAccessKey',
                                     'listZonesSecretKey')

    def build(self):
        self.tear_down()
        group = {
            'name': 'list-zones-group',
            'email': '*****@*****.**',
            'description': 'this is a description',
            'members': [{
                'id': 'list-zones-user'
            }],
            'admins': [{
                'id': 'list-zones-user'
            }]
        }
        list_zones_group = self.client.create_group(group, status=200)
        search_zone_1_change = self.client.create_zone(
            {
                'name': 'list-zones-test-searched-1.',
                'email': '*****@*****.**',
                'shared': False,
                'adminGroupId': list_zones_group['id'],
                'isTest': True,
                'backendId': 'func-test-backend'
            },
            status=202)

        search_zone_2_change = self.client.create_zone(
            {
                'name': 'list-zones-test-searched-2.',
                'email': '*****@*****.**',
                'shared': False,
                'adminGroupId': list_zones_group['id'],
                'isTest': True,
                'backendId': 'func-test-backend'
            },
            status=202)

        search_zone_3_change = self.client.create_zone(
            {
                'name': 'list-zones-test-searched-3.',
                'email': '*****@*****.**',
                'shared': False,
                'adminGroupId': list_zones_group['id'],
                'isTest': True,
                'backendId': 'func-test-backend'
            },
            status=202)

        non_search_zone_1_change = self.client.create_zone(
            {
                'name': 'list-zones-test-unfiltered-1.',
                'email': '*****@*****.**',
                'shared': False,
                'adminGroupId': list_zones_group['id'],
                'isTest': True,
                'backendId': 'func-test-backend'
            },
            status=202)

        non_search_zone_2_change = self.client.create_zone(
            {
                'name': 'list-zones-test-unfiltered-2.',
                'email': '*****@*****.**',
                'shared': False,
                'adminGroupId': list_zones_group['id'],
                'isTest': True,
                'backendId': 'func-test-backend'
            },
            status=202)

        zone_changes = [
            search_zone_1_change, search_zone_2_change, search_zone_3_change,
            non_search_zone_1_change, non_search_zone_2_change
        ]
        for change in zone_changes:
            self.client.wait_until_zone_active(change[u'zone'][u'id'])

    def tear_down(self):
        clear_zones(self.client)
        clear_groups(self.client)
class SharedZoneTestContext(object):
    """
    Creates multiple zones to test authorization / access to shared zones across users
    """
    def __init__(self):
        self.ok_vinyldns_client = VinylDNSClient(VinylDNSTestContext.vinyldns_url, 'okAccessKey', 'okSecretKey')
        self.dummy_vinyldns_client = VinylDNSClient(VinylDNSTestContext.vinyldns_url, 'dummyAccessKey', 'dummySecretKey')
        self.shared_zone_vinyldns_client = VinylDNSClient(VinylDNSTestContext.vinyldns_url, 'sharedZoneUserAccessKey', 'sharedZoneUserSecretKey')
        self.support_user_client = VinylDNSClient(VinylDNSTestContext.vinyldns_url, 'supportUserAccessKey', 'supportUserSecretKey')
        self.unassociated_client = VinylDNSClient(VinylDNSTestContext.vinyldns_url, 'listGroupAccessKey', 'listGroupSecretKey')
        self.test_user_client = VinylDNSClient(VinylDNSTestContext.vinyldns_url, 'testUserAccessKey', 'testUserSecretKey')

        self.dummy_group = None
        self.ok_group = None
        self.shared_record_group = None

        self.tear_down() # ensures that the environment is clean before starting

        try:
            ok_group = {
                'name': 'ok-group',
                'email': '*****@*****.**',
                'description': 'this is a description',
                'members': [ { 'id': 'ok'}, { 'id': 'support-user-id'} ],
                'admins': [ { 'id': 'ok'} ]
            }

            self.ok_group = self.ok_vinyldns_client.create_group(ok_group, status=200)
            # in theory this shouldn't be needed, but getting 'user is not in group' errors on zone creation
            self.confirm_member_in_group(self.ok_vinyldns_client, self.ok_group)

            dummy_group = {
                'name': 'dummy-group',
                'email': '*****@*****.**',
                'description': 'this is a description',
                'members': [ { 'id': 'dummy'} ],
                'admins': [ { 'id': 'dummy'} ]
            }
            self.dummy_group = self.dummy_vinyldns_client.create_group(dummy_group, status=200)
            # in theory this shouldn't be needed, but getting 'user is not in group' errors on zone creation
            self.confirm_member_in_group(self.dummy_vinyldns_client, self.dummy_group)

            shared_record_group = {
                'name': 'record-ownergroup',
                'email': '*****@*****.**',
                'description': 'this is a description',
                'members': [ { 'id': 'sharedZoneUser'}, { 'id': 'ok'} ],
                'admins': [ { 'id': 'sharedZoneUser'}, { 'id': 'ok'}  ]
            }
            self.shared_record_group = self.ok_vinyldns_client.create_group(shared_record_group, status=200)

            ok_zone_change = self.ok_vinyldns_client.create_zone(
                {
                    'name': 'ok.',
                    'email': '*****@*****.**',
                    'shared': False,
                    'adminGroupId': self.ok_group['id'],
                    'isTest': True,
                    'connection': {
                        'name': 'ok.',
                        'keyName': VinylDNSTestContext.dns_key_name,
                        'key': VinylDNSTestContext.dns_key,
                        'primaryServer': VinylDNSTestContext.dns_ip
                    },
                    'transferConnection': {
                        'name': 'ok.',
                        'keyName': VinylDNSTestContext.dns_key_name,
                        'key': VinylDNSTestContext.dns_key,
                        'primaryServer': VinylDNSTestContext.dns_ip
                    }
                }, status=202)
            self.ok_zone = ok_zone_change['zone']

            dummy_zone_change = self.dummy_vinyldns_client.create_zone(
                {
                    'name': 'dummy.',
                    'email': '*****@*****.**',
                    'shared': False,
                    'adminGroupId': self.dummy_group['id'],
                    'isTest': True,
                    'connection': {
                        'name': 'dummy.',
                        'keyName': VinylDNSTestContext.dns_key_name,
                        'key': VinylDNSTestContext.dns_key,
                        'primaryServer': VinylDNSTestContext.dns_ip
                    },
                    'transferConnection': {
                        'name': 'dummy.',
                        'keyName': VinylDNSTestContext.dns_key_name,
                        'key': VinylDNSTestContext.dns_key,
                        'primaryServer': VinylDNSTestContext.dns_ip
                    }
                }, status=202)
            self.dummy_zone = dummy_zone_change['zone']

            ip6_reverse_zone_change = self.ok_vinyldns_client.create_zone(
                {
                    'name': '1.9.e.f.c.c.7.2.9.6.d.f.ip6.arpa.',
                    'email': '*****@*****.**',
                    'shared': False,
                    'adminGroupId': self.ok_group['id'],
                    'isTest': True,
                    'connection': {
                        'name': 'ip6.',
                        'keyName': VinylDNSTestContext.dns_key_name,
                        'key': VinylDNSTestContext.dns_key,
                        'primaryServer': VinylDNSTestContext.dns_ip
                    },
                    'transferConnection': {
                        'name': 'ip6.',
                        'keyName': VinylDNSTestContext.dns_key_name,
                        'key': VinylDNSTestContext.dns_key,
                        'primaryServer': VinylDNSTestContext.dns_ip
                    }
                }, status=202
            )
            self.ip6_reverse_zone = ip6_reverse_zone_change['zone']

            ip6_16_nibble_zone_change = self.ok_vinyldns_client.create_zone(
                {
                    'name': '0.0.0.1.1.9.e.f.c.c.7.2.9.6.d.f.ip6.arpa.',
                    'email': '*****@*****.**',
                    'shared': False,
                    'adminGroupId': self.ok_group['id'],
                    'isTest': True,
                    'backendId': 'func-test-backend'
                }, status=202
            )
            self.ip6_16_nibble_zone = ip6_16_nibble_zone_change['zone']

            ip4_reverse_zone_change = self.ok_vinyldns_client.create_zone(
                {
                    'name': '10.10.in-addr.arpa.',
                    'email': '*****@*****.**',
                    'shared': False,
                    'adminGroupId': self.ok_group['id'],
                    'isTest': True,
                    'connection': {
                        'name': 'ip4.',
                        'keyName': VinylDNSTestContext.dns_key_name,
                        'key': VinylDNSTestContext.dns_key,
                        'primaryServer': VinylDNSTestContext.dns_ip
                    },
                    'transferConnection': {
                        'name': 'ip4.',
                        'keyName': VinylDNSTestContext.dns_key_name,
                        'key': VinylDNSTestContext.dns_key,
                        'primaryServer': VinylDNSTestContext.dns_ip
                    }
                }, status=202
            )
            self.ip4_reverse_zone = ip4_reverse_zone_change['zone']

            self.classless_base_zone_json = {
                'name': '2.0.192.in-addr.arpa.',
                'email': '*****@*****.**',
                'shared': False,
                'adminGroupId': self.ok_group['id'],
                'isTest': True,
                'connection': {
                    'name': 'classless-base.',
                    'keyName': VinylDNSTestContext.dns_key_name,
                    'key': VinylDNSTestContext.dns_key,
                    'primaryServer': VinylDNSTestContext.dns_ip
                },
                'transferConnection': {
                    'name': 'classless-base.',
                    'keyName': VinylDNSTestContext.dns_key_name,
                    'key': VinylDNSTestContext.dns_key,
                    'primaryServer': VinylDNSTestContext.dns_ip
                }
            }

            classless_base_zone_change = self.ok_vinyldns_client.create_zone(
                self.classless_base_zone_json, status=202
            )
            self.classless_base_zone = classless_base_zone_change['zone']

            classless_zone_delegation_change = self.ok_vinyldns_client.create_zone(
                {
                    'name': '192/30.2.0.192.in-addr.arpa.',
                    'email': '*****@*****.**',
                    'shared': False,
                    'adminGroupId': self.ok_group['id'],
                    'isTest': True,
                    'connection': {
                        'name': 'classless.',
                        'keyName': VinylDNSTestContext.dns_key_name,
                        'key': VinylDNSTestContext.dns_key,
                        'primaryServer': VinylDNSTestContext.dns_ip
                    },
                    'transferConnection': {
                        'name': 'classless.',
                        'keyName': VinylDNSTestContext.dns_key_name,
                        'key': VinylDNSTestContext.dns_key,
                        'primaryServer': VinylDNSTestContext.dns_ip
                    }
                }, status=202
            )
            self.classless_zone_delegation_zone = classless_zone_delegation_change['zone']

            system_test_zone_change = self.ok_vinyldns_client.create_zone(
                {
                    'name': 'system-test.',
                    'email': '*****@*****.**',
                    'shared': False,
                    'adminGroupId': self.ok_group['id'],
                    'isTest': True,
                    'connection': {
                        'name': 'system-test.',
                        'keyName': VinylDNSTestContext.dns_key_name,
                        'key': VinylDNSTestContext.dns_key,
                        'primaryServer': VinylDNSTestContext.dns_ip
                    },
                    'transferConnection': {
                        'name': 'system-test.',
                        'keyName': VinylDNSTestContext.dns_key_name,
                        'key': VinylDNSTestContext.dns_key,
                        'primaryServer': VinylDNSTestContext.dns_ip
                    }
                }, status=202
            )
            self.system_test_zone = system_test_zone_change['zone']

            # parent zone gives access to the dummy user, dummy user cannot manage ns records
            parent_zone_change = self.ok_vinyldns_client.create_zone(
                {
                    'name': 'parent.com.',
                    'email': '*****@*****.**',
                    'shared': False,
                    'adminGroupId': self.ok_group['id'],
                    'isTest': True,
                    'acl': {
                        'rules': [
                            {
                                'accessLevel': 'Delete',
                                'description': 'some_test_rule',
                                'userId': 'dummy'
                            }
                        ]
                    },
                    'connection': {
                        'name': 'parent.',
                        'keyName': VinylDNSTestContext.dns_key_name,
                        'key': VinylDNSTestContext.dns_key,
                        'primaryServer': VinylDNSTestContext.dns_ip
                    },
                    'transferConnection': {
                        'name': 'parent.',
                        'keyName': VinylDNSTestContext.dns_key_name,
                        'key': VinylDNSTestContext.dns_key,
                        'primaryServer': VinylDNSTestContext.dns_ip
                    }
                }, status=202)
            self.parent_zone = parent_zone_change['zone']

            # mimicking the spec example
            ds_zone_change = self.ok_vinyldns_client.create_zone(
                {
                    'name': 'example.com.',
                    'email': '*****@*****.**',
                    'shared': False,
                    'adminGroupId': self.ok_group['id'],
                    'isTest': True,
                    'connection': {
                        'name': 'example.',
                        'keyName': VinylDNSTestContext.dns_key_name,
                        'key': VinylDNSTestContext.dns_key,
                        'primaryServer': VinylDNSTestContext.dns_ip
                    },
                    'transferConnection': {
                        'name': 'example.',
                        'keyName': VinylDNSTestContext.dns_key_name,
                        'key': VinylDNSTestContext.dns_key,
                        'primaryServer': VinylDNSTestContext.dns_ip
                    }
                }, status=202)
            self.ds_zone = ds_zone_change['zone']

            # zone with name configured for manual review
            requires_review_zone_change = self.ok_vinyldns_client.create_zone(
                {
                    'name': 'zone.requires.review.',
                    'email': '*****@*****.**',
                    'shared': False,
                    'adminGroupId': self.ok_group['id'],
                    'isTest': True,
                    'backendId': 'func-test-backend'
                }, status=202)
            self.requires_review_zone = requires_review_zone_change['zone']

            get_shared_zones = self.shared_zone_vinyldns_client.list_zones(status=200)['zones']
            shared_zone = [zone for zone in get_shared_zones if zone['name'] == "shared."]
            non_test_shared_zone = [zone for zone in get_shared_zones if zone['name'] == "non.test.shared."]

            shared_zone_change = self.set_up_shared_zone(shared_zone[0]['id'])
            self.shared_zone = shared_zone_change['zone']

            non_test_shared_zone_change = self.set_up_shared_zone(non_test_shared_zone[0]['id'])
            self.non_test_shared_zone = non_test_shared_zone_change['zone']

            # wait until our zones are created
            self.ok_vinyldns_client.wait_until_zone_active(system_test_zone_change[u'zone'][u'id'])
            self.ok_vinyldns_client.wait_until_zone_active(ok_zone_change[u'zone'][u'id'])
            self.dummy_vinyldns_client.wait_until_zone_active(dummy_zone_change[u'zone'][u'id'])
            self.ok_vinyldns_client.wait_until_zone_active(ip6_reverse_zone_change[u'zone'][u'id'])
            self.ok_vinyldns_client.wait_until_zone_active(ip6_16_nibble_zone_change[u'zone'][u'id'])
            self.ok_vinyldns_client.wait_until_zone_active(ip4_reverse_zone_change[u'zone'][u'id'])
            self.ok_vinyldns_client.wait_until_zone_active(classless_base_zone_change[u'zone'][u'id'])
            self.ok_vinyldns_client.wait_until_zone_active(classless_zone_delegation_change[u'zone'][u'id'])
            self.ok_vinyldns_client.wait_until_zone_active(system_test_zone_change[u'zone'][u'id'])
            self.ok_vinyldns_client.wait_until_zone_active(parent_zone_change[u'zone'][u'id'])
            self.ok_vinyldns_client.wait_until_zone_active(ds_zone_change[u'zone'][u'id'])
            self.ok_vinyldns_client.wait_until_zone_active(requires_review_zone_change[u'zone'][u'id'])
            self.shared_zone_vinyldns_client.wait_until_zone_change_status_synced(shared_zone_change)
            shared_sync_change = self.shared_zone_vinyldns_client.sync_zone(self.shared_zone['id'])
            self.shared_zone_vinyldns_client.wait_until_zone_change_status_synced(non_test_shared_zone_change)
            non_test_shared_sync_change = self.shared_zone_vinyldns_client.sync_zone(self.non_test_shared_zone['id'])
            self.shared_zone_vinyldns_client.wait_until_zone_change_status_synced(shared_sync_change)
            self.shared_zone_vinyldns_client.wait_until_zone_change_status_synced(non_test_shared_sync_change)

            # validate all in there
            zones = self.dummy_vinyldns_client.list_zones()['zones']
            assert_that(len(zones), is_(2))
            zones = self.ok_vinyldns_client.list_zones()['zones']
            assert_that(len(zones), is_(10))
            zones = self.shared_zone_vinyldns_client.list_zones()['zones']
            assert_that(len(zones), is_(2))

        except:
            # teardown if there was any issue in setup
            try:
                self.tear_down()
            except:
                pass
            raise

    def set_up_shared_zone(self, zone_id):
        # shared zones are created through test data loader, but needs connection info added here to use
        get_shared_zone = self.shared_zone_vinyldns_client.get_zone(zone_id)
        shared_zone = get_shared_zone['zone']

        connection_info = {
            'name': 'shared.',
            'keyName': VinylDNSTestContext.dns_key_name,
            'key': VinylDNSTestContext.dns_key,
            'primaryServer': VinylDNSTestContext.dns_ip
        }

        shared_zone['connection'] = connection_info
        shared_zone['transferConnection'] = connection_info

        return self.shared_zone_vinyldns_client.update_zone(shared_zone, status=202)

    def tear_down(self):
        """
        The ok_vinyldns_client is a zone admin on _all_ the zones.

        We shouldn't have to do any checks now, as zone admins have full rights to all zones, including
        deleting all records (even in the old shared model)
        """
        clear_zones(self.dummy_vinyldns_client)
        clear_zones(self.ok_vinyldns_client)
        clear_groups(self.dummy_vinyldns_client, "global-acl-group-id")
        clear_groups(self.ok_vinyldns_client, "global-acl-group-id")

    def confirm_member_in_group(self, client, group):
        retries = 2
        success = group in client.list_all_my_groups(status=200)
        while retries >= 0 and not success:
            success = group in client.list_all_my_groups(status=200)
            time.sleep(.05)
            retries -= 1
        assert_that(success, is_(True))
Beispiel #4
0
class ListZonesTestContext(object):
    def __init__(self, partition_id):
        self.partition_id = partition_id
        self.setup_started = False
        self.client = VinylDNSClient(VinylDNSTestContext.vinyldns_url,
                                     "listZonesAccessKey",
                                     "listZonesSecretKey")
        self.search_zone1 = None
        self.search_zone2 = None
        self.search_zone3 = None
        self.non_search_zone1 = None
        self.non_search_zone2 = None
        self.list_zones_group = None

    def setup(self):
        if self.setup_started:
            # Safeguard against reentrance
            return
        self.setup_started = True

        partition_id = self.partition_id
        group = {
            "name": f"list-zones-group{partition_id}",
            "email": "*****@*****.**",
            "description": "this is a description",
            "members": [{
                "id": "list-zones-user"
            }],
            "admins": [{
                "id": "list-zones-user"
            }]
        }
        self.list_zones_group = self.client.create_group(group, status=200)

        search_zone_1_change = self.client.create_zone(
            {
                "name": f"list-zones-test-searched-1{partition_id}.",
                "email": "*****@*****.**",
                "shared": False,
                "adminGroupId": self.list_zones_group["id"],
                "isTest": True,
                "backendId": "func-test-backend"
            },
            status=202)
        self.search_zone1 = search_zone_1_change["zone"]

        search_zone_2_change = self.client.create_zone(
            {
                "name": f"list-zones-test-searched-2{partition_id}.",
                "email": "*****@*****.**",
                "shared": False,
                "adminGroupId": self.list_zones_group["id"],
                "isTest": True,
                "backendId": "func-test-backend"
            },
            status=202)
        self.search_zone2 = search_zone_2_change["zone"]

        search_zone_3_change = self.client.create_zone(
            {
                "name": f"list-zones-test-searched-3{partition_id}.",
                "email": "*****@*****.**",
                "shared": False,
                "adminGroupId": self.list_zones_group["id"],
                "isTest": True,
                "backendId": "func-test-backend"
            },
            status=202)
        self.search_zone3 = search_zone_3_change["zone"]

        non_search_zone_1_change = self.client.create_zone(
            {
                "name": f"list-zones-test-unfiltered-1{partition_id}.",
                "email": "*****@*****.**",
                "shared": False,
                "adminGroupId": self.list_zones_group["id"],
                "isTest": True,
                "backendId": "func-test-backend"
            },
            status=202)
        self.non_search_zone1 = non_search_zone_1_change["zone"]

        non_search_zone_2_change = self.client.create_zone(
            {
                "name": f"list-zones-test-unfiltered-2{partition_id}.",
                "email": "*****@*****.**",
                "shared": False,
                "adminGroupId": self.list_zones_group["id"],
                "isTest": True,
                "backendId": "func-test-backend"
            },
            status=202)
        self.non_search_zone2 = non_search_zone_2_change["zone"]

        zone_changes = [
            search_zone_1_change, search_zone_2_change, search_zone_3_change,
            non_search_zone_1_change, non_search_zone_2_change
        ]
        for change in zone_changes:
            self.client.wait_until_zone_active(change["zone"]["id"])

    def tear_down(self):
        self.client.clear_zones()
        self.client.clear_groups()
        self.client.tear_down()
Beispiel #5
0
class SharedZoneTestContext(object):
    """
    Creates multiple zones to test authorization / access to shared zones across users
    """
    _data_cache: MutableMapping[str, MutableMapping[str, Mapping]] = {}

    def __init__(self, partition_id: str):
        self.partition_id = partition_id
        self.setup_started = False
        self.ok_vinyldns_client = VinylDNSClient(
            VinylDNSTestContext.vinyldns_url, "okAccessKey", "okSecretKey")
        self.dummy_vinyldns_client = VinylDNSClient(
            VinylDNSTestContext.vinyldns_url, "dummyAccessKey",
            "dummySecretKey")
        self.shared_zone_vinyldns_client = VinylDNSClient(
            VinylDNSTestContext.vinyldns_url, "sharedZoneUserAccessKey",
            "sharedZoneUserSecretKey")
        self.support_user_client = VinylDNSClient(
            VinylDNSTestContext.vinyldns_url, "supportUserAccessKey",
            "supportUserSecretKey")
        self.unassociated_client = VinylDNSClient(
            VinylDNSTestContext.vinyldns_url, "listGroupAccessKey",
            "listGroupSecretKey")
        self.test_user_client = VinylDNSClient(
            VinylDNSTestContext.vinyldns_url, "testUserAccessKey",
            "testUserSecretKey")
        self.history_client = VinylDNSClient(VinylDNSTestContext.vinyldns_url,
                                             "history-key", "history-secret")
        self.clients = [
            self.ok_vinyldns_client, self.dummy_vinyldns_client,
            self.shared_zone_vinyldns_client, self.support_user_client,
            self.unassociated_client, self.test_user_client,
            self.history_client
        ]
        self.list_zones = ListZonesTestContext(partition_id)
        self.list_zones_client = self.list_zones.client
        self.list_records_context = ListRecordSetsTestContext(partition_id)
        self.list_groups_context = ListGroupsTestContext(partition_id)
        self.list_batch_summaries_context = ListBatchChangeSummariesTestContext(
            partition_id)

        self.dummy_group = None
        self.ok_group = None
        self.shared_record_group = None
        self.history_group = None
        self.group_activity_created = None
        self.group_activity_updated = None

        self.history_zone = None
        self.ok_zone = None
        self.dummy_zone = None
        self.ip6_reverse_zone = None
        self.ip6_16_nibble_zone = None
        self.ip4_reverse_zone = None
        self.classless_base_zone = None
        self.classless_zone_delegation_zone = None
        self.system_test_zone = None
        self.parent_zone = None
        self.ds_zone = None
        self.requires_review_zone = None
        self.shared_zone = None

        self.ip4_10_prefix = None
        self.ip4_classless_prefix = None
        self.ip6_prefix = None

    def setup(self):
        if self.setup_started:
            # Safeguard against reentrance
            return
        self.setup_started = True

        partition_id = self.partition_id
        try:
            ok_group = {
                "name": f"ok-group{partition_id}",
                "email": "*****@*****.**",
                "description": "this is a description",
                "members": [{
                    "id": "ok"
                }, {
                    "id": "support-user-id"
                }],
                "admins": [{
                    "id": "ok"
                }]
            }

            self.ok_group = self.ok_vinyldns_client.create_group(ok_group,
                                                                 status=200)
            # in theory this shouldn"t be needed, but getting "user is not in group' errors on zone creation
            self.confirm_member_in_group(self.ok_vinyldns_client,
                                         self.ok_group)

            dummy_group = {
                "name": f"dummy-group{partition_id}",
                "email": "*****@*****.**",
                "description": "this is a description",
                "members": [{
                    "id": "dummy"
                }],
                "admins": [{
                    "id": "dummy"
                }]
            }
            self.dummy_group = self.dummy_vinyldns_client.create_group(
                dummy_group, status=200)
            # in theory this shouldn"t be needed, but getting "user is not in group' errors on zone creation
            self.confirm_member_in_group(self.dummy_vinyldns_client,
                                         self.dummy_group)

            shared_record_group = {
                "name":
                f"record-ownergroup{partition_id}",
                "email":
                "*****@*****.**",
                "description":
                "this is a description",
                "members": [{
                    "id": "sharedZoneUser"
                }, {
                    "id": "ok"
                }, {
                    "id": "support-user-id"
                }],
                "admins": [{
                    "id": "sharedZoneUser"
                }, {
                    "id": "ok"
                }]
            }
            self.shared_record_group = self.ok_vinyldns_client.create_group(
                shared_record_group, status=200)

            history_group = {
                "name": f"history-group{partition_id}",
                "email": "*****@*****.**",
                "description": "this is a description",
                "members": [{
                    "id": "history-id"
                }],
                "admins": [{
                    "id": "history-id"
                }]
            }
            self.history_group = self.history_client.create_group(
                history_group, status=200)
            self.confirm_member_in_group(self.history_client,
                                         self.history_group)

            history_zone_change = self.history_client.create_zone(
                {
                    "name": f"system-test-history{partition_id}.",
                    "email": "*****@*****.**",
                    "shared": False,
                    "adminGroupId": self.history_group["id"],
                    "isTest": True,
                    "connection": {
                        "name": "vinyldns.",
                        "keyName": VinylDNSTestContext.dns_key_name,
                        "key": VinylDNSTestContext.dns_key,
                        "algorithm": VinylDNSTestContext.dns_key_algo,
                        "primaryServer": VinylDNSTestContext.name_server_ip
                    },
                    "transferConnection": {
                        "name": "vinyldns.",
                        "keyName": VinylDNSTestContext.dns_key_name,
                        "key": VinylDNSTestContext.dns_key,
                        "algorithm": VinylDNSTestContext.dns_key_algo,
                        "primaryServer": VinylDNSTestContext.name_server_ip
                    }
                },
                status=202)
            self.history_zone = history_zone_change["zone"]

            # initialize history
            self.history_client.wait_until_zone_active(
                history_zone_change["zone"]["id"])
            self.init_history()

            ok_zone_change = self.ok_vinyldns_client.create_zone(
                {
                    "name": f"ok{partition_id}.",
                    "email": "*****@*****.**",
                    "shared": False,
                    "adminGroupId": self.ok_group["id"],
                    "isTest": True,
                    "connection": {
                        "name": "ok.",
                        "keyName": VinylDNSTestContext.dns_key_name,
                        "key": VinylDNSTestContext.dns_key,
                        "algorithm": VinylDNSTestContext.dns_key_algo,
                        "primaryServer": VinylDNSTestContext.name_server_ip
                    },
                    "transferConnection": {
                        "name": "ok.",
                        "keyName": VinylDNSTestContext.dns_key_name,
                        "key": VinylDNSTestContext.dns_key,
                        "algorithm": VinylDNSTestContext.dns_key_algo,
                        "primaryServer": VinylDNSTestContext.name_server_ip
                    }
                },
                status=202)
            self.ok_zone = ok_zone_change["zone"]

            dummy_zone_change = self.dummy_vinyldns_client.create_zone(
                {
                    "name": f"dummy{partition_id}.",
                    "email": "*****@*****.**",
                    "shared": False,
                    "adminGroupId": self.dummy_group["id"],
                    "isTest": True,
                    "connection": {
                        "name": "dummy.",
                        "keyName": VinylDNSTestContext.dns_key_name,
                        "key": VinylDNSTestContext.dns_key,
                        "algorithm": VinylDNSTestContext.dns_key_algo,
                        "primaryServer": VinylDNSTestContext.name_server_ip
                    },
                    "transferConnection": {
                        "name": "dummy.",
                        "keyName": VinylDNSTestContext.dns_key_name,
                        "key": VinylDNSTestContext.dns_key,
                        "algorithm": VinylDNSTestContext.dns_key_algo,
                        "primaryServer": VinylDNSTestContext.name_server_ip
                    }
                },
                status=202)
            self.dummy_zone = dummy_zone_change["zone"]

            self.ip6_prefix = f"fd69:27cc:fe9{partition_id}"
            ip6_reverse_zone_change = self.ok_vinyldns_client.create_zone(
                {
                    "name": f"{partition_id}.9.e.f.c.c.7.2.9.6.d.f.ip6.arpa.",
                    "email": "*****@*****.**",
                    "shared": False,
                    "adminGroupId": self.ok_group["id"],
                    "isTest": True,
                    "connection": {
                        "name": "ip6.",
                        "keyName": VinylDNSTestContext.dns_key_name,
                        "key": VinylDNSTestContext.dns_key,
                        "algorithm": VinylDNSTestContext.dns_key_algo,
                        "primaryServer": VinylDNSTestContext.name_server_ip
                    },
                    "transferConnection": {
                        "name": "ip6.",
                        "keyName": VinylDNSTestContext.dns_key_name,
                        "key": VinylDNSTestContext.dns_key,
                        "algorithm": VinylDNSTestContext.dns_key_algo,
                        "primaryServer": VinylDNSTestContext.name_server_ip
                    }
                },
                status=202)
            self.ip6_reverse_zone = ip6_reverse_zone_change["zone"]

            ip6_16_nibble_zone_change = self.ok_vinyldns_client.create_zone(
                {
                    "name":
                    f"0.0.0.1.{partition_id}.9.e.f.c.c.7.2.9.6.d.f.ip6.arpa.",
                    "email": "*****@*****.**",
                    "shared": False,
                    "adminGroupId": self.ok_group["id"],
                    "isTest": True,
                    "backendId": "func-test-backend"
                },
                status=202)
            self.ip6_16_nibble_zone = ip6_16_nibble_zone_change["zone"]

            self.ip4_10_prefix = f"10.{partition_id}"
            ip4_reverse_zone_change = self.ok_vinyldns_client.create_zone(
                {
                    "name": f"{partition_id}.10.in-addr.arpa.",
                    "email": "*****@*****.**",
                    "shared": False,
                    "adminGroupId": self.ok_group["id"],
                    "isTest": True,
                    "connection": {
                        "name": "ip4.",
                        "keyName": VinylDNSTestContext.dns_key_name,
                        "key": VinylDNSTestContext.dns_key,
                        "algorithm": VinylDNSTestContext.dns_key_algo,
                        "primaryServer": VinylDNSTestContext.name_server_ip
                    },
                    "transferConnection": {
                        "name": "ip4.",
                        "keyName": VinylDNSTestContext.dns_key_name,
                        "key": VinylDNSTestContext.dns_key,
                        "algorithm": VinylDNSTestContext.dns_key_algo,
                        "primaryServer": VinylDNSTestContext.name_server_ip
                    }
                },
                status=202)
            self.ip4_reverse_zone = ip4_reverse_zone_change["zone"]

            self.ip4_classless_prefix = f"192.0.{partition_id}"
            classless_base_zone_change = self.ok_vinyldns_client.create_zone(
                {
                    "name": f"{partition_id}.0.192.in-addr.arpa.",
                    "email": "*****@*****.**",
                    "shared": False,
                    "adminGroupId": self.ok_group["id"],
                    "isTest": True,
                    "connection": {
                        "name": "classless-base.",
                        "keyName": VinylDNSTestContext.dns_key_name,
                        "key": VinylDNSTestContext.dns_key,
                        "algorithm": VinylDNSTestContext.dns_key_algo,
                        "primaryServer": VinylDNSTestContext.name_server_ip
                    },
                    "transferConnection": {
                        "name": "classless-base.",
                        "keyName": VinylDNSTestContext.dns_key_name,
                        "key": VinylDNSTestContext.dns_key,
                        "algorithm": VinylDNSTestContext.dns_key_algo,
                        "primaryServer": VinylDNSTestContext.name_server_ip
                    }
                },
                status=202)
            self.classless_base_zone = classless_base_zone_change["zone"]

            classless_zone_delegation_change = self.ok_vinyldns_client.create_zone(
                {
                    "name": f"192/30.{partition_id}.0.192.in-addr.arpa.",
                    "email": "*****@*****.**",
                    "shared": False,
                    "adminGroupId": self.ok_group["id"],
                    "isTest": True,
                    "connection": {
                        "name": "classless.",
                        "keyName": VinylDNSTestContext.dns_key_name,
                        "key": VinylDNSTestContext.dns_key,
                        "algorithm": VinylDNSTestContext.dns_key_algo,
                        "primaryServer": VinylDNSTestContext.name_server_ip
                    },
                    "transferConnection": {
                        "name": "classless.",
                        "keyName": VinylDNSTestContext.dns_key_name,
                        "key": VinylDNSTestContext.dns_key,
                        "algorithm": VinylDNSTestContext.dns_key_algo,
                        "primaryServer": VinylDNSTestContext.name_server_ip
                    }
                },
                status=202)
            self.classless_zone_delegation_zone = classless_zone_delegation_change[
                "zone"]

            system_test_zone_change = self.ok_vinyldns_client.create_zone(
                {
                    "name": f"system-test{partition_id}.",
                    "email": "*****@*****.**",
                    "shared": False,
                    "adminGroupId": self.ok_group["id"],
                    "isTest": True,
                    "connection": {
                        "name": "system-test.",
                        "keyName": VinylDNSTestContext.dns_key_name,
                        "key": VinylDNSTestContext.dns_key,
                        "algorithm": VinylDNSTestContext.dns_key_algo,
                        "primaryServer": VinylDNSTestContext.name_server_ip
                    },
                    "transferConnection": {
                        "name": "system-test.",
                        "keyName": VinylDNSTestContext.dns_key_name,
                        "key": VinylDNSTestContext.dns_key,
                        "algorithm": VinylDNSTestContext.dns_key_algo,
                        "primaryServer": VinylDNSTestContext.name_server_ip
                    }
                },
                status=202)
            self.system_test_zone = system_test_zone_change["zone"]

            # parent zone gives access to the dummy user, dummy user cannot manage ns records
            parent_zone_change = self.ok_vinyldns_client.create_zone(
                {
                    "name": f"parent.com{partition_id}.",
                    "email": "*****@*****.**",
                    "shared": False,
                    "adminGroupId": self.ok_group["id"],
                    "isTest": True,
                    "acl": {
                        "rules": [{
                            "accessLevel": "Delete",
                            "description": "some_test_rule",
                            "userId": "dummy"
                        }]
                    },
                    "connection": {
                        "name": "parent.",
                        "keyName": VinylDNSTestContext.dns_key_name,
                        "key": VinylDNSTestContext.dns_key,
                        "algorithm": VinylDNSTestContext.dns_key_algo,
                        "primaryServer": VinylDNSTestContext.name_server_ip
                    },
                    "transferConnection": {
                        "name": "parent.",
                        "keyName": VinylDNSTestContext.dns_key_name,
                        "key": VinylDNSTestContext.dns_key,
                        "algorithm": VinylDNSTestContext.dns_key_algo,
                        "primaryServer": VinylDNSTestContext.name_server_ip
                    }
                },
                status=202)
            self.parent_zone = parent_zone_change["zone"]

            # mimicking the spec example
            ds_zone_change = self.ok_vinyldns_client.create_zone(
                {
                    "name": f"example.com{partition_id}.",
                    "email": "*****@*****.**",
                    "shared": False,
                    "adminGroupId": self.ok_group["id"],
                    "isTest": True,
                    "connection": {
                        "name": "example.",
                        "keyName": VinylDNSTestContext.dns_key_name,
                        "key": VinylDNSTestContext.dns_key,
                        "algorithm": VinylDNSTestContext.dns_key_algo,
                        "primaryServer": VinylDNSTestContext.name_server_ip
                    },
                    "transferConnection": {
                        "name": "example.",
                        "keyName": VinylDNSTestContext.dns_key_name,
                        "key": VinylDNSTestContext.dns_key,
                        "algorithm": VinylDNSTestContext.dns_key_algo,
                        "primaryServer": VinylDNSTestContext.name_server_ip
                    }
                },
                status=202)
            self.ds_zone = ds_zone_change["zone"]

            # zone with name configured for manual review
            requires_review_zone_change = self.ok_vinyldns_client.create_zone(
                {
                    "name": f"zone.requires.review{partition_id}.",
                    "email": "*****@*****.**",
                    "shared": False,
                    "adminGroupId": self.ok_group["id"],
                    "isTest": True,
                    "backendId": "func-test-backend"
                },
                status=202)
            self.requires_review_zone = requires_review_zone_change["zone"]

            # Shared zone
            shared_zone_change = self.support_user_client.create_zone(
                {
                    "name": f"shared{partition_id}.",
                    "email": "*****@*****.**",
                    "shared": True,
                    "adminGroupId": self.shared_record_group["id"],
                    "isTest": True,
                    "connection": {
                        "name": "shared.",
                        "keyName": VinylDNSTestContext.dns_key_name,
                        "key": VinylDNSTestContext.dns_key,
                        "algorithm": VinylDNSTestContext.dns_key_algo,
                        "primaryServer": VinylDNSTestContext.name_server_ip
                    },
                    "transferConnection": {
                        "name": "shared.",
                        "keyName": VinylDNSTestContext.dns_key_name,
                        "key": VinylDNSTestContext.dns_key,
                        "algorithm": VinylDNSTestContext.dns_key_algo,
                        "primaryServer": VinylDNSTestContext.name_server_ip
                    }
                },
                status=202)
            self.shared_zone = shared_zone_change["zone"]

            # wait until our zones are created
            self.ok_vinyldns_client.wait_until_zone_active(
                system_test_zone_change["zone"]["id"])
            self.ok_vinyldns_client.wait_until_zone_active(
                ok_zone_change["zone"]["id"])
            self.dummy_vinyldns_client.wait_until_zone_active(
                dummy_zone_change["zone"]["id"])
            self.ok_vinyldns_client.wait_until_zone_active(
                ip6_reverse_zone_change["zone"]["id"])
            self.ok_vinyldns_client.wait_until_zone_active(
                ip6_16_nibble_zone_change["zone"]["id"])
            self.ok_vinyldns_client.wait_until_zone_active(
                ip4_reverse_zone_change["zone"]["id"])
            self.ok_vinyldns_client.wait_until_zone_active(
                classless_base_zone_change["zone"]["id"])
            self.ok_vinyldns_client.wait_until_zone_active(
                classless_zone_delegation_change["zone"]["id"])
            self.ok_vinyldns_client.wait_until_zone_active(
                system_test_zone_change["zone"]["id"])
            self.ok_vinyldns_client.wait_until_zone_active(
                parent_zone_change["zone"]["id"])
            self.ok_vinyldns_client.wait_until_zone_active(
                ds_zone_change["zone"]["id"])
            self.ok_vinyldns_client.wait_until_zone_active(
                requires_review_zone_change["zone"]["id"])
            self.shared_zone_vinyldns_client.wait_until_zone_active(
                shared_zone_change["zone"]["id"])

            # initialize group activity
            self.init_group_activity()

            # initialize list zones, only do this when constructing the whole!
            self.list_zones.setup()

            # note: there are no state to load, the tests only need the client
            self.list_zones_client = self.list_zones.client

            # build the list of records; note: we do need to save the test records
            self.list_records_context.setup()

            # build the list of groups
            self.list_groups_context.setup()
        except Exception:
            # Cleanup if setup fails
            self.tear_down()
            traceback.print_exc()
            raise

    def init_history(self):
        # Initialize the zone history
        # change the zone nine times to we have update events in zone change history,
        # ten total changes including creation
        for i in range(2, 11):
            zone_update = copy.deepcopy(self.history_zone)
            zone_update["connection"]["key"] = VinylDNSTestContext.dns_key
            zone_update["transferConnection"][
                "key"] = VinylDNSTestContext.dns_key
            zone_update[
                "email"] = "i.changed.this.{0}[email protected]".format(
                    i)
            self.history_client.update_zone(zone_update, status=202)

        # create some record sets
        test_a = TestData.A.copy()
        test_a["zoneId"] = self.history_zone["id"]
        test_aaaa = TestData.AAAA.copy()
        test_aaaa["zoneId"] = self.history_zone["id"]
        test_cname = TestData.CNAME.copy()
        test_cname["zoneId"] = self.history_zone["id"]

        a_record = self.history_client.create_recordset(
            test_a, status=202)["recordSet"]
        aaaa_record = self.history_client.create_recordset(
            test_aaaa, status=202)["recordSet"]
        cname_record = self.history_client.create_recordset(
            test_cname, status=202)["recordSet"]

        # wait here for all the record sets to be created
        self.history_client.wait_until_recordset_exists(
            a_record["zoneId"], a_record["id"])
        self.history_client.wait_until_recordset_exists(
            aaaa_record["zoneId"], aaaa_record["id"])
        self.history_client.wait_until_recordset_exists(
            cname_record["zoneId"], cname_record["id"])

        # update the record sets
        a_record_update = copy.deepcopy(a_record)
        a_record_update["ttl"] += 100
        a_record_update["records"][0]["address"] = "9.9.9.9"
        a_change = self.history_client.update_recordset(a_record_update,
                                                        status=202)

        aaaa_record_update = copy.deepcopy(aaaa_record)
        aaaa_record_update["ttl"] += 100
        aaaa_record_update["records"][0]["address"] = "2003:db8:0:0:0:0:0:4"
        aaaa_change = self.history_client.update_recordset(aaaa_record_update,
                                                           status=202)

        cname_record_update = copy.deepcopy(cname_record)
        cname_record_update["ttl"] += 100
        cname_record_update["records"][0]["cname"] = "changed-cname."
        cname_change = self.history_client.update_recordset(
            cname_record_update, status=202)

        self.history_client.wait_until_recordset_change_status(
            a_change, "Complete")
        self.history_client.wait_until_recordset_change_status(
            aaaa_change, "Complete")
        self.history_client.wait_until_recordset_change_status(
            cname_change, "Complete")

        # delete the recordsets
        self.history_client.delete_recordset(a_record["zoneId"],
                                             a_record["id"])
        self.history_client.delete_recordset(aaaa_record["zoneId"],
                                             aaaa_record["id"])
        self.history_client.delete_recordset(cname_record["zoneId"],
                                             cname_record["id"])

        self.history_client.wait_until_recordset_deleted(
            a_record["zoneId"], a_record["id"])
        self.history_client.wait_until_recordset_deleted(
            aaaa_record["zoneId"], aaaa_record["id"])
        self.history_client.wait_until_recordset_deleted(
            cname_record["zoneId"], cname_record["id"])

    def init_group_activity(self):
        client = self.ok_vinyldns_client

        group_name = f"test-list-group-activity-max-item-success{self.partition_id}"

        members = [{"id": "ok"}]
        new_group = {
            "name": group_name,
            "email": "*****@*****.**",
            "members": members,
            "admins": [{
                "id": "ok"
            }]
        }
        created_group = client.create_group(new_group, status=200)

        update_groups = []
        updated_groups = []
        # each update changes the member
        for runner in range(0, 10):
            members = [{"id": "dummy{0:0>3}".format(runner)}]
            update_groups.append({
                "id": created_group["id"],
                "name": group_name,
                "email": "*****@*****.**",
                "members": members,
                "admins": [{
                    "id": "ok"
                }]
            })
            updated_groups.append(
                client.update_group(update_groups[runner]["id"],
                                    update_groups[runner],
                                    status=200))

        self.group_activity_created = created_group
        self.group_activity_updated = updated_groups

    def tear_down(self):
        """
        The ok_vinyldns_client is a zone admin on _all_ the zones.

        We shouldn't have to do any checks now, as zone admins have full rights to all zones, including
        deleting all records (even in the old shared model)
        """
        try:
            self.list_zones.tear_down()
            self.list_records_context.tear_down()

            if self.list_batch_summaries_context:
                self.list_batch_summaries_context.tear_down(self)

            if self.list_groups_context:
                self.list_groups_context.tear_down()

            for client in self.clients:
                client.clear_zones()

            for client in self.clients:
                client.clear_groups()

            # Close all clients
            for client in self.clients:
                client.tear_down()

        except Exception:
            traceback.print_exc()
            raise

    @staticmethod
    def confirm_member_in_group(client, group):
        retries = 2
        success = group in client.list_all_my_groups(status=200)
        while retries >= 0 and not success:
            success = group in client.list_all_my_groups(status=200)
            time.sleep(.05)
            retries -= 1
        assert_that(success, is_(True))
Beispiel #6
0
class ListZonesTestContext(object):
    def __init__(self):
        self.client = VinylDNSClient(VinylDNSTestContext.vinyldns_url,
                                     'listZonesAccessKey',
                                     'listZonesSecretKey')
        self.tear_down(
        )  # ensures that the environment is clean before starting

        try:
            group = {
                'name': 'list-zones-group',
                'email': '*****@*****.**',
                'description': 'this is a description',
                'members': [{
                    'id': 'list-zones-user'
                }],
                'admins': [{
                    'id': 'list-zones-user'
                }]
            }

            self.list_zones_group = self.client.create_group(group, status=200)

            search_zone_1_change = self.client.create_zone(
                {
                    'name': 'list-zones-test-searched-1.',
                    'email': '*****@*****.**',
                    'shared': False,
                    'adminGroupId': self.list_zones_group['id'],
                    'isTest': True,
                    'backendId': 'func-test-backend'
                },
                status=202)
            self.search_zone_1 = search_zone_1_change['zone']

            search_zone_2_change = self.client.create_zone(
                {
                    'name': 'list-zones-test-searched-2.',
                    'email': '*****@*****.**',
                    'shared': False,
                    'adminGroupId': self.list_zones_group['id'],
                    'isTest': True,
                    'backendId': 'func-test-backend'
                },
                status=202)
            self.search_zone_2 = search_zone_2_change['zone']

            search_zone_3_change = self.client.create_zone(
                {
                    'name': 'list-zones-test-searched-3.',
                    'email': '*****@*****.**',
                    'shared': False,
                    'adminGroupId': self.list_zones_group['id'],
                    'isTest': True,
                    'backendId': 'func-test-backend'
                },
                status=202)
            self.search_zone_3 = search_zone_3_change['zone']

            non_search_zone_1_change = self.client.create_zone(
                {
                    'name': 'list-zones-test-unfiltered-1.',
                    'email': '*****@*****.**',
                    'shared': False,
                    'adminGroupId': self.list_zones_group['id'],
                    'isTest': True,
                    'backendId': 'func-test-backend'
                },
                status=202)
            self.non_search_zone_1 = non_search_zone_1_change['zone']

            non_search_zone_2_change = self.client.create_zone(
                {
                    'name': 'list-zones-test-unfiltered-2.',
                    'email': '*****@*****.**',
                    'shared': False,
                    'adminGroupId': self.list_zones_group['id'],
                    'isTest': True,
                    'backendId': 'func-test-backend'
                },
                status=202)
            self.non_search_zone_2 = non_search_zone_2_change['zone']

            self.zone_ids = [
                self.search_zone_1['id'], self.search_zone_2['id'],
                self.search_zone_3['id'], self.non_search_zone_1['id'],
                self.non_search_zone_2['id']
            ]
            zone_changes = [
                search_zone_1_change, search_zone_2_change,
                search_zone_3_change, non_search_zone_1_change,
                non_search_zone_2_change
            ]
            for change in zone_changes:
                self.client.wait_until_zone_active(change[u'zone'][u'id'])
        except:
            # teardown if there was any issue in setup
            try:
                self.tear_down()
            except:
                pass
            raise

    def tear_down(self):
        clear_zones(self.client)
        clear_groups(self.client)
class ZoneHistoryContext(object):
    """
    Creates a zone with multiple zone changes and record set changes
    """

    def __init__(self):
        self.client = VinylDNSClient(VinylDNSTestContext.vinyldns_url, 'history-key', 'history-secret')
        self.tear_down()
        self.group = None

        group = {
            'name': 'history-group',
            'email': '*****@*****.**',
            'description': 'this is a description',
            'members': [ { 'id': 'history-id'} ],
            'admins': [ { 'id': 'history-id'} ]
        }

        self.group = self.client.create_group(group, status=200)
        # in theory this shouldn't be needed, but getting 'user is not in group' errors on zone creation
        self.confirm_member_in_group(self.client, self.group)

        zone_change = self.client.create_zone(
            {
                'name': 'system-test-history.',
                'email': '*****@*****.**',
                'shared': False,
                'adminGroupId': self.group['id'],
                'isTest': True,
                'connection': {
                    'name': 'vinyldns.',
                    'keyName': VinylDNSTestContext.dns_key_name,
                    'key': VinylDNSTestContext.dns_key,
                    'primaryServer': VinylDNSTestContext.dns_ip
                },
                'transferConnection': {
                    'name': 'vinyldns.',
                    'keyName': VinylDNSTestContext.dns_key_name,
                    'key': VinylDNSTestContext.dns_key,
                    'primaryServer': VinylDNSTestContext.dns_ip
                }
            }, status=202)
        self.zone = zone_change['zone']

        self.client.wait_until_zone_active(zone_change[u'zone'][u'id'])

        # change the zone nine times to we have update events in zone change history, ten total changes including creation
        for i in range(2,11):
            zone_update = dict(self.zone)
            zone_update['connection']['key'] = VinylDNSTestContext.dns_key
            zone_update['transferConnection']['key'] = VinylDNSTestContext.dns_key
            zone_update['email'] = 'i.changed.this.{0}[email protected]'.format(i)
            zone_update = self.client.update_zone(zone_update, status=202)['zone']

        # create some record sets
        (achange, a_record) = self.create_recordset(TestData.A)
        (aaaachange, aaaa_record) = self.create_recordset(TestData.AAAA)
        (cnamechange, cname_record) = self.create_recordset(TestData.CNAME)

        # wait here for all the record sets to be created
        self.client.wait_until_recordset_exists(a_record['zoneId'], a_record['id'])
        self.client.wait_until_recordset_exists(aaaa_record['zoneId'], aaaa_record['id'])
        self.client.wait_until_recordset_exists(cname_record['zoneId'], cname_record['id'])

        # update the record sets
        a_record_update = dict(a_record)
        a_record_update['ttl'] += 100
        a_record_update['records'][0]['address'] = '9.9.9.9'
        (achange, a_record_update) = self.update_recordset(a_record_update)

        aaaa_record_update = dict(aaaa_record)
        aaaa_record_update['ttl'] += 100
        aaaa_record_update['records'][0]['address'] = '2003:db8:0:0:0:0:0:4'
        (aaaachange, aaaa_record_update) = self.update_recordset(aaaa_record_update)

        cname_record_update = dict(cname_record)
        cname_record_update['ttl'] += 100
        cname_record_update['records'][0]['cname'] = 'changed-cname.'
        (cnamechange, cname_record_update) = self.update_recordset(cname_record_update)

        self.client.wait_until_recordset_change_status(achange, 'Complete')
        self.client.wait_until_recordset_change_status(aaaachange, 'Complete')
        self.client.wait_until_recordset_change_status(cnamechange, 'Complete')


        # delete the recordsets
        self.delete_recordset(a_record)
        self.delete_recordset(aaaa_record)
        self.delete_recordset(cname_record)

        self.client.wait_until_recordset_deleted(a_record['zoneId'], a_record['id'])
        self.client.wait_until_recordset_deleted(aaaa_record['zoneId'], aaaa_record['id'])
        self.client.wait_until_recordset_deleted(cname_record['zoneId'], cname_record['id'])


        # the resulting context should contain all of the parts so it makes it simple to test
        self.results = {
            'zone': self.zone,
            'zoneUpdate': zone_update,
            'creates': [a_record, aaaa_record, cname_record],
            'updates': [a_record_update, aaaa_record_update, cname_record_update]
        }

    # finalizer called by py.test when the simulation is torn down
    def tear_down(self):
        self.clear_zones()
        self.clear_group()


    def clear_group(self):
        groups = self.client.list_all_my_groups()
        group_ids = map(lambda x: x['id'], groups)

        for group_id in group_ids:
            self.client.delete_group(group_id, status=200)


    def clear_zones(self):
        # Get the groups for the ok user
        groups = self.client.list_all_my_groups()
        group_ids = map(lambda x: x['id'], groups)

        zones = self.client.list_zones()['zones']

        # we only want to delete zones that the ok user "owns"
        zones_to_delete = filter(lambda x: (x['adminGroupId'] in group_ids) or (x['account'] in group_ids), zones)
        zone_names_to_delete = map(lambda x: x['name'], zones_to_delete)

        zoneids_to_delete = map(lambda x: x['id'], zones_to_delete)

        self.client.abandon_zones(zoneids_to_delete)


    def create_recordset(self, rs):
        rs['zoneId'] = self.zone['id']
        result = self.client.create_recordset(rs, status=202)
        return result, result['recordSet']


    def update_recordset(self, rs):
        rs['zoneId'] = self.zone['id']
        result = self.client.update_recordset(rs, status=202)
        return result, result['recordSet']


    def delete_recordset(self, rs):
        result =  self.client.delete_recordset(self.zone['id'], rs['id'], status=202)
        return result, result['recordSet']

    def confirm_member_in_group(self, client, group):
        retries = 2
        success = group in client.list_all_my_groups(status=200)
        while retries >= 0 and not success:
            success = group in client.list_all_my_groups(status=200)
            time.sleep(.05)
            retries -= 1
        assert_that(success, is_(True))
Beispiel #8
0
class ListRecordSetsTestContext(object):
    def __init__(self, partition_id: str):
        self.partition_id = partition_id
        self.setup_started = False
        self.client = VinylDNSClient(VinylDNSTestContext.vinyldns_url,
                                     "listRecordsAccessKey",
                                     "listRecordsSecretKey")
        self.zone = None
        self.all_records = []
        self.group = None

        get_zone = self.client.get_zone_by_name(f"list-records{partition_id}.",
                                                status=(200, 404))
        if get_zone and "zone" in get_zone:
            self.zone = get_zone["zone"]
            self.all_records = self.client.list_recordsets_by_zone(
                self.zone["id"])["recordSets"]
            my_groups = self.client.list_my_groups(
                group_name_filter="list-records-group")
            if my_groups and "groups" in my_groups and len(
                    my_groups["groups"]) > 0:
                self.group = my_groups["groups"][0]

    def setup(self):
        if self.setup_started:
            # Safeguard against reentrance
            return
        self.setup_started = True

        partition_id = self.partition_id
        group = {
            "name": f"list-records-group{partition_id}",
            "email": "*****@*****.**",
            "description": "this is a description",
            "members": [{
                "id": "list-records-user"
            }],
            "admins": [{
                "id": "list-records-user"
            }]
        }
        self.group = self.client.create_group(group, status=200)
        zone_change = self.client.create_zone(
            {
                "name": f"list-records{partition_id}.",
                "email": "*****@*****.**",
                "shared": False,
                "adminGroupId": self.group["id"],
                "isTest": True,
                "backendId": "func-test-backend"
            },
            status=202)
        self.client.wait_until_zone_active(zone_change["zone"]["id"])
        self.zone = zone_change["zone"]
        self.all_records = self.client.list_recordsets_by_zone(
            self.zone["id"])["recordSets"]

    def tear_down(self):
        self.client.clear_zones()
        self.client.clear_groups()
        self.client.tear_down()

    def check_recordsets_page_accuracy(self,
                                       list_results_page,
                                       size,
                                       offset,
                                       next_id=False,
                                       start_from=False,
                                       max_items=100,
                                       record_type_filter=False,
                                       name_sort="ASC"):
        # validate fields
        if next_id:
            assert_that(list_results_page, has_key("nextId"))
        else:
            assert_that(list_results_page, is_not(has_key("nextId")))
        if start_from:
            assert_that(list_results_page["startFrom"], is_(start_from))
        else:
            assert_that(list_results_page, is_not(has_key("startFrom")))
        if record_type_filter:
            assert_that(list_results_page, has_key("recordTypeFilter"))
        else:
            assert_that(list_results_page, is_not(has_key("recordTypeFilter")))
        assert_that(list_results_page["maxItems"], is_(max_items))
        assert_that(list_results_page["nameSort"], is_(name_sort))

        # validate actual page
        list_results_recordsets_page = list_results_page["recordSets"]
        assert_that(list_results_recordsets_page, has_length(size))
        for i in range(len(list_results_recordsets_page)):
            assert_that(list_results_recordsets_page[i]["name"],
                        is_(self.all_records[i + offset]["name"]))
            verify_recordset(list_results_recordsets_page[i],
                             self.all_records[i + offset])
            assert_that(list_results_recordsets_page[i]["accessLevel"],
                        is_("Delete"))

    def check_recordsets_parameters(self,
                                    list_results_page,
                                    next_id=False,
                                    start_from=False,
                                    max_items=100,
                                    record_type_filter=False,
                                    name_sort="ASC"):
        # validate fields
        if next_id:
            assert_that(list_results_page, has_key("nextId"))
        else:
            assert_that(list_results_page, is_not(has_key("nextId")))
        if start_from:
            assert_that(list_results_page["startFrom"], is_(start_from))
        else:
            assert_that(list_results_page, is_not(has_key("startFrom")))
        if record_type_filter:
            assert_that(list_results_page, has_key("recordTypeFilter"))
        else:
            assert_that(list_results_page, is_not(has_key("recordTypeFilter")))
        assert_that(list_results_page["maxItems"], is_(max_items))
        assert_that(list_results_page["nameSort"], is_(name_sort))
Beispiel #9
0
class SharedZoneTestContext(object):
    """
    Creates multiple zones to test authorization / access to shared zones across users
    """
    def __init__(self, fixture_file=None):
        self.ok_vinyldns_client = VinylDNSClient(
            VinylDNSTestContext.vinyldns_url, 'okAccessKey', 'okSecretKey')
        self.dummy_vinyldns_client = VinylDNSClient(
            VinylDNSTestContext.vinyldns_url, 'dummyAccessKey',
            'dummySecretKey')
        self.shared_zone_vinyldns_client = VinylDNSClient(
            VinylDNSTestContext.vinyldns_url, 'sharedZoneUserAccessKey',
            'sharedZoneUserSecretKey')
        self.support_user_client = VinylDNSClient(
            VinylDNSTestContext.vinyldns_url, 'supportUserAccessKey',
            'supportUserSecretKey')
        self.unassociated_client = VinylDNSClient(
            VinylDNSTestContext.vinyldns_url, 'listGroupAccessKey',
            'listGroupSecretKey')
        self.test_user_client = VinylDNSClient(
            VinylDNSTestContext.vinyldns_url, 'testUserAccessKey',
            'testUserSecretKey')
        self.history_client = VinylDNSClient(VinylDNSTestContext.vinyldns_url,
                                             'history-key', 'history-secret')
        self.list_zones = ListZonesTestContext()
        self.list_zones_client = self.list_zones.client
        self.list_records_context = ListRecordSetsTestContext()
        self.list_groups_context = ListGroupsTestContext()
        self.list_batch_summaries_context = None

        self.dummy_group = None
        self.ok_group = None
        self.shared_record_group = None
        self.history_group = None
        self.group_activity_created = None
        self.group_activity_updated = None

        # if we are using an existing fixture, load the fixture file and pull all of our data from there
        if fixture_file:
            print "\r\n!!! FIXTURE FILE IS SET !!!"
            self.load_fixture_file(fixture_file)
        else:
            print "\r\n!!! FIXTURE FILE NOT SET, BUILDING FIXTURE !!!"
            # No fixture file, so we have to build everything ourselves
            self.tear_down(
            )  # ensures that the environment is clean before starting
            try:
                ok_group = {
                    'name': 'ok-group',
                    'email': '*****@*****.**',
                    'description': 'this is a description',
                    'members': [{
                        'id': 'ok'
                    }, {
                        'id': 'support-user-id'
                    }],
                    'admins': [{
                        'id': 'ok'
                    }]
                }

                self.ok_group = self.ok_vinyldns_client.create_group(
                    ok_group, status=200)
                # in theory this shouldn't be needed, but getting 'user is not in group' errors on zone creation
                self.confirm_member_in_group(self.ok_vinyldns_client,
                                             self.ok_group)

                dummy_group = {
                    'name': 'dummy-group',
                    'email': '*****@*****.**',
                    'description': 'this is a description',
                    'members': [{
                        'id': 'dummy'
                    }],
                    'admins': [{
                        'id': 'dummy'
                    }]
                }
                self.dummy_group = self.dummy_vinyldns_client.create_group(
                    dummy_group, status=200)
                # in theory this shouldn't be needed, but getting 'user is not in group' errors on zone creation
                self.confirm_member_in_group(self.dummy_vinyldns_client,
                                             self.dummy_group)

                shared_record_group = {
                    'name': 'record-ownergroup',
                    'email': '*****@*****.**',
                    'description': 'this is a description',
                    'members': [{
                        'id': 'sharedZoneUser'
                    }, {
                        'id': 'ok'
                    }],
                    'admins': [{
                        'id': 'sharedZoneUser'
                    }, {
                        'id': 'ok'
                    }]
                }
                self.shared_record_group = self.ok_vinyldns_client.create_group(
                    shared_record_group, status=200)

                history_group = {
                    'name': 'history-group',
                    'email': '*****@*****.**',
                    'description': 'this is a description',
                    'members': [{
                        'id': 'history-id'
                    }],
                    'admins': [{
                        'id': 'history-id'
                    }]
                }
                self.history_group = self.history_client.create_group(
                    history_group, status=200)
                self.confirm_member_in_group(self.history_client,
                                             self.history_group)

                history_zone_change = self.history_client.create_zone(
                    {
                        'name': 'system-test-history.',
                        'email': '*****@*****.**',
                        'shared': False,
                        'adminGroupId': self.history_group['id'],
                        'isTest': True,
                        'connection': {
                            'name': 'vinyldns.',
                            'keyName': VinylDNSTestContext.dns_key_name,
                            'key': VinylDNSTestContext.dns_key,
                            'primaryServer': VinylDNSTestContext.dns_ip
                        },
                        'transferConnection': {
                            'name': 'vinyldns.',
                            'keyName': VinylDNSTestContext.dns_key_name,
                            'key': VinylDNSTestContext.dns_key,
                            'primaryServer': VinylDNSTestContext.dns_ip
                        }
                    },
                    status=202)
                self.history_zone = history_zone_change['zone']

                ok_zone_change = self.ok_vinyldns_client.create_zone(
                    {
                        'name': 'ok.',
                        'email': '*****@*****.**',
                        'shared': False,
                        'adminGroupId': self.ok_group['id'],
                        'isTest': True,
                        'connection': {
                            'name': 'ok.',
                            'keyName': VinylDNSTestContext.dns_key_name,
                            'key': VinylDNSTestContext.dns_key,
                            'primaryServer': VinylDNSTestContext.dns_ip
                        },
                        'transferConnection': {
                            'name': 'ok.',
                            'keyName': VinylDNSTestContext.dns_key_name,
                            'key': VinylDNSTestContext.dns_key,
                            'primaryServer': VinylDNSTestContext.dns_ip
                        }
                    },
                    status=202)
                self.ok_zone = ok_zone_change['zone']

                dummy_zone_change = self.dummy_vinyldns_client.create_zone(
                    {
                        'name': 'dummy.',
                        'email': '*****@*****.**',
                        'shared': False,
                        'adminGroupId': self.dummy_group['id'],
                        'isTest': True,
                        'connection': {
                            'name': 'dummy.',
                            'keyName': VinylDNSTestContext.dns_key_name,
                            'key': VinylDNSTestContext.dns_key,
                            'primaryServer': VinylDNSTestContext.dns_ip
                        },
                        'transferConnection': {
                            'name': 'dummy.',
                            'keyName': VinylDNSTestContext.dns_key_name,
                            'key': VinylDNSTestContext.dns_key,
                            'primaryServer': VinylDNSTestContext.dns_ip
                        }
                    },
                    status=202)
                self.dummy_zone = dummy_zone_change['zone']

                ip6_reverse_zone_change = self.ok_vinyldns_client.create_zone(
                    {
                        'name': '1.9.e.f.c.c.7.2.9.6.d.f.ip6.arpa.',
                        'email': '*****@*****.**',
                        'shared': False,
                        'adminGroupId': self.ok_group['id'],
                        'isTest': True,
                        'connection': {
                            'name': 'ip6.',
                            'keyName': VinylDNSTestContext.dns_key_name,
                            'key': VinylDNSTestContext.dns_key,
                            'primaryServer': VinylDNSTestContext.dns_ip
                        },
                        'transferConnection': {
                            'name': 'ip6.',
                            'keyName': VinylDNSTestContext.dns_key_name,
                            'key': VinylDNSTestContext.dns_key,
                            'primaryServer': VinylDNSTestContext.dns_ip
                        }
                    },
                    status=202)
                self.ip6_reverse_zone = ip6_reverse_zone_change['zone']

                ip6_16_nibble_zone_change = self.ok_vinyldns_client.create_zone(
                    {
                        'name': '0.0.0.1.1.9.e.f.c.c.7.2.9.6.d.f.ip6.arpa.',
                        'email': '*****@*****.**',
                        'shared': False,
                        'adminGroupId': self.ok_group['id'],
                        'isTest': True,
                        'backendId': 'func-test-backend'
                    },
                    status=202)
                self.ip6_16_nibble_zone = ip6_16_nibble_zone_change['zone']

                ip4_reverse_zone_change = self.ok_vinyldns_client.create_zone(
                    {
                        'name': '10.10.in-addr.arpa.',
                        'email': '*****@*****.**',
                        'shared': False,
                        'adminGroupId': self.ok_group['id'],
                        'isTest': True,
                        'connection': {
                            'name': 'ip4.',
                            'keyName': VinylDNSTestContext.dns_key_name,
                            'key': VinylDNSTestContext.dns_key,
                            'primaryServer': VinylDNSTestContext.dns_ip
                        },
                        'transferConnection': {
                            'name': 'ip4.',
                            'keyName': VinylDNSTestContext.dns_key_name,
                            'key': VinylDNSTestContext.dns_key,
                            'primaryServer': VinylDNSTestContext.dns_ip
                        }
                    },
                    status=202)
                self.ip4_reverse_zone = ip4_reverse_zone_change['zone']

                self.classless_base_zone_json = {
                    'name': '2.0.192.in-addr.arpa.',
                    'email': '*****@*****.**',
                    'shared': False,
                    'adminGroupId': self.ok_group['id'],
                    'isTest': True,
                    'connection': {
                        'name': 'classless-base.',
                        'keyName': VinylDNSTestContext.dns_key_name,
                        'key': VinylDNSTestContext.dns_key,
                        'primaryServer': VinylDNSTestContext.dns_ip
                    },
                    'transferConnection': {
                        'name': 'classless-base.',
                        'keyName': VinylDNSTestContext.dns_key_name,
                        'key': VinylDNSTestContext.dns_key,
                        'primaryServer': VinylDNSTestContext.dns_ip
                    }
                }

                classless_base_zone_change = self.ok_vinyldns_client.create_zone(
                    self.classless_base_zone_json, status=202)
                self.classless_base_zone = classless_base_zone_change['zone']

                classless_zone_delegation_change = self.ok_vinyldns_client.create_zone(
                    {
                        'name': '192/30.2.0.192.in-addr.arpa.',
                        'email': '*****@*****.**',
                        'shared': False,
                        'adminGroupId': self.ok_group['id'],
                        'isTest': True,
                        'connection': {
                            'name': 'classless.',
                            'keyName': VinylDNSTestContext.dns_key_name,
                            'key': VinylDNSTestContext.dns_key,
                            'primaryServer': VinylDNSTestContext.dns_ip
                        },
                        'transferConnection': {
                            'name': 'classless.',
                            'keyName': VinylDNSTestContext.dns_key_name,
                            'key': VinylDNSTestContext.dns_key,
                            'primaryServer': VinylDNSTestContext.dns_ip
                        }
                    },
                    status=202)
                self.classless_zone_delegation_zone = classless_zone_delegation_change[
                    'zone']

                system_test_zone_change = self.ok_vinyldns_client.create_zone(
                    {
                        'name': 'system-test.',
                        'email': '*****@*****.**',
                        'shared': False,
                        'adminGroupId': self.ok_group['id'],
                        'isTest': True,
                        'connection': {
                            'name': 'system-test.',
                            'keyName': VinylDNSTestContext.dns_key_name,
                            'key': VinylDNSTestContext.dns_key,
                            'primaryServer': VinylDNSTestContext.dns_ip
                        },
                        'transferConnection': {
                            'name': 'system-test.',
                            'keyName': VinylDNSTestContext.dns_key_name,
                            'key': VinylDNSTestContext.dns_key,
                            'primaryServer': VinylDNSTestContext.dns_ip
                        }
                    },
                    status=202)
                self.system_test_zone = system_test_zone_change['zone']

                # parent zone gives access to the dummy user, dummy user cannot manage ns records
                parent_zone_change = self.ok_vinyldns_client.create_zone(
                    {
                        'name': 'parent.com.',
                        'email': '*****@*****.**',
                        'shared': False,
                        'adminGroupId': self.ok_group['id'],
                        'isTest': True,
                        'acl': {
                            'rules': [{
                                'accessLevel': 'Delete',
                                'description': 'some_test_rule',
                                'userId': 'dummy'
                            }]
                        },
                        'connection': {
                            'name': 'parent.',
                            'keyName': VinylDNSTestContext.dns_key_name,
                            'key': VinylDNSTestContext.dns_key,
                            'primaryServer': VinylDNSTestContext.dns_ip
                        },
                        'transferConnection': {
                            'name': 'parent.',
                            'keyName': VinylDNSTestContext.dns_key_name,
                            'key': VinylDNSTestContext.dns_key,
                            'primaryServer': VinylDNSTestContext.dns_ip
                        }
                    },
                    status=202)
                self.parent_zone = parent_zone_change['zone']

                # mimicking the spec example
                ds_zone_change = self.ok_vinyldns_client.create_zone(
                    {
                        'name': 'example.com.',
                        'email': '*****@*****.**',
                        'shared': False,
                        'adminGroupId': self.ok_group['id'],
                        'isTest': True,
                        'connection': {
                            'name': 'example.',
                            'keyName': VinylDNSTestContext.dns_key_name,
                            'key': VinylDNSTestContext.dns_key,
                            'primaryServer': VinylDNSTestContext.dns_ip
                        },
                        'transferConnection': {
                            'name': 'example.',
                            'keyName': VinylDNSTestContext.dns_key_name,
                            'key': VinylDNSTestContext.dns_key,
                            'primaryServer': VinylDNSTestContext.dns_ip
                        }
                    },
                    status=202)
                self.ds_zone = ds_zone_change['zone']

                # zone with name configured for manual review
                requires_review_zone_change = self.ok_vinyldns_client.create_zone(
                    {
                        'name': 'zone.requires.review.',
                        'email': '*****@*****.**',
                        'shared': False,
                        'adminGroupId': self.ok_group['id'],
                        'isTest': True,
                        'backendId': 'func-test-backend'
                    },
                    status=202)
                self.requires_review_zone = requires_review_zone_change['zone']

                get_shared_zones = self.shared_zone_vinyldns_client.list_zones(
                    status=200)['zones']
                shared_zone = [
                    zone for zone in get_shared_zones
                    if zone['name'] == "shared."
                ]
                non_test_shared_zone = [
                    zone for zone in get_shared_zones
                    if zone['name'] == "non.test.shared."
                ]

                shared_zone_change = self.set_up_shared_zone(
                    shared_zone[0]['id'])
                self.shared_zone = shared_zone_change['zone']

                non_test_shared_zone_change = self.set_up_shared_zone(
                    non_test_shared_zone[0]['id'])
                self.non_test_shared_zone = non_test_shared_zone_change['zone']

                # wait until our zones are created
                self.ok_vinyldns_client.wait_until_zone_active(
                    system_test_zone_change[u'zone'][u'id'])
                self.ok_vinyldns_client.wait_until_zone_active(
                    ok_zone_change[u'zone'][u'id'])
                self.dummy_vinyldns_client.wait_until_zone_active(
                    dummy_zone_change[u'zone'][u'id'])
                self.ok_vinyldns_client.wait_until_zone_active(
                    ip6_reverse_zone_change[u'zone'][u'id'])
                self.ok_vinyldns_client.wait_until_zone_active(
                    ip6_16_nibble_zone_change[u'zone'][u'id'])
                self.ok_vinyldns_client.wait_until_zone_active(
                    ip4_reverse_zone_change[u'zone'][u'id'])
                self.ok_vinyldns_client.wait_until_zone_active(
                    classless_base_zone_change[u'zone'][u'id'])
                self.ok_vinyldns_client.wait_until_zone_active(
                    classless_zone_delegation_change[u'zone'][u'id'])
                self.ok_vinyldns_client.wait_until_zone_active(
                    system_test_zone_change[u'zone'][u'id'])
                self.ok_vinyldns_client.wait_until_zone_active(
                    parent_zone_change[u'zone'][u'id'])
                self.ok_vinyldns_client.wait_until_zone_active(
                    ds_zone_change[u'zone'][u'id'])
                self.ok_vinyldns_client.wait_until_zone_active(
                    requires_review_zone_change[u'zone'][u'id'])
                self.history_client.wait_until_zone_active(
                    history_zone_change[u'zone'][u'id'])
                self.shared_zone_vinyldns_client.wait_until_zone_change_status_synced(
                    shared_zone_change)

                shared_sync_change = self.shared_zone_vinyldns_client.sync_zone(
                    self.shared_zone['id'])
                self.shared_zone_vinyldns_client.wait_until_zone_change_status_synced(
                    non_test_shared_zone_change)
                non_test_shared_sync_change = self.shared_zone_vinyldns_client.sync_zone(
                    self.non_test_shared_zone['id'])

                self.shared_zone_vinyldns_client.wait_until_zone_change_status_synced(
                    shared_sync_change)
                self.shared_zone_vinyldns_client.wait_until_zone_change_status_synced(
                    non_test_shared_sync_change)

                # validate all in there
                zones = self.dummy_vinyldns_client.list_zones()['zones']
                assert_that(len(zones), is_(2))
                zones = self.ok_vinyldns_client.list_zones()['zones']
                assert_that(len(zones), is_(10))
                zones = self.shared_zone_vinyldns_client.list_zones()['zones']
                assert_that(len(zones), is_(2))

                # initialize history
                self.init_history()

                # initalize group activity
                self.init_group_activity()

                # initialize list zones, only do this when constructing the whole!
                self.list_zones.build()

                # note: there are no state to load, the tests only need the client
                self.list_zones_client = self.list_zones.client

                # build the list of records; note: we do need to save the test records
                self.list_records_context.build()

                # build the list of groups
                self.list_groups_context.build()

            except:
                # teardown if there was any issue in setup
                try:
                    self.tear_down()
                except:
                    pass
                raise

        # We need to load somethings AFTER we are all initialized, do that here
        self.list_batch_summaries_context = ListBatchChangeSummariesTestContext(
            self)

    def init_history(self):
        from test_data import TestData
        import copy
        # Initialize the zone history
        # change the zone nine times to we have update events in zone change history,
        # ten total changes including creation
        for i in range(2, 11):
            zone_update = copy.deepcopy(self.history_zone)
            zone_update['connection']['key'] = VinylDNSTestContext.dns_key
            zone_update['transferConnection'][
                'key'] = VinylDNSTestContext.dns_key
            zone_update[
                'email'] = 'i.changed.this.{0}[email protected]'.format(
                    i)
            zone_update = self.history_client.update_zone(zone_update,
                                                          status=202)['zone']

        # create some record sets
        test_a = TestData.A.copy()
        test_a['zoneId'] = self.history_zone['id']
        test_aaaa = TestData.AAAA.copy()
        test_aaaa['zoneId'] = self.history_zone['id']
        test_cname = TestData.CNAME.copy()
        test_cname['zoneId'] = self.history_zone['id']

        a_record = self.history_client.create_recordset(
            test_a, status=202)['recordSet']
        aaaa_record = self.history_client.create_recordset(
            test_aaaa, status=202)['recordSet']
        cname_record = self.history_client.create_recordset(
            test_cname, status=202)['recordSet']

        # wait here for all the record sets to be created
        self.history_client.wait_until_recordset_exists(
            a_record['zoneId'], a_record['id'])
        self.history_client.wait_until_recordset_exists(
            aaaa_record['zoneId'], aaaa_record['id'])
        self.history_client.wait_until_recordset_exists(
            cname_record['zoneId'], cname_record['id'])

        # update the record sets
        a_record_update = copy.deepcopy(a_record)
        a_record_update['ttl'] += 100
        a_record_update['records'][0]['address'] = '9.9.9.9'
        a_change = self.history_client.update_recordset(a_record_update,
                                                        status=202)

        aaaa_record_update = copy.deepcopy(aaaa_record)
        aaaa_record_update['ttl'] += 100
        aaaa_record_update['records'][0]['address'] = '2003:db8:0:0:0:0:0:4'
        aaaa_change = self.history_client.update_recordset(aaaa_record_update,
                                                           status=202)

        cname_record_update = copy.deepcopy(cname_record)
        cname_record_update['ttl'] += 100
        cname_record_update['records'][0]['cname'] = 'changed-cname.'
        cname_change = self.history_client.update_recordset(
            cname_record_update, status=202)

        self.history_client.wait_until_recordset_change_status(
            a_change, 'Complete')
        self.history_client.wait_until_recordset_change_status(
            aaaa_change, 'Complete')
        self.history_client.wait_until_recordset_change_status(
            cname_change, 'Complete')

        # delete the recordsets
        self.history_client.delete_recordset(a_record['zoneId'],
                                             a_record['id'])
        self.history_client.delete_recordset(aaaa_record['zoneId'],
                                             aaaa_record['id'])
        self.history_client.delete_recordset(cname_record['zoneId'],
                                             cname_record['id'])

        self.history_client.wait_until_recordset_deleted(
            a_record['zoneId'], a_record['id'])
        self.history_client.wait_until_recordset_deleted(
            aaaa_record['zoneId'], aaaa_record['id'])
        self.history_client.wait_until_recordset_deleted(
            cname_record['zoneId'], cname_record['id'])

    def init_group_activity(self):
        client = self.ok_vinyldns_client
        created_group = None

        group_name = 'test-list-group-activity-max-item-success'

        # cleanup existing group if it's already in there
        groups = client.list_all_my_groups()
        existing = [grp for grp in groups if grp['name'] == group_name]
        for grp in existing:
            client.delete_group(grp['id'], status=200)

        members = [{'id': 'ok'}]
        new_group = {
            'name': group_name,
            'email': '*****@*****.**',
            'members': members,
            'admins': [{
                'id': 'ok'
            }]
        }
        created_group = client.create_group(new_group, status=200)

        update_groups = []
        updated_groups = []
        # each update changes the member
        for runner in range(0, 10):
            id = "dummy{0:0>3}".format(runner)
            members = [{'id': id}]
            update_groups.append({
                'id': created_group['id'],
                'name': group_name,
                'email': '*****@*****.**',
                'members': members,
                'admins': [{
                    'id': 'ok'
                }]
            })
            updated_groups.append(
                client.update_group(update_groups[runner]['id'],
                                    update_groups[runner],
                                    status=200))

        self.group_activity_created = created_group
        self.group_activity_updated = updated_groups

    def load_fixture_file(self, fixture_file):
        # The fixture file contains all of the groups and zones,
        # The format is simply json where groups = [] and zones = []
        import json
        with open(fixture_file) as json_file:
            data = json.load(json_file)
            self.ok_group = data['ok_group']
            self.ok_zone = data['ok_zone']
            self.dummy_group = data['dummy_group']
            self.shared_record_group = data['shared_record_group']
            self.dummy_zone = data['dummy_zone']
            self.ip6_reverse_zone = data['ip6_reverse_zone']
            self.ip6_16_nibble_zone = data['ip6_16_nibble_zone']
            self.ip4_reverse_zone = data['ip4_reverse_zone']
            self.classless_base_zone = data['classless_base_zone']
            self.classless_zone_delegation_zone = data[
                'classless_zone_delegation_zone']
            self.system_test_zone = data['system_test_zone']
            self.parent_zone = data['parent_zone']
            self.ds_zone = data['ds_zone']
            self.requires_review_zone = data['requires_review_zone']
            self.shared_zone = data['shared_zone']
            self.non_test_shared_zone = data['non_test_shared_zone']
            self.history_zone = data['history_zone']
            self.history_group = data['history_group']
            self.group_activity_created = data['group_activity_created']
            self.group_activity_updated = data['group_activity_updated']

    def out_fixture_file(self, fixture_file):
        print "\r\n!!! PRINTING OUT FIXTURE FILE !!!"
        import json
        # output the fixture file, be sure to be in sync with the load_fixture_file
        data = {
            'ok_group': self.ok_group,
            'ok_zone': self.ok_zone,
            'dummy_group': self.dummy_group,
            'shared_record_group': self.shared_record_group,
            'dummy_zone': self.dummy_zone,
            'ip6_reverse_zone': self.ip6_reverse_zone,
            'ip6_16_nibble_zone': self.ip6_16_nibble_zone,
            'ip4_reverse_zone': self.ip4_reverse_zone,
            'classless_base_zone': self.classless_base_zone,
            'classless_zone_delegation_zone':
            self.classless_zone_delegation_zone,
            'system_test_zone': self.system_test_zone,
            'parent_zone': self.parent_zone,
            'ds_zone': self.ds_zone,
            'requires_review_zone': self.requires_review_zone,
            'shared_zone': self.shared_zone,
            'non_test_shared_zone': self.non_test_shared_zone,
            'history_zone': self.history_zone,
            'history_group': self.history_group,
            'group_activity_created': self.group_activity_created,
            'group_activity_updated': self.group_activity_updated
        }
        with open(fixture_file, 'w') as out_file:
            json.dump(data, out_file)

    def set_up_shared_zone(self, zone_id):
        # shared zones are created through test data loader, but needs connection info added here to use
        get_shared_zone = self.shared_zone_vinyldns_client.get_zone(zone_id)
        shared_zone = get_shared_zone['zone']

        connection_info = {
            'name': 'shared.',
            'keyName': VinylDNSTestContext.dns_key_name,
            'key': VinylDNSTestContext.dns_key,
            'primaryServer': VinylDNSTestContext.dns_ip
        }

        shared_zone['connection'] = connection_info
        shared_zone['transferConnection'] = connection_info

        return self.shared_zone_vinyldns_client.update_zone(shared_zone,
                                                            status=202)

    def tear_down(self):
        """
        The ok_vinyldns_client is a zone admin on _all_ the zones.

        We shouldn't have to do any checks now, as zone admins have full rights to all zones, including
        deleting all records (even in the old shared model)
        """
        self.list_zones.tear_down()
        self.list_records_context.tear_down()

        if self.list_batch_summaries_context:
            self.list_batch_summaries_context.tear_down(self)

        if self.list_groups_context:
            self.list_groups_context.tear_down()

        clear_zones(self.dummy_vinyldns_client)
        clear_zones(self.ok_vinyldns_client)
        clear_zones(self.history_client)
        clear_groups(self.dummy_vinyldns_client, "global-acl-group-id")
        clear_groups(self.ok_vinyldns_client, "global-acl-group-id")
        clear_groups(self.history_client)

    @staticmethod
    def confirm_member_in_group(client, group):
        retries = 2
        success = group in client.list_all_my_groups(status=200)
        while retries >= 0 and not success:
            success = group in client.list_all_my_groups(status=200)
            time.sleep(.05)
            retries -= 1
        assert_that(success, is_(True))