Пример #1
0
    def syncFirstTime(self, localRecord, currentPublicIP):
        remoteRecord = self.matchRemoteDomainRecord(localRecord.domain, localRecord.subDomain, localRecord.type)
        if not remoteRecord:
            DDNSUtils.err("Failed to match remote domain record for {0}.{1}"
                          "".format(localRecord.subDomain, localRecord.domain))
            return False

        remoteRecordId = self.extractDomainRecordId(remoteRecord)
        if not remoteRecordId:
            DDNSUtils.err("Failed to extract domain id from remote domain record desc")
            return False

        # save domain record id for future reference
        if not self.config.save(localRecord.alias, "id", remoteRecordId):
            DDNSUtils.err("Failed to save domain record id to config file")
            return False

        remoteRecordValue = self.extractDomainRecordValue(remoteRecord)
        if not remoteRecordValue:
            DDNSUtils.err("Failed to extract domain value from remote domain record desc")
            return False

        # Now, check if domain record value is different with current public ip or not
        if currentPublicIP != remoteRecordValue or currentPublicIP != localRecord.value:
            return self.sync(localRecord, currentPublicIP)

        if self.config.debug:
            DDNSUtils.info("No change with domain record value on remote server, skip it...")
        return True
Пример #2
0
    def fetch_remote_record(self, local_record):
        """
        Fetch RemoteDomainReord from Aliyun server by using LocalDomainRecord info

        :param    LocalDomainRecord
        :return:  RemoteDomainRecord or None
        """
        # Aliyun use fuzzy matching pattern for RR and type keyword
        fuzzy_matched_list = self.resolver.describe_domain_records(local_record.domainname,
                                                                   rr_keyword=local_record.rr,
                                                                   type_keyword=local_record.type)
        if not fuzzy_matched_list:
            DDNSUtils.err("Failed to fetch remote DomainRecords.")
            return None

        exact_matched_list = []
        check_keys = ('DomainName', 'RR', 'Type')
        for rec in fuzzy_matched_list:
            if all(rec.get(key, None) == getattr(local_record, key.lower()) for key in check_keys):
                exact_matched_list.append(rec)

        if not exact_matched_list:
            return None

        if len(exact_matched_list) > 1:
            DDNSUtils.err("Duplicate DomainRecord in Aliyun: {rec.subdomain}.{rec.domainname}"
                          .format(rec=local_record))
            return None

        try:
            remote_record = RemoteDomainRecord(exact_matched_list[0])
        except Exception as ex:
            raise ex

        return remote_record
Пример #3
0
 def extractDomainRecordValue(self, recordInfo):
     value = None
     try:
         value = recordInfo['Value']
     except Exception,e:
         DDNSUtils.err("Failed to get domain record value from {0}".format(recordInfo))
         DDNSUtils.err("Exception:\n{0}".format(e))
Пример #4
0
    def validate(self):
        if not self.accessId or not self.accessKey:
            DDNSUtils.err_and_exit("Invalid access_id or access_key in config file.")

        for rec in self.localDomainRecordList:
            if not rec.domain or not rec.subDomain or not rec.type:
                DDNSUtils.err_and_exit("Invalid domain or sub_domain or type in config file.")
Пример #5
0
 def extractDomainRecordId(self, recordInfo):
     id = None
     try:
         id = recordInfo['RecordId']
     except Exception,e:
         DDNSUtils.err("Failed to get domain record id from {0}".format(recordInfo))
         DDNSUtils.err("Exception:\n{0}".format(e))
Пример #6
0
    def getRemoteDomainRecordList(self, domain):
        if not domain:
            DDNSUtils.err("getDomainReordId: You must specify domain name.")
            return None

        # try get domain record id
        domainRecordList = self.resolver.describeDomainRecords(domain)
        return domainRecordList
Пример #7
0
    def save(self, section, option, value):
        self.configParser.set(section, option, value)
        try:
            with open(self.configFile, 'wb') as cf:
                self.configParser.write(cf)
        except:
            DDNSUtils.err("Failed to save the config value")
            return False

        return True
Пример #8
0
    def sync(self, localRecord, currentPublicIP):
        if not localRecord.id:
            DDNSUtils.err("You must specify domain record id.")
            return False

        if not localRecord.subDomain:
            DDNSUtils.err("You must specify subdomain name.")
            return False

        if not currentPublicIP:
            DDNSUtils.err("Current public ip is empty.")
            return False

        result = self.resolver.updateDomainRecord(localRecord.id, rr=localRecord.subDomain, value=currentPublicIP)
        # if we update domain record successfully, save current domain record value to config file
        if result is True:
            if not self.config.save(localRecord.alias, "value", currentPublicIP):
                DDNSUtils.err("Failed to save domain record value to config file")
                return False

        return result
Пример #9
0
    def matchRemoteDomainRecord(self, domain, subDomain, type):
        if not domain:
            DDNSUtils.err("matchRemoteDomainRecord: You must specify domain.")
            return None

        if not subDomain:
            DDNSUtils.err("matchRemoteDomainRecord: You must specify sub_domain.")
            return None

        if not type:
            DDNSUtils.err("matchRemoteDomainRecord: You must specify type.")
            return None

        remoteRecordList = self.resolver.describeDomainRecords(domain, rrKeyword=subDomain, typeKeyword=type)
        if not remoteRecordList:
            return None

        return remoteRecordList[0]
