From 856298a67f56250fc8c6748b69448db04de8a8c3 Mon Sep 17 00:00:00 2001 From: Tobias Reisinger Date: Thu, 22 Jun 2023 21:33:26 +0200 Subject: [PATCH] Init --- .gitignore | 2 ++ src/handler.py | 85 ++++++++++++++++++++++++++++++++++++++++++++ src/requirements.txt | 1 + stack.yml | 15 ++++++++ 4 files changed, 103 insertions(+) create mode 100644 .gitignore create mode 100644 src/handler.py create mode 100644 src/requirements.txt create mode 100644 stack.yml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4fda848 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +build/ +template/ diff --git a/src/handler.py b/src/handler.py new file mode 100644 index 0000000..2e3726d --- /dev/null +++ b/src/handler.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python + +import os +import sys +import time +import urllib.request +import yaml + +def eprint(*args, **kwargs): + print(*args, file=sys.stderr, **kwargs) + +# The key is the url +# The value holds the content and the timestamp +file_cache = {} +file_cache_ttl = 60 + +mapper_file = '' +with open('/var/openfaas/secrets/url-mapper-file', 'r') as f: + mapper_file = f.read().strip() + +def get_url_content(url): + if url in file_cache: + cache_entry = file_cache[url] + if cache_entry['timestamp'] + file_cache_ttl > time.time(): + return cache_entry['content'] + + try: + response = urllib.request.urlopen(url) + targets = yaml.safe_load(response.read()) + except Exception as e: + eprint("Failed to load URL mapper file: %s" % e) + return None + + file_cache[url] = { + 'content': targets, + 'timestamp': time.time() + } + return targets + + +def get_entry(args, targets): + while args: + arg = args.pop(0) + if not arg: + continue + targets = targets.get(arg, None) + if isinstance(targets, dict): + continue + return targets, args + return None, args + +def get_entry_for_url(url, args): + targets = get_url_content(url) + if not targets: + return None + + entry, args = get_entry(args, targets) + if not entry: + return None + if entry.startswith('include:'): + entry = entry.split(':', 1)[1] + return get_entry_for_url(entry, args) + return entry + + +def handle(event, context): + + args = event.path.split('/') + + url = get_entry_for_url(mapper_file, args) + + + if not url: + return { + "statusCode": 404, + "body": "URL not found" + } + + return { + "statusCode": 302, + "body": url, + "headers": { + "Location": url + } + } diff --git a/src/requirements.txt b/src/requirements.txt new file mode 100644 index 0000000..bee6c14 --- /dev/null +++ b/src/requirements.txt @@ -0,0 +1 @@ +PyYAML==6.0 diff --git a/stack.yml b/stack.yml new file mode 100644 index 0000000..7b5d68e --- /dev/null +++ b/stack.yml @@ -0,0 +1,15 @@ +provider: + name: openfaas + gateway: https://faas.serguzim.me + +functions: + url-mapper: + lang: python3-http + handler: ./src + image: registry.serguzim.me/faas/url-mapper + secrets: + - url-mapper-file # url to mapper file +configuration: + templates: + - name: python3-http-debian + source: https://github.com/openfaas-incubator/python-flask-template