Tidying up for future changes

- Changelog started. Existing version 0.0.2
- Add section for application wide TODOs. Each moved to changelog when done
- Adjusted .gitignore and .dockerignore
- Updated image base to python:3.10-slim-trixie. Cleaned up image build.
- Added default environment values to compose file
- Cleaned up pyproject.toml.
- Deleted unused gui-tk.py.
This commit is contained in:
Doc
2025-10-03 16:00:52 -04:00
parent 71e933be72
commit a8b254fa8b
9 changed files with 82 additions and 73 deletions

View File

@@ -2,6 +2,7 @@
.credentials .credentials
.secrets .secrets
auth.yaml auth.yaml
config.yaml
*._py_ *._py_
# Editors (Editor-specific config files) # Editors (Editor-specific config files)
@@ -124,3 +125,11 @@ dmypy.json
.pyre/ .pyre/
.pytype/ .pytype/
cython_debug/ cython_debug/
design_documents/
distro_client/subdomain_client.tar.gz
distro_client/
config/config.yaml
config/
scripts/
template_vars.env

36
.gitignore vendored
View File

@@ -2,6 +2,7 @@
.credentials .credentials
.secrets .secrets
auth.yaml auth.yaml
config.yaml
*._py_ *._py_
# Editors # Editors
@@ -75,12 +76,6 @@ cover/
*.mo *.mo
*.pot *.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite-journal
# Flask stuff: # Flask stuff:
instance/ instance/
.webassets-cache .webassets-cache
@@ -119,13 +114,6 @@ pdm.lock
__pypackages__/ __pypackages__/
# celery beat schedule file
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments # Environments
.env .env
.venv .venv
@@ -135,13 +123,6 @@ ENV/
env.bak/ env.bak/
venv.bak/ venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation # mkdocs documentation
/site /site
@@ -156,15 +137,10 @@ dmypy.json
# pytype static type analyzer # pytype static type analyzer
.pytype/ .pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
distro_client/subdomain_client.tar.gz distro_client/subdomain_client.tar.gz
distro_client/
config/config.yaml config/config.yaml
config/
scripts/project-cli
scripts/update-variables.sh
template_vars.env

View File

@@ -1,24 +1,26 @@
# Dockerfile # Dockerfile
FROM python:3.10-slim FROM python:3.10-slim-trixie
# Set working directory # Set working directory
WORKDIR /app WORKDIR /app
# Copy requirements file and install dependencies # Apply security updates
# COPY requirements.txt . RUN apt update && apt-get install -y --only-upgrade $(apt-get --just-print upgrade | awk 'tolower($4) ~ /.*security.*/ || tolower($5) ~ /.*security.*/ {print $2}' | sort | uniq) && rm -rf /var/lib/apt/lists/*
RUN pip install --no-cache-dir hatch RUN pip install --no-cache-dir hatch
# Copy the entire project to the working directory # Copy first part of project that needs to be rebuilt
COPY ./src /app/src # if it changes
COPY ./README.md /app/README.md COPY ./pyproject.toml ./src /app/
COPY ./LICENSE /app/LICENSE
COPY ./pyproject.toml /app/pyproject.toml
COPY ./scripts /app/scripts
#COPY ./tests /app/tests
COPY ./docs /app/docs
# Expose the port the app runs on (adjust based on your app's settings) # Pre-installed files needed at runtime
RUN hatch env create default -- --no-cache-dir
# Copy the rest of the project; readme and license
COPY ./README.md ./LICENSE /app/
# Expose the default port the app runs on
EXPOSE 5232 EXPOSE 5232
# Command to run the app # Command to run the app
CMD ["hatch","run","subdomain_server","--port","5232","--config-path","/app/config/config.yaml","--debug"] CMD ["hatch","run","subdomain_server","--config-path","/app/config/config.yaml"]

View File

@@ -13,6 +13,9 @@ services:
- /home/doc/src/my/subdomain_server/config:/app/config:ro - /home/doc/src/my/subdomain_server/config:/app/config:ro
environment: environment:
- AUTH_FILE=/app/config/config.yaml - AUTH_FILE=/app/config/config.yaml
- LOG_LEVEL=DEBUG
- PORT=5232
- BINDING=0.0.0.0
restart: always restart: always
networks: networks:

View File

