- Added configuration management using Viper in internal/config/config.go - Implemented ClientConfig, ServerConfig, TLSConfig, HetznerConfig, UpstreamConfig, and main Config struct. - Created LoadConfig function to read and validate configuration files. - Developed Hetzner DNS provider in internal/provider/hetzner/hetzner.go with methods for updating DNS records. - Added comprehensive unit tests for configuration loading and Hetzner provider functionality. - Established HTTP server with metrics and update endpoint in internal/server/server.go. - Implemented request handling, authorization, and error management in the server. - Created integration tests for the Hetzner provider API interactions. - Removed legacy dynamic DNS integration tests in favor of the new API-based approach.
147 lines
4.0 KiB
Markdown
147 lines
4.0 KiB
Markdown
# Development Plan for UpDNS
|
||
|
||
A step-by-step roadmap to build, test, and evolve the Go‑based DynDNS proxy—including support for both exact hostnames and wildcard domains.
|
||
|
||
---
|
||
|
||
## Phase 1: Project Setup (Week 1)
|
||
|
||
1. **Repository Initialization**
|
||
- `go mod init git.cloonar.com/cloonar/updns`
|
||
- Create directory structure:
|
||
```
|
||
cmd/updns
|
||
internal/config
|
||
internal/server
|
||
internal/provider
|
||
test/
|
||
```
|
||
|
||
2. **Configuration Loader**
|
||
- Use [spf13/viper] to parse YAML/JSON/TOML.
|
||
- Define `Config` struct with:
|
||
```go
|
||
type ClientConfig struct {
|
||
Secret string `mapstructure:"secret"`
|
||
Exact []string `mapstructure:"exact"`
|
||
Wildcard []string `mapstructure:"wildcard"`
|
||
}
|
||
|
||
type Config struct {
|
||
Server ServerConfig `mapstructure:"server"`
|
||
Upstream UpstreamConfig `mapstructure:"upstream"`
|
||
Clients map[string]ClientConfig `mapstructure:"clients"`
|
||
}
|
||
```
|
||
- Validate that at least one of `Exact` or `Wildcard` is set per client.
|
||
|
||
3. **Main & CLI**
|
||
- Parse `--config` flag.
|
||
- Load config, handle errors, and pass into server setup.
|
||
|
||
---
|
||
|
||
## Phase 2: HTTP API & Authentication (Week 2)
|
||
|
||
1. **Server Implementation**
|
||
- Choose router: `net/http` or `gin-gonic/gin`.
|
||
- Define route `POST /update`.
|
||
|
||
2. **Authentication & Authorization**
|
||
- Middleware to:
|
||
- Lookup client by `key`.
|
||
- Verify `secret` matches stored token.
|
||
- Check that requested `host` is allowed by matching either:
|
||
- An entry in `Exact` (full string equality), or
|
||
- A wildcard base domain in `Wildcard`, e.g. `example.com` matches `foo.example.com` and `example.com`.
|
||
- Reject requests with clear error if host not authorized.
|
||
|
||
3. **Request Validation**
|
||
- Validate JSON payload: `key`, `secret`, `host`, optional `ip`.
|
||
- Default `ip` to requestor’s IP if omitted.
|
||
|
||
---
|
||
|
||
## Phase 3: Hetzner Provider Integration (Week 3)
|
||
|
||
1. **Provider Interface**
|
||
```go
|
||
type Provider interface {
|
||
UpdateRecord(ctx context.Context, domain, ip string) error
|
||
}
|
||
```
|
||
|
||
2. **Hetzner Implementation**
|
||
- On startup, fetch or cache record IDs by domain.
|
||
- Use Hetzner’s DDNS API to PATCH IP on update.
|
||
|
||
3. **Error Handling & Retries**
|
||
- Retry transient errors with exponential backoff.
|
||
- Surface permanent errors in response.
|
||
|
||
---
|
||
|
||
## Phase 4: Testing & CI (Week 4)
|
||
|
||
1. **Unit Tests**
|
||
- Config parsing, ensuring `Exact` and `Wildcard` fields load correctly.
|
||
- Authorization logic: hosts matching exact list vs. wildcard list.
|
||
- Secret validation.
|
||
|
||
2. **Integration Tests**
|
||
- Use `httptest.Server` to simulate upstream.
|
||
- Test success and failure for:
|
||
- Exact hostname updates.
|
||
- Subdomain updates via wildcard rules.
|
||
- Unauthorized host attempts.
|
||
|
||
3. **CI Pipeline**
|
||
- GitHub Actions to run `go fmt`, `go vet`, `go test`.
|
||
- Build artifacts for Linux/macOS.
|
||
|
||
---
|
||
|
||
## Phase 5: TLS, Logging & Metrics (Week 5)
|
||
|
||
1. **TLS Support**
|
||
- Enable HTTPS when `tls.enabled` in config.
|
||
- Load cert/key files.
|
||
|
||
2. **Structured Logging**
|
||
- Integrate `uber/zap` or `sirupsen/logrus`.
|
||
- Log requests, responses, errors, and authorization decisions (with no secrets).
|
||
|
||
3. **Metrics**
|
||
- Expose Prometheus `/metrics` endpoint.
|
||
- Track:
|
||
- Total updates.
|
||
- Successes vs. failures.
|
||
- Requests authorized via exact vs. wildcard.
|
||
|
||
---
|
||
|
||
## Phase 6: Extensibility & Additional Providers (Week 6)
|
||
|
||
1. **Provider Factory**
|
||
- Map `upstream.provider` string to constructor.
|
||
|
||
2. **Cloudflare & AWS Stubs**
|
||
- Scaffold `cloudflare` and `aws` provider packages.
|
||
- Document config for each.
|
||
|
||
3. **Documentation Update**
|
||
- Update README to reflect exact + wildcard support and new provider instructions.
|
||
|
||
---
|
||
|
||
## Phase 7: Deployment & Release (Week 7)
|
||
|
||
1. **Dockerization**
|
||
- Write `Dockerfile` and example `docker-compose.yml`.
|
||
|
||
2. **Optional Helm Chart**
|
||
- Package for Kubernetes.
|
||
|
||
3. **Release v1.0.0**
|
||
- Tag in GitHub, attach binaries, update changelog.
|