Compare commits

...

177 commits
v0.2.0 ... main

Author SHA1 Message Date
0f4ff679d2
chore(deps): lock file maintenance
All checks were successful
/ check-renovaterc (push) Successful in 4s
/ build (push) Successful in 1s
/ test (push) Successful in 12s
/ report-size (push) Successful in 2s
2025-04-03 22:10:16 +02:00
e28cf9be3f
chore(deps): lock file maintenance
All checks were successful
/ check-renovaterc (push) Successful in 3s
/ build (push) Successful in 1s
/ test (push) Successful in 12s
/ report-size (push) Successful in 2s
2025-04-03 22:00:34 +02:00
1dac706aeb
chore(deps): lock file maintenance
All checks were successful
/ check-renovaterc (push) Successful in 3s
/ build (push) Successful in 1s
/ test (push) Successful in 12s
/ report-size (push) Successful in 2s
2025-04-02 22:00:44 +02:00
29916c0841 fix(deps): update rust crate axum-client-ip to v1
All checks were successful
/ check-renovaterc (push) Successful in 3s
/ build (push) Successful in 0s
/ test (push) Successful in 12s
/ report-size (push) Successful in 2s
| datasource | package        | from  | to    |
| ---------- | -------------- | ----- | ----- |
| crate      | axum-client-ip | 0.7.0 | 1.0.0 |
2025-04-02 19:43:49 +02:00
3c9587bd4c
chore(deps): lock file maintenance
All checks were successful
/ check-renovaterc (push) Successful in 3s
/ build (push) Successful in 1s
/ test (push) Successful in 12s
/ report-size (push) Successful in 2s
2025-04-01 22:00:24 +02:00
7dcd2c6a4c
fix(deps): update rust crate clap to v4.5.35
All checks were successful
/ check-renovaterc (push) Successful in 3s
/ build (push) Successful in 1s
/ test (push) Successful in 12s
/ report-size (push) Successful in 3s
| datasource | package | from   | to     |
| ---------- | ------- | ------ | ------ |
| crate      | clap    | 4.5.34 | 4.5.35 |
2025-04-01 19:20:25 +02:00
5a98e8205f
chore(deps): lock file maintenance
All checks were successful
/ check-renovaterc (push) Successful in 4s
/ build (push) Successful in 1s
/ test (push) Successful in 12s
/ report-size (push) Successful in 2s
2025-03-31 22:00:32 +02:00
2183c81d70
chore(deps): lock file maintenance
All checks were successful
/ check-renovaterc (push) Successful in 3s
/ build (push) Successful in 1s
/ test (push) Successful in 12s
/ report-size (push) Successful in 1s
2025-03-30 22:00:20 +02:00
4ab2f709a9
chore(deps): lock file maintenance
All checks were successful
/ check-renovaterc (push) Successful in 4s
/ build (push) Successful in 1s
/ test (push) Successful in 12s
/ report-size (push) Successful in 2s
2025-03-29 22:00:33 +01:00
269a37c920
chore(deps): lock file maintenance
All checks were successful
/ check-renovaterc (push) Successful in 4s
/ build (push) Successful in 1s
/ test (push) Successful in 12s
/ report-size (push) Successful in 2s
2025-03-28 22:00:17 +01:00
6ac1133486
fix(deps): update rust crate axum to v0.8.3
All checks were successful
/ check-renovaterc (push) Successful in 3s
/ build (push) Successful in 0s
/ test (push) Successful in 12s
/ report-size (push) Successful in 2s
| datasource | package | from  | to    |
| ---------- | ------- | ----- | ----- |
| crate      | axum    | 0.8.1 | 0.8.3 |
2025-03-28 21:50:30 +01:00
c5c51645ba
chore(deps): lock file maintenance
All checks were successful
/ check-renovaterc (push) Successful in 3s
/ build (push) Successful in 1s
/ test (push) Successful in 12s
/ report-size (push) Successful in 2s
2025-03-27 22:00:14 +01:00
fe58c295ff
fix(deps): update rust crate clap to v4.5.34
All checks were successful
/ check-renovaterc (push) Successful in 3s
/ build (push) Successful in 1s
/ test (push) Successful in 13s
/ report-size (push) Successful in 2s
| datasource | package | from   | to     |
| ---------- | ------- | ------ | ------ |
| crate      | clap    | 4.5.33 | 4.5.34 |
2025-03-27 03:10:24 +01:00
f356463079
chore(deps): lock file maintenance
All checks were successful
/ check-renovaterc (push) Successful in 4s
/ build (push) Successful in 1s
/ test (push) Successful in 12s
/ report-size (push) Successful in 2s
2025-03-26 22:00:30 +01:00
caa7c1165f
fix(deps): update rust crate clap to v4.5.33
All checks were successful
/ check-renovaterc (push) Successful in 3s
/ build (push) Successful in 0s
/ test (push) Successful in 12s
/ report-size (push) Successful in 2s
| datasource | package | from   | to     |
| ---------- | ------- | ------ | ------ |
| crate      | clap    | 4.5.32 | 4.5.33 |
2025-03-26 20:20:14 +01:00
7dca0efdf2
chore(deps): lock file maintenance
All checks were successful
/ check-renovaterc (push) Successful in 4s
/ build (push) Successful in 1s
/ test (push) Successful in 12s
/ report-size (push) Successful in 2s
2025-03-24 22:00:31 +01:00
5f2ec1089f
chore(deps): lock file maintenance
All checks were successful
/ check-renovaterc (push) Successful in 3s
/ build (push) Successful in 1s
/ test (push) Successful in 12s
/ report-size (push) Successful in 2s
2025-03-23 22:00:37 +01:00
ba2babb0ae
chore(deps): lock file maintenance
All checks were successful
/ check-renovaterc (push) Successful in 2s
/ build (push) Successful in 2s
/ test (push) Successful in 11s
/ report-size (push) Successful in 7s
2025-03-21 22:00:34 +01:00
f9da4aecd4
chore(deps): lock file maintenance
All checks were successful
/ check-renovaterc (push) Successful in 3s
/ build (push) Successful in 2s
/ test (push) Successful in 11s
/ report-size (push) Successful in 7s
2025-03-20 22:00:15 +01:00
2d00dd3818
chore(deps): pin rust crate insta to =1.42.2
All checks were successful
/ check-renovaterc (push) Successful in 3s
/ build (push) Successful in 2s
/ test (push) Successful in 11s
/ report-size (push) Successful in 6s
| datasource | package | from   | to     |
| ---------- | ------- | ------ | ------ |
| crate      | insta   | 1.42.2 | 1.42.2 |
2025-03-19 23:20:34 +01:00
2daf620a4a
chore: pin nix-flake-outputs-size
All checks were successful
/ check-renovaterc (push) Successful in 2s
/ build (push) Successful in 1s
/ test (push) Successful in 12s
/ report-size (push) Successful in 2s
Renovate seems to be erroring out when trying to do it.
2025-03-19 23:10:10 +01:00
316f2bf576
feat: add config file to webnsupdate
All checks were successful
/ check-renovaterc (push) Successful in 2s
/ build (push) Successful in 1s
/ test (push) Successful in 12s
/ report-size (push) Successful in 2s
Move flags to config file, and add more options. Mirror some in the
module.
2025-03-19 23:05:38 +01:00
3d660314cf
chore(deps): lock file maintenance
All checks were successful
/ check-renovaterc (push) Successful in 3s
/ build (push) Successful in 2s
/ test (push) Successful in 12s
/ report-size (push) Successful in 7s
2025-03-19 22:00:49 +01:00
f207cbe859
chore(deps): lock file maintenance
All checks were successful
/ check-renovaterc (push) Successful in 2s
/ build (push) Successful in 2s
/ test (push) Successful in 12s
/ report-size (push) Successful in 7s
2025-03-18 22:00:32 +01:00
c589fb40c3
chore(deps): lock file maintenance
All checks were successful
/ check-renovaterc (push) Successful in 3s
/ build (push) Successful in 2s
/ test (push) Successful in 12s
/ report-size (push) Successful in 6s
2025-03-16 22:00:43 +01:00
08ea3271c1
ci: use nix-fast-build to speedup checks
All checks were successful
/ check-renovaterc (push) Successful in 3s
/ build (push) Successful in 1s
/ test (push) Successful in 11s
/ report-size (push) Successful in 2s
Should be a noticeable improvement c:
2025-03-16 19:27:05 +01:00
8787adae30
chore(deps): lock file maintenance
All checks were successful
/ check-renovaterc (push) Successful in 2s
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 6s
/ check (module-nginx-test) (push) Successful in 6s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 2s
2025-03-14 22:00:31 +01:00
130c949723
chore(deps): lock file maintenance
All checks were successful
/ check-renovaterc (push) Successful in 3s
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 6s
/ check (module-nginx-test) (push) Successful in 6s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 2s
2025-03-13 22:00:46 +01:00
e236aa424b
fix(deps): update rust crate tokio to v1.44.1
All checks were successful
/ check-renovaterc (push) Successful in 2s
/ build (push) Successful in 0s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 6s
/ check (module-ipv4-test) (push) Successful in 6s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 2s
| datasource | package | from   | to     |
| ---------- | ------- | ------ | ------ |
| crate      | tokio   | 1.44.0 | 1.44.1 |
2025-03-13 09:40:24 +01:00
baeb98a2e6
chore(deps): lock file maintenance
All checks were successful
/ check-renovaterc (push) Successful in 3s
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 3s
/ report-size (push) Successful in 2s
2025-03-12 01:00:32 +01:00
9b41d7d2a5
fix(deps): update rust crate http to v1.3.1
All checks were successful
/ check-renovaterc (push) Successful in 2s
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 6s
/ check (module-ipv6-only-test) (push) Successful in 6s
/ check (module-ipv6-test) (push) Successful in 6s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 2s
| datasource | package | from  | to    |
| ---------- | ------- | ----- | ----- |
| crate      | http    | 1.3.0 | 1.3.1 |
2025-03-11 21:50:30 +01:00
33f8b1570d
fix(deps): update rust crate ring to v0.17.14
All checks were successful
/ check-renovaterc (push) Successful in 3s
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 6s
/ check (module-nginx-test) (push) Successful in 6s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 2s
| datasource | package | from    | to      |
| ---------- | ------- | ------- | ------- |
| crate      | ring    | 0.17.13 | 0.17.14 |
2025-03-11 21:20:24 +01:00
06995416d2
fix(deps): update rust crate http to v1.3.0
All checks were successful
/ check-renovaterc (push) Successful in 3s
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 6s
/ check (module-ipv6-only-test) (push) Successful in 6s
/ check (module-ipv6-test) (push) Successful in 6s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 2s
| datasource | package | from  | to    |
| ---------- | ------- | ----- | ----- |
| crate      | http    | 1.2.0 | 1.3.0 |
2025-03-11 18:00:26 +01:00
f8848e669e
chore(deps): lock file maintenance
All checks were successful
/ check-renovaterc (push) Successful in 3s
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 3s
/ check (module-ipv4-only-test) (push) Successful in 6s
/ check (module-ipv4-test) (push) Successful in 6s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 1s
2025-03-10 22:00:53 +01:00
72843b8f52
fix(deps): update rust crate clap to v4.5.32
All checks were successful
/ check-renovaterc (push) Successful in 3s
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 6s
/ check (module-ipv6-only-test) (push) Successful in 6s
/ check (module-ipv6-test) (push) Successful in 6s
/ check (module-nginx-test) (push) Successful in 6s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 2s
| datasource | package | from   | to     |
| ---------- | ------- | ------ | ------ |
| crate      | clap    | 4.5.31 | 4.5.32 |
2025-03-10 21:50:28 +01:00
4cdffc20bc chore(config): migrate config .renovaterc.json
All checks were successful
/ check-renovaterc (push) Successful in 3s
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 8s
/ check (module-nginx-test) (push) Successful in 10s
/ check (nextest) (push) Successful in 4s
/ check (treefmt) (push) Successful in 3s
/ report-size (push) Successful in 2s
2025-03-10 08:09:25 +01:00
cf66c77136
chore(deps): lock file maintenance
All checks were successful
/ check-renovaterc (push) Successful in 2s
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 6s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 3s
/ report-size (push) Successful in 2s
2025-03-09 22:00:32 +01:00
5fc53886f2
chore(deps): pin dependencies
All checks were successful
/ check-renovaterc (push) Successful in 2s
/ build (push) Successful in 0s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 6s
/ check (module-ipv4-test) (push) Successful in 6s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 1s
2025-03-09 21:50:22 +01:00
881983dd6c ci: validate renovaterc
All checks were successful
/ check-renovaterc (push) Successful in 2s
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 3s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 6s
/ check (module-ipv6-only-test) (push) Successful in 6s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 3s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 2s
Also use config:best-practices
2025-03-09 21:38:51 +01:00
632250d544
fix(deps): update rust crate serde to v1.0.219
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 3s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 6s
/ check (module-ipv6-only-test) (push) Successful in 6s
/ check (module-ipv6-test) (push) Successful in 6s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 3s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 2s
| datasource | package | from    | to      |
| ---------- | ------- | ------- | ------- |
| crate      | serde   | 1.0.218 | 1.0.219 |
2025-03-09 20:20:28 +01:00
c71a8b418c
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 6s
/ check (module-ipv4-test) (push) Successful in 6s
/ check (module-ipv6-only-test) (push) Successful in 6s
/ check (module-ipv6-test) (push) Successful in 6s
/ check (module-nginx-test) (push) Successful in 6s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 1s
2025-03-07 22:00:42 +01:00
873dd980ff
fix(deps): update rust crate tokio to v1.44.0
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 3s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 6s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 6s
/ check (module-nginx-test) (push) Successful in 6s
/ check (nextest) (push) Successful in 3s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 1s
| datasource | package | from   | to     |
| ---------- | ------- | ------ | ------ |
| crate      | tokio   | 1.43.0 | 1.44.0 |
2025-03-07 21:20:23 +01:00
3e1140ffe5
fix(deps): update rust crate ring to v0.17.13
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 3s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-only-test) (push) Successful in 6s
/ check (module-ipv6-test) (push) Successful in 6s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 3s
/ report-size (push) Successful in 1s
| datasource | package | from    | to      |
| ---------- | ------- | ------- | ------- |
| crate      | ring    | 0.17.12 | 0.17.13 |
2025-03-07 01:40:27 +01:00
6c78e8d78e
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 2s
2025-03-06 02:20:27 +01:00
3ed76c094c
fix(deps): update rust crate ring to v0.17.12
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 3s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 6s
/ check (module-ipv6-only-test) (push) Successful in 6s
/ check (module-ipv6-test) (push) Successful in 6s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 3s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 2s
| datasource | package | from    | to      |
| ---------- | ------- | ------- | ------- |
| crate      | ring    | 0.17.11 | 0.17.12 |
2025-03-06 02:10:27 +01:00
f16c3b9138
fix(typo): typos corrected typ to typo
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 3s
/ report-size (push) Successful in 2s
This is wrong for us (we use typ instead of type, not typo, because type
is a rust keyword).
2025-03-04 09:46:38 +01:00
42482574ac
chore(deps): lock file maintenance
Some checks failed
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 6s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 6s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Failing after 3s
/ report-size (push) Successful in 2s
2025-03-03 22:00:50 +01:00
855963bc85
fix(deps): update rust crate serde_json to v1.0.140
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 3s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 2s
| datasource | package    | from    | to      |
| ---------- | ---------- | ------- | ------- |
| crate      | serde_json | 1.0.139 | 1.0.140 |
2025-03-03 10:20:22 +01:00
7cc182b23e
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 6s
/ check (module-ipv6-only-test) (push) Successful in 6s
/ check (module-ipv6-test) (push) Successful in 6s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 3s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 2s
2025-03-02 02:10:30 +01:00
bc62fd7c1d
chore(deps): update rust crate insta to v1.42.2
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 2s
| datasource | package | from   | to     |
| ---------- | ------- | ------ | ------ |
| crate      | insta   | 1.42.1 | 1.42.2 |
2025-03-02 02:00:39 +01:00
cdef8078cc
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 2s
2025-03-01 22:00:54 +01:00
a6f0785dc3
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 8s
/ check (module-ipv4-test) (push) Successful in 6s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 3s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 1s
2025-03-01 00:00:35 +01:00
5d4c0fdb70
ci(renovate): don't overlap schedules
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 6s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 6s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 1s
Branch creation schedule and automerge schedule should not overlap, or
we'll get PRs that don't contain updates, which stop renovate from
creating further PRs.
2025-02-28 23:52:07 +01:00
2a2f9ef06c
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 6s
/ check (module-ipv6-only-test) (push) Successful in 6s
/ check (module-ipv6-test) (push) Successful in 6s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 3s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 1s
2025-02-27 23:00:49 +01:00
ef6e955b90
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 3s
/ report-size (push) Successful in 2s
2025-02-24 17:00:45 +01:00
b581e2adf1
fix(deps): update rust crate clap to v4.5.31
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 6s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 3s
/ report-size (push) Successful in 2s
| datasource | package | from   | to     |
| ---------- | ------- | ------ | ------ |
| crate      | clap    | 4.5.30 | 4.5.31 |
2025-02-24 16:50:22 +01:00
48034ec6e5
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 6s
/ check (module-nginx-test) (push) Successful in 6s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 3s
/ report-size (push) Successful in 2s
2025-02-23 23:00:42 +01:00
593bee9024
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 2s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 2s
2025-02-23 00:10:23 +01:00
09345f2193
fix(deps): update rust crate ring to v0.17.11
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 3s
/ report-size (push) Successful in 2s
| datasource | package | from    | to      |
| ---------- | ------- | ------- | ------- |
| crate      | ring    | 0.17.10 | 0.17.11 |
2025-02-22 19:50:25 +01:00
71d1e43ef2
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 2s
2025-02-21 23:00:24 +01:00
528aad1d8e
fix(deps): update rust crate ring to v0.17.10
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 6s
/ check (module-nginx-test) (push) Successful in 6s
/ check (nextest) (push) Successful in 3s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 1s
| datasource | package | from   | to      |
| ---------- | ------- | ------ | ------- |
| crate      | ring    | 0.17.9 | 0.17.10 |
2025-02-21 18:30:23 +01:00
cb7e4d554b
fix(deps): update rust crate serde to v1.0.218
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 3s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 3s
/ report-size (push) Successful in 2s
| datasource | package | from    | to      |
| ---------- | ------- | ------- | ------- |
| crate      | serde   | 1.0.217 | 1.0.218 |
2025-02-20 06:30:30 +01:00
01f53b2bf0
fix(deps): update rust crate serde_json to v1.0.139
All checks were successful
/ build (push) Successful in 2s
/ check (clippy) (push) Successful in 3s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 3s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 2s
| datasource | package    | from    | to      |
| ---------- | ---------- | ------- | ------- |
| crate      | serde_json | 1.0.138 | 1.0.139 |
2025-02-20 04:10:23 +01:00
60662ff1f0
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 3s
/ report-size (push) Successful in 2s
2025-02-19 17:41:04 +01:00
eaed7b2302
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 6s
/ check (module-ipv4-test) (push) Successful in 6s
/ check (module-ipv6-only-test) (push) Successful in 6s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 3s
/ report-size (push) Successful in 2s
2025-02-17 23:00:41 +01:00
8a04c2726f
fix(deps): update rust crate clap to v4.5.30
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 3s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 2s
| datasource | package | from   | to     |
| ---------- | ------- | ------ | ------ |
| crate      | clap    | 4.5.29 | 4.5.30 |
2025-02-17 20:20:29 +01:00
1a88dbaeb2
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 4s
/ report-size (push) Successful in 2s
2025-02-16 20:30:52 +01:00
c41008f800
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 6s
/ check (module-ipv6-only-test) (push) Successful in 6s
/ check (module-ipv6-test) (push) Successful in 6s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 1s
2025-02-15 23:00:22 +01:00
3c18f07a2a
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 2s
/ check (clippy) (push) Successful in 3s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 6s
/ check (module-nginx-test) (push) Successful in 6s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 2s
2025-02-14 02:10:35 +01:00
0a5348097d
fix(deps): update rust crate ring to v0.17.9
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 6s
/ check (module-ipv4-test) (push) Successful in 6s
/ check (module-ipv6-only-test) (push) Successful in 6s
/ check (module-ipv6-test) (push) Successful in 6s
/ check (module-nginx-test) (push) Successful in 6s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 3s
/ report-size (push) Successful in 2s
| datasource | package | from   | to     |
| ---------- | ------- | ------ | ------ |
| crate      | ring    | 0.17.8 | 0.17.9 |
2025-02-14 02:00:26 +01:00
bdb27d7cb1
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 6s
/ check (module-ipv6-only-test) (push) Successful in 6s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 2s
2025-02-12 23:00:37 +01:00
41c30372fb
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 3s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 3s
/ report-size (push) Successful in 2s
2025-02-11 21:40:30 +01:00
e99bc52de2
fix(deps): update rust crate clap to v4.5.29
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 3s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 6s
/ check (module-ipv6-only-test) (push) Successful in 6s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 3s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 2s
| datasource | package | from   | to     |
| ---------- | ------- | ------ | ------ |
| crate      | clap    | 4.5.28 | 4.5.29 |
2025-02-11 21:20:45 +01:00
338e296683
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 3s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-only-test) (push) Successful in 6s
/ check (module-ipv6-test) (push) Successful in 6s
/ check (module-nginx-test) (push) Successful in 6s
/ check (nextest) (push) Successful in 3s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 1s
2025-02-10 09:20:41 +01:00
29f7315f67
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 3s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-only-test) (push) Successful in 6s
/ check (module-ipv6-test) (push) Successful in 6s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 2s
2025-02-06 23:00:24 +01:00
738fa8accf
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 3s
/ report-size (push) Successful in 2s
2025-02-05 23:30:28 +01:00
172076eaad
feat(webnsupdate): parse IPv6 prefixes
All checks were successful
/ build (push) Successful in 2s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 3s
/ report-size (push) Successful in 2s
This allows us to better support IPv6 from fritzbox updates in the
future.
2025-02-05 23:17:49 +01:00
b775f8e811
refactor(nsupdate): send all commands at once
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 6s
/ check (module-ipv4-test) (push) Successful in 6s
/ check (module-ipv6-only-test) (push) Successful in 6s
/ check (module-ipv6-test) (push) Successful in 6s
/ check (module-nginx-test) (push) Successful in 6s
/ check (nextest) (push) Successful in 3s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 2s
This ensures `nsupdate` is only called once per IP update (even for both
IPv4 and IPv6 in a single call).
2025-02-05 22:47:13 +01:00
48c2e5be4d
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 6s
/ check (module-ipv4-test) (push) Successful in 6s
/ check (module-ipv6-only-test) (push) Successful in 6s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 2s
2025-02-04 23:00:40 +01:00
d56af9ecfe
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 6s
/ check (module-nginx-test) (push) Successful in 6s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 1s
2025-02-04 00:00:46 +01:00
72aa4f365e
fix(deps): update rust crate clap to v4.5.28
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 3s
/ report-size (push) Successful in 2s
| datasource | package | from   | to     |
| ---------- | ------- | ------ | ------ |
| crate      | clap    | 4.5.27 | 4.5.28 |
2025-02-03 23:50:29 +01:00
d8630aa8cb
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 3s
/ report-size (push) Successful in 2s
2025-02-01 23:00:21 +01:00
5655d7de67
fix(deps): update rust crate miette to v7.5.0
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 3s
/ report-size (push) Successful in 2s
| datasource | package | from  | to    |
| ---------- | ------- | ----- | ----- |
| crate      | miette  | 7.4.0 | 7.5.0 |
2025-02-01 04:20:25 +01:00
d2f6c3cd66
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 3s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 6s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 2s
2025-01-31 22:00:20 +01:00
13c9c544a7
fix(webnsupdate): updating IPv6 in ipv4-only mode
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 6s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 1s
Dumb logic error T-T.
2025-01-31 21:46:27 +01:00
70ed898f1d
fix(tests): add case for when query has empty string
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 1s
This is produced by the FRITZ!Box DDNS client.
2025-01-31 21:25:41 +01:00
2f97008475
fix(webnsupdate): make IP none when query is empty
This happens when one of the IPs hasn't changed (but the other has) in
the FRITZ!Box DDNS client.
2025-01-31 21:25:41 +01:00
09bd450a46
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 1s
/ check (module-ipv4-only-test) (push) Successful in 1s
/ check (module-ipv4-test) (push) Successful in 1s
/ check (module-ipv6-only-test) (push) Successful in 1s
/ check (module-ipv6-test) (push) Successful in 1s
/ check (module-nginx-test) (push) Successful in 1s
/ check (nextest) (push) Successful in 1s
/ check (treefmt) (push) Successful in 0s
/ report-size (push) Successful in 1s
2025-01-29 23:00:44 +01:00
a6bb8bf817
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 2s
/ check (clippy) (push) Successful in 3s
/ check (module-ipv4-only-test) (push) Successful in 7s
/ check (module-ipv4-test) (push) Successful in 6s
/ check (module-ipv6-only-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 3s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 2s
2025-01-29 00:00:30 +01:00
a39fa354e4
feat(webnsupdate): add support for fritzbox style updates
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-only-test) (push) Successful in 6s
/ check (module-ipv4-test) (push) Successful in 6s
/ check (module-ipv6-only-test) (push) Successful in 10s
/ check (module-ipv6-test) (push) Successful in 8s
/ check (module-nginx-test) (push) Successful in 10s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 3s
/ report-size (push) Successful in 2s
Update now optionally accepts query params (e.g. `/update?ipv4=1.2.3.4`)
if present they will control how the update is made (only ipv4 and ipv6
are implemented right now).