Пример #10
0
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
"""
import sys
from helper import DDNSHelper
from utils import DDNSUtils
from config import DDNSConfig

CONF_FILE = "/etc/ddns.conf"

if __name__ == "__main__":
    config = DDNSConfig(CONF_FILE)
    config.validate()

    utils = DDNSUtils(config.debug)
    helper = DDNSHelper(config)

    # get current public ip
    currentPublicIP = utils.getCurrentPublicIP()
    if not currentPublicIP:
        DDNSUtils.err_and_exit("Failed to get current public ip")

    for localRecord in config.localDomainRecordList:
        # if we don't have domain record's id in config file, then we never sync to server before
        if not localRecord.id or not localRecord.value:
            result = helper.syncFirstTime(localRecord,currentPublicIP)
            if result is False:
                DDNSUtils.err_and_exit("Failed doing the first time sync for record:{0}".format(localRecord.alias))
                continue
Пример #11
0
def main():
    """
    Main routine
    """
    config = DDNSConfig()
    record_manager = DDNSDomainRecordManager(config)

    # get current public ip for this server
    if config.pifn_enable:
        current_public_ip = DDNSUtils.get_interface_address(
            config.pifn_interface)
    else:
        current_public_ip = DDNSUtils.get_current_public_ip()
    if not current_public_ip:
        DDNSUtils.err_and_exit("Failed to get current public IP")

    for local_record in record_manager.local_record_list:
        if local_record.subdomain == '*':
            dns_resolved_ip = DDNSUtils.get_dns_resolved_ip(
                'xxx', local_record.domainname)
        else:
            dns_resolved_ip = DDNSUtils.get_dns_resolved_ip(
                local_record.subdomain, local_record.domainname)

        if local_record.type == "AAAA":
            current_ip = DDNSUtils.get_interface_ipv6_address(
                local_record.interface)
        else:
            current_ip = current_public_ip

        if current_ip == dns_resolved_ip:
            DDNSUtils.info("Skipped as no changes for DomainRecord" \
                           "[{rec.subdomain}.{rec.domainname}]".format(rec=local_record))
            continue

        # If current public IP doesn't equal to current DNS resolved ip, only in three cases:
        # 1. The new synced IP for remote record in Aliyun doesn't take effect yet
        # 2. remote record's IP in Aliyun server has changed
        # 3. current public IP is changed
        remote_record = record_manager.fetch_remote_record(local_record)
        if not remote_record:
            DDNSUtils.err("Failed finding remote DomainRecord" \
                          "[{rec.subdomain}.{rec.domainname}]".format(rec=local_record))
            continue

        if current_ip == remote_record.value:
            DDNSUtils.info("Skipped as we already updated DomainRecord" \
                           "[{rec.subdomain}.{rec.domainname}]".format(rec=local_record))
            continue

        # if we can fetch remote record and record's value doesn't equal to public IP
        sync_result = record_manager.update(remote_record, current_ip,
                                            local_record.type)

        if not sync_result:
            DDNSUtils.err("Failed updating DomainRecord" \
                          "[{rec.subdomain}.{rec.domainname}]".format(rec=local_record))
        else:
            DDNSUtils.info("Successfully updated DomainRecord" \
                           "[{rec.subdomain}.{rec.domainname}]".format(rec=local_record))
Пример #12
0
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
"""
import sys
from helper import DDNSHelper
from utils import DDNSUtils
from config import DDNSConfig

CONF_FILE = "./ddns.conf"

if __name__ == "__main__":
    config = DDNSConfig(CONF_FILE)
    config.validate()

    utils = DDNSUtils(config.debug)
    helper = DDNSHelper(config)

    # get current public ip
    currentPublicIP = utils.getCurrentPublicIP()
    if not currentPublicIP:
        DDNSUtils.err_and_exit("Failed to get current public ip")

    for localRecord in config.localDomainRecordList:
        # try to sync all record,
        if config.debug:
            DDNSUtils.info("current public ip is:{0}, cached ip is:{1}".format(currentPublicIP, localRecord.value))

        result = helper.sync(localRecord, currentPublicIP);

        if result is False:
Пример #13
0
def main():
    """
    Main routine
    """
    config = DDNSConfig()
    record_manager = DDNSDomainRecordManager(config)

    # get current public ip for this server
    current_public_ip = DDNSUtils.get_current_public_ip()
    if not current_public_ip:
        DDNSUtils.err_and_exit("Failed to get current public IP")

    for local_record in record_manager.local_record_list:
        dns_resolved_ip = DDNSUtils.get_dns_resolved_ip(local_record.subdomain,
                                                        local_record.domainname)

        if current_public_ip == dns_resolved_ip:
            DDNSUtils.info("Skipped as no changes for DomainRecord" \
                           "[{rec.subdomain}.{rec.domainname}]".format(rec=local_record))
            continue

        # If current public IP doesn't equal to current DNS resolved ip, only in three cases:
        # 1. The new synced IP for remote record in Aliyun doesn't take effect yet
        # 2. remote record's IP in Aliyun server has changed
        # 3. current public IP is changed
        remote_record = record_manager.fetch_remote_record(local_record)
        if not remote_record:
            DDNSUtils.err("Failed finding remote DomainRecord" \
                          "[{rec.subdomain}.{rec.domainname}]".format(rec=local_record))
            continue

        if current_public_ip == remote_record.value:
            DDNSUtils.info("Skipped as we already updated DomainRecord" \
                           "[{rec.subdomain}.{rec.domainname}]".format(rec=local_record))
            continue

        # if we can fetch remote record and record's value doesn't equal to public IP
        sync_result = record_manager.update(remote_record, current_public_ip)
        if not sync_result:
            DDNSUtils.err("Failed updating DomainRecord" \
                          "[{rec.subdomain}.{rec.domainname}]".format(rec=local_record))
        else:
            DDNSUtils.info("Successfully updated DomainRecord" \
                           "[{rec.subdomain}.{rec.domainname}]".format(rec=local_record))