# 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(proxyserveruserNamepasswordaddressesFromaddressTo):
    """
    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=usernamepassword=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.reffilter="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' % (recordRefe.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(proxyserverusernamepasswordaddressesFromaddressTo):
        # Script ran successfully
        exit(0)
    else:
        exit(1)