Closes #80
2025-01-28 23:56:52 +01:00
26566fd612
fix(deps): update rust crate serde_json to v1.0.138
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 3s
/ report-size (push) Successful in 1s
| datasource | package    | from    | to      |
| ---------- | ---------- | ------- | ------- |
| crate      | serde_json | 1.0.137 | 1.0.138 |
2025-01-28 19:00:24 +01:00
09be5627c3
refactor(module): NixOS tests
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-test) (push) Successful in 6s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 2s
Way easier to extend/maintain.
2025-01-28 00:31:32 +01:00
dff29cab77
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-test) (push) Successful in 6s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 1s
2025-01-26 23:00:37 +01:00
c8407a8eb4
chore(release): prepare for 0.3.6
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 1s
/ check (module-ipv4-test) (push) Successful in 1s
/ check (module-ipv6-test) (push) Successful in 1s
/ check (module-nginx-test) (push) Successful in 1s
/ check (nextest) (push) Successful in 1s
/ check (treefmt) (push) Successful in 1s
/ report-size (push) Successful in 2s
Generate changelog and bump version.
2025-01-26 22:39:19 +01:00
77cb03576d
feat(flake): add tests for new allowedIPVersion option
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 1s
This ensures we don't accidentally update records.
2025-01-26 22:30:04 +01:00
a47dd0bfac
feat(module): add option for setting --ip-type
This makes it easy to set the server to ipv4-only mode.
2025-01-26 22:25:41 +01:00
34ce8a69f6
feat(webnsupdate): allow running in IPv4/6 only mode
This fixes issues when the IPv6/IPv4 is not working properly but updates
are still happening (like rn) T-T.
2025-01-26 22:25:41 +01:00
ea428d1aef
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-test) (push) Successful in 8s
/ check (module-ipv6-test) (push) Successful in 6s
/ check (module-nginx-test) (push) Successful in 6s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 2s
2025-01-25 19:40:22 +01:00
98aa3c2a97
chore(deps): update rust crate insta to v1.42.1
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 3s
/ check (module-ipv4-test) (push) Successful in 6s
/ check (module-ipv6-test) (push) Successful in 6s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 2s
| datasource | package | from   | to     |
| ---------- | ------- | ------ | ------ |
| crate      | insta   | 1.42.0 | 1.42.1 |
2025-01-25 19:30:20 +01:00
0fc17d9150
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 3s
/ report-size (push) Successful in 2s
2025-01-24 23:00:42 +01:00
e72e3777b8
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-test) (push) Successful in 6s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 2s
2025-01-23 23:00:21 +01:00
2473e6edbc
chore(release): prepare for 0.3.5 (docs)
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 1s
/ check (module-ipv4-test) (push) Successful in 1s
/ check (module-ipv6-test) (push) Successful in 1s
/ check (module-nginx-test) (push) Successful in 1s
/ check (nextest) (push) Successful in 1s
/ check (treefmt) (push) Successful in 1s
/ report-size (push) Successful in 2s
Generate changelog
2025-01-23 22:49:09 +01:00
989ed2a080
chore(release): prepare for 0.3.5 (rust)
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-test) (push) Successful in 7s
/ check (module-ipv6-test) (push) Successful in 7s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 3s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 2s
Bump version
2025-01-23 22:47:26 +01:00
2e8d20f89d
ci: parallelize checks
All checks were successful
/ build (push) Successful in 1s
/ check (clippy) (push) Successful in 2s
/ check (module-ipv4-test) (push) Successful in 6s
/ check (module-ipv6-test) (push) Successful in 6s
/ check (module-nginx-test) (push) Successful in 7s
/ check (nextest) (push) Successful in 2s
/ check (treefmt) (push) Successful in 2s
/ report-size (push) Successful in 2s
If I ever get more runners, this will be a great speedup.
2025-01-23 22:32:15 +01:00
ec27e31336
feat(tests): add nginx integration test
All checks were successful
/ build (push) Successful in 1s
/ check (push) Successful in 9s
/ report-size (push) Successful in 1s
This ensures we can handle IPv4 and IPv6 simultaneously
2025-01-23 22:24:30 +01:00
e5f7d94f77
feat: tune compilation for size
All checks were successful
/ build (push) Successful in 1s
/ check (push) Successful in 8s
/ report-size (push) Successful in 2s
Reduce size by setting `codegen-units = 1` in release mode.
2025-01-23 21:31:27 +01:00
a2735b46b5
feat(webnsupdate): add handling for multiple IPs
All checks were successful
/ build (push) Successful in 1s
/ check (push) Successful in 8s
/ report-size (push) Successful in 2s
Specifically, for when both and IPv6 and and IPv4 addr is provided. This
ensures we can forward both addrs to webnsupdate, instead of only
allowing IPv4.
2025-01-23 21:10:21 +01:00
542336867a
fix(module): test both IPv4 and IPv6
All checks were successful
/ build (push) Successful in 1s
/ check (push) Successful in 8s
/ report-size (push) Successful in 2s
This ensures both work
2025-01-23 21:06:26 +01:00
70162c83f6
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 1s
/ check (push) Successful in 6s
/ report-size (push) Successful in 1s
2025-01-21 23:00:21 +01:00
0fd9a87907
fix(deps): update rust crate axum to v0.8.2
All checks were successful
/ build (push) Successful in 1s
/ check (push) Successful in 7s
/ report-size (push) Successful in 2s
| datasource | package | from  | to    |
| ---------- | ------- | ----- | ----- |
| crate      | axum    | 0.8.1 | 0.8.2 |
2025-01-21 14:20:22 +01:00
880d462e80
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 2s
/ check (push) Successful in 8s
/ report-size (push) Successful in 2s
2025-01-20 22:30:26 +01:00
40a9d600c9
fix(deps): update rust crate clap to v4.5.27
All checks were successful
/ build (push) Successful in 1s
/ check (push) Successful in 7s
/ report-size (push) Successful in 2s
| datasource | package | from   | to     |
| ---------- | ------- | ------ | ------ |
| crate      | clap    | 4.5.26 | 4.5.27 |
2025-01-20 22:20:18 +01:00
8bf62f3ce2
fix(flake): switch overlay to callPackage
All checks were successful
/ build (push) Successful in 1s
/ check (push) Successful in 7s
/ report-size (push) Successful in 1s
This ensures it can be built for any architecture (supported by Rust).
2025-01-10 23:42:40 +01:00
883f6e6ae7
fix(deps): update rust crate clap to v4.5.26
All checks were successful
/ build (push) Successful in 1s
/ check (push) Successful in 7s
/ report-size (push) Successful in 2s
| datasource | package | from   | to     |
| ---------- | ------- | ------ | ------ |
| crate      | clap    | 4.5.25 | 4.5.26 |
2025-01-09 19:30:24 +01:00
4863ebc6df
fix(deps): update rust crate clap to v4.5.25
All checks were successful
/ build (push) Successful in 1s
/ check (push) Successful in 7s
/ report-size (push) Successful in 2s
| datasource | package | from   | to     |
| ---------- | ------- | ------ | ------ |
| crate      | clap    | 4.5.24 | 4.5.25 |
2025-01-09 16:40:31 +01:00
36b4d55ea8
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 1s
/ check (push) Successful in 7s
/ report-size (push) Successful in 1s
2025-01-08 23:00:22 +01:00
faf1f637ab
fix(deps): update rust crate tokio to v1.43.0
All checks were successful
/ build (push) Successful in 1s
/ check (push) Successful in 7s
/ report-size (push) Successful in 2s
| datasource | package | from   | to     |
| ---------- | ------- | ------ | ------ |
| crate      | tokio   | 1.42.0 | 1.43.0 |
2025-01-08 17:10:21 +01:00
9b2880c141
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 0s
/ check (push) Successful in 7s
/ report-size (push) Successful in 2s
2025-01-07 18:30:25 +01:00
0685c2601a
fix(deps): update rust crate clap to v4.5.24
All checks were successful
/ build (push) Successful in 1s
/ check (push) Successful in 7s
/ report-size (push) Successful in 2s
| datasource | package | from   | to     |
| ---------- | ------- | ------ | ------ |
| crate      | clap    | 4.5.23 | 4.5.24 |
2025-01-07 18:20:30 +01:00
5e16700652
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 1s
/ check (push) Successful in 7s
/ report-size (push) Successful in 2s
2025-01-06 23:00:38 +01:00
ccc1ccba97
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 1s
/ check (push) Successful in 7s
/ report-size (push) Successful in 2s
2025-01-05 12:20:24 +01:00
a515c5d8df
fix(renovaterc): invalid cron syntax
All checks were successful
/ build (push) Successful in 1s
/ check (push) Successful in 7s
/ report-size (push) Successful in 2s
There was a small mistake in the config.
2025-01-05 12:17:09 +01:00
7fdf322c73
fix(renovate): branch creation before automerge
All checks were successful
/ build (push) Successful in 0s
/ check (push) Successful in 6s
/ report-size (push) Successful in 2s
Otherwise renovate might miss the merge window QAQ
2025-01-05 11:11:02 +01:00
5d6fd054ee
chore(deps): update rust crate insta to v1.42.0
All checks were successful
/ build (push) Successful in 0s
/ check (push) Successful in 6s
/ report-size (push) Successful in 2s
| datasource | package | from   | to     |
| ---------- | ------- | ------ | ------ |
| crate      | insta   | 1.41.1 | 1.42.0 |
2025-01-05 01:40:22 +01:00
2b953c4b75
fix(typos): typos caught more typos :3
All checks were successful
/ build (push) Successful in 1s
/ check (push) Successful in 7s
/ report-size (push) Successful in 2s
Some typos where not a typo tho, just a test T-T. This fixes it.
2025-01-04 13:43:53 +01:00
c038b68ecb
chore(deps): lock file maintenance
Some checks failed
/ build (push) Successful in 1m4s
/ check (push) Failing after 37s
/ report-size (push) Successful in 7s
2025-01-04 13:20:20 +01:00
dcba690961
fix(ci): remove update workflow
All checks were successful
/ build (push) Successful in 1s
/ check (push) Successful in 7s
/ report-size (push) Successful in 2s
Not needed as renovate fulfills this purpose.
2025-01-04 13:08:55 +01:00
99e887513d
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 1s
/ check (push) Successful in 7s
/ report-size (push) Successful in 2s
2025-01-02 00:00:25 +01:00
4490dfac05
chore: update to axum 0.8
All checks were successful
/ build (push) Successful in 1s
/ check (push) Successful in 7s
/ report-size (push) Successful in 2s
This requires updating axum-client-ip too as it depends on axum.
2025-01-01 19:32:15 +01:00
22ab037b6f
fix(renovate): switch automergeStrategy to auto
All checks were successful
/ build (push) Successful in 1s
/ check (push) Successful in 7s
/ report-size (push) Successful in 2s
fast-forward triggers a rebase which is not allowed in this repo.
2025-01-01 10:44:48 +01:00
e4451beebf
chore(deps): lock file maintenance
All checks were successful
/ build (push) Successful in 1s
/ check (push) Successful in 7s
/ report-size (push) Successful in 2s
2025-01-01 00:00:28 +01:00
6a1feb2612
fix(flake): switch to github ref
All checks were successful
/ build (push) Successful in 1s
/ check (push) Successful in 7s
/ report-size (push) Successful in 2s
Switch from a flake ref to a github ref as renovate cannot resolve flake
refs, and they are slightly impure.

