mirror of
https://github.com/qdm12/ddns-updater.git
synced 2026-04-24 01:52:35 -04:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f4e1cca222 | ||
|
|
79efca2bf4 | ||
|
|
f17be83112 | ||
|
|
2a9e41c646 | ||
|
|
8664aa0e5c | ||
|
|
4c840f4bb6 | ||
|
|
7230fea962 | ||
|
|
8aa6aba8b7 | ||
|
|
1d8690fb14 | ||
|
|
2922d441d2 | ||
|
|
607ca8f0b8 |
@@ -1 +1 @@
|
||||
FROM ghcr.io/qdm12/godevcontainer:v0.22.0-alpine
|
||||
FROM qmcgaw/godevcontainer
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Development container that can be used with VSCode.
|
||||
|
||||
It works on Linux, Windows (WSL2) and OSX.
|
||||
It works on Linux, Windows and OSX.
|
||||
|
||||
## Requirements
|
||||
|
||||
@@ -13,41 +13,49 @@ It works on Linux, Windows (WSL2) and OSX.
|
||||
|
||||
## Setup
|
||||
|
||||
1. Create the following files and directory on your host if you don't have them:
|
||||
1. Create the following files on your host if you don't have them:
|
||||
|
||||
```sh
|
||||
touch ~/.gitconfig ~/.zsh_history
|
||||
mkdir -p ~/.ssh
|
||||
```
|
||||
|
||||
1. **For OSX hosts**: ensure the project directory and your home directory `~` are accessible by Docker.
|
||||
Note that the development container will create the empty directories `~/.docker`, `~/.ssh` and `~/.kube` if you don't have them.
|
||||
|
||||
1. **For Docker on OSX or Windows without WSL**: ensure your home directory `~` is accessible by Docker.
|
||||
1. Open the command palette in Visual Studio Code (CTRL+SHIFT+P).
|
||||
1. Select `Dev-Containers: Open Folder in Container...` and choose the project directory.
|
||||
1. Select `Dev Containers: Open Folder in Container...` and choose the project directory.
|
||||
|
||||
## Customization
|
||||
|
||||
For any customization to take effect, you should "rebuild and reopen":
|
||||
### Customize the image
|
||||
|
||||
1. Open the command palette in Visual Studio Code (CTRL+SHIFT+P)
|
||||
2. Select `Dev-Containers: Rebuild Container`
|
||||
You can make changes to the [Dockerfile](Dockerfile) and then rebuild the image. For example, your Dockerfile could be:
|
||||
|
||||
Changes you can make are notably:
|
||||
```Dockerfile
|
||||
FROM qmcgaw/godevcontainer
|
||||
RUN apk add curl
|
||||
```
|
||||
|
||||
- Changes to the Docker image in [Dockerfile](Dockerfile)
|
||||
- Changes to VSCode **settings** and **extensions** in [devcontainer.json](devcontainer.json).
|
||||
- Change the entrypoint script by adding a bind mount in [devcontainer.json](devcontainer.json) of a shell script to `/root/.welcome.sh` to replace the [current welcome script](https://github.com/qdm12/godevcontainer/blob/master/shell/.welcome.sh). For example:
|
||||
To rebuild the image, either:
|
||||
|
||||
```json
|
||||
// Welcome script
|
||||
{
|
||||
"source": "/yourpath/.welcome.sh",
|
||||
"target": "/root/.welcome.sh",
|
||||
"type": "bind"
|
||||
},
|
||||
```
|
||||
- With VSCode through the command palette, select `Remote-Containers: Rebuild and reopen in container`
|
||||
- With a terminal, go to this directory and `docker-compose build`
|
||||
|
||||
- Change the `vscode` service container configuration either in [docker-compose.yml](docker-compose.yml) or in [devcontainer.json](devcontainer.json).
|
||||
- Add other services in [docker-compose.yml](docker-compose.yml) to run together with the development VSCode service container. For example to add a test database:
|
||||
### Customize VS code settings
|
||||
|
||||
You can customize **settings** and **extensions** in the [devcontainer.json](devcontainer.json) definition file.
|
||||
|
||||
### Entrypoint script
|
||||
|
||||
You can bind mount a shell script to `/root/.welcome.sh` to replace the [current welcome script](https://github.com/qdm12/basedevcontainer/blob/master/shell/.welcome.sh).
|
||||
|
||||
### Publish a port
|
||||
|
||||
To access a port from your host to your development container, publish a port in [docker-compose.yml](docker-compose.yml). You can also now do it directly with VSCode without restarting the container.
|
||||
|
||||
### Run other services
|
||||
|
||||
1. Modify [docker-compose.yml](docker-compose.yml) to launch other services at the same time as this development container, such as a test database:
|
||||
|
||||
```yml
|
||||
database:
|
||||
@@ -57,4 +65,5 @@ Changes you can make are notably:
|
||||
POSTGRES_PASSWORD: password
|
||||
```
|
||||
|
||||
- More options are documented in the [devcontainer.json reference](https://containers.dev/implementors/json_reference/).
|
||||
1. In [devcontainer.json](devcontainer.json), change the line `"runServices": ["vscode"],` to `"runServices": ["vscode", "database"],`.
|
||||
1. In the VS code command palette, rebuild the container.
|
||||
|
||||
@@ -1,51 +1,16 @@
|
||||
{
|
||||
// See https://containers.dev/implementors/json_reference/
|
||||
// User defined settings
|
||||
"containerEnv": {
|
||||
"TZ": ""
|
||||
},
|
||||
// Fixed settings
|
||||
"name": "ddns-dev",
|
||||
"postCreateCommand": "~/.windows.sh && go mod download && go mod tidy",
|
||||
"dockerComposeFile": "docker-compose.yml",
|
||||
"overrideCommand": true,
|
||||
"service": "vscode",
|
||||
"workspaceFolder": "/workspace",
|
||||
"mounts": [
|
||||
// Source code
|
||||
{
|
||||
"source": "../",
|
||||
"target": "/workspace",
|
||||
"type": "bind"
|
||||
},
|
||||
// Zsh commands history persistence
|
||||
{
|
||||
"source": "${localEnv:HOME}/.zsh_history",
|
||||
"target": "/root/.zsh_history",
|
||||
"type": "bind"
|
||||
},
|
||||
// Git configuration file
|
||||
{
|
||||
"source": "${localEnv:HOME}/.gitconfig",
|
||||
"target": "/root/.gitconfig",
|
||||
"type": "bind"
|
||||
},
|
||||
// SSH directory for Linux, OSX and WSL
|
||||
// On Linux and OSX, a symlink /mnt/ssh <-> ~/.ssh is
|
||||
// created in the container. On Windows, files are copied
|
||||
// from /mnt/ssh to ~/.ssh to fix permissions.
|
||||
{
|
||||
"source": "${localEnv:HOME}/.ssh",
|
||||
"target": "/mnt/ssh",
|
||||
"type": "bind"
|
||||
},
|
||||
// Docker socket to access the host Docker server
|
||||
{
|
||||
"source": "/var/run/docker.sock",
|
||||
"target": "/var/run/docker.sock",
|
||||
"type": "bind"
|
||||
}
|
||||
"dockerComposeFile": [
|
||||
"docker-compose.yml"
|
||||
],
|
||||
"service": "vscode",
|
||||
"runServices": [
|
||||
"vscode"
|
||||
],
|
||||
"shutdownAction": "stopCompose",
|
||||
"postCreateCommand": "~/.windows.sh && go mod download && go mod tidy",
|
||||
"workspaceFolder": "/workspace",
|
||||
// "overrideCommand": "",
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
@@ -93,16 +58,12 @@
|
||||
"go.lintOnSave": "package",
|
||||
"[go]": {
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.organizeImports": "always"
|
||||
"source.organizeImports": true
|
||||
}
|
||||
},
|
||||
"gopls": {
|
||||
"formatting.gofumpt": true,
|
||||
"usePlaceholders": false,
|
||||
"staticcheck": true,
|
||||
"ui.diagnostic.analyses": {
|
||||
"ST1000": false
|
||||
},
|
||||
"vulncheck": "Imports"
|
||||
},
|
||||
"remote.extensionKind": {
|
||||
|
||||
@@ -1,3 +1,27 @@
|
||||
version: "3.7"
|
||||
|
||||
services:
|
||||
vscode:
|
||||
build: .
|
||||
volumes:
|
||||
- ../:/workspace
|
||||
# Docker socket to access Docker server
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
# SSH directory for Linux, OSX and WSL
|
||||
# On Linux and OSX, a symlink /mnt/ssh <-> ~/.ssh is
|
||||
# created in the container. On Windows, files are copied
|
||||
# from /mnt/ssh to ~/.ssh to fix permissions.
|
||||
- ~/.ssh:/mnt/ssh
|
||||
# Shell history persistence
|
||||
- ~/.zsh_history:/root/.zsh_history
|
||||
# Git config
|
||||
- ~/.gitconfig:/root/.gitconfig
|
||||
environment:
|
||||
- TZ=
|
||||
cap_add:
|
||||
# For debugging with dlv
|
||||
- SYS_PTRACE
|
||||
security_opt:
|
||||
# For debugging with dlv
|
||||
- seccomp:unconfined
|
||||
entrypoint: [ "zsh", "-c", "while sleep 1000; do :; done" ]
|
||||
|
||||
8
.github/CONTRIBUTING.md
vendored
8
.github/CONTRIBUTING.md
vendored
@@ -50,9 +50,9 @@ You might want to use an editor such as [Visual Studio Code](https://code.visual
|
||||
|
||||
- Test the code: `go test ./...`
|
||||
- Lint the code `golangci-lint run`
|
||||
- Build the program: `go build -o app cmd/ddns-updater/main.go`
|
||||
- Build the Docker image (tests and lint included): `docker build -t ghcr.io/qdm12/ddns-updater .`
|
||||
- Run the Docker container: `docker run -it --rm -v /yourpath/data:/updater/data ghcr.io/qdm12/ddns-updater`
|
||||
- Build the program: `go build -o app cmd/updater/main.go`
|
||||
- Build the Docker image (tests and lint included): `docker build -t qmcgaw/ddns-updater .`
|
||||
- Run the Docker container: `docker run -it --rm -v /yourpath/data:/updater/data qmcgaw/ddns-updater`
|
||||
|
||||
## Add a new DNS provider
|
||||
|
||||
@@ -77,7 +77,7 @@ In more detailed steps:
|
||||
|
||||
```go
|
||||
case constants.Example:
|
||||
return example.New(data, domain, owner, ipVersion, ipv6Suffix)
|
||||
return example.New(data, domain, host, ipVersion, ipv6Suffix)
|
||||
```
|
||||
|
||||
1. Copy the file [`docs/example.md`](../docs/example.md) to `docs/yourprovider.md` and modify it to fit the configuration and domain setup of your DNS provider. There are a few `<!-- ... -->` comments indicating what to change, please **remove them** when done.
|
||||
|
||||
34
.github/workflows/build.yml
vendored
34
.github/workflows/build.yml
vendored
@@ -37,7 +37,7 @@ jobs:
|
||||
env:
|
||||
DOCKER_BUILDKIT: "1"
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: reviewdog/action-misspell@v1
|
||||
with:
|
||||
@@ -72,15 +72,15 @@ jobs:
|
||||
contents: read
|
||||
security-events: write
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-go@v6
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
- uses: github/codeql-action/init@v4
|
||||
go-version: "^1.22"
|
||||
- uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: go
|
||||
- uses: github/codeql-action/autobuild@v4
|
||||
- uses: github/codeql-action/analyze@v4
|
||||
- uses: github/codeql-action/autobuild@v3
|
||||
- uses: github/codeql-action/analyze@v3
|
||||
|
||||
publish:
|
||||
if: |
|
||||
@@ -97,7 +97,7 @@ jobs:
|
||||
packages: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 # for gorelease last step
|
||||
|
||||
@@ -105,7 +105,7 @@ jobs:
|
||||
# https://github.com/docker/metadata-action
|
||||
- name: Extract Docker metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@v6
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
flavor: |
|
||||
latest=${{ github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }}
|
||||
@@ -122,15 +122,15 @@ jobs:
|
||||
type=semver,pattern=v{{major}},enable=${{ !startsWith(github.ref, 'refs/tags/v0.') }}
|
||||
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }}
|
||||
|
||||
- uses: docker/setup-qemu-action@v4
|
||||
- uses: docker/setup-buildx-action@v4
|
||||
- uses: docker/setup-qemu-action@v3
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
|
||||
- uses: docker/login-action@v4
|
||||
- uses: docker/login-action@v3
|
||||
with:
|
||||
username: qmcgaw
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
|
||||
- uses: docker/login-action@v4
|
||||
- uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
@@ -141,7 +141,7 @@ jobs:
|
||||
run: echo "::set-output name=value::$(git rev-parse --short HEAD)"
|
||||
|
||||
- name: Build and push final image
|
||||
uses: docker/build-push-action@v7
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
platforms: linux/amd64,linux/386,linux/arm64,linux/arm/v6,linux/arm/v7,linux/s390x,linux/ppc64le,linux/riscv64
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
@@ -153,12 +153,12 @@ jobs:
|
||||
push: true
|
||||
|
||||
- if: github.event_name == 'release'
|
||||
uses: actions/setup-go@v6
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
go-version: 1.22
|
||||
|
||||
- if: github.event_name == 'release'
|
||||
uses: goreleaser/goreleaser-action@v7
|
||||
uses: goreleaser/goreleaser-action@v6
|
||||
with:
|
||||
version: latest
|
||||
args: release --clean --config .github/workflows/configs/.goreleaser.yaml
|
||||
|
||||
2
.github/workflows/configs/.goreleaser.yaml
vendored
2
.github/workflows/configs/.goreleaser.yaml
vendored
@@ -2,7 +2,7 @@ before:
|
||||
hooks:
|
||||
- go mod download
|
||||
builds:
|
||||
- main: ./cmd/ddns-updater/main.go
|
||||
- main: ./cmd/updater/main.go
|
||||
flags:
|
||||
- -trimpath
|
||||
env:
|
||||
|
||||
12
.github/workflows/configs/mlc-config.json
vendored
12
.github/workflows/configs/mlc-config.json
vendored
@@ -4,7 +4,7 @@
|
||||
"pattern": "^http://localhost"
|
||||
},
|
||||
{
|
||||
"pattern": "^https://api(6|64).ipify.org$"
|
||||
"pattern": "^https://api6.ipify.org$"
|
||||
},
|
||||
{
|
||||
"pattern": "^http://ip1.dynupdate6.no-ip.com$"
|
||||
@@ -29,12 +29,6 @@
|
||||
},
|
||||
{
|
||||
"pattern": "^https://www.duckdns.org/$"
|
||||
},
|
||||
{
|
||||
"pattern": "^https://my.vultr.com/settings/#settingsapi$"
|
||||
},
|
||||
{
|
||||
"pattern": "^https://www.namesilo.com"
|
||||
}
|
||||
],
|
||||
"timeout": "20s",
|
||||
@@ -42,8 +36,6 @@
|
||||
"fallbackRetryDelay": "30s",
|
||||
"aliveStatusCodes": [
|
||||
200,
|
||||
206,
|
||||
403,
|
||||
429
|
||||
206
|
||||
]
|
||||
}
|
||||
4
.github/workflows/labels.yml
vendored
4
.github/workflows/labels.yml
vendored
@@ -10,9 +10,9 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
- name: Labeler
|
||||
if: success()
|
||||
uses: crazy-max/ghaction-github-labeler@v6
|
||||
uses: crazy-max/ghaction-github-labeler@v5
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
6
.github/workflows/markdown.yml
vendored
6
.github/workflows/markdown.yml
vendored
@@ -18,9 +18,9 @@ jobs:
|
||||
actions: read
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: DavidAnson/markdownlint-cli2-action@v23
|
||||
- uses: DavidAnson/markdownlint-cli2-action@v16
|
||||
with:
|
||||
globs: "**.md"
|
||||
config: .markdownlint.json
|
||||
@@ -37,7 +37,7 @@ jobs:
|
||||
use-quiet-mode: yes
|
||||
config-file: .github/workflows/configs/mlc-config.json
|
||||
|
||||
- uses: peter-evans/dockerhub-description@v5
|
||||
- uses: peter-evans/dockerhub-description@v4
|
||||
if: github.repository == 'qdm12/ddns-updater' && github.event_name == 'push'
|
||||
with:
|
||||
username: qmcgaw
|
||||
|
||||
@@ -1,70 +1,43 @@
|
||||
version: "2"
|
||||
linters-settings:
|
||||
misspell:
|
||||
locale: US
|
||||
|
||||
formatters:
|
||||
enable:
|
||||
- gci
|
||||
- gofumpt
|
||||
- goimports
|
||||
exclusions:
|
||||
generated: lax
|
||||
paths:
|
||||
- third_party$
|
||||
- builtin$
|
||||
- examples$
|
||||
issues:
|
||||
exclude-rules:
|
||||
- path: _test\.go
|
||||
linters:
|
||||
- containedctx
|
||||
- dupl
|
||||
- goerr113
|
||||
- text: Function `exitHealthchecksio` should pass the context parameter
|
||||
linters:
|
||||
- contextcheck
|
||||
- source: "See https://"
|
||||
linters:
|
||||
- lll
|
||||
|
||||
linters:
|
||||
settings:
|
||||
misspell:
|
||||
locale: US
|
||||
exclusions:
|
||||
generated: lax
|
||||
presets:
|
||||
- comments
|
||||
- common-false-positives
|
||||
- legacy
|
||||
- std-error-handling
|
||||
rules:
|
||||
- linters:
|
||||
- containedctx
|
||||
- dupl
|
||||
- err113
|
||||
path: _test\.go
|
||||
- linters:
|
||||
- contextcheck
|
||||
text: Function `exitHealthchecksio` should pass the context parameter
|
||||
- linters:
|
||||
- lll
|
||||
source: See https://
|
||||
- linters:
|
||||
- revive
|
||||
text: "var-naming: avoid meaningless package names"
|
||||
path: internal\/provider\/utils\/
|
||||
paths:
|
||||
- third_party$
|
||||
- builtin$
|
||||
- examples$
|
||||
enable:
|
||||
# - cyclop
|
||||
- asasalint
|
||||
- asciicheck
|
||||
- bidichk
|
||||
- bodyclose
|
||||
- canonicalheader
|
||||
- containedctx
|
||||
- contextcheck
|
||||
- copyloopvar
|
||||
- decorder
|
||||
- dogsled
|
||||
- dupl
|
||||
- dupword
|
||||
- durationcheck
|
||||
- err113
|
||||
- errchkjson
|
||||
- errname
|
||||
- errorlint
|
||||
- execinquery
|
||||
- exhaustive
|
||||
- fatcontext
|
||||
- exportloopref
|
||||
- forcetypeassert
|
||||
- gci
|
||||
- gocheckcompilerdirectives
|
||||
- gochecknoglobals
|
||||
- gochecknoinits
|
||||
@@ -73,9 +46,11 @@ linters:
|
||||
- goconst
|
||||
- gocritic
|
||||
- gocyclo
|
||||
- godoclint
|
||||
- godot
|
||||
- goerr113
|
||||
- goheader
|
||||
- goimports
|
||||
- gomnd
|
||||
- gomoddirectives
|
||||
- goprintffuncname
|
||||
- gosec
|
||||
@@ -84,16 +59,11 @@ linters:
|
||||
- importas
|
||||
- inamedparam
|
||||
- interfacebloat
|
||||
- intrange
|
||||
- iotamixing
|
||||
- ireturn
|
||||
- lll
|
||||
- maintidx
|
||||
- makezero
|
||||
- mirror
|
||||
- misspell
|
||||
- mnd
|
||||
- modernize
|
||||
- musttag
|
||||
- nakedret
|
||||
- nestif
|
||||
@@ -114,6 +84,7 @@ linters:
|
||||
- sloglint
|
||||
- sqlclosecheck
|
||||
- tagalign
|
||||
- tenv
|
||||
- thelper
|
||||
- tparallel
|
||||
- unconvert
|
||||
|
||||
24
Dockerfile
24
Dockerfile
@@ -1,13 +1,13 @@
|
||||
ARG BUILDPLATFORM=linux/amd64
|
||||
ARG ALPINE_VERSION=3.23
|
||||
ARG GO_VERSION=1.26
|
||||
ARG XCPUTRANSLATE_VERSION=v0.9.0
|
||||
ARG GOLANGCI_LINT_VERSION=v2.11.4
|
||||
ARG MOCKGEN_VERSION=v0.6.0
|
||||
ARG ALPINE_VERSION=3.19
|
||||
ARG GO_VERSION=1.22
|
||||
ARG XCPUTRANSLATE_VERSION=v0.6.0
|
||||
ARG GOLANGCI_LINT_VERSION=v1.56.2
|
||||
ARG MOCKGEN_VERSION=v1.6.0
|
||||
|
||||
FROM --platform=${BUILDPLATFORM} ghcr.io/qdm12/xcputranslate:${XCPUTRANSLATE_VERSION} AS xcputranslate
|
||||
FROM --platform=${BUILDPLATFORM} ghcr.io/qdm12/binpot:golangci-lint-${GOLANGCI_LINT_VERSION} AS golangci-lint
|
||||
FROM --platform=${BUILDPLATFORM} ghcr.io/qdm12/binpot:mockgen-${MOCKGEN_VERSION} AS mockgen
|
||||
FROM --platform=${BUILDPLATFORM} qmcgaw/xcputranslate:${XCPUTRANSLATE_VERSION} AS xcputranslate
|
||||
FROM --platform=${BUILDPLATFORM} qmcgaw/binpot:golangci-lint-${GOLANGCI_LINT_VERSION} AS golangci-lint
|
||||
FROM --platform=${BUILDPLATFORM} qmcgaw/binpot:mockgen-${MOCKGEN_VERSION} AS mockgen
|
||||
|
||||
FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine${ALPINE_VERSION} AS base
|
||||
WORKDIR /tmp/gobuild
|
||||
@@ -50,7 +50,8 @@ RUN git init && \
|
||||
rm -rf .git/
|
||||
|
||||
FROM --platform=$BUILDPLATFORM base AS build
|
||||
RUN mkdir -p /tmp/data
|
||||
RUN mkdir -p /tmp/data && \
|
||||
touch /tmp/isdocker
|
||||
ARG VERSION=unknown
|
||||
ARG CREATED="an unknown date"
|
||||
ARG COMMIT=unknown
|
||||
@@ -61,7 +62,7 @@ RUN GOARCH="$(xcputranslate translate -targetplatform ${TARGETPLATFORM} -field a
|
||||
-X 'main.version=$VERSION' \
|
||||
-X 'main.date=$CREATED' \
|
||||
-X 'main.commit=$COMMIT' \
|
||||
" -o app cmd/ddns-updater/main.go
|
||||
" -o app cmd/updater/main.go
|
||||
|
||||
FROM scratch
|
||||
EXPOSE 8000
|
||||
@@ -72,6 +73,7 @@ USER ${UID}:${GID}
|
||||
WORKDIR /updater
|
||||
ENTRYPOINT ["/updater/ddns-updater"]
|
||||
COPY --from=build --chown=${UID}:${GID} /tmp/data /updater/data
|
||||
COPY --from=build --chown=${UID}:${GID} /tmp/isdocker /updater/isdocker
|
||||
ENV \
|
||||
# Core
|
||||
CONFIG= \
|
||||
@@ -101,8 +103,6 @@ ENV \
|
||||
SHOUTRRR_ADDRESSES= \
|
||||
SHOUTRRR_DEFAULT_TITLE="DDNS Updater" \
|
||||
TZ= \
|
||||
# UMASK left empty so it dynamically defaults to the OS current umask
|
||||
UMASK= \
|
||||
HEALTH_SERVER_ADDRESS=127.0.0.1:9999 \
|
||||
HEALTH_HEALTHCHECKSIO_BASE_URL=https://hc-ping.com \
|
||||
HEALTH_HEALTHCHECKSIO_UUID=
|
||||
|
||||
67
README.md
67
README.md
@@ -6,8 +6,10 @@ Program to keep DNS A and/or AAAA records updated for multiple DNS providers
|
||||
|
||||
[](https://github.com/qdm12/ddns-updater/actions/workflows/build.yml)
|
||||
|
||||
[](https://hub.docker.com/r/qmcgaw/ddns-updater)
|
||||
|
||||

|
||||

|
||||

|
||||
[](https://hub.docker.com/r/qmcgaw/ddns-updater/tags?page=1&ordering=last_updated)
|
||||

|
||||

|
||||
@@ -20,6 +22,7 @@ Program to keep DNS A and/or AAAA records updated for multiple DNS providers
|
||||
[](https://github.com/qdm12/ddns-updater/issues)
|
||||
[](https://github.com/qdm12/ddns-updater/issues?q=is%3Aissue+is%3Aclosed)
|
||||
|
||||
[](https://github.com/qdm12/ddns-updater)
|
||||

|
||||

|
||||

|
||||
@@ -34,26 +37,23 @@ This readme and the [docs/](docs/) directory are **versioned** to match the prog
|
||||
| Version | Readme link | Docs link |
|
||||
| --- | --- | --- |
|
||||
| Latest | [README](https://github.com/qdm12/ddns-updater/blob/master/README.md) | [docs/](https://github.com/qdm12/ddns-updater/tree/master/docs) |
|
||||
| `v2.8` | [README](https://github.com/qdm12/ddns-updater/blob/v2.8.0/README.md) | [docs/](https://github.com/qdm12/ddns-updater/blob/v2.8.0/docs) |
|
||||
| `v2.7` | [README](https://github.com/qdm12/ddns-updater/blob/v2.7.1/README.md) | [docs/](https://github.com/qdm12/ddns-updater/blob/v2.7.1/docs) |
|
||||
| `v2.6` | [README](https://github.com/qdm12/ddns-updater/blob/v2.6.1/README.md) | [docs/](https://github.com/qdm12/ddns-updater/blob/v2.6.1/docs) |
|
||||
| `v2.5` | [README](https://github.com/qdm12/ddns-updater/blob/v2.5.0/README.md) | [docs/](https://github.com/qdm12/ddns-updater/blob/v2.5.0/docs) |
|
||||
| `v2.5` | [README](https://github.com/qdm12/ddns-updater/blob/v2.5/README.md) | [docs/](https://github.com/qdm12/ddns-updater/blob/v2.5/docs) |
|
||||
|
||||
## Features
|
||||
|
||||
- Available as a Docker image [`ghcr.io/qdm12/ddns-updater`]((https://github.com/qdm12/ddns-updater/pkgs/container/ddns-updater)) and [`qmcgaw/ddns-updater`](https://hub.docker.com/r/qmcgaw/ddns-updater)
|
||||
- Available as [zero-dependency binaries for Linux, Windows and MacOS](https://github.com/qdm12/ddns-updater/releases)
|
||||
- 🆕 Available in the AUR as [`ddns-updater`](https://aur.archlinux.org/packages/ddns-updater) - see [#808](https://github.com/qdm12/ddns-updater/discussions/808)
|
||||
- Available as a Docker image [`qmcgaw/ddns-updater`](https://hub.docker.com/r/qmcgaw/ddns-updater) and [`ghcr.io/qdm12/ddns-updater`]((https://github.com/qdm12/ddns-updater/pkgs/container/ddns-updater))
|
||||
- 🆕 Available as [zero-dependency binaries for Linux, Windows and MacOS](https://github.com/qdm12/ddns-updater/releases)
|
||||
- Updates periodically A records for different DNS providers:
|
||||
- Aliyun
|
||||
- AllInkl
|
||||
- ChangeIP
|
||||
- Changeip
|
||||
- Cloudflare
|
||||
- DD24
|
||||
- DDNSS.de
|
||||
- deSEC
|
||||
- DigitalOcean
|
||||
- Domeneshop
|
||||
- DonDominio
|
||||
- DNSOMatic
|
||||
- DNSPod
|
||||
@@ -61,7 +61,6 @@ This readme and the [docs/](docs/) directory are **versioned** to match the prog
|
||||
- DuckDNS
|
||||
- DynDNS
|
||||
- Dynu
|
||||
- DynV6
|
||||
- EasyDNS
|
||||
- FreeDNS
|
||||
- Gandi
|
||||
@@ -69,19 +68,14 @@ This readme and the [docs/](docs/) directory are **versioned** to match the prog
|
||||
- GoDaddy
|
||||
- GoIP.de
|
||||
- He.net
|
||||
- Hetzner (legacy API)
|
||||
- Hetzner Cloud
|
||||
- Hetzner
|
||||
- Infomaniak
|
||||
- INWX
|
||||
- Ionos
|
||||
- ipv64
|
||||
- Ionos
|
||||
- Linode
|
||||
- Loopia
|
||||
- LuaDNS
|
||||
- Myaddr
|
||||
- Name.com
|
||||
- Namecheap
|
||||
- NameSilo
|
||||
- Netcup
|
||||
- NoIP
|
||||
- Now-DNS
|
||||
@@ -90,13 +84,11 @@ This readme and the [docs/](docs/) directory are **versioned** to match the prog
|
||||
- OVH
|
||||
- Porkbun
|
||||
- Route53
|
||||
- Scaleway
|
||||
- Selfhost.de
|
||||
- Servercow.de
|
||||
- Spdyn
|
||||
- Strato.de
|
||||
- Variomedia.de
|
||||
- Vultr
|
||||
- Zoneedit
|
||||
- **Want more?** [Create an issue for it](https://github.com/qdm12/ddns-updater/issues/new/choose)!
|
||||
- Web user interface (Desktop)
|
||||
@@ -118,7 +110,7 @@ This readme and the [docs/](docs/) directory are **versioned** to match the prog
|
||||
|
||||
### Binary programs
|
||||
|
||||
1. Download the pre-built program for your platform from the assets of a release in the [releases page](https://github.com/qdm12/ddns-updater/releases). You can alternatively download, build and install the latest version of the program by installing [Go](https://golang.org/doc/install) and then run `go install github.com/qdm12/ddns-updater/cmd/ddns-updater@latest`.
|
||||
1. Download the pre-built program for your platform from the assets of a release in the [releases page](https://github.com/qdm12/ddns-updater/releases). Note this is only available from [release v2.6.0](https://github.com/qdm12/ddns-updater/releases/tag/v2.6.0).
|
||||
1. For Linux and MacOS, make the program executable with `chmod +x ddns-updater`.
|
||||
1. In the directory where the program is saved, create a directory `data`.
|
||||
1. Write a JSON configuration in `data/config.json`, for example:
|
||||
@@ -128,7 +120,8 @@ This readme and the [docs/](docs/) directory are **versioned** to match the prog
|
||||
"settings": [
|
||||
{
|
||||
"provider": "namecheap",
|
||||
"domain": "sub.example.com",
|
||||
"domain": "example.com",
|
||||
"host": "@",
|
||||
"password": "e5322165c1d74692bfa6d807100c0310"
|
||||
}
|
||||
]
|
||||
@@ -172,7 +165,8 @@ This readme and the [docs/](docs/) directory are **versioned** to match the prog
|
||||
"settings": [
|
||||
{
|
||||
"provider": "namecheap",
|
||||
"domain": "sub.example.com",
|
||||
"domain": "example.com",
|
||||
"host": "@",
|
||||
"password": "e5322165c1d74692bfa6d807100c0310"
|
||||
}
|
||||
]
|
||||
@@ -184,15 +178,15 @@ This readme and the [docs/](docs/) directory are **versioned** to match the prog
|
||||
1. Run the container with
|
||||
|
||||
```sh
|
||||
docker run -d -p 8000:8000/tcp -v "$(pwd)"/data:/updater/data ghcr.io/qdm12/ddns-updater
|
||||
docker run -d -p 8000:8000/tcp -v "$(pwd)"/data:/updater/data qmcgaw/ddns-updater
|
||||
```
|
||||
|
||||
1. The following is **optional**.
|
||||
- You can customize the program behavior using [environment variables](#environment-variables)
|
||||
- You can use [docker-compose.yml](docker-compose.yml) with `docker-compose up -d`
|
||||
- **Kubernetes**: check out the [k8s directory](k8s) for an installation guide and examples.
|
||||
- Other [Docker image tags are available](https://github.com/qdm12/ddns-updater/pkgs/container/ddns-updater)
|
||||
- You can update the image with `docker pull ghcr.io/qdm12/ddns-updater`
|
||||
- Other [Docker image tags are available](https://hub.docker.com/repository/docker/qmcgaw/ddns-updater/tags)
|
||||
- You can update the image with `docker pull qmcgaw/ddns-updater`
|
||||
- You can set your JSON configuration as a single environment variable line (i.e. `{"settings": [{"provider": "namecheap", ...}]}`), which takes precedence over config.json. Note however that if you don't bind mount the `/updater/data` directory, there won't be a persistent database file `/updater/updates.json` but it will still work.
|
||||
|
||||
## Configuration
|
||||
@@ -219,11 +213,11 @@ Check the documentation for your DNS provider:
|
||||
- [Allinkl](docs/allinkl.md)
|
||||
- [ChangeIP](docs/changeip.md)
|
||||
- [Cloudflare](docs/cloudflare.md)
|
||||
- [DD24](docs/dd24.md)
|
||||
- [Custom](docs/custom.md)
|
||||
- [DDNSS.de](docs/ddnss.de.md)
|
||||
- [deSEC](docs/desec.md)
|
||||
- [DigitalOcean](docs/digitalocean.md)
|
||||
- [Domeneshop](docs/domeneshop.md)
|
||||
- [DD24](docs/dd24.md)
|
||||
- [DonDominio](docs/dondominio.md)
|
||||
- [DNSOMatic](docs/dnsomatic.md)
|
||||
- [DNSPod](docs/dnspod.md)
|
||||
@@ -239,19 +233,13 @@ Check the documentation for your DNS provider:
|
||||
- [GoDaddy](docs/godaddy.md)
|
||||
- [GoIP.de](docs/goip.md)
|
||||
- [He.net](docs/he.net.md)
|
||||
- [Hetzner](docs/hetzner.md)
|
||||
- [HetznerCloud](docs/hetznercloud.md)
|
||||
- [Infomaniak](docs/infomaniak.md)
|
||||
- [INWX](docs/inwx.md)
|
||||
- [Ionos](docs/ionos.md)
|
||||
- [IPv64](docs/ipv64.md)
|
||||
- [Linode](docs/linode.md)
|
||||
- [Loopia](docs/loopia.md)
|
||||
- [LuaDNS](docs/luadns.md)
|
||||
- [Myaddr](docs/myaddr.md)
|
||||
- [Name.com](docs/name.com.md)
|
||||
- [Namecheap](docs/namecheap.md)
|
||||
- [NameSilo](docs/namesilo.md)
|
||||
- [Netcup](docs/netcup.md)
|
||||
- [NoIP](docs/noip.md)
|
||||
- [Now-DNS](docs/nowdns.md)
|
||||
@@ -259,21 +247,16 @@ Check the documentation for your DNS provider:
|
||||
- [OpenDNS](docs/opendns.md)
|
||||
- [OVH](docs/ovh.md)
|
||||
- [Porkbun](docs/porkbun.md)
|
||||
- [Route53](docs/route53.md)
|
||||
- [Scaleway](docs/scaleway.md)
|
||||
- [Selfhost.de](docs/selfhost.de.md)
|
||||
- [Servercow.de](docs/servercow.md)
|
||||
- [Spdyn](docs/spdyn.md)
|
||||
- [Strato.de](docs/strato.md)
|
||||
- [Variomedia.de](docs/variomedia.md)
|
||||
- [Vultr](docs/vultr.md)
|
||||
- [Zoneedit](docs/zoneedit.md)
|
||||
- [Custom](docs/custom.md)
|
||||
|
||||
Note that:
|
||||
|
||||
- you can specify multiple owners/hosts for the same domain using a comma separated list. For example with `"domain": "example.com,sub.example.com,sub2.example.com",`.
|
||||
⚠️ this is a bit different for DuckDNS and GoIP, see their respective documentation.
|
||||
- you can specify multiple hosts for the same domain using a comma separated list. For example with `"host": "@,subdomain1,subdomain2",`.
|
||||
|
||||
### Environment variables
|
||||
|
||||
@@ -304,10 +287,9 @@ Note that:
|
||||
| `RESOLVER_ADDRESS` | Your network DNS | A plaintext DNS address to use to resolve your domain names defined in your settings only. For example it can be `1.1.1.1:53`. This is useful for split dns, see [#389](https://github.com/qdm12/ddns-updater/issues/389) |
|
||||
| `LOG_LEVEL` | `info` | Level of logging, `debug`, `info`, `warning` or `error` |
|
||||
| `LOG_CALLER` | `hidden` | Show caller per log line, `hidden` or `short` |
|
||||
| `SHOUTRRR_ADDRESSES` | | (optional) Comma separated list of [Shoutrrr addresses](https://containrrr.dev/shoutrrr/v0.8/services/overview/) (notification services) |
|
||||
| `SHOUTRRR_ADDRESSES` | | (optional) Comma separated list of [Shoutrrr addresses](https://containrrr.dev/shoutrrr/v0.8/services/overview/) (notification services) |
|
||||
| `SHOUTRRR_DEFAULT_TITLE` | `DDNS Updater` | Default title for Shoutrrr notifications |
|
||||
| `TZ` | | Timezone to have accurate times, i.e. `America/Montreal` |
|
||||
| `UMASK` | System current umask | Umask to set for the program in octal, i.e. `0022` |
|
||||
|
||||
#### Public IP
|
||||
|
||||
@@ -350,7 +332,7 @@ You can otherwise customize it with the following:
|
||||
- `wtfismyip` using [https://ipv6.wtfismyip.com/text](https://ipv6.wtfismyip.com/text)
|
||||
- `seeip` using [https://ipv6.seeip.org](https://ipv6.seeip.org)
|
||||
- You can also specify an HTTPS URL with prefix `url:` for example `url:https://ipinfo.io/ip`
|
||||
- `PUBLICIP_DNS_PROVIDERS` gets your public IPv4 address only or IPv6 address only or one of them (see [#136](https://github.com/qdm12/ddns-updater/issues/136)). It can be one or more of the following:
|
||||
- `PUBLICIP_DNS_PROVIDERS` gets your public IPv4 address only or IPv6 address only or one of them (see #136). It can be one or more of the following:
|
||||
- `cloudflare`
|
||||
- `opendns`
|
||||
|
||||
@@ -410,7 +392,7 @@ We could do an API call to get the record IP address every period, but that woul
|
||||
You can build the image yourself with:
|
||||
|
||||
```sh
|
||||
docker build -t ghcr.io/qdm12/ddns-updater https://github.com/qdm12/ddns-updater.git
|
||||
docker build -t qmcgaw/ddns-updater https://github.com/qdm12/ddns-updater.git
|
||||
```
|
||||
|
||||
You can use optional build arguments with `--build-arg KEY=VALUE` from the table below:
|
||||
@@ -428,6 +410,7 @@ You can use optional build arguments with `--build-arg KEY=VALUE` from the table
|
||||
- [Contribute with code](.github/CONTRIBUTING.md)
|
||||
- [Github workflows to know what's building](https://github.com/qdm12/ddns-updater/actions)
|
||||
- [List of issues and feature requests](https://github.com/qdm12/ddns-updater/issues)
|
||||
- [Kanban board](https://github.com/qdm12/ddns-updater/projects/1)
|
||||
|
||||
## License
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@ import (
|
||||
"github.com/qdm12/ddns-updater/internal/resolver"
|
||||
"github.com/qdm12/ddns-updater/internal/server"
|
||||
"github.com/qdm12/ddns-updater/internal/shoutrrr"
|
||||
"github.com/qdm12/ddns-updater/internal/system"
|
||||
"github.com/qdm12/ddns-updater/internal/update"
|
||||
"github.com/qdm12/ddns-updater/pkg/publicip"
|
||||
"github.com/qdm12/goservices"
|
||||
@@ -46,7 +45,7 @@ func main() {
|
||||
buildInfo := models.BuildInformation{
|
||||
Version: version,
|
||||
Commit: commit,
|
||||
Created: date,
|
||||
Date: date,
|
||||
}
|
||||
logger := log.New()
|
||||
|
||||
@@ -99,8 +98,7 @@ func main() {
|
||||
}
|
||||
|
||||
func _main(ctx context.Context, reader *reader.Reader, args []string, logger log.LoggerInterface,
|
||||
buildInfo models.BuildInformation, timeNow func() time.Time,
|
||||
) (err error) {
|
||||
buildInfo models.BuildInformation, timeNow func() time.Time) (err error) {
|
||||
if len(args) > 1 {
|
||||
switch args[1] {
|
||||
case "version", "-version", "--version":
|
||||
@@ -131,10 +129,6 @@ func _main(ctx context.Context, reader *reader.Reader, args []string, logger log
|
||||
return err
|
||||
}
|
||||
|
||||
if *config.Paths.Umask > 0 {
|
||||
system.SetUmask(*config.Paths.Umask)
|
||||
}
|
||||
|
||||
shoutrrrSettings := shoutrrr.Settings{
|
||||
Addresses: config.Shoutrrr.Addresses,
|
||||
DefaultTitle: config.Shoutrrr.DefaultTitle,
|
||||
@@ -278,7 +272,7 @@ func printSplash(buildInfo models.BuildInformation) {
|
||||
Emails: []string{"quentin.mcgaw@gmail.com"},
|
||||
Version: buildInfo.Version,
|
||||
Commit: buildInfo.Commit,
|
||||
Created: buildInfo.Created,
|
||||
BuildDate: buildInfo.Date,
|
||||
Announcement: "Public IP http provider GOOGLE is no longer working",
|
||||
AnnounceExp: announcementExp,
|
||||
// Sponsor information
|
||||
@@ -291,8 +285,7 @@ func printSplash(buildInfo models.BuildInformation) {
|
||||
}
|
||||
|
||||
func readConfig(reader *reader.Reader, logger log.LoggerInterface) (
|
||||
config config.Config, err error,
|
||||
) {
|
||||
config config.Config, err error) {
|
||||
err = config.Read(reader, logger)
|
||||
if err != nil {
|
||||
return config, fmt.Errorf("reading settings: %w", err)
|
||||
@@ -322,15 +315,14 @@ func logProvidersCount(providersCount int, logger log.LeveledLogger) {
|
||||
|
||||
func readRecords(providers []provider.Provider, persistentDB *persistence.Database,
|
||||
logger log.LoggerInterface, shoutrrrClient *shoutrrr.Client) (
|
||||
records []recordslib.Record, err error,
|
||||
) {
|
||||
records []recordslib.Record, err error) {
|
||||
records = make([]recordslib.Record, len(providers))
|
||||
for i, provider := range providers {
|
||||
logger.Info("Reading history from database: domain " +
|
||||
provider.Domain() + " owner " + provider.Owner() +
|
||||
provider.Domain() + " host " + provider.Host() +
|
||||
" " + provider.IPVersion().String())
|
||||
events, err := persistentDB.GetEvents(provider.Domain(),
|
||||
provider.Owner(), provider.IPVersion())
|
||||
provider.Host(), provider.IPVersion())
|
||||
if err != nil {
|
||||
shoutrrrClient.Notify(err.Error())
|
||||
return nil, err
|
||||
@@ -341,8 +333,7 @@ func readRecords(providers []provider.Provider, persistentDB *persistence.Databa
|
||||
}
|
||||
|
||||
func exitHealthchecksio(hioClient *healthchecksio.Client,
|
||||
logger log.LoggerInterface, state healthchecksio.State,
|
||||
) {
|
||||
logger log.LoggerInterface, state healthchecksio.State) {
|
||||
const timeout = 3 * time.Second
|
||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||
defer cancel()
|
||||
@@ -355,9 +346,8 @@ func exitHealthchecksio(hioClient *healthchecksio.Client,
|
||||
//nolint:ireturn
|
||||
func createHealthServer(db health.AllSelecter, resolver health.LookupIPer,
|
||||
logger log.LoggerInterface, serverAddress string) (
|
||||
healthServer goservices.Service, err error,
|
||||
) {
|
||||
if serverAddress == "" {
|
||||
healthServer goservices.Service, err error) {
|
||||
if !health.IsDocker() {
|
||||
return noop.New("healthcheck server"), nil
|
||||
}
|
||||
isHealthy := health.MakeIsHealthy(db, resolver)
|
||||
@@ -369,8 +359,7 @@ func createHealthServer(db health.AllSelecter, resolver health.LookupIPer,
|
||||
func createServer(ctx context.Context, config config.Server,
|
||||
logger log.LoggerInterface, db server.Database,
|
||||
updaterService server.UpdateForcer) (
|
||||
service goservices.Service, err error,
|
||||
) {
|
||||
service goservices.Service, err error) {
|
||||
if !*config.Enabled {
|
||||
return noop.New("server"), nil
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
{
|
||||
"provider": "namecheap",
|
||||
"domain": "example.com",
|
||||
"host": "@",
|
||||
"password": "e5322165c1d74692bfa6d807100c0310"
|
||||
},
|
||||
{
|
||||
@@ -12,7 +13,8 @@
|
||||
},
|
||||
{
|
||||
"provider": "godaddy",
|
||||
"domain": "subdomain.example.org",
|
||||
"domain": "example.org",
|
||||
"host": "subdomain",
|
||||
"key": "aaaaaaaaaaaaaaaa",
|
||||
"secret": "aaaaaaaaaaaaaaaa"
|
||||
},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
version: "3.7"
|
||||
services:
|
||||
ddns-updater:
|
||||
image: ghcr.io/qdm12/ddns-updater
|
||||
image: qmcgaw/ddns-updater
|
||||
container_name: ddns-updater
|
||||
network_mode: bridge
|
||||
ports:
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
{
|
||||
"provider": "aliyun",
|
||||
"domain": "domain.com",
|
||||
"host": "@",
|
||||
"access_key_id": "your access_key_id",
|
||||
"access_secret": "your access_secret",
|
||||
"ip_version": "ipv4",
|
||||
@@ -21,13 +22,14 @@
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain) or `sub.example.com` (subdomain of `example.com`).
|
||||
- `"domain"`
|
||||
- `"host"` is your host and can be a subdomain or `"@"`
|
||||
- `"access_key_id"`
|
||||
- `"access_secret"`
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
|
||||
## Domain setup
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
"settings": [
|
||||
{
|
||||
"provider": "allinkl",
|
||||
"domain": "sub.domain.com",
|
||||
"domain": "domain.com",
|
||||
"host": "host",
|
||||
"username": "dynXXXXXXX",
|
||||
"password": "password",
|
||||
"ip_version": "ipv4",
|
||||
@@ -21,13 +22,14 @@
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain) or `sub.example.com` (subdomain of `example.com`).
|
||||
- `"domain"`
|
||||
- `"host"` is your host (subdomain)
|
||||
- `"username"` username (usually starts with dyn followed by numbers)
|
||||
- `"password"` password in plain text
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
|
||||
## Domain setup
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
"settings": [
|
||||
{
|
||||
"provider": "changeip",
|
||||
"domain": "sub.domain.com",
|
||||
"domain": "domain.com",
|
||||
"host": "host",
|
||||
"username": "dynXXXXXXX",
|
||||
"password": "password",
|
||||
"ip_version": "ipv4",
|
||||
@@ -21,13 +22,14 @@
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain) or `sub.example.com` (subdomain of `example.com`).
|
||||
- `"domain"`
|
||||
- `"host"` is your host (subdomain)
|
||||
- `"username"`
|
||||
- `"password"`
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
|
||||
## Domain setup
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
"provider": "cloudflare",
|
||||
"zone_identifier": "some id",
|
||||
"domain": "domain.com",
|
||||
"host": "@",
|
||||
"ttl": 600,
|
||||
"token": "yourtoken",
|
||||
"ip_version": "ipv4",
|
||||
@@ -23,7 +24,8 @@
|
||||
### Compulsory parameters
|
||||
|
||||
- `"zone_identifier"` is the Zone ID of your site, from the domain overview page written as *Zone ID*
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain), `sub.example.com` (subdomain of `example.com`) or `*.example.com` for the wildcard.
|
||||
- `"domain"`
|
||||
- `"host"` is your host and can be `"@"`, a subdomain or the wildcard `"*"`.
|
||||
See [this issue comment for context](https://github.com/qdm12/ddns-updater/issues/243#issuecomment-928313949). This is left as is for compatibility.
|
||||
- `"ttl"` integer value for record TTL in seconds (specify 1 for automatic)
|
||||
- One of the following ([how to find API keys](https://developers.cloudflare.com/fundamentals/api/get-started/)):
|
||||
@@ -35,6 +37,6 @@ See [this issue comment for context](https://github.com/qdm12/ddns-updater/issue
|
||||
|
||||
- `"proxied"` can be set to `true` to use the proxy services of Cloudflare
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
|
||||
Special thanks to @Starttoaster for helping out with the [documentation](https://gist.github.com/Starttoaster/07d568c2a99ad7631dd776688c988326) and testing.
|
||||
|
||||
@@ -15,6 +15,7 @@ Feel free to open issues to extend its configuration options.
|
||||
{
|
||||
"provider": "custom",
|
||||
"domain": "example.com",
|
||||
"host": "@",
|
||||
"url": "https://example.com/update?domain=example.com&host=@&username=username&client_key=client_key",
|
||||
"ipv4key": "ipv4",
|
||||
"ipv6key": "ipv6",
|
||||
@@ -28,13 +29,14 @@ Feel free to open issues to extend its configuration options.
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain), `sub.example.com` (subdomain of `example.com`) or `*.example.com` for the wildcard.
|
||||
- `"domain"` is the domain name to update
|
||||
- `"host"` is the host to update, which can be `"@"` (root), `"*"` or a subdomain
|
||||
- `"url"` is the URL to update your records and should contain all the information EXCEPT the IP address to update
|
||||
- `"ipv4key"` is the URL query parameter name for the IPv4 address, for example `ipv4` will be added to the URL with `&ipv4=1.2.3.4`. In the rare case you do not wish to send an IPv4 query parameter to the registrar API when updating your A (IPv4) record, leave it to `"ipv4key": ""`.
|
||||
- `"ipv6key"` is the URL query parameter name for the IPv6 address, for example `ipv6` will be added to the URL with `&ipv6=::aaff`. In the rare case you do not wish to send an IPv6 query parameter to the registrar API when updating your AAAA (IPv6) record, leave it to `"ipv6key": ""`.
|
||||
- `"ipv4key"` is the URL query parameter name for the IPv4 address, for example `ipv4` will be added to the URL with `&ipv4=1.2.3.4`.
|
||||
- `"ipv6key"` is the URL query parameter name for the IPv6 address, for example `ipv6` will be added to the URL with `&ipv6=::aaff`. Even if you don't use IPv6, this must be set to something.
|
||||
- `"success_regex"` is a regular expression to match the response from the server to determine if the update was successful. You can use [regex101.com](https://regex101.com/) to find the regular expression you want. For example `good` would match any response containing the word "good".
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
{
|
||||
"provider": "dd24",
|
||||
"domain": "domain.com",
|
||||
"host": "@",
|
||||
"password": "password",
|
||||
"ip_version": "ipv4",
|
||||
"ipv6_suffix": ""
|
||||
@@ -20,10 +21,11 @@
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain) or `sub.example.com` (subdomain of `example.com`).
|
||||
- `"domain"`
|
||||
- `"host"` is your host and can be a subdomain or `"@"`
|
||||
- `"password"` is your password
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
"settings": [
|
||||
{
|
||||
"provider": "ddnss",
|
||||
"provider_ip": true,
|
||||
"domain": "domain.com",
|
||||
"host": "@",
|
||||
"username": "user",
|
||||
"password": "password",
|
||||
"dual_stack": false,
|
||||
@@ -22,16 +24,17 @@
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain) or `sub.example.com` (subdomain of `example.com`).
|
||||
- `"domain"`
|
||||
- `"host"` is your host and can be a subdomain or `"@"`
|
||||
- `"username"`
|
||||
- `"password"`
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"dual_stack"` can be set to `true` **if you have turn on dual stack for your record** to update both IPv4 and IPv6 addresses. More precisely:
|
||||
- `"dual_stack"` can be set to `true` **if you have turn on dual stack for your record** to update both IPv4 and IPv6 addresses. Note it is ignored if `"provider_ip": true`. More precisely:
|
||||
- if it is `false`, the updates are done using the `ip` parameter and only one IP address can be set (ipv4 or ipv6, whichever is last sent).
|
||||
- if it is `true`, the updates are done using the `ip` and `ip6` parameters, for IPv4 and IPv6 respectively, and both can be set on the same record
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
|
||||
## Domain setup
|
||||
|
||||
@@ -9,10 +9,12 @@
|
||||
"settings": [
|
||||
{
|
||||
"provider": "desec",
|
||||
"domain": "sub.dedyn.io",
|
||||
"domain": "dedyn.io",
|
||||
"host": "host",
|
||||
"token": "token",
|
||||
"ip_version": "ipv4",
|
||||
"ipv6_suffix": ""
|
||||
"ipv6_suffix": "",
|
||||
"provider_ip": false
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -20,13 +22,15 @@
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain), `sub.example.com` (subdomain of `example.com`) or `*.example.com` for the wildcard.
|
||||
- `"token"` is your token that you can create at [desec.io/tokens](https://desec.io/tokens)
|
||||
- `"domain"`
|
||||
- `"host"` can be `@` for the root domain or a subdomain or a wildcard subdomain (`*`), defaults to `@`
|
||||
- `"token"` is your token that you can create [here](https://desec.io/tokens)
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
- `"provider_ip"` can be set to `true` to let your DNS provider determine your IPv4 address (and/or IPv6 address) automatically when you send an update request, without sending the new IP address detected by the program in the request.
|
||||
|
||||
## Domain setup
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
{
|
||||
"provider": "digitalocean",
|
||||
"domain": "domain.com",
|
||||
"host": "@",
|
||||
"token": "yourtoken",
|
||||
"ip_version": "ipv4",
|
||||
"ipv6_suffix": ""
|
||||
@@ -20,12 +21,13 @@
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain), `sub.example.com` (subdomain of `example.com`) or `*.example.com` for the wildcard.
|
||||
- `"token"` is your token that you can create at [cloud.digitalocean.com/settings/applications](https://cloud.digitalocean.com/settings/applications)
|
||||
- `"domain"`
|
||||
- `"host"` is your host and can be a subdomain or `"@"` or `"*"`
|
||||
- `"token"` is your token that you can create [here](https://cloud.digitalocean.com/settings/applications)
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
|
||||
## Domain setup
|
||||
|
||||
@@ -10,8 +10,10 @@
|
||||
{
|
||||
"provider": "dnsomatic",
|
||||
"domain": "domain.com",
|
||||
"host": "@",
|
||||
"username": "username",
|
||||
"password": "password",
|
||||
"provider_ip": true,
|
||||
"ip_version": "ipv4",
|
||||
"ipv6_suffix": ""
|
||||
}
|
||||
@@ -21,13 +23,15 @@
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain), `sub.example.com` (subdomain of `example.com`) or `*.example.com` for the wildcard.
|
||||
- `"domain"`
|
||||
- `"host"` is your host and can be a subdomain or `"@"` or `"*"`
|
||||
- `"username"`
|
||||
- `"password"`
|
||||
- `"provider_ip"`
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
|
||||
## Domain setup
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
{
|
||||
"provider": "dnspod",
|
||||
"domain": "domain.com",
|
||||
"host": "@",
|
||||
"token": "yourtoken",
|
||||
"ip_version": "ipv4",
|
||||
"ipv6_suffix": ""
|
||||
@@ -20,12 +21,13 @@
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain) or `sub.example.com` (subdomain of `example.com`).
|
||||
- `"domain"`
|
||||
- `"host"` is your host and can be a subdomain or `"@"`
|
||||
- `"token"`
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
|
||||
## Domain setup
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
# Domeneshop.no
|
||||
|
||||
## Configuration
|
||||
|
||||
### Example
|
||||
|
||||
```json
|
||||
{
|
||||
"settings": [
|
||||
{
|
||||
"provider": "domeneshop",
|
||||
"domain": "domain.com,seconddomain.com",
|
||||
"token": "token",
|
||||
"secret": "secret",
|
||||
"ip_version": "ipv4",
|
||||
"ipv6_suffix": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain) or `sub.example.com` (subdomain of `example.com`)
|
||||
- `"token"` See [api.domeneshop.no/docs/](https://api.domeneshop.no/docs/) for instructions on how to generate credentials.
|
||||
- `"secret"`
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
@@ -10,6 +10,7 @@
|
||||
{
|
||||
"provider": "dondominio",
|
||||
"domain": "domain.com",
|
||||
"host": "@",
|
||||
"username": "username",
|
||||
"key": "key",
|
||||
"ip_version": "ipv4",
|
||||
@@ -21,14 +22,15 @@
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain), `sub.example.com` (subdomain of `example.com`) or `*.example.com` for the wildcard.
|
||||
- `"domain"`
|
||||
- `"host"` is the subdomain to update which can be `@`, `*` or a subdomain
|
||||
- `"username"`
|
||||
- `"password"`
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
|
||||
## Domain setup
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
{
|
||||
"provider": "dreamhost",
|
||||
"domain": "domain.com",
|
||||
"host": "@",
|
||||
"key": "key",
|
||||
"ip_version": "ipv4",
|
||||
"ipv6_suffix": ""
|
||||
@@ -25,8 +26,8 @@
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain) or `sub.example.com` (subdomain of `example.com`).
|
||||
- `"host"` is your host and can be a subdomain or `"@"`. It defaults to `"@"`.
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
|
||||
## Domain setup
|
||||
|
||||
@@ -9,10 +9,11 @@
|
||||
"settings": [
|
||||
{
|
||||
"provider": "duckdns",
|
||||
"domain": "sub.duckdns.org",
|
||||
"host": "host",
|
||||
"token": "token",
|
||||
"ip_version": "ipv4",
|
||||
"ipv6_suffix": ""
|
||||
"ipv6_suffix": "",
|
||||
"provider_ip": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -20,16 +21,14 @@
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. The [eTLD](https://developer.mozilla.org/en-US/docs/Glossary/eTLD) must be `duckdns.org`. For example:
|
||||
- for the root owner/host `@`, it would be `mydomain.duckdns.org`
|
||||
- for the owner/host `sub`, it would be `sub.mydomain.duckdns.org`
|
||||
- for multiple domains, it can be `sub1.mydomain.duckdns.org,sub2.mydomain.duckdns.org` BUT it cannot be `a.duckdns.org,b.duckdns.org`, since the effective domains would be `a.duckdns.org` and `b.duckdns.org`
|
||||
- `"host"` is your host, for example `subdomain` for `subdomain.duckdns.org`
|
||||
- `"token"`
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
- `"provider_ip"` can be set to `true` to let your DNS provider determine your IPv4 address (**NOT** your IPv6 address) automatically when you send an update request, without sending the new IP address detected by the program in the request.
|
||||
|
||||
## Domain setup
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
{
|
||||
"provider": "dyn",
|
||||
"domain": "domain.com",
|
||||
"host": "@",
|
||||
"username": "username",
|
||||
"client_key": "client_key",
|
||||
"ip_version": "ipv4",
|
||||
@@ -21,13 +22,14 @@
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain), `sub.example.com` (subdomain of `example.com`) or `*.example.com` for the wildcard.
|
||||
- `"domain"`
|
||||
- `"host"` is your host and can be a subdomain or `"@"` or `"*"`
|
||||
- `"username"`
|
||||
- `"client_key"`
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
|
||||
## Domain setup
|
||||
|
||||
10
docs/dynu.md
10
docs/dynu.md
@@ -10,11 +10,13 @@
|
||||
{
|
||||
"provider": "dynu",
|
||||
"domain": "domain.com",
|
||||
"host": "@",
|
||||
"group": "group",
|
||||
"username": "username",
|
||||
"password": "password",
|
||||
"ip_version": "ipv4",
|
||||
"ipv6_suffix": ""
|
||||
"ipv6_suffix": "",
|
||||
"provider_ip": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -22,14 +24,16 @@
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain) or `sub.example.com` (subdomain of `example.com`).
|
||||
- `"domain"`
|
||||
- `"host"` is your host and can be a subdomain or `"@"`
|
||||
- `"username"`
|
||||
- `"password"` could be plain text or password in MD5 or SHA256 format (There's also an option for setting a password for IP Update only)
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
- `"provider_ip"` can be set to `true` to let your DNS provider determine your IPv4 address (and/or IPv6 address) automatically when you send an update request, without sending the new IP address detected by the program in the request.
|
||||
- `"group"` specify the Group for which you want to set the IP (will update any domains and subdomains in the same group)
|
||||
|
||||
## Domain setup
|
||||
|
||||
@@ -10,9 +10,11 @@
|
||||
{
|
||||
"provider": "dynv6",
|
||||
"domain": "domain.com",
|
||||
"host": "@",
|
||||
"token": "token",
|
||||
"ip_version": "ipv4",
|
||||
"ipv6_suffix": ""
|
||||
"ipv6_suffix": "",
|
||||
"provider_ip": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -20,12 +22,14 @@
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain) or `sub.example.com` (subdomain of `example.com`).
|
||||
- `"token"` that you can obtain from [dynv6.com/keys#token](https://dynv6.com/keys#token)
|
||||
- `"domain"`
|
||||
- `"host"` is your host and can be a subdomain or `"@"`
|
||||
- `"token"` that you can obtain [here](https://dynv6.com/keys#token)
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
- `"provider_ip"` can be set to `true` to let your DNS provider determine your IPv4 address (and/or IPv6 address) automatically when you send an update request, without sending the new IP address detected by the program in the request.
|
||||
|
||||
## Domain setup
|
||||
|
||||
@@ -10,10 +10,12 @@
|
||||
{
|
||||
"provider": "easydns",
|
||||
"domain": "domain.com",
|
||||
"host": "@",
|
||||
"username": "username",
|
||||
"token": "token",
|
||||
"ip_version": "ipv4",
|
||||
"ipv6_suffix": ""
|
||||
"ipv6_suffix": "",
|
||||
"provider_ip": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -21,13 +23,15 @@
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain), `sub.example.com` (subdomain of `example.com`) or `*.example.com` for the wildcard.
|
||||
- `"domain"`
|
||||
- `"host"` is your host and can be a subdomain or `"@"` or `"*"`
|
||||
- `"username"`
|
||||
- `"token"`
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
- `"provider_ip"` can be set to `true` to let your DNS provider determine your IPv4 address (and/or IPv6 address) automatically when you send an update request, without sending the new IP address detected by the program in the request.
|
||||
|
||||
## Domain setup
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
{
|
||||
"provider": "example",
|
||||
"domain": "domain.com",
|
||||
"host": "@",
|
||||
"username": "username",
|
||||
"password": "password",
|
||||
"ip_version": "ipv4",
|
||||
@@ -23,7 +24,8 @@
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain), `sub.example.com` (subdomain of `example.com`) or `*.example.com` for the wildcard.
|
||||
- `"domain"`
|
||||
- `"host"` is your host and can be a subdomain or `"@"` or the wildcard `"*"`
|
||||
- `"username"`
|
||||
- `"password"`
|
||||
|
||||
@@ -32,7 +34,7 @@
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
|
||||
<!-- UPDATE THIS IF NEEDED -->
|
||||
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
"settings": [
|
||||
{
|
||||
"provider": "freedns",
|
||||
"domain": "sub.domain.com",
|
||||
"domain": "domain.com",
|
||||
"host": "host",
|
||||
"token": "token",
|
||||
"ip_version": "ipv4",
|
||||
"ipv6_suffix": ""
|
||||
@@ -20,13 +21,14 @@
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain) or `sub.example.com` (subdomain of `example.com`).
|
||||
- `"domain"`
|
||||
- `"host"` is your host (subdomain)
|
||||
- `"token"` is the randomized update token you use to update your record
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
|
||||
## Domain setup
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ This provider uses Gandi v5 API
|
||||
{
|
||||
"provider": "gandi",
|
||||
"domain": "domain.com",
|
||||
"host": "@",
|
||||
"personal_access_token": "token",
|
||||
"ttl": 3600,
|
||||
"ip_version": "ipv4",
|
||||
@@ -23,13 +24,14 @@ This provider uses Gandi v5 API
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain), `sub.example.com` (subdomain of `example.com`) or `*.example.com` for the wildcard.
|
||||
- `"domain"`
|
||||
- `"host"` which can be a subdomain, `@` or a wildcard `*`
|
||||
- `"personal_access_token"`
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
- `"ttl"` default is `3600`
|
||||
|
||||
## Domain setup
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
// ...
|
||||
},
|
||||
"domain": "domain.com",
|
||||
"host": "@",
|
||||
"ip_version": "ipv4",
|
||||
"ipv6_suffix": ""
|
||||
}
|
||||
@@ -28,10 +29,11 @@
|
||||
|
||||
- `"project"` is the id of your Google Cloud project
|
||||
- `"zone"` is the zone, that your DNS record is located in
|
||||
- `"credentials"` is the JSON credentials for your Google Cloud project. This is usually downloaded as a JSON file, which you can copy paste the content as the value of the `"credentials"` key. More information on how to get it is available at [cloud.google.com/docs/authentication/getting-started](https://cloud.google.com/docs/authentication/getting-started). Please ensure your service account has all necessary permissions to create/update/list/get DNS records within your project.
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain), `sub.example.com` (subdomain of `example.com`) or `*.example.com` for the wildcard.
|
||||
- `"credentials"` is the JSON credentials for your Google Cloud project. This is usually downloaded as a JSON file, which you can copy paste the content as the value of the `"credentials"` key. More information on how to get it is available [here](https://cloud.google.com/docs/authentication/getting-started). Please ensure your service account has all necessary permissions to create/update/list/get DNS records within your project.
|
||||
- `"domain"` is the TLD of you DNS record (without a trailing dot)
|
||||
- `"host"` is your host and can be a subdomain or `"@"` or `"*"`
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
{
|
||||
"provider": "godaddy",
|
||||
"domain": "domain.com",
|
||||
"host": "@",
|
||||
"key": "key",
|
||||
"secret": "secret",
|
||||
"ip_version": "ipv4",
|
||||
@@ -21,14 +22,15 @@
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain), `sub.example.com` (subdomain of `example.com`) or `*.example.com` for the wildcard.
|
||||
- `"domain"`
|
||||
- `"host"` is your host and can be a subdomain, `"@"` or `"*"` generally
|
||||
- `"key"`
|
||||
- `"secret"`
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
|
||||
## Domain setup
|
||||
|
||||
|
||||
14
docs/goip.md
14
docs/goip.md
@@ -9,9 +9,11 @@
|
||||
"settings": [
|
||||
{
|
||||
"provider": "goip",
|
||||
"domain": "sub.mydomain.goip.de",
|
||||
"domain": "goip.de",
|
||||
"host": "mysubdomain",
|
||||
"username": "username",
|
||||
"password": "password",
|
||||
"provider_ip": true,
|
||||
"ip_version": "",
|
||||
"ipv6_suffix": ""
|
||||
|
||||
@@ -22,15 +24,13 @@
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. For example, for the owner/host `sub`, it would be `sub.goip.de`. The [eTLD](https://developer.mozilla.org/en-US/docs/Glossary/eTLD) must be `goip.de` or `goip.it`.
|
||||
- `"domain"` is the domain to update. The [eTLD](https://developer.mozilla.org/en-US/docs/Glossary/eTLD) must be `goip.de` or `goip.it`. For example:
|
||||
- for the root owner/host `@`, it would be `mydomain.goip.de`
|
||||
- for the owner/host `sub`, it would be `sub.mydomain.goip.de`
|
||||
- for multiple domains, it can be `sub1.mydomain.goip.de,sub2.mydomain.goip.de` BUT it cannot be `a.goip.de,b.goip.de`, since the effective domains would be `a.goip.de` and `b.goip.de`
|
||||
- `"host"` is the host of your domain, for example `"example"` for `example.goip.de`.
|
||||
- `"username"` is your goip.de username listed under "Routers"
|
||||
- `"password"` is your router account password
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"domain"` is the domain name which can be `goip.de` or `goip.it`, and defaults to `goip.de` if left unset.
|
||||
- `"provider_ip"` can be set to `true` to let your DNS provider determine your IPv4 address (and/or IPv6 address) automatically when you send an update request, without sending the new IP address detected by the program in the request. This is automatically disabled for an IPv6 public address since it is not supported.
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
{
|
||||
"provider": "he",
|
||||
"domain": "domain.com",
|
||||
"host": "@",
|
||||
"password": "password",
|
||||
"provider_ip": true,
|
||||
"ip_version": "ipv4",
|
||||
"ipv6_suffix": ""
|
||||
}
|
||||
@@ -20,12 +22,14 @@
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain), `sub.example.com` (subdomain of `example.com`) or `*.example.com` for the wildcard. (untested)
|
||||
- `"domain"`
|
||||
- `"host"` is your host and can be a subdomain or `"@"` or `"*"` (untested)
|
||||
- `"password"`
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
- `"provider_ip"` can be set to `true` to let your DNS provider determine your IPv4 address (and/or IPv6 address) automatically when you send an update request, without sending the new IP address detected by the program in the request.
|
||||
|
||||
## Domain setup
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# Hetzner
|
||||
|
||||
⚠️ You should use [Hetzner Cloud](./hetznercloud.md) with the new Hetzner Cloud console instead, given this legacy Hetzner API is going to be shutdown soon.
|
||||
|
||||
## Configuration
|
||||
|
||||
### Example
|
||||
@@ -13,6 +11,7 @@
|
||||
"provider": "hetzner",
|
||||
"zone_identifier": "some id",
|
||||
"domain": "domain.com",
|
||||
"host": "@",
|
||||
"ttl": 600,
|
||||
"token": "yourtoken",
|
||||
"ip_version": "ipv4",
|
||||
@@ -25,7 +24,8 @@
|
||||
### Compulsory parameters
|
||||
|
||||
- `"zone_identifier"` is the Zone ID of your site, from the domain overview page written as *Zone ID*
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain), `sub.example.com` (subdomain of `example.com`) or `*.example.com` for the wildcard.
|
||||
- `"domain"`
|
||||
- `"host"` is your host and can be `"@"`, a subdomain or the wildcard `"*"`.
|
||||
- `"ttl"` optional integer value corresponding to a number of seconds
|
||||
- One of the following ([how to find API keys](https://docs.hetzner.com/cloud/api/getting-started/generating-api-token)):
|
||||
- API Token `"token"`, configured with DNS edit permissions for your DNS name's zone
|
||||
@@ -33,4 +33,4 @@
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
# Hetzner Cloud
|
||||
|
||||
This provider uses the Hetzner Cloud API `https://api.hetzner.cloud/v1/` which is different from the legacy Hetzner DNS API.
|
||||
|
||||
## Configuration
|
||||
|
||||
### Example
|
||||
|
||||
```json
|
||||
{
|
||||
"settings": [
|
||||
{
|
||||
"provider": "hetznercloud",
|
||||
"domain": "example.com",
|
||||
"token": "yourtoken",
|
||||
"ip_version": "ipv4",
|
||||
"ipv6_suffix": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain), `sub.example.com` (subdomain of `example.com`) or `*.example.com` for the wildcard.
|
||||
- `"token"` is your API token configured with DNS write permissions for your DNS zone, see [the Authentication section](https://docs.hetzner.com/cloud/api/getting-started/generating-api-token)
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ttl"` time to live for the DNS record in seconds. It is only used to add a record to the rrset, and is not used to update an existing record. If left empty, it defaults to the existing zone TTL.
|
||||
@@ -10,10 +10,12 @@
|
||||
{
|
||||
"provider": "infomaniak",
|
||||
"domain": "domain.com",
|
||||
"host": "@",
|
||||
"username": "username",
|
||||
"password": "password",
|
||||
"ip_version": "ipv4",
|
||||
"ipv6_suffix": ""
|
||||
"ipv6_suffix": "",
|
||||
"provider_ip": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -21,14 +23,16 @@
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain) or `sub.example.com` (subdomain of `example.com`).
|
||||
- `"domain"`
|
||||
- `"host"` is your host and can be a subdomain or `"@"`
|
||||
- `"username"` for dyndns (**not** your infomaniak admin username!)
|
||||
- `"password"` for dyndns (**not** your infomaniak admin password!)
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
- `"provider_ip"` can be set to `true` to let your DNS provider determine your IPv4 address (and/or IPv6 address) automatically when you send an update request, without sending the new IP address detected by the program in the request.
|
||||
|
||||
## Domain setup
|
||||
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
## Configuration
|
||||
|
||||
You must configure a [DynDNS Account in INWX](https://www.inwx.com/en/offer/dyndns) and use the configured account and hostname.
|
||||
|
||||
### Example
|
||||
|
||||
```json
|
||||
@@ -12,6 +10,7 @@ You must configure a [DynDNS Account in INWX](https://www.inwx.com/en/offer/dynd
|
||||
{
|
||||
"provider": "inwx",
|
||||
"domain": "domain.com",
|
||||
"host": "@",
|
||||
"username": "username",
|
||||
"password": "password",
|
||||
"ip_version": "ipv4",
|
||||
@@ -23,13 +22,14 @@ You must configure a [DynDNS Account in INWX](https://www.inwx.com/en/offer/dynd
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain configured for the DynDNS Account. It can be `example.com` (root domain) or `sub.example.com` (subdomain of `example.com`).
|
||||
- `"domain"`
|
||||
- `"host"` is your host and can be a subdomain or `"@"`
|
||||
- `"username"`
|
||||
- `"password"`
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
|
||||
## Domain setup
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
{
|
||||
"provider": "ionos",
|
||||
"domain": "domain.com",
|
||||
"host": "@",
|
||||
"api_key": "api_key",
|
||||
"ip_version": "ipv4",
|
||||
"ipv6_suffix": ""
|
||||
@@ -20,10 +21,11 @@
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain), `sub.example.com` (subdomain of `example.com`) or `*.example.com` for the wildcard.
|
||||
- `"api_key"` is your API key, consisting of two parts — a prefix and the key itself — and can be obtained by [creating an API key](https://www.ionos.com/help/domains/configuring-your-ip-address/set-up-dynamic-dns-with-company-name/#c181598). It must follow the format `<prefix>.<key>`.
|
||||
- `"domain"`
|
||||
- `"host"` is your host and can be a subdomain or `"@"` or `"*"`
|
||||
- `"api_key"` is your API key, obtained from [creating an API key](https://www.ionos.com/help/domains/configuring-your-ip-address/set-up-dynamic-dns-with-company-name/#c181598)
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
# IPv64
|
||||
|
||||
## Configuration
|
||||
|
||||
### Example
|
||||
|
||||
```json
|
||||
{
|
||||
"settings": [
|
||||
{
|
||||
"provider": "ipv64",
|
||||
"domain": "domain.com",
|
||||
"key": "key",
|
||||
"ip_version": "ipv4",
|
||||
"ipv6_suffix": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain) or `sub.example.com` (subdomain of `example.com`).
|
||||
- `"key"` that you can obtain at [ipv64.net/account](https://ipv64.net/account)
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
|
||||
## Domain setup
|
||||
@@ -10,6 +10,7 @@
|
||||
{
|
||||
"provider": "linode",
|
||||
"domain": "domain.com",
|
||||
"host": "@",
|
||||
"token": "token",
|
||||
"ip_version": "ipv4",
|
||||
"ipv6_suffix": ""
|
||||
@@ -20,13 +21,14 @@
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain), `sub.example.com` (subdomain of `example.com`) or `*.example.com` for the wildcard.
|
||||
- `"domain"`
|
||||
- `"host"` is your host and can be a subdomain or `"@"` or `"*"`
|
||||
- `"token"`
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
|
||||
## Domain setup
|
||||
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
# Loopia
|
||||
|
||||
## Configuration
|
||||
|
||||
### Example
|
||||
|
||||
```json
|
||||
{
|
||||
"settings": [
|
||||
{
|
||||
"provider": "loopia",
|
||||
"domain": "domain.com",
|
||||
"username": "username",
|
||||
"password": "password",
|
||||
"ip_version": "ipv4",
|
||||
"ipv6_suffix": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain), `sub.example.com` (subdomain of `example.com`). It cannot be a wildcard domain.
|
||||
- `"username"`
|
||||
- `"password"`
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
@@ -10,6 +10,7 @@
|
||||
{
|
||||
"provider": "luadns",
|
||||
"domain": "domain.com",
|
||||
"host": "@",
|
||||
"email": "email",
|
||||
"token": "token",
|
||||
"ip_version": "ipv4",
|
||||
@@ -21,14 +22,15 @@
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain), `sub.example.com` (subdomain of `example.com`) or `*.example.com` for the wildcard.
|
||||
- `"domain"`
|
||||
- `"host"` is your host and can be a subdomain or `"@"` or `"*"`
|
||||
- `"email"`
|
||||
- `"token"`
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
|
||||
## Domain setup
|
||||
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
# [Myaddr](https://myaddr.tools/)
|
||||
|
||||
## Configuration
|
||||
|
||||
### Example
|
||||
|
||||
```json
|
||||
{
|
||||
"settings": [
|
||||
{
|
||||
"provider": "myaddr",
|
||||
"domain": "your-name.myaddr.tools",
|
||||
"key": "key",
|
||||
"ip_version": "ipv4",
|
||||
"ipv6_suffix": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` - the **single** domain to update; note the `key` below updates all records and subdomains for this domain. It should be `your-name.myaddr.tools`.
|
||||
- `"key"` - the private key corresponding to the domain to update
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
|
||||
## Domain setup
|
||||
|
||||
Claim a subdomain at [myaddr.tools](https://myaddr.tools/)
|
||||
@@ -12,6 +12,7 @@
|
||||
{
|
||||
"provider": "name.com",
|
||||
"domain": "domain.com",
|
||||
"host": "@",
|
||||
"username": "username",
|
||||
"token": "token",
|
||||
"ttl": 300,
|
||||
@@ -24,7 +25,8 @@
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain), `sub.example.com` (subdomain of `example.com`) or `*.example.com` for the wildcard.
|
||||
- `"domain"`
|
||||
- `"host"` is your host and can be a subdomain, `"@"` or `"*"` generally
|
||||
- `"username"` is your account username
|
||||
- `"token"` which you can obtain from [www.name.com/account/settings/api](https://www.name.com/account/settings/api)
|
||||
|
||||
@@ -32,4 +34,4 @@
|
||||
|
||||
- `"ttl"` is the time this record can be cached for in seconds. Name.com allows a minimum TTL of 300, or 5 minutes. Name.com defaults to 300 if not provided.
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
{
|
||||
"provider": "namecheap",
|
||||
"domain": "domain.com",
|
||||
"password": "password"
|
||||
"host": "@",
|
||||
"password": "password",
|
||||
"provider_ip": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -18,11 +20,14 @@
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain), `sub.example.com` (subdomain of `example.com`) or `*.example.com` for the wildcard.
|
||||
- `"domain"`
|
||||
- `"host"` is your host and can be a subdomain, `"@"` or `"*"` generally
|
||||
- `"password"`
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"provider_ip"` can be set to `true` to let your DNS provider determine your IPv4 address (and/or IPv6 address) automatically when you send an update request, without sending the new IP address detected by the program in the request.
|
||||
|
||||
Note that Namecheap only supports ipv4 addresses for now.
|
||||
|
||||
## Domain setup
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
# NameSilo
|
||||
|
||||
[](https://www.namesilo.com)
|
||||
|
||||
## Configuration
|
||||
|
||||
### Example
|
||||
|
||||
```json
|
||||
{
|
||||
"settings": [
|
||||
{
|
||||
"provider": "namesilo",
|
||||
"domain": "sub.example.com",
|
||||
"key": "71dZaE8c2Aa926Ca2E8c1",
|
||||
"ttl": 7207,
|
||||
"ip_version": "ipv4"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain), `sub.example.com` (subdomain of `example.com`) or `*.example.com` for the wildcard.
|
||||
- `"key"` is the NameSilo API Key obtained using the domain setup instructions below. For example: `71dZaE8c2Aa926Ca2E8c1`.
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ttl"` is the record's Time to Live (TTL), which defaults to `7207` seconds. It must be numeric, less than `2592001`, and greater than or equal to `3600`. TTL values of `3603` or `7207` may be subject to NameSilo's [Automatic TTL Adjustments](https://www.namesilo.com/support/v2/articles/domain-manager/dns-manager#auto_ttl).
|
||||
|
||||
## Domain setup
|
||||
|
||||
1. Login to the [Namesilo API Manager](https://www.namesilo.com/account/api-manager) with your account credentials.
|
||||
1. Generate an API key. The generated API key will look similar to `71dZaE8c2Aa926Ca2E8c1`.
|
||||
- (do _not_ check the "Generate key for read-only access" box)
|
||||
|
||||
[](https://www.namesilo.com/account/api-manager)
|
||||
[](https://www.namesilo.com/account/api-manager)
|
||||
|
||||
## Testing
|
||||
|
||||
1. Go to the [NameSilo Domain Manager](https://www.namesilo.com/account_domains.php).
|
||||
1. Choose "Manage DNS for this domain" (the globe icon) for the domain you wish to test.
|
||||
[](https://www.namesilo.com/account_domains.php)
|
||||
|
||||
1. Change the IP address of the host to `127.0.0.1`.
|
||||
1. Run the ddns-updater.
|
||||
1. Refresh the Namesilo webpage to check the update occurred.
|
||||
@@ -14,6 +14,7 @@ Also keep in mind, that TTL, Expire, Retry and Refresh values of the given Domai
|
||||
{
|
||||
"provider": "netcup",
|
||||
"domain": "domain.com",
|
||||
"host": "host",
|
||||
"api_key": "xxxxx",
|
||||
"password": "yyyyy",
|
||||
"customer_number": "111111",
|
||||
@@ -26,7 +27,8 @@ Also keep in mind, that TTL, Expire, Retry and Refresh values of the given Domai
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain) or `sub.example.com` (subdomain of `example.com`) or the wildcard `*.example.com`.
|
||||
- `"domain"` is your domain
|
||||
- `"host"` is your host (subdomain) or `"@"` for the root of the domain. It cannot be the wildcard.
|
||||
- `"api_key"` is your api key (generated in the [customercontrolpanel](https://www.customercontrolpanel.de))
|
||||
- `"password"` is your api password (generated in the [customercontrolpanel](https://www.customercontrolpanel.de)). Netcup only allows one ApiPassword. This is not the account password. This password is used for all api keys.
|
||||
- `"customer_number"` is your customer number (viewable in the [customercontrolpanel](https://www.customercontrolpanel.de) next to your name). As seen in the example above, provide the number as string value.
|
||||
@@ -34,4 +36,4 @@ Also keep in mind, that TTL, Expire, Retry and Refresh values of the given Domai
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
|
||||
@@ -10,9 +10,11 @@
|
||||
{
|
||||
"provider": "njalla",
|
||||
"domain": "domain.com",
|
||||
"host": "@",
|
||||
"key": "key",
|
||||
"ip_version": "ipv4",
|
||||
"ipv6_suffix": ""
|
||||
"ipv6_suffix": "",
|
||||
"provider_ip": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -20,13 +22,15 @@
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain), `sub.example.com` (subdomain of `example.com`) or `*.example.com` for the wildcard.
|
||||
- `"domain"`
|
||||
- `"host"` is your host and can be a subdomain or `"@"` or `"*"`
|
||||
- `"key"` is the key for your record
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
- `"provider_ip"` can be set to `true` to let your DNS provider determine your IPv4 address (and/or IPv6 address) automatically when you send an update request, without sending the new IP address detected by the program in the request.
|
||||
|
||||
## Domain setup
|
||||
|
||||
|
||||
10
docs/noip.md
10
docs/noip.md
@@ -10,10 +10,12 @@
|
||||
{
|
||||
"provider": "noip",
|
||||
"domain": "domain.com",
|
||||
"host": "@",
|
||||
"username": "username",
|
||||
"password": "password",
|
||||
"ip_version": "ipv4",
|
||||
"ipv6_suffix": ""
|
||||
"ipv6_suffix": "",
|
||||
"provider_ip": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -21,13 +23,15 @@
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain) or `sub.example.com` (subdomain of `example.com`).
|
||||
- `"domain"`
|
||||
- `"host"` is your host and can be a subdomain or `"@"`
|
||||
- `"username"`
|
||||
- `"password"`
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
- `"provider_ip"` can be set to `true` to let your DNS provider determine your IPv4 address (and/or IPv6 address) automatically when you send an update request, without sending the new IP address detected by the program in the request.
|
||||
|
||||
## Domain setup
|
||||
|
||||
@@ -28,4 +28,4 @@
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
|
||||
@@ -10,10 +10,12 @@
|
||||
{
|
||||
"provider": "opendns",
|
||||
"domain": "domain.com",
|
||||
"host": "@",
|
||||
"username": "username",
|
||||
"password": "password",
|
||||
"ip_version": "ipv4",
|
||||
"ipv6_suffix": ""
|
||||
"ipv6_suffix": "",
|
||||
"provider_ip": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -21,13 +23,15 @@
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain) or `sub.example.com` (subdomain of `example.com`).
|
||||
- `"domain"`
|
||||
- `"host"` is your host and can be a subdomain or `"@"`
|
||||
- `"username"`
|
||||
- `"password"`
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
- `"provider_ip"` can be set to `true` to let your DNS provider determine your IPv4 address (and/or IPv6 address) automatically when you send an update request, without sending the new IP address detected by the program in the request.
|
||||
|
||||
## Domain setup
|
||||
|
||||
12
docs/ovh.md
12
docs/ovh.md
@@ -10,10 +10,12 @@
|
||||
{
|
||||
"provider": "ovh",
|
||||
"domain": "domain.com",
|
||||
"host": "@",
|
||||
"username": "username",
|
||||
"password": "password",
|
||||
"ip_version": "ipv4",
|
||||
"ipv6_suffix": ""
|
||||
"ipv6_suffix": "",
|
||||
"provider_ip": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -21,7 +23,8 @@
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain) or `sub.example.com` (subdomain of `example.com`).
|
||||
- `"domain"`
|
||||
- `"host"` is your host and can be a subdomain or `"@"`
|
||||
|
||||
#### Using DynHost
|
||||
|
||||
@@ -33,14 +36,15 @@
|
||||
- `"api_endpoint"` default value is `"ovh-eu"`
|
||||
- `"app_key"` which you can create at [eu.api.ovh.com/createApp](https://eu.api.ovh.com/createApp/)
|
||||
- `"app_secret"`
|
||||
- `"consumer_key"` which you can get at [www.ovh.com/auth/api/createToken](https://www.ovh.com/auth/api/createToken)
|
||||
- `"consumer_key"`
|
||||
|
||||
The ZoneDNS implementation allows you to update any record name including *.yourdomain.tld
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
- `"provider_ip"` can be set to `true` to let your DNS provider determine your IPv4 address (and/or IPv6 address) automatically when you send an update request, without sending the new IP address detected by the program in the request.
|
||||
- `"mode"` select between two modes, OVH's dynamic hosting service (`"dynamic"`) or OVH's API (`"api"`). Default is `"dynamic"`
|
||||
|
||||
## Domain setup
|
||||
|
||||
@@ -10,8 +10,9 @@
|
||||
{
|
||||
"provider": "porkbun",
|
||||
"domain": "domain.com",
|
||||
"api_key": "pk1_5299b57125c8f3cdf347d2fe0e713311ee3a1e11f11a14942b26472593e35368",
|
||||
"secret_api_key": "sk1_7d119e3f656b00ae042980302e1425a04163c476efec1833q3cb0w54fc6f5022",
|
||||
"host": "@",
|
||||
"api_key": "sk1_7d119e3f656b00ae042980302e1425a04163c476efec1833q3cb0w54fc6f5022",
|
||||
"secret_api_key": "pk1_5299b57125c8f3cdf347d2fe0e713311ee3a1e11f11a14942b26472593e35368",
|
||||
"ip_version": "ipv4",
|
||||
"ipv6_suffix": ""
|
||||
}
|
||||
@@ -21,15 +22,16 @@
|
||||
|
||||
### Compulsory Parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain), `sub.example.com` (subdomain of `example.com`) or `*.example.com` for the wildcard.
|
||||
- `"api_key"`
|
||||
- `"secret_api_key"`
|
||||
- `"domain"`
|
||||
- `"host"` is your host and can be a subdomain, `"*"` or `"@"`
|
||||
- `"apikey"`
|
||||
- `"secretapikey"`
|
||||
- `"ttl"` optional integer value corresponding to a number of seconds
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
|
||||
## Domain setup
|
||||
|
||||
@@ -41,12 +43,5 @@
|
||||
## Record creation
|
||||
|
||||
In case you don't have an A or AAAA record for your host and domain combination, it will be created by DDNS-Updater.
|
||||
|
||||
Porkbun creates default DNS entries for new domains, which can conflict with creating a root or wildcard A/AAAA record. Therefore, ddns-updater automatically removes any conflicting default record before creating records, as described in the table below:
|
||||
|
||||
| Record type | Owner | Record value | Situation requiring a removal |
|
||||
| --- | --- | --- | --- |
|
||||
| `ALIAS` | `@` | pixie.porkbun.com | Creating A or AAAA record for the root domain **or** wildcard domain |
|
||||
| `CNAME` | `*` | pixie.porkbun.com | Creating A or AAAA record for the wildcard domain |
|
||||
|
||||
However, to do so, the corresponding ALIAS record, that is automatically created by Porkbun, is automatically deleted to allow this.
|
||||
More details is in [this comment by @everydaycombat](https://github.com/qdm12/ddns-updater/issues/546#issuecomment-1773960193).
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
{
|
||||
"provider": "route53",
|
||||
"domain": "domain.com",
|
||||
"host": "@",
|
||||
"ip_version": "ipv4",
|
||||
"ipv6_suffix": "",
|
||||
"access_key": "ffffffffffffffffffff",
|
||||
@@ -23,7 +24,8 @@
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain), `sub.example.com` (subdomain of `example.com`) or `*.example.com` for the wildcard.
|
||||
- `"domain"`
|
||||
- `"host"` is your host and can be a subdomain or `"@"` or the wildcard `"*"`
|
||||
- `"access_key"` is the `AWS_ACCESS_KEY`
|
||||
- `"secret_key"` is the `AWS_SECRET_ACCESS_KEY`
|
||||
- `"zone_id"` is identification of your hosted zone
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
# Example.com
|
||||
|
||||
## Configuration
|
||||
|
||||
If something is unclear in the documentation below, please refer to the [scaleway API documentation](https://www.scaleway.com/en/developers/api/domains-and-dns/#path-records-update-records-within-a-dns-zone).
|
||||
|
||||
### Example
|
||||
|
||||
```json
|
||||
{
|
||||
"settings": [
|
||||
{
|
||||
"provider": "scaleway",
|
||||
"domain": "domain.com",
|
||||
"secret_key": "<SECRET_KEY>",
|
||||
"ip_version": "ipv4",
|
||||
"ipv6_suffix": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain), `sub.example.com` (subdomain of `example.com`) or `*.example.com` for the wildcard.
|
||||
- `"secret_key"` is your secret key
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ttl"` is the TTL of the DNS record to update, if you want to specify it.
|
||||
|
||||
## Domain setup
|
||||
|
||||
If you need more information about how to configure your domain, you can check the [scaleway official documentation](https://www.scaleway.com/en/docs/network/domains-and-dns/).
|
||||
@@ -10,8 +10,10 @@
|
||||
{
|
||||
"provider": "selfhost.de",
|
||||
"domain": "domain.com",
|
||||
"host": "@",
|
||||
"username": "username",
|
||||
"password": "password",
|
||||
"provider_ip": true,
|
||||
"ip_version": "ipv4",
|
||||
"ipv6_suffix": ""
|
||||
}
|
||||
@@ -21,13 +23,15 @@
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain) or `sub.example.com` (subdomain of `example.com`).
|
||||
- `"domain"`
|
||||
- `"host"` is your host and can be a subdomain or `"@"`
|
||||
- `"username"` is your DynDNS username
|
||||
- `"password"` is your DynDNS password
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
- `"provider_ip"` can be set to `true` to let your DNS provider determine your IPv4 address (and/or IPv6 address) automatically when you send an update request, without sending the new IP address detected by the program in the request.
|
||||
|
||||
## Domain setup
|
||||
|
||||
@@ -10,9 +10,11 @@
|
||||
{
|
||||
"provider": "servercow",
|
||||
"domain": "domain.com",
|
||||
"host": "",
|
||||
"username": "servercow_username",
|
||||
"password": "servercow_password",
|
||||
"ttl": 600,
|
||||
"provider_ip": true,
|
||||
"ip_version": "ipv4",
|
||||
"ipv6_suffix": ""
|
||||
}
|
||||
@@ -22,7 +24,8 @@
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain), `sub.example.com` (subdomain of `example.com`) or `*.example.com` for the wildcard.
|
||||
- `"domain"`
|
||||
- `"host"` is your host and can be `""`, a subdomain or `"*"` generally
|
||||
- `"username"` is the username for your DNS API User
|
||||
- `"password"` is the password for your DNS API User
|
||||
|
||||
@@ -30,8 +33,9 @@
|
||||
|
||||
- `"ttl"` can be set to an integer value for record TTL in seconds (if not set the default is 120)
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
- `"provider_ip"` can be set to `true` to let your DNS provider determine your IPv4 address (and/or IPv6 address) automatically when you send an update request, without sending the new IP address detected by the program in the request.
|
||||
|
||||
## Domain setup
|
||||
|
||||
See [their article](https://wiki.servercow.de/en/domains/dns_api/api-syntax/)
|
||||
See [their article](https://cp.servercow.de/en/plugin/support_manager/knowledgebase/view/34/dns-api-v1/7/)
|
||||
|
||||
@@ -10,11 +10,13 @@
|
||||
{
|
||||
"provider": "spdyn",
|
||||
"domain": "domain.com",
|
||||
"host": "@",
|
||||
"user": "user",
|
||||
"password": "password",
|
||||
"token": "token",
|
||||
"ip_version": "ipv4",
|
||||
"ipv6_suffix": ""
|
||||
"ipv6_suffix": "",
|
||||
"provider_ip": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -22,7 +24,8 @@
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain) or `sub.example.com` (subdomain of `example.com`).
|
||||
- `"domain"`
|
||||
- `"host"` is your host and can be a subdomain or `"@"`
|
||||
|
||||
#### Using user and password
|
||||
|
||||
@@ -36,4 +39,5 @@
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
- `"provider_ip"` can be set to `true` to let your DNS provider determine your IPv4 address (**not IPv6**)automatically when you send an update request, without sending the new IP address detected by the program in the request.
|
||||
|
||||
@@ -10,9 +10,11 @@
|
||||
{
|
||||
"provider": "strato",
|
||||
"domain": "domain.com",
|
||||
"host": "@",
|
||||
"password": "password",
|
||||
"ip_version": "ipv4",
|
||||
"ipv6_suffix": ""
|
||||
"ipv6_suffix": "",
|
||||
"provider_ip": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -20,13 +22,15 @@
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain) or `sub.example.com` (subdomain of `example.com`).
|
||||
- `"domain"`
|
||||
- `"host"` is your host and can be a subdomain or `"@"`
|
||||
- `"password"` is your dyndns password
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
- `"provider_ip"` can be set to `true` to let your DNS provider determine your IPv4 address (and/or IPv6 address) automatically when you send an update request, without sending the new IP address detected by the program in the request.
|
||||
|
||||
## Domain setup
|
||||
|
||||
|
||||
@@ -10,10 +10,12 @@
|
||||
{
|
||||
"provider": "variomedia",
|
||||
"domain": "domain.com",
|
||||
"host": "@",
|
||||
"email": "email@domain.com",
|
||||
"password": "password",
|
||||
"ip_version": "ipv4",
|
||||
"ipv6_suffix": ""
|
||||
"ipv6_suffix": "",
|
||||
"provider_ip": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -21,14 +23,16 @@
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain) or `sub.example.com` (subdomain of `example.com`).
|
||||
- `"domain"`
|
||||
- `"host"` is your host and can be a subdomain or `"@"`
|
||||
- `"email"`
|
||||
- `"password"` is your DNS settings password, not your account password ⚠️
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
- `"provider_ip"` can be set to `true` to let your DNS provider determine your IPv4 address (and/or IPv6 address) automatically when you send an update request, without sending the new IP address detected by the program in the request.
|
||||
|
||||
## Domain setup
|
||||
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
# Vercel
|
||||
|
||||
## Configuration
|
||||
|
||||
### Example
|
||||
|
||||
```json
|
||||
{
|
||||
"settings": [
|
||||
{
|
||||
"provider": "vercel",
|
||||
"domain": "domain.com",
|
||||
"token": "yourtoken",
|
||||
"ip_version": "ipv4",
|
||||
"ipv6_suffix": "",
|
||||
"team_id": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain), `sub.example.com` (subdomain of `example.com`) or `*.example.com` for the wildcard.
|
||||
- `"token"` is your Vercel API token. You can create one at [Vercel Account Settings > Tokens](https://vercel.com/account/tokens).
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"team_id"` is your Vercel team ID. Required if the domain belongs to a team rather than your personal account. You can find this in your team settings.
|
||||
- `"ttl"` is the TTL in seconds for the DNS record. It defaults to being not set, using the existing TTL configured for the record in Vercel or the default TTL determined by Vercel.
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
|
||||
## Domain setup
|
||||
|
||||
1. Ensure your domain is added to Vercel. You can do this via the [Vercel Dashboard](https://vercel.com/dashboard) under your project's Domain settings, or via the API.
|
||||
1. Your domain must be using Vercel's nameservers or have DNS management delegated to Vercel for this provider to work.
|
||||
1. Create an API token with appropriate permissions at [Vercel Account Settings > Tokens](https://vercel.com/account/tokens).
|
||||
1. If the domain belongs to a team, make sure to include the `team_id` parameter in your configuration.
|
||||
@@ -1,30 +0,0 @@
|
||||
# Vultr
|
||||
|
||||
## Configuration
|
||||
|
||||
### Example
|
||||
|
||||
```json
|
||||
{
|
||||
"settings": [
|
||||
{
|
||||
"provider": "vultr",
|
||||
"domain": "potato.example.com",
|
||||
"apikey": "AAAAAAAAAAAAAAA",
|
||||
"ttl": 300,
|
||||
"ip_version": "ipv4"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be a root domain (i.e. `example.com`) or a subdomain (i.e. `potato.example.com`) or a wildcard (i.e. `*.example.com`). In case of a wildcard, it only works if there is no existing wildcard records of any record type.
|
||||
- `"apikey"` is your API key which can be obtained from [my.vultr.com/settings/](https://my.vultr.com/settings/#settingsapi).
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ttl"` is the record TTL which defaults to 900 seconds.
|
||||
@@ -16,10 +16,12 @@ set the environment variable as `PERIOD=11m` to check your public IP address and
|
||||
{
|
||||
"provider": "zoneedit",
|
||||
"domain": "domain.com",
|
||||
"host": "@",
|
||||
"username": "username",
|
||||
"token": "token",
|
||||
"ip_version": "ipv4",
|
||||
"ipv6_suffix": ""
|
||||
"ipv6_suffix": "",
|
||||
"provider_ip": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -27,14 +29,16 @@ set the environment variable as `PERIOD=11m` to check your public IP address and
|
||||
|
||||
### Compulsory parameters
|
||||
|
||||
- `"domain"` is the domain to update. It can be `example.com` (root domain), `sub.example.com` (subdomain of `example.com`) or `*.example.com` for the wildcard.
|
||||
- `"domain"`
|
||||
- `"host"` is your host and can be a subdomain or `"@"` or `"*"`
|
||||
- `"username"`
|
||||
- `"token"`
|
||||
|
||||
### Optional parameters
|
||||
|
||||
- `"ip_version"` can be `ipv4` (A records), or `ipv6` (AAAA records) or `ipv4 or ipv6` (update one of the two, depending on the public ip found). It defaults to `ipv4 or ipv6`.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw temporary IPv6 address of the machine is used in the record updating. You might want to set this to use your permanent IPv6 address instead of your temporary IPv6 address.
|
||||
- `"ipv6_suffix"` is the IPv6 interface identifier suffix to use. It can be for example `0:0:0:0:72ad:8fbb:a54e:bedd/64`. If left empty, it defaults to no suffix and the raw public IPv6 address obtained is used in the record updating.
|
||||
- `"provider_ip"` can be set to `true` to let your DNS provider determine your IPv4 address (and/or IPv6 address) automatically when you send an update request, without sending the new IP address detected by the program in the request.
|
||||
|
||||
## Domain setup
|
||||
|
||||
|
||||
49
go.mod
49
go.mod
@@ -1,39 +1,40 @@
|
||||
module github.com/qdm12/ddns-updater
|
||||
|
||||
go 1.26.0
|
||||
go 1.22
|
||||
|
||||
require (
|
||||
github.com/breml/rootcerts v0.3.5
|
||||
github.com/breml/rootcerts v0.2.18
|
||||
github.com/chmike/domain v1.0.1
|
||||
github.com/containrrr/shoutrrr v0.8.0
|
||||
github.com/go-chi/chi/v5 v5.2.5
|
||||
github.com/miekg/dns v1.1.72
|
||||
github.com/go-chi/chi/v5 v5.0.12
|
||||
github.com/golang/mock v1.6.0
|
||||
github.com/miekg/dns v1.1.61
|
||||
github.com/qdm12/goservices v0.1.0
|
||||
github.com/qdm12/gosettings v0.4.4
|
||||
github.com/qdm12/gosplash v0.2.0
|
||||
github.com/qdm12/gotree v0.3.0
|
||||
github.com/qdm12/gosettings v0.4.4-rc1
|
||||
github.com/qdm12/gosplash v0.1.0
|
||||
github.com/qdm12/gotree v0.2.0
|
||||
github.com/qdm12/log v0.1.0
|
||||
github.com/stretchr/testify v1.11.1
|
||||
go.uber.org/mock v0.6.0
|
||||
golang.org/x/mod v0.35.0
|
||||
golang.org/x/net v0.53.0
|
||||
golang.org/x/oauth2 v0.36.0
|
||||
github.com/stretchr/testify v1.9.0
|
||||
golang.org/x/mod v0.18.0
|
||||
golang.org/x/oauth2 v0.21.0
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go/compute/metadata v0.9.0 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.3.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/fatih/color v1.18.0 // indirect
|
||||
github.com/go-logr/logr v1.4.3 // indirect
|
||||
github.com/fatih/color v1.15.0 // indirect
|
||||
github.com/go-logr/logr v1.4.1 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.17 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 // indirect
|
||||
golang.org/x/sync v0.20.0 // indirect
|
||||
golang.org/x/sys v0.43.0 // indirect
|
||||
golang.org/x/tools v0.43.0 // indirect
|
||||
google.golang.org/protobuf v1.36.11 // indirect
|
||||
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect
|
||||
golang.org/x/net v0.26.0 // indirect
|
||||
golang.org/x/sync v0.7.0 // indirect
|
||||
golang.org/x/sys v0.21.0 // indirect
|
||||
golang.org/x/tools v0.22.0 // indirect
|
||||
google.golang.org/protobuf v1.34.1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
kernel.org/pub/linux/libs/security/libcap/cap v1.2.77 // indirect
|
||||
kernel.org/pub/linux/libs/security/libcap/psx v1.2.77 // indirect
|
||||
kernel.org/pub/linux/libs/security/libcap/cap v1.2.69 // indirect
|
||||
kernel.org/pub/linux/libs/security/libcap/psx v1.2.69 // indirect
|
||||
)
|
||||
|
||||
130
go.sum
130
go.sum
@@ -1,35 +1,39 @@
|
||||
cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs=
|
||||
cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10=
|
||||
github.com/breml/rootcerts v0.3.5 h1:oi7YiZ25HH52+mrKyjrMkcAFfnRDUf6HO8aUDr7RlJI=
|
||||
github.com/breml/rootcerts v0.3.5/go.mod h1:S/PKh+4d1HUn4HQovEB8hPJZO6pUZYrIhmXBhsegfXw=
|
||||
cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc=
|
||||
cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
|
||||
github.com/breml/rootcerts v0.2.18 h1:KjZaNT7AX/akUjzpStuwTMQs42YHlPyc6NmdwShVba0=
|
||||
github.com/breml/rootcerts v0.2.18/go.mod h1:S/PKh+4d1HUn4HQovEB8hPJZO6pUZYrIhmXBhsegfXw=
|
||||
github.com/chmike/domain v1.0.1 h1:ug6h3a7LLAfAecBAysbCXWxP1Jo8iBKWNVDxcs1BNzA=
|
||||
github.com/chmike/domain v1.0.1/go.mod h1:h558M2qGKpYRUxHHNyey6puvXkZBjvjmseOla/d1VGQ=
|
||||
github.com/containrrr/shoutrrr v0.8.0 h1:mfG2ATzIS7NR2Ec6XL+xyoHzN97H8WPjir8aYzJUSec=
|
||||
github.com/containrrr/shoutrrr v0.8.0/go.mod h1:ioyQAyu1LJY6sILuNyKaQaw+9Ttik5QePU8atnAdO2o=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
||||
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
|
||||
github.com/go-chi/chi/v5 v5.2.5 h1:Eg4myHZBjyvJmAFjFvWgrqDTXFyOzjj7YIm3L3mu6Ug=
|
||||
github.com/go-chi/chi/v5 v5.2.5/go.mod h1:X7Gx4mteadT3eDOMTsXzmI4/rwUpOwBHLpAfupzFJP0=
|
||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
|
||||
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
|
||||
github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s=
|
||||
github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
||||
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
||||
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
||||
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/jarcoal/httpmock v1.3.0 h1:2RJ8GP0IIaWwcC9Fp2BmVi8Kog3v2Hn7VXM3fTd+nuc=
|
||||
github.com/jarcoal/httpmock v1.3.0/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg=
|
||||
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
|
||||
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/miekg/dns v1.1.72 h1:vhmr+TF2A3tuoGNkLDFK9zi36F2LS+hKTRW0Uf8kbzI=
|
||||
github.com/miekg/dns v1.1.72/go.mod h1:+EuEPhdHOsfk6Wk5TT2CzssZdqkmFhf8r+aVyDEToIs=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
|
||||
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs=
|
||||
github.com/miekg/dns v1.1.61/go.mod h1:mnAarhS3nWaW+NVP2wTkYVIZyHNJ098SJZUki3eykwQ=
|
||||
github.com/onsi/ginkgo/v2 v2.9.2 h1:BA2GMJOtfGAfagzYtrAlufIP0lq6QERkFmHLMLPwFSU=
|
||||
github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts=
|
||||
github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE=
|
||||
@@ -38,42 +42,66 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/qdm12/goservices v0.1.0 h1:9sODefm/yuIGS7ynCkEnNlMTAYn9GzPhtcK4F69JWvc=
|
||||
github.com/qdm12/goservices v0.1.0/go.mod h1:/JOFsAnHFiSjyoXxa5FlfX903h20K5u/3rLzCjYVMck=
|
||||
github.com/qdm12/gosettings v0.4.4 h1:SM6tOZDf6k8qbjWU8KWyBF4mWIixfsKCfh9DGRLHlj4=
|
||||
github.com/qdm12/gosettings v0.4.4/go.mod h1:CPrt2YC4UsURTrslmhxocVhMCW03lIrqdH2hzIf5prg=
|
||||
github.com/qdm12/gosplash v0.2.0 h1:DOxCEizbW6ZG+FgpH2oK1atT6bM8MHL9GZ2ywSS4zZY=
|
||||
github.com/qdm12/gosplash v0.2.0/go.mod h1:k+1PzhO0th9cpX4q2Nneu4xTsndXqrM/x7NTIYmJ4jo=
|
||||
github.com/qdm12/gotree v0.3.0 h1:Q9f4C571EFK7ZEsPkEL2oGZX7I+ZhVxhh1ZSydW+5yI=
|
||||
github.com/qdm12/gotree v0.3.0/go.mod h1:iz06uXmRR4Aq9v6tX7mosXStO/yGHxRA1hbyD0UVeYw=
|
||||
github.com/qdm12/gosettings v0.4.4-rc1 h1:VT+6O6ww3Cn5v5/LgY2zlXoiCkZzbaLDWaA8ufQoOLY=
|
||||
github.com/qdm12/gosettings v0.4.4-rc1/go.mod h1:CPrt2YC4UsURTrslmhxocVhMCW03lIrqdH2hzIf5prg=
|
||||
github.com/qdm12/gosplash v0.1.0 h1:Sfl+zIjFZFP7b0iqf2l5UkmEY97XBnaKkH3FNY6Gf7g=
|
||||
github.com/qdm12/gosplash v0.1.0/go.mod h1:+A3fWW4/rUeDXhY3ieBzwghKdnIPFJgD8K3qQkenJlw=
|
||||
github.com/qdm12/gotree v0.2.0 h1:+58ltxkNLUyHtATFereAcOjBVfY6ETqRex8XK90Fb/c=
|
||||
github.com/qdm12/gotree v0.2.0/go.mod h1:1SdFaqKZuI46U1apbXIf25pDMNnrPuYLEqMF/qL4lY4=
|
||||
github.com/qdm12/log v0.1.0 h1:jYBd/xscHYpblzZAd2kjZp2YmuYHjAAfbTViJWxoPTw=
|
||||
github.com/qdm12/log v0.1.0/go.mod h1:Vchi5M8uBvHfPNIblN4mjXn/oSbiWguQIbsgF1zdQPI=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
|
||||
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
|
||||
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 h1:fQsdNF2N+/YewlRZiricy4P1iimyPKZ/xwniHj8Q2a0=
|
||||
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93/go.mod h1:EPRbTFwzwjXj9NpYyyrvenVh9Y+GFeEvMNh7Xuz7xgU=
|
||||
golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM=
|
||||
golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU=
|
||||
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
|
||||
golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs=
|
||||
golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
|
||||
golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
|
||||
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
|
||||
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
|
||||
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
|
||||
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
|
||||
golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s=
|
||||
golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0=
|
||||
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ=
|
||||
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
|
||||
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
|
||||
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
||||
golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs=
|
||||
golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
|
||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
|
||||
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
|
||||
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
kernel.org/pub/linux/libs/security/libcap/cap v1.2.77 h1:iQtQTjFUOcTT19fI8sTCzYXsjeVs56et3D8AbKS2Uks=
|
||||
kernel.org/pub/linux/libs/security/libcap/cap v1.2.77/go.mod h1:oV+IO8kGh0B7TxErbydDe2+BRmi9g/W0CkpVV+QBTJU=
|
||||
kernel.org/pub/linux/libs/security/libcap/psx v1.2.77 h1:Z06sMOzc0GNCwp6efaVrIrz4ywGJ1v+DP0pjVkOfDuA=
|
||||
kernel.org/pub/linux/libs/security/libcap/psx v1.2.77/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24=
|
||||
kernel.org/pub/linux/libs/security/libcap/cap v1.2.69 h1:N0m3tKYbkRMmDobh/47ngz+AWeV7PcfXMDi8xu3Vrag=
|
||||
kernel.org/pub/linux/libs/security/libcap/cap v1.2.69/go.mod h1:Tk5Ip2TuxaWGpccL7//rAsLRH6RQ/jfqTGxuN/+i/FQ=
|
||||
kernel.org/pub/linux/libs/security/libcap/psx v1.2.69 h1:IdrOs1ZgwGw5CI+BH6GgVVlOt+LAXoPyh7enr8lfaXs=
|
||||
kernel.org/pub/linux/libs/security/libcap/psx v1.2.69/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24=
|
||||
|
||||
@@ -20,8 +20,7 @@ type Service struct {
|
||||
}
|
||||
|
||||
func New(backupPeriod time.Duration,
|
||||
dataDir, outputDir string, logger Logger,
|
||||
) *Service {
|
||||
dataDir, outputDir string, logger Logger) *Service {
|
||||
return &Service{
|
||||
logger: logger,
|
||||
backupPeriod: backupPeriod,
|
||||
@@ -57,8 +56,7 @@ func (s *Service) Start(ctx context.Context) (runError <-chan error, startErr er
|
||||
|
||||
func run(ready chan<- struct{}, runError chan<- error, stopCh <-chan struct{},
|
||||
done chan<- struct{}, outputDir, dataDir string, backupPeriod time.Duration,
|
||||
logger Logger,
|
||||
) {
|
||||
logger Logger) {
|
||||
defer close(done)
|
||||
|
||||
if backupPeriod == 0 {
|
||||
|
||||
@@ -12,26 +12,21 @@ import (
|
||||
)
|
||||
|
||||
type Health struct {
|
||||
// ServerAddress is the listening address:port of the
|
||||
// health server, which defaults to the empty string,
|
||||
// meaning the server will not run.
|
||||
ServerAddress *string
|
||||
HealthchecksioBaseURL string
|
||||
HealthchecksioUUID *string
|
||||
}
|
||||
|
||||
func (h *Health) SetDefaults() {
|
||||
h.ServerAddress = gosettings.DefaultPointer(h.ServerAddress, "")
|
||||
h.ServerAddress = gosettings.DefaultPointer(h.ServerAddress, "127.0.0.1:9999")
|
||||
h.HealthchecksioBaseURL = gosettings.DefaultComparable(h.HealthchecksioBaseURL, "https://hc-ping.com")
|
||||
h.HealthchecksioUUID = gosettings.DefaultPointer(h.HealthchecksioUUID, "")
|
||||
}
|
||||
|
||||
func (h Health) Validate() (err error) {
|
||||
if *h.ServerAddress != "" {
|
||||
err = validate.ListeningAddress(*h.ServerAddress, os.Getuid())
|
||||
if err != nil {
|
||||
return fmt.Errorf("server listening address: %w", err)
|
||||
}
|
||||
err = validate.ListeningAddress(*h.ServerAddress, os.Getuid())
|
||||
if err != nil {
|
||||
return fmt.Errorf("server listening address: %w", err)
|
||||
}
|
||||
|
||||
_, err = url.Parse(h.HealthchecksioBaseURL)
|
||||
@@ -48,11 +43,7 @@ func (h Health) String() string {
|
||||
|
||||
func (h Health) toLinesNode() *gotree.Node {
|
||||
node := gotree.New("Health")
|
||||
if *h.ServerAddress == "" {
|
||||
node.Appendf("Server is disabled")
|
||||
} else {
|
||||
node.Appendf("Server listening address: %s", *h.ServerAddress)
|
||||
}
|
||||
node.Appendf("Server listening address: %s", *h.ServerAddress)
|
||||
if *h.HealthchecksioUUID != "" {
|
||||
node.Appendf("Healthchecks.io base URL: %s", h.HealthchecksioBaseURL)
|
||||
node.Appendf("Healthchecks.io UUID: %s", *h.HealthchecksioUUID)
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
|
||||
"github.com/qdm12/gosettings"
|
||||
"github.com/qdm12/gosettings/reader"
|
||||
@@ -14,17 +11,12 @@ import (
|
||||
type Paths struct {
|
||||
DataDir *string
|
||||
Config *string
|
||||
// Umask is the custom umask to use for the system, if different than zero.
|
||||
// If it is set to zero, the system umask is unchanged.
|
||||
// It cannot be nil in the internal state.
|
||||
Umask *fs.FileMode
|
||||
}
|
||||
|
||||
func (p *Paths) setDefaults() {
|
||||
p.DataDir = gosettings.DefaultPointer(p.DataDir, "./data")
|
||||
defaultConfig := filepath.Join(*p.DataDir, "config.json")
|
||||
p.Config = gosettings.DefaultPointer(p.Config, defaultConfig)
|
||||
p.Umask = gosettings.DefaultPointer(p.Umask, fs.FileMode(0))
|
||||
}
|
||||
|
||||
func (p Paths) Validate() (err error) {
|
||||
@@ -39,35 +31,10 @@ func (p Paths) toLinesNode() *gotree.Node {
|
||||
node := gotree.New("Paths")
|
||||
node.Appendf("Data directory: %s", *p.DataDir)
|
||||
node.Appendf("Config file: %s", *p.Config)
|
||||
umaskString := "system default"
|
||||
if *p.Umask != 0 {
|
||||
umaskString = p.Umask.String()
|
||||
}
|
||||
node.Appendf("Umask: %s", umaskString)
|
||||
return node
|
||||
}
|
||||
|
||||
func (p *Paths) read(reader *reader.Reader) (err error) {
|
||||
func (p *Paths) read(reader *reader.Reader) {
|
||||
p.DataDir = reader.Get("DATADIR")
|
||||
p.Config = reader.Get("CONFIG_FILEPATH")
|
||||
|
||||
umaskString := reader.String("UMASK")
|
||||
if umaskString != "" {
|
||||
umask, err := parseUmask(umaskString)
|
||||
if err != nil {
|
||||
return fmt.Errorf("parse umask: %w", err)
|
||||
}
|
||||
p.Umask = &umask
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseUmask(s string) (umask fs.FileMode, err error) {
|
||||
const base, bitSize = 8, 32
|
||||
umaskUint64, err := strconv.ParseUint(s, base, bitSize)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return fs.FileMode(umaskUint64), nil
|
||||
}
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_parseUmask(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCases := map[string]struct {
|
||||
s string
|
||||
umask fs.FileMode
|
||||
errMessage string
|
||||
}{
|
||||
"invalid": {
|
||||
s: "a",
|
||||
errMessage: `strconv.ParseUint: parsing "a": invalid syntax`,
|
||||
},
|
||||
"704": {
|
||||
s: "704",
|
||||
umask: 0o704,
|
||||
},
|
||||
"0704": {
|
||||
s: "0704",
|
||||
umask: 0o0704,
|
||||
},
|
||||
}
|
||||
|
||||
for name, testCase := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
umask, err := parseUmask(testCase.s)
|
||||
|
||||
if testCase.errMessage != "" {
|
||||
assert.EqualError(t, err, testCase.errMessage)
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
assert.Equal(t, testCase.umask, umask)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -70,28 +70,28 @@ func (p *PubIP) toLinesNode() (node *gotree.Node) {
|
||||
|
||||
node.Appendf("HTTP enabled: %s", gosettings.BoolToYesNo(p.HTTPEnabled))
|
||||
if *p.HTTPEnabled {
|
||||
childNode := node.Append("HTTP IP providers")
|
||||
childNode := node.Appendf("HTTP IP providers")
|
||||
for _, provider := range p.HTTPIPProviders {
|
||||
childNode.Append(provider)
|
||||
childNode.Appendf(provider)
|
||||
}
|
||||
|
||||
childNode = node.Append("HTTP IPv4 providers")
|
||||
childNode = node.Appendf("HTTP IPv4 providers")
|
||||
for _, provider := range p.HTTPIPv4Providers {
|
||||
childNode.Append(provider)
|
||||
childNode.Appendf(provider)
|
||||
}
|
||||
|
||||
childNode = node.Append("HTTP IPv6 providers")
|
||||
childNode = node.Appendf("HTTP IPv6 providers")
|
||||
for _, provider := range p.HTTPIPv6Providers {
|
||||
childNode.Append(provider)
|
||||
childNode.Appendf(provider)
|
||||
}
|
||||
}
|
||||
|
||||
node.Appendf("DNS enabled: %s", gosettings.BoolToYesNo(p.DNSEnabled))
|
||||
if *p.DNSEnabled {
|
||||
node.Appendf("DNS timeout: %s", p.DNSTimeout)
|
||||
childNode := node.Append("DNS over TLS providers")
|
||||
childNode := node.Appendf("DNS over TLS providers")
|
||||
for _, provider := range p.DNSProviders {
|
||||
childNode.Append(provider)
|
||||
childNode.Appendf(provider)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,8 +111,7 @@ func (p *PubIP) ToHTTPOptions() (options []http.Option) {
|
||||
}
|
||||
|
||||
func stringsToHTTPProviders(providers []string, ipVersion ipversion.IPVersion) (
|
||||
updatedProviders []http.Provider,
|
||||
) {
|
||||
updatedProviders []http.Provider) {
|
||||
updatedProvidersSet := make(map[string]struct{}, len(providers))
|
||||
for _, provider := range providers {
|
||||
if provider != all {
|
||||
@@ -159,7 +158,9 @@ func (p *PubIP) ToDNSPOptions() (options []dns.Option) {
|
||||
}
|
||||
}
|
||||
|
||||
var ErrNoPublicIPDNSProvider = errors.New("no public IP DNS provider specified")
|
||||
var (
|
||||
ErrNoPublicIPDNSProvider = errors.New("no public IP DNS provider specified")
|
||||
)
|
||||
|
||||
func (p PubIP) validateDNSProviders() (err error) {
|
||||
if len(p.DNSProviders) == 0 {
|
||||
@@ -193,8 +194,7 @@ var (
|
||||
)
|
||||
|
||||
func validateHTTPIPProviders(providerStrings []string,
|
||||
version ipversion.IPVersion,
|
||||
) (err error) {
|
||||
version ipversion.IPVersion) (err error) {
|
||||
if len(providerStrings) == 0 {
|
||||
return fmt.Errorf("%w", ErrNoPublicIPHTTPProvider)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package config
|
||||
|
||||
type Warner interface {
|
||||
Warnf(format string, a ...any)
|
||||
Warnf(format string, a ...interface{})
|
||||
}
|
||||
|
||||
func handleDeprecated(warner Warner, oldKey, newKey string) {
|
||||
|
||||
@@ -80,8 +80,7 @@ func (c Config) toLinesNode() *gotree.Node {
|
||||
}
|
||||
|
||||
func (c *Config) Read(reader *reader.Reader,
|
||||
warner Warner,
|
||||
) (err error) {
|
||||
warner Warner) (err error) {
|
||||
err = c.Client.read(reader)
|
||||
if err != nil {
|
||||
return fmt.Errorf("reading client settings: %w", err)
|
||||
@@ -108,10 +107,7 @@ func (c *Config) Read(reader *reader.Reader,
|
||||
}
|
||||
|
||||
c.Health.Read(reader)
|
||||
err = c.Paths.read(reader)
|
||||
if err != nil {
|
||||
return fmt.Errorf("reading paths settings: %w", err)
|
||||
}
|
||||
c.Paths.read(reader)
|
||||
|
||||
err = c.Backup.read(reader)
|
||||
if err != nil {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -15,7 +14,7 @@ func Test_Settings_String(t *testing.T) {
|
||||
|
||||
s := defaultSettings.String()
|
||||
|
||||
expected := `Settings summary:
|
||||
const expected = `Settings summary:
|
||||
├── HTTP client
|
||||
| └── Timeout: 20s
|
||||
├── Update
|
||||
@@ -38,11 +37,10 @@ func Test_Settings_String(t *testing.T) {
|
||||
| ├── Listening address: :8000
|
||||
| └── Root URL: /
|
||||
├── Health
|
||||
| └── Server is disabled
|
||||
| └── Server listening address: 127.0.0.1:9999
|
||||
├── Paths
|
||||
| ├── Data directory: ./data
|
||||
| ├── Config file: ` + filepath.Join("data", "config.json") + `
|
||||
| └── Umask: system default
|
||||
| └── Config file: data/config.json
|
||||
├── Backup: disabled
|
||||
└── Logger
|
||||
├── Level: INFO
|
||||
|
||||
@@ -43,7 +43,7 @@ func (s Shoutrrr) ToLinesNode() *gotree.Node {
|
||||
|
||||
childNode := node.Appendf("Addresses")
|
||||
for _, address := range s.Addresses {
|
||||
childNode.Append(address)
|
||||
childNode.Appendf(address)
|
||||
}
|
||||
|
||||
return node
|
||||
|
||||
@@ -7,5 +7,5 @@ import (
|
||||
|
||||
type PersistentDatabase interface {
|
||||
Close() error
|
||||
StoreNewIP(domain, owner string, ip netip.Addr, t time.Time) (err error)
|
||||
StoreNewIP(domain, host string, ip netip.Addr, t time.Time) (err error)
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ var ErrRecordNotFound = errors.New("record not found")
|
||||
func (db *Database) Select(id uint) (record records.Record, err error) {
|
||||
db.RLock()
|
||||
defer db.RUnlock()
|
||||
if id > uint(len(db.data))-1 {
|
||||
if int(id) > len(db.data)-1 {
|
||||
return record, fmt.Errorf("%w: for id %d", ErrRecordNotFound, id)
|
||||
}
|
||||
return db.data[id], nil
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
func (db *Database) Update(id uint, record records.Record) (err error) {
|
||||
db.Lock()
|
||||
defer db.Unlock()
|
||||
if id > uint(len(db.data))-1 {
|
||||
if int(id) > len(db.data)-1 {
|
||||
return fmt.Errorf("%w: for id %d", ErrRecordNotFound, id)
|
||||
}
|
||||
currentCount := len(db.data[id].History)
|
||||
@@ -19,7 +19,7 @@ func (db *Database) Update(id uint, record records.Record) (err error) {
|
||||
if newCount > currentCount {
|
||||
if err := db.persistentDB.StoreNewIP(
|
||||
record.Provider.Domain(),
|
||||
record.Provider.Owner(),
|
||||
record.Provider.Host(),
|
||||
record.History.GetCurrentIP(),
|
||||
record.History.GetSuccessTime(),
|
||||
); err != nil {
|
||||
|
||||
@@ -7,7 +7,9 @@ import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
var ErrHTTPStatusCodeNotOK = errors.New("status code is not OK")
|
||||
var (
|
||||
ErrHTTPStatusCodeNotOK = errors.New("status code is not OK")
|
||||
)
|
||||
|
||||
func CheckHTTP(ctx context.Context, client *http.Client) (err error) {
|
||||
const url = "https://github.com"
|
||||
|
||||
8
internal/health/isdocker.go
Normal file
8
internal/health/isdocker.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package health
|
||||
|
||||
import "os"
|
||||
|
||||
func IsDocker() (ok bool) {
|
||||
_, err := os.Stat("isdocker")
|
||||
return err == nil
|
||||
}
|
||||
@@ -7,8 +7,7 @@ import (
|
||||
)
|
||||
|
||||
func NewServer(address string, logger Logger, healthcheck func(context.Context) error) (
|
||||
server *httpserver.Server, err error,
|
||||
) {
|
||||
server *httpserver.Server, err error) {
|
||||
name := "health"
|
||||
return httpserver.New(httpserver.Settings{
|
||||
Handler: newHandler(healthcheck),
|
||||
|
||||
@@ -23,7 +23,9 @@ type Client struct {
|
||||
uuid string
|
||||
}
|
||||
|
||||
var ErrStatusCode = errors.New("bad status code")
|
||||
var (
|
||||
ErrStatusCode = errors.New("bad status code")
|
||||
)
|
||||
|
||||
type State string
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ package models
|
||||
type BuildInformation struct {
|
||||
Version string `json:"version"`
|
||||
Commit string `json:"commit"`
|
||||
Created string `json:"buildDate"`
|
||||
Date string `json:"buildDate"`
|
||||
}
|
||||
|
||||
func (b BuildInformation) VersionString() string {
|
||||
|
||||
@@ -23,7 +23,7 @@ func (h History) GetPreviousIPs() (previousIPs []netip.Addr) {
|
||||
return nil
|
||||
}
|
||||
previousIPs = make([]netip.Addr, len(h)-1)
|
||||
mostRecentPreviousIPIndex := len(h) - 2 //nolint:mnd
|
||||
mostRecentPreviousIPIndex := len(h) - 2 //nolint:gomnd
|
||||
for i := range previousIPs {
|
||||
previousIPs[i] = h[mostRecentPreviousIPIndex-i].IP
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ func Test_GetPreviousIPs(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for name, testCase := range testCases {
|
||||
testCase := testCase
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
previousIPs := testCase.h.GetPreviousIPs()
|
||||
@@ -72,6 +73,7 @@ func Test_GetDurationSinceSuccess(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for name, tc := range tests {
|
||||
tc := tc
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
now, _ := time.Parse("2006-01-02", "2000-01-01")
|
||||
|
||||
@@ -10,7 +10,7 @@ type HTMLData struct {
|
||||
// It is exported so that the HTML template engine can render it.
|
||||
type HTMLRow struct {
|
||||
Domain string
|
||||
Owner string
|
||||
Host string
|
||||
Provider string
|
||||
IPVersion string
|
||||
Status string
|
||||
|
||||
6
internal/models/persistence.go
Normal file
6
internal/models/persistence.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package models
|
||||
|
||||
type DomainHost struct {
|
||||
Domain string
|
||||
Host string
|
||||
}
|
||||
@@ -10,34 +10,29 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/chmike/domain"
|
||||
"github.com/qdm12/ddns-updater/internal/models"
|
||||
"github.com/qdm12/ddns-updater/internal/provider"
|
||||
"github.com/qdm12/ddns-updater/internal/provider/constants"
|
||||
"github.com/qdm12/ddns-updater/internal/provider/utils"
|
||||
"github.com/qdm12/ddns-updater/pkg/publicip/ipversion"
|
||||
"golang.org/x/net/publicsuffix"
|
||||
)
|
||||
|
||||
type commonSettings struct {
|
||||
Provider string `json:"provider"`
|
||||
Domain string `json:"domain"`
|
||||
// Host is kept for retro-compatibility and is replaced by Owner.
|
||||
Host string `json:"host,omitempty"`
|
||||
// Owner is kept for retro-compatibility and is determined from the
|
||||
// Domain field.
|
||||
Owner string `json:"owner,omitempty"`
|
||||
Provider string `json:"provider"`
|
||||
Domain string `json:"domain"`
|
||||
Host string `json:"host"`
|
||||
IPVersion string `json:"ip_version"`
|
||||
IPv6Suffix netip.Prefix `json:"ipv6_suffix"`
|
||||
IPv6Suffix netip.Prefix `json:"ipv6_suffix,omitempty"`
|
||||
// Retro values for warnings
|
||||
ProviderIP *bool `json:"provider_ip,omitempty"`
|
||||
IPMethod *string `json:"ip_method,omitempty"`
|
||||
Delay *uint64 `json:"delay,omitempty"`
|
||||
}
|
||||
|
||||
// JSONProviders obtain the update settings from the JSON content,
|
||||
// first trying from the environment variable CONFIG and then from
|
||||
// the file config.json.
|
||||
func (r *Reader) JSONProviders(filePath string) (
|
||||
providers []provider.Provider, warnings []string, err error,
|
||||
) {
|
||||
providers []provider.Provider, warnings []string, err error) {
|
||||
providers, warnings, err = r.getProvidersFromEnv(filePath)
|
||||
if providers != nil || warnings != nil || err != nil {
|
||||
return providers, warnings, err
|
||||
@@ -49,8 +44,7 @@ var errWriteConfigToFile = errors.New("cannot write configuration to file")
|
||||
|
||||
// getProvidersFromFile obtain the update settings from config.json.
|
||||
func (r *Reader) getProvidersFromFile(filePath string) (
|
||||
providers []provider.Provider, warnings []string, err error,
|
||||
) {
|
||||
providers []provider.Provider, warnings []string, err error) {
|
||||
r.logger.Info("reading JSON config from file " + filePath)
|
||||
bytes, err := r.readFile(filePath)
|
||||
if err != nil {
|
||||
@@ -60,8 +54,9 @@ func (r *Reader) getProvidersFromFile(filePath string) (
|
||||
|
||||
r.logger.Info("file not found, creating an empty settings file")
|
||||
|
||||
const filePerm = fs.FileMode(0o666)
|
||||
err = r.writeFile(filePath, []byte(`{}`), filePerm)
|
||||
const mode = fs.FileMode(0600)
|
||||
|
||||
err = r.writeFile(filePath, []byte(`{}`), mode)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("%w: %w", errWriteConfigToFile, err)
|
||||
}
|
||||
@@ -75,8 +70,7 @@ func (r *Reader) getProvidersFromFile(filePath string) (
|
||||
// getProvidersFromEnv obtain the update settings from the environment variable CONFIG.
|
||||
// If the settings are valid, they are written to the filePath.
|
||||
func (r *Reader) getProvidersFromEnv(filePath string) (
|
||||
providers []provider.Provider, warnings []string, err error,
|
||||
) {
|
||||
providers []provider.Provider, warnings []string, err error) {
|
||||
s := os.Getenv("CONFIG")
|
||||
if s == "" {
|
||||
return nil, nil, nil
|
||||
@@ -96,8 +90,8 @@ func (r *Reader) getProvidersFromEnv(filePath string) (
|
||||
if err != nil {
|
||||
return providers, warnings, fmt.Errorf("%w: %w", errWriteConfigToFile, err)
|
||||
}
|
||||
const filePerm = fs.FileMode(0o666)
|
||||
err = r.writeFile(filePath, buffer.Bytes(), filePerm)
|
||||
const mode = fs.FileMode(0600)
|
||||
err = r.writeFile(filePath, buffer.Bytes(), mode)
|
||||
if err != nil {
|
||||
return providers, warnings, fmt.Errorf("%w: %w", errWriteConfigToFile, err)
|
||||
}
|
||||
@@ -111,8 +105,7 @@ var (
|
||||
)
|
||||
|
||||
func extractAllSettings(jsonBytes []byte) (
|
||||
allProviders []provider.Provider, warnings []string, err error,
|
||||
) {
|
||||
allProviders []provider.Provider, warnings []string, err error) {
|
||||
config := struct {
|
||||
CommonSettings []commonSettings `json:"settings"`
|
||||
}{}
|
||||
@@ -148,44 +141,43 @@ func extractAllSettings(jsonBytes []byte) (
|
||||
|
||||
var (
|
||||
ErrProviderNoLongerSupported = errors.New("provider no longer supported")
|
||||
ErrProviderMultipleDomains = errors.New("provider does not support multiple domains")
|
||||
ErrDomainBlank = errors.New("domain cannot be blank for provider")
|
||||
)
|
||||
|
||||
func makeSettingsFromObject(common commonSettings, rawSettings json.RawMessage,
|
||||
retroGlobalIPv6Suffix netip.Prefix) (
|
||||
providers []provider.Provider, warnings []string, err error,
|
||||
) {
|
||||
providers []provider.Provider, warnings []string, err error) {
|
||||
if common.Provider == "google" {
|
||||
return nil, nil, fmt.Errorf("%w: %s", ErrProviderNoLongerSupported, common.Provider)
|
||||
}
|
||||
|
||||
if common.Owner == "" { // retro compatibility
|
||||
common.Owner = common.Host
|
||||
if common.Domain == "" && (common.Provider != "duckdns" && common.Provider != "goip") {
|
||||
return nil, nil, fmt.Errorf("%w: for provider %s", ErrDomainBlank, common.Provider)
|
||||
}
|
||||
|
||||
var domain string
|
||||
var owners []string
|
||||
if common.Owner != "" { // retro compatibility
|
||||
owners = strings.Split(common.Owner, ",")
|
||||
domain = common.Domain // single domain only
|
||||
domains := make([]string, len(owners))
|
||||
for i, owner := range owners {
|
||||
domains[i] = utils.BuildURLQueryHostname(owner, common.Domain)
|
||||
}
|
||||
warnings = append(warnings,
|
||||
fmt.Sprintf("you can specify the owner %q directly in the domain field as %q",
|
||||
common.Owner, strings.Join(domains, ",")))
|
||||
} else { // extract owner(s) from domain(s)
|
||||
domain, owners, err = extractFromDomainField(common.Domain)
|
||||
if common.Domain != "" {
|
||||
err = domain.Check(common.Domain)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("extracting owners from domains: %w", err)
|
||||
return nil, nil, fmt.Errorf("validating domain: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if common.Provider == string(constants.Myaddr) && len(owners) > 1 {
|
||||
return nil, nil, fmt.Errorf("%w: %s for parent domain %q",
|
||||
ErrProviderMultipleDomains, common.Provider, domain)
|
||||
providerName := models.Provider(common.Provider)
|
||||
if providerName == constants.DuckDNS { // only hosts, no domain
|
||||
if common.Domain != "" { // retro compatibility
|
||||
if common.Host == "" {
|
||||
common.Host = strings.TrimSuffix(common.Domain, ".duckdns.org")
|
||||
warnings = append(warnings,
|
||||
fmt.Sprintf("DuckDNS record should have %q specified as host instead of %q as domain",
|
||||
common.Host, common.Domain))
|
||||
} else {
|
||||
warnings = append(warnings,
|
||||
fmt.Sprintf("ignoring domain %q because host %q is specified for DuckDNS record",
|
||||
common.Domain, common.Host))
|
||||
}
|
||||
}
|
||||
}
|
||||
hosts := strings.Split(common.Host, ",")
|
||||
|
||||
if common.IPVersion == "" {
|
||||
common.IPVersion = ipversion.IP4or6.String()
|
||||
@@ -206,54 +198,14 @@ func makeSettingsFromObject(common commonSettings, rawSettings json.RawMessage,
|
||||
ipv6Suffix, ipVersion))
|
||||
}
|
||||
|
||||
if common.ProviderIP != nil {
|
||||
warning := fmt.Sprintf("for domain %s and ip version %s: "+
|
||||
`the field "provider_ip" is deprecated and no longer used`,
|
||||
domain, ipVersion)
|
||||
warnings = append(warnings, warning)
|
||||
}
|
||||
|
||||
providerName := models.Provider(common.Provider)
|
||||
if providerName == constants.Hetzner {
|
||||
warnings = append(warnings,
|
||||
"You should use the hetznercloud with the new Hetzner Cloud console instead, "+
|
||||
"given this legacy Hetzner API is going to be shutdown soon.")
|
||||
}
|
||||
providers = make([]provider.Provider, len(owners))
|
||||
for i, owner := range owners {
|
||||
owner = strings.TrimSpace(owner)
|
||||
providers[i], err = provider.New(providerName, rawSettings, domain,
|
||||
owner, ipVersion, ipv6Suffix)
|
||||
providers = make([]provider.Provider, len(hosts))
|
||||
for i, host := range hosts {
|
||||
host = strings.TrimSpace(host)
|
||||
providers[i], err = provider.New(providerName, rawSettings, common.Domain,
|
||||
host, ipVersion, ipv6Suffix)
|
||||
if err != nil {
|
||||
return nil, warnings, err
|
||||
}
|
||||
}
|
||||
return providers, warnings, nil
|
||||
}
|
||||
|
||||
var ErrMultipleDomainsSpecified = errors.New("multiple domains specified")
|
||||
|
||||
func extractFromDomainField(domainField string) (domainRegistered string,
|
||||
owners []string, err error,
|
||||
) {
|
||||
domains := strings.Split(domainField, ",")
|
||||
owners = make([]string, len(domains))
|
||||
for i, domain := range domains {
|
||||
newDomainRegistered, err := publicsuffix.EffectiveTLDPlusOne(domain)
|
||||
switch {
|
||||
case err != nil:
|
||||
return "", nil, fmt.Errorf("extracting effective TLD+1: %w", err)
|
||||
case domainRegistered == "":
|
||||
domainRegistered = newDomainRegistered
|
||||
case domainRegistered != newDomainRegistered:
|
||||
return "", nil, fmt.Errorf("%w: %q and %q",
|
||||
ErrMultipleDomainsSpecified, domainRegistered, newDomainRegistered)
|
||||
}
|
||||
if domain == domainRegistered {
|
||||
owners[i] = "@"
|
||||
continue
|
||||
}
|
||||
owners[i] = strings.TrimSuffix(domain, "."+domainRegistered)
|
||||
}
|
||||
return domainRegistered, owners, nil
|
||||
}
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
package params
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_extractFromDomainField(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCases := map[string]struct {
|
||||
domainField string
|
||||
domainRegistered string
|
||||
owners []string
|
||||
errWrapped error
|
||||
errMessage string
|
||||
}{
|
||||
"root_domain": {
|
||||
domainField: "example.com",
|
||||
domainRegistered: "example.com",
|
||||
owners: []string{"@"},
|
||||
},
|
||||
"subdomain": {
|
||||
domainField: "abc.example.com",
|
||||
domainRegistered: "example.com",
|
||||
owners: []string{"abc"},
|
||||
},
|
||||
"two_dots_tld": {
|
||||
domainField: "abc.example.co.uk",
|
||||
domainRegistered: "example.co.uk",
|
||||
owners: []string{"abc"},
|
||||
},
|
||||
"wildcard": {
|
||||
domainField: "*.example.com",
|
||||
domainRegistered: "example.com",
|
||||
owners: []string{"*"},
|
||||
},
|
||||
"multiple": {
|
||||
domainField: "*.example.com,example.com",
|
||||
domainRegistered: "example.com",
|
||||
owners: []string{"*", "@"},
|
||||
},
|
||||
"different_domains": {
|
||||
domainField: "*.example.com,abc.something.com",
|
||||
errWrapped: ErrMultipleDomainsSpecified,
|
||||
errMessage: "multiple domains specified: \"example.com\" and \"something.com\"",
|
||||
},
|
||||
"goip.de": {
|
||||
domainField: "my.domain.goip.de",
|
||||
domainRegistered: "domain.goip.de",
|
||||
owners: []string{"my"},
|
||||
},
|
||||
"duckdns.org": {
|
||||
domainField: "my.domain.duckdns.org",
|
||||
domainRegistered: "domain.duckdns.org",
|
||||
owners: []string{"my"},
|
||||
},
|
||||
}
|
||||
|
||||
for name, testCase := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
domainRegistered, owners, err := extractFromDomainField(testCase.domainField)
|
||||
|
||||
assert.ErrorIs(t, err, testCase.errWrapped)
|
||||
if testCase.errWrapped != nil {
|
||||
assert.EqualError(t, err, testCase.errMessage)
|
||||
}
|
||||
assert.Equal(t, testCase.domainRegistered, domainRegistered)
|
||||
assert.Equal(t, testCase.owners, owners)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,9 @@ func getRetroIPv6Suffix() (suffix netip.Prefix, err error) {
|
||||
return makeIPv6Suffix(prefixBitsString)
|
||||
}
|
||||
|
||||
var ErrIPv6PrefixFormat = errors.New("IPv6 prefix format is incorrect")
|
||||
var (
|
||||
ErrIPv6PrefixFormat = errors.New("IPv6 prefix format is incorrect")
|
||||
)
|
||||
|
||||
func makeIPv6Suffix(prefixBitsString string) (suffix netip.Prefix, err error) {
|
||||
prefixBitsString = strings.TrimPrefix(prefixBitsString, "/")
|
||||
|
||||
@@ -46,6 +46,7 @@ func Test_makeIPv6Suffix(t *testing.T) {
|
||||
}
|
||||
|
||||
for name, testCase := range testCases {
|
||||
testCase := testCase
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
@@ -15,12 +16,12 @@ import (
|
||||
type Database struct {
|
||||
data dataModel
|
||||
filepath string
|
||||
mutex sync.RWMutex
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
func (db *Database) Close() error {
|
||||
db.mutex.Lock() // ensure a write operation finishes
|
||||
defer db.mutex.Unlock()
|
||||
db.Lock() // ensure a write operation finishes
|
||||
defer db.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -33,8 +34,8 @@ func NewDatabase(dataDir string) (*Database, error) {
|
||||
if !errors.Is(err, os.ErrNotExist) {
|
||||
return nil, fmt.Errorf("reading file: %w", err)
|
||||
}
|
||||
const dirPerm = os.FileMode(0o777)
|
||||
err = os.MkdirAll(filepath.Dir(filePath), dirPerm)
|
||||
const perm fs.FileMode = 0700
|
||||
err = os.MkdirAll(filepath.Dir(filePath), perm)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("creating data directory: %w", err)
|
||||
}
|
||||
@@ -63,14 +64,6 @@ func NewDatabase(dataDir string) (*Database, error) {
|
||||
return nil, fmt.Errorf("closing database file: %w", err)
|
||||
}
|
||||
|
||||
// Migration from older database using "host" instead of "owner".
|
||||
for i := range data.Records {
|
||||
if data.Records[i].Owner == "" {
|
||||
data.Records[i].Owner = data.Records[i].Host
|
||||
data.Records[i].Host = ""
|
||||
}
|
||||
}
|
||||
|
||||
err = checkData(data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s validation error: %w", filePath, err)
|
||||
@@ -84,7 +77,7 @@ func NewDatabase(dataDir string) (*Database, error) {
|
||||
|
||||
var (
|
||||
ErrDomainEmpty = errors.New("domain is empty")
|
||||
ErrOwnerNotSet = errors.New("owner is not set")
|
||||
ErrHostIsEmpty = errors.New("host is empty")
|
||||
ErrIPRecordsMisordered = errors.New("IP records are not ordered correctly by time")
|
||||
ErrIPEmpty = errors.New("IP is empty")
|
||||
ErrIPTimeEmpty = errors.New("time of IP is empty")
|
||||
@@ -96,16 +89,16 @@ func checkData(data dataModel) (err error) {
|
||||
case record.Domain == "":
|
||||
return fmt.Errorf("%w: for record %d of %d", ErrDomainEmpty,
|
||||
i+1, len(data.Records))
|
||||
case record.Owner == "":
|
||||
case record.Host == "":
|
||||
return fmt.Errorf("%w: for record %d of %d with domain %s",
|
||||
ErrOwnerNotSet, i+1, len(data.Records), record.Domain)
|
||||
ErrHostIsEmpty, i+1, len(data.Records), record.Domain)
|
||||
}
|
||||
|
||||
err = checkHistoryEvents(record.Events)
|
||||
if err != nil {
|
||||
return fmt.Errorf("for record %d of %d with domain %s and owner %s: "+
|
||||
return fmt.Errorf("for record %d of %d with domain %s and host %s: "+
|
||||
"history events: %w", i+1, len(data.Records),
|
||||
record.Domain, record.Owner, err)
|
||||
record.Domain, record.Host, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -133,8 +126,8 @@ func checkHistoryEvents(events []models.HistoryEvent) (err error) {
|
||||
}
|
||||
|
||||
func (db *Database) write() error {
|
||||
const filePerm = os.FileMode(0o666)
|
||||
file, err := os.OpenFile(db.filepath, os.O_TRUNC|os.O_CREATE|os.O_WRONLY, filePerm)
|
||||
const createPerms fs.FileMode = 0600
|
||||
file, err := os.OpenFile(db.filepath, os.O_TRUNC|os.O_CREATE|os.O_WRONLY, createPerms)
|
||||
if err != nil {
|
||||
return fmt.Errorf("opening file: %w", err)
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user