Get all resource records from a given zone matching the provided StartRecordName (if given) or all
    records in the zone (if not), optionally filtered by a specific StartRecordType.  This will return
    any and all RRs matching, regardless of their special AWS flavors (weighted, geolocation, alias,
    etc.) so your code should be prepared for potentially large numbers of records back from this
    function - for example, if you've created a complex geolocation mapping with lots of entries all
    over the world providing the same server name to many different regional clients.

    If you want EXACTLY ONE record to operate on, you'll need to implement any logic required to
    pick the specific RR you care about from those returned.

    Note that if you pass in Name without providing a value for PrivateZone (either True or
    False), CommandExecutionError can be raised in the case of both public and private zones
    matching the domain. XXX FIXME DOCU

    CLI example::

        salt myminion boto3_route53.get_records test.example.org example.org A

def get_resource_records(HostedZoneId=None, Name=None, StartRecordName=None,
                         StartRecordType=None, PrivateZone=None,
                         region=None, key=None, keyid=None, profile=None):
    '''
    Get all resource records from a given zone matching the provided StartRecordName (if given) or all
    records in the zone (if not), optionally filtered by a specific StartRecordType.  This will return
    any and all RRs matching, regardless of their special AWS flavors (weighted, geolocation, alias,
    etc.) so your code should be prepared for potentially large numbers of records back from this
    function - for example, if you've created a complex geolocation mapping with lots of entries all
    over the world providing the same server name to many different regional clients.

    If you want EXACTLY ONE record to operate on, you'll need to implement any logic required to
    pick the specific RR you care about from those returned.

    Note that if you pass in Name without providing a value for PrivateZone (either True or
    False), CommandExecutionError can be raised in the case of both public and private zones
    matching the domain. XXX FIXME DOCU

    CLI example::

        salt myminion boto3_route53.get_records test.example.org example.org A
    '''
    if not _exactly_one((HostedZoneId, Name)):
        raise SaltInvocationError('Exactly one of either HostedZoneId or Name must '
                                  'be provided.')
    if Name:
        args = {'Name': Name, 'region': region, 'key': key, 'keyid': keyid,
                'profile': profile}
        args.update({'PrivateZone': PrivateZone}) if PrivateZone is not None else None
        zone = find_hosted_zone(**args)
        if not zone:
            log.error("Couldn't resolve domain name %s to a hosted zone ID.", Name)
            return []
        HostedZoneId = zone[0]['HostedZone']['Id']

    conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
    ret = []
    next_rr_name = StartRecordName
    next_rr_type = StartRecordType
    next_rr_id = None
    done = False
    while True:
        if done:
            return ret
        args = {'HostedZoneId': HostedZoneId}
        args.update({'StartRecordName': aws_encode(next_rr_name)}) if next_rr_name else None
        # Grrr, can't specify type unless name is set...  We'll do this via filtering later instead
        args.update({'StartRecordType': next_rr_type}) if next_rr_name and next_rr_type else None
        args.update({'StartRecordIdentifier': next_rr_id}) if next_rr_id else None
        try:
            r = conn.list_resource_record_sets(**args)
            rrs = r['ResourceRecordSets']
            next_rr_name = r.get('NextRecordName')
            next_rr_type = r.get('NextRecordType')
            next_rr_id = r.get('NextRecordIdentifier')
            for rr in rrs:
                rr['Name'] = _aws_decode(rr['Name'])
                # now iterate over the ResourceRecords and replace any encoded
                # value strings with the decoded versions
                if 'ResourceRecords' in rr:
                    x = 0
                    while x < len(rr['ResourceRecords']):
                        if 'Value' in rr['ResourceRecords'][x]:
                            rr['ResourceRecords'][x]['Value'] = _aws_decode(rr['ResourceRecords'][x]['Value'])
                        x += 1
                # or if we are an AliasTarget then decode the DNSName
                if 'AliasTarget' in rr:
                    rr['AliasTarget']['DNSName'] = _aws_decode(rr['AliasTarget']['DNSName'])
                if StartRecordName and rr['Name'] != StartRecordName:
                    done = True
                    break
                if StartRecordType and rr['Type'] != StartRecordType:
                    if StartRecordName:
                        done = True
                        break
                    else:
                        # We're filtering by type alone, and there might be more later, so...
                        continue
                ret += [rr]
            if not next_rr_name:
                done = True
        except ClientError as e:
            # Try forever on a simple thing like this...
            if e.response.get('Error', {}).get('Code') == 'Throttling':
                log.debug('Throttled by AWS API.')
                time.sleep(3)
                continue
            raise e