This shows some issues with the previous patch to the bind module which
we fix.
2024-12-29 18:19:32 +01:00
2ba6277778
feat(renovate): enable lockFileMaintenance
Some checks failed
/ build (push) Successful in 2s
/ check (push) Failing after 13s
/ report-size (push) Successful in 7s
This allows it to update the flake.lock and Cargo.lock files.
2024-12-29 18:07:36 +01:00
69fde96f67
refactor: setup renovate to manage dependencies
All checks were successful
/ build (push) Successful in 1s
/ check (push) Successful in 6s
/ report-size (push) Successful in 1s
This should make it easier to keep the repo up to date.
2024-12-28 10:08:11 +01:00
f6084449fa
Add renovate.json
All checks were successful
/ build (push) Successful in 1s
/ check (push) Successful in 6s
/ report-size (push) Successful in 1s
2024-12-28 01:07:06 +01:00
e9d5b87ecc
fix(main): add more logging and default to info
All checks were successful
/ build (push) Successful in 1s
/ check (push) Successful in 7s
/ report-size (push) Successful in 2s
`leo` fails to run with v0.3.3 so we are adding a bit more logging to
debug the case.

As part of this, change default log level to `info`.
2024-12-26 17:21:27 +01:00
63a7505724
chore(release): prepare for v0.3.3
All checks were successful
/ build (push) Successful in 1s
/ check (push) Successful in 7s
/ report-size (push) Successful in 1s
2024-12-22 14:13:14 +01:00
502f7cbcdf
fix(ci): remove tea
All checks were successful
/ build (push) Successful in 1s
/ check (push) Successful in 7s
/ report-size (push) Successful in 2s
`tea` doesn't like the forgejo GITHUB_TOKENs and doesn't work.
2024-12-22 13:40:12 +01:00
7bc103e861
chore: generate base changelog
All checks were successful
/ build (push) Successful in 1s
/ check (push) Successful in 7s
/ report-size (push) Successful in 2s
2024-12-22 13:21:11 +01:00
2a52e66bc0
feat: add git-cliff to generate changelogs
This should make the project a bit more "official" c:
2024-12-22 13:12:52 +01:00
bd8badac23
fix(webnsupdate): reduce binary size
All checks were successful
/ build (push) Successful in 1s
/ check (push) Successful in 6s
/ report-size (push) Successful in 1s
There is no need to compile for speed of execution, this is not a
contested component.
2024-12-22 00:52:01 +01:00
forgejo-actions
6b4c0c4865 chore: cargo update
All checks were successful
/ build (push) Successful in 1s
/ check (push) Successful in 7s
/ report-size (push) Successful in 2s
Locking 31 packages to latest compatible versions
    Updating bytes v1.8.0 -> v1.9.0
    Updating cc v1.2.1 -> v1.2.5
    Updating clap v4.5.21 -> v4.5.23
    Updating clap-verbosity-flag v3.0.0 -> v3.0.2
    Updating clap_builder v4.5.21 -> v4.5.23
    Updating clap_lex v0.7.3 -> v0.7.4
    Updating console v0.15.8 -> v0.15.10
    Updating encode_unicode v0.3.6 -> v1.0.0
    Updating errno v0.3.9 -> v0.3.10
    Removing hermit-abi v0.3.9
    Updating http v1.1.0 -> v1.2.0
    Updating hyper v1.5.1 -> v1.5.2
    Updating itoa v1.0.13 -> v1.0.14
    Updating libc v0.2.164 -> v0.2.169
    Updating miette v7.2.0 -> v7.4.0
    Updating miette-derive v7.2.0 -> v7.4.0
    Updating miniz_oxide v0.8.0 -> v0.8.2
    Updating mio v1.0.2 -> v1.0.3
    Updating rustix v0.38.41 -> v0.38.42
    Updating serde v1.0.215 -> v1.0.216
    Updating serde_derive v1.0.215 -> v1.0.216
    Removing smawk v0.3.2
    Updating socket2 v0.5.7 -> v0.5.8
    Updating supports-color v3.0.1 -> v3.0.2
    Updating supports-hyperlinks v3.0.0 -> v3.1.0
    Updating syn v2.0.89 -> v2.0.90
    Removing sync_wrapper v0.1.2
    Updating terminal_size v0.3.0 -> v0.4.1
    Updating tokio v1.41.1 -> v1.42.0
    Updating tower v0.5.1 -> v0.5.2
    Updating tracing v0.1.40 -> v0.1.41
    Updating tracing-attributes v0.1.27 -> v0.1.28
    Updating tracing-core v0.1.32 -> v0.1.33
    Updating tracing-subscriber v0.3.18 -> v0.3.19
    Removing windows-sys v0.48.0
    Removing windows-targets v0.48.5
    Removing windows_aarch64_gnullvm v0.48.5
    Removing windows_aarch64_msvc v0.48.5
    Removing windows_i686_gnu v0.48.5
    Removing windows_i686_msvc v0.48.5
    Removing windows_x86_64_gnu v0.48.5
    Removing windows_x86_64_gnullvm v0.48.5
    Removing windows_x86_64_msvc v0.48.5
note: pass `--verbose` to see 12 unchanged dependencies behind latest
2024-12-22 00:46:26 +01:00
9f40444846
chore(flake.lock): update inputs
All checks were successful
/ build (push) Successful in 1s
/ check (push) Successful in 7s
/ report-size (push) Successful in 2s
Flake lock file updates:

• Updated input 'crane':
    'github:ipetkov/crane/3cb338ce81076ce5e461cf77f7824476addb0e1c' (2024-11-19)
  → 'github:ipetkov/crane/72e2d02dbac80c8c86bf6bf3e785536acf8ee926' (2024-12-21)
• Updated input 'flake-parts':
    'github:hercules-ci/flake-parts/506278e768c2a08bec68eb62932193e341f55c90' (2024-11-01)
  → 'github:hercules-ci/flake-parts/205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9' (2024-12-04)
• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/23e89b7da85c3640bbc2173fe04f4bd114342367' (2024-11-19)
  → 'github:NixOS/nixpkgs/d3c42f187194c26d9f0309a8ecc469d6c878ce33' (2024-12-17)
• Updated input 'treefmt-nix':
    'github:numtide/treefmt-nix/705df92694af7093dfbb27109ce16d828a79155f' (2024-11-22)
  → 'github:numtide/treefmt-nix/65712f5af67234dad91a5a4baee986a8b62dbf8f' (2024-12-20)
