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("getDomainReordId: 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 if len(remoteRecordList) > 1: DDNSUtils.err( "Duplicate domain records set in Aliyun: (sub_domain: %s, domain: %s)" % (subDomain, domain)) return None return remoteRecordList[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)) return id
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("getDomainReordId: 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,e: DDNSUtils.err("Failed to get domain record id from {0}".format(recordInfo)) DDNSUtils.err("Exception:\n{0}".format(e)) return id
def __init__(self, config): self.config = config self.resolver = YunResolver(self.config.access_id, self.config.access_key, self.config.debug) self.local_record_list = self.get_local_record_list()
class DDNSDomainRecordManager(object): """ Manager class used to manage local domain record and remote domain records """ def __init__(self, config): self.config = config self.resolver = YunResolver(self.config.access_id, self.config.access_key, self.config.debug) self.local_record_list = self.get_local_record_list() def get_local_record_list(self): """ Create local domain record objectes based on local config info :return: list of LocalDomainRecord objects """ local_record_list = [] for section in self.config.get_domain_record_sections(): try: local_record = LocalDomainRecord(self.config, section) except ValueError: continue local_record_list.append(local_record) return local_record_list def find_local_record(self, remote_record): """ Find LocalDomainRecord based on RemoteDomainRecord :param RemoteDomainRecord :return: LocalDomainRecord or None """ for local_record in self.local_record_list: if all( getattr(local_record, attr) == getattr( remote_record, attr) for attr in ('domainname', 'rr', 'type')): return local_record return None 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 def update(self, remote_record, current_public_ip, record_type='A'): """ Update RemoteDomainRecord 's value to current public IP on Aliyun server :param RemoteDomainRecord: :param current public IP :return: True or False """ return self.resolver.update_domain_record( remote_record.recordid, rr=remote_record.rr, record_value=current_public_ip, record_type=record_type)
class DDNSDomainRecordManager(object): """ Manager class used to manage local domain record and remote domain records """ def __init__(self, config): self.config = config self.resolver = YunResolver(self.config.access_id, self.config.access_key, self.config.debug) self.local_record_list = self.get_local_record_list() def get_local_record_list(self): """ Create local domain record objectes based on local config info :return: list of LocalDomainRecord objects """ local_record_list = [] for section in self.config.get_domain_record_sections(): try: local_record = LocalDomainRecord(self.config, section) except ValueError: continue local_record_list.append(local_record) return local_record_list def find_local_record(self, remote_record): """ Find LocalDomainRecord based on RemoteDomainRecord :param RemoteDomainRecord :return: LocalDomainRecord or None """ for local_record in self.local_record_list: if all(getattr(local_record, attr) == getattr(remote_record, attr) for attr in ('domainname', 'rr', 'type')): return local_record return None 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 def update(self, remote_record, current_public_ip): """ Update RemoteDomainRecord 's value to current public IP on Aliyun server :param RemoteDomainRecord: :param current public IP :return: True or False """ return self.resolver.update_domain_record(remote_record.recordid, rr=remote_record.rr, record_value=current_public_ip)
def __init__(self, config): self.config = config self.resolver = YunResolver(self.config.accessId, self.config.accessKey, self.config.debug)
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