Return detailed info about one, or all, zones in the bound account.
    If neither zone_id nor domain_name is provided, return all zones.
    Note that the return format is slightly different between the 'all'
    and 'single' description types.

    zone_id
        The unique identifier for the Hosted Zone

    domain_name
        The FQDN of the Hosted Zone (including final period)

    region
        Region to connect to.

    key
        Secret key to be used.

    keyid
        Access key to be used.

    profile
        A dict with region, key and keyid, or a pillar key (string) that
        contains a dict with region, key and keyid.

    CLI Example:

    .. code-block:: bash

        salt myminion boto_route53.describe_hosted_zones domain_name=foo.bar.com. \
                profile='{"region": "us-east-1", "keyid": "A12345678AB", "key": "xblahblahblah"}'

def describe_hosted_zones(zone_id=None, domain_name=None, region=None,
                          key=None, keyid=None, profile=None):
    '''
    Return detailed info about one, or all, zones in the bound account.
    If neither zone_id nor domain_name is provided, return all zones.
    Note that the return format is slightly different between the 'all'
    and 'single' description types.

    zone_id
        The unique identifier for the Hosted Zone

    domain_name
        The FQDN of the Hosted Zone (including final period)

    region
        Region to connect to.

    key
        Secret key to be used.

    keyid
        Access key to be used.

    profile
        A dict with region, key and keyid, or a pillar key (string) that
        contains a dict with region, key and keyid.

    CLI Example:

    .. code-block:: bash

        salt myminion boto_route53.describe_hosted_zones domain_name=foo.bar.com. \
                profile='{"region": "us-east-1", "keyid": "A12345678AB", "key": "xblahblahblah"}'
    '''
    conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
    if zone_id and domain_name:
        raise SaltInvocationError('At most one of zone_id or domain_name may '
                                  'be provided')
    retries = 10
    while retries:
        try:
            if zone_id:
                zone_id = zone_id.replace('/hostedzone/',
                        '') if zone_id.startswith('/hostedzone/') else zone_id
                ret = getattr(conn.get_hosted_zone(zone_id),
                              'GetHostedZoneResponse', None)
            elif domain_name:
                ret = getattr(conn.get_hosted_zone_by_name(domain_name),
                              'GetHostedZoneResponse', None)
            else:
                marker = None
                ret = None
                while marker is not '':
                    r = conn.get_all_hosted_zones(start_marker=marker,
                                                  zone_list=ret)
                    ret = r['ListHostedZonesResponse']['HostedZones']
                    marker = r['ListHostedZonesResponse'].get('NextMarker', '')
            return ret if ret else []
        except DNSServerError as e:
            if retries:
                if 'Throttling' == e.code:
                    log.debug('Throttled by AWS API.')
                elif 'PriorRequestNotComplete' == e.code:
                    log.debug('The request was rejected by AWS API.\
                              Route 53 was still processing a prior request')
                time.sleep(3)
                retries -= 1
                continue
            log.error('Could not list zones: %s', e.message)
            return []