26 Commits

Author SHA1 Message Date
7193302454 chore(deps): update module github.com/go-co-op/gocron to v2
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI / test (pull_request) Successful in 31s
2026-04-13 10:15:41 +00:00
10bf551f32 chore(deps): update docker/login-action action to v4.1.0 (#101)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [docker/login-action](https://github.com/docker/login-action) | action | minor | `v4.0.0` → `v4.1.0` |

---

### Release Notes

<details>
<summary>docker/login-action (docker/login-action)</summary>

### [`v4.1.0`](https://github.com/docker/login-action/releases/tag/v4.1.0)

[Compare Source](https://github.com/docker/login-action/compare/v4.0.0...v4.1.0)

- Fix scoped Docker Hub cleanup path when registry is omitted by [@&#8203;crazy-max](https://github.com/crazy-max) in [#&#8203;945](https://github.com/docker/login-action/pull/945)
- Bump [@&#8203;aws-sdk/client-ecr](https://github.com/aws-sdk/client-ecr) and [@&#8203;aws-sdk/client-ecr-public](https://github.com/aws-sdk/client-ecr-public) to 3.1020.0 in [#&#8203;930](https://github.com/docker/login-action/pull/930)
- Bump [@&#8203;docker/actions-toolkit](https://github.com/docker/actions-toolkit) from 0.77.0 to 0.86.0 in [#&#8203;932](https://github.com/docker/login-action/pull/932) [#&#8203;936](https://github.com/docker/login-action/pull/936)
- Bump brace-expansion from 1.1.12 to 1.1.13 in [#&#8203;952](https://github.com/docker/login-action/pull/952)
- Bump fast-xml-parser from 5.3.4 to 5.3.6 in [#&#8203;942](https://github.com/docker/login-action/pull/942)
- Bump flatted from 3.3.3 to 3.4.2 in [#&#8203;944](https://github.com/docker/login-action/pull/944)
- Bump glob from 10.3.12 to 10.5.0 in [#&#8203;940](https://github.com/docker/login-action/pull/940)
- Bump handlebars from 4.7.8 to 4.7.9 in [#&#8203;949](https://github.com/docker/login-action/pull/949)
- Bump http-proxy-agent and https-proxy-agent to 8.0.0 in [#&#8203;937](https://github.com/docker/login-action/pull/937)
- Bump lodash from 4.17.23 to 4.18.1 in [#&#8203;958](https://github.com/docker/login-action/pull/958)
- Bump minimatch from 3.1.2 to 3.1.5 in [#&#8203;941](https://github.com/docker/login-action/pull/941)
- Bump picomatch from 4.0.3 to 4.0.4 in [#&#8203;948](https://github.com/docker/login-action/pull/948)
- Bump undici from 6.23.0 to 6.24.1 in [#&#8203;938](https://github.com/docker/login-action/pull/938)

**Full Changelog**: <https://github.com/docker/login-action/compare/v4.0.0...v4.1.0>

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My41LjQiLCJ1cGRhdGVkSW5WZXIiOiI0My41LjQiLCJ0YXJnZXRCcmFuY2giOiJtYWluIiwibGFiZWxzIjpbImFjdGlvbiIsImRlcHMiXX0=-->

Reviewed-on: #101
Reviewed-by: t.behrendt <t.behrendt@noreply.localhost>
Co-authored-by: Renovate Bot <renovate@t00n.de>
Co-committed-by: Renovate Bot <renovate@t00n.de>
2026-04-11 10:32:47 +02:00
0b80f77d83 chore(deps): update https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment action to v0.1.30 (#98)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment](https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment) | action | patch | `0.1.29` → `0.1.30` |

---

### Release Notes

<details>
<summary>t.behrendt/conventional-semantic-git-tag-increment (https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment)</summary>

### [`v0.1.30`](https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment/compare/0.1.29...0.1.30)

[Compare Source](https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment/compare/0.1.29...0.1.30)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My41LjQiLCJ1cGRhdGVkSW5WZXIiOiI0My41LjQiLCJ0YXJnZXRCcmFuY2giOiJtYWluIiwibGFiZWxzIjpbImFjdGlvbiIsImRlcHMiXX0=-->

Reviewed-on: #98
Reviewed-by: t.behrendt <t.behrendt@noreply.localhost>
Co-authored-by: Renovate Bot <renovate@t00n.de>
Co-committed-by: Renovate Bot <renovate@t00n.de>
2026-03-26 21:37:28 +01:00
fca2f44f14 chore(deps): update docker.io/library/golang:1.25-alpine docker digest to 8e02eb3 (#93)
All checks were successful
CD / test (push) Successful in 55s
CD / Create tag (push) Successful in 1m5s
CD / Build and push (amd64) (push) Successful in 1m13s
CD / Build and push (arm64) (push) Successful in 6m8s
CD / Create manifest (push) Successful in 23s
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [docker.io/library/golang](https://hub.docker.com/_/golang) ([source](https://github.com/docker-library/golang)) | stage | digest | `f6751d8` → `8e02eb3` |

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My41LjQiLCJ1cGRhdGVkSW5WZXIiOiI0My41LjQiLCJ0YXJnZXRCcmFuY2giOiJtYWluIiwibGFiZWxzIjpbXX0=-->

Reviewed-on: #93
Reviewed-by: t.behrendt <t.behrendt@noreply.localhost>
Co-authored-by: Renovate Bot <renovate@t00n.de>
Co-committed-by: Renovate Bot <renovate@t00n.de>
2026-03-15 22:20:24 +01:00
07f6ace85e chore(deps): update actions/setup-go digest to 4b73464 (#92)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [actions/setup-go](https://github.com/actions/setup-go) ([changelog](7a3fe6cf4c..4b73464bb3)) | action | digest | `7a3fe6c` → `4b73464` |

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My41LjQiLCJ1cGRhdGVkSW5WZXIiOiI0My41LjQiLCJ0YXJnZXRCcmFuY2giOiJtYWluIiwibGFiZWxzIjpbImFjdGlvbiIsImRlcHMiXX0=-->

Reviewed-on: #92
Reviewed-by: t.behrendt <t.behrendt@noreply.localhost>
Co-authored-by: Renovate Bot <renovate@t00n.de>
Co-committed-by: Renovate Bot <renovate@t00n.de>
2026-03-15 22:20:13 +01:00
5131331242 chore(deps): update docker/build-push-action action to v7 (#94)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [docker/build-push-action](https://github.com/docker/build-push-action) | action | major | `v6.19.2` → `v7.0.0` |

---

### Release Notes

<details>
<summary>docker/build-push-action (docker/build-push-action)</summary>

### [`v7.0.0`](https://github.com/docker/build-push-action/releases/tag/v7.0.0)

[Compare Source](https://github.com/docker/build-push-action/compare/v6.19.2...v7.0.0)

- Node 24 as default runtime (requires [Actions Runner v2.327.1](https://github.com/actions/runner/releases/tag/v2.327.1) or later) by [@&#8203;crazy-max](https://github.com/crazy-max) in [#&#8203;1470](https://github.com/docker/build-push-action/pull/1470)
- Remove deprecated `DOCKER_BUILD_NO_SUMMARY` and `DOCKER_BUILD_EXPORT_RETENTION_DAYS` envs by [@&#8203;crazy-max](https://github.com/crazy-max) in [#&#8203;1473](https://github.com/docker/build-push-action/pull/1473)
- Remove legacy export-build tool support for build summary by [@&#8203;crazy-max](https://github.com/crazy-max) in [#&#8203;1474](https://github.com/docker/build-push-action/pull/1474)
- Switch to ESM and update config/test wiring by [@&#8203;crazy-max](https://github.com/crazy-max) in [#&#8203;1466](https://github.com/docker/build-push-action/pull/1466)
- Bump [@&#8203;actions/core](https://github.com/actions/core) from 1.11.1 to 3.0.0 in [#&#8203;1454](https://github.com/docker/build-push-action/pull/1454)
- Bump [@&#8203;docker/actions-toolkit](https://github.com/docker/actions-toolkit) from 0.62.1 to 0.79.0 in [#&#8203;1453](https://github.com/docker/build-push-action/pull/1453) [#&#8203;1472](https://github.com/docker/build-push-action/pull/1472) [#&#8203;1479](https://github.com/docker/build-push-action/pull/1479)
- Bump minimatch from 3.1.2 to 3.1.5 in [#&#8203;1463](https://github.com/docker/build-push-action/pull/1463)

**Full Changelog**: <https://github.com/docker/build-push-action/compare/v6.19.2...v7.0.0>

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My41LjQiLCJ1cGRhdGVkSW5WZXIiOiI0My41LjQiLCJ0YXJnZXRCcmFuY2giOiJtYWluIiwibGFiZWxzIjpbImFjdGlvbiIsImRlcHMiXX0=-->

Reviewed-on: #94
Reviewed-by: t.behrendt <t.behrendt@noreply.localhost>
Co-authored-by: Renovate Bot <renovate@t00n.de>
Co-committed-by: Renovate Bot <renovate@t00n.de>
2026-03-15 22:17:02 +01:00
696215c3cf chore(deps): update docker/setup-buildx-action action to v4 (#96)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) | action | major | `v3` → `v4` |

---

### Release Notes

<details>
<summary>docker/setup-buildx-action (docker/setup-buildx-action)</summary>

### [`v4`](https://github.com/docker/setup-buildx-action/compare/v3...v4)

[Compare Source](https://github.com/docker/setup-buildx-action/compare/v3...v4)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My41LjQiLCJ1cGRhdGVkSW5WZXIiOiI0My41LjQiLCJ0YXJnZXRCcmFuY2giOiJtYWluIiwibGFiZWxzIjpbImFjdGlvbiIsImRlcHMiXX0=-->

Reviewed-on: #96
Reviewed-by: t.behrendt <t.behrendt@noreply.localhost>
Co-authored-by: Renovate Bot <renovate@t00n.de>
Co-committed-by: Renovate Bot <renovate@t00n.de>
2026-03-15 22:16:56 +01:00
43192da152 chore(deps): update docker/login-action action to v4 (#95)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [docker/login-action](https://github.com/docker/login-action) | action | major | `v3.7.0` → `v4.0.0` |

---

### Release Notes

<details>
<summary>docker/login-action (docker/login-action)</summary>

### [`v4.0.0`](https://github.com/docker/login-action/releases/tag/v4.0.0)

[Compare Source](https://github.com/docker/login-action/compare/v3.7.0...v4.0.0)

- Node 24 as default runtime (requires [Actions Runner v2.327.1](https://github.com/actions/runner/releases/tag/v2.327.1) or later) by [@&#8203;crazy-max](https://github.com/crazy-max) in [#&#8203;929](https://github.com/docker/login-action/pull/929)
- Switch to ESM and update config/test wiring by [@&#8203;crazy-max](https://github.com/crazy-max) in [#&#8203;927](https://github.com/docker/login-action/pull/927)
- Bump [@&#8203;actions/core](https://github.com/actions/core) from 1.11.1 to 3.0.0 in [#&#8203;919](https://github.com/docker/login-action/pull/919)
- Bump [@&#8203;aws-sdk/client-ecr](https://github.com/aws-sdk/client-ecr) from 3.890.0 to 3.1000.0 in [#&#8203;909](https://github.com/docker/login-action/pull/909) [#&#8203;920](https://github.com/docker/login-action/pull/920)
- Bump [@&#8203;aws-sdk/client-ecr-public](https://github.com/aws-sdk/client-ecr-public) from 3.890.0 to 3.1000.0 in [#&#8203;909](https://github.com/docker/login-action/pull/909) [#&#8203;920](https://github.com/docker/login-action/pull/920)
- Bump [@&#8203;docker/actions-toolkit](https://github.com/docker/actions-toolkit) from 0.63.0 to 0.77.0 in [#&#8203;910](https://github.com/docker/login-action/pull/910) [#&#8203;928](https://github.com/docker/login-action/pull/928)
- Bump [@&#8203;isaacs/brace-expansion](https://github.com/isaacs/brace-expansion) from 5.0.0 to 5.0.1 in [#&#8203;921](https://github.com/docker/login-action/pull/921)
- Bump js-yaml from 4.1.0 to 4.1.1 in [#&#8203;901](https://github.com/docker/login-action/pull/901)

**Full Changelog**: <https://github.com/docker/login-action/compare/v3.7.0...v4.0.0>

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My41LjQiLCJ1cGRhdGVkSW5WZXIiOiI0My41LjQiLCJ0YXJnZXRCcmFuY2giOiJtYWluIiwibGFiZWxzIjpbImFjdGlvbiIsImRlcHMiXX0=-->

Reviewed-on: #95
Reviewed-by: t.behrendt <t.behrendt@noreply.localhost>
Co-authored-by: Renovate Bot <renovate@t00n.de>
Co-committed-by: Renovate Bot <renovate@t00n.de>
2026-03-15 22:14:44 +01:00
74e6e06887 chore(deps): update docker.io/library/golang:1.25-alpine docker digest to f6751d8 (#90)
All checks were successful
CD / test (push) Successful in 9s
CD / Create tag (push) Successful in 11s
CD / Build and push (amd64) (push) Successful in 21s
CD / Build and push (arm64) (push) Successful in 2m32s
CD / Create manifest (push) Successful in 1m28s
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [docker.io/library/golang](https://hub.docker.com/_/golang) ([source](https://github.com/docker-library/golang)) | stage | digest | `2611181` → `f6751d8` |

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My41LjQiLCJ1cGRhdGVkSW5WZXIiOiI0My41LjQiLCJ0YXJnZXRCcmFuY2giOiJtYWluIiwibGFiZWxzIjpbXX0=-->

Reviewed-on: #90
Reviewed-by: t.behrendt <t.behrendt@noreply.localhost>
Co-authored-by: Renovate Bot <renovate@t00n.de>
Co-committed-by: Renovate Bot <renovate@t00n.de>
2026-02-20 21:31:43 +01:00
e497eb67a2 chore(deps): update gcr.io/distroless/static-debian12 docker digest to 20bc6c0 (#76)
All checks were successful
CD / Create tag (push) Successful in 12s
CD / test (push) Successful in 28s
CD / Build and push (amd64) (push) Successful in 21s
CD / Build and push (arm64) (push) Successful in 2m6s
CD / Create manifest (push) Successful in 21s
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| gcr.io/distroless/static-debian12 | final | digest | `4b2a093` → `20bc6c0` |

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0Mi43MS4wIiwidXBkYXRlZEluVmVyIjoiNDMuNS40IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Reviewed-on: #76
Reviewed-by: t.behrendt <t.behrendt@noreply.localhost>
Co-authored-by: Renovate Bot <renovate@t00n.de>
Co-committed-by: Renovate Bot <renovate@t00n.de>
2026-02-20 21:28:22 +01:00
8f336a10e5 chore(deps): update docker/build-push-action action to v6.19.2 (#87)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [docker/build-push-action](https://github.com/docker/build-push-action) | action | minor | `v6.18.0` → `v6.19.2` |

---

### Release Notes

<details>
<summary>docker/build-push-action (docker/build-push-action)</summary>

### [`v6.19.2`](https://github.com/docker/build-push-action/releases/tag/v6.19.2)

[Compare Source](https://github.com/docker/build-push-action/compare/v6.19.1...v6.19.2)

- Preserve port in `GIT_AUTH_TOKEN` host by [@&#8203;crazy-max](https://github.com/crazy-max) in [#&#8203;1458](https://github.com/docker/build-push-action/pull/1458)

**Full Changelog**: <https://github.com/docker/build-push-action/compare/v6.19.1...v6.19.2>

### [`v6.19.1`](https://github.com/docker/build-push-action/releases/tag/v6.19.1)

[Compare Source](https://github.com/docker/build-push-action/compare/v6.19.0...v6.19.1)

- Derive `GIT_AUTH_TOKEN` host from GitHub server URL by [@&#8203;crazy-max](https://github.com/crazy-max) in [#&#8203;1456](https://github.com/docker/build-push-action/pull/1456)

**Full Changelog**: <https://github.com/docker/build-push-action/compare/v6.19.0...v6.19.1>

### [`v6.19.0`](https://github.com/docker/build-push-action/releases/tag/v6.19.0)

[Compare Source](https://github.com/docker/build-push-action/compare/v6.18.0...v6.19.0)

- Scope default git auth token to `github.com` by [@&#8203;crazy-max](https://github.com/crazy-max) in [#&#8203;1451](https://github.com/docker/build-push-action/pull/1451)
- Bump brace-expansion from 1.1.11 to 1.1.12 in [#&#8203;1396](https://github.com/docker/build-push-action/pull/1396)
- Bump form-data from 2.5.1 to 2.5.5 in [#&#8203;1391](https://github.com/docker/build-push-action/pull/1391)
- Bump js-yaml from 3.14.1 to 3.14.2 in [#&#8203;1429](https://github.com/docker/build-push-action/pull/1429)
- Bump lodash from 4.17.21 to 4.17.23 in [#&#8203;1446](https://github.com/docker/build-push-action/pull/1446)
- Bump tmp from 0.2.3 to 0.2.4 in [#&#8203;1398](https://github.com/docker/build-push-action/pull/1398)
- Bump undici from 5.28.4 to 5.29.0 in [#&#8203;1397](https://github.com/docker/build-push-action/pull/1397)

**Full Changelog**: <https://github.com/docker/build-push-action/compare/v6.18.0...v6.19.0>

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My41LjQiLCJ1cGRhdGVkSW5WZXIiOiI0My41LjQiLCJ0YXJnZXRCcmFuY2giOiJtYWluIiwibGFiZWxzIjpbImFjdGlvbiIsImRlcHMiXX0=-->

Reviewed-on: #87
Reviewed-by: t.behrendt <t.behrendt@noreply.localhost>
Co-authored-by: Renovate Bot <renovate@t00n.de>
Co-committed-by: Renovate Bot <renovate@t00n.de>
2026-02-20 21:28:02 +01:00
525d85728e chore(deps): update https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment action to v0.1.29 (#91)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment](https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment) | action | patch | `0.1.26` → `0.1.29` |

---

### Release Notes

<details>
<summary>t.behrendt/conventional-semantic-git-tag-increment (https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment)</summary>

### [`v0.1.29`](https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment/compare/0.1.28...0.1.29)

[Compare Source](https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment/compare/0.1.28...0.1.29)

### [`v0.1.28`](https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment/compare/0.1.27...0.1.28)

[Compare Source](https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment/compare/0.1.27...0.1.28)

### [`v0.1.27`](https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment/compare/0.1.26...0.1.27)

[Compare Source](https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment/compare/0.1.26...0.1.27)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My41LjQiLCJ1cGRhdGVkSW5WZXIiOiI0My41LjQiLCJ0YXJnZXRCcmFuY2giOiJtYWluIiwibGFiZWxzIjpbImFjdGlvbiIsImRlcHMiXX0=-->

Reviewed-on: #91
Reviewed-by: t.behrendt <t.behrendt@noreply.localhost>
Co-authored-by: Renovate Bot <renovate@t00n.de>
Co-committed-by: Renovate Bot <renovate@t00n.de>
2026-02-20 21:17:46 +01:00
8df7711b39 chore: add fully qualified docker image name (#89)
All checks were successful
CD / Create tag (push) Successful in 26s
CD / test (push) Successful in 52s
CD / Build and push (amd64) (push) Successful in 22s
CD / Build and push (arm64) (push) Successful in 4m10s
CD / Create manifest (push) Successful in 31s
Reviewed-on: #89
Co-authored-by: Timo Behrendt <t.behrendt@t00n.de>
Co-committed-by: Timo Behrendt <t.behrendt@t00n.de>
2026-02-19 18:48:27 +01:00
e39a6f0c23 chore(deps): update https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment action to v0.1.26 (#84)
This PR contains the following updates:

| Package | Type | Update | Change | Pending |
|---|---|---|---|---|
| [https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment](https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment) | action | patch | `0.1.24` → `0.1.26` | `0.1.27` |

---

### Release Notes

<details>
<summary>t.behrendt/conventional-semantic-git-tag-increment (https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment)</summary>

### [`v0.1.26`](https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment/compare/0.1.25...0.1.26)

[Compare Source](https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment/compare/0.1.25...0.1.26)

### [`v0.1.25`](https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment/compare/0.1.24...0.1.25)

[Compare Source](https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment/compare/0.1.24...0.1.25)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0Mi45NS4yIiwidXBkYXRlZEluVmVyIjoiNDMuNS40IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJhY3Rpb24iLCJkZXBzIl19-->

Reviewed-on: #84
Reviewed-by: t.behrendt <t.behrendt@noreply.localhost>
Co-authored-by: Renovate Bot <renovate@t00n.de>
Co-committed-by: Renovate Bot <renovate@t00n.de>
2026-02-18 19:48:43 +01:00
d40f004f5b ci: pin various actions to a proper semver version (#86)
Reviewed-on: #86
Co-authored-by: Timo Behrendt <t.behrendt@t00n.de>
Co-committed-by: Timo Behrendt <t.behrendt@t00n.de>
2026-02-14 19:14:11 +01:00
7d9e3bf6e2 chore(deps): update https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment action to v0.1.24 (#83)
This PR contains the following updates:

| Package | Type | Update | Change | Pending |
|---|---|---|---|---|
| [https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment](https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment) | action | patch | `0.1.23` → `0.1.24` | `0.1.26` (+1) |

---

### Release Notes

<details>
<summary>t.behrendt/conventional-semantic-git-tag-increment (https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment)</summary>

### [`v0.1.24`](https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment/compare/0.1.23...0.1.24)

[Compare Source](https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment/compare/0.1.23...0.1.24)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0Mi45NS4xIiwidXBkYXRlZEluVmVyIjoiNDIuOTUuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiYWN0aW9uIiwiZGVwcyJdfQ==-->

Reviewed-on: #83
Reviewed-by: t.behrendt <t.behrendt@noreply.localhost>
Co-authored-by: Renovate Bot <renovate@t00n.de>
Co-committed-by: Renovate Bot <renovate@t00n.de>
2026-02-07 18:30:17 +01:00
613f192294 chore(deps): update https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment action to v0.1.23 (#81)
This PR contains the following updates:

| Package | Type | Update | Change | Pending |
|---|---|---|---|---|
| [https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment](https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment) | action | patch | `0.1.22` → `0.1.23` | `0.1.25` (+1) |

---

### Release Notes

<details>
<summary>t.behrendt/conventional-semantic-git-tag-increment (https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment)</summary>

### [`v0.1.23`](https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment/compare/0.1.22...0.1.23)

[Compare Source](https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment/compare/0.1.22...0.1.23)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0Mi45Mi40IiwidXBkYXRlZEluVmVyIjoiNDIuOTIuNCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiYWN0aW9uIiwiZGVwcyJdfQ==-->

Reviewed-on: #81
Reviewed-by: t.behrendt <t.behrendt@noreply.localhost>
Co-authored-by: Renovate Bot <renovate@t00n.de>
Co-committed-by: Renovate Bot <renovate@t00n.de>
2026-02-03 16:07:58 +01:00
b2cfaa9885 chore(deps): update actions/cache digest to cdf6c1f (#80)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [actions/cache](https://github.com/actions/cache) ([changelog](8b402f58fb..cdf6c1fa76)) | action | digest | `8b402f5` → `cdf6c1f` |

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0Mi44NS41IiwidXBkYXRlZEluVmVyIjoiNDIuODUuNSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiYWN0aW9uIiwiZGVwcyJdfQ==-->

Reviewed-on: #80
Reviewed-by: t.behrendt <t.behrendt@noreply.localhost>
Co-authored-by: Renovate Bot <renovate@t00n.de>
Co-committed-by: Renovate Bot <renovate@t00n.de>
2026-01-30 09:55:55 +01:00
41ab5af905 chore(deps): update docker/login-action digest to c94ce9f (#79)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [docker/login-action](https://github.com/docker/login-action) ([changelog](5e57cd1181..c94ce9fb46)) | action | digest | `5e57cd1` → `c94ce9f` |

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0Mi44NS41IiwidXBkYXRlZEluVmVyIjoiNDIuODUuNSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiYWN0aW9uIiwiZGVwcyJdfQ==-->

Reviewed-on: #79
Reviewed-by: t.behrendt <t.behrendt@noreply.localhost>
Co-authored-by: Renovate Bot <renovate@t00n.de>
Co-committed-by: Renovate Bot <renovate@t00n.de>
2026-01-30 09:48:10 +01:00
7f65b3e2fc chore(deps): update actions/setup-go digest to 7a3fe6c (#77)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [actions/setup-go](https://github.com/actions/setup-go) ([changelog](4dc6199c7b..7a3fe6cf4c)) | action | digest | `4dc6199` → `7a3fe6c` |

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0Mi43MS4wIiwidXBkYXRlZEluVmVyIjoiNDIuODQuMiIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiYWN0aW9uIiwiZGVwcyJdfQ==-->

Reviewed-on: #77
Reviewed-by: t.behrendt <t.behrendt@noreply.localhost>
Co-authored-by: Renovate Bot <renovate@t00n.de>
Co-committed-by: Renovate Bot <renovate@t00n.de>
2026-01-26 13:55:57 +01:00
a66788839c chore(deps): update actions/cache digest to 8b402f5 (#78)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [actions/cache](https://github.com/actions/cache) ([changelog](9255dc7a25..8b402f58fb)) | action | digest | `9255dc7` → `8b402f5` |

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0Mi43NC41IiwidXBkYXRlZEluVmVyIjoiNDIuODQuMiIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiYWN0aW9uIiwiZGVwcyJdfQ==-->

Reviewed-on: #78
Reviewed-by: t.behrendt <t.behrendt@noreply.localhost>
Co-authored-by: Renovate Bot <renovate@t00n.de>
Co-committed-by: Renovate Bot <renovate@t00n.de>
2026-01-26 13:50:15 +01:00
603ca25093 chore: update test tooling (#75)
All checks were successful
CD / Create tag (push) Successful in 12s
CD / test (push) Successful in 50s
CD / Build and push (amd64) (push) Successful in 37s
CD / Build and push (arm64) (push) Successful in 2m8s
CD / Create manifest (push) Successful in 7s
Reviewed-on: #75
Co-authored-by: Timo Behrendt <t.behrendt@t00n.de>
Co-committed-by: Timo Behrendt <t.behrendt@t00n.de>
2026-01-10 21:42:49 +01:00
485d5b6f22 Revert "choreL: update test tooling (#72)" (#74)
All checks were successful
CD / Create tag (push) Successful in 5s
CD / test (push) Successful in 1m43s
CD / Build and push (amd64) (push) Successful in 37s
CD / Build and push (arm64) (push) Successful in 2m11s
CD / Create manifest (push) Successful in 7s
This reverts commit 2bfb4419d3.

Reviewed-on: #74
Co-authored-by: Timo Behrendt <t.behrendt@t00n.de>
Co-committed-by: Timo Behrendt <t.behrendt@t00n.de>
2026-01-10 21:25:12 +01:00
2bfb4419d3 choreL: update test tooling (#72)
Some checks failed
CD / Create tag (push) Successful in 5s
CD / test (push) Failing after 3m2s
CD / Build and push (amd64) (push) Has been skipped
CD / Build and push (arm64) (push) Has been skipped
CD / Create manifest (push) Has been skipped
Reviewed-on: #72
Co-authored-by: Timo Behrendt <t.behrendt@t00n.de>
Co-committed-by: Timo Behrendt <t.behrendt@t00n.de>
2026-01-10 21:18:09 +01:00
ac73cf14eb refactor: to use ionosDnsClient (#71)
All checks were successful
CD / Create tag (push) Successful in 14s
CD / test (push) Successful in 32s
CD / Build and push (amd64) (push) Successful in 43s
CD / Build and push (arm64) (push) Successful in 2m23s
CD / Create manifest (push) Successful in 34s
Reviewed-on: #71
Co-authored-by: Timo Behrendt <t.behrendt@t00n.de>
Co-committed-by: Timo Behrendt <t.behrendt@t00n.de>
2026-01-10 21:00:43 +01:00
15431166e0 chore(deps): update https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment action to v0.1.22 (#68)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment](https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment) | action | patch | `0.1.20` → `0.1.22` |

---

> ⚠️ **Warning**
>
> Some dependencies could not be looked up. Check the Dependency Dashboard for more information.

---

### Release Notes

<details>
<summary>t.behrendt/conventional-semantic-git-tag-increment (https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment)</summary>

### [`v0.1.22`](https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment/compare/0.1.21...0.1.22)

[Compare Source](https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment/compare/0.1.21...0.1.22)

### [`v0.1.21`](https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment/compare/0.1.20...0.1.21)

[Compare Source](https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment/compare/0.1.20...0.1.21)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0Mi42OS4yIiwidXBkYXRlZEluVmVyIjoiNDIuNjkuMiIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiYWN0aW9uIiwiZGVwcyJdfQ==-->

Reviewed-on: #68
Reviewed-by: t.behrendt <t.behrendt@noreply.localhost>
Co-authored-by: Renovate Bot <renovate@t00n.de>
Co-committed-by: Renovate Bot <renovate@t00n.de>
2026-01-08 19:25:18 +01:00
12 changed files with 1673 additions and 654 deletions

View File

@@ -19,12 +19,14 @@ env:
jobs:
test:
name: test
runs-on: ubuntu-latest
runs-on:
- ubuntu-latest
- linux_amd64
steps:
- name: Checkout
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Setup go
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6
with:
go-version-file: go.mod
check-latest: true
@@ -37,7 +39,7 @@ jobs:
go.sum
- name: cache go
id: cache-go
uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
with:
path: |
/go_path
@@ -54,7 +56,7 @@ jobs:
name: Build and push
strategy:
matrix:
arch: [amd64, arm64]
arch: [ amd64, arm64 ]
needs:
- test
runs-on:
@@ -62,11 +64,11 @@ jobs:
- linux_${{ matrix.arch }}
steps:
- name: Checkout
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4
- name: Login to Registry
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
with:
registry: ${{ env.DOCKER_REGISTRY }}
username: ${{ secrets.REGISTRY_USER }}
@@ -77,7 +79,7 @@ jobs:
echo REPO_NAME=$(echo ${GITHUB_REPOSITORY} | awk -F"/" '{print $2}' | tr '[:upper:]' '[:lower:]') >> $GITHUB_OUTPUT
echo REPO_VERSION=$(git describe --tags --always | sed 's/^v//') >> $GITHUB_OUTPUT
- name: Build and push
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0
with:
context: .
file: ./Dockerfile
@@ -94,10 +96,10 @@ jobs:
outputs:
tag: ${{ steps.tag.outputs.new-tag }}
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
- uses: https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment@0.1.20
- uses: https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment@11c694022eefab5876ac346fc9ffc0464b2548c7 # 0.1.30
id: tag
with:
token: ${{ secrets.GITEA_TOKEN }}
@@ -117,7 +119,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Get Metadata
id: meta
@@ -126,7 +128,7 @@ jobs:
echo REPO_VERSION=$(git describe --tags --always | sed 's/^v//') >> $GITHUB_OUTPUT
- name: Login to Registry
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
with:
registry: ${{ env.DOCKER_REGISTRY }}
username: ${{ secrets.REGISTRY_USER }}

View File

@@ -10,12 +10,14 @@ env:
jobs:
test:
name: test
runs-on: ubuntu-latest
runs-on:
- ubuntu-latest
- linux_amd64
steps:
- name: Checkout
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Setup go
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6
with:
go-version-file: go.mod
check-latest: true
@@ -28,7 +30,7 @@ jobs:
go.sum
- name: cache go
id: cache-go
uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
with:
path: |
/go_path
@@ -42,3 +44,10 @@ jobs:
run: make test
- name: check:format
run: make check-format
- name: Upload test-coverage
uses: ChristopherHX/gitea-upload-artifact@v4
with:
name: realdnydns-test-coverage
path: |
lcov.info
retention-days: 1

2
.gitignore vendored
View File

@@ -23,3 +23,5 @@ go.work
.vscode
config.yaml
lcov.info
realdnydns

View File

@@ -1,4 +1,4 @@
FROM golang:1.25-alpine@sha256:26111811bc967321e7b6f852e914d14bede324cd1accb7f81811929a6a57fea9 as build
FROM docker.io/library/golang:1.25-alpine@sha256:8e02eb337d9e0ea459e041f1ee5eece41cbb61f1d83e7d883a3e2fb4862063fa as build
ARG GOARCH=amd64
@@ -9,6 +9,6 @@ COPY . .
RUN CGO_ENABLED=0 GOOS=linux GOARCH=${GOARCH} \
go build -trimpath -ldflags="-s -w" -o main .
FROM gcr.io/distroless/static-debian12@sha256:4b2a093ef4649bccd586625090a3c668b254cfe180dee54f4c94f3e9bd7e381e
FROM gcr.io/distroless/static-debian12@sha256:20bc6c0bc4d625a22a8fde3e55f6515709b32055ef8fb9cfbddaa06d1760f838
COPY --from=build /app/main /
CMD ["/main"]

View File

@@ -1,11 +1,19 @@
test:
test: test-unit test-race test-coverage
test-unit:
go test ./pkg/... -coverprofile=coverage.out
test-race:
go test ./pkg/... -race
test-coverage:
go tool gcov2lcov -infile coverage.out > lcov.info
build:
go build
lint:
golint ./...
go tool golint ./...
run:
make build

View File

@@ -8,6 +8,10 @@ dns_provider:
config:
api_key: <your-api-key>
base_url: https://api.hosting.ionos.com/dns
# Optional: default TTL to use when patching records with missing TTL (default: 300)
# default_ttl: 300
# Optional: default priority to use when patching records with missing priority (default: 0)
# default_prio: 0
notification_provider:
type: gotify
config:

13
go.mod
View File

@@ -3,14 +3,25 @@ module realdnydns
go 1.25.0
require (
gitea.t000-n.de/t.behrendt/ionosDnsClient v1.0.2
github.com/go-co-op/gocron v1.37.0
github.com/go-co-op/gocron/v2 v2.19.0
github.com/go-co-op/gocron/v2 v2.20.0
gopkg.in/yaml.v3 v3.0.1
)
require (
github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/jandelgado/gcov2lcov v1.1.1 // indirect
github.com/oapi-codegen/runtime v1.1.1 // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
github.com/stretchr/testify v1.11.1 // indirect
go.uber.org/atomic v1.11.0 // indirect
golang.org/x/lint v0.0.0-20241112194109-818c5a804067 // indirect
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7 // indirect
)
tool (
github.com/jandelgado/gcov2lcov
golang.org/x/lint/golint
)

35
go.sum
View File

@@ -1,14 +1,22 @@
gitea.t000-n.de/t.behrendt/ionosDnsClient v1.0.2 h1:EWz4kLLv7lSZx/F8K0/WxN5xeVNh7z4qbeDurZYBcNk=
gitea.t000-n.de/t.behrendt/ionosDnsClient v1.0.2/go.mod h1:HZfdMF7X9LK/3FP1jJVzMWbM5BcgcZg/Qwx2WClFipg=
github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk=
github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ=
github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk=
github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-co-op/gocron v1.37.0 h1:ZYDJGtQ4OMhTLKOKMIch+/CY70Brbb1dGdooLEhh7b0=
github.com/go-co-op/gocron v1.37.0/go.mod h1:3L/n6BkO7ABj+TrfSVXLRzsP26zmikL4ISkLQ0O8iNY=
github.com/go-co-op/gocron/v2 v2.18.0/go.mod h1:Zii6he+Zfgy5W9B+JKk/KwejFOW0kZTFvHtwIpR4aBI=
github.com/go-co-op/gocron/v2 v2.19.0/go.mod h1:5lEiCKk1oVJV39Zg7/YG10OnaVrDAV5GGR6O0663k6U=
github.com/go-co-op/gocron/v2 v2.20.0/go.mod h1:5lEiCKk1oVJV39Zg7/YG10OnaVrDAV5GGR6O0663k6U=
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/jandelgado/gcov2lcov v1.1.1 h1:CHUNoAglvb34DqmMoZchnzDbA3yjpzT8EoUvVqcAY+s=
github.com/jandelgado/gcov2lcov v1.1.1/go.mod h1:tMVUlMVtS1po2SB8UkADWhOT5Y5Q13XOce2AYU69JuI=
github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
@@ -17,6 +25,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/oapi-codegen/runtime v1.1.1 h1:EXLHh0DXIJnWhdRPN2w4MXAzFyE4CskzhNLUmtpMYro=
github.com/oapi-codegen/runtime v1.1.1/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@@ -25,19 +35,36 @@ github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzG
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg=
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/lint v0.0.0-20241112194109-818c5a804067 h1:adDmSQyFTCiv19j015EGKJBoaa7ElV0Q1Wovb/4G7NA=
golang.org/x/lint v0.0.0-20241112194109-818c5a804067/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7 h1:EBZoQjiKKPaLbPrbpssUfuHtwM6KV/vb4U85g/cigFY=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=

View File

@@ -1,224 +0,0 @@
package ionosAPI
import (
"bytes"
"encoding/json"
"errors"
"io"
"net"
"net/http"
"net/url"
"realdnydns/model/common"
)
/**
* Docs: https://developer.hosting.ionos.com/docs/dns
*/
type IonosAPI interface {
GetARecord(tld string, subdomain string) (*common.ARecord, error)
SetARecord(tld string, subdomain string, ip net.IP, ttl int, prio int, disabled bool) (*common.ARecord, error)
GetZoneId(tld string) (string, error)
GetRecordId(zoneId string, tld string, subdomain string, recordType string) (string, error)
HttpCall(method string, url string, body io.Reader, queryParams map[string]string) (*http.Response, error)
}
type IonosAPIImpl struct {
APIKey string
BaseURL string
HTTPClient *http.Client
}
type ZonesResponse []struct {
Name string `json:"name"`
Id string `json:"id"`
Type string `json:"type"`
}
type ZoneResponse struct {
Id string `json:"id"`
Name string `json:"name"`
Type string `json:"type"`
Records []RecordResponse `json:"records"`
}
type RecordResponse struct {
Id string `json:"id"`
Name string `json:"name"`
RootName string `json:"rootName"`
Type string `json:"type"`
Content string `json:"content"`
ChangeDate string `json:"changeDate"`
TTL int `json:"ttl"`
Prio int `json:"prio"`
Disabled bool `json:"disabled"`
}
type ChangeRecord struct {
Name string `json:"name"`
Type string `json:"type"`
Content string `json:"content"`
TTL int `json:"ttl"`
Prio int `json:"prio"`
Disabled bool `json:"disabled"`
}
type ChangeRecordRequest struct {
Content string `json:"content"`
TTL int `json:"ttl"`
Prio int `json:"prio"`
Disabled bool `json:"disabled"`
}
func New(APIKey string, BaseURL string) IonosAPI {
return &IonosAPIImpl{
APIKey: APIKey,
BaseURL: BaseURL,
HTTPClient: &http.Client{},
}
}
func (i *IonosAPIImpl) HttpCall(method string, path string, body io.Reader, queryParams map[string]string) (*http.Response, error) {
requestUrl, _ := url.Parse(i.BaseURL + path)
query := requestUrl.Query()
for key, value := range queryParams {
query.Add(key, value)
}
requestUrl.RawQuery = query.Encode()
req, err := http.NewRequest(method, requestUrl.String(), body)
if err != nil {
return nil, err
}
req.Header.Add("X-API-Key", i.APIKey)
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Accept", "application/json")
return i.HTTPClient.Do(req)
}
func (i *IonosAPIImpl) GetZoneId(tld string) (string, error) {
res, err := i.HttpCall("GET", "/v1/zones", nil, nil)
if err != nil {
return "", err
}
responseBody := make([]byte, res.ContentLength)
res.Body.Read(responseBody)
zones := []ZoneResponse{}
json.Unmarshal(responseBody, &zones)
for _, z := range zones {
if z.Name == tld {
return z.Id, nil
}
}
return "", errors.New("zone not found")
}
func (i *IonosAPIImpl) GetRecordId(zoneId string, tld string, subdomain string, recordType string) (string, error) {
var domain string
if subdomain == "@" || subdomain == "" {
domain = tld
} else {
domain = subdomain + "." + tld
}
res, err := i.HttpCall("GET", "/v1/zones/"+zoneId, nil, map[string]string{"recordName": domain, "recordType": recordType})
if err != nil {
return "", err
}
responseBody := make([]byte, res.ContentLength)
res.Body.Read(responseBody)
zone := ZoneResponse{}
json.Unmarshal(responseBody, &zone)
for _, record := range zone.Records {
if record.Type == recordType && record.Name == domain {
return record.Id, nil
}
}
return "", errors.New("record not found")
}
func (i *IonosAPIImpl) SetARecord(tld string, subdomain string, ip net.IP, ttl int, prio int, disabled bool) (*common.ARecord, error) {
zoneId, err := i.GetZoneId(tld)
if err != nil {
return nil, err
}
recordId, err := i.GetRecordId(zoneId, tld, subdomain, "A")
if err != nil {
return nil, err
}
changeRecordRequest, err := json.Marshal(ChangeRecordRequest{
Content: ip.String(),
TTL: ttl,
Prio: prio,
Disabled: false,
})
if err != nil {
return nil, err
}
res, err := i.HttpCall("PUT", "/v1/zones/"+zoneId+"/records/"+recordId, bytes.NewReader(changeRecordRequest), nil)
if err != nil {
return nil, err
}
responseBody := make([]byte, res.ContentLength)
res.Body.Read(responseBody)
if res.StatusCode != 200 {
return nil, errors.New("error updating record")
}
changeRecord := ChangeRecord{}
json.Unmarshal(responseBody, &changeRecord)
return &common.ARecord{
Domain: changeRecord.Name,
IP: changeRecord.Content,
TTL: changeRecord.TTL,
Prio: changeRecord.Prio,
Disabled: changeRecord.Disabled,
}, nil
}
func (ionos *IonosAPIImpl) GetARecord(tld string, subdomain string) (*common.ARecord, error) {
zoneId, err := ionos.GetZoneId(tld)
if err != nil {
return nil, err
}
recordId, err := ionos.GetRecordId(zoneId, tld, subdomain, "A")
if err != nil {
return nil, err
}
res, err := ionos.HttpCall("GET", "/v1/zones/"+zoneId+"/records/"+recordId, nil, nil)
if err != nil {
return nil, err
}
responseBody := make([]byte, res.ContentLength)
res.Body.Read(responseBody)
record := RecordResponse{}
json.Unmarshal(responseBody, &record)
return &common.ARecord{
Domain: record.Name,
IP: record.Content,
TTL: record.TTL,
Prio: record.Prio,
Disabled: record.Disabled,
}, nil
}

View File

@@ -1,285 +0,0 @@
package ionosAPI
import (
"encoding/json"
"net"
"net/http"
"net/http/httptest"
"testing"
)
func utilMockServerImpl() func(w http.ResponseWriter, r *http.Request) {
zonesResponse := []ZoneResponse{
{
Name: "example.com",
Id: "1234567890",
Type: "NATIVE",
},
{
Name: "notTheExample.org",
Id: "0987654321",
Type: "SLAVE",
},
}
zonesResponseJson, _ := json.Marshal(zonesResponse)
recordResponseSub := RecordResponse{
Id: "abcdefghij",
Name: "example.com",
RootName: "example.com",
Type: "A",
Content: "127.0.0.1",
ChangeDate: "2019-12-09T13:04:25.772Z",
TTL: 300,
Prio: 0,
Disabled: false,
}
recordResponseSubJson, _ := json.Marshal(recordResponseSub)
recordResponseTLD := RecordResponse{
Id: "jihgfedcba",
Name: "sub.example.com",
RootName: "example.com",
Type: "A",
Content: "127.0.0.2",
ChangeDate: "2019-12-09T13:04:25.772Z",
TTL: 300,
Prio: 0,
Disabled: false,
}
recordResponseTLDJson, _ := json.Marshal(recordResponseTLD)
zoneResponse := ZoneResponse{
Id: "1234567890",
Name: "example.com",
Type: "NATIVE",
Records: []RecordResponse{
recordResponseSub,
recordResponseTLD,
},
}
zoneResponseJson, _ := json.Marshal(zoneResponse)
changeRecord := ChangeRecord{
Name: "sub.example.com",
Type: "A",
Content: "127.0.0.1",
TTL: 300,
Prio: 0,
Disabled: false,
}
changeRecordJson, _ := json.Marshal(changeRecord)
return func(w http.ResponseWriter, r *http.Request) {
var response []byte
if r.Method == "GET" {
if r.RequestURI == "/v1/zones" {
response = zonesResponseJson
} else if r.RequestURI == "/v1/zones/1234567890?recordName=example.com&recordType=A" ||
r.RequestURI == "/v1/zones/1234567890?recordName=sub.example.com&recordType=A" {
response = zoneResponseJson
} else if r.RequestURI == "/v1/zones/1234567890/records/abcdefghij" {
response = recordResponseSubJson
} else if r.RequestURI == "/v1/zones/1234567890/records/jihgfedcba" {
response = recordResponseTLDJson
}
} else if r.Method == "PUT" {
response = changeRecordJson
} else {
response = []byte("404")
}
w.Write(response)
}
}
func TestHttpCall(t *testing.T) {
mockServer := httptest.NewServer(http.HandlerFunc(utilMockServerImpl()))
defer mockServer.Close()
ionosAPI := New("dummyKey", mockServer.URL)
t.Run("returns response for GET request", testHttpCallGet(ionosAPI))
t.Run("returns response for PUT request", testHttpCallPut(ionosAPI))
t.Run("returns error for non existing endpoint", testHttpCallNonExistingEndpoint())
}
func testHttpCallGet(api IonosAPI) func(t *testing.T) {
return func(t *testing.T) {
res, err := api.HttpCall("GET", "/v1/zones", nil, nil)
if err != nil {
t.Fatalf("HttpCall() returned unexpected error: %v", err)
}
if res.StatusCode != 200 {
t.Fatalf("HttpCall() returned unexpected status code: %v instead of 200", res.StatusCode)
}
}
}
func testHttpCallPut(api IonosAPI) func(t *testing.T) {
return func(t *testing.T) {
res, err := api.HttpCall("PUT", "/v1/zones/1234567890/records/abcdefghij", nil, nil)
if err != nil {
t.Fatalf("HttpCall() returned unexpected error: %v", err)
}
if res.StatusCode != 200 {
t.Fatalf("HttpCall() returned unexpected status code: %v instead of 200", res.StatusCode)
}
}
}
func testHttpCallNonExistingEndpoint() func(t *testing.T) {
return func(t *testing.T) {
mockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(404)
}))
defer mockServer.Close()
api := New("dummyKey", mockServer.URL)
res, err := api.HttpCall("GET", "/v1/nonExistingEndpoint", nil, nil)
if err != nil {
t.Fatalf("HttpCall() returned unexpected error: %v", err)
}
if res.StatusCode != 404 {
t.Fatalf("HttpCall() returned unexpected status code: %v instead of 404", res.StatusCode)
}
}
}
func TestGetZoneId(t *testing.T) {
mockServer := httptest.NewServer(http.HandlerFunc(utilMockServerImpl()))
ionosAPI := New("dummyKey", mockServer.URL)
t.Run("returns zoneId for tracked domain", testGetZoneIdSuccess(ionosAPI))
t.Run("returns error for non tracked domain", testGetZoneIdNoMatch(ionosAPI))
}
func testGetZoneIdSuccess(api IonosAPI) func(t *testing.T) {
return func(t *testing.T) {
zoneId, err := api.GetZoneId("example.com")
if err != nil {
t.Fatalf("GetZoneId() returned unexpected error: %v", err)
}
if zoneId != "1234567890" {
t.Fatalf("GetZoneId() returned unexpected zoneId: %v instead of 1234567890", zoneId)
}
}
}
func testGetZoneIdNoMatch(api IonosAPI) func(t *testing.T) {
return func(t *testing.T) {
zoneId, err := api.GetZoneId("nonTrackedDomain.com")
if err == nil || zoneId != "" {
t.Fatalf("GetZoneId() did not return an error for a non tracked domain")
}
}
}
func TestGetRecordId(t *testing.T) {
mockServer := httptest.NewServer(http.HandlerFunc(utilMockServerImpl()))
defer mockServer.Close()
ionosAPI := New("dummyKey", mockServer.URL)
t.Run("returns zoneId for top level domain", testGetRecordIdForTopLevelDomain(ionosAPI))
t.Run("returns zoneId for subdomain", testGetRecordIdForSubdomain(ionosAPI))
t.Run("returns error for untracked subdomain", testGetRecordIdWithUntrackedSubdomain(ionosAPI))
}
func testGetRecordIdForTopLevelDomain(api IonosAPI) func(t *testing.T) {
return func(t *testing.T) {
recordId, err := api.GetRecordId("1234567890", "example.com", "", "A")
if err != nil {
t.Fatalf("GetZoneId() returned unexpected error: %v", err)
}
if recordId != "abcdefghij" {
t.Fatalf("GetZoneId() returned unexpected zoneId: %v instead of abcdefghij", recordId)
}
}
}
func testGetRecordIdForSubdomain(api IonosAPI) func(t *testing.T) {
return func(t *testing.T) {
recordId, err := api.GetRecordId("1234567890", "example.com", "sub", "A")
if err != nil {
t.Fatalf("GetZoneId() returned unexpected error: %v", err)
}
if recordId != "jihgfedcba" {
t.Fatalf("GetZoneId() returned unexpected zoneId: %v instead of jihgfedcba", recordId)
}
}
}
func testGetRecordIdWithUntrackedSubdomain(api IonosAPI) func(t *testing.T) {
return func(t *testing.T) {
recordId, err := api.GetRecordId("1234567890", "example.com", "untrackedSub", "A")
if err == nil && recordId == "" {
t.Fatalf("GetZoneId() did not return an error for a non tracked domain")
}
}
}
func TestGetARecord(t *testing.T) {
mockServer := httptest.NewServer(http.HandlerFunc(utilMockServerImpl()))
defer mockServer.Close()
ionosAPI := New("dummyKey", mockServer.URL)
t.Run("returns A record for top level domain", testGetARecordFor(ionosAPI, "example.com", ""))
t.Run("returns A record for subdomain", testGetARecordFor(ionosAPI, "example.com", "sub"))
}
func testGetARecordFor(api IonosAPI, tld string, subdomain string) func(t *testing.T) {
return func(t *testing.T) {
var domain string
if subdomain == "" {
domain = tld
} else {
domain = subdomain + "." + tld
}
record, err := api.GetARecord(tld, subdomain)
if err != nil {
t.Fatalf("GetARecord() returned unexpected error: %v", err)
}
if record.Domain != domain {
t.Fatalf("GetARecord() returned unexpected record for: %v instead of %v", record.Domain, domain)
}
}
}
func TestSetARecord(t *testing.T) {
mockServer := httptest.NewServer(http.HandlerFunc(utilMockServerImpl()))
defer mockServer.Close()
ionosAPI := New("dummyKey", mockServer.URL)
changedARecord, err := ionosAPI.SetARecord("example.com", "sub", net.ParseIP("127.0.0.1"), 300, 0, false)
if err != nil {
t.Fatalf("SetARecord() returned unexpected error: %v", err)
}
if changedARecord.Domain != "sub.example.com" {
t.Fatalf("SetARecord() returned unexpected record for: %v instead of sub.example.com", changedARecord.Domain)
}
}

View File

@@ -1,20 +1,30 @@
package ionosDnsProvider
import (
"context"
"errors"
"net"
"net/http"
"realdnydns/model/common"
"realdnydns/pkg/dnsProvider"
ionosAPI "realdnydns/pkg/dnsProvider/ionos/api"
"sync"
ionosDnsClient "gitea.t000-n.de/t.behrendt/ionosDnsClient"
)
type IONOS struct {
API ionosAPI.IonosAPI
client *ionosDnsClient.ClientWithResponses
zoneIdMap map[string]string
defaultTtl int
defaultPrio int
zoneIdMapMutex sync.Mutex
}
type IONOSConfig struct {
APIKey string `yaml:"api_key"`
BaseURL string `yaml:"base_url"`
APIKey string `yaml:"api_key"`
BaseURL string `yaml:"base_url"`
DefaultTTL *int `yaml:"default_ttl,omitempty"`
DefaultPrio *int `yaml:"default_prio,omitempty"`
}
func NewIonos(config *IONOSConfig) (dnsProvider.DNSProvider, error) {
@@ -26,15 +36,231 @@ func NewIonos(config *IONOSConfig) (dnsProvider.DNSProvider, error) {
return nil, errors.New("base_url is required")
}
options := []ionosDnsClient.ClientOption{
ionosDnsClient.WithRequestEditorFn(func(ctx context.Context, req *http.Request) error {
req.Header.Set("X-API-Key", config.APIKey)
return nil
}),
}
client, err := ionosDnsClient.NewClientWithResponses(config.BaseURL, options...)
if err != nil {
return nil, err
}
// Set default values for TTL and Prio if not provided
defaultTtl := 300
if config.DefaultTTL != nil {
defaultTtl = *config.DefaultTTL
}
defaultPrio := 0
if config.DefaultPrio != nil {
defaultPrio = *config.DefaultPrio
}
return &IONOS{
ionosAPI.New(config.APIKey, config.BaseURL),
client: client,
zoneIdMap: make(map[string]string),
defaultTtl: defaultTtl,
defaultPrio: defaultPrio,
}, nil
}
func (ionos *IONOS) UpdateRecord(tld string, subdomain string, ip net.IP, ttl int, prio int, disabled bool) (*common.ARecord, error) {
return ionos.API.SetARecord(tld, subdomain, ip, ttl, prio, disabled)
func (i *IONOS) UpdateRecord(tld string, subdomain string, ip net.IP, ttl int, prio int, disabled bool) (*common.ARecord, error) {
zoneId, err := i.getZoneIdForTld(tld)
if err != nil {
return nil, err
}
domain := assembleTldSubdomainToDomain(tld, subdomain)
recordId, err := i.getRecordIdForDomain(zoneId, domain)
if err != nil {
return nil, err
}
ipString := ip.String()
res, err := i.client.UpdateRecordWithResponse(context.Background(), zoneId, recordId, ionosDnsClient.RecordUpdate{
Content: &ipString,
Ttl: &ttl,
Prio: &prio,
Disabled: &disabled,
})
if err != nil || res.StatusCode() != 200 {
return nil, errors.New("failed to update record")
}
if res.JSON200 == nil {
return nil, errors.New("record response is empty")
}
record := *res.JSON200
if record.Name == nil || record.Content == nil {
return nil, errors.New("record is empty")
}
// Handle optional fields with defaults
recordTtl := 0
if record.Ttl != nil {
recordTtl = *record.Ttl
}
recordPrio := 0
if record.Prio != nil {
recordPrio = *record.Prio
}
recordDisabled := false
if record.Disabled != nil {
recordDisabled = *record.Disabled
}
return &common.ARecord{
Domain: *record.Name,
IP: *record.Content,
TTL: recordTtl,
Prio: recordPrio,
Disabled: recordDisabled,
}, nil
}
func (ionos *IONOS) GetRecord(tld string, subdomain string) (*common.ARecord, error) {
return ionos.API.GetARecord(tld, subdomain)
func (i *IONOS) getZoneIdForTld(tld string) (string, error) {
i.zoneIdMapMutex.Lock()
defer i.zoneIdMapMutex.Unlock()
if zoneId, ok := i.zoneIdMap[tld]; ok {
return zoneId, nil
}
res, err := i.client.GetZonesWithResponse(context.Background())
if err != nil {
return "", err
} else if res.StatusCode() != 200 {
return "", errors.New("failed to get zones")
}
if res.JSON200 == nil {
return "", errors.New("zones response is empty")
}
zones := *res.JSON200
for _, zone := range zones {
if *zone.Name == tld {
if zone.Id == nil || *zone.Id == "" {
return "", errors.New("zone id is empty")
}
i.zoneIdMap[tld] = *zone.Id
return *zone.Id, nil
}
}
return "", errors.New("no zone found")
}
var recordTypeA = "A"
func assembleTldSubdomainToDomain(tld string, subdomain string) string {
if subdomain == "@" || subdomain == "" {
return tld
}
return subdomain + "." + tld
}
func (i *IONOS) getRecordIdForDomain(zoneId string, domain string) (string, error) {
res, err := i.client.GetZoneWithResponse(context.Background(), zoneId, &ionosDnsClient.GetZoneParams{
RecordName: &domain,
RecordType: &recordTypeA,
})
if err != nil || res.StatusCode() != 200 {
return "", errors.New("failed to get zone")
}
if res.JSON200 == nil {
return "", errors.New("zone response is empty")
}
zone := *res.JSON200
for _, record := range *zone.Records {
if *record.Name == domain && *record.Type == ionosDnsClient.RecordTypes("A") {
return *record.Id, nil
}
}
return "", errors.New("no record found")
}
func (i *IONOS) GetRecord(tld string, subdomain string) (*common.ARecord, error) {
zoneId, err := i.getZoneIdForTld(tld)
if err != nil {
return nil, err
}
domain := assembleTldSubdomainToDomain(tld, subdomain)
recordId, err := i.getRecordIdForDomain(zoneId, domain)
if err != nil {
return nil, err
}
res, err := i.client.GetRecordWithResponse(context.Background(), zoneId, recordId)
if err != nil || res.StatusCode() != 200 || res.JSON200 == nil {
return nil, errors.New("failed to get record")
}
record := *res.JSON200
if record.Name == nil || *record.Name == "" || *record.Name != domain {
return nil, errors.New("record name does not match or is empty")
}
if record.Content == nil || *record.Content == "" {
return nil, errors.New("record content is empty")
}
needsUpdate := false
ttl := i.defaultTtl
if record.Ttl != nil {
ttl = *record.Ttl
} else {
needsUpdate = true
}
prio := i.defaultPrio
if record.Prio != nil {
prio = *record.Prio
} else {
needsUpdate = true
}
disabled := false
if record.Disabled != nil {
disabled = *record.Disabled
} else {
needsUpdate = true
}
// realDynDns requires every field to be set, so we need to update the record if any of the fields are missing
if needsUpdate {
ip := net.ParseIP(*record.Content)
if ip == nil {
return nil, errors.New("invalid IP address in record content")
}
updatedRecord, err := i.UpdateRecord(tld, subdomain, ip, ttl, prio, disabled)
if err != nil {
return nil, err
}
return updatedRecord, nil
}
return &common.ARecord{
Domain: *record.Name,
IP: *record.Content,
TTL: ttl,
Prio: prio,
Disabled: disabled,
}, nil
}

File diff suppressed because it is too large Load Diff