コード例 #1
0
class DDNSHelper(object):
    def __init__(self, config):
        self.config = config
        self.resolver = YunResolver(self.config.accessId,
                                    self.config.accessKey, self.config.debug)

    def getRemoteDomainRecordList(self, domain):
        if not domain:
            DDNSUtils.err("getDomainRecordId: You must specify domain name.")
            return None

        # try get domain record id
        domainRecordList = self.resolver.describeDomainRecords(domain)
        return domainRecordList

    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]

    def extractDomainRecordId(self, recordInfo):
        id = None
        try:
            id = recordInfo['RecordId']
        except Exception as e:
            DDNSUtils.err(
                "Failed to get domain record id from {0}".format(recordInfo))
            DDNSUtils.err("Exception:\n{0}".format(e))

        return id

    def extractDomainRecordValue(self, recordInfo):
        value = None
        try:
            value = recordInfo['Value']
        except Exception as e:
            DDNSUtils.err("Failed to get domain record value from {0}".format(
                recordInfo))
            DDNSUtils.err("Exception:\n{0}".format(e))

        return value

    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

    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