Compare commits

...

57 commits

Author SHA1 Message Date
10f6aa8455
Release 1.1.9 Ammend
All checks were successful
Build and release binary file and packages / test (push) Successful in 21s
Run Tests on Code / run-tests (push) Successful in 23s
Build and release binary file and packages / build (push) Successful in 2m1s
Build and release binary file and packages / upload-generic-package (push) Successful in 1s
Build and release binary file and packages / upload-debian-package (push) Successful in 2s
Build and release binary file and packages / create-release (push) Successful in 9s
2024-09-30 11:41:20 +02:00
af6dcad5df
Release 1.1.9
All checks were successful
Run Tests on Code / run-tests (push) Successful in 23s
2024-09-30 11:40:07 +02:00
afb4dd8ff3
Include interface name when malformed IP is detected 2024-09-30 11:39:43 +02:00
3f41b8958e
Update Release Debian Ref Collecting
All checks were successful
Run Tests on Code / run-tests (push) Successful in 13s
2024-08-07 20:50:25 +02:00
7e7646a4eb Merge pull request 'Bump forgejo-release to v2' (#36) from actions-update into main
All checks were successful
Run Tests on Code / run-tests (push) Successful in 42s
Reviewed-on: https://forgejo.neshweb.net///Neshura/cloudflare-dns-updater/pulls/36
2024-08-06 12:23:21 +00:00
40f617a2d6 Bump forgejo-release to v2
All checks were successful
Build binary file and bundle packages / test (pull_request) Successful in 35s
Run Tests on Code / run-tests (push) Successful in 37s
Build binary file and bundle packages / build (pull_request) Successful in 49s
2024-08-06 12:20:15 +00:00
65519933be
Release 1.1.8
All checks were successful
Run Tests on Code / run-tests (push) Successful in 24s
Build and release binary file and packages / test (push) Successful in 7s
Build and release binary file and packages / build (push) Successful in 23s
Build and release binary file and packages / upload-generic-package (push) Successful in 1s
Build and release binary file and packages / upload-debian-package (push) Successful in 1s
Build and release binary file and packages / create-release (push) Successful in 7s
2024-06-10 12:46:00 +02:00
2c83671c8e Migrate away from Mullvad API
All checks were successful
Run Tests on Code / run-tests (push) Successful in 20s
2024-06-10 11:51:27 +02:00
3626237d90
Release 1.1.7
All checks were successful
Run Tests on Code / run-tests (push) Successful in 20s
Build and release binary file and packages / test (push) Successful in 22s
Build and release binary file and packages / build (push) Successful in 28s
Build and release binary file and packages / upload-generic-package (push) Successful in 1s
Build and release binary file and packages / upload-debian-package (push) Successful in 1s
Build and release binary file and packages / create-release (push) Successful in 7s
2024-03-04 16:44:11 +01:00
6a31ae0f9a
Elevated Mullvad Error Returns to Error Level from Warning
All checks were successful
Run Tests on Code / run-tests (push) Successful in 10s
2024-03-04 16:43:56 +01:00
04a1be9bcb
Improved Error Message Syntax 2024-03-04 16:43:06 +01:00
49b8d8cc05
Release 1.1.6
All checks were successful
Run Tests on Code / run-tests (push) Successful in 21s
Build and release binary file and packages / test (push) Successful in 20s
Build and release binary file and packages / build (push) Successful in 27s
Build and release binary file and packages / upload-generic-package (push) Successful in 1s
Build and release binary file and packages / upload-debian-package (push) Successful in 2s
Build and release binary file and packages / create-release (push) Successful in 7s
2024-03-04 16:35:06 +01:00
ffe1fbc7a4
DNS Update Log was logged with level 'WARN' instead of 'INFO'
All checks were successful
Run Tests on Code / run-tests (push) Successful in 10s
2024-03-04 16:34:40 +01:00
3c4e55d126
Release 1.1.5
All checks were successful
Run Tests on Code / run-tests (push) Successful in 27s
Build and release binary file and packages / test (push) Successful in 10s
Build and release binary file and packages / build (push) Successful in 27s
Build and release binary file and packages / upload-generic-package (push) Successful in 2s
Build and release binary file and packages / upload-debian-package (push) Successful in 1s
Build and release binary file and packages / create-release (push) Successful in 8s
2024-03-04 16:23:54 +01:00
8a1c52cd90
Bugfix: IP could be set to '::' or '0.0.0.0' 2024-03-04 16:23:54 +01:00
7b6bdc37c7 Correct zone.d naming in README to zones.d
All checks were successful
Run Tests on Code / run-tests (push) Successful in 27s
2024-01-19 08:55:50 +00:00
bff7057c45
Release 1.1.4
All checks were successful
Build and release binary file and packages / build (push) Successful in 28s
Build and release binary file and packages / upload-generic-package (push) Successful in 1s
Build and release binary file and packages / upload-debian-package (push) Successful in 1s
Run Tests on Code / run-tests (push) Successful in 22s
Build and release binary file and packages / test (push) Successful in 21s
Build and release binary file and packages / create-release (push) Successful in 7s
2024-01-08 09:47:31 +01:00
9dfd21ce8d Merge pull request 'Closes #34' (#35) from systemd-fix into main
All checks were successful
Run Tests on Code / run-tests (push) Successful in 8s
Reviewed-on: #35
2024-01-08 08:46:26 +00:00
dec6834920 Remove User Service file from cargo deb config
All checks were successful
Run Tests on Code / run-tests (push) Successful in 9s
Build binary file and bundle packages / test (pull_request) Successful in 8s
Build binary file and bundle packages / build (pull_request) Successful in 28s
2024-01-08 08:43:43 +00:00
9d5c3fcc23 Remove deprecated scripts for User Service File
All checks were successful
Run Tests on Code / run-tests (push) Successful in 9s
2024-01-08 08:43:14 +00:00
bbee00c9f9 Remove deprecated scripts for User Service File
Some checks failed
Run Tests on Code / run-tests (push) Has been cancelled
2024-01-08 08:43:08 +00:00
46bf5dc50d Remove deprecated scripts for User Service File
Some checks failed
Run Tests on Code / run-tests (push) Has been cancelled
2024-01-08 08:43:04 +00:00
ba34228cbd Remove User Service File
All checks were successful
Run Tests on Code / run-tests (push) Successful in 8s
2024-01-08 08:42:44 +00:00
74cb65a658 Add User Variable to Service File
All checks were successful
Run Tests on Code / run-tests (push) Successful in 21s
2024-01-08 08:42:17 +00:00
973741f7bb
Release 1.1.3
All checks were successful
Run Tests on Code / run-tests (push) Successful in 26s
Build and release binary file and packages / test (push) Successful in 23s
Build and release binary file and packages / build (push) Successful in 28s
Build and release binary file and packages / upload-generic-package (push) Successful in 2s
Build and release binary file and packages / upload-debian-package (push) Successful in 2s
Build and release binary file and packages / create-release (push) Successful in 9s
2023-12-29 14:28:22 +01:00
1e578d1a6b
Filter out build.env file for releases
All checks were successful
Run Tests on Code / run-tests (push) Successful in 15s
2023-12-29 14:28:04 +01:00
fda3c6bab6
Fix package name in generic package registry 2023-12-29 14:27:52 +01:00
7b7b55de0d
Split upload phase
All checks were successful
Run Tests on Code / run-tests (push) Successful in 9s
2023-12-29 03:43:59 +01:00
561bcbba26
1.1.2
All checks were successful
Run Tests on Code / run-tests (push) Successful in 13s
Build and release binary file and packages / test (push) Successful in 16s
Build and release binary file and packages / build (push) Successful in 24s
Build and release binary file and packages / upload-release (push) Successful in 9s
2023-12-29 03:38:55 +01:00
6d0c792f52
rc.3 v2
Some checks failed
Run Tests on Code / run-tests (push) Successful in 10s
Build and release binary file and packages / test (push) Successful in 10s
Build and release binary file and packages / build (push) Successful in 34s
Build and release binary file and packages / upload-release (push) Failing after 8s
2023-12-29 03:38:20 +01:00
3da5ac2a0c
Add missing () to tag rc check
All checks were successful
Run Tests on Code / run-tests (push) Successful in 12s
2023-12-29 03:37:26 +01:00
89192016fd
Release 1.1.2
All checks were successful
Run Tests on Code / run-tests (push) Successful in 25s
Build and release binary file and packages / test (push) Successful in 24s
Build and release binary file and packages / build (push) Successful in 26s
Build and release binary file and packages / upload-release (push) Successful in 10s
2023-12-29 03:36:07 +01:00
6a4a2b6445
Release Candidate 1.1.2-rc.3
All checks were successful
Run Tests on Code / run-tests (push) Successful in 24s
Build and release binary file and packages / test (push) Successful in 22s
Build and release binary file and packages / build (push) Successful in 30s
Build and release binary file and packages / upload-release (push) Successful in 23s
2023-12-29 03:35:37 +01:00
bccfc3d1f1
Always upload to staging, only upload to main on non-rc tags
All checks were successful
Run Tests on Code / run-tests (push) Successful in 11s
2023-12-29 03:35:18 +01:00
b6aade0ad3
Release Candidate 1.1.2-rc.2
All checks were successful
Run Tests on Code / run-tests (push) Successful in 12s
Build and release binary file and packages / test (push) Successful in 13s
Build and release binary file and packages / build (push) Successful in 26s
Build and release binary file and packages / upload-release (push) Successful in 10s
2023-12-29 03:31:17 +01:00
83a0b37c4e
Inline debian component switch instead of using if 2023-12-29 03:31:03 +01:00
61e45713e3
Fix Actions
All checks were successful
Run Tests on Code / run-tests (push) Successful in 11s
Build and release binary file and packages / test (push) Successful in 10s
Build and release binary file and packages / build (push) Successful in 25s
Build and release binary file and packages / upload-release (push) Successful in 10s
2023-12-29 03:26:50 +01:00
9ccd290ebc
Release Candidate 1.1.2-rc.1
Some checks failed
Run Tests on Code / run-tests (push) Successful in 11s
Build and release binary file and packages / upload-release (push) Blocked by required conditions
Build and release binary file and packages / test (push) Successful in 11s
Build and release binary file and packages / build (push) Has been cancelled
2023-12-29 03:19:37 +01:00
0c8414f0d0
Fix workflow if
All checks were successful
Run Tests on Code / run-tests (push) Successful in 11s
2023-12-29 03:18:40 +01:00
50c9677b82
Revert env changes
All checks were successful
Run Tests on Code / run-tests (push) Successful in 12s
Build and release binary file and packages / test (push) Successful in 10s
Build and release binary file and packages / build (push) Successful in 26s
Build and release binary file and packages / upload-release (push) Successful in 10s
2023-12-29 03:14:53 +01:00
f8f6737ae6
Add whitespace
Some checks failed
Run Tests on Code / run-tests (push) Successful in 11s
Build and release binary file and packages / test (push) Successful in 11s
Build and release binary file and packages / build (push) Failing after 24s
Build and release binary file and packages / upload-release (push) Has been skipped
2023-12-29 02:54:33 +01:00
9b47a6dbac
More syntax fix
All checks were successful
Run Tests on Code / run-tests (push) Successful in 12s
2023-12-29 02:54:02 +01:00
cbab7703ef
Syntax fix
All checks were successful
Run Tests on Code / run-tests (push) Successful in 11s
2023-12-29 02:52:44 +01:00
7b6cc44e17
Release Candidate 1.1.2-rc.2
All checks were successful
Run Tests on Code / run-tests (push) Successful in 19s
2023-12-29 02:50:19 +01:00
30cf1afba8
Switch variable referencing style + change if condition check
All checks were successful
Run Tests on Code / run-tests (push) Successful in 13s
2023-12-29 02:49:38 +01:00
c62dd2ff39
Fix pre-release check
All checks were successful
Run Tests on Code / run-tests (push) Successful in 11s
Build and release binary file and packages / test (push) Successful in 10s
Build and release binary file and packages / build (push) Successful in 27s
Build and release binary file and packages / upload-release (push) Successful in 12s
2023-12-29 02:36:29 +01:00
86dcdea7c6
Release Candidate 1.1.1-rc.1
All checks were successful
Run Tests on Code / run-tests (push) Successful in 21s
Build and release binary file and packages / test (push) Successful in 9s
Build and release binary file and packages / build (push) Successful in 28s
Build and release binary file and packages / upload-release (push) Successful in 10s
2023-12-29 02:31:01 +01:00
d28bbd45d7
Add staging debian component for pre-releases
All checks were successful
Run Tests on Code / run-tests (push) Successful in 13s
2023-12-29 02:30:30 +01:00
3fc17bcd4a
Specify config directory in Readme
All checks were successful
Run Tests on Code / run-tests (push) Successful in 11s
2023-12-29 02:21:12 +01:00
3dec954747
Update README
All checks were successful
Run Tests on Code / run-tests (push) Successful in 11s
2023-12-29 02:19:31 +01:00
45a7ab58d7
Add manual depends to cargo deb config. Should be complete
All checks were successful
Run Tests on Code / run-tests (push) Successful in 12s
2023-12-29 02:16:53 +01:00
ceddb5454d
Release 1.1.1
All checks were successful
Build and release binary file and packages / test (push) Successful in 23s
Run Tests on Code / run-tests (push) Successful in 27s
Build and release binary file and packages / build (push) Successful in 25s
Build and release binary file and packages / upload-release (push) Successful in 10s
2023-12-29 02:08:57 +01:00
812f93d2be Merge pull request 'Add Debian packaging to the App' (#32) from debian into main
All checks were successful
Run Tests on Code / run-tests (push) Successful in 10s
Reviewed-on: #32
2023-12-29 01:08:29 +00:00
b9419a5446
Different install target for user systemd service unit
All checks were successful
Run Tests on Code / run-tests (push) Successful in 13s
2023-12-29 02:08:07 +01:00
6936fa87d4 Merge pull request 'Run check on pull-requests' (#33) from pull_request_checking into main
All checks were successful
Run Tests on Code / run-tests (push) Successful in 11s
Reviewed-on: #33
2023-12-29 00:27:45 +00:00
db0df8f0f0
Remove Version checking from test step
Some checks failed
Run Tests on Code / run-tests (push) Successful in 11s
Build binary file and bundle packages / test (pull_request) Successful in 11s
Build binary file and bundle packages / build (pull_request) Failing after 28s
2023-12-29 01:20:32 +01:00
95268b5020
Run check on pull-requests
Some checks failed
Run Tests on Code / run-tests (push) Successful in 13s
Build binary file and bundle packages / test (pull_request) Failing after 13s
Build binary file and bundle packages / build (pull_request) Has been skipped
2023-12-29 01:13:19 +01:00
12 changed files with 172 additions and 126 deletions

View file

@ -1,4 +1,4 @@
name: 'Build and Release Binary File' name: 'Build and release binary file and packages'
author: 'Neshura' author: 'Neshura'
on: on:
@ -63,7 +63,7 @@ jobs:
name: Bundle .deb package name: Bundle .deb package
run: | run: |
cargo deb cargo deb
DEBIAN_REF=$(echo ${{ github.ref_name }} | tr - \~) DEBIAN_REF=$(cat Cargo.toml | grep -E "(^|\|)version =" | cut -f2- -d= | tr -d \" | tr -d " " | tr - \~)
echo "DEBIAN_REF=$DEBIAN_REF" >> dist/build.env echo "DEBIAN_REF=$DEBIAN_REF" >> dist/build.env
DEBIAN_REV=-$(cat Cargo.toml | grep -E "(^|\|)revision =" | cut -f2- -d= | tr -d \" | tr -d " ") DEBIAN_REV=-$(cat Cargo.toml | grep -E "(^|\|)revision =" | cut -f2- -d= | tr -d \" | tr -d " ")
echo "DEBIAN_REV=$DEBIAN_REV" >> dist/build.env echo "DEBIAN_REV=$DEBIAN_REV" >> dist/build.env
@ -76,7 +76,7 @@ jobs:
path: dist path: dist
if-no-files-found: error if-no-files-found: error
upload-release: upload-generic-package:
needs: build needs: build
if: success() if: success()
runs-on: docker runs-on: docker
@ -89,23 +89,55 @@ jobs:
run: | run: |
echo 'curl -v --user ${{ secrets.FORGEJO_USERNAME }}:${{ secrets.FORGEJO_TOKEN }} \ echo 'curl -v --user ${{ secrets.FORGEJO_USERNAME }}:${{ secrets.FORGEJO_TOKEN }} \
--upload-file release_blobs/${{ github.event.repository.name }}-linux-amd64 \ --upload-file release_blobs/${{ github.event.repository.name }}-linux-amd64 \
https://forgejo.neshweb.net/api/packages/${{ secrets.FORGEJO_USERNAME }}/generic/${{ github.event.repository.name }}/${{ github.ref_name }}/chellaris-rust-api-linux-amd64' https://forgejo.neshweb.net/api/packages/${{ secrets.FORGEJO_USERNAME }}/generic/${{ github.event.repository.name }}/${{ github.ref_name }}/${{ github.event.repository.name }}-linux-amd64'
curl -v --user ${{ secrets.FORGEJO_USERNAME }}:${{ secrets.FORGEJO_TOKEN }} \ curl -v --user ${{ secrets.FORGEJO_USERNAME }}:${{ secrets.FORGEJO_TOKEN }} \
--upload-file release_blobs/${{ github.event.repository.name }}-linux-amd64 \ --upload-file release_blobs/${{ github.event.repository.name }}-linux-amd64 \
https://forgejo.neshweb.net/api/packages/${{ secrets.FORGEJO_USERNAME }}/generic/${{ github.event.repository.name }}/${{ github.ref_name }}/chellaris-rust-api-linux-amd64 https://forgejo.neshweb.net/api/packages/${{ secrets.FORGEJO_USERNAME }}/generic/${{ github.event.repository.name }}/${{ github.ref_name }}/${{ github.event.repository.name }}-linux-amd64
upload-debian-package:
needs: build
if: success()
runs-on: docker
steps:
- -
name: Upload Debian Package name: Downloading All Build Artifacts
uses: actions/download-artifact@v3
-
name: Upload Debian Package to staging
run: | run: |
source release_blobs/build.env source release_blobs/build.env
echo 'curl -v --user ${{ secrets.FORGEJO_USERNAME }}:${{ secrets.FORGEJO_TOKEN }} \ echo 'curl -v --user ${{ secrets.FORGEJO_USERNAME }}:${{ secrets.FORGEJO_TOKEN }} \
--upload-file release_blobs/${{ github.event.repository.name }}_'"$DEBIAN_REF""$DEBIAN_REV"'_amd64.deb \
https://forgejo.neshweb.net/api/packages/${{ secrets.FORGEJO_USERNAME }}/debian/pool/bookworm/staging/upload'
curl -v --user ${{ secrets.FORGEJO_USERNAME }}:${{ secrets.FORGEJO_TOKEN }} \
--upload-file release_blobs/${{ github.event.repository.name }}_"$DEBIAN_REF""$DEBIAN_REV"_amd64.deb \ --upload-file release_blobs/${{ github.event.repository.name }}_"$DEBIAN_REF""$DEBIAN_REV"_amd64.deb \
https://forgejo.neshweb.net/api/packages/${{ secrets.FORGEJO_USERNAME }}/debian/pool/bookworm/staging/upload
-
name: Upload Debian Package to main
if: (! contains(github.ref_name, '-rc'))
run: |
source release_blobs/build.env
echo 'curl -v --user ${{ secrets.FORGEJO_USERNAME }}:${{ secrets.FORGEJO_TOKEN }} \
--upload-file release_blobs/${{ github.event.repository.name }}_'"$DEBIAN_REF""$DEBIAN_REV"'_amd64.deb \
https://forgejo.neshweb.net/api/packages/${{ secrets.FORGEJO_USERNAME }}/debian/pool/bookworm/main/upload' https://forgejo.neshweb.net/api/packages/${{ secrets.FORGEJO_USERNAME }}/debian/pool/bookworm/main/upload'
curl -v --user ${{ secrets.FORGEJO_USERNAME }}:${{ secrets.FORGEJO_TOKEN }} \ curl -v --user ${{ secrets.FORGEJO_USERNAME }}:${{ secrets.FORGEJO_TOKEN }} \
--upload-file release_blobs/${{ github.event.repository.name }}_"$DEBIAN_REF""$DEBIAN_REV"_amd64.deb \ --upload-file release_blobs/${{ github.event.repository.name }}_"$DEBIAN_REF""$DEBIAN_REV"_amd64.deb \
https://forgejo.neshweb.net/api/packages/${{ secrets.FORGEJO_USERNAME }}/debian/pool/bookworm/main/upload https://forgejo.neshweb.net/api/packages/${{ secrets.FORGEJO_USERNAME }}/debian/pool/bookworm/main/upload
create-release:
needs: build
if: success()
runs-on: docker
steps:
-
name: Downloading All Build Artifacts
uses: actions/download-artifact@v3
-
name: Filter out env files
run: rm release_blobs/build.env
- -
name: Release New Version name: Release New Version
uses: actions/forgejo-release@v1 uses: actions/forgejo-release@v2
with: with:
direction: upload direction: upload
url: https://forgejo.neshweb.net url: https://forgejo.neshweb.net

View file

@ -0,0 +1,67 @@
name: 'Build binary file and bundle packages'
author: 'Neshura'
on:
pull_request:
branches:
- main
jobs:
test:
runs-on: docker
container: forgejo.neshweb.net/ci-docker-images/rust-node:latest
steps:
-
name: Add Clippy
run: rustup component add clippy
-
name: Checking Out Repository Code
uses: https://code.forgejo.org/actions/checkout@v3
-
name: Set Up Cargo Cache
uses: actions/cache@v3
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
-
name: Run Clippy
run: cargo clippy
build:
needs: test
if: success()
runs-on: docker
container: forgejo.neshweb.net/ci-docker-images/rust-node:latest
steps:
-
name: Checking Out Repository Code
uses: https://code.forgejo.org/actions/checkout@v3
-
name: Prepare build environment
run: mkdir dist
-
name: Compiling To Linux Target
run: |
cargo build -r
mv target/release/${{ github.event.repository.name }} dist/${{ github.event.repository.name }}-linux-amd64
-
name: Bundle .deb package
run: |
cargo deb
DEBIAN_REF=$(cat Cargo.toml | grep -E "(^|\|)version =" | cut -f2- -d= | tr -d \" | tr -d " " | tr - \~)
echo "DEBIAN_REF=$DEBIAN_REF" >> dist/build.env
DEBIAN_REV=-$(cat Cargo.toml | grep -E "(^|\|)revision =" | cut -f2- -d= | tr -d \" | tr -d " ")
echo "DEBIAN_REV=$DEBIAN_REV" >> dist/build.env
mv target/debian/${{ github.event.repository.name }}_"$DEBIAN_REF""$DEBIAN_REV"_amd64.deb dist/${{ github.event.repository.name }}_"$DEBIAN_REF""$DEBIAN_REV"_amd64.deb
-
name: Uploading Build Artifact
uses: actions/upload-artifact@v3
with:
name: release_blobs
path: dist
if-no-files-found: error

2
Cargo.lock generated
View file

@ -114,7 +114,7 @@ dependencies = [
[[package]] [[package]]
name = "cloudflare-dns-updater" name = "cloudflare-dns-updater"
version = "1.1.1-rc.7" version = "1.1.9"
dependencies = [ dependencies = [
"chrono", "chrono",
"confy", "confy",

View file

@ -1,7 +1,7 @@
[package] [package]
authors = ["Neshura"] authors = ["Neshura"]
name = "cloudflare-dns-updater" name = "cloudflare-dns-updater"
version = "1.1.1-rc.7" version = "1.1.9"
edition = "2021" edition = "2021"
description = "Application for automatically updating Cloudflare DNS records" description = "Application for automatically updating Cloudflare DNS records"
license = "GPL-3.0-or-later" license = "GPL-3.0-or-later"
@ -10,17 +10,13 @@ license = "GPL-3.0-or-later"
extended-description = "Application for automatically updating Cloudflare DNS records" extended-description = "Application for automatically updating Cloudflare DNS records"
maintainer-scripts = "debian/" maintainer-scripts = "debian/"
revision = "1" revision = "1"
depends = ["libc6", "libssl3", "systemd"]
assets = [ assets = [
[ [
"target/release/cloudflare-dns-updater", "target/release/cloudflare-dns-updater",
"/usr/local/bin/cloudflare-dns-updater", "/usr/local/bin/cloudflare-dns-updater",
"755", "755",
], ]
[
"debian/cloudflare-dns-updater.service",
"/lib/systemd/user/cloudflare-dns-updater.service",
"755",
],
] ]
systemd-units = { enable = false } systemd-units = { enable = false }

View file

@ -7,10 +7,10 @@
The application necessarily requires a valid Cloudflare API Token. The application necessarily requires a valid Cloudflare API Token.
Further the application must be located in the same network as the configured zones. Further the application must be located in the same network as the configured zones.
The actual configuration happens in three or more files: The actual configuration happens in three or more files located in `~/.config/cloudflare-dns-updater/`:
`config.toml` contains general configuration parameters for the application `config.toml` contains general configuration parameters for the application
`interfaces.toml` contains all IPv6 interfaces available/used by the zone config files. `interfaces.toml` contains all IPv6 interfaces available/used by the zone config files.
`.toml` files in `zone.d` contain settings for individual zones. `.toml` files in `zones.d` contain settings for individual zones.
Example: Example:
@ -29,7 +29,7 @@ host_address = "::edcb:a098:7654:3210"
example-interface = "::0123:4567:890a:bcde" # static part of the IP, the rest will be dynamically generated using the host example-interface = "::0123:4567:890a:bcde" # static part of the IP, the rest will be dynamically generated using the host
``` ```
*zone.d/example.org.toml* *zones.d/example.org.toml*
```toml ```toml
email = "owner@example.org" # Email of User owning the Zone email = "owner@example.org" # Email of User owning the Zone
zone = "example.org" # Zone Name zone = "example.org" # Zone Name
@ -42,4 +42,10 @@ interface = "example-interface" # Only required on type values 6 and 10
``` ```
## Debian Repository ## Debian Repository
TODO!
Currently supported:
- Debian 12 'Bookworm'
Includes systemd system and user unit files
For more details see [the package registry](https://forgejo.neshweb.net/Neshura/-/packages/debian/cloudflare-dns-updater)

View file

@ -5,6 +5,7 @@ After=network-online.target
[Service] [Service]
Type=simple Type=simple
User=%i
ExecStart=/usr/local/bin/cloudflare-dns-updater ExecStart=/usr/local/bin/cloudflare-dns-updater
Restart=always Restart=always
RestartSec=3 RestartSec=3

36
debian/postinst vendored
View file

@ -1,36 +0,0 @@
#!/bin/sh
#DEBHELPER#
# Also enable User Service
# Automatically added by cargo-deb
if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-deconfigure" ] || [ "$1" = "abort-remove" ] ; then
if deb-systemd-helper --user debian-installed cloudflare-dns-updater.service; then
# This will only remove masks created by d-s-h on package removal.
deb-systemd-helper --user unmask cloudflare-dns-updater.service >/dev/null || true
if deb-systemd-helper --user --quiet was-enabled cloudflare-dns-updater.service; then
# Create new symlinks, if any.
deb-systemd-helper --user enable cloudflare-dns-updater.service >/dev/null || true
fi
fi
# Update the statefile to add new symlinks (if any), which need to be cleaned
# up on purge. Also remove old symlinks.
deb-systemd-helper --user update-state cloudflare-dns-updater.service >/dev/null || true
fi
# End automatically added section
# Automatically added by cargo-deb
if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-deconfigure" ] || [ "$1" = "abort-remove" ] ; then
if [ -d /run/systemd/system ]; then
USER="$(who | head -1 | awk '{print $1;}')"
runuser -l $USER -c "XDG_RUNTIME_DIR=/run/user/$(id -u $USER) systemctl --user daemon-reload >/dev/null || true"
if [ -n "$2" ]; then
_dh_action=restart
else
_dh_action=start
fi
runuser -l $USER -c "XDG_RUNTIME_DIR=/run/user/$(id -u $USER) deb-systemd-invoke --user $_dh_action cloudflare-dns-updater.service >/dev/null || true"
fi
fi
# End automatically added section

27
debian/postrm vendored
View file

@ -1,27 +0,0 @@
#!/bin/sh
#DEBHELPER#
# Also enable User Service
# Automatically added by cargo-deb
if [ -d /run/systemd/system ]; then
USER="$(who | head -1 | awk '{print $1;}')"
runuser -l $USER -c "XDG_RUNTIME_DIR=/run/user/$(id -u $USER) systemctl --user daemon-reload >/dev/null || true"
fi
# End automatically added section
# Automatically added by cargo-deb
if [ "$1" = "remove" ]; then
if [ -x "/usr/bin/deb-systemd-helper" ]; then
USER="$(who | head -1 | awk '{print $1;}')"
runuser -l $USER -c "XDG_RUNTIME_DIR=/run/user/$(id -u $USER) deb-systemd-helper --user mask cloudflare-dns-updater.service >/dev/null || true"
fi
fi
if [ "$1" = "purge" ]; then
if [ -x "/usr/bin/deb-systemd-helper" ]; then
USER="$(who | head -1 | awk '{print $1;}')"
runuser -l $USER -c "XDG_RUNTIME_DIR=/run/user/$(id -u $USER) deb-systemd-helper --user purge cloudflare-dns-updater.service >/dev/null || true"
runuser -l $USER -c "XDG_RUNTIME_DIR=/run/user/$(id -u $USER) deb-systemd-helper --user unmask cloudflare-dns-updater.service >/dev/null || true"
fi
fi
# End automatically added section

11
debian/prerm vendored
View file

@ -1,11 +0,0 @@
#!/bin/sh
#DEBHELPER#
# Also enable User Service
# Automatically added by cargo-deb
if [ -d /run/systemd/system ] && [ "$1" = remove ]; then
USER="$(who | head -1 | awk '{print $1;}')"
runuser -l $USER -c "XDG_RUNTIME_DIR=/run/user/$(id -u $USER) deb-systemd-invoke --user stop cloudflare-dns-updater.service >/dev/null || true"
fi
# End automatically added section

View file

@ -64,7 +64,7 @@ impl CloudflareZone {
let entries = match response.json::<CloudflareApiResults>() { let entries = match response.json::<CloudflareApiResults>() {
Ok(data) => data, Ok(data) => data,
Err(e) => { Err(e) => {
let err_msg = format!("Unable to parse API response. Error: {e}"); let err_msg = format!("Unable to parse API response: {e}");
match connected_to_journal() { match connected_to_journal() {
true => error!("[ERROR] {err_msg}"), true => error!("[ERROR] {err_msg}"),
false => eprintln!("[ERROR] {err_msg}"), false => eprintln!("[ERROR] {err_msg}"),
@ -75,7 +75,7 @@ impl CloudflareZone {
Ok(entries.result) Ok(entries.result)
} else { } else {
let err_msg = format!("Unable to fetch Cloudflare Zone Entries for {}. Error: {}",self.name ,response.status()); let err_msg = format!("Unable to fetch Cloudflare Zone Entries for {}: {}",self.name ,response.status());
match connected_to_journal() { match connected_to_journal() {
true => error!("[ERROR] {err_msg}"), true => error!("[ERROR] {err_msg}"),
false => eprintln!("[ERROR] {err_msg}"), false => eprintln!("[ERROR] {err_msg}"),
@ -84,7 +84,7 @@ impl CloudflareZone {
} }
} }
Err(e) => { Err(e) => {
let err_msg = format!("Unable to access Cloudflare API. Error: {e}"); let err_msg = format!("Unable to access Cloudflare API: {e}");
match connected_to_journal() { match connected_to_journal() {
true => error!("[ERROR] {err_msg}"), true => error!("[ERROR] {err_msg}"),
false => eprintln!("[ERROR] {err_msg}"), false => eprintln!("[ERROR] {err_msg}"),
@ -107,7 +107,7 @@ impl CloudflareZone {
self.validate_response(response) self.validate_response(response)
}, },
Err(e) => { Err(e) => {
let err_msg = format!("Unable to access Cloudflare API. Error: {e}"); let err_msg = format!("Unable to access Cloudflare API: {e}");
match connected_to_journal() { match connected_to_journal() {
true => error!("[ERROR] {err_msg}"), true => error!("[ERROR] {err_msg}"),
false => eprintln!("[ERROR] {err_msg}"), false => eprintln!("[ERROR] {err_msg}"),
@ -133,7 +133,7 @@ impl CloudflareZone {
self.validate_response(response) self.validate_response(response)
}, },
Err(e) => { Err(e) => {
let err_msg = format!("Unable to access Cloudflare API. Error: {e}"); let err_msg = format!("Unable to access Cloudflare API: {e}");
match connected_to_journal() { match connected_to_journal() {
true => error!("[ERROR] {err_msg}"), true => error!("[ERROR] {err_msg}"),
false => eprintln!("[ERROR] {err_msg}"), false => eprintln!("[ERROR] {err_msg}"),
@ -174,7 +174,7 @@ impl CloudflareZone {
self.validate_response(response) self.validate_response(response)
}, },
Err(e) => { Err(e) => {
let err_msg = format!("Unable to access Cloudflare API. Error: {e}"); let err_msg = format!("Unable to access Cloudflare API: {e}");
match connected_to_journal() { match connected_to_journal() {
true => error!("[ERROR] {err_msg}"), true => error!("[ERROR] {err_msg}"),
false => eprintln!("[ERROR] {err_msg}"), false => eprintln!("[ERROR] {err_msg}"),
@ -200,7 +200,7 @@ impl CloudflareZone {
self.validate_response(response) self.validate_response(response)
}, },
Err(e) => { Err(e) => {
let err_msg = format!("Unable to access Cloudflare API. Error: {e}"); let err_msg = format!("Unable to access Cloudflare API: {e}");
match connected_to_journal() { match connected_to_journal() {
true => error!("[ERROR] {err_msg}"), true => error!("[ERROR] {err_msg}"),
false => eprintln!("[ERROR] {err_msg}"), false => eprintln!("[ERROR] {err_msg}"),
@ -270,7 +270,7 @@ impl CloudflareZone {
match Url::parse(input) { match Url::parse(input) {
Ok(url) => Ok(url), Ok(url) => Ok(url),
Err(e) => { Err(e) => {
let err_msg = format!("Unable to parse URL. Error: {}", e); let err_msg = format!("Unable to parse URL: {}", e);
match connected_to_journal() { match connected_to_journal() {
true => error!("[ERROR] {err_msg}"), true => error!("[ERROR] {err_msg}"),
false => eprintln!("[ERROR] {err_msg}"), false => eprintln!("[ERROR] {err_msg}"),
@ -293,7 +293,7 @@ impl CloudflareZone {
let data = match response.json::<CloudflareApiResult>() { let data = match response.json::<CloudflareApiResult>() {
Ok(data) => data, Ok(data) => data,
Err(e) => { Err(e) => {
let err_msg = format!("Unable to parse API response. Error: {e}"); let err_msg = format!("Unable to parse API response: {e}");
match connected_to_journal() { match connected_to_journal() {
true => error!("[ERROR] {err_msg}"), true => error!("[ERROR] {err_msg}"),
false => eprintln!("[ERROR] {err_msg}"), false => eprintln!("[ERROR] {err_msg}"),
@ -305,7 +305,7 @@ impl CloudflareZone {
match data.success { match data.success {
true => Ok(()), true => Ok(()),
false => { false => {
let err_msg = format!("Unexpected error while updating DNS record. Info: {:?}", data); let err_msg = format!("Unexpected error while updating DNS record: {:?}", data);
match connected_to_journal() { match connected_to_journal() {
true => error!("[ERROR] {err_msg}"), true => error!("[ERROR] {err_msg}"),
false => eprintln!("[ERROR] {err_msg}"), false => eprintln!("[ERROR] {err_msg}"),
@ -314,7 +314,7 @@ impl CloudflareZone {
} }
} }
} else { } else {
let err_msg = format!("Unable to post/put Cloudflare DNS entry. Error: {}", response.status()); let err_msg = format!("Unable to post/put Cloudflare DNS entry: {}", response.status());
match connected_to_journal() { match connected_to_journal() {
true => error!("[ERROR] {err_msg}"), true => error!("[ERROR] {err_msg}"),
false => eprintln!("[ERROR] {err_msg}"), false => eprintln!("[ERROR] {err_msg}"),

View file

@ -37,7 +37,7 @@ impl InterfaceConfig {
let interface_address = match self.interfaces.get(interface_name) { let interface_address = match self.interfaces.get(interface_name) {
Some(address) => *address, Some(address) => *address,
None => { None => {
let err_msg = "Malformed IP in interfaces.toml"; let err_msg = format!("Malformed or missing IP in interfaces.toml for interface {}", interface_name);
match connected_to_journal() { match connected_to_journal() {
true => error!("[ERROR] {err_msg}"), true => error!("[ERROR] {err_msg}"),
false => eprintln!("[ERROR] {err_msg}"), false => eprintln!("[ERROR] {err_msg}"),

View file

@ -24,8 +24,8 @@ struct Addresses {
impl Addresses { impl Addresses {
fn new() -> Result<Self, Box<dyn Error>> { fn new() -> Result<Self, Box<dyn Error>> {
let mut ret = Self { let mut ret = Self {
ipv4_uri: "https://am.i.mullvad.net/ip".to_owned(), ipv4_uri: "http://ip4only.me/api/".to_owned(),
ipv6_uri: "https://ipv6.am.i.mullvad.net/ip".to_owned(), ipv6_uri: "http://ip6only.me/api/".to_owned(),
ipv4: Ipv4Addr::new(0, 0, 0, 0), ipv4: Ipv4Addr::new(0, 0, 0, 0),
ipv6: Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0) ipv6: Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)
}; };
@ -61,19 +61,28 @@ impl Addresses {
match self.get_v4() { match self.get_v4() {
Ok(ip) => { Ok(ip) => {
if ip != self.ipv4 { if ip != self.ipv4 {
let info_msg = format!("IPv4 changed from '{}' to '{}'", self.ipv4, ip); if ip == Ipv4Addr::new(0,0,0,0) {
match connected_to_journal() { let warn_msg = "'0.0.0.0' detected as new IPv4, skipping changes".to_owned();
true => info!("[INFO] {info_msg}"), match connected_to_journal() {
false => println!("[INFO] {info_msg}"), true => warn!("[WARN] {warn_msg}"),
false => println!("[WARN] {warn_msg}"),
}
}
else {
let info_msg = format!("IPv4 changed from '{}' to '{}'", self.ipv4, ip);
match connected_to_journal() {
true => info!("[INFO] {info_msg}"),
false => println!("[INFO] {info_msg}"),
}
self.ipv4 = ip;
} }
self.ipv4 = ip;
} }
} }
Err(e) => { Err(e) => {
let warn_msg = format!("Unable to fetch IPv4 from '{}'. Error: {}", self.ipv4_uri, e); let error_msg = format!("Unable to fetch IPv4 from '{}': {}", self.ipv4_uri, e);
match connected_to_journal() { match connected_to_journal() {
true => warn!("[WARN] {warn_msg}"), true => error!("[ERROR] {error_msg}"),
false => println!("[WARN] {warn_msg}"), false => eprintln!("[ERROR] {error_msg}"),
} }
} }
} }
@ -81,19 +90,28 @@ impl Addresses {
match self.get_v6() { match self.get_v6() {
Ok(ip) => { Ok(ip) => {
if ip != self.ipv6 { if ip != self.ipv6 {
let info_msg = format!("IPv6 changed from '{}' to '{}'", self.ipv6, ip); if ip == Ipv6Addr::new(0,0,0,0,0,0,0,0) {
match connected_to_journal() { let warn_msg = "'::' detected as new IPv6, skipping changes".to_owned();
true => info!("[INFO] {info_msg}"), match connected_to_journal() {
false => println!("[INFO] {info_msg}"), true => warn!("[WARN] {warn_msg}"),
false => println!("[WARN] {warn_msg}"),
}
}
else {
let info_msg = format!("IPv6 changed from '{}' to '{}'", self.ipv6, ip);
match connected_to_journal() {
true => info!("[INFO] {info_msg}"),
false => println!("[INFO] {info_msg}"),
}
self.ipv6 = ip;
} }
self.ipv6 = ip;
} }
} }
Err(e) => { Err(e) => {
let warn_msg = format!("Unable to fetch IPv6 from '{}'. Error: {}", self.ipv6_uri, e); let error_msg = format!("Unable to fetch IPv6 from '{}': {}", self.ipv6_uri, e);
match connected_to_journal() { match connected_to_journal() {
true => warn!("[WARN] {warn_msg}"), true => error!("[ERROR] {error_msg}"),
false => println!("[WARN] {warn_msg}"), false => eprintln!("[ERROR] {error_msg}"),
} }
} }
} }
@ -104,7 +122,7 @@ impl Addresses {
Ok(res) => { Ok(res) => {
match res.status() { match res.status() {
StatusCode::OK => { StatusCode::OK => {
let ip_string = res.text().expect("Returned data should always contain text").trim_end().to_owned(); let ip_string = res.text().expect("Returned data should always contain text").trim_end().split(',').collect::<Vec<&str>>()[1].to_owned();
Ok(Ipv4Addr::from_str(ip_string.as_str()).expect("Returned IP should always be parseable")) Ok(Ipv4Addr::from_str(ip_string.as_str()).expect("Returned IP should always be parseable"))
}, },
_ => { _ => {
@ -127,7 +145,7 @@ impl Addresses {
Ok(res) => { Ok(res) => {
match res.status() { match res.status() {
StatusCode::OK => { StatusCode::OK => {
let ip_string = res.text().expect("Returned data should always contain text").trim_end().to_owned(); let ip_string: String = res.text().expect("Returned data should always contain text").trim_end().split(',').collect::<Vec<&str>>()[1].to_owned();
Ok(Ipv6Addr::from_str(ip_string.as_str()).expect("Returned IP should always be parseable")) Ok(Ipv6Addr::from_str(ip_string.as_str()).expect("Returned IP should always be parseable"))
}, },
_ => { _ => {
@ -638,7 +656,7 @@ fn main() {
if cf_zone.update(entry, r#type, &cf_entry.id, ipv6, ipv4).is_ok() { if cf_zone.update(entry, r#type, &cf_entry.id, ipv6, ipv4).is_ok() {
let info_msg = format!("Updated {} DNS Record for entry '{}' in zone '{}'", r#type, entry.name, zone.name); let info_msg = format!("Updated {} DNS Record for entry '{}' in zone '{}'", r#type, entry.name, zone.name);
match connected_to_journal() { match connected_to_journal() {
true => warn!("[INFO] {info_msg}"), true => info!("[INFO] {info_msg}"),
false => println!("[INFO] {info_msg}"), false => println!("[INFO] {info_msg}"),
} }
} }