예제 #1
0
 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
예제 #2
0
 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
예제 #3
0
 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
예제 #4
0
 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'))
예제 #5
0
 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
예제 #6
0
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
예제 #7
0
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
예제 #8
0
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))
예제 #9
0
 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'))
예제 #10
0
 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'))
예제 #11
0
 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))
예제 #12
0
 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
예제 #13
0
 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'))
예제 #14
0
 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'))
예제 #15
0
  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))
예제 #16
0
 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
예제 #17
0
 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
예제 #18
0
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))
예제 #19
0
 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))
예제 #20
0
 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'))
예제 #21
0
 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))
예제 #22
0
 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
예제 #23
0
 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))
예제 #24
0
 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))