2024-12-22 00:43:41 +01:00
faf09c7de1
feat(ci): generate package size report
All checks were successful
/ build (push) Successful in 1s
/ check (push) Successful in 7s
/ report-size (push) Successful in 2s
We should keep it lean c:
2024-12-22 00:41:52 +01:00
657a877168
chore: bump version to dev
All checks were successful
/ build (push) Successful in 2s
/ check (push) Successful in 7s
preparing for the next dev cycle
2024-11-23 21:26:47 +01:00
ce2692f66d
feat: release new version
All checks were successful
/ build (push) Successful in 1s
/ check (push) Successful in 7s
2024-11-23 21:16:46 +01:00
bea38bc445
fix(clippy): enable more lints and fix issues
All checks were successful
/ build (push) Successful in 3s
/ check (push) Successful in 7s
We also add some more metadata to the Cargo.toml manifest
2024-11-23 21:12:27 +01:00
846a0675d1
refactor: reorganize main.rs
All checks were successful
/ build (push) Successful in 2s
/ check (push) Successful in 8s
2024-11-23 21:01:58 +01:00
750cbbff93
feat: replace axum-auth with tower_http
All checks were successful
/ build (push) Successful in 3s
/ check (push) Successful in 7s
Slightly more involde in the auth code, but it makes the rest of the
application more straight forward.

Fixes #10
2024-11-23 20:39:06 +01:00
60aed649b1
feat: upgrade clap_verbosity_flag
All checks were successful
/ build (push) Successful in 2s
/ check (push) Successful in 7s
Adds tracing support which simplyfies code.
2024-11-23 13:10:48 +01:00
d98c4202f4
feat(ci): check depends on build
All checks were successful
/ build (push) Successful in 2s
/ check (push) Successful in 7s
Because it depends on build, if build runs afterward, nix uses the cache
and no valuable logs are produced.
2024-11-23 13:02:25 +01:00
68cf43c539
chore: update flake inputs
All checks were successful
/ check (push) Successful in 7s
/ build (push) Successful in 2s
• Updated input 'crane':
    'github:ipetkov/crane/498d9f122c413ee1154e8131ace5a35a80d8fa76' (2024-10-27)
  → 'github:ipetkov/crane/3cb338ce81076ce5e461cf77f7824476addb0e1c' (2024-11-19)
• Updated input 'flake-parts':
    'github:hercules-ci/flake-parts/3d04084d54bedc3d6b8b736c70ef449225c361b1' (2024-10-01)
  → 'github:hercules-ci/flake-parts/506278e768c2a08bec68eb62932193e341f55c90' (2024-11-01)
• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/5633bcff0c6162b9e4b5f1264264611e950c8ec7' (2024-10-09)
  → 'github:NixOS/nixpkgs/23e89b7da85c3640bbc2173fe04f4bd114342367' (2024-11-19)
• Updated input 'treefmt-nix':
    'github:numtide/treefmt-nix/aac86347fb5063960eccb19493e0cadcdb4205ca' (2024-10-22)
  → 'github:numtide/treefmt-nix/705df92694af7093dfbb27109ce16d828a79155f' (2024-11-22)
2024-11-23 12:56:55 +01:00
forgejo-actions
82b1078a94 chore: cargo update
All checks were successful
/ check (push) Successful in 7s
/ build (push) Successful in 2s
Locking 25 packages to latest compatible versions
    Updating anstream v0.6.17 -> v0.6.18
    Updating anstyle v1.0.9 -> v1.0.10
    Updating axum v0.7.7 -> v0.7.9
    Updating cc v1.1.31 -> v1.2.1
    Updating clap v4.5.20 -> v4.5.21
    Updating clap-verbosity-flag v2.2.2 -> v2.2.3 (latest: v3.0.0)
    Updating clap_builder v4.5.20 -> v4.5.21
    Updating clap_lex v0.7.2 -> v0.7.3
    Updating hyper v1.5.0 -> v1.5.1
    Updating hyper-util v0.1.9 -> v0.1.10
    Updating insta v1.40.0 -> v1.41.1
    Updating itoa v1.0.11 -> v1.0.13
    Updating libc v0.2.161 -> v0.2.164
    Updating proc-macro2 v1.0.89 -> v1.0.92
    Updating regex-automata v0.4.8 -> v0.4.9
    Updating rustix v0.38.37 -> v0.38.41
    Updating serde v1.0.213 -> v1.0.215
    Updating serde_derive v1.0.213 -> v1.0.215
    Updating serde_json v1.0.132 -> v1.0.133
    Updating syn v2.0.85 -> v2.0.89
    Updating sync_wrapper v1.0.1 -> v1.0.2
    Updating thiserror v1.0.65 -> v1.0.69 (latest: v2.0.3)
    Updating thiserror-impl v1.0.65 -> v1.0.69 (latest: v2.0.3)
    Updating tokio v1.41.0 -> v1.41.1
    Updating unicode-ident v1.0.13 -> v1.0.14
2024-11-23 12:55:08 +01:00
5a9b09bc7e
chore: bump version
All checks were successful
/ check (push) Successful in 7s
/ build (push) Successful in 2s
New dev version
2024-10-28 22:44:51 +01:00
618670512e
fix: overlay was broken T-T
All checks were successful
/ check (push) Successful in 1m22s
/ build (push) Successful in 2s
2024-10-28 22:41:12 +01:00
e61913e5a8
chore: next dev version
All checks were successful
/ check (push) Successful in 6s
/ build (push) Successful in 2s
2024-10-28 22:11:56 +01:00
b7fbb65438
chore: bump version
All checks were successful
/ check (push) Successful in 6s
/ build (push) Successful in 1s
Release version 0.3.0

Main features:
- persist last IP checked to ensure DNS records can be served upon
  restart
- end-to-end testing of the NixOS module ensures most changes will not
  result in a broken DNS server
2024-10-28 22:02:03 +01:00
d44d2aa1a7
feat: switch to crane
All checks were successful
/ check (push) Successful in 6s
/ build (push) Successful in 1s
Should provide better caching of the intermediate build artifacts.
2024-10-28 21:55:53 +01:00
8dd8b9e3aa
feat: add NixOS VM tests
All checks were successful
/ check (push) Successful in 7s
/ build (push) Successful in 1s
This does integration testing to ensure the module works properly
2024-10-28 10:41:41 +01:00
c81d7af356
feat: use treefmt-nix and split up flake.nix 2024-10-28 10:41:41 +01:00
442601f25a
feat: add -v verbosity flag 2024-10-28 10:39:14 +01:00
forgejo-actions
51f557c482 chore: cargo update
All checks were successful
/ check (push) Successful in 5s
/ build (push) Successful in 1m1s
Updating anstream v0.6.15 -> v0.6.17
    Updating anstyle v1.0.8 -> v1.0.9
    Updating anstyle-parse v0.2.5 -> v0.2.6
    Updating anstyle-query v1.1.1 -> v1.1.2
    Updating anstyle-wincon v3.0.4 -> v3.0.6
    Updating bytes v1.7.2 -> v1.8.0
    Updating cc v1.1.30 -> v1.1.31
    Updating colorchoice v1.0.2 -> v1.0.3
    Updating hyper v1.4.1 -> v1.5.0
    Updating libc v0.2.159 -> v0.2.161
    Updating pin-project-lite v0.2.14 -> v0.2.15
    Updating proc-macro2 v1.0.87 -> v1.0.89
    Updating regex v1.11.0 -> v1.11.1
    Updating rustversion v1.0.17 -> v1.0.18
    Updating serde v1.0.210 -> v1.0.213
    Updating serde_derive v1.0.210 -> v1.0.213
    Updating serde_json v1.0.128 -> v1.0.132
    Updating syn v2.0.79 -> v2.0.85
    Updating thiserror v1.0.64 -> v1.0.65
    Updating thiserror-impl v1.0.64 -> v1.0.65
    Updating tokio v1.40.0 -> v1.41.0
      Adding windows-sys v0.59.0
2024-10-27 09:31:43 +01:00
5745e1aaf7
feat: refactor and add ip saving
All checks were successful
/ check (push) Successful in 4s
/ build (push) Successful in 2s
- clean up code to my new (and improved) standards
- print better miette diagnostigs for the error tests
- add an IP saving feature:
    save the last IP that successfully updated the records and usa that
    when restarting the service. This allows seamles upgrades of
    `webnsupdate` without having to manually trigger a DNS update
2024-10-13 00:54:54 +02:00
8242b83dd9
refactor(flake): use flake-parts
All checks were successful
/ check (push) Successful in 4s
/ build (push) Successful in 1s
This makes it easier to split up the flake in the future.
2024-10-12 22:34:57 +02:00
2a18f6bedb
fix(ci): do not use a name when logging in
All checks were successful
/ check (push) Successful in 2s
/ build (push) Successful in 2s
This should fix an error with `tea`
2024-10-12 22:19:00 +02:00
forgejo-actions
d26caed805 chore: cargo update
All checks were successful
/ check (push) Successful in 2s
/ build (push) Successful in 2s
Locking 14 packages to latest compatible versions
    Updating addr2line v0.24.1 -> v0.24.2
    Updating axum-client-ip v0.6.0 -> v0.6.1
    Updating cc v1.1.23 -> v1.1.30
    Updating clap v4.5.18 -> v4.5.20
    Updating clap_builder v4.5.18 -> v4.5.20
    Updating futures-channel v0.3.30 -> v0.3.31
    Updating futures-core v0.3.30 -> v0.3.31
    Updating futures-task v0.3.30 -> v0.3.31
    Updating futures-util v0.3.30 -> v0.3.31
    Updating gimli v0.31.0 -> v0.31.1
    Updating httparse v1.9.4 -> v1.9.5
    Updating object v0.36.4 -> v0.36.5
    Updating once_cell v1.20.1 -> v1.20.2
    Removing portable-atomic v1.9.0
    Updating proc-macro2 v1.0.86 -> v1.0.87
note: pass `--verbose` to see 24 unchanged dependencies behind latest
2024-10-12 22:13:18 +02:00
095bc3bc8c
fix(default.nix): small issues here and there
All checks were successful
/ check (push) Successful in 2s
/ build (push) Successful in 1s
Mostly concerning the test output
2024-09-30 16:47:48 +02:00
forgejo-actions
b1e184d186 chore: cargo update
Locking 21 packages to latest compatible versions
    Updating async-trait v0.1.82 -> v0.1.83
    Updating axum v0.7.5 -> v0.7.7
    Updating axum-core v0.4.3 -> v0.4.5
    Updating bytes v1.7.1 -> v1.7.2
    Updating cc v1.1.18 -> v1.1.23
    Updating clap v4.5.17 -> v4.5.18
    Updating clap_builder v4.5.17 -> v4.5.18
    Updating clap_derive v4.5.13 -> v4.5.18
    Updating hyper-util v0.1.8 -> v0.1.9
    Updating libc v0.2.158 -> v0.2.159
    Updating once_cell v1.19.0 -> v1.20.1
    Removing pin-project v1.1.5
    Removing pin-project-internal v1.1.5
      Adding portable-atomic v1.9.0
    Updating regex v1.10.6 -> v1.11.0
    Updating regex-automata v0.4.7 -> v0.4.8
    Updating regex-syntax v0.8.4 -> v0.8.5
    Updating rustix v0.38.36 -> v0.38.37
    Updating syn v2.0.77 -> v2.0.79
    Updating thiserror v1.0.63 -> v1.0.64
    Updating thiserror-impl v1.0.63 -> v1.0.64
    Updating tower v0.4.13 -> v0.5.1
    Updating unicode-width v0.1.13 -> v0.1.14 (latest: v0.2.0)
note: pass `--verbose` to see 23 unchanged dependencies behind latest
2024-09-30 16:41:08 +02:00
26cffb230f
feat(ci): auto-update rust deps
All checks were successful
/ check (push) Successful in 2s
/ build (push) Successful in 2s
On a weekly basis c:
2024-09-30 16:36:28 +02:00
d76722f602
chore(flake.lock): update inputs
• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/574d1eac1c200690e27b8eb4e24887f8df7ac27c' (2024-09-06)
  → 'github:NixOS/nixpkgs/1925c603f17fc89f4c8f6bf6f631a802ad85d784' (2024-09-26)
2024-09-30 16:19:39 +02:00
144d5c45c6
fix(fmt): use nixfmt-rfc-style 2024-09-30 16:14:17 +02:00
9fc79a0c7b
chore: updarte deps
All checks were successful
/ check (push) Successful in 2s
/ build (push) Successful in 2s
Falke inputs:

```
• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/e9ee548d90ff586a6471b4ae80ae9cfcbceb3420' (2024-06-13)
  → 'github:NixOS/nixpkgs/574d1eac1c200690e27b8eb4e24887f8df7ac27c' (2024-09-06)
```
2024-09-11 08:16:58 +02:00
965b289484
[feat] package: reduce rebuilds
All checks were successful
/ check (push) Successful in 2s
/ build (push) Successful in 2s
Only copy Rust sources to reduce rebuilds if only nix stuff (or CI)
changed.
2024-06-16 14:14:41 +02:00
ee65b5dcac
[chore] lockfiles: update dependencies
All checks were successful
/ check (push) Successful in 2s
/ build (push) Successful in 55s
Update `Cargo.lock` and `flake.lock`. Flake updates:

```
• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/ad57eef4ef0659193044870c731987a6df5cf56b' (2024-05-29)
  → 'github:NixOS/nixpkgs/e9ee548d90ff586a6471b4ae80ae9cfcbceb3420' (2024-06-13)
```
2024-06-16 13:50:54 +02:00
a8fcc3bd4c
[feat] ci: add forgejo ci 2024-06-06 23:29:30 +02:00
bd5737e4f2
[chore] Cargo.toml: bump version to 0.3.0-dev 2024-06-02 16:16:06 +02:00
43f3c417da
[fix] module.nix: i love parenthesis /s 2024-06-02 16:15:14 +02:00
28 changed files with 2828 additions and 1033 deletions

View file

@ -1,2 +1,2 @@
[build]
rustflags = ["-Clink-arg=-fuse-ld=mold", "-Zthreads=16"]
rustflags = ["-Clink-arg=-fuse-ld=mold"]

14
.editorconfig Normal file
View file

@ -0,0 +1,14 @@
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
[*.{nix,toml,json}]
indent_style = space
indent_size = 2
[*.rs]
indent_style = space
indent_size = 4

View file

@ -0,0 +1,41 @@
on: [push]
jobs:
check-renovaterc:
runs-on: nixos
steps:
- uses: https://git.salame.cl/actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- name: Validate renovaterc
run: |
nix --version
nix shell nixpkgs#renovate --command renovate-config-validator
build:
runs-on: nixos
steps:
- uses: https://git.salame.cl/actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- name: Build Package
run: |
nix --version
nix build --print-build-logs .#
test:
needs: build # we use the built binaries in the checks
runs-on: nixos
steps:
- uses: https://git.salame.cl/actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- name: Run tests
run: |
nix --version
nix-fast-build --max-jobs 2 --no-nom --skip-cached --no-link \
--flake ".#checks.$(nix eval --raw --impure --expr builtins.currentSystem)"
report-size:
runs-on: nixos
needs: build
steps:
- uses: https://git.salame.cl/actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- run: nix --version
- name: Generate size report
uses: "https://git.salame.cl/jalil/nix-flake-outputs-size@5c40a31e3e2ed0ea28f8ba68deca41d05fdf2e71" # main
with:
comment-on-pr: ${{ github.ref_name != 'main' }}
generate-artifact: ${{ github.ref_name == 'main' }}
do-comparison: true
job-name: report-size

