diff --git a/README.md b/README.md index 3c0ad00..6bbbbf4 100644 --- a/README.md +++ b/README.md @@ -46,3 +46,4 @@ currently implemented providers: - `hetzner` - `http` - `porkbun` (with secrets `porkbun.apikey` and `porkbun.secretapikey`) +- `he` ( hurricane electric ) diff --git a/nyacme/handlers/__init__.py b/nyacme/handlers/__init__.py index c62b352..fdc218f 100644 --- a/nyacme/handlers/__init__.py +++ b/nyacme/handlers/__init__.py @@ -1,10 +1,12 @@ from .cloudflare import CloudflareHandler +from .he import HEHandler from .hetzner import HetznerHandler from .http import HTTPHandler from .porkbun import PorkbunHandler __all__ = [ 'CloudflareHandler', + 'HEHandler', 'HetznerHandler', 'HTTPHandler', 'PorkbunHandler', diff --git a/nyacme/handlers/he.py b/nyacme/handlers/he.py new file mode 100644 index 0000000..e531821 --- /dev/null +++ b/nyacme/handlers/he.py @@ -0,0 +1,41 @@ +import urllib.parse +import urllib.request +from typing import Any + +from ..config import Config +from .base import Handler + + +class HEHandler(Handler): + nameservers = ['ns1.he.net', 'ns2.he.net', 'ns3.he.net', 'ns4.he.net', 'ns5.he.net'] + + def __init__(self, zone_name: str, config: Config, token: str) -> None: + super().__init__(zone_name, config, token) + self.password = config.get_secret('he') + + def set_record(self, record_name: str, value: str) -> Any: + full_record_name = record_name + '.' + self.zone + req = urllib.request.Request('https://dyn.dns.he.net/nic/update') + data = { + 'hostname': full_record_name, + 'password': self.password, + 'txt': value, + } + req.data = urllib.parse.urlencode(data).encode('utf-8') + req.add_header('Content-Type', 'application/x-www-form-urlencoded') + req.method = 'POST' + try: + with urllib.request.urlopen(req) as f: + return f.read() + except urllib.error.HTTPError as ex: + self.log.error('cannot set the record %s: %s', record_name, ex) + res = ex.fp.read().decode('utf-8') + raise Exception(res) + + def create(self, record_name: str, record_value: str) -> None: + self.log.info('creating %s with value %s', record_name, record_value) + self.set_record(record_name, record_value) + + def remove(self, record_name: str) -> None: + self.log.info('resetting %s', record_name) + self.set_record(record_name, '') diff --git a/nyacme/hook.py b/nyacme/hook.py index d25cafb..0f3cd1a 100644 --- a/nyacme/hook.py +++ b/nyacme/hook.py @@ -6,7 +6,7 @@ from itertools import chain import dns.resolver from .config import read_config -from .handlers import CloudflareHandler, HetznerHandler, HTTPHandler, PorkbunHandler +from .handlers import CloudflareHandler, HEHandler, HetznerHandler, HTTPHandler, PorkbunHandler logging.basicConfig(level=logging.INFO, format='> [%(levelname)s] %(name)s: %(message)s') log = logging.getLogger('nyacme_hook') @@ -14,6 +14,7 @@ log = logging.getLogger('nyacme_hook') handlers = { 'cloudflare': CloudflareHandler, + 'he': HEHandler, 'hetzner': HetznerHandler, 'http': HTTPHandler, 'porkbun': PorkbunHandler,