# Copyright (C) 2014 Men & Mice
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#!/usr/bin/python
import suds
from soapCLI import mmSoap
NULL_REF = "{#0-#0}"
def modifyRecordData(proxy, server, userName, password, addressesFrom, addressTo):
"""
Function to change data for DNS records of type "A", that are being managed in a Men & Mice suite.
:param proxy: Address of the Men & Mice proxy service.
:param server: Address of the Men & Mice Central service.
:param username: User name to use to log into the suite.
:param password: User password.
:param addressesFrom: A list of addresses. If a DNS record is found with data matching an item in
the list, then the data will be changed to the value of 'addressTo'.
:param addressTo: Value to change DNS record data to.
"""
if addressTo in addressesFrom:
print "Address to update to, can not be in the list of addresses to update from."
return False
try:
cli = mmSoap(proxy=proxy,server=server,
username=username, password=password)
cli.login()
except suds.WebFault as e:
print "Error while logging into the Men & Mice suite: %s" % e.fault.faultstring
return False
arrayOfDNSRecordsToAdd = cli.create("ArrayOfDNSRecord")
dnsRecordsToRemove = cli.create("ArrayOfObjRef")
# Retrieve all master zones
(_, arrayOfDNSZone), (_, totalResults) = cli.GetDNSZones(filter="type:Master")
if totalResults == 0:
print "No DNS zones found."
return True
for dnsZone in arrayOfDNSZone.dnsZone:
# Fetch all A records from the zone
(_, arrayOfDNSRecord), (_, totalResults) = cli.GetDNSRecords(dnsZoneRef=dnsZone.ref, filter="type:^A$")
if totalResults > 0:
for dnsRecord in arrayOfDNSRecord.dnsRecord:
if dnsRecord.data in addressesFrom:
# Modify records to point to new server
dnsRecordsToRemove.ref.append(dnsRecord.ref)
dnsRecord.ref = None
dnsRecord.data = addressTo
arrayOfDNSRecordsToAdd.dnsRecord.append(dnsRecord)
if len(arrayOfDNSRecordsToAdd.dnsRecord) > 0:
# Create new records
(_, arrayOfDNSRecordRef), (_, addRecordArrayOfErrors) = cli.AddDNSRecords(dnsRecords=arrayOfDNSRecordsToAdd,
saveComment='Modifying DNS records to point to host "%s".' % addressTo)
if len(arrayOfDNSRecordRef.ref) > 0:
for recordRef in arrayOfDNSRecordRef.ref:
if recordRef == NULL_REF:
# Caused by a record that was not added due to some error
continue
try:
print "Added record:", cli.GetDNSRecord(dnsRecordRef=recordRef)
except suds.WebFault as e:
print 'Unable to retrieve record with ref "%s" due to the following error: %s' % (recordRef, e.fault.faultstring)
if hasattr(addRecordArrayOfErrors, "error") and len(addRecordArrayOfErrors.error) > 0:
print """One or more errors occurred while adding records: %s.
Old records will not be deleted. Please check manually and delete old records that were successfully migrated.""" % addRecordArrayOfErrors.error
return False
else:
# No errors came up during migration, we delete the old records
removeRecordErrors = cli.RemoveObjects(objRefs=dnsRecordsToRemove,
saveComment="Removing records that now point to host %s." % addressTo)
if len(removeRecordErrors) > 0:
print "The following errors occurred while removing old records:", removeRecordErrors
return False
else:
print "No matching records found."
return True
if __name__ == '__main__':
proxy = "proxy.example.com"
server = "central.example.com"
username = "administrator"
password = "secret"
addressesFrom = ["10.0.0.10", "10.1.1.11", "1.1.1.1"]
addressTo = "10.0.0.1"
if modifyRecordData(proxy, server, username, password, addressesFrom, addressTo):
# Script ran successfully
exit(0)
else:
exit(1)