44
.renovaterc.json Normal file
View file

@ -0,0 +1,44 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"assignees": [
"jalil"
],
"automerge": true,
"automergeStrategy": "auto",
"automergeType": "pr",
"commitBodyTable": true,
"dependencyDashboard": true,
"extends": [
"config:best-practices"
],
"prCreation": "immediate",
"cargo": {
"commitMessageTopic": "Rust crate {{depName}}",
"fileMatch": [
"(^|/)Cargo\\.toml$"
],
"versioning": "cargo",
"enabled": true
},
"nix": {
"fileMatch": [
"(^|/)flake\\.nix$"
],
"commitMessageTopic": "nixpkgs",
"commitMessageExtra": "to {{newValue}}",
"enabled": true
},
"lockFileMaintenance": {
"enabled": true,
"recreateWhen": "always",
"rebaseWhen": "behind-base-branch",
"branchTopic": "lock-file-maintenance",
"commitMessageAction": "Lock file maintenance",
"schedule": [
"* 22 * * *"
]
},
"automergeSchedule": [
"* 23 * * *"
]
}

139
CHANGELOG.md Normal file
View file

@ -0,0 +1,139 @@
# Changelog
All notable changes to this project will be documented in this file.
## [0.3.6] - 2025-01-26
### 🚀 Features
- *(webnsupdate)* Allow running in IPv4/6 only mode
- *(module)* Add option for setting --ip-type
- *(flake)* Add tests for new allowedIPVersion option
## [0.3.5] - 2025-01-23
### 🚀 Features
- *(renovate)* Enable lockFileMaintenance
- *(webnsupdate)* Add handling for multiple IPs
- Tune compilation for size
- *(tests)* Add nginx integration test
### 🐛 Bug Fixes
- *(flake)* Switch to github ref
- *(renovate)* Switch automergeStrategy to auto
- *(ci)* Remove update workflow
- *(typos)* Typos caught more typos :3
- *(renovate)* Branch creation before automerge
- *(renovaterc)* Invalid cron syntax
- *(deps)* Update rust crate clap to v4.5.24
- *(deps)* Update rust crate tokio to v1.43.0
- *(deps)* Update rust crate clap to v4.5.25
- *(deps)* Update rust crate clap to v4.5.26
- *(flake)* Switch overlay to callPackage
- *(deps)* Update rust crate clap to v4.5.27
- *(deps)* Update rust crate axum to v0.8.2
- *(module)* Test both IPv4 and IPv6
### 🚜 Refactor
- Setup renovate to manage dependencies
### ⚙️ Miscellaneous Tasks
- Update to axum 0.8
- Parallelize checks
## [0.3.4] - 2024-12-26
### 🐛 Bug Fixes
- *(main)* Add more logging and default to info
## [0.3.3] - 2024-12-22
### 🚀 Features
- *(ci)* Generate package size report
- Add git-cliff to generate changelogs
### 🐛 Bug Fixes
- *(webnsupdate)* Reduce binary size
- *(ci)* Remove tea
### ⚙️ Miscellaneous Tasks
- *(flake.lock)* Update inputs
- Cargo update
- Generate base changelog
## [0.3.2] - 2024-11-23
### 🚀 Features
- *(ci)* Check depends on build
- Upgrade clap_verbosity_flag
- Replace axum-auth with tower_http
- Release new version
### 🐛 Bug Fixes
- *(clippy)* Enable more lints and fix issues
### 🚜 Refactor
- Reorganize main.rs
### ⚙️ Miscellaneous Tasks
- Cargo update
- Update flake inputs
## [0.3.1] - 2024-10-28
### 🐛 Bug Fixes
- Overlay was broken T-T
### ⚙️ Miscellaneous Tasks
- Next dev version
## [0.3.0] - 2024-10-28
### 🚀 Features
- *(ci)* Auto-update rust deps
- Refactor and add ip saving
- Add -v verbosity flag
- Use treefmt-nix and split up flake.nix
- Add NixOS VM tests
- Switch to crane
### 🐛 Bug Fixes
- *(fmt)* Use nixfmt-rfc-style
- *(default.nix)* Small issues here and there
- *(ci)* Do not use a name when logging in
### 🚜 Refactor
- *(flake)* Use flake-parts
### ⚙️ Miscellaneous Tasks
- Updarte deps
- *(flake.lock)* Update inputs
- Cargo update
- Cargo update
- Cargo update
## [0.2.0] - 2024-06-02
### 💼 Other
- Init at version 0.1.0
<!-- generated by git-cliff -->

