Source code for opslib.icsr53

"""
IcsR53: Library for Route53
---------------------------

+--------------------+------------+--+
| This is the IcsR53 common library. |
+--------------------+------------+--+
"""

import time
import string

from boto.route53 import Route53Connection
#from boto.route53.zone import Zone
from boto.route53.record import ResourceRecordSets
from boto.route53 import exception
from opslib.icsexception import IcsR53Exception
from opslib.zone import Zone

import logging
log = logging.getLogger(__name__)


[docs]class IcsR53(object): """ ICS Library for R53 """
[docs] def __init__(self, dns_name=None, **kwargs): self.r53 = Route53Connection(**kwargs) if dns_name is not None: self.zone = self.get_zone(dns_name) if not self.zone: raise IcsR53Exception( "Can't find DNS Zone for '%s'" % (dns_name))
@staticmethod
[docs] def parse_dns_name(name): """ Parse the value of Tag "DnsName" :type name: string :param name: the value of Instance Tag "DnsName" for example, "test.example.com:A:Public:1" :rtype: tuple :return: a tuple containing (DnsName, DnsType, Public/Private, Weight) for example, ("test.example.com", "A", True, "10") """ if name is None or not isinstance(name, basestring): raise IcsR53Exception( "DnsName should be a 'str' not %s" % type(name)) name = name.split(':', 3) if len(name) < 3 or len(name) > 4: raise IcsR53Exception( "Invalid number of sub-strings: '%s'" % len(name)) if name[1].upper() not in ("A", "CNAME"): raise IcsR53Exception( "Invalid DNS type: 'A' or 'CNAME', not '%s'" % name[1]) if name[2].lower() not in ("public", "private"): raise IcsR53Exception( "Invalid DNS value: 'public' or 'private', not '%s'" % name[2]) if len(name) == 4: return(name[0].lower(), name[1].upper(), name[2].lower() == "public", string.atoi(name[3]).__str__()) return(name[0].lower(), name[1].upper(), name[2].lower() == "public", None)
[docs] def get_zone_id(self): """ Get the hosted zone ID for the specified domain name :rtype: string :return: a string containing the ID of the specified hosted zone """ return self.zone.id
[docs] def get_zone(self, name): """ Get the hosted zone for the specified domain name :type name: string :param name: the specified domain name :rtype: class :return: a class containing the specified hosted zone """ zone_dict = self.get_zone_dict(name) return Zone(self.r53, zone_dict)
[docs] def set_zone(self, name): """ Set the hosted zone for the specified domain name :type name: string :param name: the specified domain name """ self.zone = self.get_zone(name)
[docs] def get_zone_dict(self, name): """ Get the hosted zone info for the specified domain name :type name: string :param name: the specified domain name :rtype: dict :return: a dict containing the specified hosted zone info """ if name is None or not isinstance(name, basestring): raise IcsR53Exception( "DnsName should be a 'str' not %s" % type(name)) name = name.lower() name = self.r53._make_qualified(name) results = self.r53.get_all_hosted_zones() zones = results['ListHostedZonesResponse']['HostedZones'] zones.sort(key=len, reverse=True) zones_matched = {} for zone in zones: zname = zone['Name'].lower() if len(zname) > len(name): continue if len(zname) < len(name) and name[-1 - len(zname)] != '.': continue if zname == name[-len(zname):]: zones_matched[zname] = zone if zones_matched: znames = zones_matched.keys() znames.sort(key=len, reverse=True) return zones_matched[znames[0]] return None
[docs] def get_records(self): """ Return a ResourceRecordsSets for all of the records in this zone. """ return self.zone.get_records()
[docs] def find_all_records(self): """ Search all records in this zone. """ return self.zone.find_all_records()
[docs] def find_records(self, name, type, desired=1, all=False, identifier=None): """ Search this Zone for records that match given parameters. Returns None if no results, a ResourceRecord if one result, or a ResourceRecordSets if more than one result. :type name: str :param name: The name of the records should match this parameter :type type: str :param type: The type of the records should match this parameter :type desired: int :param desired: The number of desired results. If the number of matching records in the Zone exceeds the value of this parameter, throw TooManyRecordsException :type all: Boolean :param all: If true return all records that match name, type, and identifier parameters :type identifier: Tuple :param identifier: A tuple specifying WRR or LBR attributes. Valid forms are: * (str, str): WRR record [e.g. ('foo','10')] * (str, str): LBR record [e.g. ('foo','us-east-1') """ return self.zone.find_records(name, type, desired, all, identifier)
[docs] def wait_to_complete(self, status=None, timeout=60): """ Wait for the Route53 commit change to complete :type status: class :param status: the instance initializing ``boto.route53.status.Status`` """ for i in xrange(timeout / 5): result = status.update() if result == 'INSYNC': return True elif result != 'PENDING': raise IcsR53Exception("Unexpected status found: %s" % result) time.sleep(5) result = status.update() if result == 'INSYNC': return True else: raise IcsR53Exception("Wait until timeout: %ss" % timeout)
[docs] def add_record(self, resource_type, name, value, ttl=60, identifier=None): """ Add a new record to this Zone. See _new_record for parameter documentation. Returns a Status object. """ return self.zone.add_record(self, resource_type, name, value, ttl, identifier)
[docs] def update_record(self, old_record, new_value, new_ttl=None, new_identifier=None): """ Update an existing record in this Zone. Returns a Status object. :type old_record: ResourceRecord :param old_record: A ResourceRecord (e.g. returned by find_records) See _new_record for additional parameter documentation. """ return self.zone.update_record(old_record, new_value, new_ttl, new_identifier)
[docs] def delete_record(self, record): """ Delete one or more records from this Zone. Returns a Status object. :param record: A ResourceRecord (e.g. returned by find_records) or list, tuple, or set of ResourceRecords. """ return self.zone.delete_record(record)
[docs] def add_cname(self, name, value, ttl=None, identifier=None): """ Add a new CNAME record to this Zone. See _new_record for parameter documentation. Returns a Status object. """ return self.zone.add_cname(name, value, ttl, identifier)
[docs] def add_a(self, name, value, ttl=None, identifier=None): """ Add a new A record to this Zone. See _new_record for parameter documentation. Returns a Status object. """ return self.zone.add_a(name, value, ttl, identifier)
[docs] def add_alias(self, name, type, alias_hosted_zone_id, alias_dns_name, identifier=None): """ Add a new alias record to this Zone. See _new_alias_record for parameter documentation. Returns a Status object. """ return self.zone.add_alias(name, type, alias_hosted_zone_id, alias_dns_name, identifier)
[docs] def get_cname(self, name, identifier=None, all=False): """ Search this Zone for CNAME records that match name. Returns a ResourceRecord. If there is more than one match return all as a ResourceRecordSets if all is True, otherwise throws TooManyRecordsException. """ return self.zone.find_records(name, 'CNAME', identifier=identifier, all=all)
[docs] def get_a(self, name, identifier=None, all=False): """ Search this Zone for A records that match name. Returns a ResourceRecord. If there is more than one match return all as a ResourceRecordSets if all is True, otherwise throws TooManyRecordsException. """ return self.zone.find_records(name, 'A', identifier=identifier, all=all)
[docs] def update_cname(self, name, value, ttl=None, identifier=None): """ Update the given CNAME record in this Zone to a new value, ttl, and identifier. Returns a Status object. Will throw TooManyRecordsException is name, value does not match a single record. """ name = self.r53._make_qualified(name) value = self.r53._make_qualified(value) old_record = self.get_cname(name, identifier) if old_record is None: return None else: ttl = ttl or old_record.ttl return self.update_record(old_record, new_value=value, new_ttl=ttl, new_identifier=identifier)
[docs] def update_a(self, name, value, ttl=None, identifier=None): """ Update the given A record in this Zone to a new value, ttl, and identifier. Returns a Status object. Will throw TooManyRecordsException is name, value does not match a single record. """ name = self.r53._make_qualified(name) old_record = self.get_a(name, identifier) if old_record is None: return None else: ttl = ttl or old_record.ttl return self.update_record(old_record, new_value=value, new_ttl=ttl, new_identifier=identifier)
[docs] def update_alias(self, name, type, identifier=None, alias_dns_name=None): """ Update the given alias record in this Zone to a new routing policy Returns a Status object. Will throw TooManyRecordsException is name, value does not match a single record. """ return self.zone.update_alias(name, type, identifier, alias_dns_name)
[docs] def delete_cname(self, name, identifier=None, all=False): """ Delete a CNAME record matching name and identifier from this Zone. Returns a Status object. If there is more than one match delete all matching records if all is True, otherwise throws TooManyRecordsException. """ return self.zone.delete_cname(name, identifier)
[docs] def delete_a(self, name, identifier=None, all=False): """ Delete an A record matching name and identifier from this Zone. Returns a Status object. If there is more than one match delete all matching records if all is True, otherwise throws TooManyRecordsException. """ return self.zone.delete_a(name, identifier, all) # vim: tabstop=4 shiftwidth=4 softtabstop=4
Read the Docs v: latest
Versions
latest
Downloads
PDF
HTML
Epub
On Read the Docs
Project Home
Builds

Free document hosting provided by Read the Docs.