summaryrefslogtreecommitdiffstats
path: root/test/modules/md/md_acme.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/modules/md/md_acme.py')
-rwxr-xr-xtest/modules/md/md_acme.py125
1 files changed, 125 insertions, 0 deletions
diff --git a/test/modules/md/md_acme.py b/test/modules/md/md_acme.py
new file mode 100755
index 0000000..36be347
--- /dev/null
+++ b/test/modules/md/md_acme.py
@@ -0,0 +1,125 @@
+import logging
+import os
+import shutil
+import subprocess
+import time
+from abc import ABCMeta, abstractmethod
+from datetime import datetime, timedelta
+from threading import Thread
+from typing import Dict
+
+from .md_env import MDTestEnv
+
+
+log = logging.getLogger(__name__)
+
+
+def monitor_proc(env: MDTestEnv, proc):
+ _env = env
+ proc.wait()
+
+
+class ACMEServer:
+ __metaclass__ = ABCMeta
+
+ @abstractmethod
+ def start(self):
+ raise NotImplementedError
+
+ @abstractmethod
+ def stop(self):
+ raise NotImplementedError
+
+ @abstractmethod
+ def install_ca_bundle(self, dest):
+ raise NotImplementedError
+
+
+class MDPebbleRunner(ACMEServer):
+
+ def __init__(self, env: MDTestEnv, configs: Dict[str, str]):
+ self.env = env
+ self.configs = configs
+ self._current = 'default'
+ self._pebble = None
+ self._challtestsrv = None
+ self._log = None
+
+ def start(self, config: str = None):
+ if config is not None and config != self._current:
+ # change, tear down and start again
+ assert config in self.configs
+ self.stop()
+ self._current = config
+ elif self._pebble is not None:
+ # already running
+ return
+ args = ['pebble', '-config', self.configs[self._current], '-dnsserver', ':8053']
+ env = {}
+ env.update(os.environ)
+ env['PEBBLE_VA_NOSLEEP'] = '1'
+ self._log = open(f'{self.env.gen_dir}/pebble.log', 'w')
+ self._pebble = subprocess.Popen(args=args, env=env,
+ stdout=self._log, stderr=self._log)
+ t = Thread(target=monitor_proc, args=(self.env, self._pebble))
+ t.start()
+
+ args = ['pebble-challtestsrv', '-http01', '', '-https01', '', '-tlsalpn01', '']
+ self._challtestsrv = subprocess.Popen(args, stdout=self._log, stderr=self._log)
+ t = Thread(target=monitor_proc, args=(self.env, self._challtestsrv))
+ t.start()
+ self.install_ca_bundle(self.env.acme_ca_pemfile)
+ # disable ipv6 default address, this gives trouble inside docker
+ end = datetime.now() + timedelta(seconds=5)
+ while True:
+ r = self.env.run(['curl', 'localhost:8055/'])
+ if r.exit_code == 0:
+ break
+ if datetime.now() > end:
+ raise TimeoutError(f'unable to contact pebble-challtestsrv on localhost:8055')
+ time.sleep(.1)
+ r = self.env.run(['curl', '-d', f'{{"ip":""}}',
+ 'localhost:8055/set-default-ipv6'])
+ assert r.exit_code == 0, f"{r}"
+
+ def stop(self):
+ if self._pebble:
+ self._pebble.terminate()
+ self._pebble = None
+ if self._challtestsrv:
+ self._challtestsrv.terminate()
+ self._challtestsrv = None
+ if self._log:
+ self._log.close()
+ self._log = None
+
+ def install_ca_bundle(self, dest):
+ shutil.copyfile(self.env.ca.cert_file, dest)
+ end = datetime.now() + timedelta(seconds=20)
+ while datetime.now() < end:
+ r = self.env.curl_get('https://localhost:15000/roots/0', insecure=True)
+ if r.exit_code == 0:
+ with open(dest, 'a') as fd:
+ fd.write(r.stdout)
+ break
+
+
+class MDBoulderRunner(ACMEServer):
+
+ def __init__(self, env: MDTestEnv):
+ self.env = env
+ self.install_ca_bundle(self.env.acme_ca_pemfile)
+
+ def start(self, config=None):
+ pass
+
+ def stop(self):
+ pass
+
+ def install_ca_bundle(self, dest):
+ r = self.env.run([
+ 'docker', 'exec', 'boulder_boulder_1', 'bash', '-c', "cat /tmp/root*.pem"
+ ])
+ assert r.exit_code == 0
+ with open(dest, 'w') as fd:
+ fd.write(r.stdout)