Skip to content

Latest commit

Β 

History

History
471 lines (372 loc) Β· 20.2 KB

File metadata and controls

471 lines (372 loc) Β· 20.2 KB

DDNS Agent Development Guide

Portable project instructions for coding agents. The closest AGENTS.md takes precedence.

Table of Contents

  1. Project Overview
  2. Project Architecture
  3. Agent Development Model
  4. Testing & Validation
  5. Troubleshooting

Project Overview

What is DDNS?

DDNS is a Python-based Dynamic DNS client that automatically updates DNS records to match the current IP address. It supports:

  • Multiple DNS Providers: 15+ providers including Cloudflare, DNSPod, AliDNS, etc.
  • Dual Stack: IPv4 and IPv6 support
  • Multiple Platforms: Docker, binary executables, pip installation, and source code
  • Flexible Configuration: Command-line arguments, JSON files, and environment variables
  • Advanced Features: Multi-domain support, HTTP proxy, caching, scheduled tasks

Key Technologies

  • Language: Python (2.7+ and 3.x compatible)
  • Testing: unittest (default) and pytest (optional)
  • Linting/Formatting: ruff
  • CI/CD: GitHub Actions
  • Containerization: Docker (multi-architecture support)
  • Packaging: PyPI, Nuitka (for binaries)

