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:
@@ -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
36
.gitignore
vendored
@@ -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
|
||||||
|
|||||||
28
Dockerfile
28
Dockerfile
@@ -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"]
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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"]
|
||||||
|
|||||||
@@ -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"]
|
||||||
|
|||||||
@@ -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):
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
0.0.1
|
0.0.2
|
||||||
Reference in New Issue
Block a user