boto / boto

For the latest version of boto, see https://github.com/boto/boto3 -- Python interface to Amazon Web Services
http://docs.pythonboto.org/
Other
6.48k stars 2.26k forks source link

Name parameter in get_zone is ambiguous in private hosted zones #2977

Open moee opened 9 years ago

moee commented 9 years ago

In Route53 it is possible to create private hosted zones with the same domain name but in different VPCs.

However, in such a case the parameter name in the API call get_zone(name) is ambiguous.

Unfortunately it also is not possible to work around this by enumerating the Zone elements of get_zones(), because to my knowledge there does not exist any information to which VPC a Zone object belongs. Edit: There is a workaround - See comments below.

To illustrate the problem, consider the following example.

conn.create_zone("private.zone.example.com.", private_zone=True, vpc_id=VPC1) 
conn.create_zone("private.zone.example.com.", private_zone=True, vpc_id=VPC2)

Now there are two zones named private.zone.example.com. However there is no way to pick the one that belongs to a specific VPC:

conn.get_zone("private.zone.example.com.") # returns one result even though there are two zones by that name
drbild commented 9 years ago

One workaround is to specify your own caller reference to boto.route53.create_hosted_zone()(unfortunately create_zone() doesn't take the caller reference parameter). Treating the caller reference as the id of the hosted zone, rather than the (name, vpc) tuple, just filter the result of get_zones by the caller reference.

drbild commented 9 years ago

Also, the lower-level boto.route53.get_hosted_zone() includes a list of associated VPCs. See http://docs.aws.amazon.com/Route53/latest/APIReference/API-get-hosted-zone-private.html for details. Of course, the Zone object should still be updated to include this VPC information as well.

moee commented 9 years ago

@drbild thanks for pointing out the workaround with boto.route53.get_hosted_zone(). I can confirm that it works. Q&D PoC (not for use in production)

def get_vpc_zone(name, vpc_id):
    conn = boto.route53.connect_to_region(REGION)
    for zone in conn.get_zones():
            if zone.name == name:
                if conn.get_hosted_zone(zone.id)['GetHostedZoneResponse']['VPCs']['VPC']['VPCId'] == vpc_id:
                    return zone

Anyway, I'd appreciate if get_zone could be extended with a optional vpc parameter.

cyberswat commented 9 years ago

The get_vpc_zone function posted by @moee didn't quite work for me. Here's a slight variant that did.

def get_vpc_zone(conn, name, vpc_id):
  for zone in conn.get_zones():
    if zone.name == name:
      if 'VPCs' in conn.get_hosted_zone(zone.id)['GetHostedZoneResponse']:
        return zone
cyberswat commented 9 years ago

I think having a vpc there is a coincidence and that the check should use the PrivateZone zone attribute. It exists regardless of VPC associations.

def get_private_zone(conn, name):
  for zone in conn.get_zones():
    if zone.name == name:
      if conn.get_hosted_zone(zone.id)['GetHostedZoneResponse']['HostedZone']['Config']['PrivateZone'] == 'true':
        return zone

*Note: Just posting this in case anyone else needs the information. I understand it doesn't solve the initial issue.