675
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,31 +1,48 @@
cargo-features = ["codegen-backend"]
[package]
description = "An HTTP server using HTTP basic auth to make secure calls to nsupdate"
name = "webnsupdate"
version = "0.2.0"
version = "0.3.6"
edition = "2021"
license-file = "LICENSE"
readme = "README.md"
keywords = ["dns", "dyndns", "dynamic-ip"]
categories = ["networking", "dns", "dyndns"]
repository = "https://github.com/jalil-salame/webnsupdate"
[lints.clippy]
cargo = { level = "warn", priority = -2 }
multiple_crate_versions = "allow"
pedantic = { level = "warn", priority = -1 }
[dependencies]
axum = "0.7.5"
axum-client-ip = "0.6.0"
base64 = "0.22.1"
clap = { version = "4.5.4", features = ["derive", "env"] }
http = "1.1.0"
insta = "1.38.0"
miette = { version = "7.2.0", features = ["fancy"] }
ring = { version = "0.17.8", features = ["std"] }
tracing = "0.1.40"
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
axum = "0.8"
axum-client-ip = "1.0"
base64 = "0.22"
clap = { version = "4", features = ["derive", "env"] }
clap-verbosity-flag = { version = "3", default-features = false, features = [
"tracing",
] }
http = "1"
humantime = "2.2.0"
miette = { version = "7", features = ["fancy"] }
ring = { version = "0.17", features = ["std"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
thiserror = "2"
tokio = { version = "1", features = ["macros", "rt", "process", "io-util"] }
tower-http = { version = "0.6", features = ["validate-request"] }
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
[dependencies.axum-auth]
version = "0.7.0"
default-features = false
features = ["auth-basic"]
[dev-dependencies]
insta = { version = "=1.42.2", features = ["json"] }
[dependencies.tokio]
version = "1.37.0"
features = ["macros", "rt", "process", "io-util"]
[profile.release]
opt-level = "s"
panic = "abort"
lto = true
strip = true
codegen-units = 1
[profile.dev]
debug = 0
codegen-backend = "cranelift"

85
cliff.toml Normal file
View file

@ -0,0 +1,85 @@
# git-cliff ~ default configuration file
# https://git-cliff.org/docs/configuration
#
# Lines starting with "#" are comments.
# Configuration options are organized into tables and keys.
# See documentation for more information on available options.
[changelog]
# template for the changelog header
header = """
# Changelog\n
All notable changes to this project will be documented in this file.\n
"""
# template for the changelog body
# https://keats.github.io/tera/docs/#introduction
body = """
{% if version %}\
## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
{% else %}\
## [unreleased]
{% endif %}\
{% for group, commits in commits | group_by(attribute="group") %}
### {{ group | striptags | trim | upper_first }}
{% for commit in commits %}
- {% if commit.scope %}*({{ commit.scope }})* {% endif %}\
{% if commit.breaking %}[**breaking**] {% endif %}\
{{ commit.message | upper_first }}\
{% endfor %}
{% endfor %}\n
"""
# template for the changelog footer
footer = """
<!-- generated by git-cliff -->
"""
# remove the leading and trailing s
trim = true
# postprocessors
postprocessors = [
# { pattern = '<REPO>', replace = "https://github.com/orhun/git-cliff" }, # replace repository URL
]
# render body even when there are no releases to process
# render_always = true
# output file path
# output = "test.md"
[git]
# parse the commits based on https://www.conventionalcommits.org
conventional_commits = true
# filter out the commits that are not conventional
filter_unconventional = true
# process each line of a commit as an individual commit
split_commits = false
# regex for preprocessing the commit messages
commit_preprocessors = [
# Replace issue numbers
#{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](<REPO>/issues/${2}))"},
# Check spelling of the commit with https://github.com/crate-ci/typos
# If the spelling is incorrect, it will be automatically fixed.
#{ pattern = '.*', replace_command = 'typos --write-changes -' },
]
# regex for parsing and grouping commits
commit_parsers = [
{ message = "^feat", group = "<!-- 0 -->🚀 Features" },
{ message = "^fix", group = "<!-- 1 -->🐛 Bug Fixes" },
{ message = "^doc", group = "<!-- 3 -->📚 Documentation" },
{ message = "^perf", group = "<!-- 4 -->⚡ Performance" },
{ message = "^refactor", group = "<!-- 2 -->🚜 Refactor" },
{ message = "^style", group = "<!-- 5 -->🎨 Styling" },
{ message = "^test", group = "<!-- 6 -->🧪 Testing" },
{ message = "^chore\\(release\\): prepare for", skip = true },
{ message = "^chore\\(deps.*\\)", skip = true },
{ message = "^chore\\(pr\\)", skip = true },
{ message = "^chore\\(pull\\)", skip = true },
{ message = "^chore: bump version", skip = true },
{ message = "^chore|^ci", group = "<!-- 7 -->⚙️ Miscellaneous Tasks" },
{ body = ".*security", group = "<!-- 8 -->🛡️ Security" },
{ message = "^revert", group = "<!-- 9 -->◀️ Revert" },
{ message = ".*", group = "<!-- 10 -->💼 Other" },
]
# filter out the commits that are not matched by commit parsers
filter_commits = false
# sort the tags topologically
topo_order = false
# sort the commits inside sections by oldest/newest order
sort_commits = "oldest"

View file

@ -1,25 +1,37 @@
{
lib,
rustPlatform,
}: let
readToml = path: builtins.fromTOML (builtins.readFile path);
cargoToml = readToml ./Cargo.toml;
pname = cargoToml.package.name;
inherit (cargoToml.package) version description;
in
rustPlatform.buildRustPackage {
inherit pname version;
src = builtins.path {
path = ./.;
name = "${pname}-source";
};
cargoLock.lockFile = ./Cargo.lock;
useNextest = true;
pkgs ?
(builtins.getFlake (builtins.toString ./.)).inputs.nixpkgs.legacyPackages.${builtins.currentSystem},
lib ? pkgs.lib,
crane ? (builtins.getFlake (builtins.toString ./.)).inputs.crane,
pkgSrc ? ./.,
mold ? pkgs.mold,
}:
let
craneLib = crane.mkLib pkgs;
src = craneLib.cleanCargoSource pkgSrc;
commonArgs = {
inherit src;
strictDeps = true;
doCheck = false; # tests will be run in the `checks` derivation
NEXTEST_HIDE_PROGRESS_BAR = 1;
NEXTEST_FAILURE_OUTPUT = "immediate-final";
nativeBuildInputs = [ mold ];
meta = {
inherit description;
license = lib.licenses.mit;
homepage = "https://github.com/jalil-salame/webnsupdate";
mainProgram = "webnsupdate";
};
}
};
cargoArtifacts = craneLib.buildDepsOnly commonArgs;
in
craneLib.buildPackage (
lib.mergeAttrsList [
commonArgs
{ inherit cargoArtifacts; }
]
)

41
flake-modules/default.nix Normal file
View file

@ -0,0 +1,41 @@
{ inputs, ... }:
{
imports = [
inputs.treefmt-nix.flakeModule
./package.nix
./tests.nix
];
flake.nixosModules =
let
webnsupdate = ../module.nix;
in
{
default = webnsupdate;
inherit webnsupdate;
};
perSystem =
{ pkgs, ... }:
{
# Setup formatters
treefmt = {
projectRootFile = "flake.nix";
programs = {
nixfmt.enable = true;
rustfmt.enable = true;
statix.enable = true;
typos.enable = true;
};
};
devShells.default = pkgs.mkShellNoCC {
packages = with pkgs; [
cargo-insta
cargo-udeps
mold
git-cliff
];
};
};
}

60
flake-modules/package.nix Normal file
View file

@ -0,0 +1,60 @@
{ inputs, ... }:
{
flake.overlays.default = final: prev: {
webnsupdate = prev.callPackage ../default.nix {
inherit (inputs) crane;
pkgSrc = inputs.self;
};
};
perSystem =
{ pkgs, lib, ... }:
let
craneLib = inputs.crane.mkLib pkgs;
src = craneLib.cleanCargoSource inputs.self;
commonArgs = {
inherit src;
strictDeps = true;
doCheck = false; # tests will be run in the `checks` derivation
NEXTEST_HIDE_PROGRESS_BAR = 1;
NEXTEST_FAILURE_OUTPUT = "immediate-final";
nativeBuildInputs = [ pkgs.mold ];
meta = {
license = lib.licenses.mit;
homepage = "https://github.com/jalil-salame/webnsupdate";
mainProgram = "webnsupdate";
};
};
cargoArtifacts = craneLib.buildDepsOnly commonArgs;
withArtifacts = lib.mergeAttrsList [
commonArgs
{ inherit cargoArtifacts; }
];
webnsupdate = pkgs.callPackage ../default.nix {
inherit (inputs) crane;
pkgSrc = inputs.self;
};
in
{
checks = {
nextest = craneLib.cargoNextest withArtifacts;
clippy = craneLib.cargoClippy (
lib.mergeAttrsList [
withArtifacts
{ cargoClippyExtraArgs = "--all-targets -- --deny warnings"; }
]
);
};
packages = {
inherit webnsupdate;
inherit (pkgs) git-cliff;
default = webnsupdate;
};
};
}

343
flake-modules/tests.nix Normal file
View file

@ -0,0 +1,343 @@
{ self, ... }:
{
perSystem =
{ pkgs, self', ... }:
{
checks =
let
testDomain = "webnstest.example";
lastIPPath = "/var/lib/webnsupdate/last-ip.json";
zoneFile = pkgs.writeText "${testDomain}.zoneinfo" ''
$TTL 600 ; 10 minutes
$ORIGIN ${testDomain}.
@ IN SOA ns1.${testDomain}. admin.${testDomain}. (
1 ; serial
6h ; refresh
1h ; retry
1w ; expire
1d) ; negative caching TTL
IN NS ns1.${testDomain}.
@ IN A 127.0.0.1
ns1 IN A 127.0.0.1
nsupdate IN A 127.0.0.1
@ IN AAAA ::1
ns1 IN AAAA ::1
nsupdate IN AAAA ::1
'';
bindDynamicZone =
{ config, ... }:
let
bindCfg = config.services.bind;
bindData = bindCfg.directory;
dynamicZonesDir = "${bindData}/zones";
in
{
services.bind.zones.${testDomain} = {
master = true;
file = "${dynamicZonesDir}/${testDomain}";
extraConfig = ''
allow-update { key rndc-key; };
'';
};
systemd.services.bind.preStart = ''
# shellcheck disable=SC2211,SC1127
rm -f ${dynamicZonesDir}/* # reset dynamic zones
# create a dynamic zones dir
mkdir -m 0755 -p ${dynamicZonesDir}
# copy dynamic zone's file to the dynamic zones dir
cp ${zoneFile} ${dynamicZonesDir}/${testDomain}
'';
};
webnsupdate-ipv4-machine =
{ lib, ... }:
{
imports = [
bindDynamicZone
self.nixosModules.webnsupdate
];
config = {
environment.systemPackages = [
pkgs.dig
pkgs.curl
];
services = {
bind.enable = true;
webnsupdate = {
enable = true;
package = self'.packages.webnsupdate;
extraArgs = [ "-vvv" ]; # debug messages
settings = {
address = lib.mkDefault "127.0.0.1:5353";
key_file = "/etc/bind/rndc.key";
password_file = pkgs.writeText "webnsupdate.pass" "FQoNmuU1BKfg8qsU96F6bK5ykp2b0SLe3ZpB3nbtfZA"; # test:test
ip_source = lib.mkDefault "ConnectInfo";
records = [
"test1.${testDomain}."
"test2.${testDomain}."
"test3.${testDomain}."
];
};
};
};
};
};
webnsupdate-ipv6-machine = {
imports = [
webnsupdate-ipv4-machine
];
config.services.webnsupdate.settings.address = "[::1]:5353";
};
webnsupdate-nginx-machine =
{ lib, config, ... }:
{
imports = [
webnsupdate-ipv4-machine
];
config.services = {
# Use default IP Source
webnsupdate.settings.ip_source = "RightmostXForwardedFor";
nginx = {
enable = true;
recommendedProxySettings = true;
virtualHosts.webnsupdate.locations."/".proxyPass =
"http://${config.services.webnsupdate.settings.address}";
};
};
};
webnsupdate-ipv4-only-machine = {
imports = [ webnsupdate-nginx-machine ];
config.services.webnsupdate.settings.ip_type = "Ipv4Only";
};
webnsupdate-ipv6-only-machine = {
imports = [ webnsupdate-nginx-machine ];
config.services.webnsupdate.settings.ip_type = "Ipv6Only";
};
# "A" for IPv4, "AAAA" for IPv6, "ANY" for any
testTemplate =
{
ipv4 ? false,
ipv6 ? false,
nginx ? false,
exclusive ? false,
}:
if exclusive && (ipv4 == ipv6) then
builtins.throw "exclusive means one of ipv4 or ipv6 must be set, but not both"
else
''
IPV4: bool = ${if ipv4 then "True" else "False"}
IPV6: bool = ${if ipv6 then "True" else "False"}
NGINX: bool = ${if nginx then "True" else "False"}
EXCLUSIVE: bool = ${if exclusive then "True" else "False"}
print(f"{IPV4=} {IPV6=} {EXCLUSIVE=}")
CURL: str = "curl --fail --no-progress-meter --show-error"
machine.start(allow_reboot=True)
machine.wait_for_unit("bind.service")
machine.wait_for_unit("webnsupdate.service")
STATIC_DOMAINS: list[str] = ["${testDomain}", "ns1.${testDomain}", "nsupdate.${testDomain}"]
DYNAMIC_DOMAINS: list[str] = ["test1.${testDomain}", "test2.${testDomain}", "test3.${testDomain}"]
def dig_cmd(domain: str, record: str, ip: str | None) -> tuple[str, str]:
match_ip = "" if ip is None else f"\\s\\+600\\s\\+IN\\s\\+{record}\\s\\+{ip}$"
return f"dig @localhost {record} {domain} +noall +answer", f"grep '^{domain}.{match_ip}'"
def curl_cmd(domain: str, identity: str, path: str, query: dict[str, str]) -> str:
from urllib.parse import urlencode
q= f"?{urlencode(query)}" if query else ""
return f"{CURL} -u {identity} -X GET 'http://{domain}{"" if NGINX else ":5353"}/{path}{q}'"
def domain_available(domain: str, record: str, ip: str | None=None):
dig, grep = dig_cmd(domain, record, ip)
rc, output = machine.execute(dig)
print(f"{dig}[{rc}]: {output}")
machine.succeed(f"{dig} | {grep}")
def domain_missing(domain: str, record: str, ip: str | None=None):
dig, grep = dig_cmd(domain, record, ip)
rc, output = machine.execute(dig)
print(f"{dig}[{rc}]: {output}")
machine.fail(f"{dig} | {grep}")
def update_records(domain: str="localhost", /, *, path: str="update", **kwargs):
machine.succeed(curl_cmd(domain, "test:test", path, kwargs))
machine.succeed("cat ${lastIPPath}")
def update_records_fail(domain: str="localhost", /, *, identity: str="test:test", path: str="update", **kwargs):
machine.fail(curl_cmd(domain, identity, path, kwargs))
machine.fail("cat ${lastIPPath}")
def invalid_update(domain: str="localhost"):
update_records_fail(domain, identity="bad_user:test")
update_records_fail(domain, identity="test:bad_pass")
# Tests
with subtest("static DNS records are available"):
print(f"{IPV4=} {IPV6=} {EXCLUSIVE=}")
for domain in STATIC_DOMAINS:
domain_available(domain, "A", "127.0.0.1") # IPv4
domain_available(domain, "AAAA", "::1") # IPv6
with subtest("dynamic DNS records are missing"):
print(f"{IPV4=} {IPV6=} {EXCLUSIVE=}")
for domain in DYNAMIC_DOMAINS:
domain_missing(domain, "A") # IPv4
domain_missing(domain, "AAAA") # IPv6
with subtest("invalid auth fails to update records"):
print(f"{IPV4=} {IPV6=} {EXCLUSIVE=}")
invalid_update()
for domain in DYNAMIC_DOMAINS:
domain_missing(domain, "A") # IPv4
domain_missing(domain, "AAAA") # IPv6
if EXCLUSIVE:
with subtest("exclusive IP version fails to update with invalid version"):
print(f"{IPV4=} {IPV6=} {EXCLUSIVE=}")
if IPV6:
update_records_fail("127.0.0.1")
if IPV4:
update_records_fail("[::1]")
with subtest("valid auth updates records"):
print(f"{IPV4=} {IPV6=} {EXCLUSIVE=}")
if IPV4:
update_records("127.0.0.1")
if IPV6:
update_records("[::1]")
for domain in DYNAMIC_DOMAINS:
if IPV4:
domain_available(domain, "A", "127.0.0.1")
elif IPV6 and EXCLUSIVE:
domain_missing(domain, "A")
if IPV6:
domain_available(domain, "AAAA", "::1")
elif IPV4 and EXCLUSIVE:
domain_missing(domain, "AAAA")
with subtest("valid auth fritzbox compatible updates records"):
print(f"{IPV4=} {IPV6=} {EXCLUSIVE=}")
if IPV4 and IPV6:
update_records("127.0.0.1", domain="test", ipv4="1.2.3.4", ipv6="::1234")
elif IPV4:
update_records("127.0.0.1", ipv4="1.2.3.4", ipv6="")
elif IPV6:
update_records("[::1]", ipv4="", ipv6="::1234")
for domain in DYNAMIC_DOMAINS:
if IPV4:
domain_available(domain, "A", "1.2.3.4")
elif IPV6 and EXCLUSIVE:
domain_missing(domain, "A")
if IPV6:
domain_available(domain, "AAAA", "::1234")
elif IPV4 and EXCLUSIVE:
domain_missing(domain, "AAAA")
with subtest("valid auth replaces records"):
print(f"{IPV4=} {IPV6=} {EXCLUSIVE=}")
if IPV4:
update_records("127.0.0.1")
if IPV6:
update_records("[::1]")
for domain in DYNAMIC_DOMAINS:
if IPV4:
domain_available(domain, "A", "127.0.0.1")
elif IPV6 and EXCLUSIVE:
domain_missing(domain, "A")
if IPV6:
domain_available(domain, "AAAA", "::1")
elif IPV4 and EXCLUSIVE:
domain_missing(domain, "AAAA")
machine.reboot()
machine.succeed("cat ${lastIPPath}")
machine.wait_for_unit("webnsupdate.service")
machine.succeed("cat ${lastIPPath}")
with subtest("static DNS records are available after reboot"):
print(f"{IPV4=} {IPV6=} {EXCLUSIVE=}")
for domain in STATIC_DOMAINS:
domain_available(domain, "A", "127.0.0.1") # IPv4
domain_available(domain, "AAAA", "::1") # IPv6
with subtest("dynamic DNS records are available after reboot"):
print(f"{IPV4=} {IPV6=} {EXCLUSIVE=}")
for domain in DYNAMIC_DOMAINS:
if IPV4:
domain_available(domain, "A", "127.0.0.1")
elif IPV6 and EXCLUSIVE:
domain_missing(domain, "A")
if IPV6:
domain_available(domain, "AAAA", "::1")
elif IPV4 and EXCLUSIVE:
domain_missing(domain, "AAAA")
'';
in
{
module-ipv4-test = pkgs.testers.nixosTest {
name = "webnsupdate-ipv4-module";
nodes.machine = webnsupdate-ipv4-machine;
testScript = testTemplate { ipv4 = true; };
};
module-ipv6-test = pkgs.testers.nixosTest {
name = "webnsupdate-ipv6-module";
nodes.machine = webnsupdate-ipv6-machine;
testScript = testTemplate { ipv6 = true; };
};
module-nginx-test = pkgs.testers.nixosTest {
name = "webnsupdate-nginx-module";
nodes.machine = webnsupdate-nginx-machine;
testScript = testTemplate {
ipv4 = true;
ipv6 = true;
nginx = true;
};
};
module-ipv4-only-test = pkgs.testers.nixosTest {
name = "webnsupdate-ipv4-only-module";
nodes.machine = webnsupdate-ipv4-only-machine;
testScript = testTemplate {
ipv4 = true;
nginx = true;
exclusive = true;
};
};
module-ipv6-only-test = pkgs.testers.nixosTest {
name = "webnsupdate-ipv6-only-module";
nodes.machine = webnsupdate-ipv6-only-machine;
testScript = testTemplate {
ipv6 = true;
nginx = true;
exclusive = true;
};
};
};
};
}

77
flake.lock generated
View file

@ -1,24 +1,63 @@
{
"nodes": {
"nixpkgs": {
"crane": {
"locked": {
"lastModified": 1716948383,
"narHash": "sha256-SzDKxseEcHR5KzPXLwsemyTR/kaM9whxeiJohbL04rs=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "ad57eef4ef0659193044870c731987a6df5cf56b",
"lastModified": 1743700120,
"narHash": "sha256-8BjG/P0xnuCyVOXlYRwdI1B8nVtyYLf3oDwPSimqREY=",
"owner": "ipetkov",
"repo": "crane",
"rev": "e316f19ee058e6db50075115783be57ac549c389",
"type": "github"
},
"original": {
"id": "nixpkgs",
"owner": "ipetkov",
"repo": "crane",
"type": "github"
}
},
"flake-parts": {
"inputs": {
"nixpkgs-lib": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1743550720,
"narHash": "sha256-hIshGgKZCgWh6AYJpJmRgFdR3WUbkY04o82X05xqQiY=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "c621e8422220273271f52058f618c94e405bb0f5",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1743583204,
"narHash": "sha256-F7n4+KOIfWrwoQjXrL2wD9RhFYLs2/GGe/MQY1sSdlE=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "2c8d3f48d33929642c1c12cd243df4cc7d2ce434",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"type": "indirect"
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"crane": "crane",
"flake-parts": "flake-parts",
"nixpkgs": "nixpkgs",
"systems": "systems"
"systems": "systems",
"treefmt-nix": "treefmt-nix"
}
},
"systems": {
@ -35,6 +74,26 @@
"repo": "default",
"type": "github"
}
},
"treefmt-nix": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1743677901,
"narHash": "sha256-eWZln+k+L/VHO69tUTzEmgeDWNQNKIpSUa9nqQgBrSE=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "57dabe2a6255bd6165b2437ff6c2d1f6ee78421a",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
}
}
},
"root": "root",

View file

@ -1,39 +1,23 @@
{
description = "An http server that calls nsupdate internally";
inputs = {
nixpkgs.url = "nixpkgs/nixos-unstable";
systems.url = "github:nix-systems/default";
};
outputs = {
self,
nixpkgs,
systems,
}: let
forEachSupportedSystem = nixpkgs.lib.genAttrs (import systems);
in {
formatter = forEachSupportedSystem (system: nixpkgs.legacyPackages.${system}.alejandra);
packages = forEachSupportedSystem (system: {
default = nixpkgs.legacyPackages.${system}.callPackage ./default.nix {};
});
overlays.default = final: prev: {
webnsupdate = final.callPackage ./default.nix {};
crane.url = "github:ipetkov/crane";
flake-parts = {
url = "github:hercules-ci/flake-parts";
inputs.nixpkgs-lib.follows = "nixpkgs";
};
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
systems.url = "github:nix-systems/default";
treefmt-nix = {
url = "github:numtide/treefmt-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
nixosModules.default = ./module.nix;
devShells = forEachSupportedSystem (system: let
pkgs = nixpkgs.legacyPackages.${system};
in {
default = pkgs.mkShell {
packages = [
pkgs.cargo-insta
pkgs.cargo-udeps
pkgs.mold
];
};
});
};
outputs =
inputs:
inputs.flake-parts.lib.mkFlake { inherit inputs; } {
imports = [ ./flake-modules ];
systems = import inputs.systems;
};
}

2
justfile Normal file
View file

@ -0,0 +1,2 @@
changelog version:
git cliff --unreleased --prepend=CHANGELOG.md --tag='{{ version }}'

View file

@ -1,15 +1,18 @@
{ lib, pkgs, ... }@args:
let
cfg = args.config.services.webnsupdate;
inherit (lib)
mkOption
mkEnableOption
mkPackageOption
types
;
format = pkgs.formats.json { };
in
{
lib,
pkgs,
config,
...
}: let
cfg = config.services.webnsupdate;
inherit (lib) mkOption mkEnableOption types;
in {
options.services.webnsupdate = mkOption {
description = "An HTTP server for nsupdate.";
default = {};
default = { };
type = types.submodule {
options = {
enable = mkEnableOption "webnsupdate";
@ -18,75 +21,79 @@ in {
Extra arguments to be passed to the webnsupdate server command.
'';
type = types.listOf types.str;
default = [];
example = ["--ip-source"];
default = [ ];
example = [ "--ip-source" ];
};
bindIp = mkOption {
description = ''
IP address to bind to.
package = mkPackageOption pkgs "webnsupdate" { };
settings = mkOption {
description = "The webnsupdate JSON configuration";
default = { };
type = types.submodule {
freeformType = format.type;
options = {
address = mkOption {
description = ''
IP address and port to bind to.
Setting it to anything other than localhost is very insecure as
`webnsupdate` only supports plain HTTP and should always be behind a
reverse proxy.
'';
type = types.str;
default = "localhost";
example = "0.0.0.0";
};
bindPort = mkOption {
description = "Port to bind to.";
type = types.port;
default = 5353;
};
passwordFile = mkOption {
description = ''
The file where the password is stored.
Setting it to anything other than localhost is very
insecure as `webnsupdate` only supports plain HTTP and
should always be behind a reverse proxy.
'';
type = types.str;
default = "127.0.0.1:5353";
example = "[::1]:5353";
};
ip_type = mkOption {
description = ''The allowed IP versions to accept updates from.'';
type = types.enum [
"Both"
"Ipv4Only"
"Ipv6Only"
];
default = "Both";
example = "Ipv4Only";
};
password_file = mkOption {
description = ''
The file where the password is stored.
This file can be created by running `webnsupdate mkpasswd $USERNAME $PASSWORD`.
'';
type = types.path;
example = "/secrets/webnsupdate.pass";
};
keyFile = mkOption {
description = ''
The TSIG key that `nsupdate` should use.
This file can be created by running `webnsupdate mkpasswd $USERNAME $PASSWORD`.
'';
type = types.path;
example = "/secrets/webnsupdate.pass";
};
key_file = mkOption {
description = ''
The TSIG key that `nsupdate` should use.
This file will be passed to `nsupdate` through the `-k` option, so look
at `man 8 nsupdate` for information on the key's format.
'';
type = types.path;
example = "/secrets/webnsupdate.key";
};
ttl = mkOption {
description = "The TTL that should be set on the zone records created by `nsupdate`.";
type = types.ints.positive;
default = 60;
example = 3600;
};
records = mkOption {
description = ''
The fqdn of records that should be updated.
This file will be passed to `nsupdate` through the `-k` option, so look
at `man 8 nsupdate` for information on the key's format.
'';
type = types.path;
example = "/secrets/webnsupdate.key";
};
ttl = mkOption {
description = "The TTL that should be set on the zone records created by `nsupdate`.";
default = "10m";
example = "60s";
type = types.str;
};
records = mkOption {
description = ''
The fqdn of records that should be updated.
Empty lines will be ignored, but whitespace will not be.
'';
type = types.nullOr types.lines;
default = null;
example = ''
example.com.
example.org.
ci.example.org.
'';
};
recordsFile = mkOption {
description = ''
The fqdn of records that should be updated.
Empty lines will be ignored, but whitespace will not be.
'';
type = types.nullOr types.path;
default = null;
example = "/secrets/webnsupdate.records";
Empty lines will be ignored, but whitespace will not be.
'';
type = types.listOf types.str;
default = [ ];
example = [
"example.com."
"example.org."
"ci.example.org."
];
};
};
};
};
user = mkOption {
description = "The user to run as.";
@ -102,46 +109,30 @@ in {
};
};
config = let
recordsFile =
if cfg.recordsFile != null
then cfg.recordsFile
else pkgs.writeText "webnsrecords" cfg.records;
args = lib.strings.escapeShellArgs [
"--records"
recordsFile
"--key-file"
cfg.keyFile
"--password-file"
cfg.passwordFile
"--address"
cfg.bindIp
"--port"
(builtins.toString cfg.bindPort)
"--ttl"
(builtins.toString cfg.ttl)
] ++ cfg.extraArgs;
cmd = "${lib.getExe pkgs.webnsupdate} ${args}";
in
config =
let
configFile = format.generate "webnsupdate.json" cfg.settings;
args = lib.strings.escapeShellArgs ([ "--config=${configFile}" ] ++ cfg.extraArgs);
cmd = "${lib.getExe cfg.package} ${args}";
in
lib.mkIf cfg.enable {
# FIXME: re-enable once I stop using the patched version of bind
# warnings =
# lib.optional (!config.services.bind.enable) "`webnsupdate` is expected to be used alongside `bind`. This is an unsopported configuration.";
assertions = [
{
assertion = (cfg.records != null || cfg.recordsFile != null) && !(cfg.records != null && cfg.recordsFile != null);
message = "Exactly one of `services.webnsupdate.records` and `services.webnsupdate.recordsFile` must be set.";
}
];
# lib.optional (!config.services.bind.enable) "`webnsupdate` is expected to be used alongside `bind`. This is an unsupported configuration.";
systemd.services.webnsupdate = {
description = "Web interface for nsupdate.";
wantedBy = ["multi-user.target"];
after = ["network.target" "bind.service"];
preStart = "${cmd} verify";
path = [pkgs.dig];
wantedBy = [ "multi-user.target" ];
after = [
"network.target"
"bind.service"
];
preStart = "${lib.getExe cfg.package} verify ${configFile}";
path = [ pkgs.dig ];
startLimitIntervalSec = 60;
environment.DATA_DIR = "%S/webnsupdate";
serviceConfig = {
ExecStart = [cmd];
ExecStart = [ cmd ];
Type = "exec";
Restart = "on-failure";
RestartSec = "10s";
@ -157,6 +148,9 @@ in {
# Logs directory and mode
LogsDirectory = "webnsupdate";
LogsDirectoryMode = "0750";
# State directory and mode
StateDirectory = "webnsupdate";
StateDirectoryMode = "0750";
# New file permissions
UMask = "0027";
# Security

104
src/auth.rs Normal file
View file

@ -0,0 +1,104 @@
use base64::engine::general_purpose::URL_SAFE_NO_PAD;
use base64::Engine;
use tower_http::validate_request::ValidateRequestHeaderLayer;
use tracing::{trace, warn};
use crate::password;
pub fn layer<'a, ResBody>(
user_pass_hash: &'a [u8],
salt: &'a str,
) -> ValidateRequestHeaderLayer<Basic<'a, ResBody>> {
ValidateRequestHeaderLayer::custom(Basic::new(user_pass_hash, salt))
}
#[derive(Copy)]
pub struct Basic<'a, ResBody> {
pass: &'a [u8],
salt: &'a str,
_ty: std::marker::PhantomData<fn() -> ResBody>,
}
impl<ResBody> std::fmt::Debug for Basic<'_, ResBody> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("BasicAuth")
.field("pass", &self.pass)
.field("salt", &self.salt)
.field("_ty", &self._ty)
.finish()
}
}
impl<ResBody> Clone for Basic<'_, ResBody> {
fn clone(&self) -> Self {
Self {
pass: self.pass,
salt: self.salt,
_ty: std::marker::PhantomData,
}
}
}
impl<'a, ResBody> Basic<'a, ResBody> {
pub fn new(pass: &'a [u8], salt: &'a str) -> Self {
Self {
pass,
salt,
_ty: std::marker::PhantomData,
}
}
fn check_headers(&self, headers: &http::HeaderMap<http::HeaderValue>) -> bool {
let Some(auth) = headers.get(http::header::AUTHORIZATION) else {
return false;
};
// Poor man's split once: https://doc.rust-lang.org/std/primitive.slice.html#method.split_once
let Some(index) = auth.as_bytes().iter().position(|&c| c == b' ') else {
return false;
};
let user_pass = &auth.as_bytes()[index + 1..];
match base64::engine::general_purpose::URL_SAFE.decode(user_pass) {
Ok(user_pass) => {
let hashed = password::hash_basic_auth(&user_pass, self.salt);
if hashed.as_ref() == self.pass {
return true;
}
warn!("rejected update");
trace!(
"mismatched hashes:\nprovided: {}\nstored: {}",
URL_SAFE_NO_PAD.encode(hashed.as_ref()),
URL_SAFE_NO_PAD.encode(self.pass),
);
false
}
Err(err) => {
warn!("received invalid base64 when decoding Basic header: {err}");
false
}
}
}
}
impl<B, ResBody> tower_http::validate_request::ValidateRequest<B> for Basic<'_, ResBody>
where
ResBody: Default,
{
type ResponseBody = ResBody;
fn validate(
&mut self,
request: &mut http::Request<B>,
) -> std::result::Result<(), http::Response<Self::ResponseBody>> {
if self.check_headers(request.headers()) {
return Ok(());
}
let mut res = http::Response::new(ResBody::default());
*res.status_mut() = http::status::StatusCode::UNAUTHORIZED;
res.headers_mut()
.insert(http::header::WWW_AUTHENTICATE, "Basic".parse().unwrap());
Err(res)
}
}

253
src/config.rs Normal file
View file

@ -0,0 +1,253 @@
use std::{
fs::File,
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr},
path::PathBuf,
};
use axum_client_ip::ClientIpSource;
use miette::{Context, IntoDiagnostic};
#[derive(Debug, Default, Clone, Copy, serde::Deserialize, serde::Serialize)]
pub enum IpType {
#[default]
Both,
Ipv4Only,
Ipv6Only,
}
impl IpType {
pub fn valid_for_type(self, ip: IpAddr) -> bool {
match self {
IpType::Both => true,
IpType::Ipv4Only => ip.is_ipv4(),
IpType::Ipv6Only => ip.is_ipv6(),
}
}
}
impl std::fmt::Display for IpType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
IpType::Both => f.write_str("both"),
IpType::Ipv4Only => f.write_str("ipv4-only"),
IpType::Ipv6Only => f.write_str("ipv6-only"),
}
}
}
impl std::str::FromStr for IpType {
type Err = miette::Error;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
match s {
"both" => Ok(Self::Both),
"ipv4-only" => Ok(Self::Ipv4Only),
"ipv6-only" => Ok(Self::Ipv6Only),
_ => miette::bail!("expected one of 'ipv4-only', 'ipv6-only' or 'both', got '{s}'"),
}
}
}
/// Webserver settings
#[derive(Debug, serde::Deserialize, serde::Serialize)]
pub struct Server {
/// Ip address and port of the server
#[serde(default = "default_address")]
pub address: SocketAddr,
}
/// Password settings
#[derive(Debug, serde::Deserialize, serde::Serialize)]
pub struct Password {
/// File containing password to match against
///
/// Should be of the format `username:password` and contain a single password
#[serde(default, skip_serializing_if = "Option::is_none")]
pub password_file: Option<PathBuf>,
/// Salt to get more unique hashed passwords and prevent table based attacks
#[serde(default = "default_salt")]
pub salt: Box<str>,
}
/// Records settings
#[derive(Debug, serde::Deserialize, serde::Serialize)]
pub struct Records {
/// Time To Live (in seconds) to set on the DNS records
#[serde(
default = "default_ttl",
serialize_with = "humantime_ser",
deserialize_with = "humantime_de"
)]
pub ttl: humantime::Duration,
/// List of domain names for which to update the IP when an update is requested
#[serde(default, skip_serializing_if = "Vec::is_empty")]
#[allow(clippy::struct_field_names)]
pub records: Vec<Box<str>>,
/// If provided, when an IPv6 prefix is provided with an update, this will be used to derive
/// the full IPv6 address of the client
#[serde(default, skip_serializing_if = "Option::is_none")]
pub client_id: Option<Ipv6Addr>,
/// If a client id is provided the ipv6 update will be ignored (only the prefix will be used).
/// This domain will point to the ipv6 address instead of the address derived from the client
/// id (usually this is the router).
#[serde(default, skip_serializing_if = "Option::is_none")]
pub router_domain: Option<Box<str>>,
/// Set client IP source
///
/// see: <https://docs.rs/axum-client-ip/latest/axum_client_ip/enum.ClientIpSource.html>
#[serde(default = "default_ip_source")]
pub ip_source: ClientIpSource,
/// Set which IPs to allow updating (ipv4, ipv6 or both)
#[serde(default = "default_ip_type")]
pub ip_type: IpType,
/// Keyfile `nsupdate` should use
///
/// If specified, then `webnsupdate` must have read access to the file
#[serde(default, skip_serializing_if = "Option::is_none")]
pub key_file: Option<PathBuf>,
}
#[derive(Debug, serde::Deserialize, serde::Serialize)]
pub struct Config {
/// Server Configuration
#[serde(flatten)]
pub server: Server,
/// Password Configuration
#[serde(flatten)]
pub password: Password,
/// Records Configuration
#[serde(flatten)]
pub records: Records,
/// The config schema (used for lsp completions)
#[serde(default, rename = "$schema", skip_serializing)]
pub _schema: serde::de::IgnoredAny,
}
impl Config {
/// Load the configuration without verifying it
pub fn load(path: &std::path::Path) -> miette::Result<Self> {
serde_json::from_reader::<File, Self>(
File::open(path)
.into_diagnostic()
.wrap_err_with(|| format!("failed open {}", path.display()))?,
)
.into_diagnostic()
.wrap_err_with(|| format!("failed to load configuration from {}", path.display()))
}
/// Ensure only a verified configuration is returned
pub fn verified(self) -> miette::Result<Self> {
self.verify()?;
Ok(self)
}
/// Verify the configuration
pub fn verify(&self) -> Result<(), Invalid> {
let mut invalid_records: Vec<miette::Error> = self
.records
.records
.iter()
.filter_map(|record| crate::records::validate_record_str(record).err())
.collect();
invalid_records.extend(
self.records
.router_domain
.as_ref()
.and_then(|domain| crate::records::validate_record_str(domain).err()),
);
let err = Invalid { invalid_records };
if err.invalid_records.is_empty() {
Ok(())
} else {
Err(err)
}
}
}
#[derive(Debug, miette::Diagnostic, thiserror::Error)]
#[error("the configuration was invalid")]
pub struct Invalid {
#[related]
pub invalid_records: Vec<miette::Error>,
}
// --- Default Values (sadly serde doesn't have a way to specify a constant as a default value) ---
fn default_ttl() -> humantime::Duration {
super::DEFAULT_TTL.into()
}
fn default_salt() -> Box<str> {
super::DEFAULT_SALT.into()
}
fn default_address() -> SocketAddr {
SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 5353)
}
fn default_ip_source() -> ClientIpSource {
ClientIpSource::RightmostXForwardedFor
}
fn default_ip_type() -> IpType {
IpType::Both
}
fn humantime_de<'de, D>(de: D) -> Result<humantime::Duration, D::Error>
where
D: serde::Deserializer<'de>,
{
struct Visitor;
impl serde::de::Visitor<'_> for Visitor {
type Value = humantime::Duration;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(formatter, "a duration (e.g. 5s)")
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
v.parse().map_err(E::custom)
}
}
de.deserialize_str(Visitor)
}
fn humantime_ser<S>(duration: &humantime::Duration, ser: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
ser.serialize_str(&duration.to_string())
}
#[test]
fn default_values_config_snapshot() {
let config: Config = serde_json::from_str("{}").unwrap();
insta::assert_json_snapshot!(config, @r#"
{
"address": "127.0.0.1:5353",
"salt": "UpdateMyDNS",
"ttl": {
"secs": 60,
"nanos": 0
},
"ip_source": "RightmostXForwardedFor",
"ip_type": "Both"
}
"#);
}

File diff suppressed because it is too large Load diff

156
src/nsupdate.rs Normal file
View file

@ -0,0 +1,156 @@
use std::{
ffi::OsStr,
net::IpAddr,
path::Path,
process::{ExitStatus, Stdio},
time::Duration,
};
use tokio::io::AsyncWriteExt;
use tracing::{debug, warn};
pub enum Action<'a> {
// Reassign a domain to a different IP
Reassign {
domain: &'a str,
to: IpAddr,
ttl: Duration,
},
}
impl<'a> Action<'a> {
/// Create a set of [`Action`]s reassigning the domains in `records` to the specified
/// [`IpAddr`]
pub fn from_records(
to: IpAddr,
ttl: Duration,
records: &'a [&'a str],
) -> impl IntoIterator<Item = Self> + std::iter::ExactSizeIterator + 'a {
records
.iter()
.map(move |&domain| Action::Reassign { domain, to, ttl })
}
}
impl std::fmt::Display for Action<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Action::Reassign { domain, to, ttl } => {
let ttl = ttl.as_secs();
let kind = match to {
IpAddr::V4(_) => "A",
IpAddr::V6(_) => "AAAA",
};
// Delete previous record of type `kind`
writeln!(f, "update delete {domain} {ttl} IN {kind}")?;
// Add record with new IP
writeln!(f, "update add {domain} {ttl} IN {kind} {to}")
}
}
}
}
#[tracing::instrument(level = "trace", skip(actions), ret(level = "warn"))]
pub async fn nsupdate(
key_file: Option<&Path>,
actions: impl IntoIterator<Item = Action<'_>>,
) -> std::io::Result<ExitStatus> {
let mut cmd = tokio::process::Command::new("nsupdate");
if let Some(key_file) = key_file {
cmd.args([OsStr::new("-k"), key_file.as_os_str()]);
}
debug!("spawning new process");
let mut child = cmd
.stdin(Stdio::piped())
.spawn()
.inspect_err(|err| warn!("failed to spawn child: {err}"))?;
let mut stdin = child.stdin.take().expect("stdin not present");
debug!("sending update request");
let mut buf = Vec::new();
update_ns_records(&mut buf, actions).unwrap();
stdin
.write_all(&buf)
.await
.inspect_err(|err| warn!("failed to write to the stdin of nsupdate: {err}"))?;
debug!("closing stdin");
stdin
.shutdown()
.await
.inspect_err(|err| warn!("failed to close stdin to nsupdate: {err}"))?;
debug!("waiting for nsupdate to exit");
child
.wait()
.await
.inspect_err(|err| warn!("failed to wait for child: {err}"))
}
fn update_ns_records<'a>(
mut buf: impl std::io::Write,
actions: impl IntoIterator<Item = Action<'a>>,
) -> std::io::Result<()> {
writeln!(buf, "server 127.0.0.1")?;
for action in actions {
write!(buf, "{action}")?;
}
writeln!(buf, "send")?;
writeln!(buf, "quit")
}
#[cfg(test)]
mod test {
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use insta::assert_snapshot;
use super::{update_ns_records, Action};
use crate::DEFAULT_TTL;
#[test]
#[allow(non_snake_case)]
fn expected_update_string_A() {
let mut buf = Vec::new();
let actions = Action::from_records(
IpAddr::V4(Ipv4Addr::LOCALHOST),
DEFAULT_TTL,
&["example.com.", "example.org.", "example.net."],
);
update_ns_records(&mut buf, actions).unwrap();
assert_snapshot!(String::from_utf8(buf).unwrap(), @r###"
server 127.0.0.1
update delete example.com. 60 IN A
update add example.com. 60 IN A 127.0.0.1
update delete example.org. 60 IN A
update add example.org. 60 IN A 127.0.0.1
update delete example.net. 60 IN A
update add example.net. 60 IN A 127.0.0.1
send
quit
"###);
}
#[test]
#[allow(non_snake_case)]
fn expected_update_string_AAAA() {
let mut buf = Vec::new();
let actions = Action::from_records(
IpAddr::V6(Ipv6Addr::LOCALHOST),
DEFAULT_TTL,
&["example.com.", "example.org.", "example.net."],
);
update_ns_records(&mut buf, actions).unwrap();
assert_snapshot!(String::from_utf8(buf).unwrap(), @r###"
server 127.0.0.1
update delete example.com. 60 IN AAAA
update add example.com. 60 IN AAAA ::1
update delete example.org. 60 IN AAAA
update add example.org. 60 IN AAAA ::1
update delete example.net. 60 IN AAAA
update add example.net. 60 IN AAAA ::1
send
quit
"###);
}
}

80
src/password.rs Normal file
View file

@ -0,0 +1,80 @@
//! Make a password for use with webnsupdate
//!
//! You should call this command an give it's output to the app/script that will update the DNS
//! records
use std::io::Write;
use std::os::unix::fs::OpenOptionsExt;
use std::path::PathBuf;
use base64::prelude::*;
use miette::{Context, IntoDiagnostic, Result};
use ring::digest::Digest;
/// Create a password file
///
/// If `--password-file` is provided, the password is written to that file
#[derive(Debug, clap::Args)]
pub struct Mkpasswd {
/// The username
username: String,
/// The password
password: String,
/// An application specific value
#[arg(long, default_value = crate::DEFAULT_SALT)]
salt: String,
/// The file to write the password to
password_file: Option<PathBuf>,
}
impl Mkpasswd {
pub fn process(self, _args: &crate::Opts) -> Result<()> {
mkpasswd(self)
}
}
pub fn hash_basic_auth(user_pass: &[u8], salt: &str) -> Digest {
let mut context = ring::digest::Context::new(&ring::digest::SHA256);
context.update(user_pass);
context.update(salt.as_bytes());
context.finish()
}
pub fn hash_identity(username: &str, password: &str, salt: &str) -> Digest {
let mut context = ring::digest::Context::new(&ring::digest::SHA256);
context.update(username.as_bytes());
context.update(b":");
context.update(password.as_bytes());
context.update(salt.as_bytes());
context.finish()
}
pub fn mkpasswd(
Mkpasswd {
username,
password,
salt,
password_file,
}: Mkpasswd,
) -> miette::Result<()> {
let hash = hash_identity(&username, &password, &salt);
let encoded = BASE64_URL_SAFE_NO_PAD.encode(hash.as_ref());
let Some(path) = password_file.as_deref() else {
println!("{encoded}");
return Ok(());
};
let err = || format!("trying to save password hash to {}", path.display());
std::fs::File::options()
.mode(0o600)
.create_new(true)
.open(path)
.into_diagnostic()
.wrap_err_with(err)?
.write_all(encoded.as_bytes())
.into_diagnostic()
.wrap_err_with(err)?;
Ok(())
}

187
src/records.rs Normal file
View file

@ -0,0 +1,187 @@
//! Deal with the DNS records
use miette::{ensure, miette, LabeledSpan, Result};
pub fn validate_record_str(record: &str) -> Result<()> {
validate_line(0, record).map_err(|err| err.with_source_code(String::from(record)))
}
fn validate_line(offset: usize, line: &str) -> Result<()> {
if line.is_empty() {
return Ok(());
}
ensure!(
line.len() <= 255,
miette!(
labels = [LabeledSpan::new(
Some("this line".to_string()),
offset,
line.len(),
)],
help = "fully qualified domain names can be at most 255 characters long",
url = "https://en.wikipedia.org/wiki/Fully_qualified_domain_name",
"hostname too long ({} octets)",
line.len(),
)
);
ensure!(
line.ends_with('.'),
miette!(
labels = [LabeledSpan::new(
Some("last character".to_string()),
offset + line.len() - 1,
1,
)],
help = "hostname should be a fully qualified domain name (end with a '.')",
url = "https://en.wikipedia.org/wiki/Fully_qualified_domain_name",
"not a fully qualified domain name"
)
);
let mut label_offset = 0usize;
for label in line.strip_suffix('.').unwrap_or(line).split('.') {
validate_label(offset + label_offset, label)?;
label_offset += label.len() + 1;
}
Ok(())
}
fn validate_label(offset: usize, label: &str) -> Result<()> {
ensure!(
!label.is_empty(),
miette!(
labels = [LabeledSpan::new(
Some("label".to_string()),
offset,
label.len(),
)],
help = "each label should have at least one character",
url = "https://en.wikipedia.org/wiki/Fully_qualified_domain_name",
"empty label",
)
);
ensure!(
label.len() <= 63,
miette!(
labels = [LabeledSpan::new(
Some("label".to_string()),
offset,
label.len(),
)],
help = "labels should be at most 63 octets",
url = "https://en.wikipedia.org/wiki/Fully_qualified_domain_name",
"label too long ({} octets)",
label.len(),
)
);
for (octet_offset, octet) in label.bytes().enumerate() {
validate_octet(offset + octet_offset, octet)?;
}
Ok(())
}
fn validate_octet(offset: usize, octet: u8) -> Result<()> {
let spans = || [LabeledSpan::new(Some("octet".to_string()), offset, 1)];
ensure!(
octet.is_ascii(),
miette!(
labels = spans(),
help = "we only accept ascii characters",
url = "https://en.wikipedia.org/wiki/Hostname#Syntax",
"invalid octet: '{}'",
octet.escape_ascii(),
)
);
ensure!(
octet.is_ascii_alphanumeric() || octet == b'-' || octet == b'_',
miette!(
labels = spans(),
help = "hostnames are only allowed to contain characters in [a-zA-Z0-9_-]",
url = "https://en.wikipedia.org/wiki/Hostname#Syntax",
"invalid octet: '{}'",
octet.escape_ascii(),
)
);
Ok(())
}
#[cfg(test)]
mod test {
use crate::records::validate_record_str;
macro_rules! assert_miette_snapshot {
($diag:expr) => {{
use std::borrow::Borrow;
use insta::{with_settings, assert_snapshot};
use miette::{GraphicalReportHandler, GraphicalTheme};
let mut out = String::new();
GraphicalReportHandler::new_themed(GraphicalTheme::unicode_nocolor())
.with_width(80)
.render_report(&mut out, $diag.borrow())
.unwrap();
with_settings!({
description => stringify!($diag)
}, {
assert_snapshot!(out);
});
}};
}
#[test]
fn valid_records() -> miette::Result<()> {
for record in [
"example.com.",
"example.org.",
"example.net.",
"subdomain.example.com.",
] {
validate_record_str(record)?;
}
Ok(())
}
#[test]
fn hostname_too_long() {
let err = validate_record_str("example.example.example.example.example.example.example.example.example.example.example.example.example.example.example.example.example.example.example.example.example.example.example.example.example.example.example.example.example.example.example.example.net.").unwrap_err();
assert_miette_snapshot!(err);
}
#[test]
fn not_fqd() {
let err = validate_record_str("example.net").unwrap_err();
assert_miette_snapshot!(err);
}
#[test]
fn empty_label() {
let err = validate_record_str("name..example.org.").unwrap_err();
assert_miette_snapshot!(err);
}
#[test]
fn label_too_long() {
let err = validate_record_str("name.an-entremely-long-label-that-should-not-exist-because-it-goes-against-the-spec.example.org.").unwrap_err();
assert_miette_snapshot!(err);
}
#[test]
fn invalid_ascii() {
let err = validate_record_str("name.this-is-not-ascii-ß.example.org.").unwrap_err();
assert_miette_snapshot!(err);
}
#[test]
fn invalid_octet() {
let err =
validate_record_str("name.this-character:-is-not-allowed.example.org.").unwrap_err();
assert_miette_snapshot!(err);
}
}

View file

@ -0,0 +1,14 @@
---
source: src/records.rs
description: err
expression: out
---
]8;;https://en.wikipedia.org/wiki/Fully_qualified_domain_name\(link)]8;;\
× empty label
╭────
1 │ name..example.org.
· ▲
· ╰── label
╰────
help: each label should have at least one character

View file

@ -0,0 +1,14 @@
---
source: src/records.rs
description: err
expression: out
---
]8;;https://en.wikipedia.org/wiki/Fully_qualified_domain_name\(link)]8;;\
× hostname too long (260 octets)
╭────
1 │ example.example.example.example.example.example.example.example.example.example.example.example.example.example.example.example.example.example.example.example.example.example.example.example.example.example.example.example.example.example.example.example.net.
· ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
· ╰── this line
╰────
help: fully qualified domain names can be at most 255 characters long

View file

@ -0,0 +1,14 @@
---
source: src/records.rs
description: err
expression: out
---
]8;;https://en.wikipedia.org/wiki/Hostname#Syntax\(link)]8;;\
× invalid octet: '\xc3'
╭────
1 │ name.this-is-not-ascii-ß.example.org.
· ┬
· ╰── octet
╰────
help: we only accept ascii characters

View file

@ -0,0 +1,14 @@
---
source: src/records.rs
description: err
expression: out
---
]8;;https://en.wikipedia.org/wiki/Hostname#Syntax\(link)]8;;\
× invalid octet: ':'
╭────
1 │ name.this-character:-is-not-allowed.example.org.
· ┬
· ╰── octet
╰────
help: hostnames are only allowed to contain characters in [a-zA-Z0-9_-]

View file

@ -0,0 +1,14 @@
---
source: src/records.rs
description: err
expression: out
---
]8;;https://en.wikipedia.org/wiki/Fully_qualified_domain_name\(link)]8;;\
× label too long (78 octets)
╭────
1 │ name.an-entremely-long-label-that-should-not-exist-because-it-goes-against-the-spec.example.org.
· ───────────────────────────────────────┬──────────────────────────────────────
· ╰── label
╰────
help: labels should be at most 63 octets

View file

@ -0,0 +1,14 @@
---
source: src/records.rs
description: err
expression: out
---
]8;;https://en.wikipedia.org/wiki/Fully_qualified_domain_name\(link)]8;;\
× not a fully qualified domain name
╭────
1 │ example.net
· ┬
· ╰── last character
╰────
help: hostname should be a fully qualified domain name (end with a '.')