Compare commits

..

72 commits

Author SHA1 Message Date
3790894563
feat(generator): generate nav file (#83)
Some checks failed
CI Workflow / Check GoReleaser config (pull_request) Successful in 5s
CI Workflow / Prepare GO cache (pull_request) Successful in 5m4s
Publish / Check GoReleaser config (push) Successful in 1m14s
CI Workflow / Test readiness for publishing provider (pull_request) Successful in 20m19s
Publish / Publish provider (push) Successful in 20m56s
CI Workflow / CI run build and linting (pull_request) Successful in 26m50s
CI Workflow / Code coverage report (pull_request) Successful in 10s
CI Workflow / CI run tests (pull_request) Failing after 50m42s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Reviewed-on: #83
2026-03-13 09:53:54 +00:00
f173fd54fe
fix: fix publish pipeline (#82)
All checks were successful
Publish / Check GoReleaser config (push) Successful in 9s
Publish / Publish provider (push) Successful in 28m2s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Reviewed-on: #82
2026-03-11 13:28:48 +00:00
1033d7e034
fix: builder and sdk changes (#81)
Some checks failed
Publish / Check GoReleaser config (push) Successful in 8s
Publish / Publish provider (push) Failing after 20s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-authored-by: marcel.henselin <marcel.henselin@stackit.cloud>
Reviewed-on: #81
2026-03-11 13:13:46 +00:00
marcel.henselin
635a9abf20
fix: disable shell color in runnerstats (#80)
Signed-off-by: marcel.henselin <marcel.henselin@stackit.cloud>

## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #80
Co-authored-by: marcel.henselin <marcel.henselin@stackit.cloud>
Co-committed-by: marcel.henselin <marcel.henselin@stackit.cloud>
2026-02-27 10:25:10 +00:00
marcel.henselin
07458c5677
feat: add runner stats (#79)
Signed-off-by: marcel.henselin <marcel.henselin@stackit.cloud>

## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #79
Co-authored-by: marcel.henselin <marcel.henselin@stackit.cloud>
Co-committed-by: marcel.henselin <marcel.henselin@stackit.cloud>
2026-02-27 10:20:02 +00:00
marcel.henselin
eb13630d2f
feat: test STACKIT runner (#78)
Signed-off-by: marcel.henselin <marcel.henselin@stackit.cloud>

## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #78
Co-authored-by: marcel.henselin <marcel.henselin@stackit.cloud>
Co-committed-by: marcel.henselin <marcel.henselin@stackit.cloud>
2026-02-27 10:08:09 +00:00
4a2819787d
fix: linting (#77)
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #77
Co-authored-by: Andre Harms <andre.harms@stackit.cloud>
Co-committed-by: Andre Harms <andre.harms@stackit.cloud>
2026-02-19 08:54:34 +00:00
Marcel S. Henselin
36eccc52c3
fix: null_ident (#76)
All checks were successful
Publish / Check GoReleaser config (push) Successful in 9s
Publish / Publish provider (push) Successful in 34m58s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #76
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-02-17 17:18:40 +00:00
Marcel S. Henselin
841e702b95
fix: encryption_fix (#75)
All checks were successful
Publish / Check GoReleaser config (push) Successful in 12s
Publish / Publish provider (push) Successful in 33m28s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #75
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-02-17 09:42:46 +00:00
Marcel S. Henselin
aba831cbdd
fix: some_fixes (#74)
All checks were successful
Publish / Check GoReleaser config (push) Successful in 8s
Publish / Publish provider (push) Successful in 14m6s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #74
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-02-16 19:49:02 +00:00
Marcel S. Henselin
89a24ce780
fix: try fix errors (#73)
All checks were successful
Publish / Check GoReleaser config (push) Successful in 9s
Publish / Publish provider (push) Successful in 43m1s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #73
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-02-16 19:09:42 +00:00
Marcel S. Henselin
f05e90c35a
fix: some more fix tests (#72)
All checks were successful
Publish / Check GoReleaser config (push) Successful in 5s
Publish / Publish provider (push) Successful in 12m42s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #72
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-02-16 16:12:53 +00:00
Marcel S. Henselin
7ee82366d7
fix: try fix errors (#71)
All checks were successful
Publish / Check GoReleaser config (push) Successful in 11s
Publish / Publish provider (push) Successful in 35m24s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #71
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-02-16 13:40:05 +00:00
d5644ec27f
chore: #64 add system hardening with retry logic for client (#68)
All checks were successful
Publish / Check GoReleaser config (push) Successful in 5s
Publish / Publish provider (push) Successful in 12m49s
- implement RetryRoundTripper

Refs: #64

Reviewed-on: #68
Reviewed-by: Marcel_Henselin <marcel.henselin@stackit.cloud>
Co-authored-by: Andre Harms <andre.harms@stackit.cloud>
Co-committed-by: Andre Harms <andre.harms@stackit.cloud>
2026-02-16 09:35:21 +00:00
Marcel S. Henselin
20e9b3ca4c
fix: #66 non generic api error handling (#67)
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #67
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-02-16 09:20:36 +00:00
Marcel S. Henselin
43223f5d1f
fix: #63 sort user roles to prevent state change (#65)
fix: include recent api changes
Reviewed-on: #65
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-02-16 09:04:16 +00:00
Marcel S. Henselin
452f73877f
fix: fix pgsql db state (#62)
All checks were successful
Publish / Check GoReleaser config (push) Successful in 5s
Publish / Publish provider (push) Successful in 12m26s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #62
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-02-13 17:06:57 +00:00
Marcel S. Henselin
55a0917a86
fix: fix sqlserverflexalpha (#61)
All checks were successful
Publish / Check GoReleaser config (push) Successful in 5s
Publish / Publish provider (push) Successful in 12m55s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #61
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-02-13 16:23:42 +00:00
Marcel_Henselin
d90236b02e
chore: refactorings (#60)
All checks were successful
Publish / Check GoReleaser config (push) Successful in 4s
Publish / Publish provider (push) Successful in 12m30s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #60
2026-02-13 15:49:32 +00:00
Marcel S. Henselin
b1f8c8a4d9
fix: fix wrong order of params (#59)
All checks were successful
Publish / Check GoReleaser config (push) Successful in 10s
Publish / Publish provider (push) Successful in 34m9s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #59
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-02-13 14:55:36 +00:00
Marcel S. Henselin
e01ae1a920
fix: fix lintings (#58)
All checks were successful
Publish / Check GoReleaser config (push) Successful in 5s
Publish / Publish provider (push) Successful in 12m24s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #58
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-02-13 14:27:14 +00:00
Marcel S. Henselin
843fc46f54
fix: tests (#57)
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #57
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-02-13 10:38:19 +00:00
Marcel S. Henselin
10af1dbbba
fix: postgres_fixes (#54)
Some checks failed
Publish / Check GoReleaser config (push) Successful in 9s
Publish / Publish provider (push) Successful in 30m38s
CI Workflow / Check GoReleaser config (pull_request) Successful in 6s
CI Workflow / CI (pull_request) Failing after 22m26s
CI Workflow / Code coverage report (pull_request) Has been skipped
CI Workflow / Test readiness for publishing provider (pull_request) Successful in 37m30s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #54
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-02-13 08:15:21 +00:00
Marcel S. Henselin
459120d3b3
fix: sqlserver return values mapping (#53)
All checks were successful
Publish / Check GoReleaser config (push) Successful in 11s
Publish / Publish provider (push) Successful in 30m7s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #53
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-02-12 15:14:53 +00:00
Marcel S. Henselin
82c654f3ba
fix: publisher - create versions file correctly (#52)
All checks were successful
Publish / Check GoReleaser config (push) Successful in 16s
Publish / Publish provider (push) Successful in 43m11s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #52
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-02-12 12:03:14 +00:00
Marcel S. Henselin
0c9ecfc670
fix: sqlserver beta fixes (#51)
All checks were successful
Publish / Check GoReleaser config (push) Successful in 11s
Publish / Publish provider (push) Successful in 48m24s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #51
Reviewed-by: Andre_Harms <andre.harms@stackit.cloud>
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-02-12 11:42:37 +00:00
131e1700bb
fix: change identity handling for user & database (#50)
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #50
Reviewed-by: Marcel_Henselin <marcel.henselin@stackit.cloud>
Co-authored-by: Andre Harms <andre.harms@stackit.cloud>
Co-committed-by: Andre Harms <andre.harms@stackit.cloud>
2026-02-11 15:39:20 +00:00
Marcel S. Henselin
86fc98461c
chore: add sqlserveralpha tests (#49)
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #49
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-02-11 15:21:57 +00:00
Marcel S. Henselin
ed7ff0f58e
chore: add tests (#48)
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #48
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-02-11 14:20:41 +00:00
Marcel S. Henselin
f2bffa9ece
chore: add_protocol (#47)
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #47
Reviewed-by: Andre_Harms <andre.harms@stackit.cloud>
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-02-11 09:07:38 +00:00
399e8ccb0c
feat: update sql server flex configuration for user and database (#46)
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #46
Reviewed-by: Marcel_Henselin <marcel.henselin@stackit.cloud>
Co-authored-by: Andre Harms <andre.harms@stackit.cloud>
Co-committed-by: Andre Harms <andre.harms@stackit.cloud>
2026-02-11 09:03:31 +00:00
Marcel S. Henselin
e21fe64326
feat: add_testing (#45)
All checks were successful
Publish / Check GoReleaser config (push) Successful in 13s
Publish / Publish provider (push) Successful in 23m29s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #45
Reviewed-by: Andre_Harms <andre.harms@stackit.cloud>
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-02-10 16:46:21 +00:00
4991897eca
fix: fix mapping tests (#44)
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #44
Reviewed-by: Marcel_Henselin <marcel.henselin@stackit.cloud>
Co-authored-by: Andre Harms <andre.harms@stackit.cloud>
Co-committed-by: Andre Harms <andre.harms@stackit.cloud>
2026-02-10 16:06:10 +00:00
Marcel_Henselin
b737875c68
fix: fix README.md (#42)
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #42
Reviewed-by: Andre_Harms <andre.harms@stackit.cloud>
2026-02-10 13:32:15 +00:00
marcel.henselin
9dbf36dd35
chore: activate darwin and windows builds (#43)
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #43
Co-authored-by: marcel.henselin <marcel.henselin@stackit.cloud>
Co-committed-by: marcel.henselin <marcel.henselin@stackit.cloud>
2026-02-10 13:31:42 +00:00
Marcel S. Henselin
00a43dfb4c
fix: fix wrong identity handling in Read (#41)
All checks were successful
Publish / Check GoReleaser config (push) Successful in 12s
Publish / Publish provider (push) Successful in 7m54s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #41
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-02-10 12:25:19 +00:00
Marcel S. Henselin
b63526b065
chore: regenerate gen files (#40)
All checks were successful
Publish / Check GoReleaser config (push) Successful in 13s
Publish / Publish provider (push) Successful in 19m5s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #40
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-02-10 09:56:54 +00:00
Marcel S. Henselin
68e4c137f1
fix: fix build pipeline error (#38)
Some checks failed
Publish / Check GoReleaser config (push) Successful in 5s
Publish / Publish provider (push) Failing after 4m1s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #38
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-02-10 09:32:06 +00:00
Marcel_Henselin
6e23dab949
feat: create docs upload pipeline (#37)
Some checks failed
Publish / Check GoReleaser config (push) Successful in 14s
Publish / Publish provider (push) Failing after 15m24s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #37
Reviewed-by: Andre_Harms <andre.harms@stackit.cloud>
2026-02-10 08:21:01 +00:00
de019908d2
chore: changed and refactored providers (#36)
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Reviewed-on: #36
Reviewed-by: Marcel_Henselin <marcel.henselin@stackit.cloud>
Co-authored-by: Andre Harms <andre.harms@stackit.cloud>
Co-committed-by: Andre Harms <andre.harms@stackit.cloud>
2026-02-10 08:10:02 +00:00
Marcel S. Henselin
b1b359f436
feat: refactor testing (#35)
Some checks failed
Publish / Check GoReleaser config (push) Successful in 5s
Publish / Publish provider (push) Failing after 3m54s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #35
Reviewed-by: Andre_Harms <andre.harms@stackit.cloud>
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-02-09 07:28:01 +00:00
Marcel S. Henselin
32e41d8b44
feat: testing (#34)
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #34
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-02-06 09:57:51 +00:00
Marcel S. Henselin
c22e758b2c
fix: sqlserver_beta (#33)
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #33
Reviewed-by: Andre_Harms <andre.harms@stackit.cloud>
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-02-05 15:11:41 +00:00
Marcel S. Henselin
581e45eb9c
feat: SQL server beta and templates refactoring (#32)
Some checks failed
Publish / Check GoReleaser config (push) Successful in 5s
Publish / Publish provider (push) Failing after 4m6s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #32
Reviewed-by: Andre_Harms <andre.harms@stackit.cloud>
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-02-05 09:55:32 +00:00
Marcel_Henselin
4549ba63e5
fix: refactor sqlserver to handle encryption correctly (#31)
All checks were successful
Publish / Check GoReleaser config (push) Successful in 6s
Publish / Publish provider (push) Successful in 6m59s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #31
Reviewed-by: Andre_Harms <andre.harms@stackit.cloud>
2026-02-04 07:30:00 +00:00
marcel.henselin
80d1d12278
fix: add missing folder creation in pipeline (#30)
All checks were successful
Publish / Check GoReleaser config (push) Successful in 13s
Publish / Publish provider (push) Successful in 11m17s
Signed-off-by: marcel.henselin <marcel.henselin@stackit.cloud>

## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #30
Co-authored-by: marcel.henselin <marcel.henselin@stackit.cloud>
Co-committed-by: marcel.henselin <marcel.henselin@stackit.cloud>
2026-02-03 15:22:31 +00:00
marcel.henselin
5e9051fb89
fix: update publish pipeline (#29)
Some checks failed
Publish / Check GoReleaser config (push) Successful in 11s
Publish / Publish provider (push) Failing after 8m47s
need to create a folder upfront

Signed-off-by: marcel.henselin <marcel.henselin@stackit.cloud>

## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #29
Co-authored-by: marcel.henselin <marcel.henselin@stackit.cloud>
Co-committed-by: marcel.henselin <marcel.henselin@stackit.cloud>
2026-02-03 15:05:34 +00:00
Marcel_Henselin
e7176b2eef
Merge pull request 'fix: spec files in subfolders and refactored builder' (#28) from fix/cmd_refactor_subfolders_and-version into alpha
Some checks failed
Publish / Check GoReleaser config (push) Successful in 6s
Publish / Publish provider (push) Failing after 4m8s
Reviewed-on: #28
Reviewed-by: Andre_Harms <andre.harms@stackit.cloud>
2026-02-03 08:27:22 +00:00
Marcel S. Henselin
2c0e8e874e fix: spec files in subfolders and refactored builder
Some checks failed
CI Workflow / Check GoReleaser config (pull_request) Successful in 6s
CI Workflow / Test readiness for publishing provider (pull_request) Failing after 6m6s
CI Workflow / CI (pull_request) Failing after 6m26s
CI Workflow / Code coverage report (pull_request) Has been skipped
2026-02-03 09:25:43 +01:00
Marcel S. Henselin
3dbf79c95f
fix: refactor sqlserver handle optional encryption (#27)
All checks were successful
Publish / Check GoReleaser config (push) Successful in 12s
Publish / Publish provider (push) Successful in 17m14s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #27
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-02-02 10:52:21 +00:00
Marcel S. Henselin
a5a388f238
chore: refactor import urls after repo move (#26)
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #26
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-02-02 10:01:27 +00:00
Marcel S. Henselin
cd390b1dfc
fix: fix publisher is creating wrong urls (#25)
All checks were successful
Publish / Check GoReleaser config (push) Successful in 12s
Publish / Publish provider (push) Successful in 6m44s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #25
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-01-30 15:35:32 +00:00
Marcel S. Henselin
9242a9526c
fix: fix publisher (#24)
All checks were successful
Publish / Check GoReleaser config (push) Successful in 9s
Publish / Publish provider (push) Successful in 6m44s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #24
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-01-30 15:05:56 +00:00
Marcel_Henselin
760bcfd658
fix: fix releaser (#23)
Some checks failed
Publish / Check GoReleaser config (push) Successful in 13s
Publish / Publish provider (push) Failing after 28m53s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #23
2026-01-30 14:28:48 +00:00
Marcel S. Henselin
024534da5f
fix: fix releaser to use correct string format in gpg strings (#22)
All checks were successful
Publish / Check GoReleaser config (push) Successful in 9s
Publish / Publish provider (push) Successful in 17m45s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #22
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-01-30 13:50:39 +00:00
Marcel_Henselin
4e479a365b
fix: fix ci pipeline (#21)
All checks were successful
Publish / Check GoReleaser config (push) Successful in 6s
Publish / Publish provider (push) Successful in 6m46s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #21
2026-01-30 13:33:50 +00:00
Marcel S. Henselin
50184f4478
fix: fix releaser to be able to replace a version (#20)
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #20
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-01-30 13:32:42 +00:00
Marcel S. Henselin
8532f09ce2
fix: fix pipelines to quote string (#19)
All checks were successful
Publish / Check GoReleaser config (push) Successful in 23s
Publish / Publish provider (push) Successful in 11m13s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #19
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-01-30 13:12:05 +00:00
Marcel S. Henselin
ee89243b3a
fix: pipeline_fixes (#18)
All checks were successful
Publish / Check GoReleaser config (push) Successful in 9s
Publish / Publish provider (push) Successful in 6m39s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #18
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-01-30 12:48:20 +00:00
Marcel S. Henselin
70f7492043
fix: deactivate release pipeline (#17)
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #17
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-01-30 11:08:35 +00:00
Marcel_Henselin
4153035eae
fix: pgsql_api_updates (#16)
Some checks failed
Publish / Check GoReleaser config (push) Successful in 4s
Release / goreleaser (push) Failing after 23s
Publish / Publish provider (push) Failing after 6m29s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #16
2026-01-30 10:59:24 +00:00
Marcel S. Henselin
f3d66c7569
fix: refactor postgres genereated files (#15)
Some checks failed
Publish / Check GoReleaser config (push) Successful in 4s
Release / goreleaser (push) Failing after 28s
Publish / Publish provider (push) Failing after 6m28s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #15
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-01-30 10:37:50 +00:00
Marcel S. Henselin
a9df5b0ff5
fix: refactor publish command (#14)
Some checks failed
Publish / Check GoReleaser config (push) Successful in 5s
Release / goreleaser (push) Failing after 27s
Publish / Publish provider (push) Failing after 4m4s
feat: add connection info

fix: prevent postgresql from failing when encryption is empty

## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #14
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-01-30 10:15:49 +00:00
Marcel S. Henselin
5ec2ab8c67
fix: refactor publish pipeline (#13)
Some checks failed
Publish / Check GoReleaser config (push) Successful in 5s
Release / goreleaser (push) Failing after 24s
Publish / Publish provider (push) Successful in 6m38s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #13
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-01-29 17:09:46 +00:00
Marcel S. Henselin
bb54206ba9
fix: refactor publish command (#12)
Some checks failed
Publish / Check GoReleaser config (push) Successful in 5s
Release / goreleaser (push) Failing after 26s
Publish / Publish provider (push) Successful in 6m49s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #12
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-01-29 16:48:31 +00:00
Marcel S. Henselin
7fe135f337
fix: refactor publish command (#11)
Some checks failed
Publish / Check GoReleaser config (push) Successful in 6s
Release / goreleaser (push) Failing after 28s
Publish / Publish provider (push) Successful in 6m50s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #11
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-01-29 16:22:18 +00:00
Marcel S. Henselin
0a21d9f0f2
fix: refactor package generation (#10)
Some checks failed
Publish / Check GoReleaser config (push) Successful in 5s
Release / goreleaser (push) Failing after 27s
Publish / Publish provider (push) Failing after 6m43s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #10
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-01-29 16:00:09 +00:00
Marcel S. Henselin
37ba538a8e
fix: refactor pipeline (#9)
Some checks failed
Publish / Check GoReleaser config (push) Successful in 6s
Release / goreleaser (push) Failing after 26s
Publish / Publish provider (push) Failing after 3m57s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #9
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-01-29 15:23:59 +00:00
Marcel S. Henselin
f986d919da
fix: pipeline_fix (#8)
Some checks failed
Publish / Check GoReleaser config (push) Successful in 5s
Release / goreleaser (push) Failing after 27s
Publish / Publish provider (push) Failing after 6m51s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #8
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-01-29 15:14:17 +00:00
Marcel S. Henselin
5e303ba8dd
fix: do not use SNAPSHOT on push tags (#6)
chore: disable some platforms for now

## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #6
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-01-29 15:04:42 +00:00
Marcel S. Henselin
3149537a4a
fix: need to create key file from secret (#5)
Some checks failed
Release / goreleaser (push) Failing after 26s
Publish / Check GoReleaser config (push) Successful in 6s
Publish / Publish provider (push) Failing after 12m45s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #5
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-01-29 14:30:13 +00:00
Marcel S. Henselin
9f41c4da7f
feat: auto generated files and new structure (#4)
Some checks failed
Publish / Check GoReleaser config (push) Successful in 4s
Release / goreleaser (push) Failing after 29s
Publish / Publish provider (push) Failing after 4m24s
## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #4
Reviewed-by: Andre_Harms <andre.harms@stackit.cloud>
Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
Co-committed-by: Marcel S. Henselin <marcel.henselin@stackit.cloud>
2026-01-29 14:10:25 +00:00
536 changed files with 55374 additions and 56539 deletions

View file

@ -1,24 +0,0 @@
# NOTE: This file is for HashiCorp specific licensing automation and can be deleted after creating a new repo with this template.
schema_version = 1
project {
license = "Apache-2.0"
copyright_year = 2025
header_ignore = [
# internal catalog metadata (prose)
"META.d/**/*.yaml",
# examples used within documentation (prose)
"examples/**",
# GitHub issue template configuration
".github/ISSUE_TEMPLATE/*.yml",
# golangci-lint tooling configuration
".golangci.yml",
# GoReleaser tooling configuration
".goreleaser.yml",
]
}

1
.github/actions/acc_test/README.md vendored Normal file
View file

@ -0,0 +1 @@
# acceptance test action

262
.github/actions/acc_test/action.yaml vendored Normal file
View file

@ -0,0 +1,262 @@
name: Acceptance Testing
description: "Acceptance Testing pipeline"
inputs:
test_timeout_string:
description: "string that determines the timeout (default: 45m)"
default: '45m'
required: true
go-version:
description: "go version to install"
default: '1.25'
required: true
project_id:
description: "STACKIT project ID for tests"
required: true
project_user_email:
required: true
description: "project user email for acc testing"
tf_acc_kek_key_id:
description: "KEK key ID"
required: true
tf_acc_kek_key_ring_id:
description: "KEK key ring ID"
required: true
tf_acc_kek_key_version:
description: "KEK key version"
required: true
tf_acc_kek_service_account:
description: "KEK service account email"
required: true
region:
description: "STACKIT region for tests"
default: 'eu01'
required: true
service_account_json_content:
description: "STACKIT service account JSON file contents"
required: true
default: ""
service_account_json_content_b64:
description: "STACKIT service account JSON file contents"
required: true
default: ""
service_account_json_file_path:
description: "STACKIT service account JSON file contents"
required: true
default: 'service_account.json'
test_file:
description: "testfile to run"
default: ''
#outputs:
# random-number:
# description: "Random number"
# value: ${{ steps.random-number-generator.outputs.random-number }}
runs:
using: "composite"
steps:
# - name: Random Number Generator
# id: random-number-generator
# run: echo "random-number=$(echo $RANDOM)" >> $GITHUB_OUTPUT
# shell: bash
- name: Install needed tools
shell: bash
run: |
echo "::group::apt install"
set -e
apt-get -y -qq update >apt_update.log 2>apt_update_err.log
if [ $? -ne 0 ]; then
cat apt_update.log apt_update_err.log
fi
apt-get -y -qq install jq python3 python3-pip python-is-python3 s3cmd git make wget >apt_get.log 2>apt_get_err.log
if [ $? -ne 0 ]; then
cat apt_get.log apt_get_err.log
fi
echo "::endgroup::"
- name: Setup JAVA
uses: actions/setup-java@v5
with:
distribution: 'temurin' # See 'Supported distributions' for available options
java-version: '21'
- name: Install Go ${{ inputs.go-version }}
uses: actions/setup-go@v6
with:
# go-version: ${{ inputs.go-version }}
check-latest: true
go-version-file: 'go.mod'
- name: Determine GOMODCACHE
shell: bash
id: goenv
run: |
set -e
echo "gomodcache=$(go env GOMODCACHE)" >> "$GITHUB_OUTPUT"
- name: Restore cached GO pkg
id: cache-gopkg
uses: actions/cache/restore@v5
with:
path: "${{ steps.goenv.outputs.gomodcache }}"
key: ${{ runner.os }}-gopkg
- name: Install go tools
if: steps.cache-gopkg.outputs.cache-hit != 'true'
shell: bash
run: |
echo "::group::go install"
set -e
go mod download
go install golang.org/x/tools/cmd/goimports@latest
go install github.com/hashicorp/terraform-plugin-codegen-framework/cmd/tfplugingen-framework@latest
go install github.com/hashicorp/terraform-plugin-codegen-openapi/cmd/tfplugingen-openapi@latest
go install github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs@latest
go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest
echo "::endgroup::"
- name: Run go mod tidy
shell: bash
run: go mod tidy
- name: Save GO package Cache
id: cache-gopkg-save
uses: actions/cache/save@v5
with:
path: |
${{ steps.goenv.outputs.gomodcache }}
key: ${{ runner.os }}-gopkg
- name: Creating service_account file from json input
if: inputs.service_account_json_content != ''
shell: bash
run: |
echo "::group::create service account file"
set -e
set -o pipefail
jsonFile="${{ inputs.service_account_json_file_path }}"
jsonFile="${jsonFile:-x}"
if [ "${jsonFile}" == "x" ]; then
echo "no service account file path provided"
exit 1
fi
if [ ! -f "${jsonFile}" ]; then
echo "creating service account file '${{ inputs.service_account_json_file_path }}'"
echo "${{ inputs.service_account_json_content }}" > stackit/"${{ inputs.service_account_json_file_path }}"
fi
ls -l stackit/"${{ inputs.service_account_json_file_path }}"
echo "::endgroup::"
- name: Creating service_account file from base64 json input
if: inputs.service_account_json_content_b64 != ''
shell: bash
run: |
echo "::group::create service account file"
set -e
set -o pipefail
jsonFile="${{ inputs.service_account_json_file_path }}"
jsonFile="${jsonFile:-x}"
if [ "${jsonFile}" == "x" ]; then
echo "no service account file path provided"
exit 1
fi
if [ ! -f "${jsonFile}" ]; then
echo "creating service account file '${{ inputs.service_account_json_file_path }}'"
echo "${{ inputs.service_account_json_content_b64 }}" | base64 -d > stackit/"${{ inputs.service_account_json_file_path }}"
fi
ls -l stackit/"${{ inputs.service_account_json_file_path }}"
echo "::endgroup::"
- name: Run acceptance test file
if: ${{ inputs.test_file != '' }}
shell: bash
run: |
echo "::group::go test file"
set -e
set -o pipefail
echo "Running acceptance tests for the terraform provider"
cd stackit || exit 1
TF_ACC=1 \
TF_ACC_PROJECT_ID=${TF_ACC_PROJECT_ID} \
TF_ACC_REGION=${TF_ACC_REGION} \
TF_ACC_TEST_PROJECT_USER_EMAIL=${TF_ACC_TEST_PROJECT_USER_EMAIL} \
TF_ACC_SERVICE_ACCOUNT_FILE="${PWD}/${{ inputs.service_account_json_file_path }}" \
TF_ACC_KEK_KEY_ID=${TF_ACC_KEK_KEY_ID} \
TF_ACC_KEK_KEY_RING_ID=${TF_ACC_KEK_KEY_RING_ID} \
TF_ACC_KEK_KEY_VERSION=${TF_ACC_KEK_KEY_VERSION} \
TF_ACC_KEK_SERVICE_ACCOUNT=${TF_ACC_KEK_SERVICE_ACCOUNT} \
go test ${{ inputs.test_file }} -count=1 -timeout=${{ inputs.test_timeout_string }}
echo "::endgroup::"
env:
TF_ACC_PROJECT_ID: ${{ inputs.project_id }}
TF_ACC_REGION: ${{ inputs.region }}
TF_ACC_TEST_PROJECT_USER_EMAIL: ${{ inputs.project_user_email }}
TF_ACC_KEK_KEY_ID: ${{ inputs.tf_acc_kek_key_id }}
TF_ACC_KEK_KEY_RING_ID: ${{ inputs.tf_acc_kek_key_ring_id }}
TF_ACC_KEK_KEY_VERSION: ${{ inputs.tf_acc_kek_key_version }}
TF_ACC_KEK_SERVICE_ACCOUNT: ${{ inputs.tf_acc_kek_service_account }}
# - name: Run test action
# if: ${{ inputs.test_file == '' }}
# env:
# TF_ACC: 1
# TF_ACC_PROJECT_ID: ${{ inputs.project_id }}
# TF_ACC_REGION: ${{ inputs.region }}
# TF_ACC_TEST_PROJECT_USER_EMAIL: ${{ inputs.project_user_email }}
# TF_ACC_KEK_KEY_ID: ${{ inputs.tf_acc_kek_key_id }}
# TF_ACC_KEK_KEY_RING_ID: ${{ inputs.tf_acc_kek_key_ring_id }}
# TF_ACC_KEK_KEY_VERSION: ${{ inputs.tf_acc_kek_key_version }}
# TF_ACC_KEK_SERVICE_ACCOUNT: ${{ inputs.tf_acc_kek_service_account }}
# TF_ACC_SERVICE_ACCOUNT_FILE: "${PWD}/${{ inputs.service_account_json_file_path }}"
# uses: robherley/go-test-action@v0.1.0
# with:
# testArguments: "./... -timeout 45m"
- name: Run acceptance tests
if: ${{ inputs.test_file == '' }}
shell: bash
run: |
echo "::group::go test all"
set -e
set -o pipefail
echo "Running acceptance tests for the terraform provider"
cd stackit || exit 1
TF_ACC=1 \
TF_ACC_PROJECT_ID=${TF_ACC_PROJECT_ID} \
TF_ACC_REGION=${TF_ACC_REGION} \
TF_ACC_TEST_PROJECT_USER_EMAIL=${TF_ACC_TEST_PROJECT_USER_EMAIL} \
TF_ACC_SERVICE_ACCOUNT_FILE="${PWD}/${{ inputs.service_account_json_file_path }}" \
TF_ACC_KEK_KEY_ID=${TF_ACC_KEK_KEY_ID} \
TF_ACC_KEK_KEY_RING_ID=${TF_ACC_KEK_KEY_RING_ID} \
TF_ACC_KEK_KEY_VERSION=${TF_ACC_KEK_KEY_VERSION} \
TF_ACC_KEK_SERVICE_ACCOUNT=${TF_ACC_KEK_SERVICE_ACCOUNT} \
go test ./... -count=1 -timeout=${{ inputs.test_timeout_string }}
echo "::endgroup::"
env:
TF_ACC_PROJECT_ID: ${{ inputs.project_id }}
TF_ACC_REGION: ${{ inputs.region }}
TF_ACC_TEST_PROJECT_USER_EMAIL: ${{ inputs.project_user_email }}
TF_ACC_KEK_KEY_ID: ${{ inputs.tf_acc_kek_key_id }}
TF_ACC_KEK_KEY_RING_ID: ${{ inputs.tf_acc_kek_key_ring_id }}
TF_ACC_KEK_KEY_VERSION: ${{ inputs.tf_acc_kek_key_version }}
TF_ACC_KEK_SERVICE_ACCOUNT: ${{ inputs.tf_acc_kek_service_account }}

View file

@ -3,14 +3,89 @@ description: "Build pipeline"
inputs:
go-version:
description: "Go version to install"
default: '1.25'
required: true
java-distribution:
description: "JAVA distribution to use (default: temurin)"
default: 'temurin'
java-version:
description: "JAVA version to use (default: 21)"
default: '21'
runs:
using: "composite"
steps:
- name: Install Go ${{ inputs.go-version }}
uses: actions/setup-go@v5
with:
go-version: ${{ inputs.go-version }}
- name: Install project tools and dependencies
- name: Install needed tools
shell: bash
run: make project-tools
run: |
set -e
apt-get -y -qq update
apt-get -y -qq install jq python3 python3-pip python-is-python3 s3cmd git make wget unzip bc
- name: Checkout
uses: actions/checkout@v6
- name: Install Go ${{ inputs.go-version }}
uses: actions/setup-go@v6
with:
# go-version: ${{ inputs.go-version }}
check-latest: true
go-version-file: 'go.mod'
- name: Determine GOMODCACHE
shell: bash
id: goenv
run: |
set -e
# echo "::set-output name=gomodcache::$(go env GOMODCACHE)"
echo "gomodcache=$(go env GOMODCACHE)" >> "$GITHUB_OUTPUT"
- name: Restore cached GO pkg
id: cache-gopkg
uses: actions/cache/restore@v5
with:
path: "${{ steps.goenv.outputs.gomodcache }}"
key: ${{ runner.os }}-gopkg
- name: Install go tools
if: steps.cache-gopkg.outputs.cache-hit != 'true'
shell: bash
run: |
set -e
go install golang.org/x/tools/cmd/goimports@latest
go install github.com/hashicorp/terraform-plugin-codegen-framework/cmd/tfplugingen-framework@latest
go install github.com/hashicorp/terraform-plugin-codegen-openapi/cmd/tfplugingen-openapi@latest
go install github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs@latest
# - name: Run build pkg directory
# shell: bash
# run: |
# set -e
# go run generator/main.go build
- name: Get all go packages
if: steps.cache-gopkg.outputs.cache-hit != 'true'
shell: bash
run: |
set -e
go get ./...
- name: Save Cache
id: cache-gopkg-save
uses: actions/cache/save@v5
with:
path: |
${{ steps.goenv.outputs.gomodcache }}
key: ${{ runner.os }}-gopkg
- name: Setup JAVA ${{ inputs.java-distribution }} ${{ inputs.go-version }}
uses: actions/setup-java@v5
with:
distribution: ${{ inputs.java-distribution }} # See 'Supported distributions' for available options
java-version: ${{ inputs.java-version }}
- name: Run make to build app
shell: bash
run: |
set -e
make build

View file

@ -0,0 +1,71 @@
name: 'Setup Go and cache dependencies'
author: 'Forgejo authors, Marcel S. Henselin'
description: |
Wrap the setup-go with improved dependency caching.
inputs:
username:
description: 'User for which to manage the dependency cache'
default: root
go-version:
description: "go version to install"
default: '1.25'
required: true
runs:
using: "composite"
steps:
- name: "Install zstd for faster caching"
shell: bash
run: |
apt-get update -qq
apt-get -q install -qq -y zstd
- name: "Set up Go using setup-go"
uses: https://code.forgejo.org/actions/setup-go@v6
id: go-version
with:
# go-version: ${{ inputs.go-version }}
check-latest: true # Always check for the latest patch release
go-version-file: "go.mod"
# do not cache dependencies, we do this manually
cache: false
- name: "Get go environment information"
shell: bash
id: go-environment
run: |
chmod 755 $HOME # ensure ${RUN_AS_USER} has permission when go is located in $HOME
export GOROOT="$(go env GOROOT)"
echo "modcache=$(su ${RUN_AS_USER} -c '${GOROOT}/bin/go env GOMODCACHE')" >> "$GITHUB_OUTPUT"
echo "cache=$(su ${RUN_AS_USER} -c '${GOROOT}/bin/go env GOCACHE')" >> "$GITHUB_OUTPUT"
env:
RUN_AS_USER: ${{ inputs.username }}
GO_VERSION: ${{ steps.go-version.outputs.go-version }}
- name: "Create cache folders with correct permissions (for non-root users)"
shell: bash
if: inputs.username != 'root'
# when the cache is restored, only the permissions of the last part are restored
# so assuming that /home/user exists and we are restoring /home/user/go/pkg/mod,
# both folders will have the correct permissions, but
# /home/user/go and /home/user/go/pkg might be owned by root
run: |
su ${RUN_AS_USER} -c 'mkdir -p "${MODCACHE_DIR}" "${CACHE_DIR}"'
env:
RUN_AS_USER: ${{ inputs.username }}
MODCACHE_DIR: ${{ steps.go-environment.outputs.modcache }}
CACHE_DIR: ${{ steps.go-environment.outputs.cache }}
- name: "Restore Go dependencies from cache or mark for later caching"
id: cache-deps
uses: https://code.forgejo.org/actions/cache@v5
with:
key: setup-cache-go-deps-${{ runner.os }}-${{ inputs.username }}-${{ steps.go-version.outputs.go_version }}-${{ hashFiles('go.sum', 'go.mod') }}
restore-keys: |
setup-cache-go-deps-${{ runner.os }}-${{ inputs.username }}-${{ steps.go-version.outputs.go_version }}-
setup-cache-go-deps-${{ runner.os }}-${{ inputs.username }}-
path: |
${{ steps.go-environment.outputs.modcache }}
${{ steps.go-environment.outputs.cache }}

View file

@ -14,10 +14,10 @@ import (
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
"github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/core"
fooUtils "github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/services/foo/utils"
"github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/utils"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
fooUtils "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/foo/utils"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
"github.com/stackitcloud/stackit-sdk-go/services/foo" // Import service "foo" from the STACKIT SDK for Go
"github.com/stackitcloud/stackit-sdk-go/services/foo/wait" // Import service "foo" waiters from the STACKIT SDK for Go (in case the service API has asynchronous endpoints)

View file

@ -7,10 +7,10 @@ import (
"fmt"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/core"
"github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/utils"
"github.com/stackitcloud/stackit-sdk-go/core/config"
"github.com/stackitcloud/stackit-sdk-go/services/foo"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
)
func ConfigureClient(ctx context.Context, providerData *core.ProviderData, diags *diag.Diagnostics) *foo.APIClient {

View file

@ -1,90 +0,0 @@
name: CI Workflow
on:
pull_request:
workflow_dispatch:
push:
branches:
- main
env:
GO_VERSION: "1.25"
CODE_COVERAGE_FILE_NAME: "coverage.out" # must be the same as in Makefile
CODE_COVERAGE_ARTIFACT_NAME: "code-coverage"
jobs:
main:
name: CI
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build
uses: ./.github/actions/build
with:
go-version: ${{ env.GO_VERSION }}
- name: Setup Terraform
uses: hashicorp/setup-terraform@v2
with:
terraform_wrapper: false
- name: "Ensure docs are up-to-date"
if: ${{ github.event_name == 'pull_request' }}
run: ./scripts/check-docs.sh
continue-on-error: true
- name: "Run go mod tidy"
if: ${{ github.event_name == 'pull_request' }}
run: go mod tidy
- name: golangci-lint
uses: golangci/golangci-lint-action@v9
with:
version: v2.7
args: --config=golang-ci.yaml --allow-parallel-runners --timeout=5m
- name: Lint
run: make lint
- name: Test
run: make test
- name: Archive code coverage results
uses: actions/upload-artifact@v4
with:
name: ${{ env.CODE_COVERAGE_ARTIFACT_NAME }}
path: "stackit/${{ env.CODE_COVERAGE_FILE_NAME }}"
config:
name: Check GoReleaser config
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Check GoReleaser
uses: goreleaser/goreleaser-action@v6
with:
args: check
code_coverage:
name: "Code coverage report"
if: github.event_name == 'pull_request' # Do not run when workflow is triggered by push to main branch
runs-on: ubuntu-latest
needs: main
permissions:
contents: read
actions: read # to download code coverage results from "main" job
pull-requests: write # write permission needed to comment on PR
steps:
- name: Check new code coverage
uses: fgrosse/go-coverage-report@v1.2.0
continue-on-error: true # Add this line to prevent pipeline failures in forks
with:
coverage-artifact-name: ${{ env.CODE_COVERAGE_ARTIFACT_NAME }}
coverage-file-name: ${{ env.CODE_COVERAGE_FILE_NAME }}
root-package: 'github.com/stackitcloud/terraform-provider-stackit'

290
.github/workflows/ci.yaml.bak vendored Normal file
View file

@ -0,0 +1,290 @@
name: CI Workflow
on:
pull_request:
branches:
- alpha
- main
workflow_dispatch:
schedule:
# every sunday at 00:00
# - cron: '0 0 * * 0'
# every day at 00:00
- cron: '0 0 * * *'
push:
branches:
- '!main'
- '!alpha'
env:
GO_VERSION: "1.25"
CODE_COVERAGE_FILE_NAME: "coverage.out" # must be the same as in Makefile
CODE_COVERAGE_ARTIFACT_NAME: "code-coverage"
jobs:
runner_test:
name: "Test STACKIT runner"
runs-on: stackit-docker
steps:
- name: Install needed tools
run: |
apt-get -y -qq update
apt-get -y -qq install jq python3 python3-pip python-is-python3 s3cmd git make wget
- name: Setup Go
uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
- name: Install go tools
run: |
go install golang.org/x/tools/cmd/goimports@latest
go install github.com/hashicorp/terraform-plugin-codegen-framework/cmd/tfplugingen-framework@latest
go install github.com/hashicorp/terraform-plugin-codegen-openapi/cmd/tfplugingen-openapi@latest
- name: Setup JAVA
uses: actions/setup-java@v5
with:
distribution: 'temurin' # See 'Supported distributions' for available options
java-version: '21'
- name: Checkout
uses: actions/checkout@v6
- name: Run build pkg directory
run: |
go run cmd/main.go build
publish_test:
name: "Test readiness for publishing provider"
needs: config
runs-on: ubuntu-latest
permissions:
actions: read # Required to identify workflow run.
checks: write # Required to add status summary.
contents: read # Required to checkout repository.
pull-requests: write # Required to add PR comment.
steps:
- name: Install needed tools
run: |
apt-get -y -qq update
apt-get -y -qq install jq python3 python3-pip python-is-python3 s3cmd git make wget
- name: Setup Go
uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
- name: Install go tools
run: |
go install golang.org/x/tools/cmd/goimports@latest
go install github.com/hashicorp/terraform-plugin-codegen-framework/cmd/tfplugingen-framework@latest
go install github.com/hashicorp/terraform-plugin-codegen-openapi/cmd/tfplugingen-openapi@latest
- name: Setup JAVA
uses: actions/setup-java@v5
with:
distribution: 'temurin' # See 'Supported distributions' for available options
java-version: '21'
- name: Checkout
uses: actions/checkout@v6
- name: Run build pkg directory
run: |
go run cmd/main.go build
- name: Set up s3cfg
run: |
cat <<'EOF' >> ~/.s3cfg
[default]
host_base = https://object.storage.eu01.onstackit.cloud
host_bucket = https://%(bucket).object.storage.eu01.onstackit.cloud
check_ssl_certificate = False
access_key = ${{ secrets.S3_ACCESS_KEY }}
secret_key = ${{ secrets.S3_SECRET_KEY }}
EOF
- name: Import GPG key
run: |
echo "${{ secrets.PRIVATE_KEY_PEM }}" > ~/private.key.pem
gpg --import ~/private.key.pem
rm ~/private.key.pem
- name: Run GoReleaser with SNAPSHOT
id: goreleaser
env:
GITHUB_TOKEN: ${{ env.FORGEJO_TOKEN }}
GPG_FINGERPRINT: ${{ secrets.GPG_FINGERPRINT }}
uses: goreleaser/goreleaser-action@v6
with:
args: release --skip publish --clean --snapshot
- name: Prepare key file
run: |
echo "${{ secrets.PUBLIC_KEY_PEM }}" >public_key.pem
- name: Prepare provider directory structure
run: |
VERSION=$(jq -r .version < dist/metadata.json)
go run cmd/main.go \
publish \
--namespace=mhenselin \
--providerName=stackitprivatepreview \
--repoName=terraform-provider-stackitprivatepreview \
--domain=tfregistry.sysops.stackit.rocks \
--gpgFingerprint="${{ secrets.GPG_FINGERPRINT }}" \
--gpgPubKeyFile=public_key.pem \
--version=${VERSION}
testing:
name: CI run tests
runs-on: ubuntu-latest
needs: config
env:
TF_ACC_PROJECT_ID: ${{ vars.TF_ACC_PROJECT_ID }}
TF_ACC_REGION: ${{ vars.TF_ACC_REGION }}
TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_EMAIL: ${{ vars.TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_EMAIL }}
TF_ACC_SERVICE_ACCOUNT_FILE: "~/service_account.json"
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Build
uses: ./.github/actions/build
with:
go-version: ${{ env.GO_VERSION }}
- name: Setup Terraform
uses: hashicorp/setup-terraform@v2
with:
terraform_wrapper: false
- name: Create service account json file
if: ${{ github.event_name == 'pull_request' }}
run: |
echo "${{ secrets.TF_ACC_SERVICE_ACCOUNT_JSON }}" >~/service_account.json
- name: Run go mod tidy
if: ${{ github.event_name == 'pull_request' }}
run: go mod tidy
- name: Testing
run: make test
- name: Acceptance Testing
env:
TF_ACC: "1"
if: ${{ github.event_name == 'pull_request' }}
run: make test-acceptance-tf
- name: Check coverage threshold
shell: bash
run: |
make coverage
COVERAGE=$(go tool cover -func=coverage.out | grep total | awk '{print $3}' | sed 's/%//')
echo "Coverage: $COVERAGE%"
if (( $(echo "$COVERAGE < 80" | bc -l) )); then
echo "Coverage is below 80%"
# exit 1
fi
- name: Archive code coverage results
uses: actions/upload-artifact@v4
with:
name: ${{ env.CODE_COVERAGE_ARTIFACT_NAME }}
path: "stackit/${{ env.CODE_COVERAGE_FILE_NAME }}"
main:
if: ${{ github.event_name != 'schedule' }}
name: CI run build and linting
runs-on: ubuntu-latest
needs: config
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Build
uses: ./.github/actions/build
with:
go-version: ${{ env.GO_VERSION }}
- name: Setup Terraform
uses: hashicorp/setup-terraform@v2
with:
terraform_wrapper: false
- name: "Ensure docs are up-to-date"
if: ${{ github.event_name == 'pull_request' }}
run: ./scripts/check-docs.sh
continue-on-error: true
- name: "Run go mod tidy"
if: ${{ github.event_name == 'pull_request' }}
run: go mod tidy
- name: golangci-lint
uses: golangci/golangci-lint-action@v9
with:
version: v2.9
args: --config=golang-ci.yaml --allow-parallel-runners --timeout=5m
continue-on-error: true
- name: Linting
run: make lint
continue-on-error: true
# - name: Testing
# run: make test
#
# - name: Acceptance Testing
# if: ${{ github.event_name == 'pull_request' }}
# run: make test-acceptance-tf
#
# - name: Check coverage threshold
# shell: bash
# run: |
# make coverage
# COVERAGE=$(go tool cover -func=coverage.out | grep total | awk '{print $3}' | sed 's/%//')
# echo "Coverage: $COVERAGE%"
# if (( $(echo "$COVERAGE < 80" | bc -l) )); then
# echo "Coverage is below 80%"
# # exit 1
# fi
# - name: Archive code coverage results
# uses: actions/upload-artifact@v4
# with:
# name: ${{ env.CODE_COVERAGE_ARTIFACT_NAME }}
# path: "stackit/${{ env.CODE_COVERAGE_FILE_NAME }}"
config:
if: ${{ github.event_name != 'schedule' }}
name: Check GoReleaser config
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Check GoReleaser
uses: goreleaser/goreleaser-action@v6
with:
args: check
code_coverage:
name: "Code coverage report"
if: github.event_name == 'pull_request' # Do not run when workflow is triggered by push to main branch
runs-on: ubuntu-latest
needs: main
permissions:
contents: read
actions: read # to download code coverage results from "main" job
pull-requests: write # write permission needed to comment on PR
steps:
- name: Check new code coverage
uses: fgrosse/go-coverage-report@v1.2.0
continue-on-error: true # Add this line to prevent pipeline failures in forks
with:
coverage-artifact-name: ${{ env.CODE_COVERAGE_ARTIFACT_NAME }}
coverage-file-name: ${{ env.CODE_COVERAGE_FILE_NAME }}
root-package: 'github.com/stackitcloud/terraform-provider-stackit'

343
.github/workflows/ci_new.yaml vendored Normal file
View file

@ -0,0 +1,343 @@
name: CI Workflow
on:
pull_request:
branches:
- alpha
- main
workflow_dispatch:
schedule:
# every sunday at 00:00
# - cron: '0 0 * * 0'
# every day at 00:00
- cron: '0 0 * * *'
push:
branches:
- '!main'
- '!alpha'
paths:
- '!.github'
env:
GO_VERSION: "1.25"
CODE_COVERAGE_FILE_NAME: "coverage.out" # must be the same as in Makefile
CODE_COVERAGE_ARTIFACT_NAME: "code-coverage"
jobs:
config:
if: ${{ github.event_name != 'schedule' }}
name: Check GoReleaser config
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Check GoReleaser
uses: goreleaser/goreleaser-action@v7
with:
args: check
prepare:
name: Prepare GO cache
runs-on: ubuntu-latest
permissions:
actions: read # Required to identify workflow run.
checks: write # Required to add status summary.
contents: read # Required to checkout repository.
pull-requests: write # Required to add PR comment.
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install Go ${{ inputs.go-version }}
id: go-install
uses: actions/setup-go@v6
with:
# go-version: ${{ inputs.go-version }}
check-latest: true
go-version-file: 'go.mod'
- name: Determine GOMODCACHE
shell: bash
id: goenv
run: |
set -e
# echo "::set-output name=gomodcache::$(go env GOMODCACHE)"
echo "gomodcache=$(go env GOMODCACHE)" >> "$GITHUB_OUTPUT"
- name: Restore cached GO pkg
id: cache-gopkg
uses: actions/cache/restore@v5
with:
path: "${{ steps.goenv.outputs.gomodcache }}"
key: ${{ runner.os }}-gopkg
- name: Install go tools
if: steps.cache-gopkg.outputs.cache-hit != 'true'
run: |
go install golang.org/x/tools/cmd/goimports@latest
go install github.com/hashicorp/terraform-plugin-codegen-framework/cmd/tfplugingen-framework@latest
go install github.com/hashicorp/terraform-plugin-codegen-openapi/cmd/tfplugingen-openapi@latest
- name: Get all go packages
if: steps.cache-gopkg.outputs.cache-hit != 'true'
shell: bash
run: |
set -e
go get ./...
- name: Save Cache
if: steps.cache-gopkg.outputs.cache-hit != 'true'
id: cache-gopkg-save
uses: actions/cache/save@v5
with:
path: |
${{ steps.goenv.outputs.gomodcache }}
key: ${{ runner.os }}-gopkg
publish_test:
name: "Test readiness for publishing provider"
needs:
- config
- prepare
runs-on: ubuntu-latest
permissions:
actions: read # Required to identify workflow run.
checks: write # Required to add status summary.
contents: read # Required to checkout repository.
pull-requests: write # Required to add PR comment.
steps:
- name: Install needed tools
run: |
apt-get -y -qq update
apt-get -y -qq install jq python3 python3-pip python-is-python3 s3cmd git make wget unzip bc
- name: Checkout
uses: actions/checkout@v6
- name: Setup Go
uses: actions/setup-go@v6
with:
# go-version: ${{ env.GO_VERSION }}
check-latest: true
go-version-file: 'go.mod'
- name: Install go tools
run: |
go install golang.org/x/tools/cmd/goimports@latest
go install github.com/hashicorp/terraform-plugin-codegen-framework/cmd/tfplugingen-framework@latest
go install github.com/hashicorp/terraform-plugin-codegen-openapi/cmd/tfplugingen-openapi@latest
- name: Setup JAVA
uses: actions/setup-java@v5
with:
distribution: 'temurin' # See 'Supported distributions' for available options
java-version: '21'
# - name: Run build pkg directory
# run: |
# go run generator/main.go build
- name: Set up s3cfg
run: |
cat <<'EOF' >> ~/.s3cfg
[default]
host_base = https://object.storage.eu01.onstackit.cloud
host_bucket = https://%(bucket).object.storage.eu01.onstackit.cloud
check_ssl_certificate = False
access_key = ${{ secrets.S3_ACCESS_KEY }}
secret_key = ${{ secrets.S3_SECRET_KEY }}
EOF
- name: Import GPG key
run: |
echo "${{ secrets.PRIVATE_KEY_PEM }}" > ~/private.key.pem
gpg --import ~/private.key.pem
rm ~/private.key.pem
- name: Run GoReleaser with SNAPSHOT
id: goreleaser
env:
GITHUB_TOKEN: ${{ env.FORGEJO_TOKEN }}
GPG_FINGERPRINT: ${{ secrets.GPG_FINGERPRINT }}
uses: goreleaser/goreleaser-action@v7
with:
args: release --skip publish --clean --snapshot
- name: Prepare key file
run: |
echo "${{ secrets.PUBLIC_KEY_PEM }}" >public_key.pem
- name: Prepare provider directory structure
run: |
VERSION=$(jq -r .version < dist/metadata.json)
go run generator/main.go \
publish \
--namespace=mhenselin \
--providerName=stackitprivatepreview \
--repoName=terraform-provider-stackitprivatepreview \
--domain=tfregistry.sysops.stackit.rocks \
--gpgFingerprint="${{ secrets.GPG_FINGERPRINT }}" \
--gpgPubKeyFile=public_key.pem \
--version=${VERSION}
testing:
name: CI run tests
runs-on: ubuntu-latest
needs:
- config
- prepare
env:
TF_ACC_PROJECT_ID: ${{ vars.TF_ACC_PROJECT_ID }}
TF_ACC_ORGANIZATION_ID: ${{ vars.TF_ACC_ORGANIZATION_ID }}
TF_ACC_REGION: ${{ vars.TF_ACC_REGION }}
TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_EMAIL: ${{ vars.TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_EMAIL }}
TF_ACC_SERVICE_ACCOUNT_FILE: "~/service_account.json"
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Build
uses: ./.github/actions/build
with:
go-version: ${{ env.GO_VERSION }}
- name: Setup Terraform
uses: hashicorp/setup-terraform@v2
with:
terraform_wrapper: false
- name: Create service account json file
if: ${{ github.event_name == 'pull_request' }}
run: |
echo "${{ secrets.TF_ACC_SERVICE_ACCOUNT_JSON }}" >~/.service_account.json
- name: Run go mod tidy
if: ${{ github.event_name == 'pull_request' }}
run: go mod tidy
- name: Testing
run: |
TF_ACC_SERVICE_ACCOUNT_FILE=~/.service_account.json
export TF_ACC_SERVICE_ACCOUNT_FILE
make test
# - name: Acceptance Testing
# env:
# TF_ACC: "1"
# if: ${{ github.event_name == 'pull_request' }}
# run: |
# TF_ACC_SERVICE_ACCOUNT_FILE=~/.service_account.json
# export TF_ACC_SERVICE_ACCOUNT_FILE
# make test-acceptance-tf
- name: Run Test
if: ${{ github.event_name == 'pull_request' }}
uses: ./.github/actions/acc_test
with:
go-version: ${{ env.GO_VERSION }}
project_id: ${{ vars.TF_ACC_PROJECT_ID }}
region: ${{ vars.TF_ACC_REGION }}
service_account_json_content_b64: "${{ secrets.TF_ACC_SERVICE_ACCOUNT_JSON_B64 }}"
project_user_email: ${{ vars.TEST_PROJECT_USER_EMAIL }}
tf_acc_kek_key_id: ${{ vars.TF_ACC_KEK_KEY_ID }}
tf_acc_kek_key_ring_id: ${{ vars.TF_ACC_KEK_KEY_RING_ID }}
tf_acc_kek_key_version: ${{ vars.TF_ACC_KEK_KEY_VERSION }}
tf_acc_kek_service_account: ${{ vars.TF_ACC_KEK_SERVICE_ACCOUNT }}
# service_account_json_file_path: "~/service_account.json"
- name: Check coverage threshold
shell: bash
run: |
make coverage
COVERAGE=$(go tool cover -func=coverage.out | grep total | awk '{print $3}' | sed 's/%//')
echo "Coverage: $COVERAGE%"
if (( $(echo "$COVERAGE < 80" | bc -l) )); then
echo "Coverage is below 80%"
# exit 1
fi
- name: Archive code coverage results
uses: actions/upload-artifact@v4
with:
name: ${{ env.CODE_COVERAGE_ARTIFACT_NAME }}
path: "stackit/${{ env.CODE_COVERAGE_FILE_NAME }}"
main:
if: ${{ github.event_name != 'schedule' }}
name: CI run build and linting
runs-on: ubuntu-latest
needs:
- config
- prepare
steps:
- name: Checkout
uses: actions/checkout@v6
# - uses: actions/cache@v5
# id: cache
# with:
# path: path/to/dependencies
# key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}
# - name: Install Dependencies
# if: steps.cache.outputs.cache-hit != 'true'
# run: /install.sh
- name: Build
uses: ./.github/actions/build
with:
go-version: ${{ env.GO_VERSION }}
- name: Setup Terraform
uses: hashicorp/setup-terraform@v2
with:
terraform_wrapper: false
- name: "Ensure docs are up-to-date"
if: ${{ github.event_name == 'pull_request' }}
run: ./scripts/check-docs.sh
continue-on-error: true
- name: "Run go mod tidy"
if: ${{ github.event_name == 'pull_request' }}
run: go mod tidy
- name: golangci-lint
uses: golangci/golangci-lint-action@v9
with:
version: v2.10
args: --config=.golang-ci.yaml --allow-parallel-runners --timeout=5m
continue-on-error: true
- name: Linting terraform files
run: make lint-tf
continue-on-error: true
code_coverage:
name: "Code coverage report"
if: github.event_name == 'pull_request' # Do not run when workflow is triggered by push to main branch
runs-on: ubuntu-latest
needs:
- main
- prepare
permissions:
contents: read
actions: read # to download code coverage results from "main" job
pull-requests: write # write permission needed to comment on PR
steps:
- name: Install needed tools
shell: bash
run: |
set -e
apt-get -y -qq update
apt-get -y -qq install sudo
- name: Check new code coverage
uses: fgrosse/go-coverage-report@v1.2.0
continue-on-error: true # Add this line to prevent pipeline failures in forks
with:
coverage-artifact-name: ${{ env.CODE_COVERAGE_ARTIFACT_NAME }}
coverage-file-name: ${{ env.CODE_COVERAGE_FILE_NAME }}
root-package: 'github.com/stackitcloud/terraform-provider-stackit'

147
.github/workflows/publish.yaml vendored Normal file
View file

@ -0,0 +1,147 @@
name: Publish
run-name: Publish by @${{ github.actor }}
on:
workflow_dispatch:
push:
tags:
- 'v0.*'
env:
GO_VERSION: "1.25"
CODE_COVERAGE_FILE_NAME: "coverage.out" # must be the same as in Makefile
CODE_COVERAGE_ARTIFACT_NAME: "code-coverage"
jobs:
config:
name: Check GoReleaser config
if: github.event_name == 'push' && contains(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Check GoReleaser
uses: goreleaser/goreleaser-action@v7
with:
args: check
publish:
name: "Publish provider"
if: github.event_name == 'push' && contains(github.ref, 'refs/tags/')
needs: config
runs-on: ubuntu-latest
permissions:
actions: read # Required to identify workflow run.
checks: write # Required to add status summary.
contents: read # Required to checkout repository.
pull-requests: write # Required to add PR comment.
steps:
- name: Install needed tools
run: |
apt-get -y -qq update
apt-get -y -qq install jq python3 python3-pip python-is-python3 s3cmd git make wget
- name: Checkout
uses: actions/checkout@v6
- name: Setup Go
uses: actions/setup-go@v6
with:
# go-version: ${{ env.GO_VERSION }}
check-latest: true
go-version-file: 'go.mod'
- name: Install go tools
run: |
go install golang.org/x/tools/cmd/goimports@latest
go install github.com/hashicorp/terraform-plugin-codegen-framework/cmd/tfplugingen-framework@latest
go install github.com/hashicorp/terraform-plugin-codegen-openapi/cmd/tfplugingen-openapi@latest
- name: Setup JAVA
uses: actions/setup-java@v5
with:
distribution: 'temurin' # See 'Supported distributions' for available options
java-version: '21'
- name: Set up s3cfg
run: |
cat <<'EOF' >> ~/.s3cfg
[default]
host_base = https://object.storage.eu01.onstackit.cloud
host_bucket = https://%(bucket).object.storage.eu01.onstackit.cloud
check_ssl_certificate = False
access_key = ${{ secrets.S3_ACCESS_KEY }}
secret_key = ${{ secrets.S3_SECRET_KEY }}
EOF
- name: Import GPG key
run: |
echo "${{ secrets.PRIVATE_KEY_PEM }}" > ~/private.key.pem
gpg --import ~/private.key.pem
rm ~/private.key.pem
- name: Run GoReleaser with SNAPSHOT
if: github.event_name == 'workflow_dispatch'
id: goreleaser
env:
GITHUB_TOKEN: ${{ env.FORGEJO_TOKEN }}
GPG_FINGERPRINT: ${{ secrets.GPG_FINGERPRINT }}
uses: goreleaser/goreleaser-action@v7
with:
args: release --skip publish --clean --snapshot
- name: Run GoReleaser
if: github.event_name != 'workflow_dispatch'
id: goreleaser
env:
GITHUB_TOKEN: ${{ env.FORGEJO_TOKEN }}
GPG_FINGERPRINT: ${{ secrets.GPG_FINGERPRINT }}
uses: goreleaser/goreleaser-action@v7
with:
args: release --skip publish --clean
- name: Prepare key file
run: |
echo "${{ secrets.PUBLIC_KEY_PEM }}" >public_key.pem
- name: Prepare provider directory structure
run: |
VERSION=$(jq -r .version < dist/metadata.json)
go run generator/main.go \
publish \
--namespace=mhenselin \
--providerName=stackitprivatepreview \
--repoName=terraform-provider-stackitprivatepreview \
--domain=tfregistry.sysops.stackit.rocks \
--gpgFingerprint="${{ secrets.GPG_FINGERPRINT }}" \
--gpgPubKeyFile=public_key.pem \
--version=${VERSION}
- name: Prepare documentation nav file
run: |
go run generator/main.go \
docs \
--outFile nav.md
- name: Publish provider to S3
run: |
set -e
cd release/
s3cmd put --recursive v1 s3://terraform-provider-privatepreview/
s3cmd put --recursive .well-known s3://terraform-provider-privatepreview/
- name: Import SSH key
run: |
mkdir -p ~/.ssh
echo "${{ secrets.DOCS_UPLOAD_SSH_KEY }}" > ~/.ssh/id_ed25519
chmod 0600 ~/.ssh/id_ed25519
- name: Upload docs via scp
run: |
set -e
ssh -o StrictHostKeyChecking=no ubuntu@${{ vars.DOCS_SERVER_IP }} 'rm -rf /srv/www/docs'
echo "${{ github.ref_name }}" >docs/_version.txt
scp -o StrictHostKeyChecking=no -r docs ubuntu@${{ vars.DOCS_SERVER_IP }}:/srv/www/
scp -o StrictHostKeyChecking=no nav.md ubuntu@${{ vars.DOCS_SERVER_IP }}:/srv/www/

View file

@ -4,9 +4,9 @@ name: Release
# This GitHub action creates a release when a tag that matches the pattern
# "v*" (e.g. v0.1.0) is created.
on:
push:
tags:
- "v*"
# push:
# tags:
# - "v*"
workflow_dispatch:
# Releases need permissions to read and write the repository contents.
@ -18,21 +18,23 @@ jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
# Allow goreleaser to access older tag information.
fetch-depth: 0
- uses: actions/setup-go@v5
- uses: https://code.forgejo.org/actions/setup-go@v6
with:
go-version-file: "go.mod"
cache: true
- name: Import GPG key
uses: crazy-max/ghaction-import-gpg@v6
id: import_gpg
with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v6
uses: goreleaser/goreleaser-action@v7
with:
args: release --clean
env:

View file

@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
- name: Self-hosted Renovate
uses: renovatebot/github-action@v41.0.0
with:

29
.github/workflows/runnerstats.yaml vendored Normal file
View file

@ -0,0 +1,29 @@
name: Runner stats
on:
workflow_dispatch:
jobs:
stats-own:
name: "Get own runner stats"
runs-on: ubuntu-latest
steps:
- name: Install needed tools
run: |
apt-get -y -qq update
apt-get -y -qq install inxi
- name: Show stats
run: inxi -c 0
stats-stackit:
name: "Get STACKIT runner stats"
runs-on: stackit-docker
steps:
- name: Install needed tools
run: |
apt-get -y -qq update
apt-get -y -qq install inxi
- name: Show stats
run: inxi -c 0

View file

@ -7,21 +7,23 @@ on:
workflow_dispatch:
jobs:
main:
acc_test:
name: Acceptance Tests
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install project tools and dependencies
run: make project-tools
- name: Run tests
run: |
make test-acceptance-tf TF_ACC_PROJECT_ID=$${{ secrets.TF_ACC_PROJECT_ID }} TF_ACC_ORGANIZATION_ID=$${{ secrets.TF_ACC_ORGANIZATION_ID }} TF_ACC_REGION="eu01"
env:
STACKIT_SERVICE_ACCOUNT_TOKEN: ${{ secrets.TF_ACC_SERVICE_ACCOUNT_TOKEN }}
TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_EMAIL: ${{ secrets.TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_EMAIL }}
TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_TOKEN: ${{ secrets.TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_TOKEN }}
TF_ACC_TEST_PROJECT_PARENT_CONTAINER_ID: ${{ secrets.TF_ACC_TEST_PROJECT_PARENT_CONTAINER_ID }}
TF_ACC_TEST_PROJECT_PARENT_UUID: ${{ secrets.TF_ACC_TEST_PROJECT_PARENT_UUID }}
TF_ACC_TEST_PROJECT_USER_EMAIL: ${{ secrets.TF_ACC_TEST_PROJECT_USER_EMAIL }}
uses: actions/checkout@v6
- name: Run Test
uses: ./.github/actions/acc_test
with:
go-version: ${{ env.GO_VERSION }}
project_id: ${{ vars.TF_ACC_PROJECT_ID }}
region: 'eu01'
service_account_json_content_b64: "${{ secrets.TF_ACC_SERVICE_ACCOUNT_JSON_B64 }}"
project_user_email: ${{ vars.TEST_PROJECT_USER_EMAIL }}
tf_acc_kek_key_id: ${{ vars.TF_ACC_KEK_KEY_ID }}
tf_acc_kek_key_ring_id: ${{ vars.TF_ACC_KEK_KEY_RING_ID }}
tf_acc_kek_key_version: ${{ vars.TF_ACC_KEK_KEY_VERSION }}
tf_acc_kek_service_account: ${{ vars.TF_ACC_KEK_SERVICE_ACCOUNT }}
# service_account_json_file_path: "~/service_account.json"

11
.gitignore vendored
View file

@ -38,3 +38,14 @@ stackit/internal/services/iaas/test-512k.img
# Test coverage reports
coverage.out
coverage.html
generated
stackit-sdk-generator
stackit-sdk-generator/**
dist
.secrets
pkg_gen
/release/
.env
**/.env

View file

@ -1,6 +1,13 @@
version: "2"
run:
concurrency: 4
output:
formats:
text:
print-linter-name: true
print-issued-lines: true
colors: true
path: stdout
linters:
enable:
- bodyclose
@ -23,6 +30,11 @@ linters:
rules:
main:
list-mode: lax
allow:
- tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview
- github.com/hashicorp/terraform-plugin-framework
- github.com/hashicorp/terraform-plugin-log
- github.com/stackitcloud/stackit-sdk-go
deny:
- pkg: github.com/stretchr/testify
desc: Do not use a testing framework
@ -62,22 +74,21 @@ linters:
- name: empty-lines
- name: early-return
exclusions:
generated: lax
paths:
- third_party$
- builtin$
- examples$
- generator/
generated: lax
warn-unused: true
# Excluding configuration per-path, per-linter, per-text and per-source.
rules:
# Exclude some linters from running on tests files.
- path: _test\.go
linters:
- gochecknoinits
formatters:
enable:
- gofmt
#- gofmt
- goimports
settings:
goimports:
local-prefixes:
- github.com/freiheit-com/nmww
exclusions:
generated: lax
paths:
- third_party$
- builtin$
- examples$
- tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview

View file

@ -5,6 +5,8 @@
# behavior.
version: 2
project_name: terraform-provider-stackitprivatepreview
builds:
- env:
# goreleaser does not work with CGO, it could also complicate
@ -29,14 +31,16 @@ builds:
ignore:
- goos: darwin
goarch: '386'
- goos: windows
goarch: arm
binary: '{{ .ProjectName }}_v{{ .Version }}'
archives:
- formats: [ 'zip' ]
name_template: '{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}'
checksum:
extra_files:
- glob: 'terraform-registry-manifest.json'
name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json'
# extra_files:
# - glob: 'terraform-registry-manifest.json'
# name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json'
name_template: '{{ .ProjectName }}_{{ .Version }}_SHA256SUMS'
algorithm: sha256
signs:

View file

@ -1,5 +1,6 @@
ROOT_DIR ?= $(shell git rev-parse --show-toplevel)
SCRIPTS_BASE ?= $(ROOT_DIR)/scripts
VERSION ?= ${VER}
# SETUP AND TOOL INITIALIZATION TASKS
project-help:
@ -11,17 +12,20 @@ project-tools:
# LINT
lint-golangci-lint:
@echo "Linting with golangci-lint"
@$(SCRIPTS_BASE)/lint-golangci-lint.sh
@go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint run --fix --config .golang-ci.yaml
lint-tf:
lint-tf:
@echo "Linting terraform files"
@terraform fmt -check -diff -recursive
@terraform fmt -check -diff -recursive examples/
@terraform fmt -check -diff -recursive stackit/
lint: lint-golangci-lint lint-tf
# DOCUMENTATION GENERATION
generate-docs:
@echo "Generating documentation with tfplugindocs"
@$(SCRIPTS_BASE)/tfplugindocs.sh
build:
@ -33,15 +37,16 @@ fmt:
@terraform fmt -diff -recursive
# TEST
.PHONY: test coverage
test:
@echo "Running tests for the terraform provider"
@cd $(ROOT_DIR)/stackit && go test ./... -count=1 -coverprofile=coverage.out && cd $(ROOT_DIR)
@cd $(ROOT_DIR)/stackit && go test -timeout 0 ./... -count=1 -coverprofile=../coverage.out && cd $(ROOT_DIR)
# Test coverage
coverage:
@echo ">> Creating test coverage report for the terraform provider"
@cd $(ROOT_DIR)/stackit && (go test ./... -count=1 -coverprofile=coverage.out || true) && cd $(ROOT_DIR)
@cd $(ROOT_DIR)/stackit && go tool cover -html=coverage.out -o coverage.html && cd $(ROOT_DIR)
@cd $(ROOT_DIR)/stackit && (go test -timeout 0 ./... -count=1 -coverprofile=../coverage.out || true) && cd $(ROOT_DIR)
@cd $(ROOT_DIR)/stackit && go tool cover -html=../coverage.out -o ../coverage.html && cd $(ROOT_DIR)
test-acceptance-tf:
@if [ -z $(TF_ACC_PROJECT_ID) ]; then echo "Input TF_ACC_PROJECT_ID missing"; exit 1; fi
@ -57,3 +62,11 @@ test-acceptance-tf:
TF_ACC_REGION=$(TF_ACC_REGION) \
go test ./... -count=1 -timeout=30m && \
cd $(ROOT_DIR)
publish: build
ifeq ($(strip $(VERSION)),)
@echo "please call like this: VER=0.1.0 make publish"
else
@echo "version: $(VERSION)"
endif

View file

@ -1,15 +1,14 @@
<div align="center">
<br>
<img src=".github/images/stackit-logo.svg" alt="STACKIT logo" width="50%"/>
<br>
<br>
</div>
# STACKIT Terraform Provider
# STACKIT Terraform Provider <br />(PRIVATE PREVIEW)
[![Go Report Card](https://goreportcard.com/badge/github.com/stackitcloud/terraform-provider-stackit)](https://goreportcard.com/report/github.com/stackitcloud/terraform-provider-stackit) [![GitHub Release](https://img.shields.io/github/v/release/stackitcloud/terraform-provider-stackit)](https://registry.terraform.io/providers/stackitcloud/stackit/latest) ![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/stackitcloud/terraform-provider-stackit) [![GitHub License](https://img.shields.io/github/license/stackitcloud/terraform-provider-stackit)](https://www.apache.org/licenses/LICENSE-2.0)
[![GitHub Release](https://img.shields.io/github/v/release/stackitcloud/terraform-provider-stackit)](https://registry.terraform.io/providers/stackitcloud/stackit/latest) ![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/stackitcloud/terraform-provider-stackit) [![GitHub License](https://img.shields.io/github/license/stackitcloud/terraform-provider-stackit)](https://www.apache.org/licenses/LICENSE-2.0)
This project is the official [Terraform Provider](https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs) for [STACKIT](https://www.stackit.de/en/), which allows you to manage STACKIT resources through Terraform.
This project is the **NOT** official [Terraform Provider](https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs) for [STACKIT](https://www.stackit.de/en/)!
This a **private preview only**, which allows you to manage STACKIT resources through Terraform.
## Getting Started
@ -18,20 +17,22 @@ To install the [STACKIT Terraform Provider](https://registry.terraform.io/provid
```hcl
terraform {
required_providers {
stackit = {
source = "stackitcloud/stackit"
version = "X.X.X"
stackitprivatepreview = {
source = "tfregistry.sysops.stackit.rocks/mhenselin/stackitprivatepreview"
version = "= 0.0.5-alpha"
}
}
}
provider "stackit" {
provider "stackitprivatepreview" {
# Configuration options
}
```
Check one of the examples in the [examples](examples/) folder.
<big font-size="3rem">TODO: revise the following sections</big>
## Authentication
To authenticate, you will need a [service account](https://docs.stackit.cloud/platform/access-and-identity/service-accounts/). Create it in the [STACKIT Portal](https://portal.stackit.cloud/) and assign the necessary permissions to it, e.g. `project.owner`. There are multiple ways to authenticate:

View file

@ -3,12 +3,12 @@
page_title: "stackitprivatepreview_postgresflexalpha_database Data Source - stackitprivatepreview"
subcategory: ""
description: |-
Postgres Flex database resource schema. Must have a region specified in the provider configuration.
---
# stackitprivatepreview_postgresflexalpha_database (Data Source)
Postgres Flex database resource schema. Must have a `region` specified in the provider configuration.
## Example Usage
@ -25,16 +25,14 @@ data "stackitprivatepreview_postgresflexalpha_database" "example" {
### Required
- `database_id` (String) Database ID.
- `instance_id` (String) ID of the Postgres Flex instance.
- `project_id` (String) STACKIT project ID to which the instance is associated.
### Optional
- `region` (String) The resource region. If not defined, the provider region is used.
- `database_id` (Number) The ID of the database.
- `instance_id` (String) The ID of the instance.
- `project_id` (String) The STACKIT project ID.
- `region` (String) The region which should be addressed
### Read-Only
- `id` (String) Terraform's internal resource ID. It is structured as "`project_id`,`region`,`instance_id`,`database_id`".
- `name` (String) Database name.
- `owner` (String) Username of the database owner.
- `id` (String) Terraform's internal resource ID. It is structured as \"`project_id`,`region`,`instance_id`,`database_id`\".",
- `name` (String) The name of the database.
- `owner` (String) The owner of the database.
- `tf_original_api_id` (Number) The id of the database.

View file

@ -10,7 +10,18 @@ description: |-
## Example Usage
```terraform
data "stackitprivatepreview_postgresflexalpha_flavor" "flavor" {
project_id = var.project_id
region = var.region
cpu = 4
ram = 16
node_type = "Single"
storage_class = "premium-perf2-stackit"
}
```
<!-- schema generated by tfplugindocs -->
## Schema

View file

@ -0,0 +1,68 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "stackitprivatepreview_postgresflexalpha_flavors Data Source - stackitprivatepreview"
subcategory: ""
description: |-
---
# stackitprivatepreview_postgresflexalpha_flavors (Data Source)
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `project_id` (String) The STACKIT project ID.
- `region` (String) The region which should be addressed
### Optional
- `page` (Number) Number of the page of items list to be returned.
- `size` (Number) Number of items to be returned on each page.
- `sort` (String) Sorting of the flavors to be returned on each page.
### Read-Only
- `flavors` (Attributes List) List of flavors available for the project. (see [below for nested schema](#nestedatt--flavors))
- `pagination` (Attributes) (see [below for nested schema](#nestedatt--pagination))
<a id="nestedatt--flavors"></a>
### Nested Schema for `flavors`
Read-Only:
- `cpu` (Number) The cpu count of the instance.
- `description` (String) The flavor description.
- `max_gb` (Number) maximum storage which can be ordered for the flavor in Gigabyte.
- `memory` (Number) The memory of the instance in Gibibyte.
- `min_gb` (Number) minimum storage which is required to order in Gigabyte.
- `node_type` (String) defines the nodeType it can be either single or replica
- `storage_classes` (Attributes List) maximum storage which can be ordered for the flavor in Gigabyte. (see [below for nested schema](#nestedatt--flavors--storage_classes))
- `tf_original_api_id` (String) The id of the instance flavor.
<a id="nestedatt--flavors--storage_classes"></a>
### Nested Schema for `flavors.storage_classes`
Read-Only:
- `class` (String)
- `max_io_per_sec` (Number)
- `max_through_in_mb` (Number)
<a id="nestedatt--pagination"></a>
### Nested Schema for `pagination`
Read-Only:
- `page` (Number)
- `size` (Number)
- `sort` (String)
- `total_pages` (Number)
- `total_rows` (Number)

View file

@ -3,12 +3,12 @@
page_title: "stackitprivatepreview_postgresflexalpha_instance Data Source - stackitprivatepreview"
subcategory: ""
description: |-
Postgres Flex instance data source schema. Must have a region specified in the provider configuration.
---
# stackitprivatepreview_postgresflexalpha_instance (Data Source)
Postgres Flex instance data source schema. Must have a `region` specified in the provider configuration.
## Example Usage
@ -24,34 +24,54 @@ data "stackitprivatepreview_postgresflexalpha_instance" "example" {
### Required
- `instance_id` (String) ID of the PostgresFlex instance.
- `project_id` (String) STACKIT project ID to which the instance is associated.
### Optional
- `region` (String) The resource region. If not defined, the provider region is used.
- `instance_id` (String) The ID of the instance.
- `project_id` (String) The STACKIT project ID.
- `region` (String) The region which should be addressed
### Read-Only
- `backup_schedule` (String)
- `encryption` (Attributes) (see [below for nested schema](#nestedatt--encryption))
- `flavor_id` (String)
- `id` (String) Terraform's internal data source. ID. It is structured as "`project_id`,`region`,`instance_id`".
- `name` (String) Instance name.
- `network` (Attributes) (see [below for nested schema](#nestedatt--network))
- `replicas` (Number)
- `retention_days` (Number)
- `storage` (Attributes) (see [below for nested schema](#nestedatt--storage))
- `version` (String)
- `acl` (List of String) List of IPV4 cidr.
- `backup_schedule` (String) The schedule for when the database backup will be created. Currently, ONLY daily schedules are supported (every 24 hours). The schedule is written as a cron schedule.
- `connection_info` (Attributes) The connection information of the instance (see [below for nested schema](#nestedatt--connection_info))
- `encryption` (Attributes) The configuration for instance's volume and backup storage encryption.
⚠︝ **Note:** This feature is in private preview. Supplying this object is only permitted for enabled accounts. If your account does not have access, the request will be rejected. (see [below for nested schema](#nestedatt--encryption))
- `flavor_id` (String) The id of the instance flavor.
- `is_deletable` (Boolean) Whether the instance can be deleted or not.
- `name` (String) The name of the instance.
- `network` (Attributes) The access configuration of the instance (see [below for nested schema](#nestedatt--network))
- `replicas` (Number) How many replicas the instance should have.
- `retention_days` (Number) How long backups are retained. The value can only be between 32 and 365 days.
- `status` (String) The current status of the instance.
- `storage` (Attributes) The object containing information about the storage size and class. (see [below for nested schema](#nestedatt--storage))
- `tf_original_api_id` (String) The ID of the instance.
- `version` (String) The Postgres version used for the instance. See [Versions Endpoint](/documentation/postgres-flex-service/version/v3alpha1#tag/Version) for supported version parameters.
<a id="nestedatt--connection_info"></a>
### Nested Schema for `connection_info`
Read-Only:
- `write` (Attributes) The DNS name and port in the instance overview (see [below for nested schema](#nestedatt--connection_info--write))
<a id="nestedatt--connection_info--write"></a>
### Nested Schema for `connection_info.write`
Read-Only:
- `host` (String) The host of the instance.
- `port` (Number) The port of the instance.
<a id="nestedatt--encryption"></a>
### Nested Schema for `encryption`
Read-Only:
- `key_id` (String)
- `key_version` (String)
- `keyring_id` (String)
- `kek_key_id` (String) The encryption-key key identifier
- `kek_key_ring_id` (String) The encryption-key keyring identifier
- `kek_key_version` (String) The encryption-key version
- `service_account` (String)
@ -60,8 +80,8 @@ Read-Only:
Read-Only:
- `access_scope` (String)
- `acl` (List of String) The Access Control List (ACL) for the PostgresFlex instance.
- `access_scope` (String) The access scope of the instance. It defines if the instance is public or airgapped.
- `acl` (List of String) List of IPV4 cidr.
- `instance_address` (String)
- `router_address` (String)
@ -71,5 +91,5 @@ Read-Only:
Read-Only:
- `class` (String)
- `size` (Number)
- `performance_class` (String) The storage class for the storage.
- `size` (Number) The storage size in Gigabytes.

View file

@ -3,12 +3,12 @@
page_title: "stackitprivatepreview_postgresflexalpha_user Data Source - stackitprivatepreview"
subcategory: ""
description: |-
Postgres Flex user data source schema. Must have a region specified in the provider configuration.
---
# stackitprivatepreview_postgresflexalpha_user (Data Source)
Postgres Flex user data source schema. Must have a `region` specified in the provider configuration.
## Example Usage
@ -25,20 +25,18 @@ data "stackitprivatepreview_postgresflexalpha_user" "example" {
### Required
- `instance_id` (String) ID of the PostgresFlex instance.
- `project_id` (String) STACKIT project ID to which the instance is associated.
- `user_id` (String) User ID.
- `instance_id` (String) The ID of the instance.
- `project_id` (String) The STACKIT project ID.
- `region` (String) The region which should be addressed
- `user_id` (Number) The ID of the user.
### Optional
- `region` (String) The resource region. If not defined, the provider region is used.
- `id` (String) Terraform's internal resource ID. It is structured as \"`project_id`,`region`,`instance_id`,`user_id`\".",
### Read-Only
- `connection_string` (String)
- `host` (String)
- `id` (String) Terraform's internal data source. ID. It is structured as "`project_id`,`region`,`instance_id`,`user_id`".
- `port` (Number)
- `roles` (Set of String)
- `status` (String)
- `username` (String)
- `name` (String) The name of the user.
- `roles` (List of String) A list of user roles.
- `status` (String) The current status of the user.
- `tf_original_api_id` (Number) The ID of the user.

View file

@ -0,0 +1,32 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "stackitprivatepreview_sqlserverflexalpha_database Data Source - stackitprivatepreview"
subcategory: ""
description: |-
---
# stackitprivatepreview_sqlserverflexalpha_database (Data Source)
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `database_name` (String) The name of the database.
- `instance_id` (String) The ID of the instance.
- `project_id` (String) The STACKIT project ID.
- `region` (String) The region which should be addressed
### Read-Only
- `collation_name` (String) The collation of the database. This database collation should match the *collation_name* of one of the collations given by the **Get database collation list** endpoint.
- `compatibility_level` (Number) CompatibilityLevel of the Database.
- `id` (String) The terraform internal identifier.
- `name` (String) The name of the database.
- `owner` (String) The owner of the database.
- `tf_original_api_id` (Number) The id of the database.

View file

@ -1,43 +0,0 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "stackitprivatepreview_sqlserverflexalpha_flavor Data Source - stackitprivatepreview"
subcategory: ""
description: |-
---
# stackitprivatepreview_sqlserverflexalpha_flavor (Data Source)
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `cpu` (Number) The cpu count of the instance.
- `node_type` (String) defines the nodeType it can be either single or replica
- `project_id` (String) The cpu count of the instance.
- `ram` (Number) The memory of the instance in Gibibyte.
- `region` (String) The flavor description.
- `storage_class` (String) The memory of the instance in Gibibyte.
### Read-Only
- `description` (String) The flavor description.
- `flavor_id` (String) The flavor id of the instance flavor.
- `id` (String) The terraform id of the instance flavor.
- `max_gb` (Number) maximum storage which can be ordered for the flavor in Gigabyte.
- `min_gb` (Number) minimum storage which is required to order in Gigabyte.
- `storage_classes` (Attributes List) (see [below for nested schema](#nestedatt--storage_classes))
<a id="nestedatt--storage_classes"></a>
### Nested Schema for `storage_classes`
Read-Only:
- `class` (String)
- `max_io_per_sec` (Number)
- `max_through_in_mb` (Number)

View file

@ -3,12 +3,12 @@
page_title: "stackitprivatepreview_sqlserverflexalpha_instance Data Source - stackitprivatepreview"
subcategory: ""
description: |-
SQLServer Flex ALPHA instance resource schema. Must have a region specified in the provider configuration.
---
# stackitprivatepreview_sqlserverflexalpha_instance (Data Source)
SQLServer Flex ALPHA instance resource schema. Must have a `region` specified in the provider configuration.
## Example Usage
@ -24,61 +24,48 @@ data "stackitprivatepreview_sqlserverflexalpha_instance" "example" {
### Required
- `instance_id` (String) ID of the SQLServer Flex instance.
- `project_id` (String) STACKIT project ID to which the instance is associated.
### Optional
- `region` (String) The resource region. If not defined, the provider region is used.
- `instance_id` (String) The ID of the instance.
- `project_id` (String) The STACKIT project ID.
- `region` (String) The region which should be addressed
### Read-Only
- `backup_schedule` (String) The backup schedule. Should follow the cron scheduling system format (e.g. "0 0 * * *")
- `edition` (String)
- `encryption` (Attributes) The encryption block. (see [below for nested schema](#nestedatt--encryption))
- `flavor` (Attributes) (see [below for nested schema](#nestedatt--flavor))
- `id` (String) Terraform's internal resource ID. It is structured as "`project_id`,`region`,`instance_id`".
- `is_deletable` (Boolean)
- `name` (String) Instance name.
- `network` (Attributes) The network block. (see [below for nested schema](#nestedatt--network))
- `replicas` (Number)
- `retention_days` (Number)
- `backup_schedule` (String) The schedule for on what time and how often the database backup will be created. The schedule is written as a cron schedule.
- `edition` (String) Edition of the MSSQL server instance
- `encryption` (Attributes) this defines which key to use for storage encryption (see [below for nested schema](#nestedatt--encryption))
- `flavor_id` (String) The id of the instance flavor.
- `is_deletable` (Boolean) Whether the instance can be deleted or not.
- `name` (String) The name of the instance.
- `network` (Attributes) The access configuration of the instance (see [below for nested schema](#nestedatt--network))
- `replicas` (Number) How many replicas the instance should have.
- `retention_days` (Number) The days for how long the backup files should be stored before cleaned up. 30 to 365
- `status` (String)
- `storage` (Attributes) (see [below for nested schema](#nestedatt--storage))
- `version` (String)
- `storage` (Attributes) The object containing information about the storage size and class. (see [below for nested schema](#nestedatt--storage))
- `tf_original_api_id` (String) The ID of the instance.
- `version` (String) The sqlserver version used for the instance.
<a id="nestedatt--encryption"></a>
### Nested Schema for `encryption`
Read-Only:
- `key_id` (String) STACKIT KMS - Key ID of the encryption key to use.
- `key_version` (String) STACKIT KMS - Key version to use in the encryption key.
- `keyring_id` (String) STACKIT KMS - KeyRing ID of the encryption key to use.
- `kek_key_id` (String) The key identifier
- `kek_key_ring_id` (String) The keyring identifier
- `kek_key_version` (String) The key version
- `service_account` (String)
<a id="nestedatt--flavor"></a>
### Nested Schema for `flavor`
Read-Only:
- `cpu` (Number)
- `description` (String)
- `id` (String)
- `node_type` (String)
- `ram` (Number)
<a id="nestedatt--network"></a>
### Nested Schema for `network`
Read-Only:
- `access_scope` (String) The access scope of the instance. (e.g. SNA)
- `acl` (List of String) The Access Control List (ACL) for the SQLServer Flex instance.
- `instance_address` (String) The returned instance IP address of the SQLServer Flex instance.
- `router_address` (String) The returned router IP address of the SQLServer Flex instance.
- `access_scope` (String) The network access scope of the instance
⚠️ **Note:** This feature is in private preview. Supplying this object is only permitted for enabled accounts. If your account does not have access, the request will be rejected.
- `acl` (List of String) List of IPV4 cidr.
- `instance_address` (String)
- `router_address` (String)
<a id="nestedatt--storage"></a>
@ -86,5 +73,5 @@ Read-Only:
Read-Only:
- `class` (String)
- `size` (Number)
- `class` (String) The storage class for the storage.
- `size` (Number) The storage size in Gigabytes.

View file

@ -3,12 +3,12 @@
page_title: "stackitprivatepreview_sqlserverflexalpha_user Data Source - stackitprivatepreview"
subcategory: ""
description: |-
SQLServer Flex user data source schema. Must have a region specified in the provider configuration.
---
# stackitprivatepreview_sqlserverflexalpha_user (Data Source)
SQLServer Flex user data source schema. Must have a `region` specified in the provider configuration.
## Example Usage
@ -25,20 +25,38 @@ data "stackitprivatepreview_sqlserverflexalpha_user" "example" {
### Required
- `instance_id` (String) ID of the SQLServer Flex instance.
- `project_id` (String) STACKIT project ID to which the instance is associated.
- `user_id` (Number) User ID.
- `instance_id` (String) The ID of the instance.
- `project_id` (String) The STACKIT project ID.
- `region` (String) The region which should be addressed
### Optional
- `region` (String) The resource region. If not defined, the provider region is used.
- `page` (Number) Number of the page of items list to be returned.
- `size` (Number) Number of items to be returned on each page.
- `sort` (String) Sorting of the users to be returned on each page.
### Read-Only
- `default_database` (String)
- `host` (String)
- `id` (String) Terraform's internal data source. ID. It is structured as "`project_id`,`region`,`instance_id`,`user_id`".
- `port` (Number)
- `roles` (Set of String) Database access levels for the user.
- `status` (String)
- `username` (String) Username of the SQLServer Flex instance.
- `pagination` (Attributes) (see [below for nested schema](#nestedatt--pagination))
- `users` (Attributes List) List of all users inside an instance (see [below for nested schema](#nestedatt--users))
<a id="nestedatt--pagination"></a>
### Nested Schema for `pagination`
Read-Only:
- `page` (Number)
- `size` (Number)
- `sort` (String)
- `total_pages` (Number)
- `total_rows` (Number)
<a id="nestedatt--users"></a>
### Nested Schema for `users`
Read-Only:
- `status` (String) The current status of the user.
- `tf_original_api_id` (Number) The ID of the user.
- `username` (String) The name of the user.

View file

@ -0,0 +1,40 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "stackitprivatepreview_sqlserverflexbeta_database Data Source - stackitprivatepreview"
subcategory: ""
description: |-
---
# stackitprivatepreview_sqlserverflexbeta_database (Data Source)
## Example Usage
```terraform
data "stackitprivatepreview_sqlserverflexbeta_database" "example" {
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
instance_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
database_name = "dbname"
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `database_name` (String) The name of the database.
- `instance_id` (String) The ID of the instance.
- `project_id` (String) The STACKIT project ID.
- `region` (String) The region which should be addressed
### Read-Only
- `collation_name` (String) The collation of the database. This database collation should match the *collation_name* of one of the collations given by the **Get database collation list** endpoint.
- `compatibility_level` (Number) CompatibilityLevel of the Database.
- `id` (String) The terraform internal identifier.
- `name` (String) The name of the database.
- `owner` (String) The owner of the database.
- `tf_original_api_id` (Number) The id of the database.

View file

@ -0,0 +1,77 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "stackitprivatepreview_sqlserverflexbeta_instance Data Source - stackitprivatepreview"
subcategory: ""
description: |-
---
# stackitprivatepreview_sqlserverflexbeta_instance (Data Source)
## Example Usage
```terraform
data "stackitprivatepreview_sqlserverflexbeta_instance" "example" {
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
instance_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `instance_id` (String) The ID of the instance.
- `project_id` (String) The STACKIT project ID.
- `region` (String) The region which should be addressed
### Read-Only
- `backup_schedule` (String) The schedule for on what time and how often the database backup will be created. The schedule is written as a cron schedule.
- `edition` (String) Edition of the MSSQL server instance
- `encryption` (Attributes) this defines which key to use for storage encryption (see [below for nested schema](#nestedatt--encryption))
- `flavor_id` (String) The id of the instance flavor.
- `is_deletable` (Boolean) Whether the instance can be deleted or not.
- `name` (String) The name of the instance.
- `network` (Attributes) The access configuration of the instance (see [below for nested schema](#nestedatt--network))
- `replicas` (Number) How many replicas the instance should have.
- `retention_days` (Number) The days for how long the backup files should be stored before cleaned up. 30 to 365
- `status` (String)
- `storage` (Attributes) The object containing information about the storage size and class. (see [below for nested schema](#nestedatt--storage))
- `tf_original_api_id` (String) The ID of the instance.
- `version` (String) The sqlserver version used for the instance.
<a id="nestedatt--encryption"></a>
### Nested Schema for `encryption`
Read-Only:
- `kek_key_id` (String) The key identifier
- `kek_key_ring_id` (String) The keyring identifier
- `kek_key_version` (String) The key version
- `service_account` (String)
<a id="nestedatt--network"></a>
### Nested Schema for `network`
Read-Only:
- `access_scope` (String) The network access scope of the instance
⚠️ **Note:** This feature is in private preview. Supplying this object is only permitted for enabled accounts. If your account does not have access, the request will be rejected.
- `acl` (List of String) List of IPV4 cidr.
- `instance_address` (String)
- `router_address` (String)
<a id="nestedatt--storage"></a>
### Nested Schema for `storage`
Read-Only:
- `class` (String) The storage class for the storage.
- `size` (Number) The storage size in Gigabytes.

View file

@ -0,0 +1,54 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "stackitprivatepreview_sqlserverflexbeta_user Data Source - stackitprivatepreview"
subcategory: ""
description: |-
---
# stackitprivatepreview_sqlserverflexbeta_user (Data Source)
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `instance_id` (String) The ID of the instance.
- `project_id` (String) The STACKIT project ID.
- `region` (String) The region which should be addressed
### Optional
- `page` (Number) Number of the page of items list to be returned.
- `size` (Number) Number of items to be returned on each page.
- `sort` (String) Sorting of the users to be returned on each page.
### Read-Only
- `pagination` (Attributes) (see [below for nested schema](#nestedatt--pagination))
- `users` (Attributes List) List of all users inside an instance (see [below for nested schema](#nestedatt--users))
<a id="nestedatt--pagination"></a>
### Nested Schema for `pagination`
Read-Only:
- `page` (Number)
- `size` (Number)
- `sort` (String)
- `total_pages` (Number)
- `total_rows` (Number)
<a id="nestedatt--users"></a>
### Nested Schema for `users`
Read-Only:
- `status` (String) The current status of the user.
- `tf_original_api_id` (Number) The ID of the user.
- `username` (String) The name of the user.

View file

@ -16,14 +16,13 @@ provider "stackitprivatepreview" {
default_region = "eu01"
}
# Authentication
# Token flow (scheduled for deprecation and will be removed on December 17, 2025)
provider "stackitprivatepreview" {
default_region = "eu01"
service_account_token = var.service_account_token
default_region = "eu01"
service_account_key_path = "service_account.json"
}
# Authentication
# Key flow
provider "stackitprivatepreview" {
default_region = "eu01"

View file

@ -3,12 +3,12 @@
page_title: "stackitprivatepreview_postgresflexalpha_database Resource - stackitprivatepreview"
subcategory: ""
description: |-
Postgres Flex database resource schema. Must have a region specified in the provider configuration.
---
# stackitprivatepreview_postgresflexalpha_database (Resource)
Postgres Flex database resource schema. Must have a `region` specified in the provider configuration.
## Example Usage
@ -25,6 +25,16 @@ import {
to = stackitprivatepreview_postgresflexalpha_database.import-example
id = "${var.project_id},${var.region},${var.postgres_instance_id},${var.postgres_database_id}"
}
import {
to = stackitprivatepreview_postgresflexalpha_database.import-example
identity = {
project_id = "project_id"
region = "region"
instance_id = "instance_id"
database_id = "database_id"
}
}
```
<!-- schema generated by tfplugindocs -->
@ -32,16 +42,16 @@ import {
### Required
- `instance_id` (String) ID of the Postgres Flex instance.
- `name` (String) Database name.
- `owner` (String) Username of the database owner.
- `project_id` (String) STACKIT project ID to which the instance is associated.
- `name` (String) The name of the database.
### Optional
- `region` (String) The resource region. If not defined, the provider region is used.
- `database_id` (Number) The ID of the database.
- `instance_id` (String) The ID of the instance.
- `owner` (String) The owner of the database.
- `project_id` (String) The STACKIT project ID.
- `region` (String) The region which should be addressed
### Read-Only
- `database_id` (Number) Database ID.
- `id` (String) Terraform's internal resource ID. It is structured as "`project_id`,`region`,`instance_id`,`database_id`".
- `id` (Number) The id of the database.

View file

@ -3,31 +3,39 @@
page_title: "stackitprivatepreview_postgresflexalpha_instance Resource - stackitprivatepreview"
subcategory: ""
description: |-
Postgres Flex instance resource schema. Must have a region specified in the provider configuration.
---
# stackitprivatepreview_postgresflexalpha_instance (Resource)
Postgres Flex instance resource schema. Must have a `region` specified in the provider configuration.
## Example Usage
```terraform
resource "stackitprivatepreview_postgresflexalpha_instance" "example" {
resource "stackitprivatepreview_postgresflexalpha_instance" "example-instance" {
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
name = "example-instance"
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
backup_schedule = "00 00 * * *"
flavor = {
cpu = 2
ram = 4
}
replicas = 3
backup_schedule = "0 0 * * *"
retention_days = 30
flavor_id = "flavor.id"
replicas = 1
storage = {
class = "class"
size = 5
performance_class = "premium-perf2-stackit"
size = 10
}
version = 14
encryption = {
kek_key_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
kek_key_ring_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
kek_key_version = 1
service_account = "service@account.email"
}
network = {
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
access_scope = "PUBLIC"
}
version = 17
}
# Only use the import statement, if you want to import an existing postgresflex instance
@ -35,6 +43,15 @@ import {
to = stackitprivatepreview_postgresflexalpha_instance.import-example
id = "${var.project_id},${var.region},${var.postgres_instance_id}"
}
import {
to = stackitprivatepreview_postgresflexalpha_instance.import-example
identity = {
project_id = var.project_id
region = var.region
instance_id = var.postgres_instance_id
}
}
```
<!-- schema generated by tfplugindocs -->
@ -42,49 +59,47 @@ import {
### Required
- `backup_schedule` (String)
- `encryption` (Attributes) The encryption block. (see [below for nested schema](#nestedatt--encryption))
- `flavor_id` (String)
- `name` (String) Instance name.
- `network` (Attributes) The network block configuration. (see [below for nested schema](#nestedatt--network))
- `project_id` (String) STACKIT project ID to which the instance is associated.
- `replicas` (Number)
- `retention_days` (Number) The days of the retention period.
- `storage` (Attributes) (see [below for nested schema](#nestedatt--storage))
- `version` (String) The database version used.
- `backup_schedule` (String) The schedule for when the database backup will be created. Currently, ONLY daily schedules are supported (every 24 hours). The schedule is written as a cron schedule.
- `flavor_id` (String) The id of the instance flavor.
- `name` (String) The name of the instance.
- `network` (Attributes) The access configuration of the instance (see [below for nested schema](#nestedatt--network))
- `replicas` (Number) How many replicas the instance should have.
- `retention_days` (Number) How long backups are retained. The value can only be between 32 and 365 days.
- `storage` (Attributes) The object containing information about the storage size and class. (see [below for nested schema](#nestedatt--storage))
- `version` (String) The Postgres version used for the instance. See [Versions Endpoint](/documentation/postgres-flex-service/version/v3alpha1#tag/Version) for supported version parameters.
### Optional
- `region` (String) The resource region. If not defined, the provider region is used.
- `encryption` (Attributes) The configuration for instance's volume and backup storage encryption.
⚠︝ **Note:** This feature is in private preview. Supplying this object is only permitted for enabled accounts. If your account does not have access, the request will be rejected. (see [below for nested schema](#nestedatt--encryption))
- `instance_id` (String) The ID of the instance.
- `project_id` (String) The STACKIT project ID.
- `region` (String) The region which should be addressed
### Read-Only
- `id` (String) Terraform's internal resource ID. It is structured as "`project_id`,`region`,`instance_id`".
- `instance_id` (String) ID of the PostgresFlex instance.
<a id="nestedatt--encryption"></a>
### Nested Schema for `encryption`
Required:
- `key_id` (String) Key ID of the encryption key.
- `key_version` (String) Key version of the encryption key.
- `keyring_id` (String) KeyRing ID of the encryption key.
- `service_account` (String) The service account ID of the service account.
- `acl` (List of String) List of IPV4 cidr.
- `connection_info` (Attributes) The connection information of the instance (see [below for nested schema](#nestedatt--connection_info))
- `id` (String) The ID of the instance.
- `is_deletable` (Boolean) Whether the instance can be deleted or not.
- `status` (String) The current status of the instance.
<a id="nestedatt--network"></a>
### Nested Schema for `network`
Required:
- `acl` (List of String) The Access Control List (ACL) for the PostgresFlex instance.
- `acl` (List of String) List of IPV4 cidr.
Optional:
- `access_scope` (String) The access scope. (Either SNA or PUBLIC)
- `instance_address` (String) The returned instance address.
- `router_address` (String) The returned router address.
- `access_scope` (String) The access scope of the instance. It defines if the instance is public or airgapped.
Read-Only:
- `instance_address` (String)
- `router_address` (String)
<a id="nestedatt--storage"></a>
@ -92,5 +107,32 @@ Optional:
Required:
- `class` (String) The storage class used.
- `size` (Number) The disk size of the storage.
- `performance_class` (String) The storage class for the storage.
- `size` (Number) The storage size in Gigabytes.
<a id="nestedatt--encryption"></a>
### Nested Schema for `encryption`
Required:
- `kek_key_id` (String) The encryption-key key identifier
- `kek_key_ring_id` (String) The encryption-key keyring identifier
- `kek_key_version` (String) The encryption-key version
- `service_account` (String)
<a id="nestedatt--connection_info"></a>
### Nested Schema for `connection_info`
Read-Only:
- `write` (Attributes) The DNS name and port in the instance overview (see [below for nested schema](#nestedatt--connection_info--write))
<a id="nestedatt--connection_info--write"></a>
### Nested Schema for `connection_info.write`
Read-Only:
- `host` (String) The host of the instance.
- `port` (Number) The port of the instance.

View file

@ -3,12 +3,12 @@
page_title: "stackitprivatepreview_postgresflexalpha_user Resource - stackitprivatepreview"
subcategory: ""
description: |-
Postgres Flex user resource schema. Must have a region specified in the provider configuration.
---
# stackitprivatepreview_postgresflexalpha_user (Resource)
Postgres Flex user resource schema. Must have a `region` specified in the provider configuration.
## Example Usage
@ -16,7 +16,7 @@ Postgres Flex user resource schema. Must have a `region` specified in the provid
resource "stackitprivatepreview_postgresflexalpha_user" "example" {
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
instance_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
username = "username"
name = "username"
roles = ["role"]
}
@ -25,6 +25,16 @@ import {
to = stackitprivatepreview_postgresflexalpha_user.import-example
id = "${var.project_id},${var.region},${var.postgres_instance_id},${var.user_id}"
}
import {
to = stackitprivatepreview_postgresflexalpha_user.import-example
identity = {
project_id = "project.id"
region = "region"
instance_id = "instance.id"
user_id = "user.id"
}
}
```
<!-- schema generated by tfplugindocs -->
@ -32,19 +42,18 @@ import {
### Required
- `instance_id` (String) ID of the PostgresFlex instance.
- `project_id` (String) STACKIT project ID to which the instance is associated.
- `roles` (Set of String) Database access levels for the user. Possible values are: `login`, `createdb`.
- `username` (String)
- `name` (String) The name of the user.
### Optional
- `region` (String) The resource region. If not defined, the provider region is used.
- `instance_id` (String) The ID of the instance.
- `project_id` (String) The STACKIT project ID.
- `region` (String) The region which should be addressed
- `roles` (List of String) A list containing the user roles for the instance.
- `user_id` (Number) The ID of the user.
### Read-Only
- `connection_string` (String)
- `id` (String) Terraform's internal resource ID. It is structured as "`project_id`,`region`,`instance_id`,`user_id`".
- `password` (String, Sensitive)
- `status` (String)
- `user_id` (Number) User ID.
- `id` (Number) The ID of the user.
- `password` (String) The password for the user.
- `status` (String) The current status of the user.

View file

@ -0,0 +1,63 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "stackitprivatepreview_sqlserverflexalpha_database Resource - stackitprivatepreview"
subcategory: ""
description: |-
---
# stackitprivatepreview_sqlserverflexalpha_database (Resource)
## Example Usage
```terraform
resource "stackitprivatepreview_sqlserverflexalpha_database" "example" {
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
instance_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
collation = ""
compatibility = "160"
name = ""
owner = ""
}
# Only use the import statement, if you want to import a existing sqlserverflex database
import {
to = stackitprivatepreview_sqlserverflexalpha_database.import-example
id = "${var.project_id},${var.region},${var.sql_instance_id},${var.sql_user_id}"
}
import {
to = stackitprivatepreview_sqlserverflexalpha_database.import-example
identity = {
project_id = "project.id"
region = "region"
instance_id = "instance.id"
database_id = "database.id"
}
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `name` (String) The name of the database.
- `owner` (String) The owner of the database.
### Optional
- `collation` (String) The collation of the database. This database collation should match the *collation_name* of one of the collations given by the **Get database collation list** endpoint.
- `compatibility` (Number) CompatibilityLevel of the Database.
- `database_name` (String) The name of the database.
- `instance_id` (String) The ID of the instance.
- `project_id` (String) The STACKIT project ID.
- `region` (String) The region which should be addressed
### Read-Only
- `collation_name` (String) The collation of the database. This database collation should match the *collation_name* of one of the collations given by the **Get database collation list** endpoint.
- `compatibility_level` (Number) CompatibilityLevel of the Database.
- `id` (Number) The id of the database.

View file

@ -3,12 +3,12 @@
page_title: "stackitprivatepreview_sqlserverflexalpha_instance Resource - stackitprivatepreview"
subcategory: ""
description: |-
SQLServer Flex ALPHA instance resource schema. Must have a region specified in the provider configuration.
---
# stackitprivatepreview_sqlserverflexalpha_instance (Resource)
SQLServer Flex ALPHA instance resource schema. Must have a `region` specified in the provider configuration.
## Example Usage
@ -41,58 +41,63 @@ import {
### Required
- `encryption` (Attributes) The encryption block. (see [below for nested schema](#nestedatt--encryption))
- `flavor_id` (String)
- `name` (String) Instance name.
- `network` (Attributes) The network block. (see [below for nested schema](#nestedatt--network))
- `project_id` (String) STACKIT project ID to which the instance is associated.
- `backup_schedule` (String) The schedule for on what time and how often the database backup will be created. The schedule is written as a cron schedule.
- `flavor_id` (String) The id of the instance flavor.
- `name` (String) The name of the instance.
- `network` (Attributes) the network configuration of the instance. (see [below for nested schema](#nestedatt--network))
- `retention_days` (Number) The days for how long the backup files should be stored before cleaned up. 30 to 365
- `storage` (Attributes) The object containing information about the storage size and class. (see [below for nested schema](#nestedatt--storage))
- `version` (String) The sqlserver version used for the instance.
### Optional
- `backup_schedule` (String) The backup schedule. Should follow the cron scheduling system format (e.g. "0 0 * * *")
- `is_deletable` (Boolean)
- `region` (String) The resource region. If not defined, the provider region is used.
- `retention_days` (Number)
- `status` (String)
- `storage` (Attributes) (see [below for nested schema](#nestedatt--storage))
- `version` (String)
- `encryption` (Attributes) this defines which key to use for storage encryption (see [below for nested schema](#nestedatt--encryption))
- `instance_id` (String) The ID of the instance.
- `project_id` (String) The STACKIT project ID.
- `region` (String) The region which should be addressed
### Read-Only
- `edition` (String)
- `id` (String) Terraform's internal resource ID. It is structured as "`project_id`,`region`,`instance_id`".
- `instance_id` (String) ID of the SQLServer Flex instance.
- `replicas` (Number)
<a id="nestedatt--encryption"></a>
### Nested Schema for `encryption`
Required:
- `key_id` (String) STACKIT KMS - Key ID of the encryption key to use.
- `key_version` (String) STACKIT KMS - Key version to use in the encryption key.
- `keyring_id` (String) STACKIT KMS - KeyRing ID of the encryption key to use.
- `service_account` (String)
- `edition` (String) Edition of the MSSQL server instance
- `id` (String) The ID of the instance.
- `is_deletable` (Boolean) Whether the instance can be deleted or not.
- `replicas` (Number) How many replicas the instance should have.
- `status` (String)
<a id="nestedatt--network"></a>
### Nested Schema for `network`
Required:
- `access_scope` (String) The access scope of the instance. (SNA | PUBLIC)
- `acl` (List of String) The Access Control List (ACL) for the SQLServer Flex instance.
- `acl` (List of String) List of IPV4 cidr.
Optional:
- `access_scope` (String) The network access scope of the instance
⚠️ **Note:** This feature is in private preview. Supplying this object is only permitted for enabled accounts. If your account does not have access, the request will be rejected.
Read-Only:
- `instance_address` (String) The returned instance IP address of the SQLServer Flex instance.
- `router_address` (String) The returned router IP address of the SQLServer Flex instance.
- `instance_address` (String)
- `router_address` (String)
<a id="nestedatt--storage"></a>
### Nested Schema for `storage`
Optional:
Required:
- `class` (String)
- `size` (Number)
- `class` (String) The storage class for the storage.
- `size` (Number) The storage size in Gigabytes.
<a id="nestedatt--encryption"></a>
### Nested Schema for `encryption`
Required:
- `kek_key_id` (String) The key identifier
- `kek_key_ring_id` (String) The keyring identifier
- `kek_key_version` (String) The key version
- `service_account` (String)

View file

@ -3,12 +3,12 @@
page_title: "stackitprivatepreview_sqlserverflexalpha_user Resource - stackitprivatepreview"
subcategory: ""
description: |-
SQLServer Flex user resource schema. Must have a region specified in the provider configuration.
---
# stackitprivatepreview_sqlserverflexalpha_user (Resource)
SQLServer Flex user resource schema. Must have a `region` specified in the provider configuration.
## Example Usage
@ -32,21 +32,22 @@ import {
### Required
- `instance_id` (String) ID of the SQLServer Flex instance.
- `project_id` (String) STACKIT project ID to which the instance is associated.
- `roles` (Set of String) Database access levels for the user. The values for the default roles are: `##STACKIT_DatabaseManager##`, `##STACKIT_LoginManager##`, `##STACKIT_ProcessManager##`, `##STACKIT_ServerManager##`, `##STACKIT_SQLAgentManager##`, `##STACKIT_SQLAgentUser##`
- `username` (String) Username of the SQLServer Flex instance.
- `roles` (List of String) A list containing the user roles for the instance. A list with the valid user roles can be retrieved using the List Roles endpoint.
- `username` (String) The name of the user.
### Optional
- `region` (String)
- `default_database` (String) The default database for a user of the instance.
- `instance_id` (String) The ID of the instance.
- `project_id` (String) The STACKIT project ID.
- `region` (String) The region which should be addressed
- `user_id` (Number) The ID of the user.
### Read-Only
- `default_database` (String)
- `host` (String)
- `id` (String) Terraform's internal resource ID. It is structured as "`project_id`,`region`,`instance_id`,`user_id`".
- `password` (String, Sensitive) Password of the user account.
- `port` (Number)
- `status` (String)
- `user_id` (Number) User ID.
- `host` (String) The host of the instance in which the user belongs to.
- `id` (Number) The ID of the user.
- `password` (String) The password for the user.
- `port` (Number) The port of the instance in which the user belongs to.
- `status` (String) The current status of the user.
- `uri` (String) The connection string for the user to the instance.

View file

@ -0,0 +1,51 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "stackitprivatepreview_sqlserverflexbeta_database Resource - stackitprivatepreview"
subcategory: ""
description: |-
---
# stackitprivatepreview_sqlserverflexbeta_database (Resource)
## Example Usage
```terraform
resource "stackitprivatepreview_sqlserverflexalpha_user" "example" {
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
instance_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
username = "username"
roles = ["role"]
}
# Only use the import statement, if you want to import an existing sqlserverflex user
import {
to = stackitprivatepreview_sqlserverflexalpha_user.import-example
id = "${var.project_id},${var.region},${var.sql_instance_id},${var.sql_user_id}"
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `name` (String) The name of the database.
- `owner` (String) The owner of the database.
### Optional
- `collation` (String) The collation of the database. This database collation should match the *collation_name* of one of the collations given by the **Get database collation list** endpoint.
- `compatibility` (Number) CompatibilityLevel of the Database.
- `database_name` (String) The name of the database.
- `instance_id` (String) The ID of the instance.
- `project_id` (String) The STACKIT project ID.
- `region` (String) The region which should be addressed
### Read-Only
- `collation_name` (String) The collation of the database. This database collation should match the *collation_name* of one of the collations given by the **Get database collation list** endpoint.
- `compatibility_level` (Number) CompatibilityLevel of the Database.
- `id` (Number) The id of the database.

View file

@ -0,0 +1,158 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "stackitprivatepreview_sqlserverflexbeta_instance Resource - stackitprivatepreview"
subcategory: ""
description: |-
---
# stackitprivatepreview_sqlserverflexbeta_instance (Resource)
## Example Usage
```terraform
# without encryption and SNA
resource "stackitprivatepreview_sqlserverflexbeta_instance" "instance" {
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
name = "example-instance"
backup_schedule = "0 3 * * *"
retention_days = 31
flavor_id = "flavor_id"
storage = {
class = "premium-perf2-stackit"
size = 50
}
version = 2022
network = {
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
access_scope = "SNA"
}
}
# without encryption and PUBLIC
resource "stackitprivatepreview_sqlserverflexbeta_instance" "instance" {
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
name = "example-instance"
backup_schedule = "0 3 * * *"
retention_days = 31
flavor_id = "flavor_id"
storage = {
class = "premium-perf2-stackit"
size = 50
}
version = 2022
network = {
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
access_scope = "PUBLIC"
}
}
# with encryption and SNA
resource "stackitprivatepreview_sqlserverflexbeta_instance" "instance" {
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
name = "example-instance"
backup_schedule = "0 3 * * *"
retention_days = 31
flavor_id = "flavor_id"
storage = {
class = "premium-perf2-stackit"
size = 50
}
version = 2022
encryption = {
kek_key_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
kek_key_ring_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
kek_key_version = 1
service_account = "service_account@email"
}
network = {
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
access_scope = "SNA"
}
}
# Only use the import statement, if you want to import an existing sqlserverflex instance
import {
to = stackitprivatepreview_sqlserverflexalpha_instance.import-example
id = "${var.project_id},${var.region},${var.sql_instance_id}"
}
# import with identity
import {
to = stackitprivatepreview_sqlserverflexalpha_instance.import-example
identity = {
project_id = var.project_id
region = var.region
instance_id = var.sql_instance_id
}
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `backup_schedule` (String) The schedule for on what time and how often the database backup will be created. The schedule is written as a cron schedule.
- `flavor_id` (String) The id of the instance flavor.
- `name` (String) The name of the instance.
- `network` (Attributes) the network configuration of the instance. (see [below for nested schema](#nestedatt--network))
- `retention_days` (Number) The days for how long the backup files should be stored before cleaned up. 30 to 365
- `storage` (Attributes) The object containing information about the storage size and class. (see [below for nested schema](#nestedatt--storage))
- `version` (String) The sqlserver version used for the instance.
### Optional
- `encryption` (Attributes) this defines which key to use for storage encryption (see [below for nested schema](#nestedatt--encryption))
- `instance_id` (String) The ID of the instance.
- `project_id` (String) The STACKIT project ID.
- `region` (String) The region which should be addressed
### Read-Only
- `edition` (String) Edition of the MSSQL server instance
- `id` (String) The ID of the instance.
- `is_deletable` (Boolean) Whether the instance can be deleted or not.
- `replicas` (Number) How many replicas the instance should have.
- `status` (String)
<a id="nestedatt--network"></a>
### Nested Schema for `network`
Required:
- `acl` (List of String) List of IPV4 cidr.
Optional:
- `access_scope` (String) The network access scope of the instance
⚠️ **Note:** This feature is in private preview. Supplying this object is only permitted for enabled accounts. If your account does not have access, the request will be rejected.
Read-Only:
- `instance_address` (String)
- `router_address` (String)
<a id="nestedatt--storage"></a>
### Nested Schema for `storage`
Required:
- `class` (String) The storage class for the storage.
- `size` (Number) The storage size in Gigabytes.
<a id="nestedatt--encryption"></a>
### Nested Schema for `encryption`
Required:
- `kek_key_id` (String) The key identifier
- `kek_key_ring_id` (String) The keyring identifier
- `kek_key_version` (String) The key version
- `service_account` (String)

View file

@ -0,0 +1,53 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "stackitprivatepreview_sqlserverflexbeta_user Resource - stackitprivatepreview"
subcategory: ""
description: |-
---
# stackitprivatepreview_sqlserverflexbeta_user (Resource)
## Example Usage
```terraform
resource "stackitprivatepreview_sqlserverflexalpha_user" "example" {
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
instance_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
username = "username"
roles = ["role"]
}
# Only use the import statement, if you want to import an existing sqlserverflex user
import {
to = stackitprivatepreview_sqlserverflexalpha_user.import-example
id = "${var.project_id},${var.region},${var.sql_instance_id},${var.sql_user_id}"
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `roles` (List of String) A list containing the user roles for the instance. A list with the valid user roles can be retrieved using the List Roles endpoint.
- `username` (String) The name of the user.
### Optional
- `default_database` (String) The default database for a user of the instance.
- `instance_id` (String) The ID of the instance.
- `project_id` (String) The STACKIT project ID.
- `region` (String) The region which should be addressed
- `user_id` (Number) The ID of the user.
### Read-Only
- `host` (String) The host of the instance in which the user belongs to.
- `id` (Number) The ID of the user.
- `password` (String) The password for the user.
- `port` (Number) The port of the instance in which the user belongs to.
- `status` (String) The current status of the user.
- `uri` (String) The connection string for the user to the instance.

View file

@ -0,0 +1,8 @@
data "stackitprivatepreview_postgresflexalpha_flavor" "flavor" {
project_id = var.project_id
region = var.region
cpu = 4
ram = 16
node_type = "Single"
storage_class = "premium-perf2-stackit"
}

View file

@ -0,0 +1,8 @@
data "stackitprivatepreview_sqlserverflexalpha_flavor" "flavor" {
project_id = var.project_id
region = var.region
cpu = 4
ram = 16
node_type = "Single"
storage_class = "premium-perf2-stackit"
}

View file

@ -0,0 +1,5 @@
data "stackitprivatepreview_sqlserverflexbeta_database" "example" {
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
instance_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
database_name = "dbname"
}

View file

@ -0,0 +1,8 @@
data "stackitprivatepreview_sqlserverflexbeta_flavor" "flavor" {
project_id = var.project_id
region = var.region
cpu = 4
ram = 16
node_type = "Single"
storage_class = "premium-perf2-stackit"
}

View file

@ -0,0 +1,4 @@
data "stackitprivatepreview_sqlserverflexbeta_instance" "example" {
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
instance_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

View file

@ -2,14 +2,13 @@ provider "stackitprivatepreview" {
default_region = "eu01"
}
# Authentication
# Token flow (scheduled for deprecation and will be removed on December 17, 2025)
provider "stackitprivatepreview" {
default_region = "eu01"
service_account_token = var.service_account_token
default_region = "eu01"
service_account_key_path = "service_account.json"
}
# Authentication
# Key flow
provider "stackitprivatepreview" {
default_region = "eu01"
@ -23,4 +22,3 @@ provider "stackitprivatepreview" {
service_account_key_path = var.service_account_key_path
private_key_path = var.private_key_path
}

View file

@ -9,4 +9,14 @@ resource "stackitprivatepreview_postgresflexalpha_database" "example" {
import {
to = stackitprivatepreview_postgresflexalpha_database.import-example
id = "${var.project_id},${var.region},${var.postgres_instance_id},${var.postgres_database_id}"
}
}
import {
to = stackitprivatepreview_postgresflexalpha_database.import-example
identity = {
project_id = "project_id"
region = "region"
instance_id = "instance_id"
database_id = "database_id"
}
}

View file

@ -1,22 +1,39 @@
resource "stackitprivatepreview_postgresflexalpha_instance" "example" {
resource "stackitprivatepreview_postgresflexalpha_instance" "example-instance" {
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
name = "example-instance"
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
backup_schedule = "00 00 * * *"
flavor = {
cpu = 2
ram = 4
}
replicas = 3
backup_schedule = "0 0 * * *"
retention_days = 30
flavor_id = "flavor.id"
replicas = 1
storage = {
class = "class"
size = 5
performance_class = "premium-perf2-stackit"
size = 10
}
version = 14
encryption = {
kek_key_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
kek_key_ring_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
kek_key_version = 1
service_account = "service@account.email"
}
network = {
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
access_scope = "PUBLIC"
}
version = 17
}
# Only use the import statement, if you want to import an existing postgresflex instance
import {
to = stackitprivatepreview_postgresflexalpha_instance.import-example
id = "${var.project_id},${var.region},${var.postgres_instance_id}"
}
}
import {
to = stackitprivatepreview_postgresflexalpha_instance.import-example
identity = {
project_id = var.project_id
region = var.region
instance_id = var.postgres_instance_id
}
}

View file

@ -1,7 +1,7 @@
resource "stackitprivatepreview_postgresflexalpha_user" "example" {
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
instance_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
username = "username"
name = "username"
roles = ["role"]
}
@ -9,4 +9,14 @@ resource "stackitprivatepreview_postgresflexalpha_user" "example" {
import {
to = stackitprivatepreview_postgresflexalpha_user.import-example
id = "${var.project_id},${var.region},${var.postgres_instance_id},${var.user_id}"
}
}
import {
to = stackitprivatepreview_postgresflexalpha_user.import-example
identity = {
project_id = "project.id"
region = "region"
instance_id = "instance.id"
user_id = "user.id"
}
}

View file

@ -0,0 +1,24 @@
resource "stackitprivatepreview_sqlserverflexalpha_database" "example" {
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
instance_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
collation = ""
compatibility = "160"
name = ""
owner = ""
}
# Only use the import statement, if you want to import a existing sqlserverflex database
import {
to = stackitprivatepreview_sqlserverflexalpha_database.import-example
id = "${var.project_id},${var.region},${var.sql_instance_id},${var.sql_user_id}"
}
import {
to = stackitprivatepreview_sqlserverflexalpha_database.import-example
identity = {
project_id = "project.id"
region = "region"
instance_id = "instance.id"
database_id = "database.id"
}
}

View file

@ -0,0 +1,12 @@
resource "stackitprivatepreview_sqlserverflexalpha_user" "example" {
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
instance_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
username = "username"
roles = ["role"]
}
# Only use the import statement, if you want to import an existing sqlserverflex user
import {
to = stackitprivatepreview_sqlserverflexalpha_user.import-example
id = "${var.project_id},${var.region},${var.sql_instance_id},${var.sql_user_id}"
}

View file

@ -0,0 +1,76 @@
# without encryption and SNA
resource "stackitprivatepreview_sqlserverflexbeta_instance" "instance" {
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
name = "example-instance"
backup_schedule = "0 3 * * *"
retention_days = 31
flavor_id = "flavor_id"
storage = {
class = "premium-perf2-stackit"
size = 50
}
version = 2022
network = {
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
access_scope = "SNA"
}
}
# without encryption and PUBLIC
resource "stackitprivatepreview_sqlserverflexbeta_instance" "instance" {
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
name = "example-instance"
backup_schedule = "0 3 * * *"
retention_days = 31
flavor_id = "flavor_id"
storage = {
class = "premium-perf2-stackit"
size = 50
}
version = 2022
network = {
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
access_scope = "PUBLIC"
}
}
# with encryption and SNA
resource "stackitprivatepreview_sqlserverflexbeta_instance" "instance" {
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
name = "example-instance"
backup_schedule = "0 3 * * *"
retention_days = 31
flavor_id = "flavor_id"
storage = {
class = "premium-perf2-stackit"
size = 50
}
version = 2022
encryption = {
kek_key_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
kek_key_ring_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
kek_key_version = 1
service_account = "service_account@email"
}
network = {
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
access_scope = "SNA"
}
}
# Only use the import statement, if you want to import an existing sqlserverflex instance
import {
to = stackitprivatepreview_sqlserverflexalpha_instance.import-example
id = "${var.project_id},${var.region},${var.sql_instance_id}"
}
# import with identity
import {
to = stackitprivatepreview_sqlserverflexalpha_instance.import-example
identity = {
project_id = var.project_id
region = var.region
instance_id = var.sql_instance_id
}
}

View file

@ -0,0 +1,12 @@
resource "stackitprivatepreview_sqlserverflexalpha_user" "example" {
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
instance_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
username = "username"
roles = ["role"]
}
# Only use the import statement, if you want to import an existing sqlserverflex user
import {
to = stackitprivatepreview_sqlserverflexalpha_user.import-example
id = "${var.project_id},${var.region},${var.sql_instance_id},${var.sql_user_id}"
}

View file

@ -0,0 +1,341 @@
package build
import (
"errors"
"fmt"
"go/ast"
"go/parser"
"go/token"
"log/slog"
"os"
"path"
"regexp"
"strings"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/generator/cmd/tools"
)
type Builder struct {
rootDir string
SkipClone bool
SkipCleanup bool
PackagesOnly bool
Verbose bool
Debug bool
}
func (b *Builder) Build() error {
slog.Info("Starting Builder")
if b.PackagesOnly {
slog.Info(" >>> only generating pkg_gen <<<")
}
rootErr := b.determineRoot()
if rootErr != nil {
return rootErr
}
if !b.PackagesOnly {
if b.Verbose {
slog.Info(" ... Checking needed commands available")
}
chkErr := checkCommands([]string{})
if chkErr != nil {
return chkErr
}
}
// if !b.SkipCleanup {
// slog.Info("Cleaning up old packages directory")
// err := os.RemoveAll(path.Join(b.rootDir, "pkg_gen"))
// if err != nil {
// return err
// }
//}
//
// if !b.SkipCleanup && !b.PackagesOnly {
// slog.Info("Cleaning up old packages directory")
// err := os.RemoveAll(path.Join(b.rootDir, "pkg_gen"))
// if err != nil {
// return err
// }
//}
// slog.Info("Creating generator dir", "dir", fmt.Sprintf("%s/%s", *root, GEN_REPO_NAME))
// genDir := path.Join(*root, GEN_REPO_NAME)
// if !b.SkipClone {
// err = createGeneratorDir(GEN_REPO, genDir, b.SkipClone)
// if err != nil {
// return err
// }
//}
oasHandlerErr := b.oasHandler(path.Join(b.rootDir, "service_specs"))
if oasHandlerErr != nil {
return oasHandlerErr
}
// if !b.PackagesOnly {
// slog.Info("Generating service boilerplate")
// err = generateServiceFiles(*root, path.Join(*root, GEN_REPO_NAME))
// if err != nil {
// return err
// }
//
// slog.Info("Copying all service files")
// err = CopyDirectory(
// path.Join(*root, "generated", "internal", "services"),
// path.Join(*root, "stackit", "internal", "services"),
// )
// if err != nil {
// return err
// }
//
// err = createBoilerplate(*root, path.Join(*root, "stackit", "internal", "services"))
// if err != nil {
// return err
// }
//}
// workaround to remove linter complain :D
if b.PackagesOnly && b.Verbose && b.SkipClone && b.SkipCleanup {
bpErr := createBoilerplate(b.rootDir, "boilerplate")
if bpErr != nil {
return bpErr
}
}
slog.Info("Done")
return nil
}
type templateData struct {
PackageName string
PackageNameCamel string
PackageNamePascal string
NameCamel string
NamePascal string
NameSnake string
Fields []string
}
func createBoilerplate(rootFolder, folder string) error {
services, err := os.ReadDir(folder)
if err != nil {
return err
}
for _, svc := range services {
if !svc.IsDir() {
continue
}
resources, err := os.ReadDir(path.Join(folder, svc.Name()))
if err != nil {
return err
}
var handleDS bool
var handleRes bool
var foundDS bool
var foundRes bool
for _, res := range resources {
if !res.IsDir() {
continue
}
resourceName := res.Name()
dsFile := path.Join(
folder,
svc.Name(),
res.Name(),
"datasources_gen",
fmt.Sprintf("%s_data_source_gen.go", res.Name()),
)
handleDS = FileExists(dsFile)
resFile := path.Join(
folder,
svc.Name(),
res.Name(),
"resources_gen",
fmt.Sprintf("%s_resource_gen.go", res.Name()),
)
handleRes = FileExists(resFile)
dsGoFile := path.Join(folder, svc.Name(), res.Name(), "datasource.go")
foundDS = FileExists(dsGoFile)
resGoFile := path.Join(folder, svc.Name(), res.Name(), "resource.go")
foundRes = FileExists(resGoFile)
if handleDS && !foundDS {
slog.Info(" creating missing datasource.go", "service", svc.Name(), "resource", resourceName)
if !ValidateSnakeCase(resourceName) {
return errors.New("resource name is invalid")
}
fields, tokenErr := getTokens(dsFile)
if tokenErr != nil {
return fmt.Errorf("error reading tokens: %w", tokenErr)
}
tplName := "data_source_scaffold.gotmpl"
err = writeTemplateToFile(
tplName,
path.Join(rootFolder, "cmd", "cmd", "build", "templates", tplName),
dsGoFile,
&templateData{
PackageName: svc.Name(),
PackageNameCamel: ToCamelCase(svc.Name()),
PackageNamePascal: ToPascalCase(svc.Name()),
NameCamel: ToCamelCase(resourceName),
NamePascal: ToPascalCase(resourceName),
NameSnake: resourceName,
Fields: fields,
},
)
if err != nil {
panic(err)
}
}
if handleRes && !foundRes {
slog.Info(" creating missing resource.go", "service", svc.Name(), "resource", resourceName)
if !ValidateSnakeCase(resourceName) {
return errors.New("resource name is invalid")
}
fields, tokenErr := getTokens(resFile)
if tokenErr != nil {
return fmt.Errorf("error reading tokens: %w", tokenErr)
}
tplName := "resource_scaffold.gotmpl"
err = writeTemplateToFile(
tplName,
path.Join(rootFolder, "cmd", "cmd", "build", "templates", tplName),
resGoFile,
&templateData{
PackageName: svc.Name(),
PackageNameCamel: ToCamelCase(svc.Name()),
PackageNamePascal: ToPascalCase(svc.Name()),
NameCamel: ToCamelCase(resourceName),
NamePascal: ToPascalCase(resourceName),
NameSnake: resourceName,
Fields: fields,
},
)
if err != nil {
return err
}
if !FileExists(path.Join(folder, svc.Name(), res.Name(), "functions.go")) {
slog.Info(" creating missing functions.go", "service", svc.Name(), "resource", resourceName)
if !ValidateSnakeCase(resourceName) {
return errors.New("resource name is invalid")
}
fncTplName := "functions_scaffold.gotmpl"
err = writeTemplateToFile(
fncTplName,
path.Join(rootFolder, "cmd", "cmd", "build", "templates", fncTplName),
path.Join(folder, svc.Name(), res.Name(), "functions.go"),
&templateData{
PackageName: svc.Name(),
PackageNameCamel: ToCamelCase(svc.Name()),
PackageNamePascal: ToPascalCase(svc.Name()),
NameCamel: ToCamelCase(resourceName),
NamePascal: ToPascalCase(resourceName),
NameSnake: resourceName,
},
)
if err != nil {
return err
}
}
}
}
}
return nil
}
func handleLine(line string) (string, error) {
schemaRegex := regexp.MustCompile(`(\s+")(id)(": schema.[a-zA-Z0-9]+Attribute{)`)
schemaMatches := schemaRegex.FindAllStringSubmatch(line, -1)
if schemaMatches != nil {
return fmt.Sprintf("%stf_original_api_id%s", schemaMatches[0][1], schemaMatches[0][3]), nil
}
modelRegex := regexp.MustCompile(`(\s+Id\s+types.[a-zA-Z0-9]+\s+.tfsdk:")(id)(".)`)
modelMatches := modelRegex.FindAllStringSubmatch(line, -1)
if modelMatches != nil {
return fmt.Sprintf("%stf_original_api_id%s", modelMatches[0][1], modelMatches[0][3]), nil
}
return line, nil
}
func (b *Builder) determineRoot() error {
root, err := tools.GetGitRoot()
if err != nil {
return err
}
b.rootDir = root
if b.Verbose {
slog.Info(" ... using root", "dir", b.rootDir)
}
return nil
}
// func createGeneratorDir(repoUrl, targetDir string, skipClone bool) error {
// if !skipClone {
// if FileExists(targetDir) {
// remErr := os.RemoveAll(targetDir)
// if remErr != nil {
// return remErr
// }
// }
// _, cloneErr := git.Clone(
// clone.Repository(repoUrl),
// clone.Directory(targetDir),
// )
// if cloneErr != nil {
// return cloneErr
// }
// }
// return nil
//}
func getTokens(fileName string) ([]string, error) {
fset := token.NewFileSet()
var result []string
node, err := parser.ParseFile(fset, fileName, nil, parser.ParseComments)
if err != nil {
return nil, err
}
ast.Inspect(
node, func(n ast.Node) bool {
// Suche nach Typ-Deklarationen (structs)
ts, ok := n.(*ast.TypeSpec)
if ok {
if strings.Contains(ts.Name.Name, "Model") {
ast.Inspect(
ts, func(sn ast.Node) bool {
tts, tok := sn.(*ast.Field)
if tok {
result = append(result, tts.Names[0].String())
}
return true
},
)
}
}
return true
},
)
return result, nil
}

131
generator/cmd/build/copy.go Normal file
View file

@ -0,0 +1,131 @@
package build
import (
"fmt"
"io"
"log/slog"
"os"
"path/filepath"
"syscall"
)
// Source - https://stackoverflow.com/a
// Posted by Oleg Neumyvakin, modified by community. See post 'Timeline' for change history
// Retrieved 2026-01-20, License - CC BY-SA 4.0
func CopyDirectory(scrDir, dest string) error {
entries, err := os.ReadDir(scrDir)
if err != nil {
return err
}
for _, entry := range entries {
sourcePath := filepath.Join(scrDir, entry.Name())
destPath := filepath.Join(dest, entry.Name())
fileInfo, err := os.Stat(sourcePath)
if err != nil {
return err
}
stat, ok := fileInfo.Sys().(*syscall.Stat_t)
if !ok {
return fmt.Errorf("failed to get raw syscall.Stat_t data for '%s'", sourcePath)
}
switch fileInfo.Mode() & os.ModeType {
case os.ModeDir:
if err := CreateIfNotExists(destPath, 0o755); err != nil {
return err
}
if err := CopyDirectory(sourcePath, destPath); err != nil {
return err
}
case os.ModeSymlink:
if err := CopySymLink(sourcePath, destPath); err != nil {
return err
}
default:
if err := Copy(sourcePath, destPath); err != nil {
return err
}
}
if err := os.Lchown(destPath, int(stat.Uid), int(stat.Gid)); err != nil {
return err
}
fInfo, err := entry.Info()
if err != nil {
return err
}
isSymlink := fInfo.Mode()&os.ModeSymlink != 0
if !isSymlink {
if err := os.Chmod(destPath, fInfo.Mode()); err != nil {
return err
}
}
}
return nil
}
func Copy(srcFile, dstFile string) error {
out, err := os.Create(dstFile)
if err != nil {
return err
}
defer func(out *os.File) {
err := out.Close()
if err != nil {
slog.Error("failed to close file", slog.Any("err", err))
}
}(out)
in, err := os.Open(srcFile)
if err != nil {
return err
}
defer func(in *os.File) {
err := in.Close()
if err != nil {
slog.Error("error closing destination file", slog.Any("err", err))
}
}(in)
_, err = io.Copy(out, in)
if err != nil {
return err
}
return nil
}
func Exists(filePath string) bool {
if _, err := os.Stat(filePath); os.IsNotExist(err) {
return false
}
return true
}
func CreateIfNotExists(dir string, perm os.FileMode) error {
if Exists(dir) {
return nil
}
if err := os.MkdirAll(dir, perm); err != nil {
return fmt.Errorf("failed to create directory: '%s', error: '%s'", dir, err.Error())
}
return nil
}
func CopySymLink(source, dest string) error {
link, err := os.Readlink(source)
if err != nil {
return err
}
return os.Symlink(link, dest)
}

View file

@ -0,0 +1,53 @@
package build
import (
"regexp"
"strings"
"unicode"
"unicode/utf8"
)
// snakeLetters will match to the first letter and an underscore followed by a letter
var snakeLetters = regexp.MustCompile("(^[a-z])|_[a-z0-9]")
func ToPascalCase(in string) string {
inputSplit := strings.Split(in, ".")
var ucName string
for _, v := range inputSplit {
if len(v) < 1 {
continue
}
firstChar := v[0:1]
ucFirstChar := strings.ToUpper(firstChar)
if len(v) < 2 {
ucName += ucFirstChar
continue
}
ucName += ucFirstChar + v[1:]
}
return snakeLetters.ReplaceAllStringFunc(ucName, func(s string) string {
return strings.ToUpper(strings.ReplaceAll(s, "_", ""))
})
}
func ToCamelCase(in string) string {
pascal := ToPascalCase(in)
// Grab first rune and lower case it
firstLetter, size := utf8.DecodeRuneInString(pascal)
if firstLetter == utf8.RuneError && size <= 1 {
return pascal
}
return string(unicode.ToLower(firstLetter)) + pascal[size:]
}
func ValidateSnakeCase(in string) bool {
return snakeLetters.MatchString(string(in))
}

View file

@ -0,0 +1,120 @@
package build
import (
"fmt"
"log/slog"
"os"
"os/exec"
"strings"
"text/template"
)
func FileExists(pathValue string) bool {
_, err := os.Stat(pathValue)
if os.IsNotExist(err) {
return false
}
if err != nil {
panic(err)
}
return true
}
func ucfirst(s string) string {
if s == "" {
return ""
}
return strings.ToUpper(s[:1]) + s[1:]
}
func writeTemplateToFile(tplName, tplFile, outFile string, data *templateData) error {
fn := template.FuncMap{
"ucfirst": ucfirst,
}
tmpl, err := template.New(tplName).Funcs(fn).ParseFiles(tplFile)
if err != nil {
return err
}
var f *os.File
f, err = os.Create(outFile)
if err != nil {
return err
}
err = tmpl.Execute(f, *data)
if err != nil {
return err
}
err = f.Close()
if err != nil {
return err
}
return nil
}
/* saved for later
func deleteFiles(fNames ...string) error {
for _, fName := range fNames {
if _, err := os.Stat(fName); !os.IsNotExist(err) {
err = os.Remove(fName)
if err != nil {
return err
}
}
}
return nil
}
func copyFile(src, dst string) (int64, error) {
sourceFileStat, err := os.Stat(src)
if err != nil {
return 0, err
}
if !sourceFileStat.Mode().IsRegular() {
return 0, fmt.Errorf("%s is not a regular file", src)
}
source, err := os.Open(src)
if err != nil {
return 0, err
}
defer func(source *os.File) {
err := source.Close()
if err != nil {
slog.Error("copyFile", "err", err)
}
}(source)
destination, err := os.Create(dst)
if err != nil {
return 0, err
}
defer func(destination *os.File) {
err := destination.Close()
if err != nil {
slog.Error("copyFile", "err", err)
}
}(destination)
nBytes, err := io.Copy(destination, source)
return nBytes, err
}
*/
func checkCommands(commands []string) error {
for _, commandName := range commands {
if !commandExists(commandName) {
return fmt.Errorf("missing command %s", commandName)
}
slog.Info(" found", "command", commandName)
}
return nil
}
func commandExists(cmd string) bool {
_, err := exec.LookPath(cmd)
return err == nil
}

View file

@ -0,0 +1,446 @@
package build
import (
"bufio"
"bytes"
"errors"
"fmt"
"log"
"log/slog"
"os"
"os/exec"
"path"
"regexp"
"strings"
"gopkg.in/yaml.v3"
"github.com/ldez/go-git-cmd-wrapper/v2/clone"
"github.com/ldez/go-git-cmd-wrapper/v2/git"
)
const (
OasRepoName = "stackit-api-specifications"
OasRepo = "https://github.com/stackitcloud/stackit-api-specifications.git"
ResTypeResource = "resources"
ResTypeDataSource = "datasources"
)
type Data struct {
ServiceName string `yaml:",omitempty" json:",omitempty"`
Versions []Version `yaml:"versions" json:"versions"`
}
type Version struct {
Name string `yaml:"name" json:"name"`
Path string `yaml:"path" json:"path"`
}
var oasTempDir string
func (b *Builder) oasHandler(specDir string) error {
if b.Verbose {
slog.Info("creating schema files", "dir", specDir)
}
if _, err := os.Stat(specDir); os.IsNotExist(err) {
return fmt.Errorf("spec files directory does not exist")
}
err := b.createRepoDir(b.SkipClone)
if err != nil {
return fmt.Errorf("%s", err.Error())
}
err2 := b.handleServices(specDir)
if err2 != nil {
return err2
}
if !b.SkipCleanup {
if b.Verbose {
slog.Info("Finally removing temporary files and directories")
}
err := os.RemoveAll(path.Join(b.rootDir, "generated"))
if err != nil {
slog.Error("RemoveAll", "dir", path.Join(b.rootDir, "generated"), "err", err)
return err
}
err = os.RemoveAll(oasTempDir)
if err != nil {
slog.Error("RemoveAll", "dir", oasTempDir, "err", err)
return err
}
}
return nil
}
func (b *Builder) handleServices(specDir string) error {
services, err := os.ReadDir(specDir)
if err != nil {
return err
}
for _, svc := range services {
if !svc.IsDir() {
continue
}
if b.Verbose {
slog.Info(" ... found", "service", svc.Name())
}
var svcVersions Data
svcVersions.ServiceName = svc.Name()
versionsErr := b.getServiceVersions(path.Join(specDir, svc.Name(), "generator_settings.yml"), &svcVersions)
if versionsErr != nil {
return versionsErr
}
oasSpecErr := b.generateServiceFiles(&svcVersions)
if oasSpecErr != nil {
return oasSpecErr
}
}
return nil
}
func (b *Builder) getServiceVersions(confFile string, data *Data) error {
if _, cfgFileErr := os.Stat(confFile); os.IsNotExist(cfgFileErr) {
return fmt.Errorf("config file does not exist")
}
fileContent, fileErr := os.ReadFile(confFile)
if fileErr != nil {
return fileErr
}
convErr := yaml.Unmarshal(fileContent, &data)
if convErr != nil {
return convErr
}
return nil
}
func (b *Builder) createRepoDir(skipClone bool) error {
tmpDirName, err := os.MkdirTemp("", "oasbuild")
if err != nil {
return err
}
oasTempDir = path.Join(tmpDirName, OasRepoName)
slog.Info("Creating oas repo dir", "dir", oasTempDir)
if !skipClone {
if FileExists(oasTempDir) {
slog.Warn("target dir exists - skipping", "targetDir", oasTempDir)
return nil
}
out, cloneErr := git.Clone(
clone.Repository(OasRepo),
clone.Directory(oasTempDir),
)
if cloneErr != nil {
slog.Error("git clone error", "output", out)
return cloneErr
}
if b.Verbose {
slog.Info("git clone result", "output", out)
}
}
return nil
}
func (b *Builder) generateServiceFiles(data *Data) error {
err := os.MkdirAll(path.Join(b.rootDir, "generated", "specs"), 0o750)
if err != nil {
return err
}
for _, v := range data.Versions {
specFiles, specsErr := os.ReadDir(path.Join(b.rootDir, "service_specs", data.ServiceName, v.Name))
if specsErr != nil {
return specsErr
}
for _, specFile := range specFiles {
if specFile.IsDir() {
continue
}
r := regexp.MustCompile(`^(.*)_config.yml$`)
matches := r.FindAllStringSubmatch(specFile.Name(), -1)
if matches == nil {
slog.Warn(" skipping file (no regex match)", "file", specFile.Name())
continue
}
srcSpecFile := path.Join(b.rootDir, "service_specs", data.ServiceName, v.Name, specFile.Name())
if matches[0][0] != specFile.Name() {
return fmt.Errorf("matched filename differs from original filename - this should not happen")
}
resource := matches[0][1]
if b.Verbose {
slog.Info(
" found service spec",
"service",
data.ServiceName,
"resource",
resource,
"file",
specFile.Name(),
)
}
oasFile := path.Join(
oasTempDir,
"services",
data.ServiceName,
v.Path,
fmt.Sprintf("%s.json", data.ServiceName),
)
if _, oasErr := os.Stat(oasFile); os.IsNotExist(oasErr) {
slog.Warn(
" could not find matching oas",
"svc",
data.ServiceName,
"version",
v.Name,
)
continue
}
// determine correct target service name
scName := fmt.Sprintf("%s%s", data.ServiceName, v.Name)
scName = strings.ReplaceAll(scName, "-", "")
specJSONFile := path.Join(
b.rootDir,
"generated",
"specs",
fmt.Sprintf("%s_%s_spec.json", scName, resource),
)
cmdErr := b.runTerraformPluginGenOpenAPI(srcSpecFile, specJSONFile, oasFile)
if cmdErr != nil {
return cmdErr
}
cmdResGenErr := b.runTerraformPluginGenFramework(ResTypeResource, scName, resource, specJSONFile)
if cmdResGenErr != nil {
return cmdResGenErr
}
cmdDsGenErr := b.runTerraformPluginGenFramework(ResTypeDataSource, scName, resource, specJSONFile)
if cmdDsGenErr != nil {
return cmdDsGenErr
}
}
}
return nil
}
func (b *Builder) runTerraformPluginGenFramework(resType, svcName, resource, specJSONFile string) error {
var stdOut, stdErr bytes.Buffer
tgtFolder := path.Join(
b.rootDir,
"stackit",
"internal",
"services",
svcName,
resource,
fmt.Sprintf("%s_gen", resType),
)
//nolint:gosec // this file is not sensitive, so we can use 0755
err := os.MkdirAll(tgtFolder, 0o755)
if err != nil {
return err
}
var subCmd string
switch resType {
case ResTypeResource:
subCmd = "resources"
case ResTypeDataSource:
subCmd = "data-sources"
default:
return fmt.Errorf("unknown resource type given: %s", resType)
}
// nolint:gosec // #nosec this command is not using any untrusted input, so we can ignore gosec warning
cmd := exec.Command(
"tfplugingen-framework",
"generate",
subCmd,
"--input",
specJSONFile,
"--output",
tgtFolder,
"--package",
svcName,
)
cmd.Stdout = &stdOut
cmd.Stderr = &stdErr
if err = cmd.Start(); err != nil {
slog.Error(fmt.Sprintf("tfplugingen-framework generate %s", resType), "error", err)
return err
}
if err = cmd.Wait(); err != nil {
var exitErr *exec.ExitError
if errors.As(err, &exitErr) {
slog.Error(
fmt.Sprintf("tfplugingen-framework generate %s", resType),
"code",
exitErr.ExitCode(),
"error",
err,
"stdout",
stdOut.String(),
"stderr",
stdErr.String(),
)
return fmt.Errorf("%s", stdErr.String())
}
if err != nil {
slog.Error(
fmt.Sprintf("tfplugingen-framework generate %s", resType),
"err",
err,
"stdout",
stdOut.String(),
"stderr",
stdErr.String(),
)
return err
}
}
if resType == ResTypeDataSource {
tfAnoErr := b.handleTfTagForDatasourceFile(
path.Join(tgtFolder, fmt.Sprintf("%s_data_source_gen.go", resource)),
svcName,
resource,
)
if tfAnoErr != nil {
return tfAnoErr
}
}
return nil
}
func (b *Builder) runTerraformPluginGenOpenAPI(srcSpecFile, specJSONFile, oasFile string) error {
var stdOut, stdErr bytes.Buffer
// nolint:gosec // #nosec this command is not using any untrusted input, so we can ignore gosec warning
cmd := exec.Command(
"tfplugingen-openapi",
"generate",
"--config",
srcSpecFile,
"--output",
specJSONFile,
oasFile,
)
cmd.Stdout = &stdOut
cmd.Stderr = &stdErr
if err := cmd.Start(); err != nil {
slog.Error(
"tfplugingen-openapi generate",
"error",
err,
"stdOut",
stdOut.String(),
"stdErr",
stdErr.String(),
)
return err
}
if err := cmd.Wait(); err != nil {
var exitErr *exec.ExitError
if errors.As(err, &exitErr) {
slog.Error(
"tfplugingen-openapi generate",
"code",
exitErr.ExitCode(),
"error",
err,
"stdout",
stdOut.String(),
"stderr",
stdErr.String(),
)
return fmt.Errorf("%s", stdErr.String())
}
if err != nil {
slog.Error(
"tfplugingen-openapi generate",
"err",
err,
"stdout",
stdOut.String(),
"stderr",
stdErr.String(),
)
return err
}
}
if stdOut.Len() > 0 {
slog.Warn(" command output", "stdout", stdOut.String(), "stderr", stdErr.String())
}
return nil
}
// handleTfTagForDatasourceFile replaces existing "id" with "stf_original_api_id"
func (b *Builder) handleTfTagForDatasourceFile(filePath, service, resource string) error {
if b.Verbose {
slog.Info(" handle terraform tag for datasource", "service", service, "resource", resource)
}
if !FileExists(filePath) {
slog.Warn(" could not find file, skipping", "path", filePath)
return nil
}
f, err := os.Open(filePath)
if err != nil {
return err
}
tmp, err := os.CreateTemp(b.rootDir, "replace-*")
if err != nil {
return err
}
sc := bufio.NewScanner(f)
for sc.Scan() {
resLine, err := handleLine(sc.Text())
if err != nil {
return err
}
if _, err := tmp.WriteString(resLine + "\n"); err != nil {
return err
}
}
if scErr := sc.Err(); scErr != nil {
return scErr
}
if err := tmp.Close(); err != nil {
return err
}
if err := f.Close(); err != nil {
return err
}
//nolint:gosec // path traversal is not a concern here
if err := os.Rename(tmp.Name(), filePath); err != nil {
log.Fatal(err)
}
return nil
}

View file

@ -0,0 +1,148 @@
package {{.PackageName}}
import (
"context"
"fmt"
"net/http"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/stackitcloud/stackit-sdk-go/core/config"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
{{.PackageName}}Pkg "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/{{.PackageName}}"
{{.PackageName}}Gen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/{{.PackageName}}/{{.NameSnake}}/datasources_gen"
)
var _ datasource.DataSource = (*{{.NameCamel}}DataSource)(nil)
const errorPrefix = "[{{.PackageNamePascal}} - {{.NamePascal}}]"
func New{{.NamePascal}}DataSource() datasource.DataSource {
return &{{.NameCamel}}DataSource{}
}
type dsModel struct {
{{.PackageName}}Gen.{{.NamePascal}}Model
TfId types.String `tfsdk:"id"`
}
type {{.NameCamel}}DataSource struct{
client *{{.PackageName}}Pkg.APIClient
providerData core.ProviderData
}
func (d *{{.NameCamel}}DataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_{{.PackageName}}_{{.NameSnake}}"
}
func (d *{{.NameCamel}}DataSource) Schema(ctx context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = {{.PackageName}}Gen.{{.NamePascal}}DataSourceSchema(ctx)
resp.Schema.Attributes["id"] = schema.StringAttribute{
Computed: true,
Description: "The terraform internal identifier.",
MarkdownDescription: "The terraform internal identifier.",
}
}
// Configure adds the provider configured client to the data source.
func (d *{{.NameCamel}}DataSource) Configure(
ctx context.Context,
req datasource.ConfigureRequest,
resp *datasource.ConfigureResponse,
) {
var ok bool
d.providerData, ok = conversion.ParseProviderData(ctx, req.ProviderData, &resp.Diagnostics)
if !ok {
return
}
apiClientConfigOptions := []config.ConfigurationOption{
config.WithCustomAuth(d.providerData.RoundTripper),
utils.UserAgentConfigOption(d.providerData.Version),
}
if d.providerData.{{.PackageNamePascal}}CustomEndpoint != "" {
apiClientConfigOptions = append(
apiClientConfigOptions,
config.WithEndpoint(d.providerData.{{.PackageNamePascal}}CustomEndpoint),
)
} else {
apiClientConfigOptions = append(
apiClientConfigOptions,
config.WithRegion(d.providerData.GetRegion()),
)
}
apiClient, err := {{.PackageName}}Pkg.NewAPIClient(apiClientConfigOptions...)
if err != nil {
resp.Diagnostics.AddError(
"Error configuring API client",
fmt.Sprintf(
"Configuring client: %v. This is an error related to the provider configuration, not to the resource configuration",
err,
),
)
return
}
d.client = apiClient
tflog.Info(ctx, fmt.Sprintf("%s client configured", errorPrefix))
}
func (d *{{.NameCamel}}DataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var data dsModel
// Read Terraform configuration data into the model
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
if resp.Diagnostics.HasError() {
return
}
ctx = core.InitProviderContext(ctx)
projectId := data.ProjectId.ValueString()
region := d.providerData.GetRegionWithOverride(data.Region)
{{.NameCamel}}Id := data.{{.NamePascal}}Id.ValueString()
ctx = tflog.SetField(ctx, "project_id", projectId)
ctx = tflog.SetField(ctx, "region", region)
// TODO: implement needed fields
ctx = tflog.SetField(ctx, "{{.NameCamel}}_id", {{.NameCamel}}Id)
// TODO: refactor to correct implementation
{{.NameCamel}}Resp, err := d.client.Get{{.NamePascal}}Request(ctx, projectId, region, {{.NameCamel}}Id).Execute()
if err != nil {
utils.LogError(
ctx,
&resp.Diagnostics,
err,
"Reading {{.NameCamel}}",
fmt.Sprintf("{{.NameCamel}} with ID %q does not exist in project %q.", {{.NameCamel}}Id, projectId),
map[int]string{
http.StatusForbidden: fmt.Sprintf("Project with ID %q not found or forbidden access", projectId),
},
)
resp.State.RemoveResource(ctx)
return
}
ctx = core.LogResponse(ctx)
data.TfId = utils.BuildInternalTerraformId(projectId, region, ..)
// TODO: fill remaining fields
{{- range .Fields }}
// data.{{.}} = types.Sometype(apiResponse.Get{{.}}())
{{- end -}}
// Save data into Terraform state
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
tflog.Info(ctx, fmt.Sprintf("%s read successful", errorPrefix))
}

View file

@ -0,0 +1,98 @@
package {{.PackageName}}
import (
"context"
"fmt"
"math"
"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/types"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
{{.PackageName}} "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/{{.PackageName}}"
{{.PackageName}}ResGen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/{{.PackageName}}/instance/resources_gen"
)
func mapResponseToModel(
ctx context.Context,
resp *{{.PackageName}}.Get{{.NamePascal}}Response,
m *{{.PackageName}}ResGen.{{.NamePascal}}Model,
tfDiags diag.Diagnostics,
) error {
// TODO: complete and refactor
m.Id = types.StringValue(resp.GetId())
/*
sampleList, diags := types.ListValueFrom(ctx, types.StringType, resp.GetList())
tfDiags.Append(diags...)
if diags.HasError() {
return fmt.Errorf(
"error converting list response value",
)
}
sample, diags := {{.PackageName}}ResGen.NewSampleValue(
{{.PackageName}}ResGen.SampleValue{}.AttributeTypes(ctx),
map[string]attr.Value{
"field": types.StringValue(string(resp.GetField())),
},
)
tfDiags.Append(diags...)
if diags.HasError() {
return fmt.Errorf(
"error converting sample response value",
"sample",
types.StringValue(string(resp.GetField())),
)
}
m.Sample = sample
*/
return nil
}
func handleEncryption(
m *{{.PackageName}}ResGen.{{.NamePascal}}Model,
resp *{{.PackageName}}.Get{{.NamePascal}}Response,
) {{.PackageName}}ResGen.EncryptionValue {
if !resp.HasEncryption() ||
resp.Encryption == nil ||
resp.Encryption.KekKeyId == nil ||
resp.Encryption.KekKeyRingId == nil ||
resp.Encryption.KekKeyVersion == nil ||
resp.Encryption.ServiceAccount == nil {
if m.Encryption.IsNull() || m.Encryption.IsUnknown() {
return {{.PackageName}}ResGen.NewEncryptionValueNull()
}
return m.Encryption
}
enc := {{.PackageName}}ResGen.NewEncryptionValueNull()
if kVal, ok := resp.Encryption.GetKekKeyIdOk(); ok {
enc.KekKeyId = types.StringValue(kVal)
}
if kkVal, ok := resp.Encryption.GetKekKeyRingIdOk(); ok {
enc.KekKeyRingId = types.StringValue(kkVal)
}
if kkvVal, ok := resp.Encryption.GetKekKeyVersionOk(); ok {
enc.KekKeyVersion = types.StringValue(kkvVal)
}
if sa, ok := resp.Encryption.GetServiceAccountOk(); ok {
enc.ServiceAccount = types.StringValue(sa)
}
return enc
}
func toCreatePayload(
ctx context.Context,
model *{{.PackageName}}ResGen.{{.NamePascal}}Model,
) (*{{.PackageName}}.Create{{.NamePascal}}RequestPayload, error) {
if model == nil {
return nil, fmt.Errorf("nil model")
}
return &{{.PackageName}}.Create{{.NamePascal}}RequestPayload{
// TODO: fill fields
}, nil
}

View file

@ -0,0 +1,39 @@
package {{.PackageName}}
import (
"context"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/provider"
"github.com/hashicorp/terraform-plugin-framework/resource"
)
var _ provider.Provider = (*{{.NameCamel}}Provider)(nil)
func New() func() provider.Provider {
return func() provider.Provider {
return &{{.NameCamel}}Provider{}
}
}
type {{.NameCamel}}Provider struct{}
func (p *{{.NameCamel}}Provider) Schema(ctx context.Context, req provider.SchemaRequest, resp *provider.SchemaResponse) {
}
func (p *{{.NameCamel}}Provider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) {
}
func (p *{{.NameCamel}}Provider) Metadata(ctx context.Context, req provider.MetadataRequest, resp *provider.MetadataResponse) {
resp.TypeName = "{{.NameSnake}}"
}
func (p *{{.NameCamel}}Provider) DataSources(ctx context.Context) []func() datasource.DataSource {
return []func() datasource.DataSource{}
}
func (p *{{.NameCamel}}Provider) Resources(ctx context.Context) []func() resource.Resource {
return []func() resource.Resource{}
}

View file

@ -0,0 +1,429 @@
package {{.PackageName}}
import (
"context"
_ "embed"
"fmt"
"strings"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/identityschema"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/stackitcloud/stackit-sdk-go/core/config"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/{{.PackageName}}"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
{{.PackageName}}ResGen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/{{.PackageName}}/{{.NameSnake}}/resources_gen"
)
var (
_ resource.Resource = &{{.NameCamel}}Resource{}
_ resource.ResourceWithConfigure = &{{.NameCamel}}Resource{}
_ resource.ResourceWithImportState = &{{.NameCamel}}Resource{}
_ resource.ResourceWithModifyPlan = &{{.NameCamel}}Resource{}
_ resource.ResourceWithIdentity = &{{.NameCamel}}Resource{}
)
func New{{.NamePascal}}Resource() resource.Resource {
return &{{.NameCamel}}Resource{}
}
type {{.NameCamel}}Resource struct{
client *{{.PackageName}}.APIClient
providerData core.ProviderData
}
// resourceModel represents the Terraform resource state
type resourceModel = {{.PackageName}}.{{.NamePascal}}Model
type {{.NamePascal}}ResourceIdentityModel struct {
ProjectID types.String `tfsdk:"project_id"`
Region types.String `tfsdk:"region"`
// TODO: implement further needed parts
{{.NamePascal}}ID types.String `tfsdk:"{{.NameSnake}}_id"`
}
// Metadata defines terraform resource name
func (r *{{.NameCamel}}Resource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_{{.PackageName}}_{{.NameSnake}}"
}
//go:embed planModifiers.yaml
var modifiersFileByte []byte
// Schema loads the schema from generated files and adds plan modifiers
func (r *{{.NameCamel}}Resource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
schema = {{.PackageName}}ResGen.{{.NamePascal}}ResourceSchema(ctx)
fields, err := {{.PackageName}}Utils.ReadModifiersConfig(modifiersFileByte)
if err != nil {
resp.Diagnostics.AddError("error during read modifiers config file", err.Error())
return
}
err = {{.PackageName}}Utils.AddPlanModifiersToResourceSchema(fields, &schema)
if err != nil {
resp.Diagnostics.AddError("error adding plan modifiers", err.Error())
return
}
resp.Schema = schema
}
// IdentitySchema defines the identity schema
func (r *instanceResource) IdentitySchema(_ context.Context, _ resource.IdentitySchemaRequest, resp *resource.IdentitySchemaResponse) {
resp.IdentitySchema = identityschema.Schema{
Attributes: map[string]identityschema.Attribute{
"project_id": identityschema.StringAttribute{
RequiredForImport: true, // must be set during import by the practitioner
},
"region": identityschema.StringAttribute{
RequiredForImport: true, // can be defaulted by the provider configuration
},
"instance_id": identityschema.StringAttribute{
RequiredForImport: true, // can be defaulted by the provider configuration
},
// TODO: implement remaining schema parts
},
}
}
// Configure adds the provider configured client to the resource.
func (r *{{.NameCamel}}Resource) Configure(
ctx context.Context,
req resource.ConfigureRequest,
resp *resource.ConfigureResponse,
) {
var ok bool
r.providerData, ok = conversion.ParseProviderData(ctx, req.ProviderData, &resp.Diagnostics)
if !ok {
return
}
apiClientConfigOptions := []config.ConfigurationOption{
config.WithCustomAuth(r.providerData.RoundTripper),
utils.UserAgentConfigOption(r.providerData.Version),
}
if r.providerData.{{.PackageNamePascal}}CustomEndpoint != "" {
apiClientConfigOptions = append(apiClientConfigOptions, config.WithEndpoint(r.providerData.{{.PackageName}}CustomEndpoint))
} else {
apiClientConfigOptions = append(apiClientConfigOptions, config.WithRegion(r.providerData.GetRegion()))
}
apiClient, err := {{.PackageName}}.NewAPIClient(apiClientConfigOptions...)
if err != nil {
resp.Diagnostics.AddError(
"Error configuring API client",
fmt.Sprintf(
"Configuring client: %v. This is an error related to the provider configuration, not to the resource configuration",
err,
),
)
return
}
r.client = apiClient
tflog.Info(ctx, "{{.PackageName}}.{{.NamePascal}} client configured")
}
// ModifyPlan implements resource.ResourceWithModifyPlan.
// Use the modifier to set the effective region in the current plan.
func (r *{{.NameCamel}}Resource) ModifyPlan(
ctx context.Context,
req resource.ModifyPlanRequest,
resp *resource.ModifyPlanResponse,
) { // nolint:gocritic // function signature required by Terraform
// skip initial empty configuration to avoid follow-up errors
if req.Config.Raw.IsNull() {
return
}
var configModel {{.PackageName}}ResGen.{{.NamePascal}}Model
resp.Diagnostics.Append(req.Config.Get(ctx, &configModel)...)
if resp.Diagnostics.HasError() {
return
}
if req.Plan.Raw.IsNull() {
return
}
var planModel {{.PackageName}}ResGen.{{.NamePascal}}Model
resp.Diagnostics.Append(req.Plan.Get(ctx, &planModel)...)
if resp.Diagnostics.HasError() {
return
}
utils.AdaptRegion(ctx, configModel.Region, &planModel.Region, r.providerData.GetRegion(), resp)
if resp.Diagnostics.HasError() {
return
}
resp.Diagnostics.Append(resp.Plan.Set(ctx, planModel)...)
if resp.Diagnostics.HasError() {
return
}
}
// Create creates a new resource
func (r *{{.NameCamel}}Resource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
var data {{.PackageName}}ResGen.{{.NamePascal}}Model
// Read Terraform plan data into the model
resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
if resp.Diagnostics.HasError() {
return
}
ctx = core.InitProviderContext(ctx)
projectId := data.ProjectId.ValueString()
region := data.Region.ValueString()
ctx = tflog.SetField(ctx, "project_id", projectId)
ctx = tflog.SetField(ctx, "region", region)
// TODO: add remaining fields
// TODO: Create API call logic
/*
// Generate API request body from model
payload, err := toCreatePayload(ctx, &model)
if err != nil {
core.LogAndAddError(
ctx,
&resp.Diagnostics,
"Error creating {{.NamePascal}}",
fmt.Sprintf("Creating API payload: %v", err),
)
return
}
// Create new {{.NamePascal}}
createResp, err := r.client.Create{{.NamePascal}}Request(
ctx,
projectId,
region,
).Create{{.NamePascal}}RequestPayload(*payload).Execute()
if err != nil {
core.LogAndAddError(ctx, &resp.Diagnostics, "Error creating {{.NamePascal}}", fmt.Sprintf("Calling API: %v", err))
return
}
ctx = core.LogResponse(ctx)
{{.NamePascal}}Id := *createResp.Id
*/
// Example data value setting
data.{{.NameCamel | ucfirst}}Id = types.StringValue("id-from-response")
// TODO: Set data returned by API in identity
identity := {{.NamePascal}}ResourceIdentityModel{
ProjectID: types.StringValue(projectId),
Region: types.StringValue(region),
// TODO: add missing values
{{.NamePascal}}ID: types.StringValue({{.NamePascal}}Id),
}
resp.Diagnostics.Append(resp.Identity.Set(ctx, identity)...)
if resp.Diagnostics.HasError() {
return
}
// TODO: implement wait handler if needed
/*
waitResp, err := wait.Create{{.NamePascal}}WaitHandler(
ctx,
r.client,
projectId,
{{.NamePascal}}Id,
region,
).SetSleepBeforeWait(
30 * time.Second,
).SetTimeout(
90 * time.Minute,
).WaitWithContext(ctx)
if err != nil {
core.LogAndAddError(
ctx,
&resp.Diagnostics,
"Error creating {{.NamePascal}}",
fmt.Sprintf("{{.NamePascal}} creation waiting: %v", err),
)
return
}
if waitResp.Id == nil {
core.LogAndAddError(
ctx,
&resp.Diagnostics,
"Error creating {{.NamePascal}}",
"{{.NamePascal}} creation waiting: returned id is nil",
)
return
}
// Map response body to schema
err = mapResponseToModel(ctx, waitResp, &model, resp.Diagnostics)
if err != nil {
core.LogAndAddError(
ctx,
&resp.Diagnostics,
"Error creating {{.NamePascal}}",
fmt.Sprintf("Processing API payload: %v", err),
)
return
}
*/
// Save data into Terraform state
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
tflog.Info(ctx, "{{.PackageName}}.{{.NamePascal}} created")
}
func (r *{{.NameCamel}}Resource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
var data {{.PackageName}}ResGen.{{.NamePascal}}Model
// Read Terraform prior state data into the model
resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
if resp.Diagnostics.HasError() {
return
}
// Read identity data
var identityData {{.NamePascal}}ResourceIdentityModel
resp.Diagnostics.Append(req.Identity.Get(ctx, &identityData)...)
if resp.Diagnostics.HasError() {
return
}
ctx = core.InitProviderContext(ctx)
projectId := identityData.ProjectID.ValueString()
region := identityData.Region.ValueString()
ctx = tflog.SetField(ctx, "project_id", projectId)
ctx = tflog.SetField(ctx, "region", region)
// TODO: Read API call logic
// Save updated data into Terraform state
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
// TODO: Set data returned by API in identity
identity := {{.NamePascal}}ResourceIdentityModel{
ProjectID: types.StringValue(projectId),
Region: types.StringValue(region),
// InstanceID: types.StringValue(instanceId),
}
resp.Diagnostics.Append(resp.Identity.Set(ctx, identity)...)
if resp.Diagnostics.HasError() {
return
}
tflog.Info(ctx, "{{.PackageName}}.{{.NamePascal}} read")
}
func (r *{{.NameCamel}}Resource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
var data {{.PackageName}}ResGen.{{.NamePascal}}Model
// Read Terraform prior state data into the model
resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
if resp.Diagnostics.HasError() {
return
}
ctx = core.InitProviderContext(ctx)
projectId := data.ProjectId.ValueString()
region := data.Region.ValueString()
ctx = tflog.SetField(ctx, "project_id", projectId)
ctx = tflog.SetField(ctx, "region", region)
// TODO: Update API call logic
// TODO: Set data returned by API in identity
identity := {{.NamePascal}}ResourceIdentityModel{
ProjectID: types.StringValue(projectId),
Region: types.StringValue(region),
// TODO: add missing values
{{.NamePascal}}ID: types.StringValue({{.NamePascal}}Id),
}
resp.Diagnostics.Append(resp.Identity.Set(ctx, identity)...)
if resp.Diagnostics.HasError() {
return
}
// Save updated data into Terraform state
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
tflog.Info(ctx, "{{.PackageName}}.{{.NamePascal}} updated")
}
func (r *{{.NameCamel}}Resource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
var data {{.PackageName}}ResGen.{{.NamePascal}}Model
// Read Terraform prior state data into the model
resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
if resp.Diagnostics.HasError() {
return
}
// Read identity data
var identityData {{.NamePascal}}ResourceIdentityModel
resp.Diagnostics.Append(req.Identity.Get(ctx, &identityData)...)
if resp.Diagnostics.HasError() {
return
}
ctx = core.InitProviderContext(ctx)
projectId := identityData.ProjectID.ValueString()
region := identityData.Region.ValueString()
ctx = tflog.SetField(ctx, "project_id", projectId)
ctx = tflog.SetField(ctx, "region", region)
// TODO: Delete API call logic
tflog.Info(ctx, "{{.PackageName}}.{{.NamePascal}} deleted")
}
// ImportState imports a resource into the Terraform state on success.
// The expected format of the resource import identifier is: project_id,zone_id,record_set_id
func (r *{{.NameCamel}}Resource) ImportState(
ctx context.Context,
req resource.ImportStateRequest,
resp *resource.ImportStateResponse,
) {
idParts := strings.Split(req.ID, core.Separator)
// TODO: Import logic
// TODO: fix len and parts itself
if len(idParts) < 2 || idParts[0] == "" || idParts[1] == "" {
core.LogAndAddError(
ctx, &resp.Diagnostics,
"Error importing database",
fmt.Sprintf(
"Expected import identifier with format [project_id],[region],..., got %q",
req.ID,
),
)
return
}
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("project_id"), idParts[0])...)
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("region"), idParts[1])...)
// ... more ...
core.LogAndAddWarning(
ctx,
&resp.Diagnostics,
"{{.PackageName | ucfirst}} database imported with empty password",
"The database password is not imported as it is only available upon creation of a new database. The password field will be empty.",
)
tflog.Info(ctx, "{{.PackageName | ucfirst}} {{.NameCamel}} state imported")
}

View file

@ -0,0 +1,47 @@
package utils
import (
"context"
"fmt"
{{.PackageName}} "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/{{.PackageName}}"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/stackitcloud/stackit-sdk-go/core/config"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
)
func ConfigureClient(
ctx context.Context,
providerData *core.ProviderData,
diags *diag.Diagnostics,
) *{{.PackageName}}.APIClient {
apiClientConfigOptions := []config.ConfigurationOption{
config.WithCustomAuth(providerData.RoundTripper),
utils.UserAgentConfigOption(providerData.Version),
}
if providerData.{{.PackageName}}CustomEndpoint != "" {
apiClientConfigOptions = append(
apiClientConfigOptions,
config.WithEndpoint(providerData.{{.PackageName}}CustomEndpoint),
)
} else {
apiClientConfigOptions = append(apiClientConfigOptions, config.WithRegion(providerData.GetRegion()))
}
apiClient, err := {{.PackageName}}.NewAPIClient(apiClientConfigOptions...)
if err != nil {
core.LogAndAddError(
ctx,
diags,
"Error configuring API client",
fmt.Sprintf(
"Configuring client: %v. This is an error related to the provider configuration, not to the resource configuration",
err,
),
)
return nil
}
return apiClient
}

View file

@ -0,0 +1,97 @@
package utils
import (
"context"
"os"
"reflect"
"testing"
"github.com/hashicorp/terraform-plugin-framework/diag"
sdkClients "github.com/stackitcloud/stackit-sdk-go/core/clients"
"github.com/stackitcloud/stackit-sdk-go/core/config"
{{.PackageName}} "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/{{.PackageName}}"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
)
const (
testVersion = "1.2.3"
testCustomEndpoint = "https://sqlserverflex-custom-endpoint.api.stackit.cloud"
)
func TestConfigureClient(t *testing.T) {
/* mock authentication by setting service account token env variable */
os.Clearenv()
err := os.Setenv(sdkClients.ServiceAccountToken, "mock-val")
if err != nil {
t.Errorf("error setting env variable: %v", err)
}
type args struct {
providerData *core.ProviderData
}
tests := []struct {
name string
args args
wantErr bool
expected *sqlserverflex.APIClient
}{
{
name: "default endpoint",
args: args{
providerData: &core.ProviderData{
Version: testVersion,
},
},
expected: func() *sqlserverflex.APIClient {
apiClient, err := sqlserverflex.NewAPIClient(
config.WithRegion("eu01"),
utils.UserAgentConfigOption(testVersion),
)
if err != nil {
t.Errorf("error configuring client: %v", err)
}
return apiClient
}(),
wantErr: false,
},
{
name: "custom endpoint",
args: args{
providerData: &core.ProviderData{
Version: testVersion,
SQLServerFlexCustomEndpoint: testCustomEndpoint,
},
},
expected: func() *sqlserverflex.APIClient {
apiClient, err := sqlserverflex.NewAPIClient(
utils.UserAgentConfigOption(testVersion),
config.WithEndpoint(testCustomEndpoint),
)
if err != nil {
t.Errorf("error configuring client: %v", err)
}
return apiClient
}(),
wantErr: false,
},
}
for _, tt := range tests {
t.Run(
tt.name, func(t *testing.T) {
ctx := context.Background()
diags := diag.Diagnostics{}
actual := ConfigureClient(ctx, tt.args.providerData, &diags)
if diags.HasError() != tt.wantErr {
t.Errorf("ConfigureClient() error = %v, want %v", diags.HasError(), tt.wantErr)
}
if !reflect.DeepEqual(actual, tt.expected) {
t.Errorf("ConfigureClient() = %v, want %v", actual, tt.expected)
}
},
)
}
}

43
generator/cmd/buildCmd.go Normal file
View file

@ -0,0 +1,43 @@
package cmd
import (
"github.com/spf13/cobra"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/generator/cmd/build"
)
var (
skipCleanup bool
skipClone bool
packagesOnly bool
verbose bool
debug bool
)
var buildCmd = &cobra.Command{
Use: "build",
Short: "Build the necessary boilerplate",
Long: `...`,
RunE: func(_ *cobra.Command, _ []string) error {
b := build.Builder{
SkipClone: skipClone,
SkipCleanup: skipCleanup,
PackagesOnly: packagesOnly,
Verbose: verbose,
Debug: debug,
}
return b.Build()
},
}
func NewBuildCmd() *cobra.Command {
return buildCmd
}
func init() { //nolint:gochecknoinits // This is the standard way to set up Cobra commands
buildCmd.Flags().BoolVarP(&skipCleanup, "skip-clean", "c", false, "Skip cleanup steps")
buildCmd.Flags().BoolVarP(&debug, "debug", "d", false, "Enable debug output")
buildCmd.Flags().BoolVarP(&skipClone, "skip-clone", "g", false, "Skip cloning from git")
buildCmd.Flags().BoolVarP(&packagesOnly, "packages-only", "p", false, "Only generate packages")
buildCmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "verbose - show more logs")
}

247
generator/cmd/docCmd.go Normal file
View file

@ -0,0 +1,247 @@
package cmd
import (
"fmt"
"log/slog"
"os"
"path"
"regexp"
"sort"
"strings"
"text/template"
"github.com/spf13/cobra"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/generator/cmd/tools"
)
var outFile string
var docsCmd = &cobra.Command{
Use: "docs",
Short: "handle documentation",
Long: `...`,
RunE: func(_ *cobra.Command, _ []string) error {
// filePathStr := "stackit/internal/services/postgresflexalpha/database/datasources_gen/database_data_source_gen.go"
//
// src, err := os.ReadFile(filePathStr)
// if err != nil {
// return err
//}
//
// i := interp.New(
// interp.Options{
// GoPath: "/home/henselinm/.asdf/installs/golang/1.25.6/packages",
// BuildTags: nil,
// Stdin: nil,
// Stdout: nil,
// Stderr: nil,
// Args: nil,
// Env: nil,
// SourcecodeFilesystem: nil,
// Unrestricted: false,
// },
//)
// err = i.Use(i.Symbols("github.com/hashicorp/terraform-plugin-framework-validators"))
// if err != nil {
// return err
//}
// err = i.Use(stdlib.Symbols)
// if err != nil {
// return err
//}
// _, err = i.Eval(string(src))
// if err != nil {
// return err
//}
//
// v, err := i.Eval("DatabaseDataSourceSchema")
// if err != nil {
// return err
//}
//
// bar := v.Interface().(func(string) string)
//
// r := bar("Kung")
// println(r)
//
// evalPath, err := i.EvalPath(filePathStr)
// if err != nil {
// return err
//}
//
// fmt.Printf("%+v\n", evalPath)
// _, err = i.Eval(`import "fmt"`)
// if err != nil {
// return err
//}
// _, err = i.Eval(`func Hallo() { fmt.Println("Hi!") }`)
// if err != nil {
// return err
//}
// v = i.Symbols("Hallo")
// fmt.Println(v)
return workDocs()
},
}
type NavDocs struct {
PageTitle string
Description string
NavigationTitle string
ProviderTitle string
IndexFound bool
Services []Service
}
type Service struct {
ServiceTitle string
DataSources []ResItem
Resources []ResItem
}
type ResItem struct {
ItemName string
ItemLink string
}
func workDocs() error {
slog.Info("creating docs navigation")
root, err := tools.GetGitRoot()
if err != nil {
slog.Error("ERROR", "err", err)
return err
}
nav := NavDocs{
PageTitle: "STACKIT terraform provider PRIVATE-PREVIEW",
Description: "",
NavigationTitle: "Navigation",
ProviderTitle: "Provider",
IndexFound: false,
}
startPath := path.Join(root, "docs")
docs, err := os.ReadDir(startPath)
if err != nil {
return err
}
services := make(map[string]Service)
dataSources := make(map[string][]ResItem)
resources := make(map[string][]ResItem)
for _, entry := range docs {
if !entry.IsDir() {
if entry.Name() == "index.md" {
slog.Debug(" found provider index file")
nav.IndexFound = true
continue
}
slog.Debug(" found am ignored file", "fileName", entry.Name())
continue
}
if entry.Name() != "data-sources" && entry.Name() != "resources" {
slog.Error("unable to handle entry, skipping", "entry", entry.Name())
continue
}
elements, err := os.ReadDir(path.Join(startPath, entry.Name()))
if err != nil {
return err
}
for _, res := range elements {
if res.IsDir() {
slog.Warn("found unexpected directory", "dir", res.Name())
continue
}
re := regexp.MustCompile(`([a-z]+)_([a-z]+).md`)
matches := re.FindAllStringSubmatch(res.Name(), -1)
if matches == nil {
slog.Error("unable to identify resource", "item", res.Name())
continue
}
services[matches[0][1]] = Service{
ServiceTitle: matches[0][1],
}
switch entry.Name() {
case "data-sources":
dataSources[matches[0][1]] = append(dataSources[matches[0][1]], ResItem{
ItemName: matches[0][2],
ItemLink: fmt.Sprintf("docs/%s/%s", entry.Name(), matches[0][0]),
})
case "resources":
resources[matches[0][1]] = append(resources[matches[0][1]], ResItem{
ItemName: matches[0][2],
ItemLink: fmt.Sprintf("docs/%s/%s", entry.Name(), matches[0][0]),
})
default:
return fmt.Errorf("this should never have happened")
}
}
}
keys := make([]string, 0, len(services))
for k := range services {
keys = append(keys, k)
}
sort.Strings(keys)
for _, name := range keys {
item := services[name]
item.DataSources = dataSources[name]
item.Resources = resources[name]
nav.Services = append(nav.Services, item)
}
fn := template.FuncMap{
"ucfirst": ucfirst,
}
tmpl, err := template.
New("nav.md.gompl").
Funcs(fn).
ParseFiles(path.Join(root, "generator", "cmd", "docs", "templates", "nav.md.gompl"))
if err != nil {
return err
}
var f *os.File
f, err = os.Create(outFile)
if err != nil {
return err
}
err = tmpl.Execute(f, nav)
if err != nil {
return err
}
err = f.Close()
if err != nil {
return err
}
slog.Info("finished")
return nil
}
func NewDocsCmd() *cobra.Command {
return docsCmd
}
func ucfirst(s string) string {
if s == "" {
return ""
}
return strings.ToUpper(s[:1]) + s[1:]
}
func init() { // nolint: gochecknoinits
docsCmd.Flags().StringVarP(&outFile, "outFile", "o", "nav.md", "nav.md")
}

View file

@ -0,0 +1,27 @@
---
page_title: {{ .PageTitle }}
description: {{ .Description }}
---
## {{ .NavigationTitle }}
### {{ .ProviderTitle }}
{{ if .IndexFound }}
[Provider](/docs/docs/index.md)
{{ end }}
{{- range $index, $service := .Services }}
### {{ $service.ServiceTitle }}
<details>
#### data sources
{{- range $service.DataSources }}
- [{{ .ItemName }}]({{ .ItemLink }})
{{- end }}
#### resources
{{- range $service.Resources }}
- [{{ .ItemName }}]({{ .ItemLink }})
{{- end }}
</details>
{{ end }}

View file

@ -0,0 +1,114 @@
package cmd
import (
"fmt"
"os"
"path"
"github.com/spf13/cobra"
)
var examplesCmd = &cobra.Command{
Use: "examples",
Short: "create examples",
Long: `...`,
RunE: func(_ *cobra.Command, _ []string) error {
// filePathStr := "stackit/internal/services/postgresflexalpha/database/datasources_gen/database_data_source_gen.go"
//
// src, err := os.ReadFile(filePathStr)
// if err != nil {
// return err
//}
//
// i := interp.New(
// interp.Options{
// GoPath: "/home/henselinm/.asdf/installs/golang/1.25.6/packages",
// BuildTags: nil,
// Stdin: nil,
// Stdout: nil,
// Stderr: nil,
// Args: nil,
// Env: nil,
// SourcecodeFilesystem: nil,
// Unrestricted: false,
// },
//)
// err = i.Use(i.Symbols("github.com/hashicorp/terraform-plugin-framework-validators"))
// if err != nil {
// return err
//}
// err = i.Use(stdlib.Symbols)
// if err != nil {
// return err
//}
// _, err = i.Eval(string(src))
// if err != nil {
// return err
//}
//
// v, err := i.Eval("DatabaseDataSourceSchema")
// if err != nil {
// return err
//}
//
// bar := v.Interface().(func(string) string)
//
// r := bar("Kung")
// println(r)
//
// evalPath, err := i.EvalPath(filePathStr)
// if err != nil {
// return err
//}
//
// fmt.Printf("%+v\n", evalPath)
// _, err = i.Eval(`import "fmt"`)
// if err != nil {
// return err
//}
// _, err = i.Eval(`func Hallo() { fmt.Println("Hi!") }`)
// if err != nil {
// return err
//}
// v = i.Symbols("Hallo")
// fmt.Println(v)
return workServices()
},
}
func workServices() error {
startPath := path.Join("stackit", "internal", "services")
services, err := os.ReadDir(startPath)
if err != nil {
return err
}
for _, entry := range services {
if !entry.IsDir() {
continue
}
resources, err := os.ReadDir(path.Join(startPath, entry.Name()))
if err != nil {
return err
}
for _, res := range resources {
if !res.IsDir() {
continue
}
fmt.Println("Gefunden:", startPath, "subdir", entry.Name(), "resource", res.Name())
}
}
return nil
}
func NewExamplesCmd() *cobra.Command {
return examplesCmd
}
// func init() { // nolint: gochecknoinits
// examplesCmd.Flags().BoolVarP(&example, "example", "e", false, "example")
//}

View file

@ -0,0 +1,148 @@
package cmd
import (
"fmt"
"go/ast"
"go/parser"
"go/token"
"path"
"path/filepath"
"strings"
"github.com/spf13/cobra"
)
var (
inFile string
svcName string
resName string
resType string
filePath string
)
var getFieldsCmd = &cobra.Command{
Use: "get-fields",
Short: "get fields from file",
Long: `...`,
PreRunE: func(_ *cobra.Command, _ []string) error {
typeStr := "data_source"
if resType != "resource" && resType != "datasource" {
return fmt.Errorf("--type can only be resource or datasource")
}
if resType == "resource" {
typeStr = resType
}
if inFile == "" && svcName == "" && resName == "" {
return fmt.Errorf("--infile or --service and --resource must be provided")
}
if inFile != "" {
if svcName != "" || resName != "" {
return fmt.Errorf("--infile is provided and excludes --service and --resource")
}
p, err := filepath.Abs(inFile)
if err != nil {
return err
}
filePath = p
return nil
}
if svcName != "" && resName == "" {
return fmt.Errorf("if --service is provided, you MUST also provide --resource")
}
if svcName == "" && resName != "" {
return fmt.Errorf("if --resource is provided, you MUST also provide --service")
}
p, err := filepath.Abs(
path.Join(
"stackit",
"internal",
"services",
svcName,
resName,
fmt.Sprintf("%ss_gen", resType),
fmt.Sprintf("%s_%s_gen.go", resName, typeStr),
),
)
if err != nil {
return err
}
filePath = p
//// Enum check
// switch format {
// case "json", "yaml":
//default:
// return fmt.Errorf("invalid --format: %s (want json|yaml)", format)
//}
return nil
},
RunE: func(_ *cobra.Command, _ []string) error {
return getFields(filePath)
},
}
func getFields(f string) error {
tokens, err := getTokens(f)
if err != nil {
return err
}
for _, item := range tokens {
fmt.Printf("%s \n", item)
}
return nil
}
func getTokens(fileName string) ([]string, error) {
fset := token.NewFileSet()
var result []string
node, err := parser.ParseFile(fset, fileName, nil, parser.ParseComments)
if err != nil {
return nil, err
}
ast.Inspect(
node, func(n ast.Node) bool {
// Suche nach Typ-Deklarationen (structs)
ts, ok := n.(*ast.TypeSpec)
if ok {
if strings.Contains(ts.Name.Name, "Model") {
ast.Inspect(
ts, func(sn ast.Node) bool {
tts, tok := sn.(*ast.Field)
if tok {
result = append(result, tts.Names[0].String())
}
return true
},
)
}
}
return true
},
)
return result, nil
}
func NewGetFieldsCmd() *cobra.Command {
return getFieldsCmd
}
func init() { //nolint:gochecknoinits //this is the only way to add the command to the rootCmd
getFieldsCmd.Flags().StringVarP(&inFile, "infile", "i", "", "input filename incl path")
getFieldsCmd.Flags().StringVarP(&svcName, "service", "s", "", "service name")
getFieldsCmd.Flags().StringVarP(&resName, "resource", "r", "", "resource name")
getFieldsCmd.Flags().StringVarP(
&resType,
"type",
"t",
"resource",
"resource type (data-source or resource [default])",
)
}

View file

@ -0,0 +1,137 @@
package publish
import (
"encoding/json"
"fmt"
"log"
"net/url"
"os"
"path"
"strings"
)
type Architecture struct {
Protocols []string `json:"protocols"`
OS string `json:"os"`
Arch string `json:"arch"`
FileName string `json:"filename"`
DownloadUrl string `json:"download_url"`
ShaSumsUrl string `json:"shasums_url"`
ShaSumsSignatureUrl string `json:"shasums_signature_url"`
ShaSum string `json:"shasum"`
SigningKeys SigningKey `json:"signing_keys"`
}
type SigningKey struct {
GpgPublicKeys []GpgPublicKey `json:"gpg_public_keys"`
}
type GpgPublicKey struct {
KeyId string `json:"key_id"`
AsciiArmor string `json:"ascii_armor"`
TrustSignature string `json:"trust_signature"`
Source string `json:"source"`
SourceUrl string `json:"source_url"`
}
func (p *Provider) CreateArchitectureFiles() error {
log.Println("* Creating architecture files in target directories")
prefix := path.Join("v1", "providers", p.Namespace, p.Provider, p.Version)
pathPrefix := path.Join("release", prefix)
urlPrefix, err := url.JoinPath("https://", p.Domain, prefix)
if err != nil {
return fmt.Errorf("error creating base url: %w", err)
}
downloadUrlPrefix, err := url.JoinPath(urlPrefix, "download")
if err != nil {
return fmt.Errorf("error crearting download url: %w", err)
}
downloadPathPrefix := path.Join(pathPrefix, "download")
shasumsUrl, err := url.JoinPath(urlPrefix, fmt.Sprintf("%s_%s_SHA256SUMS", p.RepoName, p.Version))
if err != nil {
return fmt.Errorf("error creating shasums url: %w", err)
}
shasumsSigUrl := shasumsUrl + ".sig"
gpgAsciiPub, err := p.ReadGpgFile()
if err != nil {
return err
}
shaSums, err := p.GetShaSums()
if err != nil {
return err
}
for _, sum := range shaSums {
downloadUrl, err := url.JoinPath(downloadUrlPrefix, sum.Path)
if err != nil {
return fmt.Errorf("error creating url: %w", err)
}
// get os and arch from filename
removeFileExtension := strings.Split(sum.Path, ".zip")
fileNameSplit := strings.Split(removeFileExtension[0], "_")
// Get build target and architecture from the zip file name
target := fileNameSplit[2]
arch := fileNameSplit[3]
// build filepath
archFileName := path.Join(downloadPathPrefix, target, arch)
a := Architecture{
Protocols: []string{"5.1", "6.0"},
OS: target,
Arch: arch,
FileName: sum.Path,
DownloadUrl: downloadUrl,
ShaSumsUrl: shasumsUrl,
ShaSumsSignatureUrl: shasumsSigUrl,
ShaSum: sum.Sum,
SigningKeys: SigningKey{},
}
a.SigningKeys = SigningKey{
GpgPublicKeys: []GpgPublicKey{
{
KeyId: p.GpgFingerprint,
AsciiArmor: gpgAsciiPub,
TrustSignature: "",
Source: "",
SourceUrl: "",
},
},
}
log.Printf(" - Arch file: %s", archFileName)
err = WriteArchitectureFile(archFileName, a)
if err != nil {
return err
}
}
return nil
}
func WriteArchitectureFile(filePath string, arch Architecture) error {
jsonString, err := json.Marshal(arch)
if err != nil {
return fmt.Errorf("error encoding data: %w", err)
}
//nolint:gosec // this file is not sensitive, so we can use os.ModePerm
err = os.WriteFile(
filePath,
jsonString,
os.ModePerm,
)
if err != nil {
return fmt.Errorf("error writing data: %w", err)
}
return nil
}

View file

@ -0,0 +1,14 @@
package publish
import (
"fmt"
"strings"
)
func (p *Provider) ReadGpgFile() (string, error) {
gpgFile, err := ReadFile(p.GpgPubKeyFile)
if err != nil {
return "", fmt.Errorf("error reading '%s' file: %w", p.GpgPubKeyFile, err)
}
return strings.Join(gpgFile, "\n"), nil
}

View file

@ -0,0 +1,297 @@
package publish
import (
"bufio"
"errors"
"fmt"
"io"
"io/fs"
"log"
"log/slog"
"os"
"os/exec"
"path"
"strings"
)
type Provider struct {
RootPath string
Namespace string
Provider string
DistPath string
RepoName string
Version string
GpgFingerprint string
GpgPubKeyFile string
Domain string
}
func (p *Provider) GetRoot() error {
cmd := exec.Command("git", "rev-parse", "--show-toplevel")
out, err := cmd.Output()
if err != nil {
return err
}
lines := strings.Split(string(out), "\n")
p.RootPath = lines[0]
return nil
}
func (p *Provider) CreateV1Dir() error {
// Path to semantic version dir
versionPath := p.providerDirs()
// Files to create under v1/providers/[namespace]/[provider_name]
err := p.createVersionsFile()
if err != nil {
return fmt.Errorf("[CreateV1Dir] - create versions file:%w", err)
} // Creates version file one above download, which is why downloadPath isn't used
// Files/Directories to create under v1/providers/[namespace]/[provider_name]/[version]
err = p.copyShaFiles(versionPath)
if err != nil {
return fmt.Errorf("[CreateV1Dir] - copy sha files: %w", err)
}
log.Printf("* Creating download/ in %s directory", versionPath)
downloadsPath := path.Join(versionPath, "download")
err = CreateDir(downloadsPath)
if err != nil {
return err
}
// Create darwin, freebsd, linux, windows dirs
for _, v := range [4]string{"darwin", "freebsd", "linux", "windows"} {
err = CreateDir(path.Join(downloadsPath, v))
if err != nil {
return fmt.Errorf("error creating dir '%s': %w", path.Join(downloadsPath, v), err)
}
}
// Copy all zips
err = p.copyBuildZips(downloadsPath)
if err != nil {
return err
}
// Create all individual files for build targets and each architecture for the build targets
err = p.CreateArchitectureFiles()
if err != nil {
return err
}
return nil
}
func (p *Provider) copyBuildZips(destPath string) error {
log.Println("* Copying build zips")
shaSums, err := p.GetShaSums()
if err != nil {
return err
}
// Loop through and copy each
for _, sum := range shaSums {
zipSrcPath := path.Join(p.DistPath, sum.Path)
zipDestPath := path.Join(destPath, sum.Path)
log.Printf(" - Zip Source: %s", zipSrcPath)
log.Printf(" - Zip Dest: %s", zipDestPath)
// Copy the zip
_, err = CopyFile(zipSrcPath, zipDestPath)
if err != nil {
return fmt.Errorf("error copying file '%s': %w", zipSrcPath, err)
}
}
return nil
}
func (p *Provider) copyShaFiles(destPath string) error {
log.Printf("* Copying SHA files in %s directory", p.DistPath)
// Copy files from srcPath
shaSum := p.RepoName + "_" + p.Version + "_SHA256SUMS"
shaSumPath := path.Join(p.DistPath, shaSum)
// _SHA256SUMS file
_, err := CopyFile(shaSumPath, path.Join(destPath, shaSum))
if err != nil {
return err
}
// _SHA256SUMS.sig file
_, err = CopyFile(shaSumPath+".sig", path.Join(destPath, shaSum+".sig"))
if err != nil {
return err
}
return nil
}
func (p *Provider) createVersionsFile() error {
log.Println("* Writing to release/v1/providers/[namespace]/[repo]/versions file")
versionPath := path.Join("release", "v1", "providers", p.Namespace, p.Provider, "versions")
shasums, err := p.GetShaSums()
if err != nil {
return fmt.Errorf("error getting sha sums: %w", err)
}
// Build the versions file...
version := Version{
Version: p.Version,
Protocols: []string{"5.1", "6.1"},
Platforms: nil,
}
for _, sum := range shasums {
// get os and arch from filename
removeFileExtension := strings.Split(sum.Path, ".zip")
if len(removeFileExtension) < 1 {
log.Fatalf("error: %s does not have .zip extension", sum.Path)
}
fileNameSplit := strings.Split(removeFileExtension[0], "_")
if len(fileNameSplit) < 4 {
log.Fatalf("filename does not match our regex: %s", removeFileExtension[0])
}
// Get build target and architecture from the zip file name
target := fileNameSplit[2]
arch := fileNameSplit[3]
version.Platforms = append(
version.Platforms, Platform{
OS: target,
Arch: arch,
},
)
}
data := Data{}
downloadPath := path.Join(p.Domain, "v1", "providers", p.Namespace, p.Provider, "versions")
err = data.LoadFromUrl(fmt.Sprintf("https://%s", downloadPath))
if err != nil {
slog.Warn("error getting existing versions file, start with empty")
// TODO: create flag for first use or make it more robust
// return fmt.Errorf("error getting existing versions file: %w", err)
}
err = data.AddVersion(version)
if err != nil {
return fmt.Errorf("error appending version: %w", err)
}
err = data.WriteToFile(versionPath)
if err != nil {
return fmt.Errorf("error saving file '%s':%w", versionPath, err)
}
return nil
}
func (p *Provider) providerDirs() string {
log.Println("* Creating release/v1/providers/[namespace]/[provider]/[version] directories")
target := path.Join("release", "v1", "providers", p.Namespace, p.Provider, p.Version)
err := CreateDir(target)
if err != nil {
return ""
}
return target
}
func (p *Provider) CreateWellKnown() error {
log.Println("* Creating .well-known directory")
pathString := path.Join(p.RootPath, "release", ".well-known")
//nolint:gosec // this file is not sensitive, so we can use ModePerm
err := os.MkdirAll(pathString, os.ModePerm)
if err != nil && !errors.Is(err, fs.ErrExist) {
return fmt.Errorf("error creating '%s' dir: %w", pathString, err)
}
log.Println(" - Writing to .well-known/terraform.json file")
//nolint:gosec // this file is not sensitive, so we can use 0644
err = os.WriteFile(
fmt.Sprintf("%s/terraform.json", pathString),
[]byte(`{"providers.v1": "/v1/providers/"}`),
0o644,
)
if err != nil {
return err
}
return nil
}
func CreateDir(pathValue string) error {
log.Printf("* Creating %s directory", pathValue)
//nolint:gosec // this file is not sensitive, so we can use ModePerm
err := os.MkdirAll(pathValue, os.ModePerm)
if errors.Is(err, fs.ErrExist) {
return nil
}
return err
}
func ReadFile(filePath string) ([]string, error) {
rFile, err := os.Open(filePath)
if err != nil {
return nil, err
}
fileScanner := bufio.NewScanner(rFile)
fileScanner.Split(bufio.ScanLines)
var fileLines []string
for fileScanner.Scan() {
fileLines = append(fileLines, fileScanner.Text())
}
err = rFile.Close()
if err != nil {
return nil, err
}
return fileLines, nil
}
func CopyFile(src, dst string) (int64, error) {
sourceFileStat, err := os.Stat(src)
if err != nil {
return 0, err
}
if !sourceFileStat.Mode().IsRegular() {
return 0, fmt.Errorf("%s is not a regular file", src)
}
source, err := os.Open(src)
if err != nil {
return 0, err
}
defer func(source *os.File) {
err := source.Close()
if err != nil {
slog.Error("error closing source file", slog.Any("err", err))
}
}(source)
destination, err := os.Create(dst)
if err != nil {
return 0, err
}
defer func(destination *os.File) {
err := destination.Close()
if err != nil {
slog.Error("error closing destination file", slog.Any("err", err))
}
}(destination)
nBytes, err := io.Copy(destination, source)
return nBytes, err
}

View file

@ -0,0 +1,39 @@
package publish
import (
"log/slog"
"path"
"regexp"
)
func (p *Provider) GetShaSums() (ShaSums, error) {
return GetShaSumContents(p.DistPath, p.RepoName, p.Version)
}
type ShaSums []ShaSum
type ShaSum struct {
Sum string
Path string
}
func GetShaSumContents(distPath, repoName, version string) (ShaSums, error) {
shaSumFileName := repoName + "_" + version + "_SHA256SUMS"
shaSumPath := path.Join(distPath, shaSumFileName)
shaSumLine, err := ReadFile(shaSumPath)
if err != nil {
return nil, err
}
regEx := regexp.MustCompile(`([0-9a-fA-F]+)\s+(.+)`)
shaSums := ShaSums{}
for _, line := range shaSumLine {
matches := regEx.FindAllStringSubmatch(line, -1)
if len(matches) < 1 {
slog.Warn("unable to parse SHA sum line", "line", line)
continue
}
shaSums = append(shaSums, ShaSum{Sum: matches[0][1], Path: matches[0][2]})
}
return shaSums, nil
}

View file

@ -0,0 +1,38 @@
{
log {
level debug
}
filesystem tf s3 {
bucket "terraform-provider-privatepreview"
region eu01
endpoint https://object.storage.eu01.onstackit.cloud
use_path_style
}
}
tfregistry.sysops.stackit.rocks {
encode zstd gzip
handle_path /docs/* {
root /srv/www
templates
@md {
file {path}
path *.md
}
rewrite @md /markdown.html
file_server {
browse
}
}
file_server {
fs tf
browse
}
}

View file

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="de">
<head>
<title>Forwarding | Weiterleitung</title>
<meta http-equiv="refresh" content="0; URL=index.md">
</head>
<body>
<a href="index.md">Falls Sie nicht automatisch weitergeleitet werden, klicken Sie bitte hier.</a><br />
Sie gelangen dann auf unsere Hauptseite
</body>
</html>

View file

@ -0,0 +1,34 @@
---
page_title: STACKIT provider PrivatePreview
description: none
---
# provider
[Provider](docs/index.md)
## PostGreSQL alpha
### data sources
- [Flavor](docs/data-sources/postgresflexalpha_flavor.md)
- [Database](docs/data-sources/postgresflexalpha_database.md)
- [Instance](docs/data-sources/postgresflexalpha_instance.md)
- [Flavors](docs/data-sources/postgresflexalpha_flavors.md)
- [User](docs/data-sources/postgresflexalpha_user.md)
### resources
- [Database](docs/resources/postgresflexalpha_database.md)
- [Instance](docs/resources/postgresflexalpha_instance.md)
- [User](docs/resources/postgresflexalpha_user.md)
## SQL Server alpha
### data sources
- [Database](docs/data-sources/sqlserverflexalpha_database.md)
- [Version](docs/data-sources/sqlserverflexalpha_version.md)
- [User](docs/data-sources/sqlserverflexalpha_user.md)
- [Flavor](docs/data-sources/sqlserverflexalpha_flavor.md)
- [Instance](docs/data-sources/sqlserverflexalpha_instance.md)
### resources
- [Database](docs/resources/sqlserverflexalpha_database.md)
- [User](docs/resources/sqlserverflexalpha_user.md)
- [Instance](docs/resources/sqlserverflexalpha_instance.md)

View file

@ -0,0 +1,79 @@
<!DOCTYPE html>
{{ $mdFile := .OriginalReq.URL.Path | trimPrefix "/docs" }}
{{ $md := (include $mdFile | splitFrontMatter) }}
<html lang="en">
<head>
<title>{{$md.Meta.page_title}}</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="/docs/terraform-registry.css">
</head>
<body>
<h1>{{$md.Meta.page_title}}</h1>
<div class="provider-view">
<div class="provider-nav">
<nav class="bread-crumbs is-light" aria-label="Provider">
<div class="container is-widescreen">
<div class="level">
<ul class="provider-nav-breadcrumbs bread-crumbs-list">
<li class="bread-crumbs-item">
<a id="ember20" class="ember-view bread-crumbs-link" href="/">
Main
</a>
</li>
</ul>
</div>
</div>
</nav>
<nav class="block-border section-navbar section-header" aria-label="Provider details">
<div class="container">
<div class="columns is-vcentered">
<div class="column is-4">
<div class="provider-nav-info-header">
<div class="provider-overview-logo">
<span class="provider-logo">
<img class="github-image" src="https://avatars3.githubusercontent.com/stackitcloud" alt="stackitcloud">
</span>
</div>
<div class="provider-nav-info-origin">
<h1>PRIVATE PREVIEW</h1>
</div>
</div>
</div>
<div class="column is-8">
<ul class="nav-tabs-list nav-tabs tabs">
<li class="nav-tabs-item">
<a id="ember30" class="ember-view navbar-item" href="/">
Overview
</a>
</li>
</ul>
<div class="provider-nav-provision-wrapper">
<!----> </div>
</div>
</div>
</div>
</nav>
</div>
<div class="section block-border block-white section-content">
<div class="container">
<div class="columns columns-provider-docs">
<div class="column is-3 column-provider-docs-menu"></div>
<article id="provider-docs-content" class="column is-6 provider-docs-content">
<div class="markdown">
<div class="highlighted-code-wrapper">
{{markdown $md.Body}}
</div>
</div>
</article>
<div class="column is-3 column-provider-docs-menu"></div>
</div>
</div>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,169 @@
package publish
import (
"encoding/json"
"fmt"
"io"
"log/slog"
"net/http"
"net/url"
"os"
)
type Version struct {
Version string `json:"version"`
Protocols []string `json:"protocols"`
Platforms []Platform `json:"platforms"`
}
type Platform struct {
OS string `json:"os" yaml:"os"`
Arch string `json:"arch" yaml:"arch"`
}
type Data struct {
Id string `json:"id,omitempty"`
Versions []Version `json:"versions"`
}
func (d *Data) WriteToFile(filePath string) error {
// TODO: make it variable
d.Id = "tfregistry.sysops.stackit.rocks/mhenselin/stackitprivatepreview"
jsonString, err := json.Marshal(d)
if err != nil {
return fmt.Errorf("error encoding data: %w", err)
}
//nolint:gosec // this file is not sensitive, so we can use os.ModePerm
err = os.WriteFile(
filePath,
jsonString,
os.ModePerm,
)
if err != nil {
return fmt.Errorf("error writing data: %w", err)
}
return nil
}
func (d *Data) AddVersion(v Version) error {
var newVersions []Version
for _, ver := range d.Versions {
if ver.Version != v.Version {
newVersions = append(newVersions, ver)
}
}
newVersions = append(newVersions, v)
d.Versions = newVersions
return nil
}
func (d *Data) Validate() error {
for _, v := range d.Versions {
err := v.Validate()
if err != nil {
return err
}
}
return nil
}
func (d *Data) LoadFromFile(filePath string) error {
plan, err := os.ReadFile(filePath)
if err != nil {
return err
}
err = json.Unmarshal(plan, &d)
if err != nil {
return err
}
return nil
}
func (d *Data) LoadFromUrl(uri string) error {
u, err := url.ParseRequestURI(uri)
if err != nil {
return err
}
file, err := os.CreateTemp("", "versions.*.json")
if err != nil {
return err
}
defer func(name string) {
//nolint:gosec // The file path is generated by os.CreateTemp and is not user-controllable
err := os.Remove(name)
if err != nil {
slog.Error("failed to remove temporary file", slog.Any("err", err))
}
}(file.Name()) // Clean up
err = DownloadFile(
u.String(),
file.Name(),
)
if err != nil {
return err
}
return d.LoadFromFile(file.Name())
}
func (v *Version) Validate() error {
slog.Warn("validation needs to be implemented")
return nil
}
func (v *Version) AddPlatform(p Platform) error {
if p.OS == "" || p.Arch == "" {
return fmt.Errorf("OS and Arch MUST NOT be empty")
}
v.Platforms = append(v.Platforms, p)
return nil
}
func (v *Version) AddProtocol(p string) error {
if p == "" {
return fmt.Errorf("protocol MUST NOT be empty")
}
v.Protocols = append(v.Protocols, p)
return nil
}
// DownloadFile will download a url and store it in local filepath.
// It writes to the destination file as it downloads it, without
// loading the entire file into memory.
func DownloadFile(urlValue, filepath string) error {
// Create the file
//nolint:gosec // path traversal is not a concern here, as the filepath is generated by us and not user input
out, err := os.Create(filepath)
if err != nil {
return err
}
defer func(out *os.File) {
err := out.Close()
if err != nil {
slog.Error("failed to close file", slog.Any("err", err))
}
}(out)
// Get the data
//nolint:gosec,bodyclose // this is a controlled URL, not user input
resp, err := http.Get(urlValue)
if err != nil {
return err
}
defer func(Body io.ReadCloser) {
_ = Body.Close()
}(resp.Body)
// Write the body to file
_, err = io.Copy(out, resp.Body)
if err != nil {
return err
}
return nil
}

139
generator/cmd/publishCmd.go Normal file
View file

@ -0,0 +1,139 @@
package cmd
import (
"errors"
"fmt"
"io/fs"
"log"
"os"
"path"
"path/filepath"
"github.com/spf13/cobra"
publish2 "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/generator/cmd/publish"
)
var (
namespace string
domain string
providerName string
distPath string
repoName string
version string
gpgFingerprint string
gpgPubKeyFile string
)
var publishCmd = &cobra.Command{
Use: "publish",
Short: "Publish terraform provider",
Long: `...`,
RunE: func(_ *cobra.Command, _ []string) error {
return publish()
},
}
func init() { //nolint:gochecknoinits //this is the standard way to set up cobra commands
publishCmd.Flags().StringVarP(&namespace, "namespace", "n", "", "Namespace for the Terraform registry.")
publishCmd.Flags().StringVarP(&domain, "domain", "d", "", "Domain for the Terraform registry.")
publishCmd.Flags().StringVarP(&providerName, "providerName", "p", "", "ProviderName for the Terraform registry.")
publishCmd.Flags().StringVarP(&distPath, "distPath", "x", "dist", "Dist Path for the Terraform registry.")
publishCmd.Flags().StringVarP(&repoName, "repoName", "r", "", "RepoName for the Terraform registry.")
publishCmd.Flags().StringVarP(&version, "version", "v", "", "Version for the Terraform registry.")
publishCmd.Flags().StringVarP(
&gpgFingerprint,
"gpgFingerprint",
"f",
"",
"GPG Fingerprint for the Terraform registry.",
)
publishCmd.Flags().StringVarP(
&gpgPubKeyFile,
"gpgPubKeyFile",
"k",
"",
"GPG PubKey file name for the Terraform registry.",
)
err := publishCmd.MarkFlagRequired("namespace")
if err != nil {
return
}
err = publishCmd.MarkFlagRequired("domain")
if err != nil {
return
}
err = publishCmd.MarkFlagRequired("providerName")
if err != nil {
return
}
err = publishCmd.MarkFlagRequired("gpgFingerprint")
if err != nil {
return
}
err = publishCmd.MarkFlagRequired("gpgPubKeyFile")
if err != nil {
return
}
err = publishCmd.MarkFlagRequired("repoName")
if err != nil {
return
}
err = publishCmd.MarkFlagRequired("version")
if err != nil {
return
}
err = publishCmd.MarkFlagRequired("gpgFingerprint")
if err != nil {
return
}
err = publishCmd.MarkFlagRequired("gpgPubKeyFile")
if err != nil {
return
}
}
func NewPublishCmd() *cobra.Command {
return publishCmd
}
func publish() error {
log.Println("📦 Packaging Terraform Provider for private registry...")
p := publish2.Provider{
Namespace: namespace,
Provider: providerName,
DistPath: filepath.Clean(distPath) + "/",
RepoName: repoName,
Version: version,
GpgFingerprint: gpgFingerprint,
GpgPubKeyFile: gpgPubKeyFile,
Domain: domain,
}
err := p.GetRoot()
if err != nil {
return err
}
// Create release dir - only the contents of this need to be uploaded to S3
log.Printf("* Creating release directory")
//nolint:gosec // this directory is not sensitive, so we can use 0750
err = os.MkdirAll(path.Join(p.RootPath, "release"), os.ModePerm)
if err != nil && !errors.Is(err, fs.ErrExist) {
return fmt.Errorf("error creating '%s' dir: %w", path.Join(p.RootPath, "release"), err)
}
// Create .wellKnown directory and terraform.json file
err = p.CreateWellKnown()
if err != nil {
return fmt.Errorf("error creating '.well-known' dir: %w", err)
}
err = p.CreateV1Dir()
if err != nil {
return fmt.Errorf("error creating 'v1' dir: %w", err)
}
log.Println("📦 Packaged Terraform Provider for private registry.")
return nil
}

23
generator/cmd/rootCmd.go Normal file
View file

@ -0,0 +1,23 @@
package cmd
import (
"github.com/spf13/cobra"
)
func NewRootCmd() *cobra.Command {
return &cobra.Command{
Use: "generator",
Short: "...",
Long: "...",
SilenceErrors: true, // Error is beautified in a custom way before being printed
SilenceUsage: true,
DisableAutoGenTag: true,
RunE: func(cmd *cobra.Command, _ []string) error {
err := cmd.Help()
if err != nil {
return err
}
return nil
},
}
}

View file

@ -0,0 +1,20 @@
package tools
import (
"fmt"
"os/exec"
"strings"
)
func GetGitRoot() (string, error) {
cmd := exec.Command("git", "rev-parse", "--show-toplevel")
out, err := cmd.Output()
if err != nil {
return "", err
}
lines := strings.Split(string(out), "\n")
if lines[0] == "" {
return "", fmt.Errorf("unable to determine root directory from git")
}
return lines[0], nil
}

41
generator/main.go Normal file
View file

@ -0,0 +1,41 @@
package main
import (
"log"
"log/slog"
"os"
"github.com/SladkyCitron/slogcolor"
cc "github.com/ivanpirog/coloredcobra"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/generator/cmd"
)
func main() {
slog.SetDefault(slog.New(slogcolor.NewHandler(os.Stderr, slogcolor.DefaultOptions)))
rootCmd := cmd.NewRootCmd()
cc.Init(&cc.Config{
RootCmd: rootCmd,
Headings: cc.HiCyan + cc.Bold + cc.Underline,
Commands: cc.HiYellow + cc.Bold,
Example: cc.Italic,
ExecName: cc.Bold,
Flags: cc.Bold,
})
rootCmd.SetOut(os.Stdout)
rootCmd.AddCommand(
cmd.NewBuildCmd(),
cmd.NewPublishCmd(),
cmd.NewGetFieldsCmd(),
cmd.NewExamplesCmd(),
cmd.NewDocsCmd(),
)
err := rootCmd.Execute()
if err != nil {
log.Fatal(err)
}
}

271
go.mod
View file

@ -1,75 +1,288 @@
module github.com/mhenselin/terraform-provider-stackitprivatepreview
module tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview
go 1.25.5
go 1.25.6
require (
github.com/SladkyCitron/slogcolor v1.8.0
github.com/golang-jwt/jwt/v5 v5.3.1
github.com/google/go-cmp v0.7.0
github.com/google/uuid v1.6.0
github.com/hashicorp/terraform-plugin-framework v1.17.0
github.com/hashicorp/terraform-plugin-framework v1.18.0
github.com/hashicorp/terraform-plugin-framework-validators v0.19.0
github.com/hashicorp/terraform-plugin-go v0.29.0
github.com/hashicorp/terraform-plugin-go v0.30.0
github.com/hashicorp/terraform-plugin-log v0.10.0
github.com/hashicorp/terraform-plugin-testing v1.14.0
github.com/stackitcloud/stackit-sdk-go/core v0.20.1
github.com/stackitcloud/stackit-sdk-go/services/sqlserverflex v1.4.0
github.com/iancoleman/strcase v0.3.0
github.com/ivanpirog/coloredcobra v1.0.1
github.com/jarcoal/httpmock v1.4.1
github.com/joho/godotenv v1.5.1
github.com/ldez/go-git-cmd-wrapper/v2 v2.9.1
github.com/spf13/cobra v1.10.2
github.com/stackitcloud/stackit-sdk-go/core v0.22.0
github.com/stackitcloud/stackit-sdk-go/services/postgresflex v1.4.0
github.com/stackitcloud/stackit-sdk-go/services/sqlserverflex v1.5.0
github.com/teambition/rrule-go v1.8.2
gopkg.in/yaml.v3 v3.0.1
)
require (
github.com/hashicorp/go-retryablehttp v0.7.8 // indirect
github.com/kr/text v0.2.0 // indirect
golang.org/x/telemetry v0.0.0-20260109210033-bd525da824e2 // indirect
)
require github.com/hashicorp/go-retryablehttp v0.7.8 // indirect
require (
github.com/ProtonMail/go-crypto v1.3.0 // indirect
4d63.com/gocheckcompilerdirectives v1.3.0 // indirect
4d63.com/gochecknoglobals v0.2.2 // indirect
codeberg.org/chavacava/garif v0.2.0 // indirect
codeberg.org/polyfloyd/go-errorlint v1.9.0 // indirect
dario.cat/mergo v1.0.1 // indirect
dev.gaijin.team/go/exhaustruct/v4 v4.0.0 // indirect
dev.gaijin.team/go/golib v0.6.0 // indirect
github.com/4meepo/tagalign v1.4.3 // indirect
github.com/Abirdcfly/dupword v0.1.7 // indirect
github.com/AdminBenni/iota-mixing v1.0.0 // indirect
github.com/AlwxSin/noinlineerr v1.0.5 // indirect
github.com/Antonboom/errname v1.1.1 // indirect
github.com/Antonboom/nilnil v1.1.1 // indirect
github.com/Antonboom/testifylint v1.6.4 // indirect
github.com/BurntSushi/toml v1.6.0 // indirect
github.com/Djarvur/go-err113 v0.1.1 // indirect
github.com/Kunde21/markdownfmt/v3 v3.1.0 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.4.0 // indirect
github.com/Masterminds/sprig/v3 v3.2.3 // indirect
github.com/MirrexOne/unqueryvet v1.5.4 // indirect
github.com/OpenPeeDeeP/depguard/v2 v2.2.1 // indirect
github.com/ProtonMail/go-crypto v1.4.0 // indirect
github.com/agext/levenshtein v1.2.3 // indirect
github.com/alecthomas/chroma/v2 v2.23.1 // indirect
github.com/alecthomas/go-check-sumtype v0.3.1 // indirect
github.com/alexkohler/nakedret/v2 v2.0.6 // indirect
github.com/alexkohler/prealloc v1.1.0 // indirect
github.com/alfatraining/structtag v1.0.0 // indirect
github.com/alingse/asasalint v0.0.11 // indirect
github.com/alingse/nilnesserr v0.2.0 // indirect
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
github.com/cloudflare/circl v1.6.2 // indirect
github.com/armon/go-radix v1.0.0 // indirect
github.com/ashanbrown/forbidigo/v2 v2.3.0 // indirect
github.com/ashanbrown/makezero/v2 v2.1.0 // indirect
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bgentry/speakeasy v0.1.0 // indirect
github.com/bkielbasa/cyclop v1.2.3 // indirect
github.com/blizzy78/varnamelen v0.8.0 // indirect
github.com/bmatcuk/doublestar/v4 v4.9.1 // indirect
github.com/bombsimon/wsl/v4 v4.7.0 // indirect
github.com/bombsimon/wsl/v5 v5.6.0 // indirect
github.com/breml/bidichk v0.3.3 // indirect
github.com/breml/errchkjson v0.4.1 // indirect
github.com/butuzov/ireturn v0.4.0 // indirect
github.com/butuzov/mirror v1.3.0 // indirect
github.com/catenacyber/perfsprint v0.10.1 // indirect
github.com/ccojocar/zxcvbn-go v1.0.4 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/charithe/durationcheck v0.0.11 // indirect
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect
github.com/charmbracelet/lipgloss v1.1.0 // indirect
github.com/charmbracelet/x/ansi v0.10.1 // indirect
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect
github.com/charmbracelet/x/term v0.2.1 // indirect
github.com/ckaznocha/intrange v0.3.1 // indirect
github.com/cloudflare/circl v1.6.3 // indirect
github.com/curioswitch/go-reassign v0.3.0 // indirect
github.com/daixiang0/gci v0.13.7 // indirect
github.com/dave/dst v0.27.3 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/denis-tingaikin/go-header v0.5.0 // indirect
github.com/dlclark/regexp2 v1.11.5 // indirect
github.com/ettle/strcase v0.2.0 // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/golang-jwt/jwt/v5 v5.3.0 // indirect
github.com/fatih/structtag v1.2.0 // indirect
github.com/firefart/nonamedreturns v1.0.6 // indirect
github.com/fsnotify/fsnotify v1.5.4 // indirect
github.com/fzipp/gocyclo v0.6.0 // indirect
github.com/ghostiam/protogetter v0.3.20 // indirect
github.com/go-critic/go-critic v0.14.3 // indirect
github.com/go-toolsmith/astcast v1.1.0 // indirect
github.com/go-toolsmith/astcopy v1.1.0 // indirect
github.com/go-toolsmith/astequal v1.2.0 // indirect
github.com/go-toolsmith/astfmt v1.1.0 // indirect
github.com/go-toolsmith/astp v1.1.0 // indirect
github.com/go-toolsmith/strparse v1.1.0 // indirect
github.com/go-toolsmith/typep v1.1.0 // indirect
github.com/go-viper/mapstructure/v2 v2.5.0 // indirect
github.com/go-xmlfmt/xmlfmt v1.1.3 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/godoc-lint/godoc-lint v0.11.2 // indirect
github.com/gofrs/flock v0.13.0 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/golangci/asciicheck v0.5.0 // indirect
github.com/golangci/dupl v0.0.0-20250308024227-f665c8d69b32 // indirect
github.com/golangci/go-printf-func-name v0.1.1 // indirect
github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d // indirect
github.com/golangci/golangci-lint/v2 v2.11.2 // indirect
github.com/golangci/golines v0.15.0 // indirect
github.com/golangci/misspell v0.8.0 // indirect
github.com/golangci/plugin-module-register v0.1.2 // indirect
github.com/golangci/revgrep v0.8.0 // indirect
github.com/golangci/swaggoswag v0.0.0-20250504205917-77f2aca3143e // indirect
github.com/golangci/unconvert v0.0.0-20250410112200-a129a6e6413e // indirect
github.com/gordonklaus/ineffassign v0.2.0 // indirect
github.com/gostaticanalysis/analysisutil v0.7.1 // indirect
github.com/gostaticanalysis/comment v1.5.0 // indirect
github.com/gostaticanalysis/forcetypeassert v0.2.0 // indirect
github.com/gostaticanalysis/nilerr v0.1.2 // indirect
github.com/hashicorp/cli v1.1.7 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-checkpoint v0.5.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-cty v1.5.0 // indirect
github.com/hashicorp/go-hclog v1.6.3 // indirect
github.com/hashicorp/go-immutable-radix/v2 v2.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-plugin v1.7.0 // indirect
github.com/hashicorp/go-uuid v1.0.3 // indirect
github.com/hashicorp/go-version v1.8.0 // indirect
github.com/hashicorp/hc-install v0.9.2 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/hashicorp/hc-install v0.9.3 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hashicorp/hcl/v2 v2.24.0 // indirect
github.com/hashicorp/logutils v1.0.0 // indirect
github.com/hashicorp/terraform-exec v0.24.0 // indirect
github.com/hashicorp/terraform-exec v0.25.0 // indirect
github.com/hashicorp/terraform-json v0.27.2 // indirect
github.com/hashicorp/terraform-plugin-sdk/v2 v2.38.1 // indirect
github.com/hashicorp/terraform-plugin-docs v0.24.0 // indirect
github.com/hashicorp/terraform-plugin-sdk/v2 v2.39.0 // indirect
github.com/hashicorp/terraform-registry-address v0.4.0 // indirect
github.com/hashicorp/terraform-svchost v0.1.1 // indirect
github.com/hashicorp/terraform-svchost v0.2.1 // indirect
github.com/hashicorp/yamux v0.1.2 // indirect
github.com/hexops/gotextdiff v1.0.3 // indirect
github.com/huandu/xstrings v1.3.3 // indirect
github.com/imdario/mergo v0.3.15 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jgautheron/goconst v1.8.2 // indirect
github.com/jingyugao/rowserrcheck v1.1.1 // indirect
github.com/jjti/go-spancheck v0.6.5 // indirect
github.com/julz/importas v0.2.0 // indirect
github.com/karamaru-alpha/copyloopvar v1.2.2 // indirect
github.com/kisielk/errcheck v1.10.0 // indirect
github.com/kkHAIKE/contextcheck v1.1.6 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/kulti/thelper v0.7.1 // indirect
github.com/kunwardeep/paralleltest v1.0.15 // indirect
github.com/lasiar/canonicalheader v1.1.2 // indirect
github.com/ldez/exptostd v0.4.5 // indirect
github.com/ldez/gomoddirectives v0.8.0 // indirect
github.com/ldez/grignotin v0.10.1 // indirect
github.com/ldez/structtags v0.6.1 // indirect
github.com/ldez/tagliatelle v0.7.2 // indirect
github.com/ldez/usetesting v0.5.0 // indirect
github.com/leonklingele/grouper v1.1.2 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/macabu/inamedparam v0.2.0 // indirect
github.com/magiconair/properties v1.8.6 // indirect
github.com/manuelarte/embeddedstructfieldcheck v0.4.0 // indirect
github.com/manuelarte/funcorder v0.5.0 // indirect
github.com/maratori/testableexamples v1.0.1 // indirect
github.com/maratori/testpackage v1.1.2 // indirect
github.com/matoous/godox v1.1.0 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/mgechev/revive v1.15.0 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/moricho/tparallel v0.3.2 // indirect
github.com/muesli/termenv v0.16.0 // indirect
github.com/nakabonne/nestif v0.3.1 // indirect
github.com/nishanths/exhaustive v0.12.0 // indirect
github.com/nishanths/predeclared v0.2.2 // indirect
github.com/nunnatsa/ginkgolinter v0.23.0 // indirect
github.com/oklog/run v1.2.0 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/posener/complete v1.2.3 // indirect
github.com/prometheus/client_golang v1.12.1 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.32.1 // indirect
github.com/prometheus/procfs v0.7.3 // indirect
github.com/quasilyte/go-ruleguard v0.4.5 // indirect
github.com/quasilyte/go-ruleguard/dsl v0.3.23 // indirect
github.com/quasilyte/gogrep v0.5.0 // indirect
github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect
github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect
github.com/raeperd/recvcheck v0.2.0 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/rogpeppe/go-internal v1.14.1 // indirect
github.com/ryancurrah/gomodguard v1.4.1 // indirect
github.com/ryanrolds/sqlclosecheck v0.5.1 // indirect
github.com/sanposhiho/wastedassign/v2 v2.1.0 // indirect
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect
github.com/sashamelentyev/interfacebloat v1.1.0 // indirect
github.com/sashamelentyev/usestdlibvars v1.29.0 // indirect
github.com/securego/gosec/v2 v2.24.7 // indirect
github.com/shopspring/decimal v1.3.1 // indirect
github.com/sirupsen/logrus v1.9.4 // indirect
github.com/sivchari/containedctx v1.0.3 // indirect
github.com/sonatard/noctx v0.5.0 // indirect
github.com/sourcegraph/go-diff v0.7.0 // indirect
github.com/spf13/afero v1.15.0 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.10 // indirect
github.com/spf13/viper v1.12.0 // indirect
github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect
github.com/stbenjam/no-sprintf-host-port v0.3.1 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/stretchr/testify v1.11.1 // indirect
github.com/subosito/gotenv v1.4.1 // indirect
github.com/tetafro/godot v1.5.4 // indirect
github.com/timakin/bodyclose v0.0.0-20241222091800-1db5c5ca4d67 // indirect
github.com/timonwong/loggercheck v0.11.0 // indirect
github.com/tomarrell/wrapcheck/v2 v2.12.0 // indirect
github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect
github.com/ultraware/funlen v0.2.0 // indirect
github.com/ultraware/whitespace v0.2.0 // indirect
github.com/uudashr/gocognit v1.2.1 // indirect
github.com/uudashr/iface v1.4.1 // indirect
github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
github.com/zclconf/go-cty v1.17.0 // indirect
golang.org/x/crypto v0.46.0 // indirect
golang.org/x/mod v0.32.0 // indirect
golang.org/x/net v0.48.0 // indirect
github.com/xen0n/gosmopolitan v1.3.0 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
github.com/yagipy/maintidx v1.0.0 // indirect
github.com/yeya24/promlinter v0.3.0 // indirect
github.com/ykadowak/zerologlint v0.1.5 // indirect
github.com/yuin/goldmark v1.7.7 // indirect
github.com/yuin/goldmark-meta v1.1.0 // indirect
github.com/zclconf/go-cty v1.18.0 // indirect
gitlab.com/bosi/decorder v0.4.2 // indirect
go-simpler.org/musttag v0.14.0 // indirect
go-simpler.org/sloglint v0.11.1 // indirect
go.abhg.dev/goldmark/frontmatter v0.2.0 // indirect
go.augendre.info/arangolint v0.4.0 // indirect
go.augendre.info/fatcontext v0.9.0 // indirect
go.uber.org/multierr v1.10.0 // indirect
go.uber.org/zap v1.27.0 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/crypto v0.48.0 // indirect
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect
golang.org/x/exp/typeparams v0.0.0-20260209203927-2842357ff358 // indirect
golang.org/x/mod v0.33.0 // indirect
golang.org/x/net v0.51.0 // indirect
golang.org/x/sync v0.19.0 // indirect
golang.org/x/sys v0.40.0 // indirect
golang.org/x/text v0.33.0 // indirect
golang.org/x/tools v0.40.0 // indirect
golang.org/x/sys v0.41.0 // indirect
golang.org/x/text v0.34.0 // indirect
golang.org/x/tools v0.42.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect
google.golang.org/grpc v1.78.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 // indirect
google.golang.org/grpc v1.79.2 // indirect
google.golang.org/protobuf v1.36.11 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
honnef.co/go/tools v0.7.0 // indirect
mvdan.cc/gofumpt v0.9.2 // indirect
mvdan.cc/unparam v0.0.0-20251027182757-5beb8c8f8f15 // indirect
)
tool golang.org/x/tools/cmd/goimports

1055
go.sum

File diff suppressed because it is too large Load diff

View file

@ -1,95 +0,0 @@
# This file contains all available configuration options
# with their default values.
# options for analysis running
run:
# default concurrency is a available CPU number
concurrency: 4
# timeout for analysis, e.g. 30s, 5m, default is 1m
timeout: 5m
linters-settings:
goimports:
# put imports beginning with prefix after 3rd-party packages;
# it's a comma-separated list of prefixes
local-prefixes: github.com/freiheit-com/nmww
depguard:
rules:
main:
list-mode: lax # Everything is allowed unless it is denied
deny:
- pkg: "github.com/stretchr/testify"
desc: Do not use a testing framework
misspell:
# Correct spellings using locale preferences for US or UK.
# Default is to use a neutral variety of English.
# Setting locale to US will correct the British spelling of 'colour' to 'color'.
locale: US
# golint:
# min-confidence: 0.8
gosec:
excludes:
# Suppressions: (see https://github.com/securego/gosec#available-rules for details)
- G104 # "Audit errors not checked" -> which we don't need and is a badly implemented version of errcheck
- G102 # "Bind to all interfaces" -> since this is normal in k8s
- G304 # "File path provided as taint input" -> too many false positives
- G307 # "Deferring unsafe method "Close" on type "io.ReadCloser" -> false positive when calling defer resp.Body.Close()
nakedret:
max-func-lines: 0
revive:
ignore-generated-header: true
severity: error
# https://github.com/mgechev/revive
rules:
- name: errorf
- name: context-as-argument
- name: error-return
- name: increment-decrement
- name: indent-error-flow
- name: superfluous-else
- name: unused-parameter
- name: unreachable-code
- name: atomic
- name: empty-lines
- name: early-return
gocritic:
enabled-tags:
- performance
- style
- experimental
disabled-checks:
- wrapperFunc
- typeDefFirst
- ifElseChain
- dupImport # https://github.com/go-critic/go-critic/issues/845
linters:
enable:
# https://golangci-lint.run/usage/linters/
# default linters
- gosimple
- govet
- ineffassign
- staticcheck
- typecheck
- unused
# additional linters
- errorlint
- gochecknoinits
- gocritic
- gofmt
- goimports
- gosec
- misspell
- nakedret
- revive
- depguard
- bodyclose
- sqlclosecheck
- wastedassign
- forcetypeassert
- errcheck
disable:
- noctx # false positive: finds errors with http.NewRequest that dont make sense
- unparam # false positives
issues:
exclude-use-default: false

97
golang-ci.yaml.bak Normal file
View file

@ -0,0 +1,97 @@
version: "2"
run:
concurrency: 4
output:
formats:
text:
print-linter-name: true
print-issued-lines: true
colors: true
path: stdout
linters:
enable:
- bodyclose
- depguard
- errorlint
- forcetypeassert
- gochecknoinits
- gocritic
- gosec
- misspell
- nakedret
- revive
- sqlclosecheck
- wastedassign
disable:
- noctx
- unparam
settings:
depguard:
rules:
main:
list-mode: lax
allow:
- tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview
- github.com/hashicorp/terraform-plugin-framework
- github.com/hashicorp/terraform-plugin-log
- github.com/stackitcloud/stackit-sdk-go
deny:
- pkg: github.com/stretchr/testify
desc: Do not use a testing framework
gocritic:
disabled-checks:
- wrapperFunc
- typeDefFirst
- ifElseChain
- dupImport
- hugeParam
enabled-tags:
- performance
- style
- experimental
gosec:
excludes:
- G104
- G102
- G304
- G307
misspell:
locale: US
nakedret:
max-func-lines: 0
revive:
severity: error
rules:
- name: errorf
- name: context-as-argument
- name: error-return
- name: increment-decrement
- name: indent-error-flow
- name: superfluous-else
- name: unused-parameter
- name: unreachable-code
- name: atomic
- name: empty-lines
- name: early-return
exclusions:
paths:
- stackit-sdk-generator/
- generated/
- pkg_gen/
generated: lax
warn-unused: true
# Excluding configuration per-path, per-linter, per-text and per-source.
rules:
# Exclude some linters from running on tests files.
- path: _test\.go
linters:
- gochecknoinits
formatters:
enable:
- gofmt
- goimports
settings:
goimports:
local-prefixes:
- tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview

View file

@ -0,0 +1,39 @@
package testutils
import (
"fmt"
"net/http"
"path/filepath"
"regexp"
"runtime"
"strings"
"github.com/jarcoal/httpmock"
)
func TestName() string {
pc, _, _, _ := runtime.Caller(1)
nameFull := runtime.FuncForPC(pc).Name()
nameEnd := filepath.Ext(nameFull)
name := strings.TrimPrefix(nameEnd, ".")
return name
}
func ActivateEnvironmentHttpMocks() {
httpmock.RegisterNoResponder(
func(req *http.Request) (*http.Response, error) {
return nil, fmt.Errorf("no responder found for %s %s, please check your http mocks", req.Method, req.URL)
},
)
httpmock.RegisterRegexpResponder(
"GET",
regexp.MustCompile(`^https://api\.bap\.microsoft\.com/providers/Microsoft\.BusinessAppPlatform/locations/(europe|unitedstates)/environmentLanguages\?api-version=2023-06-01$`),
func(_ *http.Request) (*http.Response, error) {
return httpmock.NewStringResponse(
http.StatusOK,
httpmock.File("../../services/languages/tests/datasource/Validate_Read/get_languages.json").String(),
), nil
},
)
}

View file

@ -0,0 +1,129 @@
package testutils
import (
"bytes"
"fmt"
"log"
"os"
"path"
"path/filepath"
"runtime"
"strings"
"testing"
"text/template"
)
// GetHomeEnvVariableName Helper function to obtain the home directory on different systems.
// Based on os.UserHomeDir().
func GetHomeEnvVariableName() string {
env := "HOME"
switch runtime.GOOS {
case "windows":
env = "USERPROFILE"
case "plan9":
env = "home"
}
return env
}
// CreateTemporaryHome create temporary home and initialize the credentials file as well
func CreateTemporaryHome(createValidCredentialsFile bool, t *testing.T) string {
// create a temporary file
tempHome, err := os.MkdirTemp("", "tempHome")
if err != nil {
t.Fatalf("Failed to create temporary home directory: %v", err)
}
// create credentials file in temp directory
stackitFolder := path.Join(tempHome, ".stackit")
if err := os.Mkdir(stackitFolder, 0o750); err != nil {
t.Fatalf("Failed to create stackit folder: %v", err)
}
filePath := path.Join(stackitFolder, "credentials.json")
file, err := os.Create(filePath)
if err != nil {
t.Fatalf("Failed to create credentials file: %v", err)
}
defer func() {
if err := file.Close(); err != nil {
t.Fatalf("Error while closing the file: %v", err)
}
}()
// Define content, default = invalid token
token := "foo_token"
//if createValidCredentialsFile {
// token = GetTestProjectServiceAccountJson("")
//}
if _, err = file.WriteString(token); err != nil {
t.Fatalf("Error writing to file: %v", err)
}
return tempHome
}
// SetTemporaryHome Function to overwrite the home folder
func SetTemporaryHome(tempHomePath string) {
env := GetHomeEnvVariableName()
if err := os.Setenv(env, tempHomePath); err != nil {
fmt.Printf("Error setting temporary home directory %v", err)
}
}
// CleanupTemporaryHome cleanup the temporary home and reset the environment variable
func CleanupTemporaryHome(tempHomePath string, t *testing.T) {
if err := os.RemoveAll(tempHomePath); err != nil {
t.Fatalf("Error cleaning up temporary folder: %v", err)
}
originalHomeDir, err := os.UserHomeDir()
if err != nil {
t.Fatalf("Failed to restore home directory back to normal: %v", err)
}
// revert back to original home folder
env := GetHomeEnvVariableName()
if err := os.Setenv(env, originalHomeDir); err != nil {
fmt.Printf("Error resetting temporary home directory %v", err)
}
}
func ucFirst(s string) string {
if s == "" {
return ""
}
return strings.ToUpper(s[:1]) + s[1:]
}
func StringFromTemplateMust(tplFile string, data any) string {
res, err := StringFromTemplate(tplFile, data)
if err != nil {
log.Fatalln(err)
}
return res
}
func StringFromTemplate(tplFile string, data any) (string, error) {
fn := template.FuncMap{
"ucfirst": ucFirst,
}
file := filepath.Base(tplFile)
tmpl, err := template.New(file).Funcs(fn).ParseFiles(tplFile)
if err != nil {
return "", err
}
tplBuf := &bytes.Buffer{}
err = tmpl.Execute(tplBuf, data)
if err != nil {
return "", err
}
return tplBuf.String(), nil
}
func ResStr(prefix, resource, name string) string {
return fmt.Sprintf("%s_%s.%s", prefix, resource, name)
}

View file

@ -1,71 +1,11 @@
// Copyright (c) STACKIT
package testutil
package testutils
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"strings"
"time"
"github.com/hashicorp/terraform-plugin-framework/providerserver"
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
"github.com/hashicorp/terraform-plugin-testing/config"
"github.com/hashicorp/terraform-plugin-testing/echoprovider"
"github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit"
)
const (
// Default location of credentials JSON
credentialsFilePath = ".stackit/credentials.json" //nolint:gosec // linter false positive
)
var (
// TestAccProtoV6ProviderFactories is used to instantiate a provider during
// acceptance testing. The factory function will be invoked for every Terraform
// CLI command executed to create a provider server to which the CLI can
// reattach.
TestAccProtoV6ProviderFactories = map[string]func() (tfprotov6.ProviderServer, error){
"stackit": providerserver.NewProtocol6WithError(stackit.New("test-version")()),
}
// TestEphemeralAccProtoV6ProviderFactories is used to instantiate a provider during
// acceptance testing. The factory function will be invoked for every Terraform
// CLI command executed to create a provider server to which the CLI can
// reattach.
//
// See the Terraform acceptance test documentation on ephemeral resources for more information:
// https://developer.hashicorp.com/terraform/plugin/testing/acceptance-tests/ephemeral-resources
TestEphemeralAccProtoV6ProviderFactories = map[string]func() (tfprotov6.ProviderServer, error){
"stackit": providerserver.NewProtocol6WithError(stackit.New("test-version")()),
"echo": echoprovider.NewProviderServer(),
}
// E2ETestsEnabled checks if end-to-end tests should be run.
// It is enabled when the TF_ACC environment variable is set to "1".
E2ETestsEnabled = os.Getenv("TF_ACC") == "1"
// OrganizationId is the id of organization used for tests
OrganizationId = os.Getenv("TF_ACC_ORGANIZATION_ID")
// ProjectId is the id of project used for tests
ProjectId = os.Getenv("TF_ACC_PROJECT_ID")
Region = os.Getenv("TF_ACC_REGION")
// ServerId is the id of a server used for some tests
ServerId = getenv("TF_ACC_SERVER_ID", "")
// TestProjectParentContainerID is the container id of the parent resource under which projects are created as part of the resource-manager acceptance tests
TestProjectParentContainerID = os.Getenv("TF_ACC_TEST_PROJECT_PARENT_CONTAINER_ID")
// TestProjectParentUUID is the uuid of the parent resource under which projects are created as part of the resource-manager acceptance tests
TestProjectParentUUID = os.Getenv("TF_ACC_TEST_PROJECT_PARENT_UUID")
// TestProjectServiceAccountEmail is the e-mail of a service account with admin permissions on the organization under which projects are created as part of the resource-manager acceptance tests
TestProjectServiceAccountEmail = os.Getenv("TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_EMAIL")
// TestProjectUserEmail is the e-mail of a user for the project created as part of the resource-manager acceptance tests
// Default email: acc-test@sa.stackit.cloud
TestProjectUserEmail = getenv("TF_ACC_TEST_PROJECT_USER_EMAIL", "acc-test@sa.stackit.cloud")
// TestImageLocalFilePath is the local path to an image file used for image acceptance tests
TestImageLocalFilePath = getenv("TF_ACC_TEST_IMAGE_LOCAL_FILE_PATH", "default")
CdnCustomEndpoint = os.Getenv("TF_ACC_CDN_CUSTOM_ENDPOINT")
DnsCustomEndpoint = os.Getenv("TF_ACC_DNS_CUSTOM_ENDPOINT")
GitCustomEndpoint = os.Getenv("TF_ACC_GIT_CUSTOM_ENDPOINT")
@ -93,30 +33,29 @@ var (
SKECustomEndpoint = os.Getenv("TF_ACC_SKE_CUSTOM_ENDPOINT")
)
// Provider config helper functions
func ObservabilityProviderConfig() string {
if ObservabilityCustomEndpoint == "" {
return `provider "stackit" {
return `provider "stackitprivatepreview" {
default_region = "eu01"
}`
}
return fmt.Sprintf(`
provider "stackit" {
provider "stackitprivatepreview" {
observability_custom_endpoint = "%s"
}`,
ObservabilityCustomEndpoint,
)
}
func CdnProviderConfig() string {
if CdnCustomEndpoint == "" {
return `
provider "stackit" {
provider "stackitprivatepreview" {
enable_beta_resources = true
}`
}
return fmt.Sprintf(`
provider "stackit" {
provider "stackitprivatepreview" {
cdn_custom_endpoint = "%s"
enable_beta_resources = true
}`,
@ -126,10 +65,10 @@ func CdnProviderConfig() string {
func DnsProviderConfig() string {
if DnsCustomEndpoint == "" {
return `provider "stackit" {}`
return `provider "stackitprivatepreview" {}`
}
return fmt.Sprintf(`
provider "stackit" {
provider "stackitprivatepreview" {
dns_custom_endpoint = "%s"
}`,
DnsCustomEndpoint,
@ -139,12 +78,12 @@ func DnsProviderConfig() string {
func IaaSProviderConfig() string {
if IaaSCustomEndpoint == "" {
return `
provider "stackit" {
provider "stackitprivatepreview" {
default_region = "eu01"
}`
}
return fmt.Sprintf(`
provider "stackit" {
provider "stackitprivatepreview" {
iaas_custom_endpoint = "%s"
}`,
IaaSCustomEndpoint,
@ -154,13 +93,13 @@ func IaaSProviderConfig() string {
func IaaSProviderConfigWithBetaResourcesEnabled() string {
if IaaSCustomEndpoint == "" {
return `
provider "stackit" {
provider "stackitprivatepreview" {
enable_beta_resources = true
default_region = "eu01"
}`
}
return fmt.Sprintf(`
provider "stackit" {
provider "stackitprivatepreview" {
enable_beta_resources = true
iaas_custom_endpoint = "%s"
}`,
@ -171,13 +110,13 @@ func IaaSProviderConfigWithBetaResourcesEnabled() string {
func IaaSProviderConfigWithExperiments() string {
if IaaSCustomEndpoint == "" {
return `
provider "stackit" {
provider "stackitprivatepreview" {
default_region = "eu01"
experiments = [ "routing-tables", "network" ]
}`
}
return fmt.Sprintf(`
provider "stackit" {
provider "stackitprivatepreview" {
iaas_custom_endpoint = "%s"
experiments = [ "routing-tables", "network" ]
}`,
@ -188,12 +127,12 @@ func IaaSProviderConfigWithExperiments() string {
func KMSProviderConfig() string {
if KMSCustomEndpoint == "" {
return `
provider "stackit" {
provider "stackitprivatepreview" {
default_region = "eu01"
}`
}
return fmt.Sprintf(`
provider "stackit" {
provider "stackitprivatepreview" {
kms_custom_endpoint = "%s"
}`,
KMSCustomEndpoint,
@ -203,12 +142,12 @@ func KMSProviderConfig() string {
func LoadBalancerProviderConfig() string {
if LoadBalancerCustomEndpoint == "" {
return `
provider "stackit" {
provider "stackitprivatepreview" {
default_region = "eu01"
}`
}
return fmt.Sprintf(`
provider "stackit" {
provider "stackitprivatepreview" {
loadbalancer_custom_endpoint = "%s"
}`,
LoadBalancerCustomEndpoint,
@ -218,12 +157,12 @@ func LoadBalancerProviderConfig() string {
func LogMeProviderConfig() string {
if LogMeCustomEndpoint == "" {
return `
provider "stackit" {
provider "stackitprivatepreview" {
default_region = "eu01"
}`
}
return fmt.Sprintf(`
provider "stackit" {
provider "stackitprivatepreview" {
logme_custom_endpoint = "%s"
}`,
LogMeCustomEndpoint,
@ -233,12 +172,12 @@ func LogMeProviderConfig() string {
func MariaDBProviderConfig() string {
if MariaDBCustomEndpoint == "" {
return `
provider "stackit" {
provider "stackitprivatepreview" {
default_region = "eu01"
}`
}
return fmt.Sprintf(`
provider "stackit" {
provider "stackitprivatepreview" {
mariadb_custom_endpoint = "%s"
}`,
MariaDBCustomEndpoint,
@ -248,13 +187,13 @@ func MariaDBProviderConfig() string {
func ModelServingProviderConfig() string {
if ModelServingCustomEndpoint == "" {
return `
provider "stackit" {
provider "stackitprivatepreview" {
default_region = "eu01"
}
`
}
return fmt.Sprintf(`
provider "stackit" {
provider "stackitprivatepreview" {
modelserving_custom_endpoint = "%s"
}`,
ModelServingCustomEndpoint,
@ -264,12 +203,12 @@ func ModelServingProviderConfig() string {
func MongoDBFlexProviderConfig() string {
if MongoDBFlexCustomEndpoint == "" {
return `
provider "stackit" {
provider "stackitprivatepreview" {
default_region = "eu01"
}`
}
return fmt.Sprintf(`
provider "stackit" {
provider "stackitprivatepreview" {
mongodbflex_custom_endpoint = "%s"
}`,
MongoDBFlexCustomEndpoint,
@ -279,12 +218,12 @@ func MongoDBFlexProviderConfig() string {
func ObjectStorageProviderConfig() string {
if ObjectStorageCustomEndpoint == "" {
return `
provider "stackit" {
provider "stackitprivatepreview" {
default_region = "eu01"
}`
}
return fmt.Sprintf(`
provider "stackit" {
provider "stackitprivatepreview" {
objectstorage_custom_endpoint = "%s"
}`,
ObjectStorageCustomEndpoint,
@ -294,29 +233,32 @@ func ObjectStorageProviderConfig() string {
func OpenSearchProviderConfig() string {
if OpenSearchCustomEndpoint == "" {
return `
provider "stackit" {
provider "stackitprivatepreview" {
default_region = "eu01"
}`
}
return fmt.Sprintf(`
provider "stackit" {
provider "stackitprivatepreview" {
opensearch_custom_endpoint = "%s"
}`,
OpenSearchCustomEndpoint,
)
}
func PostgresFlexProviderConfig() string {
func PostgresFlexProviderConfig(saFile string) string {
if PostgresFlexCustomEndpoint == "" {
return `
provider "stackit" {
return fmt.Sprintf(`
provider "stackitprivatepreview" {
default_region = "eu01"
}`
service_account_key_path = "%s"
}`, saFile)
}
return fmt.Sprintf(`
provider "stackit" {
provider "stackitprivatepreview" {
service_account_key_path = "%s"
postgresflex_custom_endpoint = "%s"
}`,
saFile,
PostgresFlexCustomEndpoint,
)
}
@ -324,12 +266,12 @@ func PostgresFlexProviderConfig() string {
func RabbitMQProviderConfig() string {
if RabbitMQCustomEndpoint == "" {
return `
provider "stackit" {
provider "stackitprivatepreview" {
default_region = "eu01"
}`
}
return fmt.Sprintf(`
provider "stackit" {
provider "stackitprivatepreview" {
rabbitmq_custom_endpoint = "%s"
}`,
RabbitMQCustomEndpoint,
@ -339,66 +281,68 @@ func RabbitMQProviderConfig() string {
func RedisProviderConfig() string {
if RedisCustomEndpoint == "" {
return `
provider "stackit" {
provider "stackitprivatepreview" {
default_region = "eu01"
}`
}
return fmt.Sprintf(`
provider "stackit" {
provider "stackitprivatepreview" {
redis_custom_endpoint = "%s"
}`,
RedisCustomEndpoint,
)
}
func ResourceManagerProviderConfig() string {
token := GetTestProjectServiceAccountToken("")
func ResourceManagerProviderConfig(saKeyPath string) string {
if ResourceManagerCustomEndpoint == "" || AuthorizationCustomEndpoint == "" {
return fmt.Sprintf(`
provider "stackit" {
service_account_token = "%s"
provider "stackitprivatepreview" {
service_account_key_path = "%s"
}`,
token,
saKeyPath,
)
}
return fmt.Sprintf(`
provider "stackit" {
provider "stackitprivatepreview" {
resourcemanager_custom_endpoint = "%s"
authorization_custom_endpoint = "%s"
service_account_token = "%s"
service_account_key_path = "%s"
}`,
ResourceManagerCustomEndpoint,
AuthorizationCustomEndpoint,
token,
saKeyPath,
)
}
func SecretsManagerProviderConfig() string {
if SecretsManagerCustomEndpoint == "" {
return `
provider "stackit" {
provider "stackitprivatepreview" {
default_region = "eu01"
}`
}
return fmt.Sprintf(`
provider "stackit" {
provider "stackitprivatepreview" {
secretsmanager_custom_endpoint = "%s"
}`,
SecretsManagerCustomEndpoint,
)
}
func SQLServerFlexProviderConfig() string {
func SQLServerFlexProviderConfig(saFile string) string {
if SQLServerFlexCustomEndpoint == "" {
return `
provider "stackit" {
return fmt.Sprintf(`
provider "stackitprivatepreview" {
default_region = "eu01"
}`
service_account_key_path = "%s"
}`, saFile)
}
return fmt.Sprintf(`
provider "stackit" {
provider "stackitprivatepreview" {
service_account_key_path = "%s"
sqlserverflex_custom_endpoint = "%s"
}`,
saFile,
SQLServerFlexCustomEndpoint,
)
}
@ -406,13 +350,13 @@ func SQLServerFlexProviderConfig() string {
func ServerBackupProviderConfig() string {
if ServerBackupCustomEndpoint == "" {
return `
provider "stackit" {
provider "stackitprivatepreview" {
default_region = "eu01"
enable_beta_resources = true
}`
}
return fmt.Sprintf(`
provider "stackit" {
provider "stackitprivatepreview" {
server_backup_custom_endpoint = "%s"
enable_beta_resources = true
}`,
@ -423,13 +367,13 @@ func ServerBackupProviderConfig() string {
func ServerUpdateProviderConfig() string {
if ServerUpdateCustomEndpoint == "" {
return `
provider "stackit" {
provider "stackitprivatepreview" {
default_region = "eu01"
enable_beta_resources = true
}`
}
return fmt.Sprintf(`
provider "stackit" {
provider "stackitprivatepreview" {
server_update_custom_endpoint = "%s"
enable_beta_resources = true
}`,
@ -440,12 +384,12 @@ func ServerUpdateProviderConfig() string {
func SKEProviderConfig() string {
if SKECustomEndpoint == "" {
return `
provider "stackit" {
provider "stackitprivatepreview" {
default_region = "eu01"
}`
}
return fmt.Sprintf(`
provider "stackit" {
provider "stackitprivatepreview" {
ske_custom_endpoint = "%s"
}`,
SKECustomEndpoint,
@ -455,13 +399,13 @@ func SKEProviderConfig() string {
func AuthorizationProviderConfig() string {
if AuthorizationCustomEndpoint == "" {
return `
provider "stackit" {
provider "stackitprivatepreview" {
default_region = "eu01"
experiments = ["iam"]
}`
}
return fmt.Sprintf(`
provider "stackit" {
provider "stackitprivatepreview" {
authorization_custom_endpoint = "%s"
experiments = ["iam"]
}`,
@ -472,13 +416,13 @@ func AuthorizationProviderConfig() string {
func ServiceAccountProviderConfig() string {
if ServiceAccountCustomEndpoint == "" {
return `
provider "stackit" {
provider "stackitprivatepreview" {
default_region = "eu01"
enable_beta_resources = true
}`
}
return fmt.Sprintf(`
provider "stackit" {
provider "stackitprivatepreview" {
service_account_custom_endpoint = "%s"
enable_beta_resources = true
}`,
@ -489,13 +433,13 @@ func ServiceAccountProviderConfig() string {
func GitProviderConfig() string {
if GitCustomEndpoint == "" {
return `
provider "stackit" {
provider "stackitprivatepreview" {
default_region = "eu01"
enable_beta_resources = true
}`
}
return fmt.Sprintf(`
provider "stackit" {
provider "stackitprivatepreview" {
git_custom_endpoint = "%s"
enable_beta_resources = true
}`,
@ -506,105 +450,15 @@ func GitProviderConfig() string {
func ScfProviderConfig() string {
if ScfCustomEndpoint == "" {
return `
provider "stackit" {
provider "stackitprivatepreview" {
default_region = "eu01"
}`
}
return fmt.Sprintf(`
provider "stackit" {
provider "stackitprivatepreview" {
default_region = "eu01"
scf_custom_endpoint = "%s"
}`,
ScfCustomEndpoint,
)
}
func ResourceNameWithDateTime(name string) string {
dateTime := time.Now().Format(time.RFC3339)
// Remove timezone to have a smaller datetime
dateTimeTrimmed, _, _ := strings.Cut(dateTime, "+")
return fmt.Sprintf("tf-acc-%s-%s", name, dateTimeTrimmed)
}
func GetTestProjectServiceAccountToken(path string) string {
var err error
token, tokenSet := os.LookupEnv("TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_TOKEN")
if !tokenSet || token == "" {
token, err = readTestTokenFromCredentialsFile(path)
if err != nil {
return ""
}
}
return token
}
func readTestTokenFromCredentialsFile(path string) (string, error) {
if path == "" {
customPath, customPathSet := os.LookupEnv("STACKIT_CREDENTIALS_PATH")
if !customPathSet || customPath == "" {
path = credentialsFilePath
home, err := os.UserHomeDir()
if err != nil {
return "", fmt.Errorf("getting home directory: %w", err)
}
path = filepath.Join(home, path)
} else {
path = customPath
}
}
credentialsRaw, err := os.ReadFile(path)
if err != nil {
return "", fmt.Errorf("opening file: %w", err)
}
var credentials struct {
TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_TOKEN string `json:"TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_TOKEN"`
}
err = json.Unmarshal(credentialsRaw, &credentials)
if err != nil {
return "", fmt.Errorf("unmarshalling credentials: %w", err)
}
return credentials.TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_TOKEN, nil
}
func getenv(key, defaultValue string) string {
val := os.Getenv(key)
if val == "" {
return defaultValue
}
return val
}
// CreateDefaultLocalFile is a helper for local_file_path. No real data is created
func CreateDefaultLocalFile() os.File {
// Define the file name and size
fileName := "test-512k.img"
size := 512 * 1024 // 512 KB
// Create the file
file, err := os.Create(fileName)
if err != nil {
panic(err)
}
// Seek to the desired position (512 KB)
_, err = file.Seek(int64(size), 0)
if err != nil {
panic(err)
}
return *file
}
func ConvertConfigVariable(variable config.Variable) string {
tmpByteArray, _ := variable.MarshalJSON()
// In case the variable is a string, the quotes should be removed
if tmpByteArray[0] == '"' && tmpByteArray[len(tmpByteArray)-1] == '"' {
result := string(tmpByteArray[1 : len(tmpByteArray)-1])
// Replace escaped quotes which where added MarshalJSON
rawString := strings.ReplaceAll(result, `\"`, `"`)
return rawString
}
return string(tmpByteArray)
}

View file

@ -0,0 +1,220 @@
package testutils
import (
"fmt"
"log"
"log/slog"
"os"
"os/exec"
"strings"
"time"
"github.com/hashicorp/terraform-plugin-framework/providerserver"
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
"github.com/hashicorp/terraform-plugin-testing/config"
"github.com/hashicorp/terraform-plugin-testing/echoprovider"
"github.com/joho/godotenv"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit"
)
const (
// Default location of service account JSON
serviceAccountFilePath = "service_account.json"
)
var (
// TestAccProtoV6ProviderFactories is used to instantiate a provider during
// acceptance testing. The factory function will be invoked for every Terraform
// CLI command executed to create a provider server to which the CLI can
// reattach.
TestAccProtoV6ProviderFactories = map[string]func() (tfprotov6.ProviderServer, error){
"stackitprivatepreview": providerserver.NewProtocol6WithError(stackit.New("test-version")()),
}
// TestEphemeralAccProtoV6ProviderFactories is used to instantiate a provider during
// acceptance testing. The factory function will be invoked for every Terraform
// CLI command executed to create a provider server to which the CLI can
// reattach.
//
// See the Terraform acceptance test documentation on ephemeral resources for more information:
// https://developer.hashicorp.com/terraform/plugin/testing/acceptance-tests/ephemeral-resources
TestEphemeralAccProtoV6ProviderFactories = map[string]func() (tfprotov6.ProviderServer, error){
"stackitprivatepreview": providerserver.NewProtocol6WithError(stackit.New("test-version")()),
"echo": echoprovider.NewProviderServer(),
}
// E2ETestsEnabled checks if end-to-end tests should be run.
// It is enabled when the TF_ACC environment variable is set to "1".
E2ETestsEnabled = os.Getenv("TF_ACC") == "1"
// OrganizationId is the id of organization used for tests
OrganizationId = os.Getenv("TF_ACC_ORGANIZATION_ID")
// ProjectId is the id of project used for tests
ProjectId = os.Getenv("TF_ACC_PROJECT_ID")
Region = os.Getenv("TF_ACC_REGION")
// ServiceAccountFile is the json file of the service account
ServiceAccountFile = os.Getenv("TF_ACC_SERVICE_ACCOUNT_FILE")
// ServerId is the id of a server used for some tests
ServerId = getenv("TF_ACC_SERVER_ID", "")
// TestProjectParentContainerID is the container id of the parent resource under which projects are created as part of the resource-manager acceptance tests
TestProjectParentContainerID = os.Getenv("TF_ACC_TEST_PROJECT_PARENT_CONTAINER_ID")
// TestProjectParentUUID is the uuid of the parent resource under which projects are created as part of the resource-manager acceptance tests
TestProjectParentUUID = os.Getenv("TF_ACC_TEST_PROJECT_PARENT_UUID")
// TestProjectServiceAccountEmail is the e-mail of a service account with admin permissions on the organization under which projects are created as part of the resource-manager acceptance tests
TestProjectServiceAccountEmail = os.Getenv("TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_EMAIL")
// TestProjectUserEmail is the e-mail of a user for the project created as part of the resource-manager acceptance tests
// Default email: acc-test@sa.stackit.cloud
TestProjectUserEmail = getenv("TF_ACC_TEST_PROJECT_USER_EMAIL", "acc-test@sa.stackit.cloud")
// TestImageLocalFilePath is the local path to an image file used for image acceptance tests
TestImageLocalFilePath = getenv("TF_ACC_TEST_IMAGE_LOCAL_FILE_PATH", "default")
)
func Setup() {
root, err := getRoot()
if err != nil {
log.Fatalln(err)
}
err = godotenv.Load(fmt.Sprintf("%s/.env", *root))
if err != nil {
slog.Info("could not find .env file - not loading .env")
return
}
slog.Info("loaded .env file", "path", *root)
}
func getRoot() (*string, error) {
cmd := exec.Command("git", "rev-parse", "--show-toplevel")
out, err := cmd.Output()
if err != nil {
return nil, err
}
lines := strings.Split(string(out), "\n")
return &lines[0], nil
}
func ResourceNameWithDateTime(name string) string {
dateTime := time.Now().Format(time.RFC3339)
// Remove timezone to have a smaller datetime
dateTimeTrimmed, _, _ := strings.Cut(dateTime, "+")
return fmt.Sprintf("tf-acc-%s-%s", name, dateTimeTrimmed)
}
//func GetTestProjectServiceAccountJson(path string) string {
// var err error
// json, ok := os.LookupEnv("TF_ACC_SERVICE_ACCOUNT_JSON_CONTENT")
// if !ok || json == "" {
// json, err = readTestServiceAccountJsonFromFile(path)
// if err != nil {
// return ""
// }
// }
// return json
//}
// func GetTestProjectServiceAccountToken(path string) string {
// var err error
// token, tokenSet := os.LookupEnv("TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_TOKEN")
// if !tokenSet || token == "" {
// token, err = readTestTokenFromCredentialsFile(path)
// if err != nil {
// return ""
// }
// }
// return token
//}
//
// func readTestTokenFromCredentialsFile(path string) (string, error) {
// if path == "" {
// customPath, customPathSet := os.LookupEnv("STACKIT_CREDENTIALS_PATH")
// if !customPathSet || customPath == "" {
// path = credentialsFilePath
// home, err := os.UserHomeDir()
// if err != nil {
// return "", fmt.Errorf("getting home directory: %w", err)
// }
// path = filepath.Join(home, path)
// } else {
// path = customPath
// }
// }
//
// credentialsRaw, err := os.ReadFile(path)
// if err != nil {
// return "", fmt.Errorf("opening file: %w", err)
// }
//
// var credentials struct {
// TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_TOKEN string `json:"TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_TOKEN"`
// }
// err = json.Unmarshal(credentialsRaw, &credentials)
// if err != nil {
// return "", fmt.Errorf("unmarshalling credentials: %w", err)
// }
// return credentials.TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_TOKEN, nil
//}
//func readTestServiceAccountJsonFromFile(path string) (string, error) {
// if path == "" {
// customPath, ok := os.LookupEnv("TF_ACC_SERVICE_ACCOUNT_FILE")
// if !ok || customPath == "" {
// path = serviceAccountFilePath
// // TODO: check if we want to handle this with a home dir
// /*
// home, err := os.UserHomeDir()
// if err != nil {
// return "", fmt.Errorf("getting home directory: %w", err)
// }
// path = filepath.Join(home, path)
// */
// } else {
// path = customPath
// }
// }
//
// credentialsRaw, err := os.ReadFile(path)
// if err != nil {
// return "", fmt.Errorf("opening file: %w", err)
// }
// return string(credentialsRaw), nil
//}
func getenv(key, defaultValue string) string {
val := os.Getenv(key)
if val == "" {
return defaultValue
}
return val
}
// CreateDefaultLocalFile is a helper for local_file_path. No real data is created
func CreateDefaultLocalFile() os.File {
// Define the file name and size
fileName := "test-512k.img"
size := 512 * 1024 // 512 KB
// Create the file
file, err := os.Create(fileName)
if err != nil {
panic(err)
}
// Seek to the desired position (512 KB)
_, err = file.Seek(int64(size), 0)
if err != nil {
panic(err)
}
return *file
}
func ConvertConfigVariable(variable config.Variable) string {
tmpByteArray, _ := variable.MarshalJSON()
// In case the variable is a string, the quotes should be removed
if tmpByteArray[0] == '"' && tmpByteArray[len(tmpByteArray)-1] == '"' {
result := string(tmpByteArray[1 : len(tmpByteArray)-1])
// Replace escaped quotes which where added MarshalJSON
rawString := strings.ReplaceAll(result, `\"`, `"`)
return rawString
}
return string(tmpByteArray)
}

View file

@ -1,6 +1,4 @@
// Copyright (c) STACKIT
package testutil
package testutils
import (
"testing"

View file

@ -1,5 +1,3 @@
// Copyright (c) STACKIT
package main
import (
@ -8,7 +6,8 @@ import (
"log"
"github.com/hashicorp/terraform-plugin-framework/providerserver"
"github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit"
)
var (
@ -21,7 +20,7 @@ func main() {
flag.BoolVar(&debug, "debug", false, "allows debugging the provider")
flag.Parse()
err := providerserver.Serve(context.Background(), stackit.New(version), providerserver.ServeOpts{
Address: "registry.terraform.io/mhenselin/stackitprivatepreview",
Address: "tfregistry.sysops.stackit.rocks/mhenselin/stackitprivatepreview",
Debug: debug,
})
if err != nil {

0
pkg/.gitkeep Normal file
View file

View file

@ -1 +0,0 @@
6.6.0

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,631 +0,0 @@
/*
PostgreSQL Flex API
This is the documentation for the STACKIT Postgres Flex service
API version: 3alpha1
*/
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
package postgresflexalpha
import (
"bytes"
"context"
"encoding/json"
"encoding/xml"
"fmt"
"io"
"log"
"mime/multipart"
"net/http"
"net/http/httputil"
"net/url"
"os"
"path/filepath"
"reflect"
"regexp"
"strconv"
"strings"
"time"
"unicode/utf8"
"github.com/stackitcloud/stackit-sdk-go/core/auth"
"github.com/stackitcloud/stackit-sdk-go/core/config"
)
var (
jsonCheck = regexp.MustCompile(`(?i:(?:application|text)/(?:vnd\.[^;]+\+)?json)`)
xmlCheck = regexp.MustCompile(`(?i:(?:application|text)/xml)`)
queryParamSplit = regexp.MustCompile(`(^|&)([^&]+)`)
queryDescape = strings.NewReplacer("%5B", "[", "%5D", "]")
)
// APIClient manages communication with the PostgreSQL Flex API API v3alpha1
// In most cases there should be only one, shared, APIClient.
type APIClient struct {
cfg *config.Configuration
common service // Reuse a single struct instead of allocating one for each service on the heap.
defaultApi *DefaultApiService
}
type service struct {
client DefaultApi
}
// NewAPIClient creates a new API client.
// Optionally receives configuration options
func NewAPIClient(opts ...config.ConfigurationOption) (*APIClient, error) {
cfg := NewConfiguration()
for _, option := range opts {
err := option(cfg)
if err != nil {
return nil, fmt.Errorf("configuring the client: %w", err)
}
}
err := config.ConfigureRegion(cfg)
if err != nil {
return nil, fmt.Errorf("configuring region: %w", err)
}
if cfg.HTTPClient == nil {
cfg.HTTPClient = &http.Client{}
}
authRoundTripper, err := auth.SetupAuth(cfg)
if err != nil {
return nil, fmt.Errorf("setting up authentication: %w", err)
}
roundTripper := authRoundTripper
if cfg.Middleware != nil {
roundTripper = config.ChainMiddleware(roundTripper, cfg.Middleware...)
}
cfg.HTTPClient.Transport = roundTripper
c := &APIClient{}
c.cfg = cfg
c.common.client = c
c.defaultApi = (*DefaultApiService)(&c.common)
return c, nil
}
func atoi(in string) (int, error) {
return strconv.Atoi(in)
}
// selectHeaderContentType select a content type from the available list.
func selectHeaderContentType(contentTypes []string) string {
if len(contentTypes) == 0 {
return ""
}
if contains(contentTypes, "application/json") {
return "application/json"
}
return contentTypes[0] // use the first content type specified in 'consumes'
}
// selectHeaderAccept join all accept types and return
func selectHeaderAccept(accepts []string) string {
if len(accepts) == 0 {
return ""
}
if contains(accepts, "application/json") {
return "application/json"
}
return strings.Join(accepts, ",")
}
// contains is a case insensitive match, finding needle in a haystack
func contains(haystack []string, needle string) bool {
for _, a := range haystack {
if strings.EqualFold(a, needle) {
return true
}
}
return false
}
// Verify optional parameters are of the correct type.
func typeCheckParameter(obj interface{}, expected string, name string) error {
// Make sure there is an object.
if obj == nil {
return nil
}
// Check the type is as expected.
if reflect.TypeOf(obj).String() != expected {
return fmt.Errorf("expected %s to be of type %s but received %s", name, expected, reflect.TypeOf(obj).String())
}
return nil
}
func ParameterValueToString(obj interface{}, key string) string {
if reflect.TypeOf(obj).Kind() != reflect.Ptr {
return fmt.Sprintf("%v", obj)
}
var param, ok = obj.(MappedNullable)
if !ok {
return ""
}
dataMap, err := param.ToMap()
if err != nil {
return ""
}
return fmt.Sprintf("%v", dataMap[key])
}
// parameterAddToHeaderOrQuery adds the provided object to the request header or url query
// supporting deep object syntax
func parameterAddToHeaderOrQuery(headerOrQueryParams interface{}, keyPrefix string, obj interface{}, collectionType string) {
var v = reflect.ValueOf(obj)
var value = ""
if v == reflect.ValueOf(nil) {
value = "null"
} else {
switch v.Kind() {
case reflect.Invalid:
value = "invalid"
case reflect.Struct:
if t, ok := obj.(MappedNullable); ok {
dataMap, err := t.ToMap()
if err != nil {
return
}
parameterAddToHeaderOrQuery(headerOrQueryParams, keyPrefix, dataMap, collectionType)
return
}
if t, ok := obj.(time.Time); ok {
parameterAddToHeaderOrQuery(headerOrQueryParams, keyPrefix, t.Format(time.RFC3339), collectionType)
return
}
value = v.Type().String() + " value"
case reflect.Slice:
var indValue = reflect.ValueOf(obj)
if indValue == reflect.ValueOf(nil) {
return
}
var lenIndValue = indValue.Len()
for i := 0; i < lenIndValue; i++ {
var arrayValue = indValue.Index(i)
parameterAddToHeaderOrQuery(headerOrQueryParams, keyPrefix, arrayValue.Interface(), collectionType)
}
return
case reflect.Map:
var indValue = reflect.ValueOf(obj)
if indValue == reflect.ValueOf(nil) {
return
}
iter := indValue.MapRange()
for iter.Next() {
k, v := iter.Key(), iter.Value()
parameterAddToHeaderOrQuery(headerOrQueryParams, fmt.Sprintf("%s[%s]", keyPrefix, k.String()), v.Interface(), collectionType)
}
return
case reflect.Interface:
fallthrough
case reflect.Ptr:
parameterAddToHeaderOrQuery(headerOrQueryParams, keyPrefix, v.Elem().Interface(), collectionType)
return
case reflect.Int, reflect.Int8, reflect.Int16,
reflect.Int32, reflect.Int64:
value = strconv.FormatInt(v.Int(), 10)
case reflect.Uint, reflect.Uint8, reflect.Uint16,
reflect.Uint32, reflect.Uint64, reflect.Uintptr:
value = strconv.FormatUint(v.Uint(), 10)
case reflect.Float32, reflect.Float64:
value = strconv.FormatFloat(v.Float(), 'g', -1, 32)
case reflect.Bool:
value = strconv.FormatBool(v.Bool())
case reflect.String:
value = v.String()
default:
value = v.Type().String() + " value"
}
}
switch valuesMap := headerOrQueryParams.(type) {
case url.Values:
if collectionType == "csv" && valuesMap.Get(keyPrefix) != "" {
valuesMap.Set(keyPrefix, valuesMap.Get(keyPrefix)+","+value)
} else {
valuesMap.Add(keyPrefix, value)
}
break
case map[string]string:
valuesMap[keyPrefix] = value
break
}
}
// helper for converting interface{} parameters to json strings
func parameterToJson(obj interface{}) (string, error) {
jsonBuf, err := json.Marshal(obj)
if err != nil {
return "", err
}
return string(jsonBuf), err
}
// callAPI do the request.
func (c *APIClient) callAPI(request *http.Request) (*http.Response, error) {
if c.cfg.Debug {
dump, err := httputil.DumpRequestOut(request, true)
if err != nil {
return nil, err
}
log.Printf("\n%s\n", string(dump))
}
resp, err := c.cfg.HTTPClient.Do(request)
if err != nil {
return resp, err
}
if c.cfg.Debug {
dump, err := httputil.DumpResponse(resp, true)
if err != nil {
return resp, err
}
log.Printf("\n%s\n", string(dump))
}
return resp, err
}
// Allow modification of underlying config for alternate implementations and testing
// Caution: modifying the configuration while live can cause data races and potentially unwanted behavior
func (c *APIClient) GetConfig() *config.Configuration {
return c.cfg
}
type formFile struct {
fileBytes []byte
fileName string
formFileName string
}
// prepareRequest build the request
func (c *APIClient) prepareRequest(
ctx context.Context,
path string, method string,
postBody interface{},
headerParams map[string]string,
queryParams url.Values,
formParams url.Values,
formFiles []formFile) (localVarRequest *http.Request, err error) {
var body *bytes.Buffer
// Detect postBody type and post.
if !IsNil(postBody) {
contentType := headerParams["Content-Type"]
if contentType == "" {
contentType = detectContentType(postBody)
headerParams["Content-Type"] = contentType
}
body, err = setBody(postBody, contentType)
if err != nil {
return nil, err
}
}
// add form parameters and file if available.
if strings.HasPrefix(headerParams["Content-Type"], "multipart/form-data") && len(formParams) > 0 || (len(formFiles) > 0) {
if body != nil {
return nil, fmt.Errorf("cannot specify postBody and multipart form at the same time.")
}
body = &bytes.Buffer{}
w := multipart.NewWriter(body)
for k, v := range formParams {
for _, iv := range v {
if strings.HasPrefix(k, "@") { // file
err = addFile(w, k[1:], iv)
if err != nil {
return nil, err
}
} else { // form value
w.WriteField(k, iv)
}
}
}
for _, formFile := range formFiles {
if len(formFile.fileBytes) > 0 && formFile.fileName != "" {
w.Boundary()
part, err := w.CreateFormFile(formFile.formFileName, filepath.Base(formFile.fileName))
if err != nil {
return nil, err
}
_, err = part.Write(formFile.fileBytes)
if err != nil {
return nil, err
}
}
}
// Set the Boundary in the Content-Type
headerParams["Content-Type"] = w.FormDataContentType()
// Set Content-Length
headerParams["Content-Length"] = fmt.Sprintf("%d", body.Len())
w.Close()
}
if strings.HasPrefix(headerParams["Content-Type"], "application/x-www-form-urlencoded") && len(formParams) > 0 {
if body != nil {
return nil, fmt.Errorf("cannot specify postBody and x-www-form-urlencoded form at the same time.")
}
body = &bytes.Buffer{}
body.WriteString(formParams.Encode())
// Set Content-Length
headerParams["Content-Length"] = fmt.Sprintf("%d", body.Len())
}
// Setup path and query parameters
url, err := url.Parse(path)
if err != nil {
return nil, err
}
// Override request host, if applicable
if c.cfg.Host != "" {
url.Host = c.cfg.Host
}
// Override request scheme, if applicable
if c.cfg.Scheme != "" {
url.Scheme = c.cfg.Scheme
}
// Adding Query Param
query := url.Query()
for k, v := range queryParams {
for _, iv := range v {
query.Add(k, iv)
}
}
// Encode the parameters.
url.RawQuery = queryParamSplit.ReplaceAllStringFunc(query.Encode(), func(s string) string {
pieces := strings.Split(s, "=")
pieces[0] = queryDescape.Replace(pieces[0])
return strings.Join(pieces, "=")
})
// Generate a new request
if body != nil {
localVarRequest, err = http.NewRequest(method, url.String(), body)
} else {
localVarRequest, err = http.NewRequest(method, url.String(), nil)
}
if err != nil {
return nil, err
}
// add header parameters, if any
if len(headerParams) > 0 {
headers := http.Header{}
for h, v := range headerParams {
headers[h] = []string{v}
}
localVarRequest.Header = headers
}
// Add the user agent to the request.
localVarRequest.Header.Add("User-Agent", c.cfg.UserAgent)
if ctx != nil {
// add context to the request
localVarRequest = localVarRequest.WithContext(ctx)
// Walk through any authentication.
}
for header, value := range c.cfg.DefaultHeader {
localVarRequest.Header.Add(header, value)
}
return localVarRequest, nil
}
func (c *APIClient) decode(v interface{}, b []byte, contentType string) (err error) {
if len(b) == 0 {
return nil
}
if s, ok := v.(*string); ok {
*s = string(b)
return nil
}
if f, ok := v.(*os.File); ok {
f, err = os.CreateTemp("", "HttpClientFile")
if err != nil {
return
}
_, err = f.Write(b)
if err != nil {
return
}
_, err = f.Seek(0, io.SeekStart)
return
}
if f, ok := v.(**os.File); ok {
*f, err = os.CreateTemp("", "HttpClientFile")
if err != nil {
return
}
_, err = (*f).Write(b)
if err != nil {
return
}
_, err = (*f).Seek(0, io.SeekStart)
return
}
if xmlCheck.MatchString(contentType) {
if err = xml.Unmarshal(b, v); err != nil {
return err
}
return nil
}
if jsonCheck.MatchString(contentType) {
if actualObj, ok := v.(interface{ GetActualInstance() interface{} }); ok { // oneOf, anyOf schemas
if unmarshalObj, ok := actualObj.(interface{ UnmarshalJSON([]byte) error }); ok { // make sure it has UnmarshalJSON defined
if err = unmarshalObj.UnmarshalJSON(b); err != nil {
return err
}
} else {
return fmt.Errorf("unknown type with GetActualInstance but no unmarshalObj.UnmarshalJSON defined")
}
} else if err = json.Unmarshal(b, v); err != nil { // simple model
return err
}
return nil
}
return fmt.Errorf("undefined response type")
}
// Add a file to the multipart request
func addFile(w *multipart.Writer, fieldName, path string) error {
file, err := os.Open(filepath.Clean(path))
if err != nil {
return err
}
err = file.Close()
if err != nil {
return err
}
part, err := w.CreateFormFile(fieldName, filepath.Base(path))
if err != nil {
return err
}
_, err = io.Copy(part, file)
return err
}
// A wrapper for strict JSON decoding
func newStrictDecoder(data []byte) *json.Decoder {
dec := json.NewDecoder(bytes.NewBuffer(data))
dec.DisallowUnknownFields()
return dec
}
// Set request body from an interface{}
func setBody(body interface{}, contentType string) (bodyBuf *bytes.Buffer, err error) {
if bodyBuf == nil {
bodyBuf = &bytes.Buffer{}
}
if reader, ok := body.(io.Reader); ok {
_, err = bodyBuf.ReadFrom(reader)
} else if fp, ok := body.(*os.File); ok {
_, err = bodyBuf.ReadFrom(fp)
} else if b, ok := body.([]byte); ok {
_, err = bodyBuf.Write(b)
} else if s, ok := body.(string); ok {
_, err = bodyBuf.WriteString(s)
} else if s, ok := body.(*string); ok {
_, err = bodyBuf.WriteString(*s)
} else if jsonCheck.MatchString(contentType) {
err = json.NewEncoder(bodyBuf).Encode(body)
} else if xmlCheck.MatchString(contentType) {
err = xml.NewEncoder(bodyBuf).Encode(body)
}
if err != nil {
return nil, err
}
if bodyBuf.Len() == 0 {
err = fmt.Errorf("invalid body type %s", contentType)
return nil, err
}
return bodyBuf, nil
}
// detectContentType method is used to figure out `Request.Body` content type for request header
func detectContentType(body interface{}) string {
contentType := "text/plain; charset=utf-8"
kind := reflect.TypeOf(body).Kind()
switch kind {
case reflect.Struct, reflect.Map, reflect.Ptr:
contentType = "application/json; charset=utf-8"
case reflect.String:
contentType = "text/plain; charset=utf-8"
default:
if b, ok := body.([]byte); ok {
contentType = http.DetectContentType(b)
} else if kind == reflect.Slice {
contentType = "application/json; charset=utf-8"
}
}
return contentType
}
// Ripped from https://github.com/gregjones/httpcache/blob/master/httpcache.go
type cacheControl map[string]string
func parseCacheControl(headers http.Header) cacheControl {
cc := cacheControl{}
ccHeader := headers.Get("Cache-Control")
for _, part := range strings.Split(ccHeader, ",") {
part = strings.Trim(part, " ")
if part == "" {
continue
}
if strings.ContainsRune(part, '=') {
keyval := strings.Split(part, "=")
cc[strings.Trim(keyval[0], " ")] = strings.Trim(keyval[1], ",")
} else {
cc[part] = ""
}
}
return cc
}
// CacheExpires helper function to determine remaining time before repeating a request.
func CacheExpires(r *http.Response) time.Time {
// Figure out when the cache expires.
var expires time.Time
now, err := time.Parse(time.RFC1123, r.Header.Get("date"))
if err != nil {
return time.Now()
}
respCacheControl := parseCacheControl(r.Header)
if maxAge, ok := respCacheControl["max-age"]; ok {
lifetime, err := time.ParseDuration(maxAge + "s")
if err != nil {
expires = now
} else {
expires = now.Add(lifetime)
}
} else {
expiresHeader := r.Header.Get("Expires")
if expiresHeader != "" {
expires, err = time.Parse(time.RFC1123, expiresHeader)
if err != nil {
expires = now
}
}
}
return expires
}
func strlen(s string) int {
return utf8.RuneCountInString(s)
}

View file

@ -1,41 +0,0 @@
/*
PostgreSQL Flex API
This is the documentation for the STACKIT Postgres Flex service
API version: 3alpha1
*/
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
package postgresflexalpha
import (
"github.com/stackitcloud/stackit-sdk-go/core/config"
)
// NewConfiguration returns a new Configuration object
func NewConfiguration() *config.Configuration {
cfg := &config.Configuration{
DefaultHeader: make(map[string]string),
UserAgent: "stackit-sdk-go/postgresflexalpha",
Debug: false,
Servers: config.ServerConfigurations{
{
URL: "https://postgres-flex-service.api.{region}stackit.cloud",
Description: "No description provided",
Variables: map[string]config.ServerVariable{
"region": {
Description: "No description provided",
DefaultValue: "eu01.",
EnumValues: []string{
"eu01.",
},
},
},
},
},
OperationServers: map[string]config.ServerConfigurations{},
}
return cfg
}

Some files were not shown because too many files have changed in this diff Show more