def makePutContext(self, name, zone): ret = super(Driver, self).makePutContext(name, zone) ret.zoneid = self._switchToZone(name) for record in ret.newrecords: if record.rclass != 'IN': raise api.UnsupportedRecordType( _( 'DomainMonster does not support non-"IN" record classes: {!r}', (record, ))) if record.ttl != 14400: raise api.UnsupportedRecordType( _('DomainMonster does not support non-4 hour TTLs: {!r}', (record, ))) # update the faked serial-tracking record... # TODO: it should only do this if there were actual changes... srec = None for record in ret.records: if record.type == 'TXT' and record.name == '_dnssync.' + ret.name: srec = record break for record in ret.newrecords: if record.type == 'TXT' and record.name == '_dnssync.' + ret.name: if srec is not None and record.content == srec.content: record.content = self._bumpSerial(record) break else: ret.newrecords.append( api.Record(name='_dnssync.' + ret.name, ttl=14400, rclass='IN', type='TXT', content=self._bumpSerial(srec))) return ret
def makePutContext(self, name, zone): ret = super(Driver, self).makePutContext(name, zone) ret.zoneid = self._switchToZone(name) for record in ret.newrecords: if record.rclass != 'IN': raise api.UnsupportedRecordType( _('DomainMonster does not support non-"IN" record classes: {!r}', (record,))) if record.ttl != 14400: raise api.UnsupportedRecordType( _('DomainMonster does not support non-4 hour TTLs: {!r}', (record,))) # update the faked serial-tracking record... # TODO: it should only do this if there were actual changes... srec = None for record in ret.records: if record.type == 'TXT' and record.name == '_dnssync.' + ret.name: srec = record break for record in ret.newrecords: if record.type == 'TXT' and record.name == '_dnssync.' + ret.name: if srec is not None and record.content == srec.content: record.content = self._bumpSerial(record) break else: ret.newrecords.append(api.Record( name='_dnssync.' + ret.name, ttl=14400, rclass='IN', type='TXT', content=self._bumpSerial(srec))) return ret
def _switchToZone(self, name): if name not in self._zones(): raise api.DomainNotFound( _('this ZoneEdit account does not manage domain "{}"', name)) resp = self.session.get( self.BASEURL + '/manage/domains/zone/index.php', params=dict(LOGIN=reldom(name))) if not resp.status_code == 200 \ or not resp.url.startswith(self.BASEURL + '/manage/domains/zone/index.php?'): raise api.DriverError(_('unknown/unexpected switch-zone response')) return resp.text
def _login(self): resp = self._session.get(self.BASEURL + '/clientarea.php') data = aadict(parser.extract_authdata(resp.text)).update({ 'username' : self.params.username, 'password' : self.params.password, }) resp = self._session.post( self.BASEURL + '/dologin.php', allow_redirects=False, data=dict(data)) if not resp.is_redirect \ or resp.headers['location'] != '/clientarea.php': if 'incorrect' in resp.headers['location']: raise api.AuthenticationError( _('invalid Registerly account username and/or password')) raise api.AuthenticationError( _('unknown/unexpected login response'))
def __init__(self, *args, **kw): super(Driver, self).__init__(*args, **kw) for attr in ('username', 'password'): if not self.params.get(attr): raise api.ConfigurationError( _('required parameter "{}" missing', attr)) self._session = None
def reg2api(record, name): record = aadict(record) # reg: {'rid':'55026','zid':'4442','domainid':'12345','type':'A', # 'name':'fh3.example.ly','ttl':'14400','content':'10.11.12.237',} ret = api.Record( name = absdom(record.name), rclass = 'IN', ttl = int(record.ttl), **morph.pick(record, 'rid', 'zid', 'domainid', 'type', 'content')) if ret.type not in api.Record.TYPES: raise api.DriverError( _('unknown/unexpected Registerly record type: "{}"', ret.type)) if ret.type in (api.Record.TYPE_MX, api.Record.TYPE_CNAME, api.Record.TYPE_NS): ret.update(content = absdom(ret.content)) if ret.type == api.Record.TYPE_SOA: # there's stuff missing!... content form should be: # {root} {contact} {serial} {refresh} {retry} {expire} {minttl} # but is comming back as: # ns1.libyanspider.com support.libyanspider.com 0 # so fetching from DNS... ugh. return ret.update(content = regGetSoaContent(name)) if ret.type == api.Record.TYPE_MX: return ret.update(priority = int(record.prio)) if ret.type == api.Record.TYPE_CNAME: return ret.update(content = absdom(ret.content)) # TODO: verify api.Record.TYPE_SRV... # TODO: verify api.Record.TYPE_NAPTR... # todo: Registerly also supports "PTR" and "URL" records... hm... return ret
def reg2api(record, name): record = aadict(record) # reg: {'rid':'55026','zid':'4442','domainid':'12345','type':'A', # 'name':'fh3.example.ly','ttl':'14400','content':'10.11.12.237',} ret = api.Record(name=absdom(record.name), rclass='IN', ttl=int(record.ttl), **morph.pick(record, 'rid', 'zid', 'domainid', 'type', 'content')) if ret.type not in api.Record.TYPES: raise api.DriverError( _('unknown/unexpected Registerly record type: "{}"', ret.type)) if ret.type in (api.Record.TYPE_MX, api.Record.TYPE_CNAME, api.Record.TYPE_NS): ret.update(content=absdom(ret.content)) if ret.type == api.Record.TYPE_SOA: # there's stuff missing!... content form should be: # {root} {contact} {serial} {refresh} {retry} {expire} {minttl} # but is comming back as: # ns1.libyanspider.com support.libyanspider.com 0 # so fetching from DNS... ugh. return ret.update(content=regGetSoaContent(name)) if ret.type == api.Record.TYPE_MX: return ret.update(priority=int(record.prio)) if ret.type == api.Record.TYPE_CNAME: return ret.update(content=absdom(ret.content)) # TODO: verify api.Record.TYPE_SRV... # TODO: verify api.Record.TYPE_NAPTR... # todo: Registerly also supports "PTR" and "URL" records... hm... return ret
def api2ze(record, name): ret = aadict(host=record.name, ttl=str(record.ttl)) if ret.host == name: ret.host = '@' elif ret.host.endswith('.' + name): ret.host = ret.host[:- len(name) - 1] if record.type == api.Record.TYPE_SOA: return aadict( zip(['refresh', 'retry', 'expire', 'ttl'], record.content.split()[-4:])) if record.type == api.Record.TYPE_NS: ret.update(server=record.content) if ret.server == 'local.zoneedit.': ret.server = 'LOCAL' return ret if record.type == api.Record.TYPE_MX: ret.update(server=record.content, pref=record.priority) if ret.server == 'local.zoneedit.': ret.server = 'LOCAL' return ret if record.type in (api.Record.TYPE_A, api.Record.TYPE_AAAA): ret.update(ip=record.content) if ret.ip == '0.0.0.0': ret.ip = 'PARK' return ret if record.type == api.Record.TYPE_CNAME: return ret.update(alias=record.content) if record.type == api.Record.TYPE_TXT: return ret.update(txt=record.content) raise ValueError( _('unknown/unexpected/unimplemented ZoneEdit record type "{}"', record.type))
def _login(self): resp = self._session.post(self.BASEURL + '/login/', allow_redirects=False, data={ 'action': 'dologin', 'username': self.params.username, 'password': self.params.password, }) if not resp.is_redirect \ or resp.headers['location'] != self.BASEURL + '/members/': if 'Invalid Email Address or Password' in resp.text: raise api.AuthenticationError( _('invalid DomainMonster account username and/or password') ) raise api.AuthenticationError( _('unknown/unexpected login response'))
def _login(self): resp = self._session.post( self.BASEURL + '/login/', allow_redirects = False, data = { 'action' : 'dologin', 'username' : self.params.username, 'password' : self.params.password, }) if not resp.is_redirect \ or resp.headers['location'] != self.BASEURL + '/members/': if 'Invalid Email Address or Password' in resp.text: raise api.AuthenticationError( _('invalid DomainMonster account username and/or password')) raise api.AuthenticationError( _('unknown/unexpected login response'))
def _postDnsAction(self, record, action, data): resp = self.session.post(self.BASEURL + '/members/managedns/', data=data) ret = parser.evaluateResponse(resp.text) if ret.code != 200: raise api.DriverError( _('could not {} record {}/{}: {}', action, record.name, record.type, ret.message))
def makePutContext(self, name, zone): ret = super(Driver, self).makePutContext(name, zone) ret.zoneid = self._zones()[name] for name, ttl, rdata in zone.iterate_rdatas(): if dns.rdataclass.to_text(rdata.rdclass) != 'IN': raise api.UnsupportedRecordType( _('PowerdDNS does not support non-"IN" record classes: {!r}', (name, ttl, rdata))) return ret
def _login(self): resp = self._session.get(self.BASEURL + '/clientarea.php') data = aadict(parser.extract_authdata(resp.text)).update({ 'username': self.params.username, 'password': self.params.password, }) resp = self._session.post(self.BASEURL + '/dologin.php', allow_redirects=False, data=dict(data)) if not resp.is_redirect \ or resp.headers['location'] != '/clientarea.php': if 'incorrect' in resp.headers['location']: raise api.AuthenticationError( _('invalid Registerly account username and/or password')) raise api.AuthenticationError( _('unknown/unexpected login response'))
def _login(self): resp = self._session.get(self.BASEURL + '/login.php') data = aadict(parser.extract_authdata(resp.text)).update({ 'login.x' : '27', 'login.y' : '8', 'login_user' : self.params.username, 'login_pass' : self.params.password, }) data.login_hash = md5(data.login_user + md5(data.login_pass) + data.login_chal) resp = self._session.post( self.BASEURL + '/home/', allow_redirects=False, data=dict(data)) if not resp.is_redirect \ or resp.headers['location'] != self.BASEURL + '/manage/domains/': if 'Invalid username-password combination' in resp.text: raise api.AuthenticationError( _('invalid ZoneEdit account username and/or password')) raise api.AuthenticationError( _('unknown/unexpected login response'))
def updateRecord(self, context, record, newrecord): # PowerDNS does not seem to support absolute DNS names... ugh. name = reldom(newrecord.name) content = ' '.join([reldom(comp) for comp in newrecord.content.split(' ')]) resp = self.client.service.updateRecord( record.id, name, newrecord.type, content, newrecord.ttl, newrecord.priority or 0) if resp.code != 100: raise api.DriverError( _('could not update record {}/{}: {}', newrecord.name, newrecord.type, resp.description))
def _switchToZone(self, name): zones = self._zones() if name not in zones: raise api.DomainNotFound( _('this DomainMonster account does not manage domain "{}"', name)) zid = zones[name] resp = self.session.post(self.BASEURL + '/members/manage/', data=dict( setdm = '1', d = zid, frompop = '0', gons = '0', goar = '0', golk = '0', gopr = '0', )) # todo: check response... return zid
def _switchToZone(self, name): zones = self._zones() if name not in zones: raise api.DomainNotFound( _('this DomainMonster account does not manage domain "{}"', name)) zid = zones[name] resp = self.session.post(self.BASEURL + '/members/manage/', data=dict( setdm='1', d=zid, frompop='0', gons='0', goar='0', golk='0', gopr='0', )) # todo: check response... return zid
def ze2api(record, name): if not record.host or record.host == '@': record.host = absdom(name) else: record.host = absdom(record.host + '.' + name) ret = api.Record( name=record.host, rclass='IN', type=record.rtype, ttl=dur2sec(record.ttl)) if record.zone_id: ret.zoneedit_id = record.zone_id if record.rtype == api.Record.TYPE_SOA: return ret.update( ttl = 3600, content = 'dns0.zoneedit.com. zone.zoneedit.com. {serial} {refresh} {retry} {expire} {minttl}'.format( serial = zeGetSerial(name) or int(time.time()), refresh = dur2sec(record.refresh), retry = dur2sec(record.retry), expire = dur2sec(record.expire), minttl = dur2sec(record.ttl), )) if record.rtype == api.Record.TYPE_NS: if record.server == 'LOCAL': record.server = 'local.zoneedit.' return ret.update(content=record.server) if record.rtype == api.Record.TYPE_MX: if record.server == 'LOCAL': record.server = 'local.zoneedit.' return ret.update(priority=dur2sec(record.pref), content=absdom(record.server)) if record.rtype == api.Record.TYPE_A: if record.ip == 'PARK': record.ip = '0.0.0.0' return ret.update(content=record.ip) if record.rtype == api.Record.TYPE_AAAA: if record.ip == 'PARK': record.ip = '::0' return ret.update(content=record.ip) if record.rtype == api.Record.TYPE_CNAME: return ret.update(content=absdom(record.alias)) if record.rtype == api.Record.TYPE_TXT: return ret.update(content=record.txt) raise ValueError( _('unknown/unexpected/unimplemented ZoneEdit record type "{}"', record.rtype))
def _getDomainID(self, name): for key, val in self._zones().items(): if val == name: return key raise api.DomainNotFound( _('this Registerly account does not manage domain "{}"', name))
def __init__(self, *args, **kw): super(Driver, self).__init__(*args, **kw) self.client = Client(self.params.apikey) if not self.params.apikey: raise api.ConfigurationError(_('required parameter "apikey" missing'))
def __init__(self, *args, **kw): super(Driver, self).__init__(*args, **kw) for attr in ('username', 'password'): if not self.params.get(attr): raise api.ConfigurationError(_('required parameter "{}" missing', attr)) self._session = None
def deleteRecord(self, context, record): resp = self.client.service.deleteRecordById(record.id) if resp.code != 100: raise api.DriverError( _('could not delete record {}/{}: {}', record.name, record.type, resp.description))