@@ -11,9 +11,9 @@ authors = [
{ name = "BipolarExpedition(Doc1979)" }, { name = "BipolarExpedition(Doc1979)" },
{ name = "Doc1979", email = "lastdoc39@gmail.com" }, { name = "Doc1979", email = "lastdoc39@gmail.com" },
] ]
requires-python = ">=3.8" requires-python = ">=3.10"
license = { file = "LICENSE" } license = { file = "LICENSE" }
# keywords = [] keywords = ["server", "domain", "subdomain", "dns", "dynamic"]
classifiers = [ classifiers = [
# How mature is this project? Common values are # How mature is this project? Common values are
# 3 - Alpha # 3 - Alpha
@@ -23,38 +23,45 @@ classifiers = [
"Programming Language :: Python :: 3", "Programming Language :: Python :: 3",
"Operating System :: OS Independent", "Operating System :: OS Independent",
] ]
dependencies = ["Flask", "PyYAML", "Typer", "requests"] dependencies = [
"Flask==3.1.1",
[project.urls] "PyYAML==6.0.2",
homepage = "https://github.com/BipolarExpedition/subdomain_server" "requests==2.32.4",
repository = "https://github.com/BipolarExpedition/subdomain_server" "typer==0.16.0",
issues = "https://github.com/BipolarExpedition/subdomain_server/issues" ]
# documentation = "https://readthedocs.org"
# changelog = "https://github.com/me/spam/blob/master/CHANGELOG.md"
[project.scripts] [project.scripts]
subdomain_server = "bpe_subdomain_server.cli:daemon" subdomain_server = "bpe_subdomain_server.cli:daemon"
# [project.gui-scripts] [project.optional-dependencies]
# subdomain_server_gui = "bpe_subdomain_server.gui-tk:main" dev = [
"ruff",
#[project.optional-dependencies] "mypy",
# gui = ["tkinter"] "pytest",
# cli = [ "types-PyYAML",
# "rich", "types-requests",
# "click", "typing_extensions",
# ] ]
[tool.hatch.build] [tool.hatch.build]
skip-excluded-dirs = true skip-excluded-dirs = true
exclude = [".secrets", ".credentials", ".vscode", ".idea"] exclude = [
".secrets",
".credentials",
".vscode",
".idea",
"auth.yaml",
"config.yaml",
"config/auth.yaml",
"config/config.yaml",
]
[tool.hatch.envs.default] [tool.hatch.envs.default]
python = "3.10" python = "3.10"
[tool.hatch.envs.test] [tool.hatch.envs.test]
python = "3.10" python = "3.10"
dependencies = ["ruff", "myst-parser", "sphinx", "pytest"] dependencies = ["ruff", "myst-parser", "sphinx", "pytest", "mypy"]
[tool.pytest.ini_options] [tool.pytest.ini_options]
testpaths = ["tests"] testpaths = ["tests"]

View File

@@ -15,8 +15,24 @@ from bpe_subdomain_server.__about__ import (
# __repository__, # __repository__,
) )
# last_update = None # Changelog:
# DEBUG = False # 2025-09-03: - Changelog started. Existing version 0.0.2
# - Adding section for application wide TODOs. Each to be moved to changelog when done
# - Adjusted .gitignore and .dockerignore
# - Updated Dockerfile image base to python:3.10-slim-trixie. Cleaned up image build.
# - Added default environment values to compose file
# - Cleaned up pyproject.toml. Deleted unused gui-tk.py. Added requirements.txt
# Application level TODOs
# TODO: Refactor Config class to be in utils.py
# TODO: add routes for lookup and health
# TODO: add proper google style documentation comments. Consider local LLM for first pass then manual edit/review
# FIXME: Move api-key to header
# TODO: Consilidate redundant debug messages "Request json" and "Received data"
# FIXME: Create solution to sanitize keys and passwords from log. Likely [filters in logging library](https://docs.python.org/3.10/library/logging.html#filter-objects)
# TODO: Consider to use Pydantic and its SecretStr type to better hide secrects from logs AND exceptions
# TODO: Remove unused Makefile. Centralize version information for project. Make script to fascilitate docker image creation (auto versioning)
# TODO: Refactor to BPE parent path for "branding"
class Config(object): class Config(object):
@@ -143,8 +159,6 @@ def setup_logging(
flask_app = Flask(__name__) flask_app = Flask(__name__)
# TODO: add routes for lookup and health
@flask_app.route("/get-ip", methods=["GET", "POST"]) @flask_app.route("/get-ip", methods=["GET", "POST"])
def request_get_ip(): def request_get_ip():
@@ -163,6 +177,7 @@ def request_get_ip():
@flask_app.route("/update", methods=["POST"]) @flask_app.route("/update", methods=["POST"])
def update(): def update():
# Refresh API keys if the file was modified # Refresh API keys if the file was modified
Config.auth_table.load_api_keys() Config.auth_table.load_api_keys()
api_keys_config = Config.auth_table.auth api_keys_config = Config.auth_table.auth
logger.debug(f"API keys: {api_keys_config}") logger.debug(f"API keys: {api_keys_config}")
@@ -199,7 +214,7 @@ def update():
logger.warning("Update request missing ip and auto_ip is false") logger.warning("Update request missing ip and auto_ip is false")
return jsonify({"error": "ip is required unless auto_ip is true"}), 400 return jsonify({"error": "ip is required unless auto_ip is true"}), 400
# Authenticate API token and check permissions # Check token and permissions
if ( if (
api_token not in api_keys_config["api_keys"] api_token not in api_keys_config["api_keys"]
or subdomain not in api_keys_config["api_keys"][api_token]["allowed_subdomains"] or subdomain not in api_keys_config["api_keys"][api_token]["allowed_subdomains"]

View File

@@ -69,9 +69,6 @@ def get_ip(addr: str) -> str:
return res return res
# TODO: At either update_domain, update_namecheap, or both, make sure IP is not a reserved address
def update_domain(subdomain, ip, auth_table: AuthTable) -> bool: def update_domain(subdomain, ip, auth_table: AuthTable) -> bool:
# Verify that the IP address is not a reserved address # Verify that the IP address is not a reserved address
if not is_public_ip(ip): if not is_public_ip(ip):

View File

@@ -1 +1 @@
0.0.1 0.0.2