Portable Agent Definitions

  • AGENTS.md files contain project and directory rules.
  • .agents/skills/*/SKILL.md contains reusable, client-neutral workflows.
  • .github/agents/*.agent.md is a thin GitHub Copilot adapter for tool boundaries and role selection.
  • Do not duplicate a Skill in client-specific directories.
  • The default coding agent owns general project work; use a domain agent only when its narrower context is useful.

Project Status

  • License: MIT
  • Python Versions: 2.7, 3.6, 3.7, 3.8, 3.9, 3.10, 3.11, 3.12, 3.13, 3.14
  • Platforms: Windows, Linux, macOS
  • Architectures: amd64, arm64, arm/v7, arm/v6, 386, ppc64le, riscv64, s390x

Project Architecture

Directory Structure

Here is the folder and file structure for the DDNS project.

Format: <TAB depth>{filename}:<TAB>{description}

.github/:	GitHub configuration
	workflows/:	CI/CD workflows (build, publish, test)
	instructions/:	Agent instructions (python.instructions.md)
	agents/:	Thin GitHub Copilot agent profiles
	copilot-instructions.md:	GitHub Copilot instructions

.agents/:	Portable agent workflows
	skills/:	Agent Skills specification directories

ddns/:	Main application code
	__init__.py:	Package initialization and version info
	__main__.py:	Entry point for module execution
	cache.py:	Cache management
	http_config.py:	Shared Web and MCP HTTP listener settings
	ip.py:	IP address detection logic
	mcp.py:	Model Context Protocol helper utilities
	mcp_http.py:	MCP Streamable HTTP transport

	config/:	Configuration management
		__init__.py
		cli.py:	Command-line argument parsing
		config.py:	Configuration loading and merging
		env.py:	Environment variable parsing
		file.py:	JSON file configuration

	provider/:	DNS provider implementations
		__init__.py:	Provider registry
		_base.py:	Abstract base classes (SimpleProvider, BaseProvider)
		_signature.py:	HMAC signature utilities
		alidns.py:	Alibaba Cloud DNS
		aliesa.py:	Alibaba Cloud ESA
		callback.py:	Custom webhook callbacks
		cloudflare.py:	Cloudflare DNS
		cloudns.py:	ClouDNS
		debug.py:	Debug provider
		dnscom.py:	DNS.COM
		dnspod.py:	DNSPod (China)
		dnspod_com.py:	DNSPod International
		edgeone.py:	Tencent EdgeOne
		edgeone_dns.py:	Tencent EdgeOne DNS
		he.py:	Hurricane Electric
		huaweidns.py:	Huawei Cloud DNS
		namesilo.py:	NameSilo
		noip.py:	No-IP
		tencentcloud.py:	Tencent Cloud DNS
		west.py:	West.cn DNS

	scheduler/:	Task scheduling implementations
		__init__.py
		_base.py:	Base scheduler class
		cron.py:	Cron-based scheduler (Linux/macOS)
		launchd.py:	macOS launchd scheduler
		schtasks.py:	Windows Task Scheduler
		systemd.py:	Linux systemd timer

	util/:	Utility modules
		__init__.py
		comment.py:	Comment handling
		fileio.py:	File I/O operations
		http.py:	HTTP client with proxy support
		try_run.py:	Safe command execution

	web/:	Embedded management dashboard
		__init__.py:	Dashboard package exports
		scheduler.py:	In-process dashboard synchronization scheduler
		server.py:	Local-only embedded dashboard HTTP server
		service.py:	Dashboard data and configuration services

tests/:	Unit tests
	__init__.py:	Test initialization (path setup)
	base_test.py:	Shared test utilities and base classes
	README.md:	Testing documentation
	config/:	Test configuration files
	scripts/:	Test helper scripts
	test_cache.py:	Cache tests
	test_config_*.py:	Configuration tests
	test_ip.py:	IP detection tests
	test_mcp_http.py:	MCP Streamable HTTP tests
	test_provider_*.py:	Provider-specific tests
	test_scheduler_*.py:	Scheduler tests
	test_util_*.py:	Utility tests

docs/:	Documentation (VitePress-based)
	AGENTS.md:	Documentation-specific agent rules
	.vitepress/:	VitePress configuration and theme
	
	config/:	Configuration documentation (Chinese)
		cli.md:	CLI usage guide
		env.md:	Environment variables guide
		json.md:	JSON configuration guide
		mcp.md:	MCP server guide

	dev/:	Developer guides (Chinese)
		provider.md:	Provider development guide
		config.md:	Configuration system design

	providers/:	Provider-specific documentation (Chinese)
		README.md:	Provider list and overview
		51dns.md:	51DNS provider guide
		alidns.md:	Alibaba Cloud DNS guide
		aliesa.md:	Alibaba Cloud ESA guide
		callback.md:	Custom webhook callbacks guide
		cloudflare.md:	Cloudflare DNS guide
		cloudns.md:	ClouDNS guide
		debug.md:	Debug provider guide
		dnscom.md:	DNS.COM provider guide
		dnspod.md:	DNSPod (China) guide
		dnspod_com.md:	DNSPod International guide
		edgeone.md:	Tencent EdgeOne guide
		edgeone_dns.md:	Tencent EdgeOne DNS guide
		he.md:	Hurricane Electric guide
		huaweidns.md:	Huawei Cloud DNS guide
		namesilo.md:	NameSilo guide
		noip.md:	No-IP guide
		tencentcloud.md:	Tencent Cloud DNS guide
		west.md:	West.cn DNS guide

	en/:	English documentation
		config/:	English configuration guides (mirrors config/)
		dev/:	English developer guides (mirrors dev/)
		providers/:	English provider guides (mirrors providers/)
		docker.md:	Docker documentation
		install.md:	Installation guide

	public/:	Public static assets
		img/:	Images and diagrams
		schema/:	JSON schema files (symlink)
		tests/:	Test configuration examples

	docker.md:	Docker documentation (Chinese)
	install.md:	Installation guide (Chinese)
	release.md:	Release notes (Chinese)

docker/:	Docker configuration
	Dockerfile:	Main Dockerfile
	glibc.Dockerfile:	glibc-based build
	musl.Dockerfile:	musl-based build
	entrypoint.sh:	Container entrypoint script

schema/:	JSON schemas
	v2.json:	Legacy schema v2
	v2.8.json:	Legacy schema v2.8
	v4.0.json:	Previous schema v4.0
	v4.1.json:	Latest schema v4.1

tools/:	Python 3.12+ repository maintenance tools
run.py:	Direct run script
pyproject.toml:	Python project configuration
setup.cfg:	Setup configuration
.gitignore:	Git ignore rules
LICENSE:	MIT License
README.md:	Main README (Chinese)
README.en.md:	Main README (English)

Module Dependencies

ddns/__main__.py
    β”œβ”€β”€ ddns.config.*           # Configuration loading
    β”‚   β”œβ”€β”€ cli                 # Command-line parsing
    β”‚   β”œβ”€β”€ env                 # Environment variables
    β”‚   β”œβ”€β”€ file                # JSON file loading
    β”‚   └── config              # Config merging and validation
    β”‚
    β”œβ”€β”€ ddns.ip                 # IP address detection
    β”‚   └── ddns.util.http      # HTTP client for public IP APIs
    β”‚
    β”œβ”€β”€ ddns.provider.*         # DNS provider implementations
    β”‚   β”œβ”€β”€ _base               # Base classes (SimpleProvider, BaseProvider)
    β”‚   β”œβ”€β”€ _signature          # HMAC signature for cloud APIs
    β”‚   └── ddns.util.http      # HTTP client for API requests
    β”‚
    β”œβ”€β”€ ddns.cache              # Caching to reduce API calls
    β”‚   └── ddns.util.fileio    # File operations
    β”‚
    └── ddns.scheduler.*        # Task scheduling
        └── ddns.util.try_run   # Safe command execution

Core Components

1. Provider System

  • BaseProvider: Full CRUD DNS provider (query, create, update records)

    • Used by: Cloudflare, AliDNS, DNSPod, TencentCloud, EdgeOne, etc.
    • Features: Automatic zone detection, record management, caching support
  • SimpleProvider: Simple update-only DNS provider

    • Used by: HE.net, No-IP, Debug, Callback
    • Features: Direct record updates without querying

2. Configuration System

Three-layer priority system:

  1. Command-line arguments (highest priority) - via ddns.config.cli
  2. JSON configuration files - via ddns.config.file
  3. Environment variables (lowest priority) - via ddns.config.env

3. IP Detection System

Multiple methods supported (via ddns.ip):

  • Network interface (by index number)
  • Default route IP
  • Public IP (via external APIs)
  • URL-based (custom API endpoint)
  • Regex matching (from ifconfig/ipconfig output)
  • Command execution (custom script)
  • Shell execution (system shell command)

4. Scheduler System

Platform-specific implementations:

  • Linux: systemd timers or cron
  • macOS: launchd or cron
  • Windows: Task Scheduler (schtasks)
  • Docker: Built-in cron with configurable intervals

Agent Development Model

Agent Quick Start

Classify the task first, then read only the nearest code, tests, docs, and schema for that lane.

  • Provider: ddns/provider/, tests/test_provider_*.py, docs/providers/, docs/en/providers/
  • Config/schema: ddns/config/, schema/, tests/test_config_*.py, docs/config/, docs/en/config/
  • IP/HTTP: ddns/ip.py, ddns/util/http.py, tests/test_ip.py, tests/test_util_http*.py
  • Scheduler: ddns/scheduler/, tests/test_scheduler_*.py
  • Web/MCP: ddns/web/, web/, ddns/mcp.py, ddns/mcp_http.py, ddns/http_config.py, tests/test_web.py, tests/test_mcp*.py
  • Docs: README*.md, docs/, docs/AGENTS.md
  • Build/release: pyproject.toml, run.py, .github/patch.py, docker/, .github/workflows/
  • Agent control plane: AGENTS.md, .agents/skills/, .github/agents/, .github/copilot-instructions.md, .github/instructions/, tools/

Use rg / rg --files for discovery, make narrow edits, validate the touched behavior, and report any command that could not run. A task is complete only when code, tests, schemas, docs, and generated metadata affected by the behavior are consistent.

Source execution and validation

  • Run Python commands from the repository root. python -m ddns --help and python run.py --help work without installing DDNS or adding runtime dependencies.
  • web/ contains the dashboard's plain HTML/CSS/JavaScript assets, served and packaged by Python. It has no npm build. docs/ is the separate VitePress site and the only npm project.
  • ddns/web/service.py shares configuration, status, and synchronization behavior with MCP. ddns/http_config.py shares HTTP listener settings between Web and MCP HTTP; cover both callers when changing shared behavior.
  • ddns/config/field-model.json supplies provider and field metadata to the dashboard and documentation configuration studio. Keep the registry, CLI, latest schema, and bilingual docs aligned; python tools/check.py --providers checks provider parity without installing dependencies.
  • After focused tests, use python tools/check.py --changed for lane-specific checks. It includes merge-base, staged, unstaged, and untracked changes; unknown paths deliberately select all lanes. Set DDNS_CHECK_BASE_REF for a non-default comparison base. Use --all when a complete cross-lane check is needed, not for every iteration.
  • tests/e2e.py is an explicit, offline suite and is not included in unittest discover tests. Run it separately for CLI, Web, MCP, or shared runtime changes. Sample configurations under tests/config/ are not a substitute for its loopback fixtures.
  • .github/patch.py transforms source and packaging metadata in place. Use it only for the relevant build in a disposable checkout, not for ordinary setup, linting, or source tests. Keep real scheduler lifecycle and platform/artifact validation in the appropriate CI environments.

Useful Commands

python -m ddns --help
python run.py --help
pip install ddns
ddns --help
docker run --rm newfuture/ddns:latest --help
curl -fsSL https://ddns.newfuture.cc/install.sh | sh
python -m ddns -c config.json
python -m ddns --dns=cloudflare --id=EMAIL --token=TOKEN --ipv4=domain.com
python -m ddns --debug
python -m ddns --dns=debug --ipv4=test.com --debug
ddns task --install 5
ddns task --enable

Linux/macOS scheduled tasks use systemd, cron, or launchd; Windows uses the release binary and ddns task --install 5.


Development Rules

Hard Rules

Follow .github/instructions/python.instructions.md for shipped Python and tests. Follow tools/AGENTS.md for maintenance tooling.

  • Use only standard-library runtime dependencies.
  • Preserve Python 2.7 and 3.x compatibility: no f-strings, annotations, async/await, or Python 3-only syntax.
  • Use type comments, for example # type: (...) -> ReturnType.
  • Keep CLI flags, provider names, config keys, schemas, and cache behavior backward compatible unless explicitly asked otherwise.
  • Do not reformat unrelated files or modernize stable code for style alone.

Change Flow

  1. Start from an approved issue, feature, or maintenance goal.
  2. Read the closest implementation, tests, docs, schema, and AGENTS.md.
  3. State the implementation plan, compatibility impact, and acceptance checks.
  4. Mirror established patterns instead of inventing new abstractions.
  5. Change code, tests, schemas, bilingual docs, and metadata together.
  6. Run focused validation first, then the full affected suite.
  7. Self-review the diff for unrelated edits, secrets, compatibility, and missing artifacts.
  8. Continue through CI and review feedback until merge-ready or escalate with evidence.

Definition of Done by Lane

Lane Required artifacts Required evidence
Core IP/HTTP/cache implementation, regression tests, offline fixtures, behavior docs focused unit tests, offline E2E, Python matrix
Config/schema/CLI parser behavior, field model, latest schema, Chinese/English docs config tests, schema checks, docs build
Provider implementation, registry/aliases, field model, tests, schema, bilingual docs, navigation provider/base tests, provider consistency check, docs build
Web service/API, static assets, auth/scheduler behavior, package resources Web tests, Web E2E, wheel/sdist install
Scheduler/install OS implementation, CLI, lifecycle scripts, install docs platform and install matrices
MCP protocol behavior, schemas/annotations, lifecycle, redaction, docs MCP tests, modern/legacy E2E, package/binary tests
Docs/site Chinese/English parity, links, navigation, examples, llms.txt documentation contracts and VitePress build
Build/release transformations, artifacts, matrices, release notes package/binary/container checks and protected rehearsal
Agent/workflow instructions, permissions, validation logic agent contracts and human review

Provider Changes

  • Use BaseProvider for query/create/update APIs and SimpleProvider for update-only APIs.
  • Register new providers in ddns/provider/__init__.py.
  • Update canonical metadata in ddns/config/field-model.json.
  • Add mocked tests in tests/test_provider_<provider>.py; never require real credentials or live provider APIs.
  • Update both docs/providers/<provider>.md and docs/en/providers/<provider>.md.
  • Update both latest schema enums, CLI choices, provider indexes, navigation, and docs/llms.txt.
  • See docs/dev/provider.md and docs/en/dev/provider.md for full provider method signatures.
  • Follow ddns/provider/AGENTS.md and .agents/skills/provider-development/SKILL.md.

Documentation

Keep Chinese and English docs aligned. Preserve code blocks, option names, JSON keys, CLI flags, and provider IDs exactly across translations. Link Chinese docs to Chinese pages and English docs to docs/en/ pages.

Follow docs/AGENTS.md and .agents/skills/documentation-maintenance/SKILL.md. Treat docs/public/install.sh and docs/esa.js as executable, high-risk files rather than ordinary prose.

Build and Release

Read the current workflows and Dockerfiles instead of relying on remembered versions or matrices. Do not publish, access release credentials, weaken required checks, disable caches, or remove platform coverage. Follow .agents/skills/build-release-maintenance/SKILL.md.


Testing & Validation

Run the smallest useful test first, then broaden when shared behavior changed.

python -m unittest tests.test_provider_cloudflare -v
python -m unittest tests.test_config_config -v
python -m unittest tests.test_ip -v
python -m unittest discover tests -v
python -m pytest tests/ -v  # optional, when pytest is installed
ruff check .
ruff format --check .

Inspect proposed lint and formatting fixes and limit them to files touched by the task.

Use these focused targets as a guide:

  • Provider: python -m unittest tests.test_provider_<provider> -v
  • Config/schema: python -m unittest discover tests -p "test_config*.py" -v
  • IP/HTTP: python -m unittest tests.test_ip tests.test_util_http tests.test_util_http_retry tests.test_util_http_proxy_list -v
  • Scheduler: python -m unittest tests.test_scheduler_<name> -v
  • Broad shared change: python -m unittest discover tests -v

For touched files or examples:

python -m py_compile ddns/provider/myprovider.py
python -m json.tool config.json

Provider tests should import from base_test; other tests should import from tests/__init__.py. Mock HTTP calls and assert request details, response parsing, and error handling.


Troubleshooting

  1. Reproduce with the smallest command, fixture, or unit test.
  2. Locate the layer: config parsing, IP detection, provider mapping, HTTP transport, cache, or scheduler.
  3. Read the nearest passing test and nearest similar implementation.
  4. Fix root cause, add a regression test when behavior changed, and re-run focused validation.

Common checks:

  • Import error: file exists, provider registered, test path setup uses tests/__init__.py or tests/base_test.py.
  • Syntax error: remove Python 3-only syntax and keep Python 2.7 compatibility.
  • Auth/signature issue: verify credential shape and signing with mocked tests; never print real tokens.
  • Record not updated: inspect cache, record type, line, TTL, domain split, and provider response parsing.
  • Proxy/network issue: compare with ddns/util/http.py; use --proxy=DIRECT or --ssl=false only as diagnostics.
  • Schema mismatch: update schema/v4.1.json and matching config tests together.
  • Test failure: inspect mock return values and mock_http.call_args.
  • Linting issue: run ruff check . and ruff format --check ., then review fixes only for the affected files.
python -m ddns --debug --dns=myprovider --ipv4=test.com
python -m ddns --debug --log_file=debug.log
python -m ddns --dns=debug --ipv4=test.com --debug
rm -f /tmp/ddns.cache

Use cache removal only when debugging stale local state. Avoid destructive git recovery unless the user explicitly requests it.


Safety and Escalation

  • Prefer small, reviewable changes that follow existing patterns.
  • Fix root causes and add tests for regressions.
  • Preserve user changes in the working tree; never reset or reformat unrelated files.
  • Treat configs, logs, environment variables, API tokens, and provider credentials as sensitive.
  • Prefer mocked or dry-run validation; ask before using real credentials, provider APIs, or scheduler installation on a host.
  • Use structured parsers for JSON, URLs, and HTTP data.
  • Refactor only when it directly supports the task or removes clear local duplication.
  • Require human direction for file/provider/config-key renames, compatibility breaks, security policy, workflow permissions, credentials, and publication.
  • For large changes, explain goal, alternatives, impact, validation plan, and rollback before implementation.
  • When asked to commit or draft PR text, use conventional commits such as fix(util.http): handle proxy errors.

Version: 1.1.0 Last Updated: 2026-08-21 Maintained by: DDNS Project Contributors