Compare commits
73 commits
chore/ci_t
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 6b5b97ac9a | |||
|
|
29cf260d56 | ||
| 4e217e20a4 | |||
|
|
2f2b5cd04a | ||
| 6c26089930 | |||
| c31a8a787a | |||
| 515b7b1357 | |||
| e6d2d3e10a | |||
| 8fee76f037 | |||
| ebb3ec051d | |||
|
|
e5b2681142 | ||
| e65c74e6e7 | |||
| afde034d64 | |||
|
|
7b911ebf70 | ||
| e320e80956 | |||
|
|
4d96cc8951 | ||
| f9a3d4265c | |||
|
|
1298c3fbf1 | ||
| fa641d29c5 | |||
|
|
dab47d4690 | ||
| a0351798e0 | |||
| f7b022ec6c | |||
|
|
6e3d2b51fa | ||
|
|
9ef7ce9029 | ||
| aac1a2ba17 | |||
| d16b97a8e9 | |||
|
|
edc5e869ce | ||
| 7b2dfaea44 | |||
| 2893a11c0a | |||
| 0b5e15d1c5 | |||
|
|
8a6d932107 | ||
| 956cedef08 | |||
|
|
d5b4e02437 | ||
|
|
bb15293dd3 | ||
|
|
6e6e771631 | ||
|
|
683bc64c12 | ||
|
|
064d2cf1db | ||
|
|
722c46b12d | ||
| 03776cc7fd | |||
| 9060aa9f6a | |||
|
|
5a1dc9cd94 | ||
| d34927537a | |||
|
|
83b0860115 | ||
|
|
97645d7a66 | ||
|
|
94f3dad963 | ||
|
|
c081f5f7bd | ||
|
|
8ab8656b5c | ||
|
|
63435e5e63 | ||
|
|
e974ccf906 | ||
|
|
1fd2df5c76 | ||
|
|
aaabadde1a | ||
|
|
0a5bc30d9c | ||
|
|
8ff6b2a4d8 | ||
| 3dbb04c917 | |||
| a1d1750a79 | |||
| 76af35f27d | |||
| 01deb9022d | |||
|
|
91fe23f5e8 | ||
|
|
4913ff1c3a | ||
| dd77da71dd | |||
|
|
431f6eff8c | ||
|
|
a310d1454a | ||
| 3790894563 | |||
|
|
7d4cbb6b08 | ||
| f173fd54fe | |||
| 1033d7e034 | |||
|
|
635a9abf20 | ||
|
|
07458c5677 | ||
|
|
eb13630d2f | ||
| 4a2819787d | |||
|
|
4cc801a7f3 | ||
|
|
4eff763519 | ||
|
|
2733834fc9 |
213 changed files with 12071 additions and 7964 deletions
260
.github/actions/acc_test/action.yaml
vendored
260
.github/actions/acc_test/action.yaml
vendored
|
|
@ -2,47 +2,104 @@ name: Acceptance Testing
|
|||
description: "Acceptance Testing pipeline"
|
||||
|
||||
inputs:
|
||||
tf_debug:
|
||||
description: "enable terraform debug logs"
|
||||
default: 'false'
|
||||
required: true
|
||||
|
||||
test_timeout_string:
|
||||
description: "string that determines the timeout (default: 45m)"
|
||||
default: '90m'
|
||||
required: true
|
||||
|
||||
go-version:
|
||||
description: "go version to install"
|
||||
default: '1.25'
|
||||
default: '1.26'
|
||||
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:
|
||||
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 }}
|
||||
result:
|
||||
value: ${{ steps.testrun.outputs.result }}
|
||||
description: "the output of the tests"
|
||||
|
||||
status:
|
||||
value: ${{ steps.status.outputs.status }}
|
||||
description: "the status of the tests"
|
||||
|
||||
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-get -y -qq install jq python3 python3-pip python-is-python3 s3cmd git make wget
|
||||
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::"
|
||||
|
||||
# Install latest version of Terraform
|
||||
- uses: hashicorp/setup-terraform@v4
|
||||
with:
|
||||
terraform_wrapper: false
|
||||
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '24.x'
|
||||
|
||||
- name: Setup JAVA
|
||||
uses: actions/setup-java@v5
|
||||
|
|
@ -53,62 +110,173 @@ runs:
|
|||
- name: Install Go ${{ inputs.go-version }}
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: ${{ inputs.go-version }}
|
||||
# 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/golangci/golangci-lint/v2/cmd/golangci-lint@v2.7.2
|
||||
go install github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs@v0.24.0
|
||||
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: Prepare pkg_gen directory
|
||||
- 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: Define service account file path variable
|
||||
id: service_account
|
||||
shell: bash
|
||||
run: |
|
||||
go run cmd/main.go build -p
|
||||
echo "safilepath=${PWD}/stackit/${{ inputs.service_account_json_file_path }}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Run acceptance test file
|
||||
if: ${{ inputs.test_file != '' }}
|
||||
- name: Creating service_account file from json input
|
||||
if: inputs.service_account_json_content != ''
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Running acceptance tests for the terraform provider"
|
||||
echo "${STACKIT_SERVICE_ACCOUNT_JSON}" > ~/.service_account.json
|
||||
cd stackit
|
||||
TF_ACC=1 \
|
||||
TF_ACC_PROJECT_ID=${TF_ACC_PROJECT_ID} \
|
||||
TF_ACC_REGION=${TF_ACC_REGION} \
|
||||
go test ${{ inputs.test_file }} -count=1 -timeout=30m
|
||||
env:
|
||||
STACKIT_SERVICE_ACCOUNT_JSON: ${{ inputs.service_account_json }}
|
||||
TF_PROJECT_ID: ${{ inputs.project_id }}
|
||||
TF_ACC_REGION: ${{ inputs.region }}
|
||||
# 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 }}
|
||||
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 tests
|
||||
if: ${{ inputs.test_file == '' }}
|
||||
id: testrun
|
||||
shell: bash
|
||||
run: |
|
||||
echo "::group::go test"
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
if [[ "${{ inputs.tf_debug }}" == "true" ]]; then
|
||||
TF_LOG=INFO
|
||||
export TF_LOG
|
||||
fi
|
||||
|
||||
testfile="${{ inputs.test_file }}"
|
||||
|
||||
echo "result=no result before run" >> "$GITHUB_OUTPUT"
|
||||
|
||||
echo "Running acceptance tests for the terraform provider"
|
||||
echo "${STACKIT_SERVICE_ACCOUNT_JSON}" > ~/.service_account.json
|
||||
cd stackit
|
||||
|
||||
if [[ -z "$testfile" ]]; then
|
||||
testfile="./..."
|
||||
fi
|
||||
|
||||
if [[ -z "$testfile" ]]; then
|
||||
echo "ERROR: No test file provided"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set +e
|
||||
cd stackit || exit 1
|
||||
TF_ACC=1 \
|
||||
TF_ACC_PROJECT_ID=${TF_ACC_PROJECT_ID} \
|
||||
TF_ACC_REGION=${TF_ACC_REGION} \
|
||||
go test ./... -count=1 -timeout=30m
|
||||
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 -v ${testfile} -timeout=${{ inputs.test_timeout_string }} | tee -a acc_test_run.log
|
||||
set -e
|
||||
|
||||
have_fail=$(cat acc_test_run.log | grep FAIL)
|
||||
if [[ -n $have_fail ]]; then
|
||||
echo "::endgroup::"
|
||||
echo "::group::go test result"
|
||||
echo "Test failed, see acc_test_run.log for details"
|
||||
echo "${have_fail}"
|
||||
echo "result=<b>FAIL:</b> <br />${have_fail}" >> "$GITHUB_OUTPUT"
|
||||
echo "::endgroup::"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "result=no FAIL detected" >> "$GITHUB_OUTPUT"
|
||||
echo "::endgroup::"
|
||||
env:
|
||||
STACKIT_SERVICE_ACCOUNT_JSON: ${{ inputs.service_account_json }}
|
||||
TF_PROJECT_ID: ${{ inputs.project_id }}
|
||||
TF_ACC_PROJECT_ID: ${{ inputs.project_id }}
|
||||
TF_ACC_REGION: ${{ inputs.region }}
|
||||
# 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 }}
|
||||
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: Set status output variable
|
||||
if: always()
|
||||
id: status
|
||||
shell: bash
|
||||
run: |
|
||||
echo "status=${{ steps.testrun.outcome == 'success' && 'SUCCESS' || 'FAILURE' }}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Upload test log artifact
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: acc_test.log
|
||||
path: "stackit/acc_test_run.log"
|
||||
|
|
|
|||
56
.github/actions/build/action.yaml
vendored
56
.github/actions/build/action.yaml
vendored
|
|
@ -3,7 +3,7 @@ description: "Build pipeline"
|
|||
inputs:
|
||||
go-version:
|
||||
description: "Go version to install"
|
||||
default: '1.25'
|
||||
default: '1.26'
|
||||
required: true
|
||||
java-distribution:
|
||||
description: "JAVA distribution to use (default: temurin)"
|
||||
|
|
@ -20,25 +20,63 @@ runs:
|
|||
run: |
|
||||
set -e
|
||||
apt-get -y -qq update
|
||||
apt-get -y -qq install jq python3 python3-pip python-is-python3 s3cmd git make wget
|
||||
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 }}
|
||||
# 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@v0.24.0
|
||||
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
|
||||
|
|
@ -46,16 +84,6 @@ runs:
|
|||
distribution: ${{ inputs.java-distribution }} # See 'Supported distributions' for available options
|
||||
java-version: ${{ inputs.java-version }}
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Run build pkg directory
|
||||
shell: bash
|
||||
run: |
|
||||
set -e
|
||||
go run cmd/main.go build
|
||||
|
||||
|
||||
- name: Run make to build app
|
||||
shell: bash
|
||||
run: |
|
||||
|
|
|
|||
1
.github/actions/clean_up/README.md
vendored
Normal file
1
.github/actions/clean_up/README.md
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
# acceptance test action
|
||||
227
.github/actions/clean_up/action.yaml
vendored
Normal file
227
.github/actions/clean_up/action.yaml
vendored
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
name: CleanUp Project Resources
|
||||
description: "Acceptance Testing CleanUp"
|
||||
|
||||
inputs:
|
||||
project_id:
|
||||
description: "STACKIT project ID for tests"
|
||||
required: true
|
||||
|
||||
region:
|
||||
description: "STACKIT region for tests"
|
||||
default: 'eu01'
|
||||
required: true
|
||||
|
||||
tf_resource_prefix:
|
||||
description: "prefix in resource names"
|
||||
default: 'tf-acc-'
|
||||
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: ''
|
||||
|
||||
list_only:
|
||||
description: "only list resources, DO NOT delete"
|
||||
required: true
|
||||
default: 'true'
|
||||
|
||||
log_level:
|
||||
description: "Log Level"
|
||||
required: true
|
||||
default: 'warning'
|
||||
|
||||
outputs:
|
||||
cli-version:
|
||||
description: "stackit cli version"
|
||||
value: ${{ steps.stackit_version.outputs.version }}
|
||||
|
||||
pre_count:
|
||||
description: "number of resources found"
|
||||
value: ${{ steps.retrieve_pre.outputs.count }}
|
||||
|
||||
post_count:
|
||||
description: "number of resources found"
|
||||
value: ${{ steps.retrieve_post.outputs.count }}
|
||||
|
||||
status:
|
||||
description: "status of the test"
|
||||
value: ${{ steps.status.outputs.status }}
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- 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 curl gnupg jq >apt_get.log 2>apt_get_err.log
|
||||
if [ $? -ne 0 ]; then
|
||||
cat apt_get.log apt_get_err.log
|
||||
fi
|
||||
echo "::endgroup::"
|
||||
|
||||
echo "::group::apt add source"
|
||||
curl https://packages.stackit.cloud/keys/key.gpg | gpg --dearmor -o /usr/share/keyrings/stackit.gpg
|
||||
echo "deb [signed-by=/usr/share/keyrings/stackit.gpg] https://packages.stackit.cloud/apt/cli stackit main" | tee -a /etc/apt/sources.list.d/stackit.list
|
||||
echo "::endgroup::"
|
||||
|
||||
echo "::group::apt install stackit cli"
|
||||
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 stackit >apt_get.log 2>apt_get_err.log
|
||||
if [ $? -ne 0 ]; then
|
||||
cat apt_get.log apt_get_err.log
|
||||
fi
|
||||
echo "::endgroup::"
|
||||
|
||||
- name: Check stackit cli version
|
||||
id: stackit_version
|
||||
run: |
|
||||
set -e
|
||||
VERSION=$(stackit --version | grep "Version:" | cut -d " " -f 2)
|
||||
echo "stackit cli version: ${VERSION}"
|
||||
echo "version=${VERSION}" >> $GITHUB_OUTPUT
|
||||
shell: bash
|
||||
|
||||
- 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
|
||||
|
||||
echo "${{ inputs.service_account_json_content }}" > .svc_acc.json
|
||||
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
|
||||
|
||||
echo "${{ inputs.service_account_json_content_b64 }}" | base64 -d > .svc_acc.json
|
||||
echo "::endgroup::"
|
||||
|
||||
- name: Check service account file exists
|
||||
shell: bash
|
||||
run: |
|
||||
set -e
|
||||
if [[ ! -s .svc_acc.json ]]; then
|
||||
echo "ERROR: service account file missing or empty"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Retrieve resources before
|
||||
id: retrieve_pre
|
||||
run: |
|
||||
echo "::group::retrieve resources"
|
||||
set -e
|
||||
echo "authenticating api"
|
||||
STACKIT_SERVICE_ACCOUNT_KEY_PATH="${PWD}/.svc_acc.json"
|
||||
export STACKIT_SERVICE_ACCOUNT_KEY_PATH
|
||||
stackit auth activate-service-account --service-account-key-path .svc_acc.json
|
||||
|
||||
echo "SQL Server Flex resources:"
|
||||
sql_res=$(stackit --verbosity ${{ inputs.log_level }} --project-id "${{ inputs.project_id }}" beta sqlserverflex instance list --output-format json | jq -r '.[] | select(.name | startswith("${{ inputs.tf_resource_prefix }}"))')
|
||||
sql_count=$(echo "$sql_res" | jq -r '.id' | wc -l)
|
||||
|
||||
echo "PostgreSQL Flex resources:"
|
||||
pg_res=$(stackit --verbosity ${{ inputs.log_level }} --project-id "${{ inputs.project_id }}" postgresflex instance list --output-format json | jq -r '.[] | select(.name | startswith("${{ inputs.tf_resource_prefix }}"))')
|
||||
pg_count=$(echo "$pg_res" | jq -r '.id' | wc -l)
|
||||
|
||||
echo "Number of resources found: ${sql_count} SQL Server Flex, ${pg_count} PostgreSQL Flex"
|
||||
echo "count=$(( ${pg_count} + ${sql_count} ))" >> $GITHUB_OUTPUT
|
||||
echo "::endgroup::"
|
||||
shell: bash
|
||||
|
||||
- name: Delete SQL Server Flex resources
|
||||
if: ${{ inputs.list_only != 'true' }}
|
||||
id: del_sql
|
||||
run: |
|
||||
echo "::group::delete SQL Server Flex resources"
|
||||
stackit --verbosity ${{ inputs.log_level }} auth activate-service-account --service-account-key-path .svc_acc.json
|
||||
for s in $(stackit --verbosity ${{ inputs.log_level }} --project-id ${{ inputs.project_id }} beta sqlserverflex instance list --output-format json | jq -r '.[] | select(.name | startswith("${{ inputs.tf_resource_prefix }}")) | .id');
|
||||
do
|
||||
stackit --verbosity ${{ inputs.log_level }} -y --project-id ${{ inputs.project_id }} beta sqlserverflex instance delete $s || echo "status=FAILURE" >> ${GITHUB_OUTPUT};
|
||||
done
|
||||
echo "::endgroup::"
|
||||
shell: bash
|
||||
|
||||
- name: Skip Delete SQL Server Flex resources
|
||||
if: ${{ inputs.list_only == 'true' }}
|
||||
run: |
|
||||
set -e
|
||||
echo "Skip deleting: list only mode"
|
||||
shell: bash
|
||||
|
||||
- name: Delete PostgreSQL Flex resources
|
||||
if: ${{ inputs.list_only != 'true' }}
|
||||
id: del_pg
|
||||
run: |
|
||||
echo "::group::delete PostgreSQL Flex resources"
|
||||
stackit auth activate-service-account --service-account-key-path .svc_acc.json
|
||||
for s in $(stackit --verbosity ${{ inputs.log_level }} --project-id ${{ inputs.project_id }} postgresflex instance list --output-format json | jq -r '.[] | select(.name | startswith("${{ inputs.tf_resource_prefix }}")) | .id');
|
||||
do
|
||||
stackit --verbosity ${{ inputs.log_level }} -y --project-id ${{ inputs.project_id }} postgresflex instance delete "$s" --force || echo "status=FAILURE" >> ${GITHUB_OUTPUT};
|
||||
done
|
||||
echo "::endgroup::"
|
||||
shell: bash
|
||||
|
||||
- name: Skip Delete PostgreSQL Flex resources
|
||||
if: ${{ inputs.list_only == 'true' }}
|
||||
run: |
|
||||
set -e
|
||||
echo "Skip deleting: list only mode"
|
||||
shell: bash
|
||||
|
||||
- name: Retrieve resources after
|
||||
id: retrieve_post
|
||||
run: |
|
||||
echo "::group::retrieve resources"
|
||||
set -e
|
||||
echo "authenticating api"
|
||||
STACKIT_SERVICE_ACCOUNT_KEY_PATH="${PWD}/.svc_acc.json"
|
||||
export STACKIT_SERVICE_ACCOUNT_KEY_PATH
|
||||
stackit auth activate-service-account --service-account-key-path .svc_acc.json
|
||||
|
||||
echo "SQL Server Flex resources:"
|
||||
sql_res=$(stackit --verbosity ${{ inputs.log_level }} --project-id "${{ inputs.project_id }}" beta sqlserverflex instance list --output-format json | jq -r '.[] | select(.name | startswith("${{ inputs.tf_resource_prefix }}"))')
|
||||
sql_count=$(echo "$sql_res" | jq -r '.id' | wc -l)
|
||||
|
||||
echo "PostgreSQL Flex resources:"
|
||||
pg_res=$(stackit --verbosity ${{ inputs.log_level }} --project-id "${{ inputs.project_id }}" postgresflex instance list --output-format json | jq -r '.[] | select(.name | startswith("${{ inputs.tf_resource_prefix }}"))')
|
||||
pg_count=$(echo "$pg_res" | jq -r '.id' | wc -l)
|
||||
|
||||
echo "Number of resources found: ${sql_count} SQL Server Flex, ${pg_count} PostgreSQL Flex"
|
||||
echo "count=$(( ${pg_count} + ${sql_count} ))" >> $GITHUB_OUTPUT
|
||||
echo "::endgroup::"
|
||||
shell: bash
|
||||
|
||||
- name: Set status
|
||||
if: always()
|
||||
id: status
|
||||
run: |
|
||||
status="SUCCESS"
|
||||
if [[ "${{ steps.del_pg.outputs.status }}" == "FAILURE" ]]; then
|
||||
status=FAILURE"
|
||||
elif [[ "${{ steps.del_sql.outputs.status }}" == "FAILURE" ]]; then
|
||||
status=FAILURE"
|
||||
fi
|
||||
echo "status=$status" >> $GITHUB_OUTPUT
|
||||
shell: bash
|
||||
148
.github/actions/notify/action.yaml
vendored
Normal file
148
.github/actions/notify/action.yaml
vendored
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
name: Send notification via Google Chat
|
||||
description: "Sends a notification to a Google Chat room when a pull request is opened."
|
||||
|
||||
inputs:
|
||||
webhook_url:
|
||||
description: "The URL of the Google Chat webhook."
|
||||
required: true
|
||||
|
||||
title:
|
||||
description: "The title of the notification."
|
||||
required: true
|
||||
|
||||
subtitle:
|
||||
description: "The subtitle of the notification."
|
||||
default: 'no subtitle provided'
|
||||
|
||||
image_slug:
|
||||
description: "The slug of the image to be included in the notification."
|
||||
default: 'git'
|
||||
|
||||
event_author:
|
||||
description: "The author of the event."
|
||||
default: 'unknown'
|
||||
|
||||
event_title:
|
||||
description: "The title of the event."
|
||||
required: true
|
||||
|
||||
event_body:
|
||||
description: "The body of the event."
|
||||
default: 'no body provided'
|
||||
|
||||
event_number:
|
||||
description: "The number of the event."
|
||||
default: 'no number provided'
|
||||
|
||||
event_url:
|
||||
description: "The url of the event."
|
||||
default: 'none'
|
||||
|
||||
status:
|
||||
description: "The status of the event."
|
||||
default: 'UNKNOWN'
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Install prerequisites
|
||||
shell: bash
|
||||
run: |
|
||||
echo "::group::apt install"
|
||||
set -e
|
||||
apt update
|
||||
apt install -y curl jq
|
||||
echo "::endgroup::"
|
||||
|
||||
- name: Determine status color
|
||||
id: status
|
||||
shell: bash
|
||||
run: |
|
||||
case "${{ inputs.status }}" in
|
||||
SUCCESS)
|
||||
STATUS_COLOR="006400/228b22"
|
||||
ADD='{"decoratedText": {"startIcon": {"materialIcon": {"name": "check_circle"}},"text": "<b style=\"color: green;\">SUCCESS</b>"}},'
|
||||
;;
|
||||
FAILURE)
|
||||
STATUS_COLOR="8b0000/dc143c"
|
||||
ADD='{"decoratedText": {"startIcon": {"materialIcon": {"name": "stop_circle"}},"text": "<b style=\"color: red;\">FAILURE</b>"}},'
|
||||
;;
|
||||
*)
|
||||
STATUS_COLOR="483d8b/6495ed"
|
||||
ADD=''
|
||||
;;
|
||||
esac
|
||||
echo "color=${STATUS_COLOR}" >> "$GITHUB_OUTPUT"
|
||||
echo "status_add=${ADD}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Notify via Google Chat Webhook
|
||||
shell: bash
|
||||
env:
|
||||
WEBHOOK: ${{ inputs.webhook_url }}
|
||||
run: |
|
||||
set -e
|
||||
|
||||
PAYLOAD=$(jq -n -r \
|
||||
--arg header "${{ inputs.title }}" \
|
||||
--arg subtitle "${{ inputs.subtitle }}" \
|
||||
--arg imgurl "https://cdn.simpleicons.org/${{ inputs.image_slug }}/${{ steps.status.outputs.color }}" \
|
||||
--arg title "${{ inputs.event_title || 'no event title given' }}" \
|
||||
--arg body "${{ inputs.event_body || 'no event body given' }}" \
|
||||
--arg author "${{ inputs.event_author || 'no event author given' }}" \
|
||||
--arg url "${{ inputs.event_url || github.repositoryUrl || github.server_url }}" \
|
||||
'{ "cardsV2": [ { "cardId": "notify-${{ github.run_id }}", "card": {
|
||||
"header": {
|
||||
"title": "\($header)",
|
||||
"subtitle": "\($subtitle)",
|
||||
"imageUrl": "\($imgurl)",
|
||||
"imageType": "SQUARE"
|
||||
},
|
||||
"sections": [
|
||||
{
|
||||
"header": "\($title)",
|
||||
"collapsible": false,
|
||||
"widgets": [
|
||||
${{ steps.status.outputs.status_add }}
|
||||
{
|
||||
"decoratedText": {
|
||||
"startIcon": {
|
||||
"knownIcon": "PERSON"
|
||||
},
|
||||
"text": "<b>\($author)</b>"
|
||||
}
|
||||
},
|
||||
{
|
||||
"textParagraph": {
|
||||
"text": "\($body)",
|
||||
"maxLines": 2
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"widgets": [
|
||||
{
|
||||
"buttonList": {
|
||||
"buttons": [
|
||||
{
|
||||
"text": "View Source Event",
|
||||
"type": "FILLED",
|
||||
"onClick": {
|
||||
"openLink": {
|
||||
"url": "\($url)"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}} ] }')
|
||||
|
||||
curl \
|
||||
-X POST \
|
||||
-H 'Content-Type: application/json' \
|
||||
"${{ inputs.webhook_url }}&threadKey=run${{ github.run_id }}&messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD" \
|
||||
-d "${PAYLOAD}"
|
||||
6
.github/actions/setup-cache-go/action.yaml
vendored
6
.github/actions/setup-cache-go/action.yaml
vendored
|
|
@ -10,7 +10,7 @@ inputs:
|
|||
|
||||
go-version:
|
||||
description: "go version to install"
|
||||
default: '1.25'
|
||||
default: '1.26'
|
||||
required: true
|
||||
|
||||
runs:
|
||||
|
|
@ -26,9 +26,9 @@ runs:
|
|||
uses: https://code.forgejo.org/actions/setup-go@v6
|
||||
id: go-version
|
||||
with:
|
||||
go-version: ${{ inputs.go-version }}
|
||||
# go-version: ${{ inputs.go-version }}
|
||||
check-latest: true # Always check for the latest patch release
|
||||
# go-version-file: "go.mod"
|
||||
go-version-file: "go.mod"
|
||||
# do not cache dependencies, we do this manually
|
||||
cache: false
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,39 @@ env:
|
|||
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
|
||||
|
|
@ -142,7 +175,6 @@ jobs:
|
|||
- name: Acceptance Testing
|
||||
env:
|
||||
TF_ACC: "1"
|
||||
TF_ACC_SERVICE_ACCOUNT_FILE: "~/service_account.json"
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
run: make test-acceptance-tf
|
||||
|
||||
|
|
@ -171,12 +203,12 @@ jobs:
|
|||
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:
|
||||
|
|
@ -201,30 +233,30 @@ jobs:
|
|||
- 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 }}"
|
||||
# - 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' }}
|
||||
367
.github/workflows/ci_new.yaml
vendored
Normal file
367
.github/workflows/ci_new.yaml
vendored
Normal file
|
|
@ -0,0 +1,367 @@
|
|||
name: CI Workflow
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [ opened, synchronize, reopened ]
|
||||
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: stackit-docker
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Notify
|
||||
if: always()
|
||||
uses: ./.github/actions/notify
|
||||
with:
|
||||
webhook_url: ${{ secrets.GOOGLE_WEBHOOK_URL }}
|
||||
title: "[START] CI pipeline (#${{ forgejo.run_number }})"
|
||||
subtitle: "${{ forgejo.event_name }} on ${{ forgejo.ref_name }}"
|
||||
event_title: "${{ forgejo.event_name }} for ${{ forgejo.repository }}"
|
||||
event_author: ${{ forgejo.actor }}
|
||||
event_body: "${{ forgejo.event_name }} on ${{ forgejo.ref }} for ${{ forgejo.repository }}"
|
||||
event_number: ${{ forgejo.run_number }}
|
||||
event_url: "https://tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/actions/runs/${{ forgejo.run_number }}"
|
||||
|
||||
- name: Check GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v7
|
||||
with:
|
||||
args: check
|
||||
|
||||
prepare:
|
||||
name: Prepare GO cache
|
||||
runs-on: stackit-docker
|
||||
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: stackit-docker
|
||||
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: stackit-docker
|
||||
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
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
run: |
|
||||
unset TF_ACC
|
||||
TF_ACC_SERVICE_ACCOUNT_FILE=~/.service_account.json
|
||||
export TF_ACC_SERVICE_ACCOUNT_FILE
|
||||
make test
|
||||
|
||||
- name: Testing with coverage
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
run: |
|
||||
unset TF_ACC
|
||||
TF_ACC_SERVICE_ACCOUNT_FILE=~/.service_account.json
|
||||
export TF_ACC_SERVICE_ACCOUNT_FILE
|
||||
make coverage
|
||||
|
||||
# - 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 Acceptance 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: stackit-docker
|
||||
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: stackit-docker
|
||||
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'
|
||||
72
.github/workflows/clean_up.yaml
vendored
Normal file
72
.github/workflows/clean_up.yaml
vendored
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
name: TF Acceptance Test CleanUp
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
list_only:
|
||||
description: "only list resources"
|
||||
type: boolean
|
||||
default: true
|
||||
required: true
|
||||
|
||||
res_prefix:
|
||||
description: "resource name prefix"
|
||||
type: string
|
||||
default: 'tf-acc-'
|
||||
required: true
|
||||
|
||||
log_level:
|
||||
description: 'Log Level'
|
||||
required: true
|
||||
default: 'warning'
|
||||
type: choice
|
||||
options:
|
||||
- info
|
||||
- warning
|
||||
- debug
|
||||
- error
|
||||
|
||||
jobs:
|
||||
clean:
|
||||
name: Clean up
|
||||
runs-on: stackit-docker
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Notify
|
||||
uses: ./.github/actions/notify
|
||||
with:
|
||||
webhook_url: ${{ secrets.GOOGLE_WEBHOOK_URL }}
|
||||
title: "[START] CLEAN UP pipeline (#${{ forgejo.run_number }})"
|
||||
subtitle: "${{ forgejo.repository }}"
|
||||
event_title: ${{ forgejo.event_name }}
|
||||
event_author: ${{ forgejo.actor }}
|
||||
event_body: "try to remove all resources with prefix <b>${{ inputs.res_prefix }}</b>"
|
||||
event_number: ${{ forgejo.run_number }}
|
||||
event_url: "https://tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/actions/runs/${{ forgejo.run_number }}"
|
||||
|
||||
- name: Clean
|
||||
id: clean
|
||||
uses: ./.github/actions/clean_up
|
||||
with:
|
||||
project_id: ${{ vars.TF_ACC_PROJECT_ID }}
|
||||
region: 'eu01'
|
||||
tf_resource_prefix: ${{ inputs.res_prefix }}
|
||||
service_account_json_content_b64: "${{ secrets.TF_ACC_SERVICE_ACCOUNT_JSON_B64 }}"
|
||||
list_only: ${{ inputs.list_only }}
|
||||
log_level: ${{ inputs.log_level }}
|
||||
|
||||
- name: Notify
|
||||
if: always()
|
||||
uses: ./.github/actions/notify
|
||||
with:
|
||||
webhook_url: ${{ secrets.GOOGLE_WEBHOOK_URL }}
|
||||
title: "[END] CLEAN UP pipeline (#${{ forgejo.run_number }})"
|
||||
subtitle: "${{ forgejo.repository }}"
|
||||
event_title: ${{ forgejo.event_name }}
|
||||
event_author: ${{ forgejo.actor }}
|
||||
event_body: "count before cleaning: ${{ steps.clean.outputs.pre_count }} <br /> count after cleaning: ${{ steps.clean.outputs.post_count }}"
|
||||
event_number: ${{ forgejo.run_number }}
|
||||
event_url: "https://tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/actions/runs/${{ forgejo.run_number }}"
|
||||
status: ${{ steps.clean.outcome == 'success' && 'SUCCESS' || 'FAILURE' }}
|
||||
25
.github/workflows/notify_pr.yaml
vendored
Normal file
25
.github/workflows/notify_pr.yaml
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
name: Notify on new PR
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
|
||||
jobs:
|
||||
notify:
|
||||
name: Notify via Google Chat
|
||||
runs-on: stackit-docker
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Notify
|
||||
uses: ./.github/actions/notify
|
||||
with:
|
||||
webhook_url: ${{ secrets.GOOGLE_WEBHOOK_URL }}
|
||||
title: "New Pull Request"
|
||||
event_title: "${{ github.event.pull_request.title }}"
|
||||
event_author: "${{ github.event.pull_request.user.login }}"
|
||||
event_body: "${{ github.event.pull_request.body || 'No description provided.' }}"
|
||||
event_number: "${{ github.event.pull_request.number }}"
|
||||
event_url: "${{ github.event.pull_request.html_url }}"
|
||||
88
.github/workflows/publish.yaml
vendored
88
.github/workflows/publish.yaml
vendored
|
|
@ -4,9 +4,10 @@ run-name: Publish by @${{ github.actor }}
|
|||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
push:
|
||||
tags:
|
||||
- 'v0.*'
|
||||
- 'v*'
|
||||
|
||||
env:
|
||||
GO_VERSION: "1.25"
|
||||
|
|
@ -16,26 +17,26 @@ env:
|
|||
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
|
||||
with:
|
||||
fetch-tags: true
|
||||
|
||||
- name: Check GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v6
|
||||
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.
|
||||
contents: write # Required to checkout repository.
|
||||
pull-requests: write # Required to add PR comment.
|
||||
steps:
|
||||
- name: Install needed tools
|
||||
|
|
@ -43,10 +44,29 @@ jobs:
|
|||
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
|
||||
with:
|
||||
fetch-tags: true
|
||||
|
||||
- name: Notify
|
||||
uses: ./.github/actions/notify
|
||||
with:
|
||||
webhook_url: ${{ secrets.GOOGLE_WEBHOOK_URL }}
|
||||
title: "[START] Publish (#${{ forgejo.run_number }})"
|
||||
subtitle: "${{ forgejo.event_name }} on branch ${{ forgejo.ref }}"
|
||||
event_title: "run started"
|
||||
event_author: ${{ forgejo.actor }}
|
||||
event_body: ""
|
||||
event_number: ${{ forgejo.event.id }}
|
||||
event_url: "https://tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/actions/runs/${{ forgejo.run_number }}"
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
# go-version: ${{ env.GO_VERSION }}
|
||||
check-latest: true
|
||||
go-version-file: 'go.mod'
|
||||
|
||||
- name: Install go tools
|
||||
run: |
|
||||
|
|
@ -60,16 +80,6 @@ jobs:
|
|||
distribution: 'temurin' # See 'Supported distributions' for available options
|
||||
java-version: '21'
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Run build pkg directory
|
||||
run: |
|
||||
set -e
|
||||
mkdir -p generated/services
|
||||
mkdir -p generated/internal/services
|
||||
go run cmd/main.go build
|
||||
|
||||
- name: Set up s3cfg
|
||||
run: |
|
||||
cat <<'EOF' >> ~/.s3cfg
|
||||
|
|
@ -87,15 +97,16 @@ jobs:
|
|||
gpg --import ~/private.key.pem
|
||||
rm ~/private.key.pem
|
||||
|
||||
- name: Run GoReleaser with 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@v6
|
||||
uses: goreleaser/goreleaser-action@v7
|
||||
with:
|
||||
args: release --skip publish --clean --snapshot
|
||||
# args: release --skip publish --clean --snapshot
|
||||
args: release --skip publish --clean
|
||||
|
||||
- name: Run GoReleaser
|
||||
if: github.event_name != 'workflow_dispatch'
|
||||
|
|
@ -103,7 +114,7 @@ jobs:
|
|||
env:
|
||||
GITHUB_TOKEN: ${{ env.FORGEJO_TOKEN }}
|
||||
GPG_FINGERPRINT: ${{ secrets.GPG_FINGERPRINT }}
|
||||
uses: goreleaser/goreleaser-action@v6
|
||||
uses: goreleaser/goreleaser-action@v7
|
||||
with:
|
||||
args: release --skip publish --clean
|
||||
|
||||
|
|
@ -111,10 +122,16 @@ jobs:
|
|||
run: |
|
||||
echo "${{ secrets.PUBLIC_KEY_PEM }}" >public_key.pem
|
||||
|
||||
- name: Determine version
|
||||
id: get_version
|
||||
run: |
|
||||
set -e
|
||||
VERSION=$(jq -r .version < dist/metadata.json)
|
||||
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Prepare provider directory structure
|
||||
run: |
|
||||
VERSION=$(jq -r .version < dist/metadata.json)
|
||||
go run cmd/main.go \
|
||||
go run generator/main.go \
|
||||
publish \
|
||||
--namespace=mhenselin \
|
||||
--providerName=stackitprivatepreview \
|
||||
|
|
@ -122,9 +139,16 @@ jobs:
|
|||
--domain=tfregistry.sysops.stackit.rocks \
|
||||
--gpgFingerprint="${{ secrets.GPG_FINGERPRINT }}" \
|
||||
--gpgPubKeyFile=public_key.pem \
|
||||
--version=${VERSION}
|
||||
--version=${{ steps.get_version.outputs.version }}
|
||||
|
||||
- name: Prepare documentation nav file
|
||||
run: |
|
||||
go run generator/main.go \
|
||||
docs \
|
||||
--outFile nav.md
|
||||
|
||||
- name: Publish provider to S3
|
||||
id: publish_to_s3
|
||||
run: |
|
||||
set -e
|
||||
cd release/
|
||||
|
|
@ -141,5 +165,21 @@ jobs:
|
|||
run: |
|
||||
set -e
|
||||
ssh -o StrictHostKeyChecking=no ubuntu@${{ vars.DOCS_SERVER_IP }} 'rm -rf /srv/www/docs'
|
||||
echo "${{ github.ref_name }}" >docs/_version.txt
|
||||
echo "${{ steps.get_version.outputs.version }}" >docs/_version.txt
|
||||
# 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/
|
||||
|
||||
- name: Notify
|
||||
if: always()
|
||||
uses: ./.github/actions/notify
|
||||
with:
|
||||
webhook_url: ${{ secrets.GOOGLE_WEBHOOK_URL }}
|
||||
title: "[END] Publish (#${{ forgejo.run_number }})"
|
||||
subtitle: "${{ forgejo.event_name }} on branch ${{ forgejo.ref }}"
|
||||
event_title: "released: ${{ steps.get_version.outputs.version }}"
|
||||
event_author: ${{ forgejo.actor }}
|
||||
event_body: ""
|
||||
event_number: ${{ forgejo.event.id }}
|
||||
event_url: "https://tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/actions/runs/${{ forgejo.run_number }}"
|
||||
status: "${{ steps.publish_to_s3.outcome == 'success' && 'SUCCESS' || 'FAILURE' }}"
|
||||
|
|
|
|||
8
.github/workflows/release.yaml
vendored
8
.github/workflows/release.yaml
vendored
|
|
@ -16,23 +16,25 @@ permissions:
|
|||
|
||||
jobs:
|
||||
goreleaser:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: stackit-docker
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
# Allow goreleaser to access older tag information.
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-go@v5
|
||||
|
||||
- uses: 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:
|
||||
|
|
|
|||
8
.github/workflows/renovate.yaml
vendored
8
.github/workflows/renovate.yaml
vendored
|
|
@ -8,12 +8,14 @@ on:
|
|||
jobs:
|
||||
renovate:
|
||||
name: Renovate
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: stackit-docker
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Self-hosted Renovate
|
||||
uses: renovatebot/github-action@v41.0.0
|
||||
uses: renovatebot/github-action@v46.1.5
|
||||
with:
|
||||
configurationFile: .github/renovate.json
|
||||
token: ${{ secrets.RENOVATE_TOKEN }}
|
||||
# token: ${{ secrets.RENOVATE_TOKEN }}
|
||||
token: ${{ env.FORGEJO_TOKEN }}
|
||||
|
|
|
|||
29
.github/workflows/runnerstats.yaml
vendored
Normal file
29
.github/workflows/runnerstats.yaml
vendored
Normal 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
|
||||
2
.github/workflows/stale.yaml
vendored
2
.github/workflows/stale.yaml
vendored
|
|
@ -20,7 +20,7 @@ permissions:
|
|||
jobs:
|
||||
stale:
|
||||
name: "Stale"
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: stackit-docker
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- name: "Mark old PRs as stale"
|
||||
|
|
|
|||
112
.github/workflows/tf-acc-test.yaml
vendored
112
.github/workflows/tf-acc-test.yaml
vendored
|
|
@ -1,23 +1,127 @@
|
|||
name: TF Acceptance Tests Workflow
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
branches:
|
||||
- alpha
|
||||
- main
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
enable_debug:
|
||||
description: "enable terraform debug logs"
|
||||
type: boolean
|
||||
default: false
|
||||
required: true
|
||||
|
||||
test_timeout_string:
|
||||
description: "string that determines the timeout (default: '120m')"
|
||||
type: string
|
||||
default: '120m'
|
||||
required: true
|
||||
|
||||
test_file:
|
||||
description: "string that determines the test file to run (default all tests)"
|
||||
type: choice
|
||||
options:
|
||||
- tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/wait/postgresflexalpha
|
||||
- tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha
|
||||
- tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/wait/sqlserverflexbeta
|
||||
- tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexbeta
|
||||
default: ''
|
||||
|
||||
jobs:
|
||||
acc_test:
|
||||
name: Acceptance Tests
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: stackit-docker
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Run Test
|
||||
- name: set start time
|
||||
id: start_time
|
||||
continue-on-error: true
|
||||
run: |
|
||||
time=$(date --rfc-3339=ns)
|
||||
echo "start_time=$time" >> ${GITHUB_OUTPUT}
|
||||
start=$(date +%s%N)
|
||||
echo "start=$start" >> ${GITHUB_OUTPUT}
|
||||
|
||||
- name: Notify
|
||||
uses: ./.github/actions/notify
|
||||
with:
|
||||
webhook_url: ${{ secrets.GOOGLE_WEBHOOK_URL }}
|
||||
title: "[START] Terraform Acceptance Tests (#${{ forgejo.run_number }})"
|
||||
subtitle: "${{ forgejo.event_name }} on branch ${{ forgejo.ref }}"
|
||||
event_title: "started: ${{ steps.start_time.outputs.start_time }}"
|
||||
event_author: ${{ forgejo.actor }}
|
||||
event_body: ${{ inputs.test_file }}
|
||||
event_number: ${{ forgejo.run_number }}
|
||||
event_url: "https://tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/actions/runs/${{ forgejo.run_number }}"
|
||||
|
||||
- name: Run Test (workflow dispatch)
|
||||
if: ${{ forgejo.event_name == 'workflow_dispatch' }}
|
||||
id: manual_run
|
||||
continue-on-error: true
|
||||
uses: ./.github/actions/acc_test
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
project_id: ${{ vars.TEST_PROJECT_ID }}
|
||||
project_id: ${{ vars.TF_ACC_PROJECT_ID }}
|
||||
region: 'eu01'
|
||||
service_account_json: ${{ secrets.TF_ACC_SERVICE_ACCOUNT_JSON }}
|
||||
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 }}
|
||||
tf_debug: ${{ inputs.enable_debug }}
|
||||
test_timeout_string: ${{ inputs.test_timeout_string }}
|
||||
test_file: ${{ inputs.test_file }}
|
||||
|
||||
- name: Run Test (automatic)
|
||||
if: ${{ forgejo.event_name != 'workflow_dispatch' }}
|
||||
id: automatic_run
|
||||
continue-on-error: true
|
||||
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 }}
|
||||
|
||||
- name: set end time
|
||||
id: end_time
|
||||
continue-on-error: true
|
||||
run: |
|
||||
set -e
|
||||
echo "auto status: ${{ steps.automatic_run.outputs.status }}"
|
||||
echo "manual status: ${{ steps.manual_run.outputs.status }}"
|
||||
echo "status: ${{ forgejo.event_name == 'workflow_dispatch' && steps.manual_run.outputs.status || steps.automatic_run.outputs.status }}"
|
||||
echo "end_time=$(date --rfc-3339=ns)" >> ${GITHUB_OUTPUT}
|
||||
end=$(date +%s%N)
|
||||
echo "end=${end}" >> ${GITHUB_OUTPUT}
|
||||
start=${{ steps.start_time.outputs.start }}
|
||||
diff=$((end-start))
|
||||
duration=$(printf "%s.%s" "${diff:0: -9}" "${diff: -9:3}")
|
||||
echo "duration=${duration}" >> ${GITHUB_OUTPUT}
|
||||
|
||||
- name: Notify
|
||||
uses: ./.github/actions/notify
|
||||
with:
|
||||
webhook_url: ${{ secrets.GOOGLE_WEBHOOK_URL }}
|
||||
title: "[END] Terraform Acceptance Tests (#${{ forgejo.run_number }})"
|
||||
subtitle: "${{ forgejo.event_name }} on branch ${{ forgejo.ref }} with status: ${{ forgejo.event_name == 'workflow_dispatch' && steps.manual_run.outputs.status || steps.automatic_run.outputs.status }}"
|
||||
event_title: "run ended: ${{ steps.end_time.outputs.end_time }}, duration: ${{ steps.end_time.outputs.duration }} seconds"
|
||||
event_author: ${{ forgejo.actor }}
|
||||
event_body: "${{ forgejo.event_name == 'workflow_dispatch' && steps.manual_run.outputs.result || steps.automatic_run.outputs.result }}"
|
||||
event_number: ${{ forgejo.event.id }}
|
||||
event_url: "https://tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/actions/runs/${{ forgejo.run_number }}"
|
||||
status: "${{ forgejo.event_name == 'workflow_dispatch' && steps.manual_run.outputs.status || steps.automatic_run.outputs.status }}"
|
||||
|
|
|
|||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -40,6 +40,7 @@ coverage.out
|
|||
coverage.html
|
||||
generated
|
||||
stackit-sdk-generator
|
||||
stackit-sdk-generator/**
|
||||
dist
|
||||
|
||||
.secrets
|
||||
|
|
|
|||
91
.golang-ci.yaml
Normal file
91
.golang-ci.yaml
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
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: original
|
||||
allow: []
|
||||
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:
|
||||
- generator/
|
||||
- internal/testutils
|
||||
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
|
||||
9
Makefile
9
Makefile
|
|
@ -12,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:
|
||||
|
|
|
|||
116
README.md
116
README.md
|
|
@ -19,7 +19,7 @@ terraform {
|
|||
required_providers {
|
||||
stackitprivatepreview = {
|
||||
source = "tfregistry.sysops.stackit.rocks/mhenselin/stackitprivatepreview"
|
||||
version = "= 0.0.5-alpha"
|
||||
version = ">= 0.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -38,7 +38,6 @@ Check one of the examples in the [examples](examples/) folder.
|
|||
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:
|
||||
|
||||
- Key flow (recommended)
|
||||
- Token flow (is scheduled for deprecation and will be removed on December 17, 2025.)
|
||||
|
||||
When setting up authentication, the provider will always try to use the key flow first and search for credentials in several locations, following a specific order:
|
||||
|
||||
|
|
@ -52,7 +51,6 @@ When setting up authentication, the provider will always try to use the key flow
|
|||
|
||||
```json
|
||||
{
|
||||
"STACKIT_SERVICE_ACCOUNT_TOKEN": "foo_token",
|
||||
"STACKIT_SERVICE_ACCOUNT_KEY_PATH": "path/to/sa_key.json"
|
||||
}
|
||||
```
|
||||
|
|
@ -71,35 +69,41 @@ To configure the key flow, follow this steps:
|
|||
|
||||
1. Create a service account key:
|
||||
|
||||
- Use the [STACKIT Portal](https://portal.stackit.cloud/): go to the `Service Accounts` tab, choose a `Service Account` and go to `Service Account Keys` to create a key. For more details, see [Create a service account key](https://docs.stackit.cloud/platform/access-and-identity/service-accounts/how-tos/manage-service-account-keys/)
|
||||
- Use the [STACKIT Portal](https://portal.stackit.cloud/): go to the `Service Accounts` tab, choose a `Service Account` and go to `Service Account Keys` to create a key. For more details, see [Create a service account key](https://docs.stackit.cloud/platform/access-and-identity/service-accounts/how-tos/manage-service-account-keys/)
|
||||
|
||||
2. Save the content of the service account key by copying it and saving it in a JSON file.
|
||||
|
||||
The expected format of the service account key is a **JSON** with the following structure:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "uuid",
|
||||
"publicKey": "public key",
|
||||
"createdAt": "2023-08-24T14:15:22Z",
|
||||
"validUntil": "2023-08-24T14:15:22Z",
|
||||
"keyType": "USER_MANAGED",
|
||||
"keyOrigin": "USER_PROVIDED",
|
||||
"keyAlgorithm": "RSA_2048",
|
||||
"active": true,
|
||||
"credentials": {
|
||||
"kid": "string",
|
||||
"iss": "my-sa@sa.stackit.cloud",
|
||||
"sub": "uuid",
|
||||
"aud": "string",
|
||||
(optional) "privateKey": "private key when generated by the SA service"
|
||||
}
|
||||
}
|
||||
```
|
||||
```json
|
||||
{
|
||||
"id": "uuid",
|
||||
"publicKey": "public key",
|
||||
"createdAt": "2023-08-24T14:15:22Z",
|
||||
"validUntil": "2023-08-24T14:15:22Z",
|
||||
"keyType": "USER_MANAGED",
|
||||
"keyOrigin": "USER_PROVIDED",
|
||||
"keyAlgorithm": "RSA_2048",
|
||||
"active": true,
|
||||
"credentials": {
|
||||
"kid": "string",
|
||||
"iss": "my-sa@sa.stackit.cloud",
|
||||
"sub": "uuid",
|
||||
"aud": "string",
|
||||
(optional) "privateKey": "private key when generated by the SA service"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
3. Configure the service account key for authentication in the provider by following one of the alternatives below:
|
||||
|
||||
- setting the fields in the provider block: `service_account_key` or `service_account_key_path`
|
||||
```hcl
|
||||
provider "stackitprivatepreview" {
|
||||
default_region = "eu01"
|
||||
service_account_key_path = "../service_account.json"
|
||||
}
|
||||
```
|
||||
- setting the environment variable: `STACKIT_SERVICE_ACCOUNT_KEY_PATH` or `STACKIT_SERVICE_ACCOUNT_KEY`
|
||||
- ensure the set the service account key in `STACKIT_SERVICE_ACCOUNT_KEY` is correctly formatted. Use e.g.
|
||||
`$ export STACKIT_SERVICE_ACCOUNT_KEY=$(cat ./service-account-key.json)`
|
||||
|
|
@ -111,16 +115,6 @@ To configure the key flow, follow this steps:
|
|||
> - setting the environment variable: `STACKIT_PRIVATE_KEY_PATH` or `STACKIT_PRIVATE_KEY`
|
||||
> - setting `STACKIT_PRIVATE_KEY_PATH` in the credentials file (see above)
|
||||
|
||||
### Token flow
|
||||
|
||||
> Is scheduled for deprecation and will be removed on December 17, 2025.
|
||||
|
||||
Using this flow is less secure since the token is long-lived. You can provide the token in several ways:
|
||||
|
||||
1. Setting the field `service_account_token` in the provider
|
||||
2. Setting the environment variable `STACKIT_SERVICE_ACCOUNT_TOKEN`
|
||||
3. Setting it in the credentials file (see above)
|
||||
|
||||
## Backend configuration
|
||||
|
||||
To keep track of your terraform state, you can configure an [S3 backend](https://developer.hashicorp.com/terraform/language/settings/backends/s3) using [STACKIT Object Storage](https://docs.stackit.cloud/products/storage/object-storage).
|
||||
|
|
@ -150,62 +144,6 @@ terraform {
|
|||
|
||||
Note: AWS specific checks must be skipped as they do not work on STACKIT. For details on what those validations do, see [here](https://developer.hashicorp.com/terraform/language/settings/backends/s3#configuration).
|
||||
|
||||
## Opting into Beta Resources
|
||||
|
||||
To use beta resources in the STACKIT Terraform provider, follow these steps:
|
||||
|
||||
1. **Provider Configuration Option**
|
||||
|
||||
Set the `enable_beta_resources` option in the provider configuration. This is a boolean attribute that can be either `true` or `false`.
|
||||
|
||||
```hcl
|
||||
provider "stackit" {
|
||||
default_region = "eu01"
|
||||
enable_beta_resources = true
|
||||
}
|
||||
```
|
||||
|
||||
2. **Environment Variable**
|
||||
|
||||
Set the `STACKIT_TF_ENABLE_BETA_RESOURCES` environment variable to `"true"` or `"false"`. Other values will be ignored and will produce a warning.
|
||||
|
||||
```sh
|
||||
export STACKIT_TF_ENABLE_BETA_RESOURCES=true
|
||||
```
|
||||
|
||||
> **Note**: The environment variable takes precedence over the provider configuration option. This means that if the `STACKIT_TF_ENABLE_BETA_RESOURCES` environment variable is set to a valid value (`"true"` or `"false"`), it will override the `enable_beta_resources` option specified in the provider configuration.
|
||||
|
||||
For more details, please refer to the [beta resources configuration guide](https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs/guides/opting_into_beta_resources).
|
||||
|
||||
## Opting into Experiments
|
||||
|
||||
Experiments are features that are even less mature and stable than Beta Resources. While there is some assumed stability in beta resources, will have to expect breaking changes while using experimental resources. Experimental Resources do not come with any support or warranty.
|
||||
|
||||
To enable experiments set the experiments field in the provider definition:
|
||||
|
||||
```hcl
|
||||
provider "stackit" {
|
||||
default_region = "eu01"
|
||||
experiments = ["iam", "routing-tables", "network"]
|
||||
}
|
||||
```
|
||||
|
||||
### Available Experiments
|
||||
|
||||
#### `iam`
|
||||
|
||||
Enables IAM management features in the Terraform provider. The underlying IAM API is expected to undergo a redesign in the future, which leads to it being considered experimental.
|
||||
|
||||
#### `routing-tables`
|
||||
|
||||
This feature enables experimental routing table capabilities in the Terraform Provider, available only to designated SNAs at this time.
|
||||
|
||||
#### `network`
|
||||
|
||||
The `stackit_network` provides the fields `region` and `routing_table_id` when the experiment flag `network` is set.
|
||||
The underlying API is not stable yet and could change in the future.
|
||||
If you don't need these fields, don't set the experiment flag `network`, to use the stable api.
|
||||
|
||||
## Acceptance Tests
|
||||
|
||||
> [!WARNING]
|
||||
|
|
|
|||
|
|
@ -1,956 +0,0 @@
|
|||
package build
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"io"
|
||||
"log"
|
||||
"log/slog"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/ldez/go-git-cmd-wrapper/v2/clone"
|
||||
"github.com/ldez/go-git-cmd-wrapper/v2/git"
|
||||
)
|
||||
|
||||
const (
|
||||
OAS_REPO_NAME = "stackit-api-specifications"
|
||||
OAS_REPO = "https://github.com/stackitcloud/stackit-api-specifications.git"
|
||||
GEN_REPO_NAME = "stackit-sdk-generator"
|
||||
GEN_REPO = "https://github.com/stackitcloud/stackit-sdk-generator.git"
|
||||
)
|
||||
|
||||
type version struct {
|
||||
verString string
|
||||
major int
|
||||
minor int
|
||||
}
|
||||
|
||||
type Builder struct {
|
||||
SkipClone bool
|
||||
SkipCleanup bool
|
||||
PackagesOnly bool
|
||||
}
|
||||
|
||||
func (b *Builder) Build() error {
|
||||
slog.Info("Starting Builder")
|
||||
if b.PackagesOnly {
|
||||
slog.Info(" >>> only generating pkg_gen <<<")
|
||||
}
|
||||
|
||||
root, err := getRoot()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if root == nil || *root == "" {
|
||||
return fmt.Errorf("unable to determine root directory from git")
|
||||
}
|
||||
slog.Info(" ... using root directory", "dir", *root)
|
||||
|
||||
if !b.PackagesOnly {
|
||||
slog.Info(" ... Checking needed commands available")
|
||||
err := checkCommands([]string{"tfplugingen-framework", "tfplugingen-openapi"})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if !b.SkipCleanup {
|
||||
slog.Info("Cleaning up old packages directory")
|
||||
err = os.RemoveAll(path.Join(*root, "pkg_gen"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if !b.SkipCleanup && !b.PackagesOnly {
|
||||
slog.Info("Cleaning up old packages directory")
|
||||
err = os.RemoveAll(path.Join(*root, "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
|
||||
}
|
||||
}
|
||||
|
||||
slog.Info("Creating oas repo dir", "dir", fmt.Sprintf("%s/%s", *root, OAS_REPO_NAME))
|
||||
repoDir, err := createRepoDir(genDir, OAS_REPO, OAS_REPO_NAME, b.SkipClone)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s", err.Error())
|
||||
}
|
||||
|
||||
slog.Info("Retrieving versions from subdirs")
|
||||
// TODO - major
|
||||
verMap, err := getVersions(repoDir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s", err.Error())
|
||||
}
|
||||
|
||||
slog.Info("Reducing to only latest or highest")
|
||||
res, err := getOnlyLatest(verMap)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s", err.Error())
|
||||
}
|
||||
|
||||
slog.Info("Creating OAS dir")
|
||||
err = os.MkdirAll(path.Join(genDir, "oas"), 0755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
slog.Info("Copying OAS files")
|
||||
for service, item := range res {
|
||||
baseService := strings.TrimSuffix(service, "alpha")
|
||||
baseService = strings.TrimSuffix(baseService, "beta")
|
||||
itemVersion := fmt.Sprintf("v%d%s", item.major, item.verString)
|
||||
if item.minor != 0 {
|
||||
itemVersion = itemVersion + "" + strconv.Itoa(item.minor)
|
||||
}
|
||||
srcFile := path.Join(
|
||||
repoDir,
|
||||
"services",
|
||||
baseService,
|
||||
itemVersion,
|
||||
fmt.Sprintf("%s.json", baseService),
|
||||
)
|
||||
dstFile := path.Join(genDir, "oas", fmt.Sprintf("%s.json", service))
|
||||
_, err = copyFile(srcFile, dstFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
slog.Info("Changing dir", "dir", genDir)
|
||||
err = os.Chdir(genDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
slog.Info("Calling make", "command", "generate-go-sdk")
|
||||
cmd := exec.Command("make", "generate-go-sdk")
|
||||
var stdOut, stdErr bytes.Buffer
|
||||
cmd.Stdout = &stdOut
|
||||
cmd.Stderr = &stdErr
|
||||
|
||||
if err = cmd.Start(); err != nil {
|
||||
slog.Error("cmd.Start", "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if err = cmd.Wait(); err != nil {
|
||||
var exitErr *exec.ExitError
|
||||
if errors.As(err, &exitErr) {
|
||||
slog.Error("cmd.Wait", "code", exitErr.ExitCode(), "error", err, "stdout", stdOut.String(), "stderr", stdErr.String())
|
||||
return fmt.Errorf("%s", stdErr.String())
|
||||
}
|
||||
if err != nil {
|
||||
slog.Error("cmd.Wait", "err", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
slog.Info("Cleaning up go.mod and go.sum files")
|
||||
cleanDir := path.Join(genDir, "sdk-repo-updated", "services")
|
||||
dirEntries, err := os.ReadDir(cleanDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, entry := range dirEntries {
|
||||
if entry.IsDir() {
|
||||
err = deleteFiles(
|
||||
path.Join(cleanDir, entry.Name(), "go.mod"),
|
||||
path.Join(cleanDir, entry.Name(), "go.sum"),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
slog.Info("Changing dir", "dir", *root)
|
||||
err = os.Chdir(*root)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
slog.Info("Rearranging package directories")
|
||||
err = os.MkdirAll(path.Join(*root, "pkg_gen"), 0755) // noqa:gosec
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
srcDir := path.Join(genDir, "sdk-repo-updated", "services")
|
||||
items, err := os.ReadDir(srcDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, item := range items {
|
||||
if item.IsDir() {
|
||||
slog.Info(" -> package", "name", item.Name())
|
||||
tgtDir := path.Join(*root, "pkg_gen", item.Name())
|
||||
if fileExists(tgtDir) {
|
||||
delErr := os.RemoveAll(tgtDir)
|
||||
if delErr != nil {
|
||||
return delErr
|
||||
}
|
||||
}
|
||||
err = os.Rename(path.Join(srcDir, item.Name()), tgtDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
if !b.SkipCleanup {
|
||||
slog.Info("Finally removing temporary files and directories")
|
||||
err = os.RemoveAll(path.Join(*root, "generated"))
|
||||
if err != nil {
|
||||
slog.Error("RemoveAll", "dir", path.Join(*root, "generated"), "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
err = os.RemoveAll(path.Join(*root, GEN_REPO_NAME))
|
||||
if err != nil {
|
||||
slog.Error("RemoveAll", "dir", path.Join(*root, GEN_REPO_NAME), "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
slog.Info("Cleaning up", "dir", repoDir)
|
||||
err = os.RemoveAll(filepath.Dir(repoDir))
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
slog.Info("Done")
|
||||
return nil
|
||||
}
|
||||
|
||||
type templateData struct {
|
||||
PackageName string
|
||||
PackageNameCamel string
|
||||
PackageNamePascal string
|
||||
NameCamel string
|
||||
NamePascal string
|
||||
NameSnake string
|
||||
Fields []string
|
||||
}
|
||||
|
||||
func fileExists(path string) bool {
|
||||
_, err := os.Stat(path)
|
||||
if os.IsNotExist(err) {
|
||||
return false
|
||||
}
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
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 ucfirst(s string) string {
|
||||
if len(s) == 0 {
|
||||
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
|
||||
}
|
||||
|
||||
func generateServiceFiles(rootDir, generatorDir string) error {
|
||||
// slog.Info("Generating specs folder")
|
||||
err := os.MkdirAll(path.Join(rootDir, "generated", "specs"), 0755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
services, err := os.ReadDir(path.Join(rootDir, "service_specs"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, service := range services {
|
||||
if !service.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
versions, err := os.ReadDir(path.Join(rootDir, "service_specs", service.Name()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, svcVersion := range versions {
|
||||
if !svcVersion.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
// TODO: use const of supported versions
|
||||
if svcVersion.Name() != "alpha" && svcVersion.Name() != "beta" {
|
||||
continue
|
||||
}
|
||||
|
||||
specFiles, err := os.ReadDir(path.Join(rootDir, "service_specs", service.Name(), svcVersion.Name()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, specFile := range specFiles {
|
||||
if specFile.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
// slog.Info("Checking spec", "name", spec.Name())
|
||||
r := regexp.MustCompile(`^(.*)_config.yml$`)
|
||||
matches := r.FindAllStringSubmatch(specFile.Name(), -1)
|
||||
if matches != nil {
|
||||
fileName := matches[0][0]
|
||||
resource := matches[0][1]
|
||||
slog.Info(
|
||||
" found service spec",
|
||||
"name",
|
||||
specFile.Name(),
|
||||
"service",
|
||||
service.Name(),
|
||||
"resource",
|
||||
resource,
|
||||
)
|
||||
|
||||
oasFile := path.Join(generatorDir, "oas", fmt.Sprintf("%s%s.json", service.Name(), svcVersion.Name()))
|
||||
if _, oasErr := os.Stat(oasFile); os.IsNotExist(oasErr) {
|
||||
slog.Warn(" could not find matching oas", "svc", service.Name(), "version", svcVersion.Name())
|
||||
continue
|
||||
}
|
||||
|
||||
scName := fmt.Sprintf("%s%s", service.Name(), svcVersion.Name())
|
||||
scName = strings.ReplaceAll(scName, "-", "")
|
||||
err = os.MkdirAll(path.Join(rootDir, "generated", "internal", "services", scName, resource), 0755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// slog.Info("Generating openapi spec json")
|
||||
specJsonFile := path.Join(rootDir, "generated", "specs", fmt.Sprintf("%s_%s_spec.json", scName, resource))
|
||||
|
||||
var stdOut, stdErr bytes.Buffer
|
||||
|
||||
// noqa:gosec
|
||||
cmd := exec.Command(
|
||||
"tfplugingen-openapi",
|
||||
"generate",
|
||||
"--config",
|
||||
path.Join(rootDir, "service_specs", service.Name(), svcVersion.Name(), fileName),
|
||||
"--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())
|
||||
}
|
||||
|
||||
// slog.Info("Creating terraform svc resource files folder")
|
||||
tgtFolder := path.Join(rootDir, "generated", "internal", "services", scName, resource, "resources_gen")
|
||||
err = os.MkdirAll(tgtFolder, 0755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// slog.Info("Generating terraform svc resource files")
|
||||
|
||||
// noqa:gosec
|
||||
cmd2 := exec.Command(
|
||||
"tfplugingen-framework",
|
||||
"generate",
|
||||
"resources",
|
||||
"--input",
|
||||
specJsonFile,
|
||||
"--output",
|
||||
tgtFolder,
|
||||
"--package",
|
||||
scName,
|
||||
)
|
||||
|
||||
cmd2.Stdout = &stdOut
|
||||
cmd2.Stderr = &stdErr
|
||||
if err = cmd2.Start(); err != nil {
|
||||
slog.Error("tfplugingen-framework generate resources", "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if err = cmd2.Wait(); err != nil {
|
||||
var exitErr *exec.ExitError
|
||||
if errors.As(err, &exitErr) {
|
||||
slog.Error("tfplugingen-framework generate resources", "code", exitErr.ExitCode(), "error", err, "stdout", stdOut.String(), "stderr", stdErr.String())
|
||||
return fmt.Errorf("%s", stdErr.String())
|
||||
}
|
||||
if err != nil {
|
||||
slog.Error("tfplugingen-framework generate resources", "err", err, "stdout", stdOut.String(), "stderr", stdErr.String())
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// slog.Info("Creating terraform svc datasource files folder")
|
||||
tgtFolder = path.Join(rootDir, "generated", "internal", "services", scName, resource, "datasources_gen")
|
||||
err = os.MkdirAll(tgtFolder, 0755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// slog.Info("Generating terraform svc resource files")
|
||||
|
||||
// noqa:gosec
|
||||
cmd3 := exec.Command(
|
||||
"tfplugingen-framework",
|
||||
"generate",
|
||||
"data-sources",
|
||||
"--input",
|
||||
specJsonFile,
|
||||
"--output",
|
||||
tgtFolder,
|
||||
"--package",
|
||||
scName,
|
||||
)
|
||||
var stdOut3, stdErr3 bytes.Buffer
|
||||
cmd3.Stdout = &stdOut3
|
||||
cmd3.Stderr = &stdErr3
|
||||
|
||||
if err = cmd3.Start(); err != nil {
|
||||
slog.Error("tfplugingen-framework generate data-sources", "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if err = cmd3.Wait(); err != nil {
|
||||
var exitErr *exec.ExitError
|
||||
if errors.As(err, &exitErr) {
|
||||
slog.Error("tfplugingen-framework generate data-sources", "code", exitErr.ExitCode(), "error", err, "stdout", stdOut.String(), "stderr", stdErr.String())
|
||||
return fmt.Errorf("%s", stdErr.String())
|
||||
}
|
||||
if err != nil {
|
||||
slog.Error("tfplugingen-framework generate data-sources", "err", err, "stdout", stdOut.String(), "stderr", stdErr.String())
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
tfAnoErr := handleTfTagForDatasourceFile(
|
||||
path.Join(tgtFolder, fmt.Sprintf("%s_data_source_gen.go", resource)),
|
||||
scName,
|
||||
resource,
|
||||
)
|
||||
if tfAnoErr != nil {
|
||||
return tfAnoErr
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// handleTfTagForDatasourceFile replaces existing "id" with "stf_original_api_id"
|
||||
func handleTfTagForDatasourceFile(filePath, service, resource string) error {
|
||||
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
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
root, err := getRoot()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
tmp, err := os.CreateTemp(*root, "replace-*")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tmp.Close()
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
if err := os.Rename(tmp.Name(), filePath); err != nil {
|
||||
log.Fatal(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 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
|
||||
}
|
||||
|
||||
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 source.Close()
|
||||
|
||||
destination, err := os.Create(dst)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer destination.Close()
|
||||
nBytes, err := io.Copy(destination, source)
|
||||
return nBytes, err
|
||||
}
|
||||
|
||||
func getOnlyLatest(m map[string]version) (map[string]version, error) {
|
||||
tmpMap := make(map[string]version)
|
||||
for k, v := range m {
|
||||
item, ok := tmpMap[k]
|
||||
if !ok {
|
||||
tmpMap[k] = v
|
||||
} else {
|
||||
if item.major == v.major && item.minor < v.minor {
|
||||
tmpMap[k] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
return tmpMap, nil
|
||||
}
|
||||
|
||||
func getVersions(dir string) (map[string]version, error) {
|
||||
res := make(map[string]version)
|
||||
children, err := os.ReadDir(path.Join(dir, "services"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, entry := range children {
|
||||
if entry.IsDir() {
|
||||
versions, err := os.ReadDir(path.Join(dir, "services", entry.Name()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m, err2 := extractVersions(entry.Name(), versions)
|
||||
if err2 != nil {
|
||||
return m, err2
|
||||
}
|
||||
for k, v := range m {
|
||||
res[k] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func extractVersions(service string, versionDirs []os.DirEntry) (map[string]version, error) {
|
||||
res := make(map[string]version)
|
||||
for _, vDir := range versionDirs {
|
||||
if vDir.IsDir() {
|
||||
r := regexp.MustCompile(`v([0-9]+)([a-z]+)([0-9]*)`)
|
||||
matches := r.FindAllStringSubmatch(vDir.Name(), -1)
|
||||
if matches == nil {
|
||||
continue
|
||||
}
|
||||
svc, ver, err := handleVersion(service, matches[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if svc != nil && ver != nil {
|
||||
res[*svc] = *ver
|
||||
}
|
||||
}
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func handleVersion(service string, match []string) (*string, *version, error) {
|
||||
if match == nil {
|
||||
fmt.Println("no matches")
|
||||
return nil, nil, nil
|
||||
}
|
||||
verString := match[2]
|
||||
if verString != "alpha" && verString != "beta" {
|
||||
return nil, nil, errors.New("unsupported version")
|
||||
}
|
||||
majVer, err := strconv.Atoi(match[1])
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if match[3] == "" {
|
||||
match[3] = "0"
|
||||
}
|
||||
minVer, err := strconv.Atoi(match[3])
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
resStr := fmt.Sprintf("%s%s", service, verString)
|
||||
return &resStr, &version{verString: verString, major: majVer, minor: minVer}, nil
|
||||
}
|
||||
|
||||
func createRepoDir(root, repoUrl, repoName string, skipClone bool) (string, error) {
|
||||
targetDir := path.Join(root, repoName)
|
||||
if !skipClone {
|
||||
if fileExists(targetDir) {
|
||||
slog.Warn("target dir exists - skipping", "targetDir", targetDir)
|
||||
return targetDir, nil
|
||||
}
|
||||
_, err := git.Clone(
|
||||
clone.Repository(repoUrl),
|
||||
clone.Directory(targetDir),
|
||||
)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
return targetDir, 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 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 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") {
|
||||
// fmt.Printf("found model: %s\n", ts.Name.Name)
|
||||
ast.Inspect(ts, func(sn ast.Node) bool {
|
||||
tts, tok := sn.(*ast.Field)
|
||||
if tok {
|
||||
// fmt.Printf(" found: %+v\n", tts.Names[0])
|
||||
// spew.Dump(tts.Type)
|
||||
|
||||
result = append(result, tts.Names[0].String())
|
||||
|
||||
// fld, fldOk := tts.Type.(*ast.Ident)
|
||||
//if fldOk {
|
||||
// fmt.Printf("type: %+v\n", fld)
|
||||
//}
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
}
|
||||
return true
|
||||
})
|
||||
return result, nil
|
||||
}
|
||||
|
|
@ -28,6 +28,9 @@ data "stackitprivatepreview_postgresflexalpha_database" "example" {
|
|||
- `database_id` (Number) The ID of the database.
|
||||
- `instance_id` (String) The ID of the instance.
|
||||
- `project_id` (String) The STACKIT project ID.
|
||||
|
||||
### Optional
|
||||
|
||||
- `region` (String) The region which should be addressed
|
||||
|
||||
### Read-Only
|
||||
|
|
|
|||
|
|
@ -26,22 +26,32 @@ data "stackitprivatepreview_postgresflexalpha_instance" "example" {
|
|||
|
||||
- `instance_id` (String) The ID of the instance.
|
||||
- `project_id` (String) The STACKIT project ID.
|
||||
|
||||
### Optional
|
||||
|
||||
- `region` (String) The region which should be addressed
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `acl` (List of String) List of IPV4 cidr.
|
||||
- `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.
|
||||
- `connection_info` (Attributes) The DNS name and port in the instance overview (see [below for nested schema](#nestedatt--connection_info))
|
||||
- `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.
|
||||
- `id` (String) internal ID
|
||||
- `is_deletable` (Boolean) Whether the instance can be deleted or not.
|
||||
- `labels` (Map of String) Key-value pairs, 63 characters max, begin and end with an alphanumerical character,
|
||||
may contain dashes (-), underscores (_), dots (.), and alphanumerics between. Key MUST be at least 1 character.
|
||||
Max 64 labels
|
||||
Regex for keys: ^(?=.{1,63}$)([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]$
|
||||
Regex for values: ^(?=.{0,63}$)(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])*$
|
||||
The stackit- prefix is reserved and cannot be used for Keys.
|
||||
- `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.
|
||||
- `retention_days` (Number) How long backups are retained. The value can only be between 32 and 90 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.
|
||||
|
|
@ -52,10 +62,18 @@ data "stackitprivatepreview_postgresflexalpha_instance" "example" {
|
|||
|
||||
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`
|
||||
|
||||
|
|
|
|||
|
|
@ -27,12 +27,12 @@ data "stackitprivatepreview_postgresflexalpha_user" "example" {
|
|||
|
||||
- `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
|
||||
|
||||
- `id` (String) Terraform's internal resource ID. It is structured as \"`project_id`,`region`,`instance_id`,`user_id`\".",
|
||||
- `region` (String) The region which should be addressed
|
||||
|
||||
### Read-Only
|
||||
|
||||
|
|
|
|||
|
|
@ -1,32 +0,0 @@
|
|||
---
|
||||
# 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.
|
||||
|
|
@ -1,54 +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)
|
||||
|
||||
|
||||
|
||||
## Example Usage
|
||||
|
||||
```terraform
|
||||
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"
|
||||
}
|
||||
```
|
||||
|
||||
<!-- 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 HA
|
||||
- `project_id` (String) The project ID of the flavor.
|
||||
- `ram` (Number) The memory of the instance in Gibibyte.
|
||||
- `region` (String) The region of the flavor.
|
||||
- `storage_class` (String) The memory of the instance in Gibibyte.
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `description` (String) The flavor description.
|
||||
- `flavor_id` (String) The id of the instance flavor.
|
||||
- `id` (String) The 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) maximum storage which can be ordered for the flavor in Gigabyte. (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)
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "stackitprivatepreview_sqlserverflexalpha_instance Data Source - stackitprivatepreview"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# stackitprivatepreview_sqlserverflexalpha_instance (Data Source)
|
||||
|
||||
|
||||
|
||||
## Example Usage
|
||||
|
||||
```terraform
|
||||
data "stackitprivatepreview_sqlserverflexalpha_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.
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "stackitprivatepreview_sqlserverflexalpha_user Data Source - stackitprivatepreview"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# stackitprivatepreview_sqlserverflexalpha_user (Data Source)
|
||||
|
||||
|
||||
|
||||
## Example Usage
|
||||
|
||||
```terraform
|
||||
data "stackitprivatepreview_sqlserverflexalpha_user" "example" {
|
||||
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||
instance_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||
user_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
|
||||
|
||||
### 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.
|
||||
|
|
@ -54,4 +54,4 @@ import {
|
|||
|
||||
### Read-Only
|
||||
|
||||
- `id` (Number) The id of the database.
|
||||
- `id` (String) The id of the database.
|
||||
|
|
|
|||
|
|
@ -13,6 +13,33 @@ description: |-
|
|||
## Example Usage
|
||||
|
||||
```terraform
|
||||
# NOTE: flavor handling will change in future
|
||||
# V2 compatible flavor usage (example without encryption)
|
||||
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 = "0 0 * * *"
|
||||
retention_days = 30
|
||||
flavor = {
|
||||
cpu = 2
|
||||
ram = 4
|
||||
}
|
||||
replicas = 1
|
||||
storage = {
|
||||
performance_class = "premium-perf2-stackit"
|
||||
size = 10
|
||||
}
|
||||
network = {
|
||||
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
|
||||
access_scope = "PUBLIC"
|
||||
}
|
||||
version = 17
|
||||
}
|
||||
|
||||
# future use of flavor (implemented in V3 API)
|
||||
# first determine flavor and then use the flavor_id
|
||||
|
||||
resource "stackitprivatepreview_postgresflexalpha_instance" "example-instance" {
|
||||
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||
name = "example-instance"
|
||||
|
|
@ -32,7 +59,7 @@ resource "stackitprivatepreview_postgresflexalpha_instance" "example-instance" {
|
|||
service_account = "service@account.email"
|
||||
}
|
||||
network = {
|
||||
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
|
||||
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
|
||||
access_scope = "PUBLIC"
|
||||
}
|
||||
version = 17
|
||||
|
|
@ -59,12 +86,11 @@ import {
|
|||
|
||||
### 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.
|
||||
- `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.
|
||||
- `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.
|
||||
- `retention_days` (Number) How long backups are retained. The value can only be between 32 and 90 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.
|
||||
|
||||
|
|
@ -73,6 +99,8 @@ import {
|
|||
- `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` (Attributes, Deprecated) (see [below for nested schema](#nestedatt--flavor))
|
||||
- `flavor_id` (String) The id of the instance flavor.
|
||||
- `instance_id` (String) The ID of the instance.
|
||||
- `project_id` (String) The STACKIT project ID.
|
||||
- `region` (String) The region which should be addressed
|
||||
|
|
@ -80,7 +108,7 @@ import {
|
|||
### Read-Only
|
||||
|
||||
- `acl` (List of String) List of IPV4 cidr.
|
||||
- `connection_info` (Attributes) The DNS name and port in the instance overview (see [below for nested schema](#nestedatt--connection_info))
|
||||
- `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.
|
||||
|
|
@ -122,10 +150,31 @@ Required:
|
|||
- `service_account` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--flavor"></a>
|
||||
### Nested Schema for `flavor`
|
||||
|
||||
Optional:
|
||||
|
||||
- `cpu` (Number, Deprecated)
|
||||
- `ram` (Number, Deprecated)
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `description` (String)
|
||||
- `id` (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.
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ description: |-
|
|||
resource "stackitprivatepreview_postgresflexalpha_user" "example" {
|
||||
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||
instance_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||
name = "username"
|
||||
name = "username"
|
||||
roles = ["role"]
|
||||
}
|
||||
|
||||
|
|
@ -54,6 +54,6 @@ import {
|
|||
|
||||
### Read-Only
|
||||
|
||||
- `id` (Number) The ID of the user.
|
||||
- `id` (String) The ID of the user.
|
||||
- `password` (String) The password for the user.
|
||||
- `status` (String) The current status of the user.
|
||||
|
|
|
|||
|
|
@ -1,63 +0,0 @@
|
|||
---
|
||||
# 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.
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "stackitprivatepreview_sqlserverflexalpha_instance Resource - stackitprivatepreview"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# stackitprivatepreview_sqlserverflexalpha_instance (Resource)
|
||||
|
||||
|
||||
|
||||
## Example Usage
|
||||
|
||||
```terraform
|
||||
resource "stackitprivatepreview_sqlserverflexalpha_instance" "example" {
|
||||
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 = 4
|
||||
ram = 16
|
||||
}
|
||||
storage = {
|
||||
class = "class"
|
||||
size = 5
|
||||
}
|
||||
version = 2022
|
||||
}
|
||||
|
||||
# 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}"
|
||||
}
|
||||
```
|
||||
|
||||
<!-- 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)
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "stackitprivatepreview_sqlserverflexalpha_user Resource - stackitprivatepreview"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# stackitprivatepreview_sqlserverflexalpha_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.
|
||||
|
|
@ -13,6 +13,31 @@ description: |-
|
|||
## Example Usage
|
||||
|
||||
```terraform
|
||||
# NOTE: flavor handling will change in future
|
||||
# V2 compatible flavor usage
|
||||
resource "stackitprivatepreview_sqlserverflexbeta_instance" "instance" {
|
||||
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||
name = "example-instance"
|
||||
backup_schedule = "0 3 * * *"
|
||||
retention_days = 31
|
||||
flavor = {
|
||||
cpu = 2
|
||||
ram = 4
|
||||
}
|
||||
storage = {
|
||||
class = "premium-perf2-stackit"
|
||||
size = 50
|
||||
}
|
||||
version = 2022
|
||||
network = {
|
||||
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
|
||||
access_scope = "SNA"
|
||||
}
|
||||
}
|
||||
|
||||
# future use of flavor (implemented in V3 API)
|
||||
# first determine flavor and then use the flavor_id
|
||||
|
||||
# without encryption and SNA
|
||||
resource "stackitprivatepreview_sqlserverflexbeta_instance" "instance" {
|
||||
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||
|
|
@ -97,7 +122,6 @@ import {
|
|||
### 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
|
||||
|
|
@ -107,6 +131,8 @@ import {
|
|||
### Optional
|
||||
|
||||
- `encryption` (Attributes) this defines which key to use for storage encryption (see [below for nested schema](#nestedatt--encryption))
|
||||
- `flavor` (Attributes, Deprecated) (see [below for nested schema](#nestedatt--flavor))
|
||||
- `flavor_id` (String) The id of the instance flavor.
|
||||
- `instance_id` (String) The ID of the instance.
|
||||
- `project_id` (String) The STACKIT project ID.
|
||||
- `region` (String) The region which should be addressed
|
||||
|
|
@ -156,3 +182,17 @@ Required:
|
|||
- `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`
|
||||
|
||||
Optional:
|
||||
|
||||
- `cpu` (Number, Deprecated)
|
||||
- `ram` (Number, Deprecated)
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `description` (String)
|
||||
- `id` (String)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,30 @@
|
|||
# NOTE: flavor handling will change in future
|
||||
# V2 compatible flavor usage (example without encryption)
|
||||
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 = "0 0 * * *"
|
||||
retention_days = 30
|
||||
flavor = {
|
||||
cpu = 2
|
||||
ram = 4
|
||||
}
|
||||
replicas = 1
|
||||
storage = {
|
||||
performance_class = "premium-perf2-stackit"
|
||||
size = 10
|
||||
}
|
||||
network = {
|
||||
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
|
||||
access_scope = "PUBLIC"
|
||||
}
|
||||
version = 17
|
||||
}
|
||||
|
||||
# future use of flavor (implemented in V3 API)
|
||||
# first determine flavor and then use the flavor_id
|
||||
|
||||
resource "stackitprivatepreview_postgresflexalpha_instance" "example-instance" {
|
||||
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||
name = "example-instance"
|
||||
|
|
@ -17,7 +44,7 @@ resource "stackitprivatepreview_postgresflexalpha_instance" "example-instance" {
|
|||
service_account = "service@account.email"
|
||||
}
|
||||
network = {
|
||||
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
|
||||
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
|
||||
access_scope = "PUBLIC"
|
||||
}
|
||||
version = 17
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
resource "stackitprivatepreview_postgresflexalpha_user" "example" {
|
||||
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||
instance_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||
name = "username"
|
||||
name = "username"
|
||||
roles = ["role"]
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,28 @@
|
|||
# NOTE: flavor handling will change in future
|
||||
# V2 compatible flavor usage
|
||||
resource "stackitprivatepreview_sqlserverflexbeta_instance" "instance" {
|
||||
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||
name = "example-instance"
|
||||
backup_schedule = "0 3 * * *"
|
||||
retention_days = 31
|
||||
flavor = {
|
||||
cpu = 2
|
||||
ram = 4
|
||||
}
|
||||
storage = {
|
||||
class = "premium-perf2-stackit"
|
||||
size = 50
|
||||
}
|
||||
version = 2022
|
||||
network = {
|
||||
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
|
||||
access_scope = "SNA"
|
||||
}
|
||||
}
|
||||
|
||||
# future use of flavor (implemented in V3 API)
|
||||
# first determine flavor and then use the flavor_id
|
||||
|
||||
# without encryption and SNA
|
||||
resource "stackitprivatepreview_sqlserverflexbeta_instance" "instance" {
|
||||
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||
|
|
|
|||
341
generator/cmd/build/build.go
Normal file
341
generator/cmd/build/build.go
Normal 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
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ package build
|
|||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
|
|
@ -74,14 +75,24 @@ func Copy(srcFile, dstFile string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
defer out.Close()
|
||||
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 in.Close()
|
||||
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 {
|
||||
120
generator/cmd/build/functions.go
Normal file
120
generator/cmd/build/functions.go
Normal 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
|
||||
}
|
||||
446
generator/cmd/build/oas-handler.go
Normal file
446
generator/cmd/build/oas-handler.go
Normal 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
|
||||
}
|
||||
|
|
@ -3,24 +3,28 @@ package cmd
|
|||
import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/cmd/cmd/build"
|
||||
"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(cmd *cobra.Command, args []string) error {
|
||||
RunE: func(_ *cobra.Command, _ []string) error {
|
||||
b := build.Builder{
|
||||
SkipClone: skipClone,
|
||||
SkipCleanup: skipCleanup,
|
||||
PackagesOnly: packagesOnly,
|
||||
Verbose: verbose,
|
||||
Debug: debug,
|
||||
}
|
||||
return b.Build()
|
||||
},
|
||||
|
|
@ -30,8 +34,10 @@ func NewBuildCmd() *cobra.Command {
|
|||
return buildCmd
|
||||
}
|
||||
|
||||
func init() { // nolint: gochecknoinits
|
||||
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
247
generator/cmd/docCmd.go
Normal 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/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/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")
|
||||
}
|
||||
27
generator/cmd/docs/templates/nav.md.gompl
vendored
Normal file
27
generator/cmd/docs/templates/nav.md.gompl
vendored
Normal 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 }}
|
||||
|
|
@ -12,16 +12,15 @@ var examplesCmd = &cobra.Command{
|
|||
Use: "examples",
|
||||
Short: "create examples",
|
||||
Long: `...`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
//filePathStr := "stackit/internal/services/postgresflexalpha/database/datasources_gen/database_data_source_gen.go"
|
||||
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 {
|
||||
// src, err := os.ReadFile(filePathStr)
|
||||
// if err != nil {
|
||||
// return err
|
||||
//}
|
||||
//
|
||||
//i := interp.New(
|
||||
// i := interp.New(
|
||||
// interp.Options{
|
||||
// GoPath: "/home/henselinm/.asdf/installs/golang/1.25.6/packages",
|
||||
// BuildTags: nil,
|
||||
|
|
@ -34,46 +33,46 @@ var examplesCmd = &cobra.Command{
|
|||
// Unrestricted: false,
|
||||
// },
|
||||
//)
|
||||
//err = i.Use(i.Symbols("github.com/hashicorp/terraform-plugin-framework-validators"))
|
||||
//if err != nil {
|
||||
// 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 {
|
||||
// err = i.Use(stdlib.Symbols)
|
||||
// if err != nil {
|
||||
// return err
|
||||
//}
|
||||
//_, err = i.Eval(string(src))
|
||||
//if err != nil {
|
||||
// _, err = i.Eval(string(src))
|
||||
// if err != nil {
|
||||
// return err
|
||||
//}
|
||||
//
|
||||
//v, err := i.Eval("DatabaseDataSourceSchema")
|
||||
//if err != nil {
|
||||
// v, err := i.Eval("DatabaseDataSourceSchema")
|
||||
// if err != nil {
|
||||
// return err
|
||||
//}
|
||||
//
|
||||
//bar := v.Interface().(func(string) string)
|
||||
// bar := v.Interface().(func(string) string)
|
||||
//
|
||||
//r := bar("Kung")
|
||||
//println(r)
|
||||
// r := bar("Kung")
|
||||
// println(r)
|
||||
//
|
||||
//evalPath, err := i.EvalPath(filePathStr)
|
||||
//if err != nil {
|
||||
// evalPath, err := i.EvalPath(filePathStr)
|
||||
// if err != nil {
|
||||
// return err
|
||||
//}
|
||||
//
|
||||
//fmt.Printf("%+v\n", evalPath)
|
||||
// fmt.Printf("%+v\n", evalPath)
|
||||
|
||||
//_, err = i.Eval(`import "fmt"`)
|
||||
//if err != nil {
|
||||
// _, err = i.Eval(`import "fmt"`)
|
||||
// if err != nil {
|
||||
// return err
|
||||
//}
|
||||
//_, err = i.Eval(`func Hallo() { fmt.Println("Hi!") }`)
|
||||
//if err != nil {
|
||||
// _, err = i.Eval(`func Hallo() { fmt.Println("Hi!") }`)
|
||||
// if err != nil {
|
||||
// return err
|
||||
//}
|
||||
|
||||
//v = i.Symbols("Hallo")
|
||||
// v = i.Symbols("Hallo")
|
||||
|
||||
// fmt.Println(v)
|
||||
return workServices()
|
||||
|
|
@ -110,6 +109,6 @@ func NewExamplesCmd() *cobra.Command {
|
|||
return examplesCmd
|
||||
}
|
||||
|
||||
//func init() { // nolint: gochecknoinits
|
||||
// func init() { // nolint: gochecknoinits
|
||||
// examplesCmd.Flags().BoolVarP(&example, "example", "e", false, "example")
|
||||
//}
|
||||
|
|
@ -24,7 +24,7 @@ var getFieldsCmd = &cobra.Command{
|
|||
Use: "get-fields",
|
||||
Short: "get fields from file",
|
||||
Long: `...`,
|
||||
PreRunE: func(cmd *cobra.Command, args []string) error {
|
||||
PreRunE: func(_ *cobra.Command, _ []string) error {
|
||||
typeStr := "data_source"
|
||||
if resType != "resource" && resType != "datasource" {
|
||||
return fmt.Errorf("--type can only be resource or datasource")
|
||||
|
|
@ -76,13 +76,13 @@ var getFieldsCmd = &cobra.Command{
|
|||
|
||||
//// Enum check
|
||||
// switch format {
|
||||
//case "json", "yaml":
|
||||
// case "json", "yaml":
|
||||
//default:
|
||||
// return fmt.Errorf("invalid --format: %s (want json|yaml)", format)
|
||||
//}
|
||||
return nil
|
||||
},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
RunE: func(_ *cobra.Command, _ []string) error {
|
||||
return getFields(filePath)
|
||||
},
|
||||
}
|
||||
|
|
@ -107,31 +107,26 @@ func getTokens(fileName string) ([]string, error) {
|
|||
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") {
|
||||
// fmt.Printf("found model: %s\n", ts.Name.Name)
|
||||
ast.Inspect(ts, func(sn ast.Node) bool {
|
||||
tts, tok := sn.(*ast.Field)
|
||||
if tok {
|
||||
// fmt.Printf(" found: %+v\n", tts.Names[0])
|
||||
// spew.Dump(tts.Type)
|
||||
|
||||
result = append(result, tts.Names[0].String())
|
||||
|
||||
// fld, fldOk := tts.Type.(*ast.Ident)
|
||||
//if fldOk {
|
||||
// fmt.Printf("type: %+v\n", fld)
|
||||
//}
|
||||
}
|
||||
return true
|
||||
})
|
||||
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 true
|
||||
},
|
||||
)
|
||||
return result, nil
|
||||
}
|
||||
|
||||
|
|
@ -139,9 +134,15 @@ func NewGetFieldsCmd() *cobra.Command {
|
|||
return getFieldsCmd
|
||||
}
|
||||
|
||||
func init() { // nolint: gochecknoinits
|
||||
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])")
|
||||
getFieldsCmd.Flags().StringVarP(
|
||||
&resType,
|
||||
"type",
|
||||
"t",
|
||||
"resource",
|
||||
"resource type (data-source or resource [default])",
|
||||
)
|
||||
}
|
||||
|
|
@ -35,36 +35,27 @@ type GpgPublicKey struct {
|
|||
}
|
||||
|
||||
func (p *Provider) CreateArchitectureFiles() error {
|
||||
// var namespace, provider, distPath, repoName, version, gpgFingerprint, gpgPubKeyFile, domain string
|
||||
|
||||
log.Println("* Creating architecture files in target directories")
|
||||
|
||||
// filename = terraform-provider-[provider]_0.0.1_darwin_amd64.zip - provider_name + version + target + architecture + .zip
|
||||
// prefix := fmt.Sprintf("v1/providers/%s/%s/%s/", namespace, provider, version)
|
||||
prefix := path.Join("v1", "providers", p.Namespace, p.Provider, p.Version)
|
||||
|
||||
// pathPrefix := fmt.Sprintf("release/%s", prefix)
|
||||
pathPrefix := path.Join("release", prefix)
|
||||
|
||||
// urlPrefix := fmt.Sprintf("https://%s/%s", domain, prefix)
|
||||
urlPrefix, err := url.JoinPath("https://", p.Domain, prefix)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating base url: %w", err)
|
||||
}
|
||||
|
||||
// download url = https://example.com/v1/providers/namespace/provider/0.0.1/download/terraform-provider_0.0.1_darwin_amd64.zip
|
||||
downloadUrlPrefix, err := url.JoinPath(urlPrefix, "download")
|
||||
if err != nil {
|
||||
return fmt.Errorf("error crearting download url: %w", err)
|
||||
}
|
||||
downloadPathPrefix := path.Join(pathPrefix, "download")
|
||||
|
||||
// shasums url = https://example.com/v1/providers/namespace/provider/0.0.1/terraform-provider_0.0.1_SHA256SUMS
|
||||
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)
|
||||
}
|
||||
// shasums_signature_url = https://example.com/v1/providers/namespace/provider/0.0.1/terraform-provider_0.0.1_SHA256SUMS.sig
|
||||
shasumsSigUrl := shasumsUrl + ".sig"
|
||||
|
||||
gpgAsciiPub, err := p.ReadGpgFile()
|
||||
|
|
@ -116,33 +107,6 @@ func (p *Provider) CreateArchitectureFiles() error {
|
|||
},
|
||||
},
|
||||
}
|
||||
// var architectureTemplate = []byte(fmt.Sprintf(`
|
||||
//{
|
||||
// "protocols": [
|
||||
// "4.0",
|
||||
// "5.1",
|
||||
// "6.0"
|
||||
// ],
|
||||
// "os": "%s",
|
||||
// "arch": "%s",
|
||||
// "filename": "%s",
|
||||
// "download_url": "%s",
|
||||
// "shasums_url": "%s",
|
||||
// "shasums_signature_url": "%s",
|
||||
// "shasum": "%s",
|
||||
// "signing_keys": {
|
||||
// "gpg_public_keys": [
|
||||
// {
|
||||
// "key_id": "%s",
|
||||
// "ascii_armor": "%s",
|
||||
// "trust_signature": "",
|
||||
// "source": "",
|
||||
// "source_url": ""
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
//}
|
||||
// `, target, arch, fileName, downloadUrl, shasumsUrl, shasumsSigUrl, shasum, gpgFingerprint, gpgAsciiPub))
|
||||
|
||||
log.Printf(" - Arch file: %s", archFileName)
|
||||
|
||||
|
|
@ -160,8 +124,12 @@ func WriteArchitectureFile(filePath string, arch Architecture) error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("error encoding data: %w", err)
|
||||
}
|
||||
|
||||
err = os.WriteFile(filePath, jsonString, os.ModePerm)
|
||||
//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)
|
||||
}
|
||||
|
|
@ -161,10 +161,12 @@ func (p *Provider) createVersionsFile() error {
|
|||
target := fileNameSplit[2]
|
||||
arch := fileNameSplit[3]
|
||||
|
||||
version.Platforms = append(version.Platforms, Platform{
|
||||
OS: target,
|
||||
Arch: arch,
|
||||
})
|
||||
version.Platforms = append(
|
||||
version.Platforms, Platform{
|
||||
OS: target,
|
||||
Arch: arch,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
data := Data{}
|
||||
|
|
@ -206,16 +208,19 @@ 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/"}`),
|
||||
0644,
|
||||
0o644,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -224,9 +229,10 @@ func (p *Provider) CreateWellKnown() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func CreateDir(path string) error {
|
||||
log.Printf("* Creating %s directory", path)
|
||||
err := os.MkdirAll(path, os.ModePerm)
|
||||
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
|
||||
}
|
||||
|
|
@ -269,13 +275,23 @@ func CopyFile(src, dst string) (int64, error) {
|
|||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer source.Close()
|
||||
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 destination.Close()
|
||||
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
|
||||
}
|
||||
|
|
@ -35,7 +35,12 @@ func (d *Data) WriteToFile(filePath string) error {
|
|||
return fmt.Errorf("error encoding data: %w", err)
|
||||
}
|
||||
|
||||
err = os.WriteFile(filePath, jsonString, os.ModePerm)
|
||||
//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)
|
||||
}
|
||||
|
|
@ -86,7 +91,13 @@ func (d *Data) LoadFromUrl(uri string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer os.Remove(file.Name()) // Clean up
|
||||
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(),
|
||||
|
|
@ -123,20 +134,30 @@ func (v *Version) AddProtocol(p string) error {
|
|||
// 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(url string, filepath string) error {
|
||||
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 out.Close()
|
||||
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
|
||||
resp, err := http.Get(url)
|
||||
|
||||
//nolint:gosec,bodyclose // this is a controlled URL, not user input
|
||||
resp, err := http.Get(urlValue)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
defer func(Body io.ReadCloser) {
|
||||
_ = Body.Close()
|
||||
}(resp.Body)
|
||||
|
||||
// Write the body to file
|
||||
_, err = io.Copy(out, resp.Body)
|
||||
|
|
@ -11,7 +11,7 @@ import (
|
|||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
publish2 "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/cmd/cmd/publish"
|
||||
publish2 "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/generator/cmd/publish"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -29,20 +29,32 @@ var publishCmd = &cobra.Command{
|
|||
Use: "publish",
|
||||
Short: "Publish terraform provider",
|
||||
Long: `...`,
|
||||
RunE: func(_ *cobra.Command, args []string) error {
|
||||
RunE: func(_ *cobra.Command, _ []string) error {
|
||||
return publish()
|
||||
},
|
||||
}
|
||||
|
||||
func init() { // nolint: gochecknoinits
|
||||
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.")
|
||||
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 {
|
||||
|
|
@ -105,6 +117,7 @@ func publish() error {
|
|||
|
||||
// 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)
|
||||
|
|
@ -6,7 +6,7 @@ import (
|
|||
|
||||
func NewRootCmd() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "build-tools",
|
||||
Use: "generator",
|
||||
Short: "...",
|
||||
Long: "...",
|
||||
SilenceErrors: true, // Error is beautified in a custom way before being printed
|
||||
20
generator/cmd/tools/tools.go
Normal file
20
generator/cmd/tools/tools.go
Normal 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
|
||||
}
|
||||
|
|
@ -8,7 +8,7 @@ import (
|
|||
"github.com/SladkyCitron/slogcolor"
|
||||
cc "github.com/ivanpirog/coloredcobra"
|
||||
|
||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/cmd/cmd"
|
||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/generator/cmd"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
|
@ -31,6 +31,7 @@ func main() {
|
|||
cmd.NewPublishCmd(),
|
||||
cmd.NewGetFieldsCmd(),
|
||||
cmd.NewExamplesCmd(),
|
||||
cmd.NewDocsCmd(),
|
||||
)
|
||||
|
||||
err := rootCmd.Execute()
|
||||
88
go.mod
88
go.mod
|
|
@ -1,89 +1,103 @@
|
|||
module tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview
|
||||
|
||||
go 1.25.6
|
||||
go 1.26.2
|
||||
|
||||
require (
|
||||
github.com/SladkyCitron/slogcolor v1.8.0
|
||||
github.com/SladkyCitron/slogcolor v1.9.0
|
||||
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.19.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.31.0
|
||||
github.com/hashicorp/terraform-plugin-log v0.10.0
|
||||
github.com/hashicorp/terraform-plugin-testing v1.14.0
|
||||
github.com/hashicorp/terraform-plugin-testing v1.16.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.21.1
|
||||
github.com/stackitcloud/stackit-sdk-go/services/iaasalpha v0.1.23-alpha
|
||||
github.com/stretchr/testify v1.11.1
|
||||
github.com/stackitcloud/stackit-sdk-go/core v0.26.0
|
||||
github.com/stackitcloud/stackit-sdk-go/services/postgresflex v1.8.0
|
||||
github.com/stackitcloud/stackit-sdk-go/services/sqlserverflex v1.10.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
|
||||
golang.org/x/telemetry v0.0.0-20260213145524-e0ab670178e1 // indirect
|
||||
)
|
||||
require github.com/hashicorp/go-retryablehttp v0.7.8 // indirect
|
||||
|
||||
require (
|
||||
dario.cat/mergo v1.0.1 // indirect
|
||||
github.com/ProtonMail/go-crypto v1.3.0 // indirect
|
||||
github.com/BurntSushi/toml v1.2.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.2.0 // indirect
|
||||
github.com/Masterminds/sprig/v3 v3.2.3 // indirect
|
||||
github.com/ProtonMail/go-crypto v1.4.1 // indirect
|
||||
github.com/agext/levenshtein v1.2.3 // indirect
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
|
||||
github.com/armon/go-radix v1.0.0 // indirect
|
||||
github.com/bgentry/speakeasy v0.1.0 // indirect
|
||||
github.com/bmatcuk/doublestar/v4 v4.10.0 // indirect
|
||||
github.com/cloudflare/circl v1.6.3 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/fatih/color v1.18.0 // indirect
|
||||
github.com/fatih/color v1.19.0 // indirect
|
||||
github.com/golang-jwt/jwt/v5 v5.3.1 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // 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-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/go-plugin v1.7.0 // indirect
|
||||
github.com/hashicorp/go-plugin v1.8.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.3 // indirect
|
||||
github.com/hashicorp/go-version v1.9.0 // indirect
|
||||
github.com/hashicorp/hc-install v0.9.5 // indirect
|
||||
github.com/hashicorp/hcl/v2 v2.24.0 // indirect
|
||||
github.com/hashicorp/logutils v1.0.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.2 // indirect
|
||||
github.com/hashicorp/terraform-exec v0.25.2 // indirect
|
||||
github.com/hashicorp/terraform-json v0.27.3-0.20260213134036-298b8f6b673a // indirect
|
||||
github.com/hashicorp/terraform-plugin-docs v0.25.0 // indirect
|
||||
github.com/hashicorp/terraform-plugin-sdk/v2 v2.40.1 // indirect
|
||||
github.com/hashicorp/terraform-registry-address v0.4.0 // indirect
|
||||
github.com/hashicorp/terraform-svchost v0.2.0 // indirect
|
||||
github.com/hashicorp/terraform-svchost v0.2.1 // indirect
|
||||
github.com/hashicorp/yamux v0.1.2 // 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/kr/text v0.2.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-isatty v0.0.22 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.9 // indirect
|
||||
github.com/mitchellh/copystructure v1.2.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/oklog/run v1.2.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/posener/complete v1.2.3 // indirect
|
||||
github.com/shopspring/decimal v1.3.1 // indirect
|
||||
github.com/spf13/cast v1.5.0 // indirect
|
||||
github.com/spf13/pflag v1.0.10 // indirect
|
||||
github.com/stretchr/testify v1.11.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.48.0 // indirect
|
||||
golang.org/x/mod v0.33.0 // indirect
|
||||
golang.org/x/net v0.50.0 // indirect
|
||||
golang.org/x/sync v0.19.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
|
||||
github.com/yuin/goldmark v1.7.7 // indirect
|
||||
github.com/yuin/goldmark-meta v1.1.0 // indirect
|
||||
github.com/zclconf/go-cty v1.18.1 // indirect
|
||||
go.abhg.dev/goldmark/frontmatter v0.2.0 // indirect
|
||||
golang.org/x/crypto v0.50.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect
|
||||
golang.org/x/mod v0.35.0 // indirect
|
||||
golang.org/x/net v0.53.0 // indirect
|
||||
golang.org/x/sync v0.20.0 // indirect
|
||||
golang.org/x/sys v0.43.0 // indirect
|
||||
golang.org/x/text v0.36.0 // indirect
|
||||
golang.org/x/tools v0.44.0 // indirect
|
||||
google.golang.org/appengine v1.6.8 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 // indirect
|
||||
google.golang.org/grpc v1.79.1 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260504160031-60b97b32f348 // indirect
|
||||
google.golang.org/grpc v1.81.0 // indirect
|
||||
google.golang.org/protobuf v1.36.11 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
)
|
||||
|
||||
tool golang.org/x/tools/cmd/goimports
|
||||
|
|
|
|||
205
go.sum
205
go.sum
|
|
@ -1,16 +1,32 @@
|
|||
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
|
||||
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
||||
github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
|
||||
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/Kunde21/markdownfmt/v3 v3.1.0 h1:KiZu9LKs+wFFBQKhrZJrFZwtLnCCWJahL+S+E/3VnM0=
|
||||
github.com/Kunde21/markdownfmt/v3 v3.1.0/go.mod h1:tPXN1RTyOzJwhfHoon9wUr4HGYmWgVxSQN6VBJDkrVc=
|
||||
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
|
||||
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
|
||||
github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g=
|
||||
github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
|
||||
github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA=
|
||||
github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM=
|
||||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||
github.com/ProtonMail/go-crypto v1.3.0 h1:ILq8+Sf5If5DCpHQp4PbZdS1J7HDFRXz/+xKBiRGFrw=
|
||||
github.com/ProtonMail/go-crypto v1.3.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE=
|
||||
github.com/SladkyCitron/slogcolor v1.8.0 h1:ln4mUPfVhs7a/vZfjnKkz5YZ71Bg/KFWneS2hfFq6FM=
|
||||
github.com/SladkyCitron/slogcolor v1.8.0/go.mod h1:ft8LEVIl4isUkebakhv+ngNXJjWBumnwhXfxTLApf3M=
|
||||
github.com/ProtonMail/go-crypto v1.4.1 h1:9RfcZHqEQUvP8RzecWEUafnZVtEvrBVL9BiF67IQOfM=
|
||||
github.com/ProtonMail/go-crypto v1.4.1/go.mod h1:e1OaTyu5SYVrO9gKOEhTc+5UcXtTUa+P3uLudwcgPqo=
|
||||
github.com/SladkyCitron/slogcolor v1.9.0 h1:fr4LeG+T6pZ1RYNNOP925jaBYrTdpA6BLzGy29yd4vI=
|
||||
github.com/SladkyCitron/slogcolor v1.9.0/go.mod h1:ft8LEVIl4isUkebakhv+ngNXJjWBumnwhXfxTLApf3M=
|
||||
github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
|
||||
github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
|
||||
github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec=
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY=
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
|
||||
github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=
|
||||
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/bmatcuk/doublestar/v4 v4.10.0 h1:zU9WiOla1YA122oLM6i4EXvGW62DvKZVxIe6TYWexEs=
|
||||
github.com/bmatcuk/doublestar/v4 v4.10.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
|
||||
github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw=
|
||||
github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
|
|
@ -19,7 +35,6 @@ github.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg
|
|||
github.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s=
|
||||
github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
|
@ -29,14 +44,14 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8Yc
|
|||
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
|
||||
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
|
||||
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
||||
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
|
||||
github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w=
|
||||
github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE=
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
|
||||
github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UNbRM=
|
||||
github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU=
|
||||
github.com/go-git/go-git/v5 v5.16.5 h1:mdkuqblwr57kVfXri5TTH+nMFLNUxIj9Z7F5ykFbw5s=
|
||||
github.com/go-git/go-git/v5 v5.16.5/go.mod h1:QOMLpNf1qxuSY4StA/ArOdfFR2TrKEjJiye2kel2m+M=
|
||||
github.com/go-git/go-billy/v5 v5.8.0 h1:I8hjc3LbBlXTtVuFNJuwYuMiHvQJDq1AT6u4DwDzZG0=
|
||||
github.com/go-git/go-billy/v5 v5.8.0/go.mod h1:RpvI/rw4Vr5QA+Z60c6d6LXH0rYJo0uD5SqfmrrheCY=
|
||||
github.com/go-git/go-git/v5 v5.18.0 h1:O831KI+0PR51hM2kep6T8k+w0/LIAD490gvqMCvL5hM=
|
||||
github.com/go-git/go-git/v5 v5.18.0/go.mod h1:pW/VmeqkanRFqR6AljLcs7EA7FbZaN5MQqO7oZADXpo=
|
||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
|
|
@ -56,8 +71,11 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
|
|||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/hashicorp/cli v1.1.7 h1:/fZJ+hNdwfTSfsxMBa9WWMlfjUZbX8/LnUxgAd7lCVU=
|
||||
github.com/hashicorp/cli v1.1.7/go.mod h1:e6Mfpga9OCT1vqzFuoGZiiF/KaG9CbUfO5s3ghU3YgU=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
|
|
@ -70,47 +88,57 @@ github.com/hashicorp/go-cty v1.5.0 h1:EkQ/v+dDNUqnuVpmS5fPqyY71NXVgT5gf32+57xY8g
|
|||
github.com/hashicorp/go-cty v1.5.0/go.mod h1:lFUCG5kd8exDobgSfyj4ONE/dc822kiYMguVKdHGMLM=
|
||||
github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
|
||||
github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||
github.com/hashicorp/go-plugin v1.7.0 h1:YghfQH/0QmPNc/AZMTFE3ac8fipZyZECHdDPshfk+mA=
|
||||
github.com/hashicorp/go-plugin v1.7.0/go.mod h1:BExt6KEaIYx804z8k4gRzRLEvxKVb+kn0NMcihqOqb8=
|
||||
github.com/hashicorp/go-plugin v1.8.0 h1:ie8S6RRY8RvB2usYZv+AAZ/wBvx2AU5p5QeP5j/FORs=
|
||||
github.com/hashicorp/go-plugin v1.8.0/go.mod h1:BExt6KEaIYx804z8k4gRzRLEvxKVb+kn0NMcihqOqb8=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.8 h1:ylXZWnqa7Lhqpk0L1P1LzDtGcCR0rPVUrx/c8Unxc48=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.8/go.mod h1:rjiScheydd+CxvumBsIrFKlx3iS0jrZ7LvzFGFmuKbw=
|
||||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
|
||||
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4=
|
||||
github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/hc-install v0.9.3 h1:1H4dgmgzxEVwT6E/d/vIL5ORGVKz9twRwDw+qA5Hyho=
|
||||
github.com/hashicorp/hc-install v0.9.3/go.mod h1:FQlQ5I3I/X409N/J1U4pPeQQz1R3BoV0IysB7aiaQE0=
|
||||
github.com/hashicorp/go-version v1.9.0 h1:CeOIz6k+LoN3qX9Z0tyQrPtiB1DFYRPfCIBtaXPSCnA=
|
||||
github.com/hashicorp/go-version v1.9.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/hc-install v0.9.5 h1:XHCjcMn2563ysuaQ9v9ec2FNc7c2PJOIEEGobAFeIx4=
|
||||
github.com/hashicorp/hc-install v0.9.5/go.mod h1:ihEW4LshrNkxq2bU/MpVbKyn+yt1is2hYqUTHDGhG84=
|
||||
github.com/hashicorp/hcl/v2 v2.24.0 h1:2QJdZ454DSsYGoaE6QheQZjtKZSUs9Nh2izTWiwQxvE=
|
||||
github.com/hashicorp/hcl/v2 v2.24.0/go.mod h1:oGoO1FIQYfn/AgyOhlg9qLC6/nOJPX3qGbkZpYAcqfM=
|
||||
github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y=
|
||||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
||||
github.com/hashicorp/terraform-exec v0.25.0 h1:Bkt6m3VkJqYh+laFMrWIpy9KHYFITpOyzRMNI35rNaY=
|
||||
github.com/hashicorp/terraform-exec v0.25.0/go.mod h1:dl9IwsCfklDU6I4wq9/StFDp7dNbH/h5AnfS1RmiUl8=
|
||||
github.com/hashicorp/terraform-exec v0.25.2 h1:fFLAVEtAjKdGfawGUXDnKooCnqJi+TuohT3W99AGbhk=
|
||||
github.com/hashicorp/terraform-exec v0.25.2/go.mod h1:uaQV2oqVLqM4cixJryk6qIWS1qji3GtuwPG5pjGXYfc=
|
||||
github.com/hashicorp/terraform-json v0.27.2 h1:BwGuzM6iUPqf9JYM/Z4AF1OJ5VVJEEzoKST/tRDBJKU=
|
||||
github.com/hashicorp/terraform-json v0.27.2/go.mod h1:GzPLJ1PLdUG5xL6xn1OXWIjteQRT2CNT9o/6A9mi9hE=
|
||||
github.com/hashicorp/terraform-plugin-framework v1.17.0 h1:JdX50CFrYcYFY31gkmitAEAzLKoBgsK+iaJjDC8OexY=
|
||||
github.com/hashicorp/terraform-plugin-framework v1.17.0/go.mod h1:4OUXKdHNosX+ys6rLgVlgklfxN3WHR5VHSOABeS/BM0=
|
||||
github.com/hashicorp/terraform-json v0.27.3-0.20260213134036-298b8f6b673a h1:T7AMR21kjrbeEpN+KhGlyd31XXHsSZF5zg+ivfeYte4=
|
||||
github.com/hashicorp/terraform-json v0.27.3-0.20260213134036-298b8f6b673a/go.mod h1:yjb5C2W07l8lmAzdyVgOLji0/D2IoHkR3rusBzUO4O0=
|
||||
github.com/hashicorp/terraform-plugin-docs v0.25.0 h1:qHs1V257NxVe8tv6HS4UQfNqjaPP5eUlLeDf7jYk85U=
|
||||
github.com/hashicorp/terraform-plugin-docs v0.25.0/go.mod h1:MQggCmY8zgP7R7E/cC0b0cmTvA9hSj3ZKyrrsDjRbLo=
|
||||
github.com/hashicorp/terraform-plugin-framework v1.19.0 h1:q0bwyhxAOR3vfdgbk9iplv3MlTv/dhBHTXjQOtQDoBA=
|
||||
github.com/hashicorp/terraform-plugin-framework v1.19.0/go.mod h1:YRXOBu0jvs7xp4AThBbX4mAzYaMJ1JgtFH//oGKxwLc=
|
||||
github.com/hashicorp/terraform-plugin-framework-validators v0.19.0 h1:Zz3iGgzxe/1XBkooZCewS0nJAaCFPFPHdNJd8FgE4Ow=
|
||||
github.com/hashicorp/terraform-plugin-framework-validators v0.19.0/go.mod h1:GBKTNGbGVJohU03dZ7U8wHqc2zYnMUawgCN+gC0itLc=
|
||||
github.com/hashicorp/terraform-plugin-go v0.29.0 h1:1nXKl/nSpaYIUBU1IG/EsDOX0vv+9JxAltQyDMpq5mU=
|
||||
github.com/hashicorp/terraform-plugin-go v0.29.0/go.mod h1:vYZbIyvxyy0FWSmDHChCqKvI40cFTDGSb3D8D70i9GM=
|
||||
github.com/hashicorp/terraform-plugin-go v0.31.0 h1:0Fz2r9DQ+kNNl6bx8HRxFd1TfMKUvnrOtvJPmp3Z0q8=
|
||||
github.com/hashicorp/terraform-plugin-go v0.31.0/go.mod h1:A88bDhd/cW7FnwqxQRz3slT+QY6yzbHKc6AOTtmdeS8=
|
||||
github.com/hashicorp/terraform-plugin-log v0.10.0 h1:eu2kW6/QBVdN4P3Ju2WiB2W3ObjkAsyfBsL3Wh1fj3g=
|
||||
github.com/hashicorp/terraform-plugin-log v0.10.0/go.mod h1:/9RR5Cv2aAbrqcTSdNmY1NRHP4E3ekrXRGjqORpXyB0=
|
||||
github.com/hashicorp/terraform-plugin-sdk/v2 v2.38.2 h1:sy0Bc4A/GZNdmwpVX/Its9aIweCfY9fRfY1IgmXkOj8=
|
||||
github.com/hashicorp/terraform-plugin-sdk/v2 v2.38.2/go.mod h1:MQisArXYCowb/5q4lDS/BWp5KnXiZ4lxOIyrpKBpUBE=
|
||||
github.com/hashicorp/terraform-plugin-testing v1.14.0 h1:5t4VKrjOJ0rg0sVuSJ86dz5K7PHsMO6OKrHFzDBerWA=
|
||||
github.com/hashicorp/terraform-plugin-testing v1.14.0/go.mod h1:1qfWkecyYe1Do2EEOK/5/WnTyvC8wQucUkkhiGLg5nk=
|
||||
github.com/hashicorp/terraform-plugin-sdk/v2 v2.40.1 h1:2yPUd7esMOpuTaG3y1iEla1iw+tla+3ZEkkBnmOAre4=
|
||||
github.com/hashicorp/terraform-plugin-sdk/v2 v2.40.1/go.mod h1:sq8qsxh+PwdvTQFcd17kfCoBgQo46ADNMvCpKE7t/gY=
|
||||
github.com/hashicorp/terraform-plugin-testing v1.16.0 h1:GB97nGnJ1hESpDrCjqZig38RodSF0gdRzxlDupLXP38=
|
||||
github.com/hashicorp/terraform-plugin-testing v1.16.0/go.mod h1:eQPYAy9xFMV7xtIFX8Y+wJGtUB++HBl329zCF6PBMZk=
|
||||
github.com/hashicorp/terraform-registry-address v0.4.0 h1:S1yCGomj30Sao4l5BMPjTGZmCNzuv7/GDTDX99E9gTk=
|
||||
github.com/hashicorp/terraform-registry-address v0.4.0/go.mod h1:LRS1Ay0+mAiRkUyltGT+UHWkIqTFvigGn/LbMshfflE=
|
||||
github.com/hashicorp/terraform-svchost v0.2.0 h1:wVc2vMiodOHvNZcQw/3y9af1XSomgjGSv+rv3BMCk7I=
|
||||
github.com/hashicorp/terraform-svchost v0.2.0/go.mod h1:/98rrS2yZsbppi4VGVCjwYmh8dqsKzISqK7Hli+0rcQ=
|
||||
github.com/hashicorp/terraform-svchost v0.2.1 h1:ubvrTFw3Q7CsoEaX7V06PtCTKG3wu7GyyobAoN4eF3Q=
|
||||
github.com/hashicorp/terraform-svchost v0.2.1/go.mod h1:zDMheBLvNzu7Q6o9TBvPqiZToJcSuCLXjAXxBslSky4=
|
||||
github.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8=
|
||||
github.com/hashicorp/yamux v0.1.2/go.mod h1:C+zze2n6e/7wshOZep2A70/aQU6QBRWJO/G6FT1wIns=
|
||||
github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4=
|
||||
github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||
github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI=
|
||||
github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
|
||||
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM=
|
||||
github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
|
|
@ -130,9 +158,8 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
|
|||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/ldez/go-git-cmd-wrapper/v2 v2.9.1 h1:QJRB9Gs5i/h6TVJI6yl09Qm6rNooznRiKwIw+VIxd90=
|
||||
github.com/ldez/go-git-cmd-wrapper/v2 v2.9.1/go.mod h1:0eUeas7XtKDPKQbB0KijfaMPbuQ/cIprtoTRiwaUoFg=
|
||||
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
|
|
@ -141,10 +168,13 @@ github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHP
|
|||
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-isatty v0.0.22 h1:j8l17JJ9i6VGPUFUYoTUKPSgKe/83EYU2zBC7YNKMw4=
|
||||
github.com/mattn/go-isatty v0.0.22/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4=
|
||||
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/maxatome/go-testdeep v1.14.0 h1:rRlLv1+kI8eOI3OaBXZwb3O7xY3exRzdW5QyX48g9wI=
|
||||
github.com/maxatome/go-testdeep v1.14.0/go.mod h1:lPZc/HAcJMP92l7yI6TRz1aZN5URwUBUAfUNvrclaNM=
|
||||
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
|
||||
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
|
||||
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
|
||||
github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU=
|
||||
|
|
@ -153,6 +183,7 @@ github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQ
|
|||
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
|
||||
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/oklog/run v1.2.0 h1:O8x3yXwah4A73hJdlrwo/2X6J62gE5qTMusH0dvz60E=
|
||||
|
|
@ -162,13 +193,21 @@ github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxu
|
|||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo=
|
||||
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
|
||||
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
|
||||
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
|
||||
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
|
||||
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8=
|
||||
github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY=
|
||||
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
|
||||
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
|
||||
github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g=
|
||||
github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
|
||||
github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=
|
||||
|
|
@ -176,11 +215,16 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An
|
|||
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
|
||||
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stackitcloud/stackit-sdk-go/core v0.21.1 h1:Y/PcAgM7DPYMNqum0MLv4n1mF9ieuevzcCIZYQfm3Ts=
|
||||
github.com/stackitcloud/stackit-sdk-go/core v0.21.1/go.mod h1:osMglDby4csGZ5sIfhNyYq1bS1TxIdPY88+skE/kkmI=
|
||||
github.com/stackitcloud/stackit-sdk-go/services/iaasalpha v0.1.23-alpha h1:ugpMOMUZGB0yXsWcfe97F7GCdjlexbjFuGD8ZeyMSts=
|
||||
github.com/stackitcloud/stackit-sdk-go/services/iaasalpha v0.1.23-alpha/go.mod h1:v5VGvTxLcCdJJmblbhqYalt/MFHcElDfYoy15CMhaWs=
|
||||
github.com/stackitcloud/stackit-sdk-go/core v0.26.0 h1:jQEb9gkehfp6VCP6TcYk7BI10cz4l0KM2L6hqYBH2QA=
|
||||
github.com/stackitcloud/stackit-sdk-go/core v0.26.0/go.mod h1:WU1hhxnjXw2EV7CYa1nlEvNpMiRY6CvmIOaHuL3pOaA=
|
||||
github.com/stackitcloud/stackit-sdk-go/services/postgresflex v1.8.0 h1:oWTviJKdlUxaaARJghTjOqBbarIK+7+nH3Kc3Wxn4rQ=
|
||||
github.com/stackitcloud/stackit-sdk-go/services/postgresflex v1.8.0/go.mod h1:yzlakB+f8ur4yAHR6lyCABO+HcEtZG3G2Faj6m5/uW8=
|
||||
github.com/stackitcloud/stackit-sdk-go/services/sqlserverflex v1.10.0 h1:angvO3z0TGqZtdwTDsG/tgTw9hxB76A6leUsiUXQtME=
|
||||
github.com/stackitcloud/stackit-sdk-go/services/sqlserverflex v1.10.0/go.mod h1:AiUoMAqQcOlMgDtkVJlqI7P/VGD5xjN3dYjERGnwN/M=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
|
|
@ -196,41 +240,51 @@ github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV
|
|||
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
|
||||
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/zclconf/go-cty v1.17.0 h1:seZvECve6XX4tmnvRzWtJNHdscMtYEx5R7bnnVyd/d0=
|
||||
github.com/zclconf/go-cty v1.17.0/go.mod h1:wqFzcImaLTI6A5HfsRwB0nj5n0MRZFwmey8YoFPPs3U=
|
||||
github.com/yuin/goldmark v1.7.7 h1:5m9rrB1sW3JUMToKFQfb+FGt1U7r57IHu5GrYrG2nqU=
|
||||
github.com/yuin/goldmark v1.7.7/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
|
||||
github.com/yuin/goldmark-meta v1.1.0 h1:pWw+JLHGZe8Rk0EGsMVssiNb/AaPMHfSRszZeUeiOUc=
|
||||
github.com/yuin/goldmark-meta v1.1.0/go.mod h1:U4spWENafuA7Zyg+Lj5RqK/MF+ovMYtBvXi1lBb2VP0=
|
||||
github.com/zclconf/go-cty v1.18.1 h1:yEGE8M4iIZlyKQURZNb2SnEyZlZHUcBCnx6KF81KuwM=
|
||||
github.com/zclconf/go-cty v1.18.1/go.mod h1:qpnV6EDNgC1sns/AleL1fvatHw72j+S+nS+MJ+T2CSg=
|
||||
github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo=
|
||||
github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM=
|
||||
go.abhg.dev/goldmark/frontmatter v0.2.0 h1:P8kPG0YkL12+aYk2yU3xHv4tcXzeVnN+gU0tJ5JnxRw=
|
||||
go.abhg.dev/goldmark/frontmatter v0.2.0/go.mod h1:XqrEkZuM57djk7zrlRUB02x8I5J0px76YjkOzhB4YlU=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
|
||||
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
|
||||
go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=
|
||||
go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=
|
||||
go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs=
|
||||
go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=
|
||||
go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew=
|
||||
go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=
|
||||
go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
|
||||
go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I=
|
||||
go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0=
|
||||
go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM=
|
||||
go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY=
|
||||
go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg=
|
||||
go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A=
|
||||
go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A=
|
||||
go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0=
|
||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts=
|
||||
golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos=
|
||||
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI=
|
||||
golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q=
|
||||
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME=
|
||||
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8=
|
||||
golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w=
|
||||
golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM=
|
||||
golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60=
|
||||
golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM=
|
||||
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
|
||||
golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
|
||||
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
|
@ -241,37 +295,37 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
|
||||
golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/telemetry v0.0.0-20260213145524-e0ab670178e1 h1:QNaHp8YvpPswfDNxlCmJyeesxbGOgaKf41iT9/QrErY=
|
||||
golang.org/x/telemetry v0.0.0-20260213145524-e0ab670178e1/go.mod h1:NuITXsA9cTiqnXtVk+/wrBT2Ja4X5hsfGOYRJ6kgYjs=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
|
||||
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg=
|
||||
golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM=
|
||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||
golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY=
|
||||
golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk=
|
||||
golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
|
||||
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k=
|
||||
golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0=
|
||||
golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c=
|
||||
golang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||
gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
|
||||
gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
|
||||
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 h1:mWPCjDEyshlQYzBpMNHaEof6UX1PmHcaUODUywQ0uac=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
|
||||
google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY=
|
||||
google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260504160031-60b97b32f348 h1:pfIbyB44sWzHiCpRqIen67ZQnVXSfIxWrqUMk1qwODE=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260504160031-60b97b32f348/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
||||
google.golang.org/grpc v1.81.0 h1:W3G9N3KQf3BU+YuCtGKJk0CmxQNbAISICD/9AORxLIw=
|
||||
google.golang.org/grpc v1.81.0/go.mod h1:xGH9GfzOyMTGIOXBJmXt+BX/V0kcdQbdcuwQ/zNw42I=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||
|
|
@ -282,6 +336,9 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN
|
|||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
|
|
|||
|
|
@ -2,6 +2,13 @@
|
|||
version: "2"
|
||||
run:
|
||||
concurrency: 4
|
||||
output:
|
||||
formats:
|
||||
text:
|
||||
print-linter-name: true
|
||||
print-issued-lines: true
|
||||
colors: true
|
||||
path: stdout
|
||||
linters:
|
||||
enable:
|
||||
- bodyclose
|
||||
|
|
@ -68,6 +75,10 @@ linters:
|
|||
- 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.
|
||||
|
|
@ -76,14 +87,6 @@ linters:
|
|||
- path: _test\.go
|
||||
linters:
|
||||
- gochecknoinits
|
||||
paths:
|
||||
- third_party/
|
||||
- builtin/
|
||||
- examples/
|
||||
- tools/copy.go
|
||||
- tools/main.go
|
||||
- pkg_gen/
|
||||
- cmd/
|
||||
formatters:
|
||||
enable:
|
||||
- gofmt
|
||||
|
|
@ -91,12 +94,4 @@ formatters:
|
|||
settings:
|
||||
goimports:
|
||||
local-prefixes:
|
||||
- tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview
|
||||
exclusions:
|
||||
generated: lax
|
||||
paths:
|
||||
- third_party/
|
||||
- builtin/
|
||||
- examples/
|
||||
- pkg_gen/
|
||||
- cmd/
|
||||
- tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
package testutil
|
||||
|
||||
import "testing"
|
||||
|
||||
func Equal[V comparable](t *testing.T, got, expected V) {
|
||||
t.Helper()
|
||||
|
||||
if expected != got {
|
||||
t.Errorf("assert equal failed:\ngot: %v \nexpected: %v", got, expected)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,651 +0,0 @@
|
|||
package testutil
|
||||
|
||||
import (
|
||||
"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"
|
||||
|
||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit"
|
||||
)
|
||||
|
||||
const (
|
||||
// Default location of credentials JSON
|
||||
// credentialsFilePath = ".stackit/credentials.json" //nolint:gosec // linter false positive
|
||||
serviceAccountFilePath = ".stackit/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")
|
||||
|
||||
CdnCustomEndpoint = os.Getenv("TF_ACC_CDN_CUSTOM_ENDPOINT")
|
||||
DnsCustomEndpoint = os.Getenv("TF_ACC_DNS_CUSTOM_ENDPOINT")
|
||||
GitCustomEndpoint = os.Getenv("TF_ACC_GIT_CUSTOM_ENDPOINT")
|
||||
IaaSCustomEndpoint = os.Getenv("TF_ACC_IAAS_CUSTOM_ENDPOINT")
|
||||
KMSCustomEndpoint = os.Getenv("TF_ACC_KMS_CUSTOM_ENDPOINT")
|
||||
LoadBalancerCustomEndpoint = os.Getenv("TF_ACC_LOADBALANCER_CUSTOM_ENDPOINT")
|
||||
LogMeCustomEndpoint = os.Getenv("TF_ACC_LOGME_CUSTOM_ENDPOINT")
|
||||
MariaDBCustomEndpoint = os.Getenv("TF_ACC_MARIADB_CUSTOM_ENDPOINT")
|
||||
ModelServingCustomEndpoint = os.Getenv("TF_ACC_MODELSERVING_CUSTOM_ENDPOINT")
|
||||
AuthorizationCustomEndpoint = os.Getenv("TF_ACC_authorization_custom_endpoint")
|
||||
MongoDBFlexCustomEndpoint = os.Getenv("TF_ACC_MONGODBFLEX_CUSTOM_ENDPOINT")
|
||||
OpenSearchCustomEndpoint = os.Getenv("TF_ACC_OPENSEARCH_CUSTOM_ENDPOINT")
|
||||
ObservabilityCustomEndpoint = os.Getenv("TF_ACC_OBSERVABILITY_CUSTOM_ENDPOINT")
|
||||
ObjectStorageCustomEndpoint = os.Getenv("TF_ACC_OBJECTSTORAGE_CUSTOM_ENDPOINT")
|
||||
PostgresFlexCustomEndpoint = os.Getenv("TF_ACC_POSTGRESFLEX_CUSTOM_ENDPOINT")
|
||||
RabbitMQCustomEndpoint = os.Getenv("TF_ACC_RABBITMQ_CUSTOM_ENDPOINT")
|
||||
RedisCustomEndpoint = os.Getenv("TF_ACC_REDIS_CUSTOM_ENDPOINT")
|
||||
ResourceManagerCustomEndpoint = os.Getenv("TF_ACC_RESOURCEMANAGER_CUSTOM_ENDPOINT")
|
||||
ScfCustomEndpoint = os.Getenv("TF_ACC_SCF_CUSTOM_ENDPOINT")
|
||||
SecretsManagerCustomEndpoint = os.Getenv("TF_ACC_SECRETSMANAGER_CUSTOM_ENDPOINT")
|
||||
SQLServerFlexCustomEndpoint = os.Getenv("TF_ACC_SQLSERVERFLEX_CUSTOM_ENDPOINT")
|
||||
ServerBackupCustomEndpoint = os.Getenv("TF_ACC_SERVER_BACKUP_CUSTOM_ENDPOINT")
|
||||
ServerUpdateCustomEndpoint = os.Getenv("TF_ACC_SERVER_UPDATE_CUSTOM_ENDPOINT")
|
||||
ServiceAccountCustomEndpoint = os.Getenv("TF_ACC_SERVICE_ACCOUNT_CUSTOM_ENDPOINT")
|
||||
SKECustomEndpoint = os.Getenv("TF_ACC_SKE_CUSTOM_ENDPOINT")
|
||||
)
|
||||
|
||||
// Provider config helper functions
|
||||
|
||||
func ObservabilityProviderConfig() string {
|
||||
if ObservabilityCustomEndpoint == "" {
|
||||
return `provider "stackitprivatepreview" {
|
||||
default_region = "eu01"
|
||||
}`
|
||||
}
|
||||
return fmt.Sprintf(`
|
||||
provider "stackitprivatepreview" {
|
||||
observability_custom_endpoint = "%s"
|
||||
}`,
|
||||
ObservabilityCustomEndpoint,
|
||||
)
|
||||
}
|
||||
|
||||
func CdnProviderConfig() string {
|
||||
if CdnCustomEndpoint == "" {
|
||||
return `
|
||||
provider "stackitprivatepreview" {
|
||||
enable_beta_resources = true
|
||||
}`
|
||||
}
|
||||
return fmt.Sprintf(`
|
||||
provider "stackitprivatepreview" {
|
||||
cdn_custom_endpoint = "%s"
|
||||
enable_beta_resources = true
|
||||
}`,
|
||||
CdnCustomEndpoint,
|
||||
)
|
||||
}
|
||||
|
||||
func DnsProviderConfig() string {
|
||||
if DnsCustomEndpoint == "" {
|
||||
return `provider "stackitprivatepreview" {}`
|
||||
}
|
||||
return fmt.Sprintf(`
|
||||
provider "stackitprivatepreview" {
|
||||
dns_custom_endpoint = "%s"
|
||||
}`,
|
||||
DnsCustomEndpoint,
|
||||
)
|
||||
}
|
||||
|
||||
func IaaSProviderConfig() string {
|
||||
if IaaSCustomEndpoint == "" {
|
||||
return `
|
||||
provider "stackitprivatepreview" {
|
||||
default_region = "eu01"
|
||||
}`
|
||||
}
|
||||
return fmt.Sprintf(`
|
||||
provider "stackitprivatepreview" {
|
||||
iaas_custom_endpoint = "%s"
|
||||
}`,
|
||||
IaaSCustomEndpoint,
|
||||
)
|
||||
}
|
||||
|
||||
func IaaSProviderConfigWithBetaResourcesEnabled() string {
|
||||
if IaaSCustomEndpoint == "" {
|
||||
return `
|
||||
provider "stackitprivatepreview" {
|
||||
enable_beta_resources = true
|
||||
default_region = "eu01"
|
||||
}`
|
||||
}
|
||||
return fmt.Sprintf(`
|
||||
provider "stackitprivatepreview" {
|
||||
enable_beta_resources = true
|
||||
iaas_custom_endpoint = "%s"
|
||||
}`,
|
||||
IaaSCustomEndpoint,
|
||||
)
|
||||
}
|
||||
|
||||
func IaaSProviderConfigWithExperiments() string {
|
||||
if IaaSCustomEndpoint == "" {
|
||||
return `
|
||||
provider "stackitprivatepreview" {
|
||||
default_region = "eu01"
|
||||
experiments = [ "routing-tables", "network" ]
|
||||
}`
|
||||
}
|
||||
return fmt.Sprintf(`
|
||||
provider "stackitprivatepreview" {
|
||||
iaas_custom_endpoint = "%s"
|
||||
experiments = [ "routing-tables", "network" ]
|
||||
}`,
|
||||
IaaSCustomEndpoint,
|
||||
)
|
||||
}
|
||||
|
||||
func KMSProviderConfig() string {
|
||||
if KMSCustomEndpoint == "" {
|
||||
return `
|
||||
provider "stackitprivatepreview" {
|
||||
default_region = "eu01"
|
||||
}`
|
||||
}
|
||||
return fmt.Sprintf(`
|
||||
provider "stackitprivatepreview" {
|
||||
kms_custom_endpoint = "%s"
|
||||
}`,
|
||||
KMSCustomEndpoint,
|
||||
)
|
||||
}
|
||||
|
||||
func LoadBalancerProviderConfig() string {
|
||||
if LoadBalancerCustomEndpoint == "" {
|
||||
return `
|
||||
provider "stackitprivatepreview" {
|
||||
default_region = "eu01"
|
||||
}`
|
||||
}
|
||||
return fmt.Sprintf(`
|
||||
provider "stackitprivatepreview" {
|
||||
loadbalancer_custom_endpoint = "%s"
|
||||
}`,
|
||||
LoadBalancerCustomEndpoint,
|
||||
)
|
||||
}
|
||||
|
||||
func LogMeProviderConfig() string {
|
||||
if LogMeCustomEndpoint == "" {
|
||||
return `
|
||||
provider "stackitprivatepreview" {
|
||||
default_region = "eu01"
|
||||
}`
|
||||
}
|
||||
return fmt.Sprintf(`
|
||||
provider "stackitprivatepreview" {
|
||||
logme_custom_endpoint = "%s"
|
||||
}`,
|
||||
LogMeCustomEndpoint,
|
||||
)
|
||||
}
|
||||
|
||||
func MariaDBProviderConfig() string {
|
||||
if MariaDBCustomEndpoint == "" {
|
||||
return `
|
||||
provider "stackitprivatepreview" {
|
||||
default_region = "eu01"
|
||||
}`
|
||||
}
|
||||
return fmt.Sprintf(`
|
||||
provider "stackitprivatepreview" {
|
||||
mariadb_custom_endpoint = "%s"
|
||||
}`,
|
||||
MariaDBCustomEndpoint,
|
||||
)
|
||||
}
|
||||
|
||||
func ModelServingProviderConfig() string {
|
||||
if ModelServingCustomEndpoint == "" {
|
||||
return `
|
||||
provider "stackitprivatepreview" {
|
||||
default_region = "eu01"
|
||||
}
|
||||
`
|
||||
}
|
||||
return fmt.Sprintf(`
|
||||
provider "stackitprivatepreview" {
|
||||
modelserving_custom_endpoint = "%s"
|
||||
}`,
|
||||
ModelServingCustomEndpoint,
|
||||
)
|
||||
}
|
||||
|
||||
func MongoDBFlexProviderConfig() string {
|
||||
if MongoDBFlexCustomEndpoint == "" {
|
||||
return `
|
||||
provider "stackitprivatepreview" {
|
||||
default_region = "eu01"
|
||||
}`
|
||||
}
|
||||
return fmt.Sprintf(`
|
||||
provider "stackitprivatepreview" {
|
||||
mongodbflex_custom_endpoint = "%s"
|
||||
}`,
|
||||
MongoDBFlexCustomEndpoint,
|
||||
)
|
||||
}
|
||||
|
||||
func ObjectStorageProviderConfig() string {
|
||||
if ObjectStorageCustomEndpoint == "" {
|
||||
return `
|
||||
provider "stackitprivatepreview" {
|
||||
default_region = "eu01"
|
||||
}`
|
||||
}
|
||||
return fmt.Sprintf(`
|
||||
provider "stackitprivatepreview" {
|
||||
objectstorage_custom_endpoint = "%s"
|
||||
}`,
|
||||
ObjectStorageCustomEndpoint,
|
||||
)
|
||||
}
|
||||
|
||||
func OpenSearchProviderConfig() string {
|
||||
if OpenSearchCustomEndpoint == "" {
|
||||
return `
|
||||
provider "stackitprivatepreview" {
|
||||
default_region = "eu01"
|
||||
}`
|
||||
}
|
||||
return fmt.Sprintf(`
|
||||
provider "stackitprivatepreview" {
|
||||
opensearch_custom_endpoint = "%s"
|
||||
}`,
|
||||
OpenSearchCustomEndpoint,
|
||||
)
|
||||
}
|
||||
|
||||
func PostgresFlexProviderConfig(saFile string) string {
|
||||
if PostgresFlexCustomEndpoint == "" {
|
||||
return fmt.Sprintf(`
|
||||
provider "stackitprivatepreview" {
|
||||
default_region = "eu01"
|
||||
service_account_key_path = "%s"
|
||||
}`, saFile)
|
||||
}
|
||||
return fmt.Sprintf(`
|
||||
provider "stackitprivatepreview" {
|
||||
service_account_key_path = "%s"
|
||||
postgresflex_custom_endpoint = "%s"
|
||||
}`,
|
||||
saFile,
|
||||
PostgresFlexCustomEndpoint,
|
||||
)
|
||||
}
|
||||
|
||||
func RabbitMQProviderConfig() string {
|
||||
if RabbitMQCustomEndpoint == "" {
|
||||
return `
|
||||
provider "stackitprivatepreview" {
|
||||
default_region = "eu01"
|
||||
}`
|
||||
}
|
||||
return fmt.Sprintf(`
|
||||
provider "stackitprivatepreview" {
|
||||
rabbitmq_custom_endpoint = "%s"
|
||||
}`,
|
||||
RabbitMQCustomEndpoint,
|
||||
)
|
||||
}
|
||||
|
||||
func RedisProviderConfig() string {
|
||||
if RedisCustomEndpoint == "" {
|
||||
return `
|
||||
provider "stackitprivatepreview" {
|
||||
default_region = "eu01"
|
||||
}`
|
||||
}
|
||||
return fmt.Sprintf(`
|
||||
provider "stackitprivatepreview" {
|
||||
redis_custom_endpoint = "%s"
|
||||
}`,
|
||||
RedisCustomEndpoint,
|
||||
)
|
||||
}
|
||||
|
||||
func ResourceManagerProviderConfig() string {
|
||||
key := GetTestProjectServiceAccountJson("")
|
||||
if ResourceManagerCustomEndpoint == "" || AuthorizationCustomEndpoint == "" {
|
||||
return fmt.Sprintf(`
|
||||
provider "stackitprivatepreview" {
|
||||
service_account_key = "%s"
|
||||
}`,
|
||||
key,
|
||||
)
|
||||
}
|
||||
return fmt.Sprintf(`
|
||||
provider "stackitprivatepreview" {
|
||||
resourcemanager_custom_endpoint = "%s"
|
||||
authorization_custom_endpoint = "%s"
|
||||
service_account_token = "%s"
|
||||
}`,
|
||||
ResourceManagerCustomEndpoint,
|
||||
AuthorizationCustomEndpoint,
|
||||
key,
|
||||
)
|
||||
}
|
||||
|
||||
func SecretsManagerProviderConfig() string {
|
||||
if SecretsManagerCustomEndpoint == "" {
|
||||
return `
|
||||
provider "stackitprivatepreview" {
|
||||
default_region = "eu01"
|
||||
}`
|
||||
}
|
||||
return fmt.Sprintf(`
|
||||
provider "stackitprivatepreview" {
|
||||
secretsmanager_custom_endpoint = "%s"
|
||||
}`,
|
||||
SecretsManagerCustomEndpoint,
|
||||
)
|
||||
}
|
||||
|
||||
func SQLServerFlexProviderConfig(saFile string) string {
|
||||
if SQLServerFlexCustomEndpoint == "" {
|
||||
return fmt.Sprintf(`
|
||||
provider "stackitprivatepreview" {
|
||||
default_region = "eu01"
|
||||
service_account_key_path = "%s"
|
||||
}`, saFile)
|
||||
}
|
||||
return fmt.Sprintf(`
|
||||
provider "stackitprivatepreview" {
|
||||
service_account_key_path = "%s"
|
||||
sqlserverflex_custom_endpoint = "%s"
|
||||
}`,
|
||||
saFile,
|
||||
SQLServerFlexCustomEndpoint,
|
||||
)
|
||||
}
|
||||
|
||||
func ServerBackupProviderConfig() string {
|
||||
if ServerBackupCustomEndpoint == "" {
|
||||
return `
|
||||
provider "stackitprivatepreview" {
|
||||
default_region = "eu01"
|
||||
enable_beta_resources = true
|
||||
}`
|
||||
}
|
||||
return fmt.Sprintf(`
|
||||
provider "stackitprivatepreview" {
|
||||
server_backup_custom_endpoint = "%s"
|
||||
enable_beta_resources = true
|
||||
}`,
|
||||
ServerBackupCustomEndpoint,
|
||||
)
|
||||
}
|
||||
|
||||
func ServerUpdateProviderConfig() string {
|
||||
if ServerUpdateCustomEndpoint == "" {
|
||||
return `
|
||||
provider "stackitprivatepreview" {
|
||||
default_region = "eu01"
|
||||
enable_beta_resources = true
|
||||
}`
|
||||
}
|
||||
return fmt.Sprintf(`
|
||||
provider "stackitprivatepreview" {
|
||||
server_update_custom_endpoint = "%s"
|
||||
enable_beta_resources = true
|
||||
}`,
|
||||
ServerUpdateCustomEndpoint,
|
||||
)
|
||||
}
|
||||
|
||||
func SKEProviderConfig() string {
|
||||
if SKECustomEndpoint == "" {
|
||||
return `
|
||||
provider "stackitprivatepreview" {
|
||||
default_region = "eu01"
|
||||
}`
|
||||
}
|
||||
return fmt.Sprintf(`
|
||||
provider "stackitprivatepreview" {
|
||||
ske_custom_endpoint = "%s"
|
||||
}`,
|
||||
SKECustomEndpoint,
|
||||
)
|
||||
}
|
||||
|
||||
func AuthorizationProviderConfig() string {
|
||||
if AuthorizationCustomEndpoint == "" {
|
||||
return `
|
||||
provider "stackitprivatepreview" {
|
||||
default_region = "eu01"
|
||||
experiments = ["iam"]
|
||||
}`
|
||||
}
|
||||
return fmt.Sprintf(`
|
||||
provider "stackitprivatepreview" {
|
||||
authorization_custom_endpoint = "%s"
|
||||
experiments = ["iam"]
|
||||
}`,
|
||||
AuthorizationCustomEndpoint,
|
||||
)
|
||||
}
|
||||
|
||||
func ServiceAccountProviderConfig() string {
|
||||
if ServiceAccountCustomEndpoint == "" {
|
||||
return `
|
||||
provider "stackitprivatepreview" {
|
||||
default_region = "eu01"
|
||||
enable_beta_resources = true
|
||||
}`
|
||||
}
|
||||
return fmt.Sprintf(`
|
||||
provider "stackitprivatepreview" {
|
||||
service_account_custom_endpoint = "%s"
|
||||
enable_beta_resources = true
|
||||
}`,
|
||||
ServiceAccountCustomEndpoint,
|
||||
)
|
||||
}
|
||||
|
||||
func GitProviderConfig() string {
|
||||
if GitCustomEndpoint == "" {
|
||||
return `
|
||||
provider "stackitprivatepreview" {
|
||||
default_region = "eu01"
|
||||
enable_beta_resources = true
|
||||
}`
|
||||
}
|
||||
return fmt.Sprintf(`
|
||||
provider "stackitprivatepreview" {
|
||||
git_custom_endpoint = "%s"
|
||||
enable_beta_resources = true
|
||||
}`,
|
||||
GitCustomEndpoint,
|
||||
)
|
||||
}
|
||||
|
||||
func ScfProviderConfig() string {
|
||||
if ScfCustomEndpoint == "" {
|
||||
return `
|
||||
provider "stackitprivatepreview" {
|
||||
default_region = "eu01"
|
||||
}`
|
||||
}
|
||||
return fmt.Sprintf(`
|
||||
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 GetTestProjectServiceAccountJson(path string) string {
|
||||
var err error
|
||||
token, tokenSet := os.LookupEnv("TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_JSON")
|
||||
if !tokenSet || token == "" {
|
||||
token, err = readTestServiceAccountJsonFromFile(path)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
return token
|
||||
}
|
||||
|
||||
//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, customPathSet := os.LookupEnv("STACKIT_SERVICE_ACCOUNT_PATH")
|
||||
if !customPathSet || customPath == "" {
|
||||
path = serviceAccountFilePath
|
||||
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)
|
||||
}
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
// Copyright (c) STACKIT
|
||||
|
||||
package testutil
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-testing/config"
|
||||
)
|
||||
|
||||
func TestConvertConfigVariable(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
variable config.Variable
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "string",
|
||||
variable: config.StringVariable("test"),
|
||||
want: "test",
|
||||
},
|
||||
{
|
||||
name: "bool: true",
|
||||
variable: config.BoolVariable(true),
|
||||
want: "true",
|
||||
},
|
||||
{
|
||||
name: "bool: false",
|
||||
variable: config.BoolVariable(false),
|
||||
want: "false",
|
||||
},
|
||||
{
|
||||
name: "integer",
|
||||
variable: config.IntegerVariable(10),
|
||||
want: "10",
|
||||
},
|
||||
{
|
||||
name: "quoted string",
|
||||
variable: config.StringVariable(`instance =~ ".*"`),
|
||||
want: `instance =~ ".*"`,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := ConvertConfigVariable(tt.variable); got != tt.want {
|
||||
t.Errorf("ConvertConfigVariable() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -20,13 +20,20 @@ func TestName() string {
|
|||
}
|
||||
|
||||
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$`),
|
||||
httpmock.RegisterNoResponder(
|
||||
func(req *http.Request) (*http.Response, error) {
|
||||
return httpmock.NewStringResponse(http.StatusOK, httpmock.File("../../services/languages/tests/datasource/Validate_Read/get_languages.json").String()), nil
|
||||
})
|
||||
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
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,9 +53,9 @@ func CreateTemporaryHome(createValidCredentialsFile bool, t *testing.T) string {
|
|||
|
||||
// Define content, default = invalid token
|
||||
token := "foo_token"
|
||||
if createValidCredentialsFile {
|
||||
token = GetTestProjectServiceAccountJson("")
|
||||
}
|
||||
// if createValidCredentialsFile {
|
||||
// token = GetTestProjectServiceAccountJson("")
|
||||
//}
|
||||
if _, err = file.WriteString(token); err != nil {
|
||||
t.Fatalf("Error writing to file: %v", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -293,25 +293,24 @@ func RedisProviderConfig() string {
|
|||
)
|
||||
}
|
||||
|
||||
func ResourceManagerProviderConfig() string {
|
||||
key := GetTestProjectServiceAccountJson("")
|
||||
func ResourceManagerProviderConfig(saKeyPath string) string {
|
||||
if ResourceManagerCustomEndpoint == "" || AuthorizationCustomEndpoint == "" {
|
||||
return fmt.Sprintf(`
|
||||
provider "stackitprivatepreview" {
|
||||
service_account_key = "%s"
|
||||
service_account_key_path = "%s"
|
||||
}`,
|
||||
key,
|
||||
saKeyPath,
|
||||
)
|
||||
}
|
||||
return fmt.Sprintf(`
|
||||
provider "stackitprivatepreview" {
|
||||
resourcemanager_custom_endpoint = "%s"
|
||||
authorization_custom_endpoint = "%s"
|
||||
service_account_token = "%s"
|
||||
service_account_key_path = "%s"
|
||||
}`,
|
||||
ResourceManagerCustomEndpoint,
|
||||
AuthorizationCustomEndpoint,
|
||||
key,
|
||||
saKeyPath,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import (
|
|||
"log/slog"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
|
@ -20,9 +19,8 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
// Default location of credentials JSON
|
||||
// credentialsFilePath = ".stackit/credentials.json" //nolint:gosec // linter false positive
|
||||
serviceAccountFilePath = ".stackit/service_account.json"
|
||||
// Default location of service account JSON
|
||||
serviceAccountFilePath = "service_account.json"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -101,17 +99,17 @@ func ResourceNameWithDateTime(name string) string {
|
|||
return fmt.Sprintf("tf-acc-%s-%s", name, dateTimeTrimmed)
|
||||
}
|
||||
|
||||
func GetTestProjectServiceAccountJson(path string) string {
|
||||
var err error
|
||||
token, tokenSet := os.LookupEnv("TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_JSON")
|
||||
if !tokenSet || token == "" {
|
||||
token, err = readTestServiceAccountJsonFromFile(path)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
return token
|
||||
}
|
||||
// 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
|
||||
|
|
@ -155,27 +153,30 @@ func GetTestProjectServiceAccountJson(path string) string {
|
|||
// return credentials.TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_TOKEN, nil
|
||||
//}
|
||||
|
||||
func readTestServiceAccountJsonFromFile(path string) (string, error) {
|
||||
if path == "" {
|
||||
customPath, customPathSet := os.LookupEnv("STACKIT_SERVICE_ACCOUNT_PATH")
|
||||
if !customPathSet || customPath == "" {
|
||||
path = serviceAccountFilePath
|
||||
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 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)
|
||||
|
|
|
|||
38
sample/alpha-from-registry/key.tf
Normal file
38
sample/alpha-from-registry/key.tf
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
resource "stackit_kms_keyring" "mshalpha-keyring" {
|
||||
project_id = var.project_id
|
||||
display_name = "msh-alpha-tests"
|
||||
description = "This is a test keyring for private endpoints"
|
||||
}
|
||||
|
||||
resource "stackit_kms_key" "mshalpha-key01" {
|
||||
project_id = var.project_id
|
||||
keyring_id = stackit_kms_keyring.mshalpha-keyring.keyring_id
|
||||
display_name = "mshalpha-key01"
|
||||
protection = "software"
|
||||
algorithm = "aes_256_gcm"
|
||||
purpose = "symmetric_encrypt_decrypt"
|
||||
access_scope = "SNA"
|
||||
}
|
||||
|
||||
output "keyid" {
|
||||
value = stackit_kms_key.mshalpha-key01.key_id
|
||||
}
|
||||
|
||||
# (because stackit_kms_key.key001 is not in configuration)
|
||||
resource "stackit_kms_key" "key001" {
|
||||
access_scope = "SNA"
|
||||
algorithm = "aes_256_gcm"
|
||||
display_name = "msh-key-sna01"
|
||||
keyring_id = stackit_kms_keyring.keyring001.keyring_id
|
||||
project_id = var.project_id
|
||||
protection = "software"
|
||||
purpose = "symmetric_encrypt_decrypt"
|
||||
}
|
||||
|
||||
# stackit_kms_keyring.keyring001 will be destroyed
|
||||
# (because stackit_kms_keyring.keyring001 is not in configuration)
|
||||
resource "stackit_kms_keyring" "keyring001" {
|
||||
description = "This is a test keyring for private endpoints"
|
||||
display_name = "msh-keyring-sna01"
|
||||
project_id = var.project_id
|
||||
}
|
||||
96
sample/alpha-from-registry/postresql.tf
Normal file
96
sample/alpha-from-registry/postresql.tf
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
|
||||
data "stackitprivatepreview_postgresflexalpha_flavor" "pgsql_flavor" {
|
||||
project_id = var.project_id
|
||||
region = "eu01"
|
||||
cpu = 2
|
||||
ram = 4
|
||||
node_type = "Single"
|
||||
storage_class = "premium-perf2-stackit"
|
||||
}
|
||||
|
||||
resource "stackitprivatepreview_postgresflexalpha_instance" "msh-alpha-sna-enc" {
|
||||
project_id = var.project_id
|
||||
name = "msh-alpha-sna-enc"
|
||||
backup_schedule = "0 0 * * *"
|
||||
retention_days = 45
|
||||
flavor_id = data.stackitprivatepreview_postgresflexalpha_flavor.pgsql_flavor.flavor_id
|
||||
replicas = 1
|
||||
storage = {
|
||||
performance_class = "premium-perf2-stackit"
|
||||
size = 10
|
||||
}
|
||||
encryption = {
|
||||
kek_key_id = stackit_kms_key.mshalpha-key01.key_id
|
||||
kek_key_ring_id = stackit_kms_keyring.mshalpha-keyring.keyring_id
|
||||
kek_key_version = 1
|
||||
service_account = var.sa_email
|
||||
}
|
||||
network = {
|
||||
acl = ["0.0.0.0/0", "193.148.160.0/19", "170.85.2.177/32"]
|
||||
access_scope = "SNA"
|
||||
}
|
||||
version = 17
|
||||
}
|
||||
|
||||
resource "stackitprivatepreview_postgresflexalpha_instance" "msh-alpha-nosna-noenc" {
|
||||
project_id = var.project_id
|
||||
name = "msh-alpha-nosna-enc"
|
||||
backup_schedule = "0 0 * * *"
|
||||
retention_days = 45
|
||||
flavor_id = data.stackitprivatepreview_postgresflexalpha_flavor.pgsql_flavor.flavor_id
|
||||
replicas = 1
|
||||
storage = {
|
||||
performance_class = "premium-perf2-stackit"
|
||||
size = 10
|
||||
}
|
||||
network = {
|
||||
acl = ["0.0.0.0/0", "193.148.160.0/19", "170.85.2.177/32"]
|
||||
access_scope = "PUBLIC"
|
||||
}
|
||||
version = 16
|
||||
}
|
||||
|
||||
resource "stackitprivatepreview_postgresflexalpha_user" "ptlsdbadminuser" {
|
||||
project_id = var.project_id
|
||||
instance_id = stackitprivatepreview_postgresflexalpha_instance.msh-alpha-sna-enc.instance_id
|
||||
name = var.db_admin_username
|
||||
roles = ["createdb", "login"]
|
||||
# roles = ["createdb", "login", "createrole"]
|
||||
}
|
||||
|
||||
resource "stackitprivatepreview_postgresflexalpha_user" "ptlsdbuser" {
|
||||
project_id = var.project_id
|
||||
instance_id = stackitprivatepreview_postgresflexalpha_instance.msh-alpha-sna-enc.instance_id
|
||||
name = var.db_username
|
||||
roles = ["login"]
|
||||
# roles = ["createdb", "login", "createrole"]
|
||||
}
|
||||
|
||||
resource "stackitprivatepreview_postgresflexalpha_database" "example" {
|
||||
count = 5
|
||||
depends_on = [stackitprivatepreview_postgresflexalpha_user.ptlsdbadminuser]
|
||||
project_id = var.project_id
|
||||
instance_id = stackitprivatepreview_postgresflexalpha_instance.msh-alpha-sna-enc.instance_id
|
||||
name = "${var.db_name}${count.index}"
|
||||
owner = var.db_admin_username
|
||||
}
|
||||
|
||||
# data "stackitprivatepreview_postgresflexalpha_instance" "datapsql" {
|
||||
# project_id = var.project_id
|
||||
# instance_id = var.instance_id
|
||||
# region = "eu01"
|
||||
# }
|
||||
|
||||
# output "psql_instance_id" {
|
||||
# value = data.stackitprivatepreview_postgresflexalpha_instance.datapsql.instance_id
|
||||
# }
|
||||
|
||||
output "psql_user_password" {
|
||||
value = stackitprivatepreview_postgresflexalpha_user.ptlsdbuser.password
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
# output "psql_user_conn" {
|
||||
# value = stackitprivatepreview_postgresflexalpha_user.ptlsdbuser.connection_string
|
||||
# sensitive = true
|
||||
# }
|
||||
24
sample/alpha-from-registry/providers.tf
Normal file
24
sample/alpha-from-registry/providers.tf
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
|
||||
terraform {
|
||||
required_providers {
|
||||
stackit = {
|
||||
source = "registry.terraform.io/stackitcloud/stackit"
|
||||
version = "~> 0.70"
|
||||
}
|
||||
stackitprivatepreview = {
|
||||
source = "tfregistry.sysops.stackit.rocks/mhenselin/stackitprivatepreview"
|
||||
version = ">=0.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "stackit" {
|
||||
default_region = "eu01"
|
||||
enable_beta_resources = true
|
||||
service_account_key_path = "../service_account.json"
|
||||
}
|
||||
|
||||
provider "stackitprivatepreview" {
|
||||
default_region = "eu01"
|
||||
service_account_key_path = "../service_account.json"
|
||||
}
|
||||
57
sample/kms/kms.tf
Normal file
57
sample/kms/kms.tf
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
resource "stackit_kms_keyring" "keyring001" {
|
||||
project_id = var.project_id
|
||||
display_name = "msh-keyring-sna01"
|
||||
description = "This is a test keyring for private endpoints"
|
||||
}
|
||||
|
||||
resource "stackit_kms_key" "key001" {
|
||||
project_id = var.project_id
|
||||
keyring_id = stackit_kms_keyring.keyring001.keyring_id
|
||||
display_name = "msh-key-sna01"
|
||||
protection = "software"
|
||||
algorithm = "aes_256_gcm"
|
||||
purpose = "symmetric_encrypt_decrypt"
|
||||
access_scope = "SNA"
|
||||
}
|
||||
|
||||
|
||||
# data "stackitprivatepreview_sqlserverflexalpha_instance" "test" {
|
||||
# project_id = var.project_id
|
||||
# instance_id = var.instance_id
|
||||
# region = "eu01"
|
||||
# }
|
||||
|
||||
output "key_ring_id" {
|
||||
value = stackit_kms_keyring.keyring001.id
|
||||
}
|
||||
|
||||
resource "stackit_kms_keyring" "keyring001yy" {
|
||||
project_id = var.project_id
|
||||
display_name = "msh-kr-sna01"
|
||||
description = "This is a test keyring for private endpoints"
|
||||
}
|
||||
|
||||
resource "stackit_kms_key" "key001yy" {
|
||||
project_id = var.project_id
|
||||
keyring_id = stackit_kms_keyring.keyring001yy.keyring_id
|
||||
display_name = "msh-k-001"
|
||||
protection = "software"
|
||||
algorithm = "aes_256_gcm"
|
||||
purpose = "symmetric_encrypt_decrypt"
|
||||
access_scope = "SNA"
|
||||
}
|
||||
|
||||
|
||||
# data "stackitprivatepreview_sqlserverflexalpha_instance" "test" {
|
||||
# project_id = var.project_id
|
||||
# instance_id = var.instance_id
|
||||
# region = "eu01"
|
||||
# }
|
||||
|
||||
output "key_ring_idxx" {
|
||||
value = stackit_kms_keyring.keyring001yy.id
|
||||
}
|
||||
|
||||
output "key_id" {
|
||||
value = stackit_kms_key.key001yy.id
|
||||
}
|
||||
25
sample/kms/providers.tf
Normal file
25
sample/kms/providers.tf
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
terraform {
|
||||
required_providers {
|
||||
stackit = {
|
||||
source = "registry.terraform.io/stackitcloud/stackit"
|
||||
version = "~> 0.70"
|
||||
}
|
||||
# stackitprivatepreview = {
|
||||
# source = "tfregistry.sysops.stackit.rocks/mhenselin/stackitprivatepreview"
|
||||
# version = "= 0.0.2-alpha"
|
||||
# }
|
||||
}
|
||||
}
|
||||
|
||||
provider "stackit" {
|
||||
default_region = "eu01"
|
||||
enable_beta_resources = true
|
||||
service_account_key_path = "../service_account.json"
|
||||
}
|
||||
|
||||
# provider "stackitprivatepreview" {
|
||||
# default_region = "eu01"
|
||||
# enable_beta_resources = true
|
||||
# service_account_key_path = "../service_account.json"
|
||||
# }
|
||||
4
sample/pg_import/outputs.tf
Normal file
4
sample/pg_import/outputs.tf
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#
|
||||
# output "postgres_flavor" {
|
||||
# value = data.stackitprivatepreview_postgresflexalpha_flavor.pgsql_flavor.flavor_id
|
||||
# }
|
||||
45
sample/pg_import/postresql.tf
Normal file
45
sample/pg_import/postresql.tf
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
|
||||
data "stackitprivatepreview_postgresflexalpha_flavor" "pgsql_flavor" {
|
||||
project_id = var.project_id
|
||||
region = "eu01"
|
||||
cpu = 2
|
||||
ram = 4
|
||||
node_type = "Single"
|
||||
storage_class = "premium-perf2-stackit"
|
||||
}
|
||||
|
||||
resource "stackitprivatepreview_postgresflexalpha_instance" "import_for_deletion" {
|
||||
project_id = var.project_id
|
||||
name = "mshpetest2"
|
||||
backup_schedule = "0 0 * * *"
|
||||
retention_days = 45
|
||||
flavor_id = data.stackitprivatepreview_postgresflexalpha_flavor.pgsql_flavor.flavor_id
|
||||
replicas = 1
|
||||
storage = {
|
||||
# class = "premium-perf2-stackit"
|
||||
performance_class = "premium-perf2-stackit"
|
||||
size = 10
|
||||
}
|
||||
encryption = {
|
||||
# key_id = stackit_kms_key.key.key_id
|
||||
# keyring_id = stackit_kms_keyring.keyring.keyring_id
|
||||
kek_key_id = var.key_id
|
||||
kek_key_ring_id = var.keyring_id
|
||||
kek_key_version = var.key_version
|
||||
service_account = var.sa_email
|
||||
}
|
||||
network = {
|
||||
acl = ["0.0.0.0/0", "193.148.160.0/19", "170.85.2.177/32"]
|
||||
access_scope = "PUBLIC"
|
||||
}
|
||||
version = 14
|
||||
}
|
||||
|
||||
import {
|
||||
to = stackitprivatepreview_postgresflexalpha_instance.import_for_deletion
|
||||
identity = {
|
||||
project_id = var.project_id
|
||||
region = "eu01"
|
||||
instance_id = "d52b5d4c-be3f-4c14-a107-330dab99fd2e"
|
||||
}
|
||||
}
|
||||
25
sample/pg_import/providers.tf
Normal file
25
sample/pg_import/providers.tf
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
terraform {
|
||||
required_providers {
|
||||
# stackit = {
|
||||
# source = "registry.terraform.io/stackitcloud/stackit"
|
||||
# version = "~> 0.70"
|
||||
# }
|
||||
stackitprivatepreview = {
|
||||
source = "tfregistry.sysops.stackit.rocks/mhenselin/stackitprivatepreview"
|
||||
version = "> 0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# provider "stackit" {
|
||||
# default_region = "eu01"
|
||||
# enable_beta_resources = true
|
||||
# service_account_key_path = "./service_account.json"
|
||||
# }
|
||||
|
||||
provider "stackitprivatepreview" {
|
||||
default_region = "eu01"
|
||||
enable_beta_resources = true
|
||||
service_account_key_path = "../service_account.json"
|
||||
}
|
||||
11
sample/pg_import/variables.tf.example
Normal file
11
sample/pg_import/variables.tf.example
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
variable "project_id" {
|
||||
default = "<PROJECT ID UUID>"
|
||||
}
|
||||
|
||||
variable "sa_email" {
|
||||
default = "<SERVICE ACCOUNT EMAIL>"
|
||||
}
|
||||
|
||||
variable "db_username" {
|
||||
default = "<DB USERNAME>"
|
||||
}
|
||||
0
sample/pg_instance/outputs.tf
Normal file
0
sample/pg_instance/outputs.tf
Normal file
17
sample/pg_instance/postresql.tf
Normal file
17
sample/pg_instance/postresql.tf
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
|
||||
data "stackitprivatepreview_postgresflexalpha_flavor" "pgsql_flavor" {
|
||||
project_id = var.project_id
|
||||
region = "eu01"
|
||||
cpu = 2
|
||||
ram = 4
|
||||
node_type = "Single"
|
||||
storage_class = "premium-perf2-stackit"
|
||||
}
|
||||
data "stackitprivatepreview_postgresflexalpha_flavor" "pgsql_flavor2"{
|
||||
project_id = var.project_id
|
||||
region = "eu01"
|
||||
cpu = 2
|
||||
ram = 4
|
||||
node_type = "Single"
|
||||
storage_class = "premium-perf2-stackit"
|
||||
}
|
||||
25
sample/pg_instance/providers.tf
Normal file
25
sample/pg_instance/providers.tf
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
terraform {
|
||||
required_providers {
|
||||
# stackit = {
|
||||
# source = "registry.terraform.io/stackitcloud/stackit"
|
||||
# version = "~> 0.70"
|
||||
# }
|
||||
stackitprivatepreview = {
|
||||
source = "tfregistry.sysops.stackit.rocks/mhenselin/stackitprivatepreview"
|
||||
version = "> 0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# provider "stackit" {
|
||||
# default_region = "eu01"
|
||||
# enable_beta_resources = true
|
||||
# service_account_key_path = "./service_account.json"
|
||||
# }
|
||||
|
||||
provider "stackitprivatepreview" {
|
||||
default_region = "eu01"
|
||||
enable_beta_resources = true
|
||||
service_account_key_path = "/home/henselinm/Development/PTLS/terraform-provider-stackit-MSH/sample/pg_instance/service_account.json"
|
||||
}
|
||||
11
sample/pg_instance/variables.tf.example
Normal file
11
sample/pg_instance/variables.tf.example
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
variable "project_id" {
|
||||
default = "<PROJECT ID UUID>"
|
||||
}
|
||||
|
||||
variable "sa_email" {
|
||||
default = "<SERVICE ACCOUNT EMAIL>"
|
||||
}
|
||||
|
||||
variable "db_username" {
|
||||
default = "<DB USERNAME>"
|
||||
}
|
||||
|
|
@ -13,7 +13,11 @@ resource "stackitprivatepreview_postgresflexalpha_instance" "msh-sna-pe-example"
|
|||
name = "mshpetest2"
|
||||
backup_schedule = "0 0 * * *"
|
||||
retention_days = 45
|
||||
flavor_id = data.stackitprivatepreview_postgresflexalpha_flavor.pgsql_flavor.flavor_id
|
||||
# flavor_id = data.stackitprivatepreview_postgresflexalpha_flavor.pgsql_flavor.flavor_id
|
||||
flavor = {
|
||||
cpu = 2
|
||||
ram = 4
|
||||
}
|
||||
replicas = 1
|
||||
storage = {
|
||||
# class = "premium-perf2-stackit"
|
||||
|
|
@ -66,7 +70,8 @@ resource "stackitprivatepreview_postgresflexalpha_user" "ptlsdbadminuser" {
|
|||
project_id = var.project_id
|
||||
instance_id = stackitprivatepreview_postgresflexalpha_instance.msh-sna-pe-example.instance_id
|
||||
name = var.db_admin_username
|
||||
roles = ["createdb", "login", "login"]
|
||||
roles = ["createdb", "login"]
|
||||
# roles = ["createdb", "login", "login"]
|
||||
# roles = ["createdb", "login", "createrole"]
|
||||
}
|
||||
|
||||
|
|
@ -110,7 +115,11 @@ output "psql_user_password" {
|
|||
sensitive = true
|
||||
}
|
||||
|
||||
output "psql_user_conn" {
|
||||
value = stackitprivatepreview_postgresflexalpha_user.ptlsdbuser.connection_string
|
||||
sensitive = true
|
||||
# output "psql_user_conn" {
|
||||
# value = stackitprivatepreview_postgresflexalpha_user.ptlsdbuser.connection.host
|
||||
# sensitive = true
|
||||
# }
|
||||
|
||||
output "determined_flavor_id" {
|
||||
value = stackitprivatepreview_postgresflexalpha_instance.msh-sna-pe-example.flavor_id
|
||||
}
|
||||
|
|
|
|||
13
sample/sqlserver_beta/flavor.tf
Normal file
13
sample/sqlserver_beta/flavor.tf
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#
|
||||
# data "stackitprivatepreview_sqlserverflexalpha_flavor" "sqlserver_flavor" {
|
||||
# project_id = var.project_id
|
||||
# region = "eu01"
|
||||
# cpu = 4
|
||||
# ram = 16
|
||||
# node_type = "Single"
|
||||
# storage_class = "premium-perf2-stackit"
|
||||
# }
|
||||
#
|
||||
# output "sqlserver_flavor" {
|
||||
# value = data.stackitprivatepreview_sqlserverflexalpha_flavor.sqlserver_flavor.flavor_id
|
||||
# }
|
||||
9
sample/sqlserver_beta/postgres.tf
Normal file
9
sample/sqlserver_beta/postgres.tf
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
data "stackitprivatepreview_postgresflexalpha_flavor" "pgsql_flavor" {
|
||||
project_id = var.project_id
|
||||
region = "eu01"
|
||||
cpu = 2
|
||||
ram = 4
|
||||
node_type = "Single"
|
||||
storage_class = "premium-perf2-stackit"
|
||||
}
|
||||
25
sample/sqlserver_beta/providers.tf
Normal file
25
sample/sqlserver_beta/providers.tf
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
terraform {
|
||||
required_providers {
|
||||
# stackit = {
|
||||
# source = "registry.terraform.io/stackitcloud/stackit"
|
||||
# version = "~> 0.70"
|
||||
# }
|
||||
stackitprivatepreview = {
|
||||
source = "tfregistry.sysops.stackit.rocks/mhenselin/stackitprivatepreview"
|
||||
version = "> 0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# provider "stackit" {
|
||||
# default_region = "eu01"
|
||||
# enable_beta_resources = true
|
||||
# service_account_key_path = "../service_account.json"
|
||||
# }
|
||||
|
||||
provider "stackitprivatepreview" {
|
||||
default_region = "eu01"
|
||||
enable_beta_resources = true
|
||||
service_account_key_path = "../service_account.json"
|
||||
}
|
||||
116
sample/sqlserver_beta/sqlserver.tf
Normal file
116
sample/sqlserver_beta/sqlserver.tf
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
data "stackitprivatepreview_sqlserverflexbeta_flavor" "sqlserver_flavor" {
|
||||
project_id = var.project_id
|
||||
region = "eu01"
|
||||
cpu = 4
|
||||
ram = 16
|
||||
node_type = "Single"
|
||||
storage_class = "premium-perf2-stackit"
|
||||
}
|
||||
|
||||
data "stackitprivatepreview_sqlserverflexbeta_flavor" "sqlserver_flavor_2" {
|
||||
project_id = var.project_id
|
||||
region = "eu01"
|
||||
cpu = 4
|
||||
ram = 32
|
||||
node_type = "Replica"
|
||||
storage_class = "premium-perf2-stackit"
|
||||
}
|
||||
|
||||
resource "stackitprivatepreview_sqlserverflexbeta_instance" "msh-beta-nosna-001" {
|
||||
project_id = var.project_id
|
||||
name = "msh-beta-nosna-001-renamed"
|
||||
backup_schedule = "0 3 * * *"
|
||||
retention_days = 31
|
||||
flavor_id = data.stackitprivatepreview_sqlserverflexbeta_flavor.sqlserver_flavor.flavor_id
|
||||
storage = {
|
||||
class = "premium-perf2-stackit"
|
||||
size = 50
|
||||
}
|
||||
version = 2022
|
||||
network = {
|
||||
acl = ["0.0.0.0/0", "193.148.160.0/19"]
|
||||
access_scope = "PUBLIC"
|
||||
}
|
||||
}
|
||||
|
||||
resource "stackitprivatepreview_sqlserverflexbeta_instance" "msh-beta-sna-001" {
|
||||
project_id = var.project_id
|
||||
name = "msh-beta-sna-001"
|
||||
backup_schedule = "0 3 * * *"
|
||||
retention_days = 31
|
||||
flavor_id = data.stackitprivatepreview_sqlserverflexbeta_flavor.sqlserver_flavor.flavor_id
|
||||
storage = {
|
||||
class = "premium-perf2-stackit"
|
||||
size = 5
|
||||
}
|
||||
version = 2022
|
||||
encryption = {
|
||||
#key_id = stackit_kms_key.key.key_id
|
||||
#keyring_id = stackit_kms_keyring.keyring.keyring_id
|
||||
#key_version = 1
|
||||
# key with scope public
|
||||
kek_key_id = "fe039bcf-8d7b-431a-801d-9e81371a6b7b"
|
||||
# key_id = var.key_id
|
||||
kek_key_ring_id = var.keyring_id
|
||||
kek_key_version = var.key_version
|
||||
service_account = var.sa_email
|
||||
}
|
||||
network = {
|
||||
acl = ["0.0.0.0/0", "193.148.160.0/19"]
|
||||
access_scope = "SNA"
|
||||
}
|
||||
}
|
||||
|
||||
resource "stackitprivatepreview_sqlserverflexbeta_user" "exampleuseruno" {
|
||||
project_id = var.project_id
|
||||
instance_id = stackitprivatepreview_sqlserverflexbeta_instance.msh-beta-nosna-001.instance_id
|
||||
username = "exampleuserdue"
|
||||
roles = ["##STACKIT_ProcessManager##", "##STACKIT_LoginManager##", "##STACKIT_ServerManager##"]
|
||||
}
|
||||
|
||||
resource "stackitprivatepreview_sqlserverflexbeta_user" "exampleuser" {
|
||||
project_id = var.project_id
|
||||
instance_id = stackitprivatepreview_sqlserverflexbeta_instance.msh-beta-nosna-001.instance_id
|
||||
username = "exampleuser"
|
||||
roles = ["##STACKIT_LoginManager##"]
|
||||
}
|
||||
|
||||
|
||||
resource "stackitprivatepreview_sqlserverflexbeta_database" "mshtest002" {
|
||||
project_id = var.project_id
|
||||
instance_id = stackitprivatepreview_sqlserverflexbeta_instance.msh-beta-nosna-001.instance_id
|
||||
name = "mshtest002"
|
||||
# owner = "dbuser"
|
||||
owner = stackitprivatepreview_sqlserverflexbeta_user.exampleuseruno.username
|
||||
}
|
||||
|
||||
|
||||
# data "stackitprivatepreview_sqlserverflexbeta_database" "example" {
|
||||
# project_id = var.project_id
|
||||
# region = "eu01"
|
||||
# instance_id = "b3b63d0c-35bf-4804-84ea-5abec2a8ae58"
|
||||
# database_name = "mshtest001"
|
||||
# }
|
||||
|
||||
# output "dbdetails" {
|
||||
# value = data.stackitprivatepreview_sqlserverflexbeta_database.example
|
||||
# }
|
||||
#
|
||||
|
||||
|
||||
# resource "stackitprivatepreview_sqlserverflexbeta_database" "mshtest" {
|
||||
# project_id = var.project_id
|
||||
# instance_id = "b3b63d0c-35bf-4804-84ea-5abec2a8ae58"
|
||||
# name = "mshtest"
|
||||
# owner = "dbuser"
|
||||
# }
|
||||
#
|
||||
# import {
|
||||
# to = stackitprivatepreview_sqlserverflexbeta_database.mshtest
|
||||
# identity = {
|
||||
# project_id = var.project_id
|
||||
# region = "eu01"
|
||||
# instance_id = "b3b63d0c-35bf-4804-84ea-5abec2a8ae58"
|
||||
# database_name = "mshtest"
|
||||
# }
|
||||
# }
|
||||
11
sample/sqlserver_beta/variables.tf.example
Normal file
11
sample/sqlserver_beta/variables.tf.example
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
variable "project_id" {
|
||||
default = "<PROJECT ID UUID>"
|
||||
}
|
||||
|
||||
variable "sa_email" {
|
||||
default = "<SERVICE ACCOUNT EMAIL>"
|
||||
}
|
||||
|
||||
variable "db_username" {
|
||||
default = "<DB USERNAME>"
|
||||
}
|
||||
|
|
@ -1,7 +1,5 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
|
||||
|
||||
# ./tf.sh apply > >(tee -a stdout.log) 2> >(tee -a stderr.log >&2)
|
||||
|
||||
usage() {
|
||||
|
|
@ -12,7 +10,8 @@ usage() {
|
|||
[ $# -eq 0 ] && usage
|
||||
|
||||
CONFIG_FOLDER=$(dirname "$0")
|
||||
BINARY=terraform
|
||||
# BINARY=terraform
|
||||
BINARY=tofu
|
||||
|
||||
ADD=""
|
||||
|
||||
|
|
|
|||
|
|
@ -1,19 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# This script lints the SDK modules and the internal examples
|
||||
# Pre-requisites: golangci-lint
|
||||
set -eo pipefail
|
||||
|
||||
ROOT_DIR=$(git rev-parse --show-toplevel)
|
||||
GOLANG_CI_YAML_PATH="${ROOT_DIR}/golang-ci.yaml"
|
||||
GOLANG_CI_ARGS="--allow-parallel-runners --timeout=5m --config=${GOLANG_CI_YAML_PATH}"
|
||||
|
||||
if type -p golangci-lint >/dev/null; then
|
||||
:
|
||||
else
|
||||
echo "golangci-lint not installed, unable to proceed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd ${ROOT_DIR}
|
||||
golangci-lint run ${GOLANG_CI_ARGS}
|
||||
|
|
@ -17,11 +17,7 @@ elif [ "$action" = "tools" ]; then
|
|||
|
||||
go mod download
|
||||
|
||||
# go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.62.0
|
||||
go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.7.2
|
||||
|
||||
# go install github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs@v0.21.0
|
||||
go install github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs@v0.24.0
|
||||
go install golang.org/x/tools/cmd/goimports@v0.42.0
|
||||
else
|
||||
echo "Invalid action: '$action', please use $0 help for help"
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -14,5 +14,5 @@ fi
|
|||
mkdir -p ${ROOT_DIR}/docs
|
||||
|
||||
echo ">> Generating documentation"
|
||||
tfplugindocs generate \
|
||||
go run github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs generate \
|
||||
--provider-name "stackitprivatepreview"
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue