diff options
author | Jan Dittberner <jandd@cacert.org> | 2019-07-18 22:29:57 +0200 |
---|---|---|
committer | Jan Dittberner <jandd@cacert.org> | 2019-07-18 22:29:57 +0200 |
commit | 09c942d512e679a824969e18753822c7853b15ab (patch) | |
tree | 71a18b7a0b402730c9a3f5a9d177db075a0fc0e6 | |
parent | 2784eca1466df80f6e5c071c7cf1e89e50a05fa5 (diff) | |
download | cacert-puppet-09c942d512e679a824969e18753822c7853b15ab.tar.gz cacert-puppet-09c942d512e679a824969e18753822c7853b15ab.tar.xz cacert-puppet-09c942d512e679a824969e18753822c7853b15ab.zip |
Change git-pull-hook to handle POST request
- Switch from GET to semantically more correct POST
- trigger r10k puppetfile install to update puppet modules
- reformat with black
-rwxr-xr-x | sitemodules/profiles/files/puppet_server/git-pull-hook | 140 |
1 files changed, 85 insertions, 55 deletions
diff --git a/sitemodules/profiles/files/puppet_server/git-pull-hook b/sitemodules/profiles/files/puppet_server/git-pull-hook index ed34047..6c92b24 100755 --- a/sitemodules/profiles/files/puppet_server/git-pull-hook +++ b/sitemodules/profiles/files/puppet_server/git-pull-hook @@ -18,9 +18,7 @@ from http import HTTPStatus from http.server import HTTPServer, BaseHTTPRequestHandler from subprocess import Popen, PIPE -ENV_FOR_GIT = { - 'PATH': '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', -} +ENV_FOR_GIT = {"PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"} TOKENS = [] GIT_DIRECTORY = "" @@ -31,37 +29,37 @@ LOGGER = None def read_ini(): global ENV_FOR_GIT, TOKENS, GIT_DIRECTORY, LOGGER config = ConfigParser() - config.read(['/etc/git-pull-hook.ini', - os.path.expanduser('~/.git-pull-hook.ini'), - 'git-pull-hook.ini']) - ENV_FOR_GIT['SSHPASS'] = config['git-pull-hook']['ssh_passphrase'] - TOKENS = [token.strip() for token in - config['git-pull-hook']['tokens'].split(',')] - GIT_DIRECTORY = config['git-pull-hook']['git_directory'] - - logging.config.dictConfig({ - 'version': 1, - 'formatters': { - 'full': { - 'format': '%(asctime)s %(levelname)-8s %(message)s', - 'datefmt': '%Y-%m-%d %H:%M:%S', - } - }, - 'handlers': { - 'file': { - 'class': 'logging.FileHandler', - 'filename': config.get('git-pull-hook', 'logfile'), - 'formatter': 'full', + config.read( + [ + "/etc/git-pull-hook.ini", + os.path.expanduser("~/.git-pull-hook.ini"), + "git-pull-hook.ini", + ] + ) + ENV_FOR_GIT["SSHPASS"] = config["git-pull-hook"]["ssh_passphrase"] + TOKENS = [token.strip() for token in config["git-pull-hook"]["tokens"].split(",")] + GIT_DIRECTORY = config["git-pull-hook"]["git_directory"] + + logging.config.dictConfig( + { + "version": 1, + "formatters": { + "full": { + "format": "%(asctime)s %(levelname)-8s %(message)s", + "datefmt": "%Y-%m-%d %H:%M:%S", + } }, - }, - 'loggers': { - 'git-pull-hook': { - 'handlers': ['file'], - 'level': 'INFO', - } + "handlers": { + "file": { + "class": "logging.FileHandler", + "filename": config.get("git-pull-hook", "logfile"), + "formatter": "full", + } + }, + "loggers": {"git-pull-hook": {"handlers": ["file"], "level": "INFO"}}, } - }) - LOGGER = logging.getLogger('git-pull-hook') + ) + LOGGER = logging.getLogger("git-pull-hook") class GitHookRequestHandler(BaseHTTPRequestHandler): @@ -78,44 +76,76 @@ class GitHookRequestHandler(BaseHTTPRequestHandler): def _send_data(self, message): self.send_header("Content-Type", "text/plain; charset=utf8") self.end_headers() - self.wfile.write(("%s\r\n" % message).encode('UTF-8')) + self.wfile.write(("%s\r\n" % message).encode("UTF-8")) def _handle_pull(self): try: git_proc = Popen( - ['sshpass', '-e', '-P', 'passphrase', 'git', 'pull'], - env=ENV_FOR_GIT, cwd=GIT_DIRECTORY, stdout=PIPE, stderr=PIPE) + ["sshpass", "-e", "-P", "passphrase", "git", "pull"], + env=ENV_FOR_GIT, + cwd=GIT_DIRECTORY, + stdout=PIPE, + stderr=PIPE, + ) stdout, stderr = git_proc.communicate() - for line in stderr.decode('UTF-8').splitlines(): - self.log_error('git: %s', line) - for line in stdout.decode('UTF-8').splitlines(): - self.log_message('git: %s', line) + for line in stderr.decode("UTF-8").splitlines(): + self.log_error("git: %s", line) + for line in stdout.decode("UTF-8").splitlines(): + self.log_message("git: %s", line) except Exception as e: - self.log_error("Could not pull changes for %s: %s", - GIT_DIRECTORY, e) + self.log_error("Could not pull changes for %s: %s", GIT_DIRECTORY, e) self._send_data("Error updating the repository.") + try: + r10k_proc = Popen( + ["/opt/puppetlabs/puppet/bin/r10k", "puppetfile", "install"], + cwd=GIT_DIRECTORY, + stdout=PIPE, + stderr=PIPE, + ) + stdout, stderr = git_proc.communicate() + for line in stderr.decode("UTF-8").splitlines(): + self.log_error("r10k: %s", line) + for line in stdout.decode("UTF-8").splitlines(): + self.log_message("r10k: %s", line) + except Exception as e: + self.log_error("Could not update modules from Puppetfile: %s", e) + self._send_data("Error updating modules.") + self.send_response(HTTPStatus.OK) self._send_data("updated %s" % GIT_DIRECTORY) # noinspection PyPep8Naming def do_GET(self): """ - Handle GET requests, requests to /health are allowed for every caller, - requests to / need a valid token in the "Authentication" HTTP header - and trigger a git pull in the configured directory. + Handle GET requests, requests to /health are allowed for every caller. """ - if self.path == '/': - if self.headers['Authentication'] in [token for token in TOKENS]: - self._handle_pull() - else: - self.send_error(HTTPStatus.UNAUTHORIZED, - 'You have to send a valid token in the "Authentication" header.') - elif self.path == '/health': + if self.path == "/health": self.send_response(HTTPStatus.OK) self._send_data("I'm healthy!") else: - self.send_error(HTTPStatus.BAD_REQUEST, - "You requested something I do not understand.") + self.send_error( + HTTPStatus.NOT_FOUND, "You requested something I do not understand." + ) + + # noinspection PyPep8Naming + def do_POST(self): + """ + Handle POST requests requests to / need a valid token in the + "Authentication" HTTP header and trigger a git pull in the configured + directory. + """ + if self.path == "/": + if self.headers["Authentication"] in [token for token in TOKENS]: + self._handle_pull() + else: + self.send_error( + HTTPStatus.UNAUTHORIZED, + 'You have to send a valid token in the "Authentication" header.', + ) + else: + self.send_error( + HTTPStatus.NOT_FOUND, "You requested something I do not understand." + ) def log_error(self, format, *args): self.log.error("%s - %s" % (self.address_string(), format), *args) @@ -125,11 +155,11 @@ class GitHookRequestHandler(BaseHTTPRequestHandler): def run(server_class=HTTPServer, handler_class=GitHookRequestHandler): - server_address = ('', 8000) + server_address = ("", 8000) httpd = server_class(server_address, handler_class) httpd.serve_forever() -if __name__ == '__main__': +if __name__ == "__main__": read_ini() run() |