From ee9f4870f9974853e3e06bc4451354f2b8cf25a6 Mon Sep 17 00:00:00 2001 From: Yehuda Deutsch Date: Wed, 1 Feb 2023 16:29:25 -0500 Subject: [PATCH 1/3] Make the app a CLI and dockerize --- Dockerfile | 11 +++++++++++ yunodiagnoser.py | 31 ++++++++++++++++++++++++++++--- 2 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..3837430 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,11 @@ +FROM python:3.9 + +ENV PYTHONUNBUFFERED=1 + +WORKDIR /app + +COPY requirements-frozen.txt yunodiagnoser.py /app/ + +RUN pip install --no-cache-dir -r /app/requirements-frozen.txt + +CMD ["python3", "/app/yunodiagnoser.py"] diff --git a/yunodiagnoser.py b/yunodiagnoser.py index f9822d8..7410ea3 100644 --- a/yunodiagnoser.py +++ b/yunodiagnoser.py @@ -4,6 +4,7 @@ import asyncio import aiohttp import validators import socket +from argparse import ArgumentParser from sanic import Sanic from sanic.log import logger @@ -125,7 +126,7 @@ async def check_http(request): # Check domain list format assert isinstance(data["domains"], list), "'domains' ain't a list" assert len(data["domains"]) > 0, "'domains' list is empty" - assert len(data["domains"]) < 60, "You cannot test that many domains" + assert len(data["domains"]) < request.app.ctx.max_domains, "You cannot test that many domains" for domain in data["domains"]: assert isinstance(domain, str), "domain names must be strings" assert len(domain) < 100, "Domain %s name seems pretty long, that's suspicious...?" % domain @@ -260,7 +261,7 @@ async def check_ports(request): assert isinstance(data["ports"], list), "'ports' ain't a list" assert len(data["ports"]) > 0, "'ports' list is empty" - assert len(data["ports"]) < 30, "That's too many ports to check" + assert len(data["ports"]) < request.app.ctx.max_ports, "That's too many ports to check" assert len(data["ports"]) == len(set(data["ports"])), "'ports' list should contain unique elements" def is_port_number(p): @@ -394,5 +395,29 @@ async def main(request): return html("You aren't really supposed to use this website using your browser.

It's a small server with an API to check if a services running on YunoHost instance can be reached from 'the global internet'.") +def serve(): + parser = ArgumentParser('yunodiagnoser.py') + parser.add_argument('--host', help='Address to host on', default='0.0.0.0') + parser.add_argument('--port', help='Port to host on', default=8000, type=int) + parser.add_argument('--workers', help='Number of processes received before it is respected', default=16, type=int) + parser.add_argument('--debug', help='Enables debug output (slows server)', action='store_true') + parser.add_argument('--auto-reload', help='Reload app whenever its source code is changed. Enabled by default in debug mode.', default=None, action='store_true') + + # Settings + parser.add_argument('--max-domains', help='Maximum domains allowed to check in a batch', default=100, type=int) + parser.add_argument('--max-ports', help='Maximum ports allowed to check in a batch', default=50, type=int) + + args, _ = parser.parse_known_args() + app.ctx.args = args + + app.run( + host=args.host, + port=args.port, + workers=args.workers, + debug=args.debug, + auto_reload=args.auto_reload, + ) + + if __name__ == "__main__": - app.run(host="0.0.0.0", port=7000, workers=16) + serve() From b767a70efb591154c4c28b1681f44b9ce3a8283e Mon Sep 17 00:00:00 2001 From: Yehuda Deutsch Date: Wed, 1 Feb 2023 16:46:54 -0500 Subject: [PATCH 2/3] Use sanic conventional config --- yunodiagnoser.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/yunodiagnoser.py b/yunodiagnoser.py index 7410ea3..09ed447 100644 --- a/yunodiagnoser.py +++ b/yunodiagnoser.py @@ -12,6 +12,9 @@ from sanic.response import html, json as json_response from sanic.exceptions import InvalidUsage app = Sanic(__name__) +# Don't override values from environment variables +app.config.setdefault('MAX_DOMAINS', 50) +app.config.setdefault('MAX_PORTS', 30) # ########################################################################### # # Rate limit # @@ -126,7 +129,7 @@ async def check_http(request): # Check domain list format assert isinstance(data["domains"], list), "'domains' ain't a list" assert len(data["domains"]) > 0, "'domains' list is empty" - assert len(data["domains"]) < request.app.ctx.max_domains, "You cannot test that many domains" + assert len(data["domains"]) < int(request.app.config.MAX_DOMAINS), "You cannot test that many domains" for domain in data["domains"]: assert isinstance(domain, str), "domain names must be strings" assert len(domain) < 100, "Domain %s name seems pretty long, that's suspicious...?" % domain @@ -261,7 +264,7 @@ async def check_ports(request): assert isinstance(data["ports"], list), "'ports' ain't a list" assert len(data["ports"]) > 0, "'ports' list is empty" - assert len(data["ports"]) < request.app.ctx.max_ports, "That's too many ports to check" + assert len(data["ports"]) < int(request.app.config.MAX_PORTS), "That's too many ports to check" assert len(data["ports"]) == len(set(data["ports"])), "'ports' list should contain unique elements" def is_port_number(p): @@ -403,12 +406,14 @@ def serve(): parser.add_argument('--debug', help='Enables debug output (slows server)', action='store_true') parser.add_argument('--auto-reload', help='Reload app whenever its source code is changed. Enabled by default in debug mode.', default=None, action='store_true') - # Settings - parser.add_argument('--max-domains', help='Maximum domains allowed to check in a batch', default=100, type=int) - parser.add_argument('--max-ports', help='Maximum ports allowed to check in a batch', default=50, type=int) + # Inherit from environment variables or defaults + parser.add_argument('--max-domains', help='Maximum domains allowed to check in a batch', default=app.config.MAX_DOMAINS, type=int) + parser.add_argument('--max-ports', help='Maximum ports allowed to check in a batch', default=app.config.MAX_PORTS, type=int) args, _ = parser.parse_known_args() - app.ctx.args = args + + for arg in ('max_domains', 'max_ports'): + app.config[arg.upper()] = getattr(args, arg) app.run( host=args.host, From f6e18f1e1604f110c18d6e9ee3929c35d1613162 Mon Sep 17 00:00:00 2001 From: Yehuda Deutsch Date: Wed, 1 Feb 2023 17:32:51 -0500 Subject: [PATCH 3/3] Revert to original default --- yunodiagnoser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yunodiagnoser.py b/yunodiagnoser.py index 09ed447..38ee7d2 100644 --- a/yunodiagnoser.py +++ b/yunodiagnoser.py @@ -13,7 +13,7 @@ from sanic.exceptions import InvalidUsage app = Sanic(__name__) # Don't override values from environment variables -app.config.setdefault('MAX_DOMAINS', 50) +app.config.setdefault('MAX_DOMAINS', 60) app.config.setdefault('MAX_PORTS', 30) # ########################################################################### #