Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Francesco Faraone committed Feb 28, 2024
1 parent 1b64602 commit 67ab578
Show file tree
Hide file tree
Showing 16 changed files with 1,739 additions and 531 deletions.
2 changes: 0 additions & 2 deletions .flake8
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,5 @@
exclude = .idea,.vscode,.git,venv,env,swo,devmock
show-source = True
max-line-length = 100
application-import-names = sud
import-order-style = smarkets
max-cognitive-complexity = 15
extend-ignore = PT004, E203
1,073 changes: 986 additions & 87 deletions poetry.lock

Large diffs are not rendered by default.

42 changes: 19 additions & 23 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ packages = [
{ include = "sud" },
]


documentation = "https://github.com/ffaraone/sud"
homepage = "https://github.com/ffaraone/sud"
repository = "https://github.com/ffaraone/sud"
Expand All @@ -29,47 +28,44 @@ classifiers = [

keywords = ["sud", "scaleway", "dns", "dynamic", "dynamicdns"]


[tool.poetry.scripts]
sud = "sud.cli:app"

[tool.poetry.dependencies]
python = ">=3.10,<4"
humanize = "^4.9.0"
python-telegram-bot = "^20.8"
pyyaml = "^6.0.1"
requests = "^2.31.0"
click = "^8.1.7"
rich = "^13.7.0"
pyyaml = "^6.0.1"
python-telegram-bot = "^20.8"
humanize = "^4.9.0"
rich-click = "^1.7.3"

[tool.poetry.scripts]
sud = "sud.cli:main"
typer = {extras = ["all"], version = "^0.9.0"}

[tool.poetry.group.dev.dependencies]
ipython = "^8.21.0"
pytest = "^8.0.1"
black = "^24.2.0"
isort = "^5.13.2"
flake8 = "^7.0.0"
flake8-pytest-style = "^1.7.2"
flake8-black = "^0.3.6"
flake8-bugbear = "^24.2.6"
flake8-debugger = "^4.1.2"
pytest-randomly = "^3.15.0"
pytest-cov = "^4.1.0"
flake8-black = "^0.3.6"
flake8-isort = "^6.1.1"
flake8-pytest-style = "^1.7.2"
ipython = "^8.21.0"
isort = "^5.13.2"
mypy = "^1.8.0"
poetry-plugin-sort = "^0.2.1"
pytest = "^8.0.1"
pytest-asyncio = "^0.23.5"
pytest-cov = "^4.1.0"
pytest-deadfixtures = "^2.2.1"
pytest-mock = "^3.12.0"
pytest-randomly = "^3.15.0"
responses = "^0.25.0"
pytest-deadfixtures = "^2.2.1"
mypy = "^1.8.0"
types-requests = "^2.31.0.20240218"
types-pyyaml = "^6.0.12.12"

types-requests = "^2.31.0.20240218"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"


[tool.pytest.ini_options]
testpaths = "tests"
pythonpath = "."
Expand Down Expand Up @@ -97,7 +93,7 @@ exclude_lines = [
profile = "black"

[tool.black]
line-length = 79
line-length = 88

[tool.mypy]
warn_no_return = false
4 changes: 1 addition & 3 deletions sud/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,7 @@ def _get_git_revision(path):

def get_revision():
package_dir = os.path.dirname(__file__)
checkout_dir = os.path.normpath(
os.path.join(package_dir, os.pardir, os.pardir)
)
checkout_dir = os.path.normpath(os.path.join(package_dir, os.pardir, os.pardir))
path = os.path.join(checkout_dir)
if os.path.exists(path):
return _get_git_revision(path)
Expand Down
4 changes: 2 additions & 2 deletions sud/__main__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from sud.cli import main
from sud.cli import app

if __name__ == "__main__":
main()
app()
172 changes: 111 additions & 61 deletions sud/cli.py
Original file line number Diff line number Diff line change
@@ -1,82 +1,132 @@
import logging
from datetime import timedelta
from pathlib import Path
from typing import Annotated, Optional, Tuple

from rich.console import Console
import typer
from rich import print
from rich.logging import RichHandler

from sud import click as click
from sud import config, get_version
from sud import get_version
from sud.config import Config
from sud.prompt import APISecretPrompt, HostnamePrompt
from sud.updater import Updater

console = Console()
app = typer.Typer(
add_completion=False,
rich_markup_mode="rich",
)


@click.group()
@click.option(
"-c",
"--config-file",
type=click.Path(
dir_okay=False,
readable=True,
writable=True,
),
default="/etc/sud/sud-config.yml",
help="Load the configuration file from a specific location.",
)
@click.version_option(get_version())
@config.pass_config
def cli(ctx, config_file):
"""
SUD the Python Scaleway DNS Updater utility.
"""
def version_callback(value: bool):
if value:
print(f"[bold dark_orange]SUD[/] version: {get_version()}")
raise typer.Exit()


@cli.command(load_config=False)
# @click.option(
# "-H",
# "--hostname",
# required=True,
# prompt="[cyan]Hostname[/cyan]",
# )
# @click.option(
# "-s",
# "--api-secret",
# required=True,
# prompt="[cyan]Scaleway API secret[/cyan]",
# hide_input=True,
# confirmation_prompt=True,
# )
@click.option(
"-s",
"--frequency",
required=True,
prompt="Check frequency",
default=300,
show_default=True,
)
@config.pass_config
def init(config, frequency):
pass
def validate_frequency_callback(value: int):
if value < 60:
raise typer.BadParameter("Minimum frequency is once per minutes (60 seconds).")
return value


@app.command()
def init(
ctx: typer.Context,
hostname: Annotated[
Optional[str],
typer.Option(
"--hostname",
"-H",
show_default=False,
help="Hostname that must be created/updated.",
),
] = None,
api_secret: Annotated[
Optional[str],
typer.Option(
"--api-secret",
"-s",
show_default=False,
help="Scaleway API secret.",
),
] = None,
frequency: Annotated[
Optional[int],
typer.Option(
"--frequency",
"-f",
callback=validate_frequency_callback,
help="Number of seconds between checks.",
),
] = 300,
telegram: Annotated[
Optional[Tuple[int, str]],
typer.Option(
"--telegram-notifications",
"-t",
metavar="CHAT_ID TOKEN",
help="Add telegram configuration for notifications.",
),
] = (None, None),
):
"""Generate a SUD configuration file."""
if not hostname:
hostname = HostnamePrompt.ask(
"Enter the hostname that must be created or update",
)

@cli.command()
@config.pass_config
def run(config):
if not api_secret:
api_secret = APISecretPrompt.ask(
"Enter the Scaleway API secret",
password=True,
)

config: Config = ctx.obj
config.hostname = hostname
config.api_secret = api_secret
config.frequency = timedelta(seconds=frequency)
config.store()


@app.command()
def run(ctx: typer.Context):
"""Run the [magenta][link=https://scaleway.com]Scaleway[/link][/magenta] DNS Updater."""
logging.basicConfig(
level=logging.INFO,
format="%(message)s",
datefmt="[%X]",
handlers=[RichHandler()],
)
updater = Updater(config)
updater = Updater(ctx.obj)
updater.run()


def main():
try:
cli(standalone_mode=False)
except click.ClickException as e:
console.print(f"[bold red]Error:[/bold red] {str(e)}")
except click.Abort:
pass
except Exception:
console.print_exception()
@app.callback()
def main(
ctx: typer.Context,
config_file: Annotated[
Optional[Path],
typer.Option(
"--config-file",
"-c",
help="Load the configuration file from a specific location.",
),
] = "/etc/sud/sud-config.yml",
version: Annotated[
Optional[bool],
typer.Option("--version", callback=version_callback, is_eager=True),
] = None,
):
"""
[bold dark_orange]SUD[/] is a small DDNS updater utility for the
Scaleway DNS service.
It periodically (default: 300 seconds) check for the IP public IP
address from through the utility goes to internet
and create or update a [cyan]Host (A)[/] record in the DNS zone of the
specified domain name.
"""
config = Config(config_file)
ctx.obj = config
if ctx.invoked_subcommand != "init":
config.load()
Loading

0 comments on commit 67ab578

Please sign in to comment.