route53-migrate-zone now handles existing records gracefully.
This commit is contained in:
parent
231f0f51ba
commit
8a32546a1c
|
@ -20,13 +20,23 @@ def commit_record_changeset(to_zone_record_changeset):
|
||||||
sys.stdout.write("The error message given was: " + error.error_message + ".\n")
|
sys.stdout.write("The error message given was: " + error.error_message + ".\n")
|
||||||
exit(69)
|
exit(69)
|
||||||
|
|
||||||
|
|
||||||
|
def diff_record(record_a, record_a_object, record_b, record_b_object):
|
||||||
|
compare_values = ["type", "ttl", "resource_records", "alias_hosted_zone_id", "alias_dns_name", "identifier", "weight", "region"]
|
||||||
|
diff_record_result = False
|
||||||
|
|
||||||
|
for value in compare_values:
|
||||||
|
if getattr(record, value) != getattr(to_zone_existing_resource_record_dict[record.name], value):
|
||||||
|
diff_record_result = True
|
||||||
|
return diff_record_result
|
||||||
|
|
||||||
app_name = os.path.basename(__file__)
|
app_name = os.path.basename(__file__)
|
||||||
config = ConfigParser.ConfigParser()
|
config = ConfigParser.ConfigParser()
|
||||||
config.read('config.ini')
|
config.read('config.ini')
|
||||||
#functions: newzone, new account, newzone and newaccount
|
#functions: currently supports newzone - the functions are set automatically by the route53-migrate-zone script
|
||||||
functions = ["newzone", "newaccount"]
|
functions = []
|
||||||
|
|
||||||
#these user credentials should be read-only
|
#the from_zone user credentials should be read-only
|
||||||
from_access_key = config.get("from_zone_values", "from_access_key")
|
from_access_key = config.get("from_zone_values", "from_access_key")
|
||||||
from_secret_key = config.get("from_zone_values", "from_secret_key")
|
from_secret_key = config.get("from_zone_values", "from_secret_key")
|
||||||
from_zone_name = config.get("from_zone_values", "from_zone_name")
|
from_zone_name = config.get("from_zone_values", "from_zone_name")
|
||||||
|
@ -37,15 +47,17 @@ to_zone_name = config.get("to_zone_values", "to_zone_name")
|
||||||
#best would be to retreive the to_zone_id using to_zone_name
|
#best would be to retreive the to_zone_id using to_zone_name
|
||||||
to_zone_id = config.get("to_zone_values", "to_zone_id")
|
to_zone_id = config.get("to_zone_values", "to_zone_id")
|
||||||
|
|
||||||
|
record_types_to_migrate = ["A", "CNAME", "MX", "TXT"]
|
||||||
|
|
||||||
|
if from_zone_name != to_zone_name:
|
||||||
|
print app_name + " will rewrite domain names ending in \"" + from_zone_name + "\" to domain names ending in \"" + to_zone_name + "\""
|
||||||
|
functions.append("newzone")
|
||||||
|
|
||||||
#creates Route53Connection Object
|
#creates Route53Connection Object
|
||||||
from_connection = boto.route53.Route53Connection(aws_access_key_id=from_access_key, aws_secret_access_key=from_secret_key)
|
from_connection = boto.route53.Route53Connection(aws_access_key_id=from_access_key, aws_secret_access_key=from_secret_key)
|
||||||
to_connection = boto.route53.Route53Connection(aws_access_key_id=to_access_key, aws_secret_access_key=to_secret_key)
|
to_connection = boto.route53.Route53Connection(aws_access_key_id=to_access_key, aws_secret_access_key=to_secret_key)
|
||||||
#creates a set of changes to be delivered to Route53
|
|
||||||
to_zone_record_changeset = boto.route53.record.ResourceRecordSets(to_connection, to_zone_id)
|
|
||||||
|
|
||||||
record_types_to_migrate = ["A", "CNAME", "MX", "TXT"]
|
#create connection to from_zone
|
||||||
|
|
||||||
#print out all records
|
|
||||||
try:
|
try:
|
||||||
from_zone = from_connection.get_zone(from_zone_name)
|
from_zone = from_connection.get_zone(from_zone_name)
|
||||||
except boto.route53.exception.DNSServerError, error:
|
except boto.route53.exception.DNSServerError, error:
|
||||||
|
@ -53,9 +65,37 @@ except boto.route53.exception.DNSServerError, error:
|
||||||
sys.stdout.write("The error message given was: " + error.error_message + ".\n")
|
sys.stdout.write("The error message given was: " + error.error_message + ".\n")
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
|
#create connection to to_zone
|
||||||
|
try:
|
||||||
|
to_zone = to_connection.get_zone(to_zone_name)
|
||||||
|
except boto.route53.exception.DNSServerError, error:
|
||||||
|
sys.stdout.write("An error occured when attempting to create a connection to AWS.\n")
|
||||||
|
sys.stdout.write("The error message given was: " + error.error_message + ".\n")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
#creates ResourceRecordSets object named from_zone_records (ResourceRecordSets = a collection of resource records)
|
||||||
from_zone_records = from_zone.get_records()
|
from_zone_records = from_zone.get_records()
|
||||||
#resource_record_dict will be used to store all resource records
|
#creates ResourceRecordSets object named to_zone_records (ResourceRecordSets = a collection of resource records)
|
||||||
|
to_zone_records = to_zone.get_records()
|
||||||
|
|
||||||
|
#resource_record_dict will be used to store all resource records that should be transferred
|
||||||
resource_record_dict = {}
|
resource_record_dict = {}
|
||||||
|
#to_zone_existing_resource_record_dict will be used to store all resource records that should be transferred
|
||||||
|
to_zone_existing_resource_record_dict = {}
|
||||||
|
|
||||||
|
#creates a set of changes to be delivered to Route53
|
||||||
|
to_zone_record_changeset = boto.route53.record.ResourceRecordSets(to_connection, to_zone_id)
|
||||||
|
|
||||||
|
for record in to_zone_records:
|
||||||
|
to_zone_existing_resource_record_dict[record.name] = record
|
||||||
|
|
||||||
|
#counts of records - should be replaced by dictionary
|
||||||
|
uncommitted_change_elements = 0
|
||||||
|
processed_record_count = 0
|
||||||
|
migrated_record_count = 0
|
||||||
|
existing_records_in_to_zone_count = 0
|
||||||
|
identical_records_in_to_zone_count = 0
|
||||||
|
different_records_in_to_zone_count = 0
|
||||||
|
|
||||||
#get records from from_zone
|
#get records from from_zone
|
||||||
for record in from_zone_records:
|
for record in from_zone_records:
|
||||||
|
@ -64,15 +104,25 @@ for record in from_zone_records:
|
||||||
#print "Existing Record Name: " + record.name
|
#print "Existing Record Name: " + record.name
|
||||||
record.name = re.sub(from_zone_name, to_zone_name, record.name)
|
record.name = re.sub(from_zone_name, to_zone_name, record.name)
|
||||||
#print "Modified Record Name: " + record.name
|
#print "Modified Record Name: " + record.name
|
||||||
resource_record_dict[record.name] = boto.route53.record.Record(name=record.name, type=record.type, ttl=record.ttl, resource_records=record.resource_records, alias_hosted_zone_id=record.alias_hosted_zone_id, alias_dns_name=record.alias_dns_name, identifier=record.identifier, weight=record.weight, region=record.region)
|
#test if record exists in to_zone
|
||||||
|
if record.name in to_zone_existing_resource_record_dict:
|
||||||
#commit records to to_zone
|
existing_records_in_to_zone_count += 1
|
||||||
uncommitted_change_elements = 0
|
#compare records in from_domain and to_domain, store result as diff_result
|
||||||
examined_record_count = 0
|
diff_result = diff_record(record.name, record, record.name, to_zone_existing_resource_record_dict)
|
||||||
migrated_record_count = 0
|
if diff_result is True:
|
||||||
|
different_records_in_to_zone_count += 1
|
||||||
|
sys.stdout.write("Record \"" + record.name + "\" exists in both \"" + from_zone_name + "\" and \"" + to_zone_name + "\" and is different.\n")
|
||||||
|
elif diff_result is False:
|
||||||
|
identical_records_in_to_zone_count += 1
|
||||||
|
sys.stdout.write("Record \"" + record.name + "\" exists in both \"" + from_zone_name + "\" and \"" + to_zone_name + "\" and is identical.\n")
|
||||||
|
else:
|
||||||
|
sys.stdout.write("Diff of record " + record.name + " failed.\n")
|
||||||
|
exit(1)
|
||||||
|
else:
|
||||||
|
resource_record_dict[record.name] = boto.route53.record.Record(name=record.name, type=record.type, ttl=record.ttl, resource_records=record.resource_records, alias_hosted_zone_id=record.alias_hosted_zone_id, alias_dns_name=record.alias_dns_name, identifier=record.identifier, weight=record.weight, region=record.region)
|
||||||
|
|
||||||
for record in resource_record_dict:
|
for record in resource_record_dict:
|
||||||
examined_record_count += 1
|
processed_record_count += 1
|
||||||
#if record is an alias record we are not supporting yet
|
#if record is an alias record we are not supporting yet
|
||||||
if resource_record_dict[record].alias_dns_name is not None:
|
if resource_record_dict[record].alias_dns_name is not None:
|
||||||
sys.stdout.write("Record \"" + resource_record_dict[record].name + "\" is an alias record set and will not be migrated. " + app_name + " does not currently support alias record sets.\n")
|
sys.stdout.write("Record \"" + resource_record_dict[record].name + "\" is an alias record set and will not be migrated. " + app_name + " does not currently support alias record sets.\n")
|
||||||
|
@ -82,7 +132,7 @@ for record in resource_record_dict:
|
||||||
#DEBUG: print "Uncommitted Record Count:" + str(uncommitted_change_elements)
|
#DEBUG: print "Uncommitted Record Count:" + str(uncommitted_change_elements)
|
||||||
#if there are 99 uncomitted change elements than they must be committed - Amazon only accepts up to 99 change elements at a given time
|
#if there are 99 uncomitted change elements than they must be committed - Amazon only accepts up to 99 change elements at a given time
|
||||||
#if the number of examined records is equal to the number of records then we can commit as well - we are now done examing records
|
#if the number of examined records is equal to the number of records then we can commit as well - we are now done examing records
|
||||||
if uncommitted_change_elements >= 99 or examined_record_count == len(resource_record_dict):
|
if uncommitted_change_elements >= 99 or processed_record_count == len(resource_record_dict):
|
||||||
#DEBUG: print "Flushing Records:" + str(uncommitted_change_elements)
|
#DEBUG: print "Flushing Records:" + str(uncommitted_change_elements)
|
||||||
commit_record_changeset(to_zone_record_changeset)
|
commit_record_changeset(to_zone_record_changeset)
|
||||||
migrated_record_count += uncommitted_change_elements
|
migrated_record_count += uncommitted_change_elements
|
||||||
|
@ -93,5 +143,8 @@ for record in resource_record_dict:
|
||||||
print "Summary:"
|
print "Summary:"
|
||||||
print "Records Migrated from zone: \"" + from_zone_name + "\" to zone: \"" + from_zone_name + "\"."
|
print "Records Migrated from zone: \"" + from_zone_name + "\" to zone: \"" + from_zone_name + "\"."
|
||||||
print "Types of Records Selected for Migration: " + str(record_types_to_migrate) + "."
|
print "Types of Records Selected for Migration: " + str(record_types_to_migrate) + "."
|
||||||
print "Records Migrated: " + str(migrated_record_count) + "."
|
print "Records processed (records such as Alias records may be processed but not migrated): " + str(processed_record_count)
|
||||||
print "Records Examined: " + str(examined_record_count) + "."
|
print "Records migrated: " + str(migrated_record_count) + "."
|
||||||
|
print "Records not migrated because they already exist in zone \"" + to_zone_name + "\": " + str(existing_records_in_to_zone_count)
|
||||||
|
print "Records that exist in both \"" + from_zone_name + "\" and \"" + to_zone_name + "\" and are identical: " + str(identical_records_in_to_zone_count)
|
||||||
|
print "Records that exist in both \"" + from_zone_name + "\" and \"" + to_zone_name + "\" and are different: " + str(different_records_in_to_zone_count)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user