Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 133 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# Contributing

Thanks for your interest in contributing to this project — we welcome improvements, bug
fixes, documentation updates, tests, and ideas. This document explains the most
common ways to contribute and the project's expectations for contributions.

## Table of content

- **Getting started**
- **Reporting issues**
- **Proposing changes (Pull Requests)**
- **Branching & commit guidance**
- **Code style & tests**
- **Pre-commit hooks & CI**
- **Security & sensitive data**
- **Code of conduct**

## Getting started

- Fork the repository on GitHub to your account.
- Clone your fork locally and add the upstream remote (the original repo):

```bash
git clone git@github.com:<your-username>/cloudflare-ddns.git
cd cloudflare-ddns
git remote add upstream git@github.com:Esysc/cloudflare-ddns.git
git fetch upstream
```

- Create a feature branch for your change (describe the change in the branch name):

```bash
git checkout -b fix/update-contributing-doc
```

## Reporting issues

- If you found a bug, missing behavior, or have a feature idea, open an issue in the
upstream repository. Provide a minimal reproduction, expected vs actual behavior,
and environment details (OS, Python version, steps to reproduce).

## Proposing changes (Pull Requests)

- Make changes on a branch in your fork, commit, and push the branch to your fork:

```bash
git add CONTRIBUTING.md
git commit -m "docs: improve contributing guide"
git push origin fix/update-contributing-doc
```

- Open a Pull Request from your fork/branch to the upstream branch (`bugfix/fixes1` or `main` as appropriate).
- In the PR description, include:
- Summary of the change
- Why it's needed
- Any testing you performed
- Any migration or breaking changes

- Keep changes focused and small where possible. Large or complex changes are easier
to review when split into smaller PRs.

## Branching & commit guidance

- Create short-lived branches for each logical change.
- Use clear commit messages. Follow this pattern for the first line:

```text
<type>(<scope>): <short summary>

e.g. "fix(ddns): preserve record TTL when updating"
```

- Types commonly used: `feat`, `fix`, `docs`, `chore`, `refactor`, `test`.

## Code style & tests

- The project uses lightweight linting and formatting tools in pre-commit.
- Keep functions small and add docstrings for public functions.
- When you add functionality, include or update tests in `tests/` that exercise
the behavior. Unit tests should not make network calls; use mocking for HTTP.

## Pre-commit hooks & CI

- This repo includes a `.pre-commit-config.yaml`. Please run and satisfy the
pre-commit checks locally before opening a PR:

```bash
pip install -r requirements-dev.txt
pre-commit install
pre-commit run --all-files
```

- The CI workflow runs tests on push/PR. Ensure your changes pass CI before requesting review.

## Security & sensitive data

- Do not commit secrets, API tokens, or credentials. Use environment variables
or GitHub Secrets for CI.
- If you discover a security issue, do not open a public issue. Instead contact
the maintainers (or the repository owner) privately so the issue can be
investigated and handled appropriately.

## Code of Conduct

- Be respectful, helpful, and collaborative. Report unacceptable behavior to the
maintainers. This project follows a standard code of conduct; by participating
you agree to be welcoming and professional.

## Maintainers & review process

- Maintainers will review PRs and may request changes. Small PRs can be merged
quickly; larger changes may take longer.
- If your PR needs more work, please address feedback and push follow-up commits
to the same branch.

## Useful commands

```bash
# keep fork up to date with upstream
git fetch upstream
git checkout main
git merge upstream/main

# create branch from updated main
git checkout -b my-feature-branch

# commit and push
git add .
git commit -m "feat: ..."
git push origin my-feature-branch
```

Thank you for considering a contribution — your help makes this project better!
65 changes: 41 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,37 @@
This repository contains a small DDNS updater script that updates A records in
a Cloudflare zone to match the host's public IP address.

Rationale
## Rationale

---------
If you host a web server and proxy the site through Cloudflare, DNS records
point to the server's public IP. When the server IP changes (reboot, DHCP,
cloud VM migration), DNS can become stale. This script queries the current
public IP and updates all matching A records for a given name in a Cloudflare
zone so DNS stays correct.

Security
--------
## Security

---------

- Do NOT store secrets in source. The script reads the Cloudflare API token
from the environment variable `CLOUDFLARE_API_TOKEN` (or from a token file).
- Use a scoped Cloudflare API token with least privileges (DNS:Edit for the
target zone).

Files
-----
## Files

---------

- `ddns.py` — main Python script (dry-run by default; reads token from env).
- `run_ddns.sh` — helper that creates/activates a `venv` and runs `ddns.py`.
- `cron.example` — suggested crontab line.
- `cron.example` — suggested crontab line
- `ddns.service` / `ddns.timer` — systemd unit and timer examples.

Quick start
-----------
## Quick start

---------

1. Create a virtual environment and install dependencies:

```bash
Expand All @@ -49,17 +56,20 @@ To perform a real update (be careful):
DDNS_DRY_RUN=0 ./run_ddns.sh --zone example.com --name host.example.com
```

Usage and flags
---------------
## Usage and flags

---------
`run_ddns.sh` accepts these options (and forwards `--zone/--name` to `ddns.py`):

- `--token` / `-t` : Cloudflare API token (fallback: `CLOUDFLARE_API_TOKEN` env)
- `--zone` / `-z` : Cloudflare zone name (fallback: `DDNS_ZONE_NAME` env)
- `--name` / `-n` : DNS record name to update (fallback: `DDNS_DNS_NAME` env)

The script supports both `--option value` and `--option=value` formats, making it resilient to different shell environments, including restrictive cron job runners.

Examples
--------
## Examples

---------

Using CLI flags (preferred):

Expand All @@ -81,24 +91,28 @@ Backwards compatibility (positional token):
DDNS_ZONE_NAME=example.com DDNS_DNS_NAME=host.example.com ./run_ddns.sh xxxxx
```

Tests
-----
## Tests

---------
There is a small test suite that validates argument/env validation for
`ddns.py` without making network calls. Run it with:

```bash
python3 -m unittest discover -v
```

Deployment notes
----------------
## Deployment notes

---------

- Prefer injecting `CLOUDFLARE_API_TOKEN` from your host's environment/secret
store rather than embedding it in crontab or files.
- Use the included `ddns.timer` / `ddns.service` example or `cron.example` to
schedule periodic runs (every 15 minutes recommended).

Token file option
-----------------
## Token file option

---------
If you store the token on disk (less recommended), create `~/.cloudflare_token`
with strict permissions and ensure only the first line contains the token:

Expand All @@ -109,17 +123,20 @@ chmod 600 ~/.cloudflare_token

`run_ddns.sh` will read and trim the first line if no env var/flag is provided.

Locking and non-overlap
------------------------
## Locking and non-overlap

---------
The runner uses `/tmp/ddns-runner.lock` (flock) to avoid overlapping runs.

License & contribution
----------------------
## License & contribution

---------
This utility is MIT-like in spirit — adapt as needed, but never commit
secrets to source. Use CI secrets or a secret manager for deployments.

Pre-commit (optional but recommended)
------------------------------------
## Pre-commit (optional but recommended)

---------
This repo includes a `.pre-commit-config.yaml` with recommended checks:

- ruff (auto-fix) and pylint for Python linting
Expand Down
Loading