92 lines
2.7 KiB
Python
92 lines
2.7 KiB
Python
from typing import Optional
|
|
import tomllib
|
|
import logging
|
|
import sys
|
|
import os
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
class Config:
|
|
post_acquire: list[str]
|
|
certificates: list[str]
|
|
domains: dict[str, str]
|
|
secrets: dict[str, str]
|
|
acme_path: str
|
|
|
|
def find_zone(self, domain: str) -> str:
|
|
parts = domain.split('.')
|
|
for i in range(len(parts)-1):
|
|
zone = '.'.join(parts[i:])
|
|
if zone in self.domains:
|
|
return zone
|
|
log.error('could not find zone for domain %s', domain)
|
|
sys.exit(1)
|
|
|
|
def get_handler(self, domain: str) -> str:
|
|
if domain in self.domains:
|
|
return self.domains[domain]
|
|
raise Exception(f'domain {domain} not found in the config')
|
|
|
|
def get_secret(self, handler: str) -> str:
|
|
return self.secrets[handler]
|
|
|
|
|
|
def read_config(path: Optional[str]) -> Config:
|
|
if not path:
|
|
# should be here only when running from hook
|
|
path = os.getenv('NYACME_CONFIG', '/etc/nyacme.toml')
|
|
|
|
with open(path, 'rb') as file:
|
|
raw_conf = tomllib.load(file)
|
|
|
|
for key in raw_conf:
|
|
if key not in ('domains', 'secrets', 'post_acquire', 'acme_path', 'certificates'):
|
|
log.warning('unknown config key: %s', key)
|
|
|
|
c = Config()
|
|
|
|
if 'domains' not in raw_conf:
|
|
log.error('missing "domains"')
|
|
sys.exit(1)
|
|
|
|
for k, v in raw_conf['domains'].items():
|
|
assert isinstance(k, str), f'domain "{k}" is not a string'
|
|
assert isinstance(v, str), f'domain "{k}" handler {v} is not a string'
|
|
|
|
c.domains = raw_conf['domains']
|
|
|
|
if 'secrets' not in raw_conf:
|
|
log.error('missing "secrets"')
|
|
sys.exit(1)
|
|
|
|
for k, v in raw_conf['secrets'].items():
|
|
assert isinstance(k, str), f'secret key "{k}" is not a string'
|
|
assert isinstance(v, str), f'secret "{k}" value {v} is not a string'
|
|
|
|
c.secrets = raw_conf['secrets']
|
|
|
|
post_acquire = []
|
|
if 'post_acquire' in raw_conf:
|
|
assert isinstance(raw_conf['post_acquire'], list), 'post_acquire is not a list'
|
|
for cmd in raw_conf['post_acquire']:
|
|
assert isinstance(cmd, str), 'post_acquire item has to be a string'
|
|
post_acquire.append(cmd)
|
|
|
|
c.post_acquire = post_acquire
|
|
|
|
if 'acme_path' in raw_conf:
|
|
c.acme_path = raw_conf['acme_path']
|
|
else:
|
|
c.acme_path = '/var/www/acme/.well-known/acme-challenge'
|
|
|
|
if 'certificates' not in raw_conf:
|
|
log.error('missing "certificates"')
|
|
sys.exit(1)
|
|
|
|
c.certificates = []
|
|
for cert in raw_conf['certificates']:
|
|
assert isinstance(cert, str), 'certificate should be a string'
|
|
c.certificates.append(cert)
|
|
|
|
return c
|