Compare commits
No commits in common. "main" and "alpha-backup" have entirely different histories.
main
...
alpha-back
568 changed files with 56461 additions and 59629 deletions
24
.copywrite.hcl
Normal file
24
.copywrite.hcl
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
# NOTE: This file is for HashiCorp specific licensing automation and can be deleted after creating a new repo with this template.
|
||||||
|
schema_version = 1
|
||||||
|
|
||||||
|
project {
|
||||||
|
license = "Apache-2.0"
|
||||||
|
copyright_year = 2025
|
||||||
|
|
||||||
|
header_ignore = [
|
||||||
|
# internal catalog metadata (prose)
|
||||||
|
"META.d/**/*.yaml",
|
||||||
|
|
||||||
|
# examples used within documentation (prose)
|
||||||
|
"examples/**",
|
||||||
|
|
||||||
|
# GitHub issue template configuration
|
||||||
|
".github/ISSUE_TEMPLATE/*.yml",
|
||||||
|
|
||||||
|
# golangci-lint tooling configuration
|
||||||
|
".golangci.yml",
|
||||||
|
|
||||||
|
# GoReleaser tooling configuration
|
||||||
|
".goreleaser.yml",
|
||||||
|
]
|
||||||
|
}
|
||||||
1
.github/actions/acc_test/README.md
vendored
1
.github/actions/acc_test/README.md
vendored
|
|
@ -1 +0,0 @@
|
||||||
# acceptance test action
|
|
||||||
282
.github/actions/acc_test/action.yaml
vendored
282
.github/actions/acc_test/action.yaml
vendored
|
|
@ -1,282 +0,0 @@
|
||||||
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.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_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:
|
|
||||||
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: Install needed tools
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
echo "::group::apt install"
|
|
||||||
set -e
|
|
||||||
apt-get -y -qq update >apt_update.log 2>apt_update_err.log
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
cat apt_update.log apt_update_err.log
|
|
||||||
fi
|
|
||||||
apt-get -y -qq install jq python3 python3-pip python-is-python3 s3cmd git make wget >apt_get.log 2>apt_get_err.log
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
cat apt_get.log apt_get_err.log
|
|
||||||
fi
|
|
||||||
echo "::endgroup::"
|
|
||||||
|
|
||||||
# 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
|
|
||||||
with:
|
|
||||||
distribution: 'temurin' # See 'Supported distributions' for available options
|
|
||||||
java-version: '21'
|
|
||||||
|
|
||||||
- name: Install Go ${{ inputs.go-version }}
|
|
||||||
uses: actions/setup-go@v6
|
|
||||||
with:
|
|
||||||
# go-version: ${{ inputs.go-version }}
|
|
||||||
check-latest: true
|
|
||||||
go-version-file: 'go.mod'
|
|
||||||
|
|
||||||
- name: Determine GOMODCACHE
|
|
||||||
shell: bash
|
|
||||||
id: goenv
|
|
||||||
run: |
|
|
||||||
set -e
|
|
||||||
echo "gomodcache=$(go env GOMODCACHE)" >> "$GITHUB_OUTPUT"
|
|
||||||
|
|
||||||
- name: Restore cached GO pkg
|
|
||||||
id: cache-gopkg
|
|
||||||
uses: actions/cache/restore@v5
|
|
||||||
with:
|
|
||||||
path: "${{ steps.goenv.outputs.gomodcache }}"
|
|
||||||
key: ${{ runner.os }}-gopkg
|
|
||||||
|
|
||||||
- name: Install go tools
|
|
||||||
if: steps.cache-gopkg.outputs.cache-hit != 'true'
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
echo "::group::go install"
|
|
||||||
set -e
|
|
||||||
go mod download
|
|
||||||
go install golang.org/x/tools/cmd/goimports@latest
|
|
||||||
go install github.com/hashicorp/terraform-plugin-codegen-framework/cmd/tfplugingen-framework@latest
|
|
||||||
go install github.com/hashicorp/terraform-plugin-codegen-openapi/cmd/tfplugingen-openapi@latest
|
|
||||||
go install github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs@latest
|
|
||||||
go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest
|
|
||||||
echo "::endgroup::"
|
|
||||||
- name: Run go mod tidy
|
|
||||||
shell: bash
|
|
||||||
run: go mod tidy
|
|
||||||
|
|
||||||
- name: Save GO package Cache
|
|
||||||
id: cache-gopkg-save
|
|
||||||
uses: actions/cache/save@v5
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
${{ steps.goenv.outputs.gomodcache }}
|
|
||||||
key: ${{ runner.os }}-gopkg
|
|
||||||
|
|
||||||
- name: Define service account file path variable
|
|
||||||
id: service_account
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
echo "safilepath=${PWD}/stackit/${{ inputs.service_account_json_file_path }}" >> "$GITHUB_OUTPUT"
|
|
||||||
|
|
||||||
- name: Creating service_account file from json input
|
|
||||||
if: inputs.service_account_json_content != ''
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
echo "::group::create service account file"
|
|
||||||
set -e
|
|
||||||
set -o pipefail
|
|
||||||
|
|
||||||
jsonFile="${{ inputs.service_account_json_file_path }}"
|
|
||||||
jsonFile="${jsonFile:-x}"
|
|
||||||
if [ "${jsonFile}" == "x" ]; then
|
|
||||||
echo "no service account file path provided"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -f "${jsonFile}" ]; then
|
|
||||||
echo "creating service account file '${{ inputs.service_account_json_file_path }}'"
|
|
||||||
echo "${{ inputs.service_account_json_content }}" > stackit/"${{ inputs.service_account_json_file_path }}"
|
|
||||||
fi
|
|
||||||
ls -l stackit/"${{ inputs.service_account_json_file_path }}"
|
|
||||||
echo "::endgroup::"
|
|
||||||
|
|
||||||
- name: Creating service_account file from base64 json input
|
|
||||||
if: inputs.service_account_json_content_b64 != ''
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
echo "::group::create service account file"
|
|
||||||
set -e
|
|
||||||
set -o pipefail
|
|
||||||
|
|
||||||
jsonFile="${{ inputs.service_account_json_file_path }}"
|
|
||||||
jsonFile="${jsonFile:-x}"
|
|
||||||
if [ "${jsonFile}" == "x" ]; then
|
|
||||||
echo "no service account file path provided"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -f "${jsonFile}" ]; then
|
|
||||||
echo "creating service account file '${{ inputs.service_account_json_file_path }}'"
|
|
||||||
echo "${{ inputs.service_account_json_content_b64 }}" | base64 -d > stackit/"${{ inputs.service_account_json_file_path }}"
|
|
||||||
fi
|
|
||||||
ls -l stackit/"${{ inputs.service_account_json_file_path }}"
|
|
||||||
echo "::endgroup::"
|
|
||||||
|
|
||||||
- name: Run acceptance tests
|
|
||||||
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"
|
|
||||||
|
|
||||||
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} \
|
|
||||||
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:
|
|
||||||
TF_ACC_PROJECT_ID: ${{ inputs.project_id }}
|
|
||||||
TF_ACC_REGION: ${{ inputs.region }}
|
|
||||||
TF_ACC_TEST_PROJECT_USER_EMAIL: ${{ inputs.project_user_email }}
|
|
||||||
TF_ACC_KEK_KEY_ID: ${{ inputs.tf_acc_kek_key_id }}
|
|
||||||
TF_ACC_KEK_KEY_RING_ID: ${{ inputs.tf_acc_kek_key_ring_id }}
|
|
||||||
TF_ACC_KEK_KEY_VERSION: ${{ inputs.tf_acc_kek_key_version }}
|
|
||||||
TF_ACC_KEK_SERVICE_ACCOUNT: ${{ inputs.tf_acc_kek_service_account }}
|
|
||||||
|
|
||||||
- name: 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"
|
|
||||||
83
.github/actions/build/action.yaml
vendored
83
.github/actions/build/action.yaml
vendored
|
|
@ -3,89 +3,14 @@ description: "Build pipeline"
|
||||||
inputs:
|
inputs:
|
||||||
go-version:
|
go-version:
|
||||||
description: "Go version to install"
|
description: "Go version to install"
|
||||||
default: '1.26'
|
|
||||||
required: true
|
required: true
|
||||||
java-distribution:
|
|
||||||
description: "JAVA distribution to use (default: temurin)"
|
|
||||||
default: 'temurin'
|
|
||||||
java-version:
|
|
||||||
description: "JAVA version to use (default: 21)"
|
|
||||||
default: '21'
|
|
||||||
|
|
||||||
runs:
|
runs:
|
||||||
using: "composite"
|
using: "composite"
|
||||||
steps:
|
steps:
|
||||||
- name: Install needed tools
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
set -e
|
|
||||||
apt-get -y -qq update
|
|
||||||
apt-get -y -qq install jq python3 python3-pip python-is-python3 s3cmd git make wget unzip bc
|
|
||||||
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v6
|
|
||||||
|
|
||||||
- name: Install Go ${{ inputs.go-version }}
|
- name: Install Go ${{ inputs.go-version }}
|
||||||
uses: actions/setup-go@v6
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
# go-version: ${{ inputs.go-version }}
|
go-version: ${{ inputs.go-version }}
|
||||||
check-latest: true
|
- name: Install project tools and dependencies
|
||||||
go-version-file: 'go.mod'
|
|
||||||
|
|
||||||
- name: Determine GOMODCACHE
|
|
||||||
shell: bash
|
shell: bash
|
||||||
id: goenv
|
run: make project-tools
|
||||||
run: |
|
|
||||||
set -e
|
|
||||||
# echo "::set-output name=gomodcache::$(go env GOMODCACHE)"
|
|
||||||
echo "gomodcache=$(go env GOMODCACHE)" >> "$GITHUB_OUTPUT"
|
|
||||||
|
|
||||||
- name: Restore cached GO pkg
|
|
||||||
id: cache-gopkg
|
|
||||||
uses: actions/cache/restore@v5
|
|
||||||
with:
|
|
||||||
path: "${{ steps.goenv.outputs.gomodcache }}"
|
|
||||||
key: ${{ runner.os }}-gopkg
|
|
||||||
|
|
||||||
- name: Install go tools
|
|
||||||
if: steps.cache-gopkg.outputs.cache-hit != 'true'
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
set -e
|
|
||||||
go install golang.org/x/tools/cmd/goimports@latest
|
|
||||||
go install github.com/hashicorp/terraform-plugin-codegen-framework/cmd/tfplugingen-framework@latest
|
|
||||||
go install github.com/hashicorp/terraform-plugin-codegen-openapi/cmd/tfplugingen-openapi@latest
|
|
||||||
go install github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs@latest
|
|
||||||
|
|
||||||
# - name: Run build pkg directory
|
|
||||||
# shell: bash
|
|
||||||
# run: |
|
|
||||||
# set -e
|
|
||||||
# go run generator/main.go build
|
|
||||||
|
|
||||||
- name: Get all go packages
|
|
||||||
if: steps.cache-gopkg.outputs.cache-hit != 'true'
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
set -e
|
|
||||||
go get ./...
|
|
||||||
|
|
||||||
- name: Save Cache
|
|
||||||
id: cache-gopkg-save
|
|
||||||
uses: actions/cache/save@v5
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
${{ steps.goenv.outputs.gomodcache }}
|
|
||||||
key: ${{ runner.os }}-gopkg
|
|
||||||
|
|
||||||
- name: Setup JAVA ${{ inputs.java-distribution }} ${{ inputs.go-version }}
|
|
||||||
uses: actions/setup-java@v5
|
|
||||||
with:
|
|
||||||
distribution: ${{ inputs.java-distribution }} # See 'Supported distributions' for available options
|
|
||||||
java-version: ${{ inputs.java-version }}
|
|
||||||
|
|
||||||
- name: Run make to build app
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
set -e
|
|
||||||
make build
|
|
||||||
1
.github/actions/clean_up/README.md
vendored
1
.github/actions/clean_up/README.md
vendored
|
|
@ -1 +0,0 @@
|
||||||
# acceptance test action
|
|
||||||
227
.github/actions/clean_up/action.yaml
vendored
227
.github/actions/clean_up/action.yaml
vendored
|
|
@ -1,227 +0,0 @@
|
||||||
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
148
.github/actions/notify/action.yaml
vendored
|
|
@ -1,148 +0,0 @@
|
||||||
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}"
|
|
||||||
71
.github/actions/setup-cache-go/action.yaml
vendored
71
.github/actions/setup-cache-go/action.yaml
vendored
|
|
@ -1,71 +0,0 @@
|
||||||
name: 'Setup Go and cache dependencies'
|
|
||||||
author: 'Forgejo authors, Marcel S. Henselin'
|
|
||||||
description: |
|
|
||||||
Wrap the setup-go with improved dependency caching.
|
|
||||||
|
|
||||||
inputs:
|
|
||||||
username:
|
|
||||||
description: 'User for which to manage the dependency cache'
|
|
||||||
default: root
|
|
||||||
|
|
||||||
go-version:
|
|
||||||
description: "go version to install"
|
|
||||||
default: '1.26'
|
|
||||||
required: true
|
|
||||||
|
|
||||||
runs:
|
|
||||||
using: "composite"
|
|
||||||
steps:
|
|
||||||
- name: "Install zstd for faster caching"
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
apt-get update -qq
|
|
||||||
apt-get -q install -qq -y zstd
|
|
||||||
|
|
||||||
- name: "Set up Go using setup-go"
|
|
||||||
uses: https://code.forgejo.org/actions/setup-go@v6
|
|
||||||
id: go-version
|
|
||||||
with:
|
|
||||||
# go-version: ${{ inputs.go-version }}
|
|
||||||
check-latest: true # Always check for the latest patch release
|
|
||||||
go-version-file: "go.mod"
|
|
||||||
# do not cache dependencies, we do this manually
|
|
||||||
cache: false
|
|
||||||
|
|
||||||
- name: "Get go environment information"
|
|
||||||
shell: bash
|
|
||||||
id: go-environment
|
|
||||||
run: |
|
|
||||||
chmod 755 $HOME # ensure ${RUN_AS_USER} has permission when go is located in $HOME
|
|
||||||
export GOROOT="$(go env GOROOT)"
|
|
||||||
echo "modcache=$(su ${RUN_AS_USER} -c '${GOROOT}/bin/go env GOMODCACHE')" >> "$GITHUB_OUTPUT"
|
|
||||||
echo "cache=$(su ${RUN_AS_USER} -c '${GOROOT}/bin/go env GOCACHE')" >> "$GITHUB_OUTPUT"
|
|
||||||
env:
|
|
||||||
RUN_AS_USER: ${{ inputs.username }}
|
|
||||||
GO_VERSION: ${{ steps.go-version.outputs.go-version }}
|
|
||||||
|
|
||||||
- name: "Create cache folders with correct permissions (for non-root users)"
|
|
||||||
shell: bash
|
|
||||||
if: inputs.username != 'root'
|
|
||||||
# when the cache is restored, only the permissions of the last part are restored
|
|
||||||
# so assuming that /home/user exists and we are restoring /home/user/go/pkg/mod,
|
|
||||||
# both folders will have the correct permissions, but
|
|
||||||
# /home/user/go and /home/user/go/pkg might be owned by root
|
|
||||||
run: |
|
|
||||||
su ${RUN_AS_USER} -c 'mkdir -p "${MODCACHE_DIR}" "${CACHE_DIR}"'
|
|
||||||
env:
|
|
||||||
RUN_AS_USER: ${{ inputs.username }}
|
|
||||||
MODCACHE_DIR: ${{ steps.go-environment.outputs.modcache }}
|
|
||||||
CACHE_DIR: ${{ steps.go-environment.outputs.cache }}
|
|
||||||
|
|
||||||
- name: "Restore Go dependencies from cache or mark for later caching"
|
|
||||||
id: cache-deps
|
|
||||||
uses: https://code.forgejo.org/actions/cache@v5
|
|
||||||
with:
|
|
||||||
key: setup-cache-go-deps-${{ runner.os }}-${{ inputs.username }}-${{ steps.go-version.outputs.go_version }}-${{ hashFiles('go.sum', 'go.mod') }}
|
|
||||||
restore-keys: |
|
|
||||||
setup-cache-go-deps-${{ runner.os }}-${{ inputs.username }}-${{ steps.go-version.outputs.go_version }}-
|
|
||||||
setup-cache-go-deps-${{ runner.os }}-${{ inputs.username }}-
|
|
||||||
path: |
|
|
||||||
${{ steps.go-environment.outputs.modcache }}
|
|
||||||
${{ steps.go-environment.outputs.cache }}
|
|
||||||
8
.github/docs/contribution-guide/resource.go
vendored
8
.github/docs/contribution-guide/resource.go
vendored
|
|
@ -14,10 +14,10 @@ import (
|
||||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
|
"github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
"github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
||||||
fooUtils "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/foo/utils"
|
fooUtils "github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/services/foo/utils"
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
|
"github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/utils"
|
||||||
|
|
||||||
"github.com/stackitcloud/stackit-sdk-go/services/foo" // Import service "foo" from the STACKIT SDK for Go
|
"github.com/stackitcloud/stackit-sdk-go/services/foo" // Import service "foo" from the STACKIT SDK for Go
|
||||||
"github.com/stackitcloud/stackit-sdk-go/services/foo/wait" // Import service "foo" waiters from the STACKIT SDK for Go (in case the service API has asynchronous endpoints)
|
"github.com/stackitcloud/stackit-sdk-go/services/foo/wait" // Import service "foo" waiters from the STACKIT SDK for Go (in case the service API has asynchronous endpoints)
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,10 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||||
|
"github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
||||||
|
"github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/utils"
|
||||||
"github.com/stackitcloud/stackit-sdk-go/core/config"
|
"github.com/stackitcloud/stackit-sdk-go/core/config"
|
||||||
"github.com/stackitcloud/stackit-sdk-go/services/foo"
|
"github.com/stackitcloud/stackit-sdk-go/services/foo"
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func ConfigureClient(ctx context.Context, providerData *core.ProviderData, diags *diag.Diagnostics) *foo.APIClient {
|
func ConfigureClient(ctx context.Context, providerData *core.ProviderData, diags *diag.Diagnostics) *foo.APIClient {
|
||||||
|
|
|
||||||
90
.github/workflows/ci.yaml
vendored
Normal file
90
.github/workflows/ci.yaml
vendored
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
name: CI Workflow
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
env:
|
||||||
|
GO_VERSION: "1.25"
|
||||||
|
CODE_COVERAGE_FILE_NAME: "coverage.out" # must be the same as in Makefile
|
||||||
|
CODE_COVERAGE_ARTIFACT_NAME: "code-coverage"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
main:
|
||||||
|
name: CI
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
uses: ./.github/actions/build
|
||||||
|
with:
|
||||||
|
go-version: ${{ env.GO_VERSION }}
|
||||||
|
|
||||||
|
- name: Setup Terraform
|
||||||
|
uses: hashicorp/setup-terraform@v2
|
||||||
|
with:
|
||||||
|
terraform_wrapper: false
|
||||||
|
|
||||||
|
- name: "Ensure docs are up-to-date"
|
||||||
|
if: ${{ github.event_name == 'pull_request' }}
|
||||||
|
run: ./scripts/check-docs.sh
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
|
- name: "Run go mod tidy"
|
||||||
|
if: ${{ github.event_name == 'pull_request' }}
|
||||||
|
run: go mod tidy
|
||||||
|
|
||||||
|
- name: golangci-lint
|
||||||
|
uses: golangci/golangci-lint-action@v9
|
||||||
|
with:
|
||||||
|
version: v2.7
|
||||||
|
args: --config=golang-ci.yaml --allow-parallel-runners --timeout=5m
|
||||||
|
|
||||||
|
- name: Lint
|
||||||
|
run: make lint
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
run: make test
|
||||||
|
|
||||||
|
- name: Archive code coverage results
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: ${{ env.CODE_COVERAGE_ARTIFACT_NAME }}
|
||||||
|
path: "stackit/${{ env.CODE_COVERAGE_FILE_NAME }}"
|
||||||
|
|
||||||
|
|
||||||
|
config:
|
||||||
|
name: Check GoReleaser config
|
||||||
|
if: github.event_name == 'pull_request'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Check GoReleaser
|
||||||
|
uses: goreleaser/goreleaser-action@v6
|
||||||
|
with:
|
||||||
|
args: check
|
||||||
|
|
||||||
|
code_coverage:
|
||||||
|
name: "Code coverage report"
|
||||||
|
if: github.event_name == 'pull_request' # Do not run when workflow is triggered by push to main branch
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: main
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
actions: read # to download code coverage results from "main" job
|
||||||
|
pull-requests: write # write permission needed to comment on PR
|
||||||
|
steps:
|
||||||
|
- name: Check new code coverage
|
||||||
|
uses: fgrosse/go-coverage-report@v1.2.0
|
||||||
|
continue-on-error: true # Add this line to prevent pipeline failures in forks
|
||||||
|
with:
|
||||||
|
coverage-artifact-name: ${{ env.CODE_COVERAGE_ARTIFACT_NAME }}
|
||||||
|
coverage-file-name: ${{ env.CODE_COVERAGE_FILE_NAME }}
|
||||||
|
root-package: 'github.com/stackitcloud/terraform-provider-stackit'
|
||||||
290
.github/workflows/ci.yaml.bak
vendored
290
.github/workflows/ci.yaml.bak
vendored
|
|
@ -1,290 +0,0 @@
|
||||||
name: CI Workflow
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- alpha
|
|
||||||
- main
|
|
||||||
workflow_dispatch:
|
|
||||||
schedule:
|
|
||||||
# every sunday at 00:00
|
|
||||||
# - cron: '0 0 * * 0'
|
|
||||||
# every day at 00:00
|
|
||||||
- cron: '0 0 * * *'
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- '!main'
|
|
||||||
- '!alpha'
|
|
||||||
|
|
||||||
env:
|
|
||||||
GO_VERSION: "1.25"
|
|
||||||
CODE_COVERAGE_FILE_NAME: "coverage.out" # must be the same as in Makefile
|
|
||||||
CODE_COVERAGE_ARTIFACT_NAME: "code-coverage"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
runner_test:
|
|
||||||
name: "Test STACKIT runner"
|
|
||||||
runs-on: stackit-docker
|
|
||||||
steps:
|
|
||||||
- name: Install needed tools
|
|
||||||
run: |
|
|
||||||
apt-get -y -qq update
|
|
||||||
apt-get -y -qq install jq python3 python3-pip python-is-python3 s3cmd git make wget
|
|
||||||
|
|
||||||
- name: Setup Go
|
|
||||||
uses: actions/setup-go@v6
|
|
||||||
with:
|
|
||||||
go-version: ${{ env.GO_VERSION }}
|
|
||||||
|
|
||||||
- name: Install go tools
|
|
||||||
run: |
|
|
||||||
go install golang.org/x/tools/cmd/goimports@latest
|
|
||||||
go install github.com/hashicorp/terraform-plugin-codegen-framework/cmd/tfplugingen-framework@latest
|
|
||||||
go install github.com/hashicorp/terraform-plugin-codegen-openapi/cmd/tfplugingen-openapi@latest
|
|
||||||
|
|
||||||
- name: Setup JAVA
|
|
||||||
uses: actions/setup-java@v5
|
|
||||||
with:
|
|
||||||
distribution: 'temurin' # See 'Supported distributions' for available options
|
|
||||||
java-version: '21'
|
|
||||||
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v6
|
|
||||||
|
|
||||||
- name: Run build pkg directory
|
|
||||||
run: |
|
|
||||||
go run cmd/main.go build
|
|
||||||
|
|
||||||
publish_test:
|
|
||||||
name: "Test readiness for publishing provider"
|
|
||||||
needs: config
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
actions: read # Required to identify workflow run.
|
|
||||||
checks: write # Required to add status summary.
|
|
||||||
contents: read # Required to checkout repository.
|
|
||||||
pull-requests: write # Required to add PR comment.
|
|
||||||
steps:
|
|
||||||
- name: Install needed tools
|
|
||||||
run: |
|
|
||||||
apt-get -y -qq update
|
|
||||||
apt-get -y -qq install jq python3 python3-pip python-is-python3 s3cmd git make wget
|
|
||||||
|
|
||||||
- name: Setup Go
|
|
||||||
uses: actions/setup-go@v6
|
|
||||||
with:
|
|
||||||
go-version: ${{ env.GO_VERSION }}
|
|
||||||
|
|
||||||
- name: Install go tools
|
|
||||||
run: |
|
|
||||||
go install golang.org/x/tools/cmd/goimports@latest
|
|
||||||
go install github.com/hashicorp/terraform-plugin-codegen-framework/cmd/tfplugingen-framework@latest
|
|
||||||
go install github.com/hashicorp/terraform-plugin-codegen-openapi/cmd/tfplugingen-openapi@latest
|
|
||||||
|
|
||||||
- name: Setup JAVA
|
|
||||||
uses: actions/setup-java@v5
|
|
||||||
with:
|
|
||||||
distribution: 'temurin' # See 'Supported distributions' for available options
|
|
||||||
java-version: '21'
|
|
||||||
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v6
|
|
||||||
|
|
||||||
- name: Run build pkg directory
|
|
||||||
run: |
|
|
||||||
go run cmd/main.go build
|
|
||||||
|
|
||||||
- name: Set up s3cfg
|
|
||||||
run: |
|
|
||||||
cat <<'EOF' >> ~/.s3cfg
|
|
||||||
[default]
|
|
||||||
host_base = https://object.storage.eu01.onstackit.cloud
|
|
||||||
host_bucket = https://%(bucket).object.storage.eu01.onstackit.cloud
|
|
||||||
check_ssl_certificate = False
|
|
||||||
access_key = ${{ secrets.S3_ACCESS_KEY }}
|
|
||||||
secret_key = ${{ secrets.S3_SECRET_KEY }}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
- name: Import GPG key
|
|
||||||
run: |
|
|
||||||
echo "${{ secrets.PRIVATE_KEY_PEM }}" > ~/private.key.pem
|
|
||||||
gpg --import ~/private.key.pem
|
|
||||||
rm ~/private.key.pem
|
|
||||||
|
|
||||||
- name: Run GoReleaser with SNAPSHOT
|
|
||||||
id: goreleaser
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ env.FORGEJO_TOKEN }}
|
|
||||||
GPG_FINGERPRINT: ${{ secrets.GPG_FINGERPRINT }}
|
|
||||||
uses: goreleaser/goreleaser-action@v6
|
|
||||||
with:
|
|
||||||
args: release --skip publish --clean --snapshot
|
|
||||||
|
|
||||||
- name: Prepare key file
|
|
||||||
run: |
|
|
||||||
echo "${{ secrets.PUBLIC_KEY_PEM }}" >public_key.pem
|
|
||||||
|
|
||||||
- name: Prepare provider directory structure
|
|
||||||
run: |
|
|
||||||
VERSION=$(jq -r .version < dist/metadata.json)
|
|
||||||
go run cmd/main.go \
|
|
||||||
publish \
|
|
||||||
--namespace=mhenselin \
|
|
||||||
--providerName=stackitprivatepreview \
|
|
||||||
--repoName=terraform-provider-stackitprivatepreview \
|
|
||||||
--domain=tfregistry.sysops.stackit.rocks \
|
|
||||||
--gpgFingerprint="${{ secrets.GPG_FINGERPRINT }}" \
|
|
||||||
--gpgPubKeyFile=public_key.pem \
|
|
||||||
--version=${VERSION}
|
|
||||||
|
|
||||||
testing:
|
|
||||||
name: CI run tests
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: config
|
|
||||||
env:
|
|
||||||
TF_ACC_PROJECT_ID: ${{ vars.TF_ACC_PROJECT_ID }}
|
|
||||||
TF_ACC_REGION: ${{ vars.TF_ACC_REGION }}
|
|
||||||
TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_EMAIL: ${{ vars.TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_EMAIL }}
|
|
||||||
TF_ACC_SERVICE_ACCOUNT_FILE: "~/service_account.json"
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v6
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
uses: ./.github/actions/build
|
|
||||||
with:
|
|
||||||
go-version: ${{ env.GO_VERSION }}
|
|
||||||
|
|
||||||
- name: Setup Terraform
|
|
||||||
uses: hashicorp/setup-terraform@v2
|
|
||||||
with:
|
|
||||||
terraform_wrapper: false
|
|
||||||
|
|
||||||
- name: Create service account json file
|
|
||||||
if: ${{ github.event_name == 'pull_request' }}
|
|
||||||
run: |
|
|
||||||
echo "${{ secrets.TF_ACC_SERVICE_ACCOUNT_JSON }}" >~/service_account.json
|
|
||||||
|
|
||||||
- name: Run go mod tidy
|
|
||||||
if: ${{ github.event_name == 'pull_request' }}
|
|
||||||
run: go mod tidy
|
|
||||||
|
|
||||||
- name: Testing
|
|
||||||
run: make test
|
|
||||||
|
|
||||||
- name: Acceptance Testing
|
|
||||||
env:
|
|
||||||
TF_ACC: "1"
|
|
||||||
if: ${{ github.event_name == 'pull_request' }}
|
|
||||||
run: make test-acceptance-tf
|
|
||||||
|
|
||||||
- name: Check coverage threshold
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
make coverage
|
|
||||||
COVERAGE=$(go tool cover -func=coverage.out | grep total | awk '{print $3}' | sed 's/%//')
|
|
||||||
echo "Coverage: $COVERAGE%"
|
|
||||||
if (( $(echo "$COVERAGE < 80" | bc -l) )); then
|
|
||||||
echo "Coverage is below 80%"
|
|
||||||
# exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Archive code coverage results
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: ${{ env.CODE_COVERAGE_ARTIFACT_NAME }}
|
|
||||||
path: "stackit/${{ env.CODE_COVERAGE_FILE_NAME }}"
|
|
||||||
|
|
||||||
main:
|
|
||||||
if: ${{ github.event_name != 'schedule' }}
|
|
||||||
name: CI run build and linting
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: config
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v6
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
uses: ./.github/actions/build
|
|
||||||
with:
|
|
||||||
go-version: ${{ env.GO_VERSION }}
|
|
||||||
|
|
||||||
- name: Setup Terraform
|
|
||||||
uses: hashicorp/setup-terraform@v2
|
|
||||||
with:
|
|
||||||
terraform_wrapper: false
|
|
||||||
|
|
||||||
- name: "Ensure docs are up-to-date"
|
|
||||||
if: ${{ github.event_name == 'pull_request' }}
|
|
||||||
run: ./scripts/check-docs.sh
|
|
||||||
continue-on-error: true
|
|
||||||
|
|
||||||
- name: "Run go mod tidy"
|
|
||||||
if: ${{ github.event_name == 'pull_request' }}
|
|
||||||
run: go mod tidy
|
|
||||||
|
|
||||||
- name: golangci-lint
|
|
||||||
uses: golangci/golangci-lint-action@v9
|
|
||||||
with:
|
|
||||||
version: v2.9
|
|
||||||
args: --config=golang-ci.yaml --allow-parallel-runners --timeout=5m
|
|
||||||
continue-on-error: true
|
|
||||||
|
|
||||||
- name: Linting
|
|
||||||
run: make lint
|
|
||||||
continue-on-error: true
|
|
||||||
|
|
||||||
# - name: Testing
|
|
||||||
# run: make test
|
|
||||||
#
|
|
||||||
# - name: Acceptance Testing
|
|
||||||
# if: ${{ github.event_name == 'pull_request' }}
|
|
||||||
# run: make test-acceptance-tf
|
|
||||||
#
|
|
||||||
# - name: Check coverage threshold
|
|
||||||
# shell: bash
|
|
||||||
# run: |
|
|
||||||
# make coverage
|
|
||||||
# COVERAGE=$(go tool cover -func=coverage.out | grep total | awk '{print $3}' | sed 's/%//')
|
|
||||||
# echo "Coverage: $COVERAGE%"
|
|
||||||
# if (( $(echo "$COVERAGE < 80" | bc -l) )); then
|
|
||||||
# echo "Coverage is below 80%"
|
|
||||||
# # exit 1
|
|
||||||
# fi
|
|
||||||
|
|
||||||
# - name: Archive code coverage results
|
|
||||||
# uses: actions/upload-artifact@v4
|
|
||||||
# with:
|
|
||||||
# name: ${{ env.CODE_COVERAGE_ARTIFACT_NAME }}
|
|
||||||
# path: "stackit/${{ env.CODE_COVERAGE_FILE_NAME }}"
|
|
||||||
|
|
||||||
config:
|
|
||||||
if: ${{ github.event_name != 'schedule' }}
|
|
||||||
name: Check GoReleaser config
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v6
|
|
||||||
|
|
||||||
- name: Check GoReleaser
|
|
||||||
uses: goreleaser/goreleaser-action@v6
|
|
||||||
with:
|
|
||||||
args: check
|
|
||||||
|
|
||||||
code_coverage:
|
|
||||||
name: "Code coverage report"
|
|
||||||
if: github.event_name == 'pull_request' # Do not run when workflow is triggered by push to main branch
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: main
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
actions: read # to download code coverage results from "main" job
|
|
||||||
pull-requests: write # write permission needed to comment on PR
|
|
||||||
steps:
|
|
||||||
- name: Check new code coverage
|
|
||||||
uses: fgrosse/go-coverage-report@v1.2.0
|
|
||||||
continue-on-error: true # Add this line to prevent pipeline failures in forks
|
|
||||||
with:
|
|
||||||
coverage-artifact-name: ${{ env.CODE_COVERAGE_ARTIFACT_NAME }}
|
|
||||||
coverage-file-name: ${{ env.CODE_COVERAGE_FILE_NAME }}
|
|
||||||
root-package: 'github.com/stackitcloud/terraform-provider-stackit'
|
|
||||||
367
.github/workflows/ci_new.yaml
vendored
367
.github/workflows/ci_new.yaml
vendored
|
|
@ -1,367 +0,0 @@
|
||||||
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
72
.github/workflows/clean_up.yaml
vendored
|
|
@ -1,72 +0,0 @@
|
||||||
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
25
.github/workflows/notify_pr.yaml
vendored
|
|
@ -1,25 +0,0 @@
|
||||||
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 }}"
|
|
||||||
185
.github/workflows/publish.yaml
vendored
185
.github/workflows/publish.yaml
vendored
|
|
@ -1,185 +0,0 @@
|
||||||
name: Publish
|
|
||||||
|
|
||||||
run-name: Publish by @${{ github.actor }}
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
push:
|
|
||||||
tags:
|
|
||||||
- 'v*'
|
|
||||||
|
|
||||||
env:
|
|
||||||
GO_VERSION: "1.25"
|
|
||||||
CODE_COVERAGE_FILE_NAME: "coverage.out" # must be the same as in Makefile
|
|
||||||
CODE_COVERAGE_ARTIFACT_NAME: "code-coverage"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
config:
|
|
||||||
name: Check GoReleaser config
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v6
|
|
||||||
with:
|
|
||||||
fetch-tags: true
|
|
||||||
|
|
||||||
- name: Check GoReleaser
|
|
||||||
uses: goreleaser/goreleaser-action@v7
|
|
||||||
with:
|
|
||||||
args: check
|
|
||||||
|
|
||||||
publish:
|
|
||||||
name: "Publish provider"
|
|
||||||
needs: config
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
actions: read # Required to identify workflow run.
|
|
||||||
checks: write # Required to add status summary.
|
|
||||||
contents: write # Required to checkout repository.
|
|
||||||
pull-requests: write # Required to add PR comment.
|
|
||||||
steps:
|
|
||||||
- name: Install needed tools
|
|
||||||
run: |
|
|
||||||
apt-get -y -qq update
|
|
||||||
apt-get -y -qq install jq python3 python3-pip python-is-python3 s3cmd git make wget
|
|
||||||
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v6
|
|
||||||
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 }}
|
|
||||||
check-latest: true
|
|
||||||
go-version-file: 'go.mod'
|
|
||||||
|
|
||||||
- name: Install go tools
|
|
||||||
run: |
|
|
||||||
go install golang.org/x/tools/cmd/goimports@latest
|
|
||||||
go install github.com/hashicorp/terraform-plugin-codegen-framework/cmd/tfplugingen-framework@latest
|
|
||||||
go install github.com/hashicorp/terraform-plugin-codegen-openapi/cmd/tfplugingen-openapi@latest
|
|
||||||
|
|
||||||
- name: Setup JAVA
|
|
||||||
uses: actions/setup-java@v5
|
|
||||||
with:
|
|
||||||
distribution: 'temurin' # See 'Supported distributions' for available options
|
|
||||||
java-version: '21'
|
|
||||||
|
|
||||||
- name: Set up s3cfg
|
|
||||||
run: |
|
|
||||||
cat <<'EOF' >> ~/.s3cfg
|
|
||||||
[default]
|
|
||||||
host_base = https://object.storage.eu01.onstackit.cloud
|
|
||||||
host_bucket = https://%(bucket).object.storage.eu01.onstackit.cloud
|
|
||||||
check_ssl_certificate = False
|
|
||||||
access_key = ${{ secrets.S3_ACCESS_KEY }}
|
|
||||||
secret_key = ${{ secrets.S3_SECRET_KEY }}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
- name: Import GPG key
|
|
||||||
run: |
|
|
||||||
echo "${{ secrets.PRIVATE_KEY_PEM }}" > ~/private.key.pem
|
|
||||||
gpg --import ~/private.key.pem
|
|
||||||
rm ~/private.key.pem
|
|
||||||
|
|
||||||
- name: Run GoReleaser
|
|
||||||
if: github.event_name == 'workflow_dispatch'
|
|
||||||
id: goreleaser
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ env.FORGEJO_TOKEN }}
|
|
||||||
GPG_FINGERPRINT: ${{ secrets.GPG_FINGERPRINT }}
|
|
||||||
uses: goreleaser/goreleaser-action@v7
|
|
||||||
with:
|
|
||||||
# args: release --skip publish --clean --snapshot
|
|
||||||
args: release --skip publish --clean
|
|
||||||
|
|
||||||
- name: Run GoReleaser
|
|
||||||
if: github.event_name != 'workflow_dispatch'
|
|
||||||
id: goreleaser
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ env.FORGEJO_TOKEN }}
|
|
||||||
GPG_FINGERPRINT: ${{ secrets.GPG_FINGERPRINT }}
|
|
||||||
uses: goreleaser/goreleaser-action@v7
|
|
||||||
with:
|
|
||||||
args: release --skip publish --clean
|
|
||||||
|
|
||||||
- name: Prepare key file
|
|
||||||
run: |
|
|
||||||
echo "${{ secrets.PUBLIC_KEY_PEM }}" >public_key.pem
|
|
||||||
|
|
||||||
- name: 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: |
|
|
||||||
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=${{ 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/
|
|
||||||
s3cmd put --recursive v1 s3://terraform-provider-privatepreview/
|
|
||||||
s3cmd put --recursive .well-known s3://terraform-provider-privatepreview/
|
|
||||||
|
|
||||||
- name: Import SSH key
|
|
||||||
run: |
|
|
||||||
mkdir -p ~/.ssh
|
|
||||||
echo "${{ secrets.DOCS_UPLOAD_SSH_KEY }}" > ~/.ssh/id_ed25519
|
|
||||||
chmod 0600 ~/.ssh/id_ed25519
|
|
||||||
|
|
||||||
- name: Upload docs via scp
|
|
||||||
run: |
|
|
||||||
set -e
|
|
||||||
ssh -o StrictHostKeyChecking=no ubuntu@${{ vars.DOCS_SERVER_IP }} 'rm -rf /srv/www/docs'
|
|
||||||
echo "${{ 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' }}"
|
|
||||||
16
.github/workflows/release.yaml
vendored
16
.github/workflows/release.yaml
vendored
|
|
@ -4,9 +4,9 @@ name: Release
|
||||||
# This GitHub action creates a release when a tag that matches the pattern
|
# This GitHub action creates a release when a tag that matches the pattern
|
||||||
# "v*" (e.g. v0.1.0) is created.
|
# "v*" (e.g. v0.1.0) is created.
|
||||||
on:
|
on:
|
||||||
# push:
|
push:
|
||||||
# tags:
|
tags:
|
||||||
# - "v*"
|
- "v*"
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
# Releases need permissions to read and write the repository contents.
|
# Releases need permissions to read and write the repository contents.
|
||||||
|
|
@ -16,25 +16,23 @@ permissions:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
goreleaser:
|
goreleaser:
|
||||||
runs-on: stackit-docker
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
# Allow goreleaser to access older tag information.
|
# Allow goreleaser to access older tag information.
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
- uses: actions/setup-go@v5
|
||||||
- uses: actions/setup-go@v6
|
|
||||||
with:
|
with:
|
||||||
go-version-file: "go.mod"
|
go-version-file: "go.mod"
|
||||||
cache: true
|
cache: true
|
||||||
|
|
||||||
- name: Import GPG key
|
- name: Import GPG key
|
||||||
uses: crazy-max/ghaction-import-gpg@v6
|
uses: crazy-max/ghaction-import-gpg@v6
|
||||||
id: import_gpg
|
id: import_gpg
|
||||||
with:
|
with:
|
||||||
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
|
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
|
||||||
- name: Run GoReleaser
|
- name: Run GoReleaser
|
||||||
uses: goreleaser/goreleaser-action@v7
|
uses: goreleaser/goreleaser-action@v6
|
||||||
with:
|
with:
|
||||||
args: release --clean
|
args: release --clean
|
||||||
env:
|
env:
|
||||||
|
|
|
||||||
10
.github/workflows/renovate.yaml
vendored
10
.github/workflows/renovate.yaml
vendored
|
|
@ -8,14 +8,12 @@ on:
|
||||||
jobs:
|
jobs:
|
||||||
renovate:
|
renovate:
|
||||||
name: Renovate
|
name: Renovate
|
||||||
runs-on: stackit-docker
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Self-hosted Renovate
|
- name: Self-hosted Renovate
|
||||||
uses: renovatebot/github-action@v46.1.5
|
uses: renovatebot/github-action@v41.0.0
|
||||||
with:
|
with:
|
||||||
configurationFile: .github/renovate.json
|
configurationFile: .github/renovate.json
|
||||||
# token: ${{ secrets.RENOVATE_TOKEN }}
|
token: ${{ secrets.RENOVATE_TOKEN }}
|
||||||
token: ${{ env.FORGEJO_TOKEN }}
|
|
||||||
|
|
|
||||||
29
.github/workflows/runnerstats.yaml
vendored
29
.github/workflows/runnerstats.yaml
vendored
|
|
@ -1,29 +0,0 @@
|
||||||
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:
|
jobs:
|
||||||
stale:
|
stale:
|
||||||
name: "Stale"
|
name: "Stale"
|
||||||
runs-on: stackit-docker
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
steps:
|
steps:
|
||||||
- name: "Mark old PRs as stale"
|
- name: "Mark old PRs as stale"
|
||||||
|
|
|
||||||
128
.github/workflows/tf-acc-test.yaml
vendored
128
.github/workflows/tf-acc-test.yaml
vendored
|
|
@ -1,127 +1,27 @@
|
||||||
name: TF Acceptance Tests Workflow
|
name: TF Acceptance Tests Workflow
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
|
||||||
types: [opened, synchronize, reopened]
|
|
||||||
branches:
|
|
||||||
- alpha
|
|
||||||
- main
|
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
workflow_dispatch:
|
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:
|
jobs:
|
||||||
acc_test:
|
main:
|
||||||
name: Acceptance Tests
|
name: Acceptance Tests
|
||||||
runs-on: stackit-docker
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v4
|
||||||
|
- name: Install project tools and dependencies
|
||||||
- name: set start time
|
run: make project-tools
|
||||||
id: start_time
|
- name: Run tests
|
||||||
continue-on-error: true
|
|
||||||
run: |
|
run: |
|
||||||
time=$(date --rfc-3339=ns)
|
make test-acceptance-tf TF_ACC_PROJECT_ID=$${{ secrets.TF_ACC_PROJECT_ID }} TF_ACC_ORGANIZATION_ID=$${{ secrets.TF_ACC_ORGANIZATION_ID }} TF_ACC_REGION="eu01"
|
||||||
echo "start_time=$time" >> ${GITHUB_OUTPUT}
|
env:
|
||||||
start=$(date +%s%N)
|
STACKIT_SERVICE_ACCOUNT_TOKEN: ${{ secrets.TF_ACC_SERVICE_ACCOUNT_TOKEN }}
|
||||||
echo "start=$start" >> ${GITHUB_OUTPUT}
|
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 }}
|
||||||
- name: Notify
|
TF_ACC_TEST_PROJECT_PARENT_CONTAINER_ID: ${{ secrets.TF_ACC_TEST_PROJECT_PARENT_CONTAINER_ID }}
|
||||||
uses: ./.github/actions/notify
|
TF_ACC_TEST_PROJECT_PARENT_UUID: ${{ secrets.TF_ACC_TEST_PROJECT_PARENT_UUID }}
|
||||||
with:
|
TF_ACC_TEST_PROJECT_USER_EMAIL: ${{ secrets.TF_ACC_TEST_PROJECT_USER_EMAIL }}
|
||||||
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.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 }}
|
|
||||||
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 }}"
|
|
||||||
|
|
|
||||||
11
.gitignore
vendored
11
.gitignore
vendored
|
|
@ -38,14 +38,3 @@ stackit/internal/services/iaas/test-512k.img
|
||||||
# Test coverage reports
|
# Test coverage reports
|
||||||
coverage.out
|
coverage.out
|
||||||
coverage.html
|
coverage.html
|
||||||
generated
|
|
||||||
stackit-sdk-generator
|
|
||||||
stackit-sdk-generator/**
|
|
||||||
dist
|
|
||||||
|
|
||||||
.secrets
|
|
||||||
|
|
||||||
pkg_gen
|
|
||||||
/release/
|
|
||||||
.env
|
|
||||||
**/.env
|
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,6 @@
|
||||||
# behavior.
|
# behavior.
|
||||||
version: 2
|
version: 2
|
||||||
|
|
||||||
project_name: terraform-provider-stackitprivatepreview
|
|
||||||
|
|
||||||
builds:
|
builds:
|
||||||
- env:
|
- env:
|
||||||
# goreleaser does not work with CGO, it could also complicate
|
# goreleaser does not work with CGO, it could also complicate
|
||||||
|
|
@ -31,16 +29,14 @@ builds:
|
||||||
ignore:
|
ignore:
|
||||||
- goos: darwin
|
- goos: darwin
|
||||||
goarch: '386'
|
goarch: '386'
|
||||||
- goos: windows
|
|
||||||
goarch: arm
|
|
||||||
binary: '{{ .ProjectName }}_v{{ .Version }}'
|
binary: '{{ .ProjectName }}_v{{ .Version }}'
|
||||||
archives:
|
archives:
|
||||||
- formats: [ 'zip' ]
|
- formats: [ 'zip' ]
|
||||||
name_template: '{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}'
|
name_template: '{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}'
|
||||||
checksum:
|
checksum:
|
||||||
# extra_files:
|
extra_files:
|
||||||
# - glob: 'terraform-registry-manifest.json'
|
- glob: 'terraform-registry-manifest.json'
|
||||||
# name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json'
|
name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json'
|
||||||
name_template: '{{ .ProjectName }}_{{ .Version }}_SHA256SUMS'
|
name_template: '{{ .ProjectName }}_{{ .Version }}_SHA256SUMS'
|
||||||
algorithm: sha256
|
algorithm: sha256
|
||||||
signs:
|
signs:
|
||||||
|
|
|
||||||
23
Makefile
23
Makefile
|
|
@ -1,6 +1,5 @@
|
||||||
ROOT_DIR ?= $(shell git rev-parse --show-toplevel)
|
ROOT_DIR ?= $(shell git rev-parse --show-toplevel)
|
||||||
SCRIPTS_BASE ?= $(ROOT_DIR)/scripts
|
SCRIPTS_BASE ?= $(ROOT_DIR)/scripts
|
||||||
VERSION ?= ${VER}
|
|
||||||
|
|
||||||
# SETUP AND TOOL INITIALIZATION TASKS
|
# SETUP AND TOOL INITIALIZATION TASKS
|
||||||
project-help:
|
project-help:
|
||||||
|
|
@ -12,20 +11,17 @@ project-tools:
|
||||||
# LINT
|
# LINT
|
||||||
lint-golangci-lint:
|
lint-golangci-lint:
|
||||||
@echo "Linting with golangci-lint"
|
@echo "Linting with golangci-lint"
|
||||||
@go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint run --fix --config .golang-ci.yaml
|
@$(SCRIPTS_BASE)/lint-golangci-lint.sh
|
||||||
|
|
||||||
|
|
||||||
lint-tf:
|
lint-tf:
|
||||||
@echo "Linting terraform files"
|
@echo "Linting terraform files"
|
||||||
@terraform fmt -check -diff -recursive examples/
|
@terraform fmt -check -diff -recursive
|
||||||
@terraform fmt -check -diff -recursive stackit/
|
|
||||||
|
|
||||||
lint: lint-golangci-lint lint-tf
|
lint: lint-golangci-lint lint-tf
|
||||||
|
|
||||||
# DOCUMENTATION GENERATION
|
# DOCUMENTATION GENERATION
|
||||||
generate-docs:
|
generate-docs:
|
||||||
@echo "Generating documentation with tfplugindocs"
|
@echo "Generating documentation with tfplugindocs"
|
||||||
|
|
||||||
@$(SCRIPTS_BASE)/tfplugindocs.sh
|
@$(SCRIPTS_BASE)/tfplugindocs.sh
|
||||||
|
|
||||||
build:
|
build:
|
||||||
|
|
@ -37,16 +33,15 @@ fmt:
|
||||||
@terraform fmt -diff -recursive
|
@terraform fmt -diff -recursive
|
||||||
|
|
||||||
# TEST
|
# TEST
|
||||||
.PHONY: test coverage
|
|
||||||
test:
|
test:
|
||||||
@echo "Running tests for the terraform provider"
|
@echo "Running tests for the terraform provider"
|
||||||
@cd $(ROOT_DIR)/stackit && go test -timeout 0 ./... -count=1 -coverprofile=../coverage.out && cd $(ROOT_DIR)
|
@cd $(ROOT_DIR)/stackit && go test ./... -count=1 -coverprofile=coverage.out && cd $(ROOT_DIR)
|
||||||
|
|
||||||
# Test coverage
|
# Test coverage
|
||||||
coverage:
|
coverage:
|
||||||
@echo ">> Creating test coverage report for the terraform provider"
|
@echo ">> Creating test coverage report for the terraform provider"
|
||||||
@cd $(ROOT_DIR)/stackit && (go test -timeout 0 ./... -count=1 -coverprofile=../coverage.out || true) && cd $(ROOT_DIR)
|
@cd $(ROOT_DIR)/stackit && (go test ./... -count=1 -coverprofile=coverage.out || true) && cd $(ROOT_DIR)
|
||||||
@cd $(ROOT_DIR)/stackit && go tool cover -html=../coverage.out -o ../coverage.html && cd $(ROOT_DIR)
|
@cd $(ROOT_DIR)/stackit && go tool cover -html=coverage.out -o coverage.html && cd $(ROOT_DIR)
|
||||||
|
|
||||||
test-acceptance-tf:
|
test-acceptance-tf:
|
||||||
@if [ -z $(TF_ACC_PROJECT_ID) ]; then echo "Input TF_ACC_PROJECT_ID missing"; exit 1; fi
|
@if [ -z $(TF_ACC_PROJECT_ID) ]; then echo "Input TF_ACC_PROJECT_ID missing"; exit 1; fi
|
||||||
|
|
@ -62,11 +57,3 @@ test-acceptance-tf:
|
||||||
TF_ACC_REGION=$(TF_ACC_REGION) \
|
TF_ACC_REGION=$(TF_ACC_REGION) \
|
||||||
go test ./... -count=1 -timeout=30m && \
|
go test ./... -count=1 -timeout=30m && \
|
||||||
cd $(ROOT_DIR)
|
cd $(ROOT_DIR)
|
||||||
|
|
||||||
publish: build
|
|
||||||
ifeq ($(strip $(VERSION)),)
|
|
||||||
@echo "please call like this: VER=0.1.0 make publish"
|
|
||||||
else
|
|
||||||
@echo "version: $(VERSION)"
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
|
||||||
95
README.md
95
README.md
|
|
@ -1,14 +1,15 @@
|
||||||
<div align="center">
|
<div align="center">
|
||||||
|
<br>
|
||||||
<img src=".github/images/stackit-logo.svg" alt="STACKIT logo" width="50%"/>
|
<img src=".github/images/stackit-logo.svg" alt="STACKIT logo" width="50%"/>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
# STACKIT Terraform Provider <br />(PRIVATE PREVIEW)
|
# STACKIT Terraform Provider
|
||||||
|
|
||||||
[](https://registry.terraform.io/providers/stackitcloud/stackit/latest)  [](https://www.apache.org/licenses/LICENSE-2.0)
|
[](https://goreportcard.com/report/github.com/stackitcloud/terraform-provider-stackit) [](https://registry.terraform.io/providers/stackitcloud/stackit/latest)  [](https://www.apache.org/licenses/LICENSE-2.0)
|
||||||
|
|
||||||
This project is the **NOT** official [Terraform Provider](https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs) for [STACKIT](https://www.stackit.de/en/)!
|
This project is the official [Terraform Provider](https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs) for [STACKIT](https://www.stackit.de/en/), which allows you to manage STACKIT resources through Terraform.
|
||||||
|
|
||||||
This a **private preview only**, which allows you to manage STACKIT resources through Terraform.
|
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
|
|
@ -17,27 +18,26 @@ To install the [STACKIT Terraform Provider](https://registry.terraform.io/provid
|
||||||
```hcl
|
```hcl
|
||||||
terraform {
|
terraform {
|
||||||
required_providers {
|
required_providers {
|
||||||
stackitprivatepreview = {
|
stackit = {
|
||||||
source = "tfregistry.sysops.stackit.rocks/mhenselin/stackitprivatepreview"
|
source = "stackitcloud/stackit"
|
||||||
version = ">= 0.1.0"
|
version = "X.X.X"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
provider "stackitprivatepreview" {
|
provider "stackit" {
|
||||||
# Configuration options
|
# Configuration options
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Check one of the examples in the [examples](examples/) folder.
|
Check one of the examples in the [examples](examples/) folder.
|
||||||
|
|
||||||
<big font-size="3rem">TODO: revise the following sections</big>
|
|
||||||
|
|
||||||
## Authentication
|
## Authentication
|
||||||
|
|
||||||
To authenticate, you will need a [service account](https://docs.stackit.cloud/platform/access-and-identity/service-accounts/). Create it in the [STACKIT Portal](https://portal.stackit.cloud/) and assign the necessary permissions to it, e.g. `project.owner`. There are multiple ways to authenticate:
|
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)
|
- 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:
|
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:
|
||||||
|
|
||||||
|
|
@ -51,6 +51,7 @@ When setting up authentication, the provider will always try to use the key flow
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
"STACKIT_SERVICE_ACCOUNT_TOKEN": "foo_token",
|
||||||
"STACKIT_SERVICE_ACCOUNT_KEY_PATH": "path/to/sa_key.json"
|
"STACKIT_SERVICE_ACCOUNT_KEY_PATH": "path/to/sa_key.json"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
@ -98,12 +99,6 @@ To configure the key flow, follow this steps:
|
||||||
3. Configure the service account key for authentication in the provider by following one of the alternatives below:
|
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`
|
- 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`
|
- 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.
|
- 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)`
|
`$ export STACKIT_SERVICE_ACCOUNT_KEY=$(cat ./service-account-key.json)`
|
||||||
|
|
@ -115,6 +110,16 @@ To configure the key flow, follow this steps:
|
||||||
> - setting the environment variable: `STACKIT_PRIVATE_KEY_PATH` or `STACKIT_PRIVATE_KEY`
|
> - setting the environment variable: `STACKIT_PRIVATE_KEY_PATH` or `STACKIT_PRIVATE_KEY`
|
||||||
> - setting `STACKIT_PRIVATE_KEY_PATH` in the credentials file (see above)
|
> - 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
|
## 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).
|
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).
|
||||||
|
|
@ -144,6 +149,62 @@ 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).
|
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
|
## Acceptance Tests
|
||||||
|
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,12 @@
|
||||||
page_title: "stackitprivatepreview_postgresflexalpha_database Data Source - stackitprivatepreview"
|
page_title: "stackitprivatepreview_postgresflexalpha_database Data Source - stackitprivatepreview"
|
||||||
subcategory: ""
|
subcategory: ""
|
||||||
description: |-
|
description: |-
|
||||||
|
Postgres Flex database resource schema. Must have a region specified in the provider configuration.
|
||||||
---
|
---
|
||||||
|
|
||||||
# stackitprivatepreview_postgresflexalpha_database (Data Source)
|
# stackitprivatepreview_postgresflexalpha_database (Data Source)
|
||||||
|
|
||||||
|
Postgres Flex database resource schema. Must have a `region` specified in the provider configuration.
|
||||||
|
|
||||||
## Example Usage
|
## Example Usage
|
||||||
|
|
||||||
|
|
@ -25,17 +25,16 @@ data "stackitprivatepreview_postgresflexalpha_database" "example" {
|
||||||
|
|
||||||
### Required
|
### Required
|
||||||
|
|
||||||
- `database_id` (Number) The ID of the database.
|
- `database_id` (String) Database ID.
|
||||||
- `instance_id` (String) The ID of the instance.
|
- `instance_id` (String) ID of the Postgres Flex instance.
|
||||||
- `project_id` (String) The STACKIT project ID.
|
- `project_id` (String) STACKIT project ID to which the instance is associated.
|
||||||
|
|
||||||
### Optional
|
### Optional
|
||||||
|
|
||||||
- `region` (String) The region which should be addressed
|
- `region` (String) The resource region. If not defined, the provider region is used.
|
||||||
|
|
||||||
### Read-Only
|
### Read-Only
|
||||||
|
|
||||||
- `id` (String) Terraform's internal resource ID. It is structured as \"`project_id`,`region`,`instance_id`,`database_id`\".",
|
- `id` (String) Terraform's internal resource ID. It is structured as "`project_id`,`region`,`instance_id`,`database_id`".
|
||||||
- `name` (String) The name of the database.
|
- `name` (String) Database name.
|
||||||
- `owner` (String) The owner of the database.
|
- `owner` (String) Username of the database owner.
|
||||||
- `tf_original_api_id` (Number) The id of the database.
|
|
||||||
|
|
|
||||||
|
|
@ -10,18 +10,7 @@ description: |-
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Example Usage
|
|
||||||
|
|
||||||
```terraform
|
|
||||||
data "stackitprivatepreview_postgresflexalpha_flavor" "flavor" {
|
|
||||||
project_id = var.project_id
|
|
||||||
region = var.region
|
|
||||||
cpu = 4
|
|
||||||
ram = 16
|
|
||||||
node_type = "Single"
|
|
||||||
storage_class = "premium-perf2-stackit"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
<!-- schema generated by tfplugindocs -->
|
<!-- schema generated by tfplugindocs -->
|
||||||
## Schema
|
## Schema
|
||||||
|
|
|
||||||
|
|
@ -1,68 +0,0 @@
|
||||||
---
|
|
||||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
|
||||||
page_title: "stackitprivatepreview_postgresflexalpha_flavors Data Source - stackitprivatepreview"
|
|
||||||
subcategory: ""
|
|
||||||
description: |-
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# stackitprivatepreview_postgresflexalpha_flavors (Data Source)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- schema generated by tfplugindocs -->
|
|
||||||
## Schema
|
|
||||||
|
|
||||||
### Required
|
|
||||||
|
|
||||||
- `project_id` (String) The STACKIT project ID.
|
|
||||||
- `region` (String) The region which should be addressed
|
|
||||||
|
|
||||||
### Optional
|
|
||||||
|
|
||||||
- `page` (Number) Number of the page of items list to be returned.
|
|
||||||
- `size` (Number) Number of items to be returned on each page.
|
|
||||||
- `sort` (String) Sorting of the flavors to be returned on each page.
|
|
||||||
|
|
||||||
### Read-Only
|
|
||||||
|
|
||||||
- `flavors` (Attributes List) List of flavors available for the project. (see [below for nested schema](#nestedatt--flavors))
|
|
||||||
- `pagination` (Attributes) (see [below for nested schema](#nestedatt--pagination))
|
|
||||||
|
|
||||||
<a id="nestedatt--flavors"></a>
|
|
||||||
### Nested Schema for `flavors`
|
|
||||||
|
|
||||||
Read-Only:
|
|
||||||
|
|
||||||
- `cpu` (Number) The cpu count of the instance.
|
|
||||||
- `description` (String) The flavor description.
|
|
||||||
- `max_gb` (Number) maximum storage which can be ordered for the flavor in Gigabyte.
|
|
||||||
- `memory` (Number) The memory of the instance in Gibibyte.
|
|
||||||
- `min_gb` (Number) minimum storage which is required to order in Gigabyte.
|
|
||||||
- `node_type` (String) defines the nodeType it can be either single or replica
|
|
||||||
- `storage_classes` (Attributes List) maximum storage which can be ordered for the flavor in Gigabyte. (see [below for nested schema](#nestedatt--flavors--storage_classes))
|
|
||||||
- `tf_original_api_id` (String) The id of the instance flavor.
|
|
||||||
|
|
||||||
<a id="nestedatt--flavors--storage_classes"></a>
|
|
||||||
### Nested Schema for `flavors.storage_classes`
|
|
||||||
|
|
||||||
Read-Only:
|
|
||||||
|
|
||||||
- `class` (String)
|
|
||||||
- `max_io_per_sec` (Number)
|
|
||||||
- `max_through_in_mb` (Number)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a id="nestedatt--pagination"></a>
|
|
||||||
### Nested Schema for `pagination`
|
|
||||||
|
|
||||||
Read-Only:
|
|
||||||
|
|
||||||
- `page` (Number)
|
|
||||||
- `size` (Number)
|
|
||||||
- `sort` (String)
|
|
||||||
- `total_pages` (Number)
|
|
||||||
- `total_rows` (Number)
|
|
||||||
|
|
@ -3,12 +3,12 @@
|
||||||
page_title: "stackitprivatepreview_postgresflexalpha_instance Data Source - stackitprivatepreview"
|
page_title: "stackitprivatepreview_postgresflexalpha_instance Data Source - stackitprivatepreview"
|
||||||
subcategory: ""
|
subcategory: ""
|
||||||
description: |-
|
description: |-
|
||||||
|
Postgres Flex instance data source schema. Must have a region specified in the provider configuration.
|
||||||
---
|
---
|
||||||
|
|
||||||
# stackitprivatepreview_postgresflexalpha_instance (Data Source)
|
# stackitprivatepreview_postgresflexalpha_instance (Data Source)
|
||||||
|
|
||||||
|
Postgres Flex instance data source schema. Must have a `region` specified in the provider configuration.
|
||||||
|
|
||||||
## Example Usage
|
## Example Usage
|
||||||
|
|
||||||
|
|
@ -24,64 +24,34 @@ data "stackitprivatepreview_postgresflexalpha_instance" "example" {
|
||||||
|
|
||||||
### Required
|
### Required
|
||||||
|
|
||||||
- `instance_id` (String) The ID of the instance.
|
- `instance_id` (String) ID of the PostgresFlex instance.
|
||||||
- `project_id` (String) The STACKIT project ID.
|
- `project_id` (String) STACKIT project ID to which the instance is associated.
|
||||||
|
|
||||||
### Optional
|
### Optional
|
||||||
|
|
||||||
- `region` (String) The region which should be addressed
|
- `region` (String) The resource region. If not defined, the provider region is used.
|
||||||
|
|
||||||
### Read-Only
|
### Read-Only
|
||||||
|
|
||||||
- `acl` (List of String) List of IPV4 cidr.
|
- `backup_schedule` (String)
|
||||||
- `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.
|
- `encryption` (Attributes) (see [below for nested schema](#nestedatt--encryption))
|
||||||
- `connection_info` (Attributes) The connection information of the instance (see [below for nested schema](#nestedatt--connection_info))
|
- `flavor_id` (String)
|
||||||
- `encryption` (Attributes) The configuration for instance's volume and backup storage encryption.
|
- `id` (String) Terraform's internal data source. ID. It is structured as "`project_id`,`region`,`instance_id`".
|
||||||
|
- `name` (String) Instance name.
|
||||||
⚠︝ **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))
|
- `network` (Attributes) (see [below for nested schema](#nestedatt--network))
|
||||||
- `flavor_id` (String) The id of the instance flavor.
|
- `replicas` (Number)
|
||||||
- `id` (String) internal ID
|
- `retention_days` (Number)
|
||||||
- `is_deletable` (Boolean) Whether the instance can be deleted or not.
|
- `storage` (Attributes) (see [below for nested schema](#nestedatt--storage))
|
||||||
- `labels` (Map of String) Key-value pairs, 63 characters max, begin and end with an alphanumerical character,
|
- `version` (String)
|
||||||
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 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.
|
|
||||||
- `version` (String) The Postgres version used for the instance. See [Versions Endpoint](/documentation/postgres-flex-service/version/v3alpha1#tag/Version) for supported version parameters.
|
|
||||||
|
|
||||||
<a id="nestedatt--connection_info"></a>
|
|
||||||
### Nested Schema for `connection_info`
|
|
||||||
|
|
||||||
Read-Only:
|
|
||||||
|
|
||||||
- `write` (Attributes) The DNS name and port in the instance overview (see [below for nested schema](#nestedatt--connection_info--write))
|
|
||||||
|
|
||||||
<a id="nestedatt--connection_info--write"></a>
|
|
||||||
### Nested Schema for `connection_info.write`
|
|
||||||
|
|
||||||
Read-Only:
|
|
||||||
|
|
||||||
- `host` (String) The host of the instance.
|
|
||||||
- `port` (Number) The port of the instance.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a id="nestedatt--encryption"></a>
|
<a id="nestedatt--encryption"></a>
|
||||||
### Nested Schema for `encryption`
|
### Nested Schema for `encryption`
|
||||||
|
|
||||||
Read-Only:
|
Read-Only:
|
||||||
|
|
||||||
- `kek_key_id` (String) The encryption-key key identifier
|
- `key_id` (String)
|
||||||
- `kek_key_ring_id` (String) The encryption-key keyring identifier
|
- `key_version` (String)
|
||||||
- `kek_key_version` (String) The encryption-key version
|
- `keyring_id` (String)
|
||||||
- `service_account` (String)
|
- `service_account` (String)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -90,8 +60,8 @@ Read-Only:
|
||||||
|
|
||||||
Read-Only:
|
Read-Only:
|
||||||
|
|
||||||
- `access_scope` (String) The access scope of the instance. It defines if the instance is public or airgapped.
|
- `access_scope` (String)
|
||||||
- `acl` (List of String) List of IPV4 cidr.
|
- `acl` (List of String) The Access Control List (ACL) for the PostgresFlex instance.
|
||||||
- `instance_address` (String)
|
- `instance_address` (String)
|
||||||
- `router_address` (String)
|
- `router_address` (String)
|
||||||
|
|
||||||
|
|
@ -101,5 +71,5 @@ Read-Only:
|
||||||
|
|
||||||
Read-Only:
|
Read-Only:
|
||||||
|
|
||||||
- `performance_class` (String) The storage class for the storage.
|
- `class` (String)
|
||||||
- `size` (Number) The storage size in Gigabytes.
|
- `size` (Number)
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,12 @@
|
||||||
page_title: "stackitprivatepreview_postgresflexalpha_user Data Source - stackitprivatepreview"
|
page_title: "stackitprivatepreview_postgresflexalpha_user Data Source - stackitprivatepreview"
|
||||||
subcategory: ""
|
subcategory: ""
|
||||||
description: |-
|
description: |-
|
||||||
|
Postgres Flex user data source schema. Must have a region specified in the provider configuration.
|
||||||
---
|
---
|
||||||
|
|
||||||
# stackitprivatepreview_postgresflexalpha_user (Data Source)
|
# stackitprivatepreview_postgresflexalpha_user (Data Source)
|
||||||
|
|
||||||
|
Postgres Flex user data source schema. Must have a `region` specified in the provider configuration.
|
||||||
|
|
||||||
## Example Usage
|
## Example Usage
|
||||||
|
|
||||||
|
|
@ -25,18 +25,20 @@ data "stackitprivatepreview_postgresflexalpha_user" "example" {
|
||||||
|
|
||||||
### Required
|
### Required
|
||||||
|
|
||||||
- `instance_id` (String) The ID of the instance.
|
- `instance_id` (String) ID of the PostgresFlex instance.
|
||||||
- `project_id` (String) The STACKIT project ID.
|
- `project_id` (String) STACKIT project ID to which the instance is associated.
|
||||||
- `user_id` (Number) The ID of the user.
|
- `user_id` (String) User ID.
|
||||||
|
|
||||||
### Optional
|
### Optional
|
||||||
|
|
||||||
- `id` (String) Terraform's internal resource ID. It is structured as \"`project_id`,`region`,`instance_id`,`user_id`\".",
|
- `region` (String) The resource region. If not defined, the provider region is used.
|
||||||
- `region` (String) The region which should be addressed
|
|
||||||
|
|
||||||
### Read-Only
|
### Read-Only
|
||||||
|
|
||||||
- `name` (String) The name of the user.
|
- `connection_string` (String)
|
||||||
- `roles` (List of String) A list of user roles.
|
- `host` (String)
|
||||||
- `status` (String) The current status of the user.
|
- `id` (String) Terraform's internal data source. ID. It is structured as "`project_id`,`region`,`instance_id`,`user_id`".
|
||||||
- `tf_original_api_id` (Number) The ID of the user.
|
- `port` (Number)
|
||||||
|
- `roles` (Set of String)
|
||||||
|
- `status` (String)
|
||||||
|
- `username` (String)
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,16 @@
|
||||||
---
|
---
|
||||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||||
page_title: "stackitprivatepreview_sqlserverflexbeta_flavor Data Source - stackitprivatepreview"
|
page_title: "stackitprivatepreview_sqlserverflexalpha_flavor Data Source - stackitprivatepreview"
|
||||||
subcategory: ""
|
subcategory: ""
|
||||||
description: |-
|
description: |-
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# stackitprivatepreview_sqlserverflexbeta_flavor (Data Source)
|
# stackitprivatepreview_sqlserverflexalpha_flavor (Data Source)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Example Usage
|
|
||||||
|
|
||||||
```terraform
|
|
||||||
data "stackitprivatepreview_sqlserverflexbeta_flavor" "flavor" {
|
|
||||||
project_id = var.project_id
|
|
||||||
region = var.region
|
|
||||||
cpu = 4
|
|
||||||
ram = 16
|
|
||||||
node_type = "Single"
|
|
||||||
storage_class = "premium-perf2-stackit"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
<!-- schema generated by tfplugindocs -->
|
<!-- schema generated by tfplugindocs -->
|
||||||
## Schema
|
## Schema
|
||||||
|
|
@ -29,20 +18,20 @@ data "stackitprivatepreview_sqlserverflexbeta_flavor" "flavor" {
|
||||||
### Required
|
### Required
|
||||||
|
|
||||||
- `cpu` (Number) The cpu count of the instance.
|
- `cpu` (Number) The cpu count of the instance.
|
||||||
- `node_type` (String) defines the nodeType it can be either single or HA
|
- `node_type` (String) defines the nodeType it can be either single or replica
|
||||||
- `project_id` (String) The project ID of the flavor.
|
- `project_id` (String) The cpu count of the instance.
|
||||||
- `ram` (Number) The memory of the instance in Gibibyte.
|
- `ram` (Number) The memory of the instance in Gibibyte.
|
||||||
- `region` (String) The region of the flavor.
|
- `region` (String) The flavor description.
|
||||||
- `storage_class` (String) The memory of the instance in Gibibyte.
|
- `storage_class` (String) The memory of the instance in Gibibyte.
|
||||||
|
|
||||||
### Read-Only
|
### Read-Only
|
||||||
|
|
||||||
- `description` (String) The flavor description.
|
- `description` (String) The flavor description.
|
||||||
- `flavor_id` (String) The id of the instance flavor.
|
- `flavor_id` (String) The flavor id of the instance flavor.
|
||||||
- `id` (String) The id of the instance flavor.
|
- `id` (String) The terraform id of the instance flavor.
|
||||||
- `max_gb` (Number) maximum storage which can be ordered for the flavor in Gigabyte.
|
- `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.
|
- `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))
|
- `storage_classes` (Attributes List) (see [below for nested schema](#nestedatt--storage_classes))
|
||||||
|
|
||||||
<a id="nestedatt--storage_classes"></a>
|
<a id="nestedatt--storage_classes"></a>
|
||||||
### Nested Schema for `storage_classes`
|
### Nested Schema for `storage_classes`
|
||||||
90
docs/data-sources/sqlserverflexalpha_instance.md
Normal file
90
docs/data-sources/sqlserverflexalpha_instance.md
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
---
|
||||||
|
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||||
|
page_title: "stackitprivatepreview_sqlserverflexalpha_instance Data Source - stackitprivatepreview"
|
||||||
|
subcategory: ""
|
||||||
|
description: |-
|
||||||
|
SQLServer Flex ALPHA instance resource schema. Must have a region specified in the provider configuration.
|
||||||
|
---
|
||||||
|
|
||||||
|
# stackitprivatepreview_sqlserverflexalpha_instance (Data Source)
|
||||||
|
|
||||||
|
SQLServer Flex ALPHA instance resource schema. Must have a `region` specified in the provider configuration.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```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) ID of the SQLServer Flex instance.
|
||||||
|
- `project_id` (String) STACKIT project ID to which the instance is associated.
|
||||||
|
|
||||||
|
### Optional
|
||||||
|
|
||||||
|
- `region` (String) The resource region. If not defined, the provider region is used.
|
||||||
|
|
||||||
|
### Read-Only
|
||||||
|
|
||||||
|
- `backup_schedule` (String) The backup schedule. Should follow the cron scheduling system format (e.g. "0 0 * * *")
|
||||||
|
- `edition` (String)
|
||||||
|
- `encryption` (Attributes) The encryption block. (see [below for nested schema](#nestedatt--encryption))
|
||||||
|
- `flavor` (Attributes) (see [below for nested schema](#nestedatt--flavor))
|
||||||
|
- `id` (String) Terraform's internal resource ID. It is structured as "`project_id`,`region`,`instance_id`".
|
||||||
|
- `is_deletable` (Boolean)
|
||||||
|
- `name` (String) Instance name.
|
||||||
|
- `network` (Attributes) The network block. (see [below for nested schema](#nestedatt--network))
|
||||||
|
- `replicas` (Number)
|
||||||
|
- `retention_days` (Number)
|
||||||
|
- `status` (String)
|
||||||
|
- `storage` (Attributes) (see [below for nested schema](#nestedatt--storage))
|
||||||
|
- `version` (String)
|
||||||
|
|
||||||
|
<a id="nestedatt--encryption"></a>
|
||||||
|
### Nested Schema for `encryption`
|
||||||
|
|
||||||
|
Read-Only:
|
||||||
|
|
||||||
|
- `key_id` (String) STACKIT KMS - Key ID of the encryption key to use.
|
||||||
|
- `key_version` (String) STACKIT KMS - Key version to use in the encryption key.
|
||||||
|
- `keyring_id` (String) STACKIT KMS - KeyRing ID of the encryption key to use.
|
||||||
|
- `service_account` (String)
|
||||||
|
|
||||||
|
|
||||||
|
<a id="nestedatt--flavor"></a>
|
||||||
|
### Nested Schema for `flavor`
|
||||||
|
|
||||||
|
Read-Only:
|
||||||
|
|
||||||
|
- `cpu` (Number)
|
||||||
|
- `description` (String)
|
||||||
|
- `id` (String)
|
||||||
|
- `node_type` (String)
|
||||||
|
- `ram` (Number)
|
||||||
|
|
||||||
|
|
||||||
|
<a id="nestedatt--network"></a>
|
||||||
|
### Nested Schema for `network`
|
||||||
|
|
||||||
|
Read-Only:
|
||||||
|
|
||||||
|
- `access_scope` (String) The access scope of the instance. (e.g. SNA)
|
||||||
|
- `acl` (List of String) The Access Control List (ACL) for the SQLServer Flex instance.
|
||||||
|
- `instance_address` (String) The returned instance IP address of the SQLServer Flex instance.
|
||||||
|
- `router_address` (String) The returned router IP address of the SQLServer Flex instance.
|
||||||
|
|
||||||
|
|
||||||
|
<a id="nestedatt--storage"></a>
|
||||||
|
### Nested Schema for `storage`
|
||||||
|
|
||||||
|
Read-Only:
|
||||||
|
|
||||||
|
- `class` (String)
|
||||||
|
- `size` (Number)
|
||||||
44
docs/data-sources/sqlserverflexalpha_user.md
Normal file
44
docs/data-sources/sqlserverflexalpha_user.md
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
---
|
||||||
|
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||||
|
page_title: "stackitprivatepreview_sqlserverflexalpha_user Data Source - stackitprivatepreview"
|
||||||
|
subcategory: ""
|
||||||
|
description: |-
|
||||||
|
SQLServer Flex user data source schema. Must have a region specified in the provider configuration.
|
||||||
|
---
|
||||||
|
|
||||||
|
# stackitprivatepreview_sqlserverflexalpha_user (Data Source)
|
||||||
|
|
||||||
|
SQLServer Flex user data source schema. Must have a `region` specified in the provider configuration.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```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) ID of the SQLServer Flex instance.
|
||||||
|
- `project_id` (String) STACKIT project ID to which the instance is associated.
|
||||||
|
- `user_id` (Number) User ID.
|
||||||
|
|
||||||
|
### Optional
|
||||||
|
|
||||||
|
- `region` (String) The resource region. If not defined, the provider region is used.
|
||||||
|
|
||||||
|
### Read-Only
|
||||||
|
|
||||||
|
- `default_database` (String)
|
||||||
|
- `host` (String)
|
||||||
|
- `id` (String) Terraform's internal data source. ID. It is structured as "`project_id`,`region`,`instance_id`,`user_id`".
|
||||||
|
- `port` (Number)
|
||||||
|
- `roles` (Set of String) Database access levels for the user.
|
||||||
|
- `status` (String)
|
||||||
|
- `username` (String) Username of the SQLServer Flex instance.
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
---
|
|
||||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
|
||||||
page_title: "stackitprivatepreview_sqlserverflexbeta_database Data Source - stackitprivatepreview"
|
|
||||||
subcategory: ""
|
|
||||||
description: |-
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# stackitprivatepreview_sqlserverflexbeta_database (Data Source)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Example Usage
|
|
||||||
|
|
||||||
```terraform
|
|
||||||
data "stackitprivatepreview_sqlserverflexbeta_database" "example" {
|
|
||||||
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
||||||
instance_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
||||||
database_name = "dbname"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
<!-- schema generated by tfplugindocs -->
|
|
||||||
## Schema
|
|
||||||
|
|
||||||
### Required
|
|
||||||
|
|
||||||
- `database_name` (String) The name of the database.
|
|
||||||
- `instance_id` (String) The ID of the instance.
|
|
||||||
- `project_id` (String) The STACKIT project ID.
|
|
||||||
- `region` (String) The region which should be addressed
|
|
||||||
|
|
||||||
### Read-Only
|
|
||||||
|
|
||||||
- `collation_name` (String) The collation of the database. This database collation should match the *collation_name* of one of the collations given by the **Get database collation list** endpoint.
|
|
||||||
- `compatibility_level` (Number) CompatibilityLevel of the Database.
|
|
||||||
- `id` (String) The terraform internal identifier.
|
|
||||||
- `name` (String) The name of the database.
|
|
||||||
- `owner` (String) The owner of the database.
|
|
||||||
- `tf_original_api_id` (Number) The id of the database.
|
|
||||||
|
|
@ -1,77 +0,0 @@
|
||||||
---
|
|
||||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
|
||||||
page_title: "stackitprivatepreview_sqlserverflexbeta_instance Data Source - stackitprivatepreview"
|
|
||||||
subcategory: ""
|
|
||||||
description: |-
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# stackitprivatepreview_sqlserverflexbeta_instance (Data Source)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Example Usage
|
|
||||||
|
|
||||||
```terraform
|
|
||||||
data "stackitprivatepreview_sqlserverflexbeta_instance" "example" {
|
|
||||||
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
||||||
instance_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
<!-- schema generated by tfplugindocs -->
|
|
||||||
## Schema
|
|
||||||
|
|
||||||
### Required
|
|
||||||
|
|
||||||
- `instance_id` (String) The ID of the instance.
|
|
||||||
- `project_id` (String) The STACKIT project ID.
|
|
||||||
- `region` (String) The region which should be addressed
|
|
||||||
|
|
||||||
### Read-Only
|
|
||||||
|
|
||||||
- `backup_schedule` (String) The schedule for on what time and how often the database backup will be created. The schedule is written as a cron schedule.
|
|
||||||
- `edition` (String) Edition of the MSSQL server instance
|
|
||||||
- `encryption` (Attributes) this defines which key to use for storage encryption (see [below for nested schema](#nestedatt--encryption))
|
|
||||||
- `flavor_id` (String) The id of the instance flavor.
|
|
||||||
- `is_deletable` (Boolean) Whether the instance can be deleted or not.
|
|
||||||
- `name` (String) The name of the instance.
|
|
||||||
- `network` (Attributes) The access configuration of the instance (see [below for nested schema](#nestedatt--network))
|
|
||||||
- `replicas` (Number) How many replicas the instance should have.
|
|
||||||
- `retention_days` (Number) The days for how long the backup files should be stored before cleaned up. 30 to 365
|
|
||||||
- `status` (String)
|
|
||||||
- `storage` (Attributes) The object containing information about the storage size and class. (see [below for nested schema](#nestedatt--storage))
|
|
||||||
- `tf_original_api_id` (String) The ID of the instance.
|
|
||||||
- `version` (String) The sqlserver version used for the instance.
|
|
||||||
|
|
||||||
<a id="nestedatt--encryption"></a>
|
|
||||||
### Nested Schema for `encryption`
|
|
||||||
|
|
||||||
Read-Only:
|
|
||||||
|
|
||||||
- `kek_key_id` (String) The key identifier
|
|
||||||
- `kek_key_ring_id` (String) The keyring identifier
|
|
||||||
- `kek_key_version` (String) The key version
|
|
||||||
- `service_account` (String)
|
|
||||||
|
|
||||||
|
|
||||||
<a id="nestedatt--network"></a>
|
|
||||||
### Nested Schema for `network`
|
|
||||||
|
|
||||||
Read-Only:
|
|
||||||
|
|
||||||
- `access_scope` (String) The network access scope of the instance
|
|
||||||
|
|
||||||
⚠️ **Note:** This feature is in private preview. Supplying this object is only permitted for enabled accounts. If your account does not have access, the request will be rejected.
|
|
||||||
- `acl` (List of String) List of IPV4 cidr.
|
|
||||||
- `instance_address` (String)
|
|
||||||
- `router_address` (String)
|
|
||||||
|
|
||||||
|
|
||||||
<a id="nestedatt--storage"></a>
|
|
||||||
### Nested Schema for `storage`
|
|
||||||
|
|
||||||
Read-Only:
|
|
||||||
|
|
||||||
- `class` (String) The storage class for the storage.
|
|
||||||
- `size` (Number) The storage size in Gigabytes.
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
||||||
---
|
|
||||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
|
||||||
page_title: "stackitprivatepreview_sqlserverflexbeta_user Data Source - stackitprivatepreview"
|
|
||||||
subcategory: ""
|
|
||||||
description: |-
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# stackitprivatepreview_sqlserverflexbeta_user (Data Source)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- schema generated by tfplugindocs -->
|
|
||||||
## Schema
|
|
||||||
|
|
||||||
### Required
|
|
||||||
|
|
||||||
- `instance_id` (String) The ID of the instance.
|
|
||||||
- `project_id` (String) The STACKIT project ID.
|
|
||||||
- `region` (String) The region which should be addressed
|
|
||||||
|
|
||||||
### Optional
|
|
||||||
|
|
||||||
- `page` (Number) Number of the page of items list to be returned.
|
|
||||||
- `size` (Number) Number of items to be returned on each page.
|
|
||||||
- `sort` (String) Sorting of the users to be returned on each page.
|
|
||||||
|
|
||||||
### Read-Only
|
|
||||||
|
|
||||||
- `pagination` (Attributes) (see [below for nested schema](#nestedatt--pagination))
|
|
||||||
- `users` (Attributes List) List of all users inside an instance (see [below for nested schema](#nestedatt--users))
|
|
||||||
|
|
||||||
<a id="nestedatt--pagination"></a>
|
|
||||||
### Nested Schema for `pagination`
|
|
||||||
|
|
||||||
Read-Only:
|
|
||||||
|
|
||||||
- `page` (Number)
|
|
||||||
- `size` (Number)
|
|
||||||
- `sort` (String)
|
|
||||||
- `total_pages` (Number)
|
|
||||||
- `total_rows` (Number)
|
|
||||||
|
|
||||||
|
|
||||||
<a id="nestedatt--users"></a>
|
|
||||||
### Nested Schema for `users`
|
|
||||||
|
|
||||||
Read-Only:
|
|
||||||
|
|
||||||
- `status` (String) The current status of the user.
|
|
||||||
- `tf_original_api_id` (Number) The ID of the user.
|
|
||||||
- `username` (String) The name of the user.
|
|
||||||
|
|
@ -16,13 +16,14 @@ provider "stackitprivatepreview" {
|
||||||
default_region = "eu01"
|
default_region = "eu01"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Authentication
|
||||||
|
|
||||||
|
# Token flow (scheduled for deprecation and will be removed on December 17, 2025)
|
||||||
provider "stackitprivatepreview" {
|
provider "stackitprivatepreview" {
|
||||||
default_region = "eu01"
|
default_region = "eu01"
|
||||||
service_account_key_path = "service_account.json"
|
service_account_token = var.service_account_token
|
||||||
}
|
}
|
||||||
|
|
||||||
# Authentication
|
|
||||||
|
|
||||||
# Key flow
|
# Key flow
|
||||||
provider "stackitprivatepreview" {
|
provider "stackitprivatepreview" {
|
||||||
default_region = "eu01"
|
default_region = "eu01"
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,12 @@
|
||||||
page_title: "stackitprivatepreview_postgresflexalpha_database Resource - stackitprivatepreview"
|
page_title: "stackitprivatepreview_postgresflexalpha_database Resource - stackitprivatepreview"
|
||||||
subcategory: ""
|
subcategory: ""
|
||||||
description: |-
|
description: |-
|
||||||
|
Postgres Flex database resource schema. Must have a region specified in the provider configuration.
|
||||||
---
|
---
|
||||||
|
|
||||||
# stackitprivatepreview_postgresflexalpha_database (Resource)
|
# stackitprivatepreview_postgresflexalpha_database (Resource)
|
||||||
|
|
||||||
|
Postgres Flex database resource schema. Must have a `region` specified in the provider configuration.
|
||||||
|
|
||||||
## Example Usage
|
## Example Usage
|
||||||
|
|
||||||
|
|
@ -25,16 +25,6 @@ import {
|
||||||
to = stackitprivatepreview_postgresflexalpha_database.import-example
|
to = stackitprivatepreview_postgresflexalpha_database.import-example
|
||||||
id = "${var.project_id},${var.region},${var.postgres_instance_id},${var.postgres_database_id}"
|
id = "${var.project_id},${var.region},${var.postgres_instance_id},${var.postgres_database_id}"
|
||||||
}
|
}
|
||||||
|
|
||||||
import {
|
|
||||||
to = stackitprivatepreview_postgresflexalpha_database.import-example
|
|
||||||
identity = {
|
|
||||||
project_id = "project_id"
|
|
||||||
region = "region"
|
|
||||||
instance_id = "instance_id"
|
|
||||||
database_id = "database_id"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
<!-- schema generated by tfplugindocs -->
|
<!-- schema generated by tfplugindocs -->
|
||||||
|
|
@ -42,16 +32,16 @@ import {
|
||||||
|
|
||||||
### Required
|
### Required
|
||||||
|
|
||||||
- `name` (String) The name of the database.
|
- `instance_id` (String) ID of the Postgres Flex instance.
|
||||||
|
- `name` (String) Database name.
|
||||||
|
- `owner` (String) Username of the database owner.
|
||||||
|
- `project_id` (String) STACKIT project ID to which the instance is associated.
|
||||||
|
|
||||||
### Optional
|
### Optional
|
||||||
|
|
||||||
- `database_id` (Number) The ID of the database.
|
- `region` (String) The resource region. If not defined, the provider region is used.
|
||||||
- `instance_id` (String) The ID of the instance.
|
|
||||||
- `owner` (String) The owner of the database.
|
|
||||||
- `project_id` (String) The STACKIT project ID.
|
|
||||||
- `region` (String) The region which should be addressed
|
|
||||||
|
|
||||||
### Read-Only
|
### Read-Only
|
||||||
|
|
||||||
- `id` (String) The id of the database.
|
- `database_id` (Number) Database ID.
|
||||||
|
- `id` (String) Terraform's internal resource ID. It is structured as "`project_id`,`region`,`instance_id`,`database_id`".
|
||||||
|
|
|
||||||
|
|
@ -3,66 +3,31 @@
|
||||||
page_title: "stackitprivatepreview_postgresflexalpha_instance Resource - stackitprivatepreview"
|
page_title: "stackitprivatepreview_postgresflexalpha_instance Resource - stackitprivatepreview"
|
||||||
subcategory: ""
|
subcategory: ""
|
||||||
description: |-
|
description: |-
|
||||||
|
Postgres Flex instance resource schema. Must have a region specified in the provider configuration.
|
||||||
---
|
---
|
||||||
|
|
||||||
# stackitprivatepreview_postgresflexalpha_instance (Resource)
|
# stackitprivatepreview_postgresflexalpha_instance (Resource)
|
||||||
|
|
||||||
|
Postgres Flex instance resource schema. Must have a `region` specified in the provider configuration.
|
||||||
|
|
||||||
## Example Usage
|
## Example Usage
|
||||||
|
|
||||||
```terraform
|
```terraform
|
||||||
# NOTE: flavor handling will change in future
|
resource "stackitprivatepreview_postgresflexalpha_instance" "example" {
|
||||||
# V2 compatible flavor usage (example without encryption)
|
|
||||||
resource "stackitprivatepreview_postgresflexalpha_instance" "example-instance" {
|
|
||||||
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||||
name = "example-instance"
|
name = "example-instance"
|
||||||
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
|
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
|
||||||
backup_schedule = "0 0 * * *"
|
backup_schedule = "00 00 * * *"
|
||||||
retention_days = 30
|
|
||||||
flavor = {
|
flavor = {
|
||||||
cpu = 2
|
cpu = 2
|
||||||
ram = 4
|
ram = 4
|
||||||
}
|
}
|
||||||
replicas = 1
|
replicas = 3
|
||||||
storage = {
|
storage = {
|
||||||
performance_class = "premium-perf2-stackit"
|
class = "class"
|
||||||
size = 10
|
size = 5
|
||||||
}
|
}
|
||||||
network = {
|
version = 14
|
||||||
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"
|
|
||||||
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
|
|
||||||
backup_schedule = "0 0 * * *"
|
|
||||||
retention_days = 30
|
|
||||||
flavor_id = "flavor.id"
|
|
||||||
replicas = 1
|
|
||||||
storage = {
|
|
||||||
performance_class = "premium-perf2-stackit"
|
|
||||||
size = 10
|
|
||||||
}
|
|
||||||
encryption = {
|
|
||||||
kek_key_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
||||||
kek_key_ring_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
||||||
kek_key_version = 1
|
|
||||||
service_account = "service@account.email"
|
|
||||||
}
|
|
||||||
network = {
|
|
||||||
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
|
|
||||||
access_scope = "PUBLIC"
|
|
||||||
}
|
|
||||||
version = 17
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Only use the import statement, if you want to import an existing postgresflex instance
|
# Only use the import statement, if you want to import an existing postgresflex instance
|
||||||
|
|
@ -70,15 +35,6 @@ import {
|
||||||
to = stackitprivatepreview_postgresflexalpha_instance.import-example
|
to = stackitprivatepreview_postgresflexalpha_instance.import-example
|
||||||
id = "${var.project_id},${var.region},${var.postgres_instance_id}"
|
id = "${var.project_id},${var.region},${var.postgres_instance_id}"
|
||||||
}
|
}
|
||||||
|
|
||||||
import {
|
|
||||||
to = stackitprivatepreview_postgresflexalpha_instance.import-example
|
|
||||||
identity = {
|
|
||||||
project_id = var.project_id
|
|
||||||
region = var.region
|
|
||||||
instance_id = var.postgres_instance_id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
<!-- schema generated by tfplugindocs -->
|
<!-- schema generated by tfplugindocs -->
|
||||||
|
|
@ -86,48 +42,49 @@ import {
|
||||||
|
|
||||||
### Required
|
### Required
|
||||||
|
|
||||||
- `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.
|
- `backup_schedule` (String)
|
||||||
- `name` (String) The name of the instance.
|
- `encryption` (Attributes) The encryption block. (see [below for nested schema](#nestedatt--encryption))
|
||||||
- `network` (Attributes) The access configuration of the instance (see [below for nested schema](#nestedatt--network))
|
- `flavor_id` (String)
|
||||||
- `replicas` (Number) How many replicas the instance should have.
|
- `name` (String) Instance name.
|
||||||
- `retention_days` (Number) How long backups are retained. The value can only be between 32 and 90 days.
|
- `network` (Attributes) The network block configuration. (see [below for nested schema](#nestedatt--network))
|
||||||
- `storage` (Attributes) The object containing information about the storage size and class. (see [below for nested schema](#nestedatt--storage))
|
- `project_id` (String) STACKIT project ID to which the instance is associated.
|
||||||
- `version` (String) The Postgres version used for the instance. See [Versions Endpoint](/documentation/postgres-flex-service/version/v3alpha1#tag/Version) for supported version parameters.
|
- `replicas` (Number)
|
||||||
|
- `retention_days` (Number) The days of the retention period.
|
||||||
|
- `storage` (Attributes) (see [below for nested schema](#nestedatt--storage))
|
||||||
|
- `version` (String) The database version used.
|
||||||
|
|
||||||
### Optional
|
### Optional
|
||||||
|
|
||||||
- `encryption` (Attributes) The configuration for instance's volume and backup storage encryption.
|
- `region` (String) The resource region. If not defined, the provider region is used.
|
||||||
|
|
||||||
⚠︝ **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
|
|
||||||
|
|
||||||
### Read-Only
|
### Read-Only
|
||||||
|
|
||||||
- `acl` (List of String) List of IPV4 cidr.
|
- `id` (String) Terraform's internal resource ID. It is structured as "`project_id`,`region`,`instance_id`".
|
||||||
- `connection_info` (Attributes) The connection information of the instance (see [below for nested schema](#nestedatt--connection_info))
|
- `instance_id` (String) ID of the PostgresFlex instance.
|
||||||
- `id` (String) The ID of the instance.
|
|
||||||
- `is_deletable` (Boolean) Whether the instance can be deleted or not.
|
<a id="nestedatt--encryption"></a>
|
||||||
- `status` (String) The current status of the instance.
|
### Nested Schema for `encryption`
|
||||||
|
|
||||||
|
Required:
|
||||||
|
|
||||||
|
- `key_id` (String) Key ID of the encryption key.
|
||||||
|
- `key_version` (String) Key version of the encryption key.
|
||||||
|
- `keyring_id` (String) KeyRing ID of the encryption key.
|
||||||
|
- `service_account` (String) The service account ID of the service account.
|
||||||
|
|
||||||
|
|
||||||
<a id="nestedatt--network"></a>
|
<a id="nestedatt--network"></a>
|
||||||
### Nested Schema for `network`
|
### Nested Schema for `network`
|
||||||
|
|
||||||
Required:
|
Required:
|
||||||
|
|
||||||
- `acl` (List of String) List of IPV4 cidr.
|
- `acl` (List of String) The Access Control List (ACL) for the PostgresFlex instance.
|
||||||
|
|
||||||
Optional:
|
Optional:
|
||||||
|
|
||||||
- `access_scope` (String) The access scope of the instance. It defines if the instance is public or airgapped.
|
- `access_scope` (String) The access scope. (Either SNA or PUBLIC)
|
||||||
|
- `instance_address` (String) The returned instance address.
|
||||||
Read-Only:
|
- `router_address` (String) The returned router address.
|
||||||
|
|
||||||
- `instance_address` (String)
|
|
||||||
- `router_address` (String)
|
|
||||||
|
|
||||||
|
|
||||||
<a id="nestedatt--storage"></a>
|
<a id="nestedatt--storage"></a>
|
||||||
|
|
@ -135,46 +92,5 @@ Read-Only:
|
||||||
|
|
||||||
Required:
|
Required:
|
||||||
|
|
||||||
- `performance_class` (String) The storage class for the storage.
|
- `class` (String) The storage class used.
|
||||||
- `size` (Number) The storage size in Gigabytes.
|
- `size` (Number) The disk size of the storage.
|
||||||
|
|
||||||
|
|
||||||
<a id="nestedatt--encryption"></a>
|
|
||||||
### Nested Schema for `encryption`
|
|
||||||
|
|
||||||
Required:
|
|
||||||
|
|
||||||
- `kek_key_id` (String) The encryption-key key identifier
|
|
||||||
- `kek_key_ring_id` (String) The encryption-key keyring identifier
|
|
||||||
- `kek_key_version` (String) The encryption-key version
|
|
||||||
- `service_account` (String)
|
|
||||||
|
|
||||||
|
|
||||||
<a id="nestedatt--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.
|
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,12 @@
|
||||||
page_title: "stackitprivatepreview_postgresflexalpha_user Resource - stackitprivatepreview"
|
page_title: "stackitprivatepreview_postgresflexalpha_user Resource - stackitprivatepreview"
|
||||||
subcategory: ""
|
subcategory: ""
|
||||||
description: |-
|
description: |-
|
||||||
|
Postgres Flex user resource schema. Must have a region specified in the provider configuration.
|
||||||
---
|
---
|
||||||
|
|
||||||
# stackitprivatepreview_postgresflexalpha_user (Resource)
|
# stackitprivatepreview_postgresflexalpha_user (Resource)
|
||||||
|
|
||||||
|
Postgres Flex user resource schema. Must have a `region` specified in the provider configuration.
|
||||||
|
|
||||||
## Example Usage
|
## Example Usage
|
||||||
|
|
||||||
|
|
@ -16,7 +16,7 @@ description: |-
|
||||||
resource "stackitprivatepreview_postgresflexalpha_user" "example" {
|
resource "stackitprivatepreview_postgresflexalpha_user" "example" {
|
||||||
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||||
instance_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
instance_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||||
name = "username"
|
username = "username"
|
||||||
roles = ["role"]
|
roles = ["role"]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -25,16 +25,6 @@ import {
|
||||||
to = stackitprivatepreview_postgresflexalpha_user.import-example
|
to = stackitprivatepreview_postgresflexalpha_user.import-example
|
||||||
id = "${var.project_id},${var.region},${var.postgres_instance_id},${var.user_id}"
|
id = "${var.project_id},${var.region},${var.postgres_instance_id},${var.user_id}"
|
||||||
}
|
}
|
||||||
|
|
||||||
import {
|
|
||||||
to = stackitprivatepreview_postgresflexalpha_user.import-example
|
|
||||||
identity = {
|
|
||||||
project_id = "project.id"
|
|
||||||
region = "region"
|
|
||||||
instance_id = "instance.id"
|
|
||||||
user_id = "user.id"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
<!-- schema generated by tfplugindocs -->
|
<!-- schema generated by tfplugindocs -->
|
||||||
|
|
@ -42,18 +32,19 @@ import {
|
||||||
|
|
||||||
### Required
|
### Required
|
||||||
|
|
||||||
- `name` (String) The name of the user.
|
- `instance_id` (String) ID of the PostgresFlex instance.
|
||||||
|
- `project_id` (String) STACKIT project ID to which the instance is associated.
|
||||||
|
- `roles` (Set of String) Database access levels for the user. Possible values are: `login`, `createdb`.
|
||||||
|
- `username` (String)
|
||||||
|
|
||||||
### Optional
|
### Optional
|
||||||
|
|
||||||
- `instance_id` (String) The ID of the instance.
|
- `region` (String) The resource region. If not defined, the provider region is used.
|
||||||
- `project_id` (String) The STACKIT project ID.
|
|
||||||
- `region` (String) The region which should be addressed
|
|
||||||
- `roles` (List of String) A list containing the user roles for the instance.
|
|
||||||
- `user_id` (Number) The ID of the user.
|
|
||||||
|
|
||||||
### Read-Only
|
### Read-Only
|
||||||
|
|
||||||
- `id` (String) The ID of the user.
|
- `connection_string` (String)
|
||||||
- `password` (String) The password for the user.
|
- `id` (String) Terraform's internal resource ID. It is structured as "`project_id`,`region`,`instance_id`,`user_id`".
|
||||||
- `status` (String) The current status of the user.
|
- `password` (String, Sensitive)
|
||||||
|
- `status` (String)
|
||||||
|
- `user_id` (Number) User ID.
|
||||||
|
|
|
||||||
98
docs/resources/sqlserverflexalpha_instance.md
Normal file
98
docs/resources/sqlserverflexalpha_instance.md
Normal file
|
|
@ -0,0 +1,98 @@
|
||||||
|
---
|
||||||
|
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||||
|
page_title: "stackitprivatepreview_sqlserverflexalpha_instance Resource - stackitprivatepreview"
|
||||||
|
subcategory: ""
|
||||||
|
description: |-
|
||||||
|
SQLServer Flex ALPHA instance resource schema. Must have a region specified in the provider configuration.
|
||||||
|
---
|
||||||
|
|
||||||
|
# stackitprivatepreview_sqlserverflexalpha_instance (Resource)
|
||||||
|
|
||||||
|
SQLServer Flex ALPHA instance resource schema. Must have a `region` specified in the provider configuration.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```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
|
||||||
|
|
||||||
|
- `encryption` (Attributes) The encryption block. (see [below for nested schema](#nestedatt--encryption))
|
||||||
|
- `flavor_id` (String)
|
||||||
|
- `name` (String) Instance name.
|
||||||
|
- `network` (Attributes) The network block. (see [below for nested schema](#nestedatt--network))
|
||||||
|
- `project_id` (String) STACKIT project ID to which the instance is associated.
|
||||||
|
|
||||||
|
### Optional
|
||||||
|
|
||||||
|
- `backup_schedule` (String) The backup schedule. Should follow the cron scheduling system format (e.g. "0 0 * * *")
|
||||||
|
- `is_deletable` (Boolean)
|
||||||
|
- `region` (String) The resource region. If not defined, the provider region is used.
|
||||||
|
- `retention_days` (Number)
|
||||||
|
- `status` (String)
|
||||||
|
- `storage` (Attributes) (see [below for nested schema](#nestedatt--storage))
|
||||||
|
- `version` (String)
|
||||||
|
|
||||||
|
### Read-Only
|
||||||
|
|
||||||
|
- `edition` (String)
|
||||||
|
- `id` (String) Terraform's internal resource ID. It is structured as "`project_id`,`region`,`instance_id`".
|
||||||
|
- `instance_id` (String) ID of the SQLServer Flex instance.
|
||||||
|
- `replicas` (Number)
|
||||||
|
|
||||||
|
<a id="nestedatt--encryption"></a>
|
||||||
|
### Nested Schema for `encryption`
|
||||||
|
|
||||||
|
Required:
|
||||||
|
|
||||||
|
- `key_id` (String) STACKIT KMS - Key ID of the encryption key to use.
|
||||||
|
- `key_version` (String) STACKIT KMS - Key version to use in the encryption key.
|
||||||
|
- `keyring_id` (String) STACKIT KMS - KeyRing ID of the encryption key to use.
|
||||||
|
- `service_account` (String)
|
||||||
|
|
||||||
|
|
||||||
|
<a id="nestedatt--network"></a>
|
||||||
|
### Nested Schema for `network`
|
||||||
|
|
||||||
|
Required:
|
||||||
|
|
||||||
|
- `access_scope` (String) The access scope of the instance. (SNA | PUBLIC)
|
||||||
|
- `acl` (List of String) The Access Control List (ACL) for the SQLServer Flex instance.
|
||||||
|
|
||||||
|
Read-Only:
|
||||||
|
|
||||||
|
- `instance_address` (String) The returned instance IP address of the SQLServer Flex instance.
|
||||||
|
- `router_address` (String) The returned router IP address of the SQLServer Flex instance.
|
||||||
|
|
||||||
|
|
||||||
|
<a id="nestedatt--storage"></a>
|
||||||
|
### Nested Schema for `storage`
|
||||||
|
|
||||||
|
Optional:
|
||||||
|
|
||||||
|
- `class` (String)
|
||||||
|
- `size` (Number)
|
||||||
52
docs/resources/sqlserverflexalpha_user.md
Normal file
52
docs/resources/sqlserverflexalpha_user.md
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
---
|
||||||
|
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||||
|
page_title: "stackitprivatepreview_sqlserverflexalpha_user Resource - stackitprivatepreview"
|
||||||
|
subcategory: ""
|
||||||
|
description: |-
|
||||||
|
SQLServer Flex user resource schema. Must have a region specified in the provider configuration.
|
||||||
|
---
|
||||||
|
|
||||||
|
# stackitprivatepreview_sqlserverflexalpha_user (Resource)
|
||||||
|
|
||||||
|
SQLServer Flex user resource schema. Must have a `region` specified in the provider configuration.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```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
|
||||||
|
|
||||||
|
- `instance_id` (String) ID of the SQLServer Flex instance.
|
||||||
|
- `project_id` (String) STACKIT project ID to which the instance is associated.
|
||||||
|
- `roles` (Set of String) Database access levels for the user. The values for the default roles are: `##STACKIT_DatabaseManager##`, `##STACKIT_LoginManager##`, `##STACKIT_ProcessManager##`, `##STACKIT_ServerManager##`, `##STACKIT_SQLAgentManager##`, `##STACKIT_SQLAgentUser##`
|
||||||
|
- `username` (String) Username of the SQLServer Flex instance.
|
||||||
|
|
||||||
|
### Optional
|
||||||
|
|
||||||
|
- `region` (String)
|
||||||
|
|
||||||
|
### Read-Only
|
||||||
|
|
||||||
|
- `default_database` (String)
|
||||||
|
- `host` (String)
|
||||||
|
- `id` (String) Terraform's internal resource ID. It is structured as "`project_id`,`region`,`instance_id`,`user_id`".
|
||||||
|
- `password` (String, Sensitive) Password of the user account.
|
||||||
|
- `port` (Number)
|
||||||
|
- `status` (String)
|
||||||
|
- `user_id` (Number) User ID.
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
---
|
|
||||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
|
||||||
page_title: "stackitprivatepreview_sqlserverflexbeta_database Resource - stackitprivatepreview"
|
|
||||||
subcategory: ""
|
|
||||||
description: |-
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# stackitprivatepreview_sqlserverflexbeta_database (Resource)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Example Usage
|
|
||||||
|
|
||||||
```terraform
|
|
||||||
resource "stackitprivatepreview_sqlserverflexalpha_user" "example" {
|
|
||||||
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
||||||
instance_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
||||||
username = "username"
|
|
||||||
roles = ["role"]
|
|
||||||
}
|
|
||||||
|
|
||||||
# Only use the import statement, if you want to import an existing sqlserverflex user
|
|
||||||
import {
|
|
||||||
to = stackitprivatepreview_sqlserverflexalpha_user.import-example
|
|
||||||
id = "${var.project_id},${var.region},${var.sql_instance_id},${var.sql_user_id}"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
<!-- schema generated by tfplugindocs -->
|
|
||||||
## Schema
|
|
||||||
|
|
||||||
### Required
|
|
||||||
|
|
||||||
- `name` (String) The name of the database.
|
|
||||||
- `owner` (String) The owner of the database.
|
|
||||||
|
|
||||||
### Optional
|
|
||||||
|
|
||||||
- `collation` (String) The collation of the database. This database collation should match the *collation_name* of one of the collations given by the **Get database collation list** endpoint.
|
|
||||||
- `compatibility` (Number) CompatibilityLevel of the Database.
|
|
||||||
- `database_name` (String) The name of the database.
|
|
||||||
- `instance_id` (String) The ID of the instance.
|
|
||||||
- `project_id` (String) The STACKIT project ID.
|
|
||||||
- `region` (String) The region which should be addressed
|
|
||||||
|
|
||||||
### Read-Only
|
|
||||||
|
|
||||||
- `collation_name` (String) The collation of the database. This database collation should match the *collation_name* of one of the collations given by the **Get database collation list** endpoint.
|
|
||||||
- `compatibility_level` (Number) CompatibilityLevel of the Database.
|
|
||||||
- `id` (Number) The id of the database.
|
|
||||||
|
|
@ -1,198 +0,0 @@
|
||||||
---
|
|
||||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
|
||||||
page_title: "stackitprivatepreview_sqlserverflexbeta_instance Resource - stackitprivatepreview"
|
|
||||||
subcategory: ""
|
|
||||||
description: |-
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# stackitprivatepreview_sqlserverflexbeta_instance (Resource)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Example Usage
|
|
||||||
|
|
||||||
```terraform
|
|
||||||
# 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"
|
|
||||||
name = "example-instance"
|
|
||||||
backup_schedule = "0 3 * * *"
|
|
||||||
retention_days = 31
|
|
||||||
flavor_id = "flavor_id"
|
|
||||||
storage = {
|
|
||||||
class = "premium-perf2-stackit"
|
|
||||||
size = 50
|
|
||||||
}
|
|
||||||
version = 2022
|
|
||||||
network = {
|
|
||||||
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
|
|
||||||
access_scope = "SNA"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# without encryption and PUBLIC
|
|
||||||
resource "stackitprivatepreview_sqlserverflexbeta_instance" "instance" {
|
|
||||||
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
||||||
name = "example-instance"
|
|
||||||
backup_schedule = "0 3 * * *"
|
|
||||||
retention_days = 31
|
|
||||||
flavor_id = "flavor_id"
|
|
||||||
storage = {
|
|
||||||
class = "premium-perf2-stackit"
|
|
||||||
size = 50
|
|
||||||
}
|
|
||||||
version = 2022
|
|
||||||
network = {
|
|
||||||
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
|
|
||||||
access_scope = "PUBLIC"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# with encryption and SNA
|
|
||||||
resource "stackitprivatepreview_sqlserverflexbeta_instance" "instance" {
|
|
||||||
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
||||||
name = "example-instance"
|
|
||||||
backup_schedule = "0 3 * * *"
|
|
||||||
retention_days = 31
|
|
||||||
flavor_id = "flavor_id"
|
|
||||||
storage = {
|
|
||||||
class = "premium-perf2-stackit"
|
|
||||||
size = 50
|
|
||||||
}
|
|
||||||
version = 2022
|
|
||||||
encryption = {
|
|
||||||
kek_key_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
||||||
kek_key_ring_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
||||||
kek_key_version = 1
|
|
||||||
service_account = "service_account@email"
|
|
||||||
}
|
|
||||||
network = {
|
|
||||||
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
|
|
||||||
access_scope = "SNA"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Only use the import statement, if you want to import an existing sqlserverflex instance
|
|
||||||
import {
|
|
||||||
to = stackitprivatepreview_sqlserverflexalpha_instance.import-example
|
|
||||||
id = "${var.project_id},${var.region},${var.sql_instance_id}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# import with identity
|
|
||||||
import {
|
|
||||||
to = stackitprivatepreview_sqlserverflexalpha_instance.import-example
|
|
||||||
identity = {
|
|
||||||
project_id = var.project_id
|
|
||||||
region = var.region
|
|
||||||
instance_id = var.sql_instance_id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
<!-- schema generated by tfplugindocs -->
|
|
||||||
## Schema
|
|
||||||
|
|
||||||
### Required
|
|
||||||
|
|
||||||
- `backup_schedule` (String) The schedule for on what time and how often the database backup will be created. The schedule is written as a cron schedule.
|
|
||||||
- `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))
|
|
||||||
- `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
|
|
||||||
|
|
||||||
### 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)
|
|
||||||
|
|
||||||
|
|
||||||
<a id="nestedatt--flavor"></a>
|
|
||||||
### Nested Schema for `flavor`
|
|
||||||
|
|
||||||
Optional:
|
|
||||||
|
|
||||||
- `cpu` (Number, Deprecated)
|
|
||||||
- `ram` (Number, Deprecated)
|
|
||||||
|
|
||||||
Read-Only:
|
|
||||||
|
|
||||||
- `description` (String)
|
|
||||||
- `id` (String)
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
---
|
|
||||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
|
||||||
page_title: "stackitprivatepreview_sqlserverflexbeta_user Resource - stackitprivatepreview"
|
|
||||||
subcategory: ""
|
|
||||||
description: |-
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# stackitprivatepreview_sqlserverflexbeta_user (Resource)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Example Usage
|
|
||||||
|
|
||||||
```terraform
|
|
||||||
resource "stackitprivatepreview_sqlserverflexalpha_user" "example" {
|
|
||||||
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
||||||
instance_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
||||||
username = "username"
|
|
||||||
roles = ["role"]
|
|
||||||
}
|
|
||||||
|
|
||||||
# Only use the import statement, if you want to import an existing sqlserverflex user
|
|
||||||
import {
|
|
||||||
to = stackitprivatepreview_sqlserverflexalpha_user.import-example
|
|
||||||
id = "${var.project_id},${var.region},${var.sql_instance_id},${var.sql_user_id}"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
<!-- schema generated by tfplugindocs -->
|
|
||||||
## Schema
|
|
||||||
|
|
||||||
### Required
|
|
||||||
|
|
||||||
- `roles` (List of String) A list containing the user roles for the instance. A list with the valid user roles can be retrieved using the List Roles endpoint.
|
|
||||||
- `username` (String) The name of the user.
|
|
||||||
|
|
||||||
### Optional
|
|
||||||
|
|
||||||
- `default_database` (String) The default database for a user of the instance.
|
|
||||||
- `instance_id` (String) The ID of the instance.
|
|
||||||
- `project_id` (String) The STACKIT project ID.
|
|
||||||
- `region` (String) The region which should be addressed
|
|
||||||
- `user_id` (Number) The ID of the user.
|
|
||||||
|
|
||||||
### Read-Only
|
|
||||||
|
|
||||||
- `host` (String) The host of the instance in which the user belongs to.
|
|
||||||
- `id` (Number) The ID of the user.
|
|
||||||
- `password` (String) The password for the user.
|
|
||||||
- `port` (Number) The port of the instance in which the user belongs to.
|
|
||||||
- `status` (String) The current status of the user.
|
|
||||||
- `uri` (String) The connection string for the user to the instance.
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
data "stackitprivatepreview_postgresflexalpha_flavor" "flavor" {
|
|
||||||
project_id = var.project_id
|
|
||||||
region = var.region
|
|
||||||
cpu = 4
|
|
||||||
ram = 16
|
|
||||||
node_type = "Single"
|
|
||||||
storage_class = "premium-perf2-stackit"
|
|
||||||
}
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
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"
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
data "stackitprivatepreview_sqlserverflexbeta_database" "example" {
|
|
||||||
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
||||||
instance_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
||||||
database_name = "dbname"
|
|
||||||
}
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
data "stackitprivatepreview_sqlserverflexbeta_flavor" "flavor" {
|
|
||||||
project_id = var.project_id
|
|
||||||
region = var.region
|
|
||||||
cpu = 4
|
|
||||||
ram = 16
|
|
||||||
node_type = "Single"
|
|
||||||
storage_class = "premium-perf2-stackit"
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
data "stackitprivatepreview_sqlserverflexbeta_instance" "example" {
|
|
||||||
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
||||||
instance_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
||||||
}
|
|
||||||
|
|
@ -2,13 +2,14 @@ provider "stackitprivatepreview" {
|
||||||
default_region = "eu01"
|
default_region = "eu01"
|
||||||
}
|
}
|
||||||
|
|
||||||
provider "stackitprivatepreview" {
|
|
||||||
default_region = "eu01"
|
|
||||||
service_account_key_path = "service_account.json"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Authentication
|
# Authentication
|
||||||
|
|
||||||
|
# Token flow (scheduled for deprecation and will be removed on December 17, 2025)
|
||||||
|
provider "stackitprivatepreview" {
|
||||||
|
default_region = "eu01"
|
||||||
|
service_account_token = var.service_account_token
|
||||||
|
}
|
||||||
|
|
||||||
# Key flow
|
# Key flow
|
||||||
provider "stackitprivatepreview" {
|
provider "stackitprivatepreview" {
|
||||||
default_region = "eu01"
|
default_region = "eu01"
|
||||||
|
|
@ -22,3 +23,4 @@ provider "stackitprivatepreview" {
|
||||||
service_account_key_path = var.service_account_key_path
|
service_account_key_path = var.service_account_key_path
|
||||||
private_key_path = var.private_key_path
|
private_key_path = var.private_key_path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,13 +10,3 @@ import {
|
||||||
to = stackitprivatepreview_postgresflexalpha_database.import-example
|
to = stackitprivatepreview_postgresflexalpha_database.import-example
|
||||||
id = "${var.project_id},${var.region},${var.postgres_instance_id},${var.postgres_database_id}"
|
id = "${var.project_id},${var.region},${var.postgres_instance_id},${var.postgres_database_id}"
|
||||||
}
|
}
|
||||||
|
|
||||||
import {
|
|
||||||
to = stackitprivatepreview_postgresflexalpha_database.import-example
|
|
||||||
identity = {
|
|
||||||
project_id = "project_id"
|
|
||||||
region = "region"
|
|
||||||
instance_id = "instance_id"
|
|
||||||
database_id = "database_id"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,53 +1,18 @@
|
||||||
# NOTE: flavor handling will change in future
|
resource "stackitprivatepreview_postgresflexalpha_instance" "example" {
|
||||||
# V2 compatible flavor usage (example without encryption)
|
|
||||||
resource "stackitprivatepreview_postgresflexalpha_instance" "example-instance" {
|
|
||||||
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||||
name = "example-instance"
|
name = "example-instance"
|
||||||
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
|
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
|
||||||
backup_schedule = "0 0 * * *"
|
backup_schedule = "00 00 * * *"
|
||||||
retention_days = 30
|
|
||||||
flavor = {
|
flavor = {
|
||||||
cpu = 2
|
cpu = 2
|
||||||
ram = 4
|
ram = 4
|
||||||
}
|
}
|
||||||
replicas = 1
|
replicas = 3
|
||||||
storage = {
|
storage = {
|
||||||
performance_class = "premium-perf2-stackit"
|
class = "class"
|
||||||
size = 10
|
size = 5
|
||||||
}
|
}
|
||||||
network = {
|
version = 14
|
||||||
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"
|
|
||||||
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
|
|
||||||
backup_schedule = "0 0 * * *"
|
|
||||||
retention_days = 30
|
|
||||||
flavor_id = "flavor.id"
|
|
||||||
replicas = 1
|
|
||||||
storage = {
|
|
||||||
performance_class = "premium-perf2-stackit"
|
|
||||||
size = 10
|
|
||||||
}
|
|
||||||
encryption = {
|
|
||||||
kek_key_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
||||||
kek_key_ring_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
||||||
kek_key_version = 1
|
|
||||||
service_account = "service@account.email"
|
|
||||||
}
|
|
||||||
network = {
|
|
||||||
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
|
|
||||||
access_scope = "PUBLIC"
|
|
||||||
}
|
|
||||||
version = 17
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Only use the import statement, if you want to import an existing postgresflex instance
|
# Only use the import statement, if you want to import an existing postgresflex instance
|
||||||
|
|
@ -55,12 +20,3 @@ import {
|
||||||
to = stackitprivatepreview_postgresflexalpha_instance.import-example
|
to = stackitprivatepreview_postgresflexalpha_instance.import-example
|
||||||
id = "${var.project_id},${var.region},${var.postgres_instance_id}"
|
id = "${var.project_id},${var.region},${var.postgres_instance_id}"
|
||||||
}
|
}
|
||||||
|
|
||||||
import {
|
|
||||||
to = stackitprivatepreview_postgresflexalpha_instance.import-example
|
|
||||||
identity = {
|
|
||||||
project_id = var.project_id
|
|
||||||
region = var.region
|
|
||||||
instance_id = var.postgres_instance_id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
resource "stackitprivatepreview_postgresflexalpha_user" "example" {
|
resource "stackitprivatepreview_postgresflexalpha_user" "example" {
|
||||||
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||||
instance_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
instance_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||||
name = "username"
|
username = "username"
|
||||||
roles = ["role"]
|
roles = ["role"]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -10,13 +10,3 @@ import {
|
||||||
to = stackitprivatepreview_postgresflexalpha_user.import-example
|
to = stackitprivatepreview_postgresflexalpha_user.import-example
|
||||||
id = "${var.project_id},${var.region},${var.postgres_instance_id},${var.user_id}"
|
id = "${var.project_id},${var.region},${var.postgres_instance_id},${var.user_id}"
|
||||||
}
|
}
|
||||||
|
|
||||||
import {
|
|
||||||
to = stackitprivatepreview_postgresflexalpha_user.import-example
|
|
||||||
identity = {
|
|
||||||
project_id = "project.id"
|
|
||||||
region = "region"
|
|
||||||
instance_id = "instance.id"
|
|
||||||
user_id = "user.id"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
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"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
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}"
|
|
||||||
}
|
|
||||||
|
|
@ -1,101 +0,0 @@
|
||||||
# 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"
|
|
||||||
name = "example-instance"
|
|
||||||
backup_schedule = "0 3 * * *"
|
|
||||||
retention_days = 31
|
|
||||||
flavor_id = "flavor_id"
|
|
||||||
storage = {
|
|
||||||
class = "premium-perf2-stackit"
|
|
||||||
size = 50
|
|
||||||
}
|
|
||||||
version = 2022
|
|
||||||
network = {
|
|
||||||
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
|
|
||||||
access_scope = "SNA"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# without encryption and PUBLIC
|
|
||||||
resource "stackitprivatepreview_sqlserverflexbeta_instance" "instance" {
|
|
||||||
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
||||||
name = "example-instance"
|
|
||||||
backup_schedule = "0 3 * * *"
|
|
||||||
retention_days = 31
|
|
||||||
flavor_id = "flavor_id"
|
|
||||||
storage = {
|
|
||||||
class = "premium-perf2-stackit"
|
|
||||||
size = 50
|
|
||||||
}
|
|
||||||
version = 2022
|
|
||||||
network = {
|
|
||||||
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
|
|
||||||
access_scope = "PUBLIC"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# with encryption and SNA
|
|
||||||
resource "stackitprivatepreview_sqlserverflexbeta_instance" "instance" {
|
|
||||||
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
||||||
name = "example-instance"
|
|
||||||
backup_schedule = "0 3 * * *"
|
|
||||||
retention_days = 31
|
|
||||||
flavor_id = "flavor_id"
|
|
||||||
storage = {
|
|
||||||
class = "premium-perf2-stackit"
|
|
||||||
size = 50
|
|
||||||
}
|
|
||||||
version = 2022
|
|
||||||
encryption = {
|
|
||||||
kek_key_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
||||||
kek_key_ring_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
||||||
kek_key_version = 1
|
|
||||||
service_account = "service_account@email"
|
|
||||||
}
|
|
||||||
network = {
|
|
||||||
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
|
|
||||||
access_scope = "SNA"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Only use the import statement, if you want to import an existing sqlserverflex instance
|
|
||||||
import {
|
|
||||||
to = stackitprivatepreview_sqlserverflexalpha_instance.import-example
|
|
||||||
id = "${var.project_id},${var.region},${var.sql_instance_id}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# import with identity
|
|
||||||
import {
|
|
||||||
to = stackitprivatepreview_sqlserverflexalpha_instance.import-example
|
|
||||||
identity = {
|
|
||||||
project_id = var.project_id
|
|
||||||
region = var.region
|
|
||||||
instance_id = var.sql_instance_id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
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}"
|
|
||||||
}
|
|
||||||
|
|
@ -1,341 +0,0 @@
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
@ -1,131 +0,0 @@
|
||||||
package build
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"log/slog"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"syscall"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Source - https://stackoverflow.com/a
|
|
||||||
// Posted by Oleg Neumyvakin, modified by community. See post 'Timeline' for change history
|
|
||||||
// Retrieved 2026-01-20, License - CC BY-SA 4.0
|
|
||||||
|
|
||||||
func CopyDirectory(scrDir, dest string) error {
|
|
||||||
entries, err := os.ReadDir(scrDir)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for _, entry := range entries {
|
|
||||||
sourcePath := filepath.Join(scrDir, entry.Name())
|
|
||||||
destPath := filepath.Join(dest, entry.Name())
|
|
||||||
|
|
||||||
fileInfo, err := os.Stat(sourcePath)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
stat, ok := fileInfo.Sys().(*syscall.Stat_t)
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("failed to get raw syscall.Stat_t data for '%s'", sourcePath)
|
|
||||||
}
|
|
||||||
|
|
||||||
switch fileInfo.Mode() & os.ModeType {
|
|
||||||
case os.ModeDir:
|
|
||||||
if err := CreateIfNotExists(destPath, 0o755); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := CopyDirectory(sourcePath, destPath); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
case os.ModeSymlink:
|
|
||||||
if err := CopySymLink(sourcePath, destPath); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
if err := Copy(sourcePath, destPath); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := os.Lchown(destPath, int(stat.Uid), int(stat.Gid)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
fInfo, err := entry.Info()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
isSymlink := fInfo.Mode()&os.ModeSymlink != 0
|
|
||||||
if !isSymlink {
|
|
||||||
if err := os.Chmod(destPath, fInfo.Mode()); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func Copy(srcFile, dstFile string) error {
|
|
||||||
out, err := os.Create(dstFile)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
defer func(out *os.File) {
|
|
||||||
err := out.Close()
|
|
||||||
if err != nil {
|
|
||||||
slog.Error("failed to close file", slog.Any("err", err))
|
|
||||||
}
|
|
||||||
}(out)
|
|
||||||
|
|
||||||
in, err := os.Open(srcFile)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
defer func(in *os.File) {
|
|
||||||
err := in.Close()
|
|
||||||
if err != nil {
|
|
||||||
slog.Error("error closing destination file", slog.Any("err", err))
|
|
||||||
}
|
|
||||||
}(in)
|
|
||||||
|
|
||||||
_, err = io.Copy(out, in)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func Exists(filePath string) bool {
|
|
||||||
if _, err := os.Stat(filePath); os.IsNotExist(err) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateIfNotExists(dir string, perm os.FileMode) error {
|
|
||||||
if Exists(dir) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := os.MkdirAll(dir, perm); err != nil {
|
|
||||||
return fmt.Errorf("failed to create directory: '%s', error: '%s'", dir, err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func CopySymLink(source, dest string) error {
|
|
||||||
link, err := os.Readlink(source)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return os.Symlink(link, dest)
|
|
||||||
}
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
package build
|
|
||||||
|
|
||||||
import (
|
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
"unicode"
|
|
||||||
"unicode/utf8"
|
|
||||||
)
|
|
||||||
|
|
||||||
// snakeLetters will match to the first letter and an underscore followed by a letter
|
|
||||||
var snakeLetters = regexp.MustCompile("(^[a-z])|_[a-z0-9]")
|
|
||||||
|
|
||||||
func ToPascalCase(in string) string {
|
|
||||||
inputSplit := strings.Split(in, ".")
|
|
||||||
|
|
||||||
var ucName string
|
|
||||||
|
|
||||||
for _, v := range inputSplit {
|
|
||||||
if len(v) < 1 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
firstChar := v[0:1]
|
|
||||||
ucFirstChar := strings.ToUpper(firstChar)
|
|
||||||
|
|
||||||
if len(v) < 2 {
|
|
||||||
ucName += ucFirstChar
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
ucName += ucFirstChar + v[1:]
|
|
||||||
}
|
|
||||||
|
|
||||||
return snakeLetters.ReplaceAllStringFunc(ucName, func(s string) string {
|
|
||||||
return strings.ToUpper(strings.ReplaceAll(s, "_", ""))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func ToCamelCase(in string) string {
|
|
||||||
pascal := ToPascalCase(in)
|
|
||||||
|
|
||||||
// Grab first rune and lower case it
|
|
||||||
firstLetter, size := utf8.DecodeRuneInString(pascal)
|
|
||||||
if firstLetter == utf8.RuneError && size <= 1 {
|
|
||||||
return pascal
|
|
||||||
}
|
|
||||||
|
|
||||||
return string(unicode.ToLower(firstLetter)) + pascal[size:]
|
|
||||||
}
|
|
||||||
|
|
||||||
func ValidateSnakeCase(in string) bool {
|
|
||||||
return snakeLetters.MatchString(string(in))
|
|
||||||
}
|
|
||||||
|
|
@ -1,120 +0,0 @@
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
@ -1,446 +0,0 @@
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
@ -1,148 +0,0 @@
|
||||||
package {{.PackageName}}
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/datasource"
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
|
||||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
|
||||||
"github.com/stackitcloud/stackit-sdk-go/core/config"
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
|
|
||||||
|
|
||||||
{{.PackageName}}Pkg "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/{{.PackageName}}"
|
|
||||||
|
|
||||||
{{.PackageName}}Gen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/{{.PackageName}}/{{.NameSnake}}/datasources_gen"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ datasource.DataSource = (*{{.NameCamel}}DataSource)(nil)
|
|
||||||
|
|
||||||
const errorPrefix = "[{{.PackageNamePascal}} - {{.NamePascal}}]"
|
|
||||||
|
|
||||||
func New{{.NamePascal}}DataSource() datasource.DataSource {
|
|
||||||
return &{{.NameCamel}}DataSource{}
|
|
||||||
}
|
|
||||||
|
|
||||||
type dsModel struct {
|
|
||||||
{{.PackageName}}Gen.{{.NamePascal}}Model
|
|
||||||
TfId types.String `tfsdk:"id"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type {{.NameCamel}}DataSource struct{
|
|
||||||
client *{{.PackageName}}Pkg.APIClient
|
|
||||||
providerData core.ProviderData
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *{{.NameCamel}}DataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
|
|
||||||
resp.TypeName = req.ProviderTypeName + "_{{.PackageName}}_{{.NameSnake}}"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *{{.NameCamel}}DataSource) Schema(ctx context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
|
|
||||||
resp.Schema = {{.PackageName}}Gen.{{.NamePascal}}DataSourceSchema(ctx)
|
|
||||||
resp.Schema.Attributes["id"] = schema.StringAttribute{
|
|
||||||
Computed: true,
|
|
||||||
Description: "The terraform internal identifier.",
|
|
||||||
MarkdownDescription: "The terraform internal identifier.",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configure adds the provider configured client to the data source.
|
|
||||||
func (d *{{.NameCamel}}DataSource) Configure(
|
|
||||||
ctx context.Context,
|
|
||||||
req datasource.ConfigureRequest,
|
|
||||||
resp *datasource.ConfigureResponse,
|
|
||||||
) {
|
|
||||||
var ok bool
|
|
||||||
d.providerData, ok = conversion.ParseProviderData(ctx, req.ProviderData, &resp.Diagnostics)
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
apiClientConfigOptions := []config.ConfigurationOption{
|
|
||||||
config.WithCustomAuth(d.providerData.RoundTripper),
|
|
||||||
utils.UserAgentConfigOption(d.providerData.Version),
|
|
||||||
}
|
|
||||||
if d.providerData.{{.PackageNamePascal}}CustomEndpoint != "" {
|
|
||||||
apiClientConfigOptions = append(
|
|
||||||
apiClientConfigOptions,
|
|
||||||
config.WithEndpoint(d.providerData.{{.PackageNamePascal}}CustomEndpoint),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
apiClientConfigOptions = append(
|
|
||||||
apiClientConfigOptions,
|
|
||||||
config.WithRegion(d.providerData.GetRegion()),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
apiClient, err := {{.PackageName}}Pkg.NewAPIClient(apiClientConfigOptions...)
|
|
||||||
if err != nil {
|
|
||||||
resp.Diagnostics.AddError(
|
|
||||||
"Error configuring API client",
|
|
||||||
fmt.Sprintf(
|
|
||||||
"Configuring client: %v. This is an error related to the provider configuration, not to the resource configuration",
|
|
||||||
err,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
d.client = apiClient
|
|
||||||
tflog.Info(ctx, fmt.Sprintf("%s client configured", errorPrefix))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *{{.NameCamel}}DataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
|
|
||||||
var data dsModel
|
|
||||||
|
|
||||||
// Read Terraform configuration data into the model
|
|
||||||
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
|
|
||||||
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx = core.InitProviderContext(ctx)
|
|
||||||
|
|
||||||
projectId := data.ProjectId.ValueString()
|
|
||||||
region := d.providerData.GetRegionWithOverride(data.Region)
|
|
||||||
{{.NameCamel}}Id := data.{{.NamePascal}}Id.ValueString()
|
|
||||||
|
|
||||||
ctx = tflog.SetField(ctx, "project_id", projectId)
|
|
||||||
ctx = tflog.SetField(ctx, "region", region)
|
|
||||||
|
|
||||||
// TODO: implement needed fields
|
|
||||||
ctx = tflog.SetField(ctx, "{{.NameCamel}}_id", {{.NameCamel}}Id)
|
|
||||||
|
|
||||||
// TODO: refactor to correct implementation
|
|
||||||
{{.NameCamel}}Resp, err := d.client.Get{{.NamePascal}}Request(ctx, projectId, region, {{.NameCamel}}Id).Execute()
|
|
||||||
if err != nil {
|
|
||||||
utils.LogError(
|
|
||||||
ctx,
|
|
||||||
&resp.Diagnostics,
|
|
||||||
err,
|
|
||||||
"Reading {{.NameCamel}}",
|
|
||||||
fmt.Sprintf("{{.NameCamel}} with ID %q does not exist in project %q.", {{.NameCamel}}Id, projectId),
|
|
||||||
map[int]string{
|
|
||||||
http.StatusForbidden: fmt.Sprintf("Project with ID %q not found or forbidden access", projectId),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
resp.State.RemoveResource(ctx)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx = core.LogResponse(ctx)
|
|
||||||
|
|
||||||
|
|
||||||
data.TfId = utils.BuildInternalTerraformId(projectId, region, ..)
|
|
||||||
|
|
||||||
// TODO: fill remaining fields
|
|
||||||
{{- range .Fields }}
|
|
||||||
// data.{{.}} = types.Sometype(apiResponse.Get{{.}}())
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
// Save data into Terraform state
|
|
||||||
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
|
|
||||||
|
|
||||||
tflog.Info(ctx, fmt.Sprintf("%s read successful", errorPrefix))
|
|
||||||
}
|
|
||||||
|
|
@ -1,98 +0,0 @@
|
||||||
package {{.PackageName}}
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"math"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/attr"
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/resource"
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
|
|
||||||
|
|
||||||
{{.PackageName}} "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/{{.PackageName}}"
|
|
||||||
{{.PackageName}}ResGen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/{{.PackageName}}/instance/resources_gen"
|
|
||||||
)
|
|
||||||
|
|
||||||
func mapResponseToModel(
|
|
||||||
ctx context.Context,
|
|
||||||
resp *{{.PackageName}}.Get{{.NamePascal}}Response,
|
|
||||||
m *{{.PackageName}}ResGen.{{.NamePascal}}Model,
|
|
||||||
tfDiags diag.Diagnostics,
|
|
||||||
) error {
|
|
||||||
// TODO: complete and refactor
|
|
||||||
m.Id = types.StringValue(resp.GetId())
|
|
||||||
|
|
||||||
/*
|
|
||||||
sampleList, diags := types.ListValueFrom(ctx, types.StringType, resp.GetList())
|
|
||||||
tfDiags.Append(diags...)
|
|
||||||
if diags.HasError() {
|
|
||||||
return fmt.Errorf(
|
|
||||||
"error converting list response value",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
sample, diags := {{.PackageName}}ResGen.NewSampleValue(
|
|
||||||
{{.PackageName}}ResGen.SampleValue{}.AttributeTypes(ctx),
|
|
||||||
map[string]attr.Value{
|
|
||||||
"field": types.StringValue(string(resp.GetField())),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
tfDiags.Append(diags...)
|
|
||||||
if diags.HasError() {
|
|
||||||
return fmt.Errorf(
|
|
||||||
"error converting sample response value",
|
|
||||||
"sample",
|
|
||||||
types.StringValue(string(resp.GetField())),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
m.Sample = sample
|
|
||||||
*/
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func handleEncryption(
|
|
||||||
m *{{.PackageName}}ResGen.{{.NamePascal}}Model,
|
|
||||||
resp *{{.PackageName}}.Get{{.NamePascal}}Response,
|
|
||||||
) {{.PackageName}}ResGen.EncryptionValue {
|
|
||||||
if !resp.HasEncryption() ||
|
|
||||||
resp.Encryption == nil ||
|
|
||||||
resp.Encryption.KekKeyId == nil ||
|
|
||||||
resp.Encryption.KekKeyRingId == nil ||
|
|
||||||
resp.Encryption.KekKeyVersion == nil ||
|
|
||||||
resp.Encryption.ServiceAccount == nil {
|
|
||||||
|
|
||||||
if m.Encryption.IsNull() || m.Encryption.IsUnknown() {
|
|
||||||
return {{.PackageName}}ResGen.NewEncryptionValueNull()
|
|
||||||
}
|
|
||||||
return m.Encryption
|
|
||||||
}
|
|
||||||
|
|
||||||
enc := {{.PackageName}}ResGen.NewEncryptionValueNull()
|
|
||||||
if kVal, ok := resp.Encryption.GetKekKeyIdOk(); ok {
|
|
||||||
enc.KekKeyId = types.StringValue(kVal)
|
|
||||||
}
|
|
||||||
if kkVal, ok := resp.Encryption.GetKekKeyRingIdOk(); ok {
|
|
||||||
enc.KekKeyRingId = types.StringValue(kkVal)
|
|
||||||
}
|
|
||||||
if kkvVal, ok := resp.Encryption.GetKekKeyVersionOk(); ok {
|
|
||||||
enc.KekKeyVersion = types.StringValue(kkvVal)
|
|
||||||
}
|
|
||||||
if sa, ok := resp.Encryption.GetServiceAccountOk(); ok {
|
|
||||||
enc.ServiceAccount = types.StringValue(sa)
|
|
||||||
}
|
|
||||||
return enc
|
|
||||||
}
|
|
||||||
|
|
||||||
func toCreatePayload(
|
|
||||||
ctx context.Context,
|
|
||||||
model *{{.PackageName}}ResGen.{{.NamePascal}}Model,
|
|
||||||
) (*{{.PackageName}}.Create{{.NamePascal}}RequestPayload, error) {
|
|
||||||
if model == nil {
|
|
||||||
return nil, fmt.Errorf("nil model")
|
|
||||||
}
|
|
||||||
|
|
||||||
return &{{.PackageName}}.Create{{.NamePascal}}RequestPayload{
|
|
||||||
// TODO: fill fields
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
package {{.PackageName}}
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/datasource"
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/provider"
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/resource"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ provider.Provider = (*{{.NameCamel}}Provider)(nil)
|
|
||||||
|
|
||||||
func New() func() provider.Provider {
|
|
||||||
return func() provider.Provider {
|
|
||||||
return &{{.NameCamel}}Provider{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type {{.NameCamel}}Provider struct{}
|
|
||||||
|
|
||||||
func (p *{{.NameCamel}}Provider) Schema(ctx context.Context, req provider.SchemaRequest, resp *provider.SchemaResponse) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *{{.NameCamel}}Provider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *{{.NameCamel}}Provider) Metadata(ctx context.Context, req provider.MetadataRequest, resp *provider.MetadataResponse) {
|
|
||||||
resp.TypeName = "{{.NameSnake}}"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *{{.NameCamel}}Provider) DataSources(ctx context.Context) []func() datasource.DataSource {
|
|
||||||
return []func() datasource.DataSource{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *{{.NameCamel}}Provider) Resources(ctx context.Context) []func() resource.Resource {
|
|
||||||
return []func() resource.Resource{}
|
|
||||||
}
|
|
||||||
|
|
@ -1,429 +0,0 @@
|
||||||
package {{.PackageName}}
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
_ "embed"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/path"
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/resource"
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/resource/identityschema"
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
|
||||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
|
||||||
"github.com/stackitcloud/stackit-sdk-go/core/config"
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
|
|
||||||
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/{{.PackageName}}"
|
|
||||||
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
|
|
||||||
|
|
||||||
{{.PackageName}}ResGen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/{{.PackageName}}/{{.NameSnake}}/resources_gen"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
_ resource.Resource = &{{.NameCamel}}Resource{}
|
|
||||||
_ resource.ResourceWithConfigure = &{{.NameCamel}}Resource{}
|
|
||||||
_ resource.ResourceWithImportState = &{{.NameCamel}}Resource{}
|
|
||||||
_ resource.ResourceWithModifyPlan = &{{.NameCamel}}Resource{}
|
|
||||||
_ resource.ResourceWithIdentity = &{{.NameCamel}}Resource{}
|
|
||||||
)
|
|
||||||
|
|
||||||
func New{{.NamePascal}}Resource() resource.Resource {
|
|
||||||
return &{{.NameCamel}}Resource{}
|
|
||||||
}
|
|
||||||
|
|
||||||
type {{.NameCamel}}Resource struct{
|
|
||||||
client *{{.PackageName}}.APIClient
|
|
||||||
providerData core.ProviderData
|
|
||||||
}
|
|
||||||
|
|
||||||
// resourceModel represents the Terraform resource state
|
|
||||||
type resourceModel = {{.PackageName}}.{{.NamePascal}}Model
|
|
||||||
|
|
||||||
type {{.NamePascal}}ResourceIdentityModel struct {
|
|
||||||
ProjectID types.String `tfsdk:"project_id"`
|
|
||||||
Region types.String `tfsdk:"region"`
|
|
||||||
// TODO: implement further needed parts
|
|
||||||
{{.NamePascal}}ID types.String `tfsdk:"{{.NameSnake}}_id"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Metadata defines terraform resource name
|
|
||||||
func (r *{{.NameCamel}}Resource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
|
|
||||||
resp.TypeName = req.ProviderTypeName + "_{{.PackageName}}_{{.NameSnake}}"
|
|
||||||
}
|
|
||||||
|
|
||||||
//go:embed planModifiers.yaml
|
|
||||||
var modifiersFileByte []byte
|
|
||||||
|
|
||||||
// Schema loads the schema from generated files and adds plan modifiers
|
|
||||||
func (r *{{.NameCamel}}Resource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
|
|
||||||
schema = {{.PackageName}}ResGen.{{.NamePascal}}ResourceSchema(ctx)
|
|
||||||
|
|
||||||
fields, err := {{.PackageName}}Utils.ReadModifiersConfig(modifiersFileByte)
|
|
||||||
if err != nil {
|
|
||||||
resp.Diagnostics.AddError("error during read modifiers config file", err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = {{.PackageName}}Utils.AddPlanModifiersToResourceSchema(fields, &schema)
|
|
||||||
if err != nil {
|
|
||||||
resp.Diagnostics.AddError("error adding plan modifiers", err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
resp.Schema = schema
|
|
||||||
}
|
|
||||||
|
|
||||||
// IdentitySchema defines the identity schema
|
|
||||||
func (r *instanceResource) IdentitySchema(_ context.Context, _ resource.IdentitySchemaRequest, resp *resource.IdentitySchemaResponse) {
|
|
||||||
resp.IdentitySchema = identityschema.Schema{
|
|
||||||
Attributes: map[string]identityschema.Attribute{
|
|
||||||
"project_id": identityschema.StringAttribute{
|
|
||||||
RequiredForImport: true, // must be set during import by the practitioner
|
|
||||||
},
|
|
||||||
"region": identityschema.StringAttribute{
|
|
||||||
RequiredForImport: true, // can be defaulted by the provider configuration
|
|
||||||
},
|
|
||||||
"instance_id": identityschema.StringAttribute{
|
|
||||||
RequiredForImport: true, // can be defaulted by the provider configuration
|
|
||||||
},
|
|
||||||
// TODO: implement remaining schema parts
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configure adds the provider configured client to the resource.
|
|
||||||
func (r *{{.NameCamel}}Resource) Configure(
|
|
||||||
ctx context.Context,
|
|
||||||
req resource.ConfigureRequest,
|
|
||||||
resp *resource.ConfigureResponse,
|
|
||||||
) {
|
|
||||||
var ok bool
|
|
||||||
r.providerData, ok = conversion.ParseProviderData(ctx, req.ProviderData, &resp.Diagnostics)
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
apiClientConfigOptions := []config.ConfigurationOption{
|
|
||||||
config.WithCustomAuth(r.providerData.RoundTripper),
|
|
||||||
utils.UserAgentConfigOption(r.providerData.Version),
|
|
||||||
}
|
|
||||||
if r.providerData.{{.PackageNamePascal}}CustomEndpoint != "" {
|
|
||||||
apiClientConfigOptions = append(apiClientConfigOptions, config.WithEndpoint(r.providerData.{{.PackageName}}CustomEndpoint))
|
|
||||||
} else {
|
|
||||||
apiClientConfigOptions = append(apiClientConfigOptions, config.WithRegion(r.providerData.GetRegion()))
|
|
||||||
}
|
|
||||||
apiClient, err := {{.PackageName}}.NewAPIClient(apiClientConfigOptions...)
|
|
||||||
if err != nil {
|
|
||||||
resp.Diagnostics.AddError(
|
|
||||||
"Error configuring API client",
|
|
||||||
fmt.Sprintf(
|
|
||||||
"Configuring client: %v. This is an error related to the provider configuration, not to the resource configuration",
|
|
||||||
err,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
r.client = apiClient
|
|
||||||
tflog.Info(ctx, "{{.PackageName}}.{{.NamePascal}} client configured")
|
|
||||||
}
|
|
||||||
|
|
||||||
// ModifyPlan implements resource.ResourceWithModifyPlan.
|
|
||||||
// Use the modifier to set the effective region in the current plan.
|
|
||||||
func (r *{{.NameCamel}}Resource) ModifyPlan(
|
|
||||||
ctx context.Context,
|
|
||||||
req resource.ModifyPlanRequest,
|
|
||||||
resp *resource.ModifyPlanResponse,
|
|
||||||
) { // nolint:gocritic // function signature required by Terraform
|
|
||||||
|
|
||||||
// skip initial empty configuration to avoid follow-up errors
|
|
||||||
if req.Config.Raw.IsNull() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var configModel {{.PackageName}}ResGen.{{.NamePascal}}Model
|
|
||||||
resp.Diagnostics.Append(req.Config.Get(ctx, &configModel)...)
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if req.Plan.Raw.IsNull() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var planModel {{.PackageName}}ResGen.{{.NamePascal}}Model
|
|
||||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &planModel)...)
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
utils.AdaptRegion(ctx, configModel.Region, &planModel.Region, r.providerData.GetRegion(), resp)
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp.Diagnostics.Append(resp.Plan.Set(ctx, planModel)...)
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create creates a new resource
|
|
||||||
func (r *{{.NameCamel}}Resource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
|
|
||||||
var data {{.PackageName}}ResGen.{{.NamePascal}}Model
|
|
||||||
|
|
||||||
// Read Terraform plan data into the model
|
|
||||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
|
|
||||||
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx = core.InitProviderContext(ctx)
|
|
||||||
|
|
||||||
projectId := data.ProjectId.ValueString()
|
|
||||||
region := data.Region.ValueString()
|
|
||||||
ctx = tflog.SetField(ctx, "project_id", projectId)
|
|
||||||
ctx = tflog.SetField(ctx, "region", region)
|
|
||||||
// TODO: add remaining fields
|
|
||||||
|
|
||||||
// TODO: Create API call logic
|
|
||||||
/*
|
|
||||||
// Generate API request body from model
|
|
||||||
payload, err := toCreatePayload(ctx, &model)
|
|
||||||
if err != nil {
|
|
||||||
core.LogAndAddError(
|
|
||||||
ctx,
|
|
||||||
&resp.Diagnostics,
|
|
||||||
"Error creating {{.NamePascal}}",
|
|
||||||
fmt.Sprintf("Creating API payload: %v", err),
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Create new {{.NamePascal}}
|
|
||||||
createResp, err := r.client.Create{{.NamePascal}}Request(
|
|
||||||
ctx,
|
|
||||||
projectId,
|
|
||||||
region,
|
|
||||||
).Create{{.NamePascal}}RequestPayload(*payload).Execute()
|
|
||||||
if err != nil {
|
|
||||||
core.LogAndAddError(ctx, &resp.Diagnostics, "Error creating {{.NamePascal}}", fmt.Sprintf("Calling API: %v", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx = core.LogResponse(ctx)
|
|
||||||
|
|
||||||
{{.NamePascal}}Id := *createResp.Id
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Example data value setting
|
|
||||||
data.{{.NameCamel | ucfirst}}Id = types.StringValue("id-from-response")
|
|
||||||
|
|
||||||
// TODO: Set data returned by API in identity
|
|
||||||
identity := {{.NamePascal}}ResourceIdentityModel{
|
|
||||||
ProjectID: types.StringValue(projectId),
|
|
||||||
Region: types.StringValue(region),
|
|
||||||
// TODO: add missing values
|
|
||||||
{{.NamePascal}}ID: types.StringValue({{.NamePascal}}Id),
|
|
||||||
}
|
|
||||||
resp.Diagnostics.Append(resp.Identity.Set(ctx, identity)...)
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: implement wait handler if needed
|
|
||||||
/*
|
|
||||||
|
|
||||||
waitResp, err := wait.Create{{.NamePascal}}WaitHandler(
|
|
||||||
ctx,
|
|
||||||
r.client,
|
|
||||||
projectId,
|
|
||||||
{{.NamePascal}}Id,
|
|
||||||
region,
|
|
||||||
).SetSleepBeforeWait(
|
|
||||||
30 * time.Second,
|
|
||||||
).SetTimeout(
|
|
||||||
90 * time.Minute,
|
|
||||||
).WaitWithContext(ctx)
|
|
||||||
if err != nil {
|
|
||||||
core.LogAndAddError(
|
|
||||||
ctx,
|
|
||||||
&resp.Diagnostics,
|
|
||||||
"Error creating {{.NamePascal}}",
|
|
||||||
fmt.Sprintf("{{.NamePascal}} creation waiting: %v", err),
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if waitResp.Id == nil {
|
|
||||||
core.LogAndAddError(
|
|
||||||
ctx,
|
|
||||||
&resp.Diagnostics,
|
|
||||||
"Error creating {{.NamePascal}}",
|
|
||||||
"{{.NamePascal}} creation waiting: returned id is nil",
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Map response body to schema
|
|
||||||
err = mapResponseToModel(ctx, waitResp, &model, resp.Diagnostics)
|
|
||||||
if err != nil {
|
|
||||||
core.LogAndAddError(
|
|
||||||
ctx,
|
|
||||||
&resp.Diagnostics,
|
|
||||||
"Error creating {{.NamePascal}}",
|
|
||||||
fmt.Sprintf("Processing API payload: %v", err),
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Save data into Terraform state
|
|
||||||
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
|
|
||||||
|
|
||||||
tflog.Info(ctx, "{{.PackageName}}.{{.NamePascal}} created")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *{{.NameCamel}}Resource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
|
|
||||||
var data {{.PackageName}}ResGen.{{.NamePascal}}Model
|
|
||||||
|
|
||||||
// Read Terraform prior state data into the model
|
|
||||||
resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read identity data
|
|
||||||
var identityData {{.NamePascal}}ResourceIdentityModel
|
|
||||||
resp.Diagnostics.Append(req.Identity.Get(ctx, &identityData)...)
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ctx = core.InitProviderContext(ctx)
|
|
||||||
|
|
||||||
projectId := identityData.ProjectID.ValueString()
|
|
||||||
region := identityData.Region.ValueString()
|
|
||||||
ctx = tflog.SetField(ctx, "project_id", projectId)
|
|
||||||
ctx = tflog.SetField(ctx, "region", region)
|
|
||||||
|
|
||||||
// TODO: Read API call logic
|
|
||||||
|
|
||||||
// Save updated data into Terraform state
|
|
||||||
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
|
|
||||||
|
|
||||||
// TODO: Set data returned by API in identity
|
|
||||||
identity := {{.NamePascal}}ResourceIdentityModel{
|
|
||||||
ProjectID: types.StringValue(projectId),
|
|
||||||
Region: types.StringValue(region),
|
|
||||||
// InstanceID: types.StringValue(instanceId),
|
|
||||||
}
|
|
||||||
resp.Diagnostics.Append(resp.Identity.Set(ctx, identity)...)
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
tflog.Info(ctx, "{{.PackageName}}.{{.NamePascal}} read")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *{{.NameCamel}}Resource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
|
|
||||||
var data {{.PackageName}}ResGen.{{.NamePascal}}Model
|
|
||||||
|
|
||||||
// Read Terraform prior state data into the model
|
|
||||||
resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx = core.InitProviderContext(ctx)
|
|
||||||
|
|
||||||
projectId := data.ProjectId.ValueString()
|
|
||||||
region := data.Region.ValueString()
|
|
||||||
ctx = tflog.SetField(ctx, "project_id", projectId)
|
|
||||||
ctx = tflog.SetField(ctx, "region", region)
|
|
||||||
|
|
||||||
// TODO: Update API call logic
|
|
||||||
|
|
||||||
// TODO: Set data returned by API in identity
|
|
||||||
identity := {{.NamePascal}}ResourceIdentityModel{
|
|
||||||
ProjectID: types.StringValue(projectId),
|
|
||||||
Region: types.StringValue(region),
|
|
||||||
// TODO: add missing values
|
|
||||||
{{.NamePascal}}ID: types.StringValue({{.NamePascal}}Id),
|
|
||||||
}
|
|
||||||
resp.Diagnostics.Append(resp.Identity.Set(ctx, identity)...)
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save updated data into Terraform state
|
|
||||||
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
|
|
||||||
|
|
||||||
tflog.Info(ctx, "{{.PackageName}}.{{.NamePascal}} updated")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *{{.NameCamel}}Resource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
|
|
||||||
var data {{.PackageName}}ResGen.{{.NamePascal}}Model
|
|
||||||
|
|
||||||
// Read Terraform prior state data into the model
|
|
||||||
resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read identity data
|
|
||||||
var identityData {{.NamePascal}}ResourceIdentityModel
|
|
||||||
resp.Diagnostics.Append(req.Identity.Get(ctx, &identityData)...)
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ctx = core.InitProviderContext(ctx)
|
|
||||||
|
|
||||||
projectId := identityData.ProjectID.ValueString()
|
|
||||||
region := identityData.Region.ValueString()
|
|
||||||
ctx = tflog.SetField(ctx, "project_id", projectId)
|
|
||||||
ctx = tflog.SetField(ctx, "region", region)
|
|
||||||
|
|
||||||
// TODO: Delete API call logic
|
|
||||||
|
|
||||||
tflog.Info(ctx, "{{.PackageName}}.{{.NamePascal}} deleted")
|
|
||||||
}
|
|
||||||
|
|
||||||
// ImportState imports a resource into the Terraform state on success.
|
|
||||||
// The expected format of the resource import identifier is: project_id,zone_id,record_set_id
|
|
||||||
func (r *{{.NameCamel}}Resource) ImportState(
|
|
||||||
ctx context.Context,
|
|
||||||
req resource.ImportStateRequest,
|
|
||||||
resp *resource.ImportStateResponse,
|
|
||||||
) {
|
|
||||||
idParts := strings.Split(req.ID, core.Separator)
|
|
||||||
|
|
||||||
// TODO: Import logic
|
|
||||||
// TODO: fix len and parts itself
|
|
||||||
if len(idParts) < 2 || idParts[0] == "" || idParts[1] == "" {
|
|
||||||
core.LogAndAddError(
|
|
||||||
ctx, &resp.Diagnostics,
|
|
||||||
"Error importing database",
|
|
||||||
fmt.Sprintf(
|
|
||||||
"Expected import identifier with format [project_id],[region],..., got %q",
|
|
||||||
req.ID,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("project_id"), idParts[0])...)
|
|
||||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("region"), idParts[1])...)
|
|
||||||
// ... more ...
|
|
||||||
|
|
||||||
core.LogAndAddWarning(
|
|
||||||
ctx,
|
|
||||||
&resp.Diagnostics,
|
|
||||||
"{{.PackageName | ucfirst}} database imported with empty password",
|
|
||||||
"The database password is not imported as it is only available upon creation of a new database. The password field will be empty.",
|
|
||||||
)
|
|
||||||
tflog.Info(ctx, "{{.PackageName | ucfirst}} {{.NameCamel}} state imported")
|
|
||||||
}
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
package utils
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
{{.PackageName}} "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/{{.PackageName}}"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
|
||||||
"github.com/stackitcloud/stackit-sdk-go/core/config"
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ConfigureClient(
|
|
||||||
ctx context.Context,
|
|
||||||
providerData *core.ProviderData,
|
|
||||||
diags *diag.Diagnostics,
|
|
||||||
) *{{.PackageName}}.APIClient {
|
|
||||||
apiClientConfigOptions := []config.ConfigurationOption{
|
|
||||||
config.WithCustomAuth(providerData.RoundTripper),
|
|
||||||
utils.UserAgentConfigOption(providerData.Version),
|
|
||||||
}
|
|
||||||
if providerData.{{.PackageName}}CustomEndpoint != "" {
|
|
||||||
apiClientConfigOptions = append(
|
|
||||||
apiClientConfigOptions,
|
|
||||||
config.WithEndpoint(providerData.{{.PackageName}}CustomEndpoint),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
apiClientConfigOptions = append(apiClientConfigOptions, config.WithRegion(providerData.GetRegion()))
|
|
||||||
}
|
|
||||||
apiClient, err := {{.PackageName}}.NewAPIClient(apiClientConfigOptions...)
|
|
||||||
if err != nil {
|
|
||||||
core.LogAndAddError(
|
|
||||||
ctx,
|
|
||||||
diags,
|
|
||||||
"Error configuring API client",
|
|
||||||
fmt.Sprintf(
|
|
||||||
"Configuring client: %v. This is an error related to the provider configuration, not to the resource configuration",
|
|
||||||
err,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return apiClient
|
|
||||||
}
|
|
||||||
|
|
@ -1,97 +0,0 @@
|
||||||
package utils
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"os"
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
|
||||||
sdkClients "github.com/stackitcloud/stackit-sdk-go/core/clients"
|
|
||||||
"github.com/stackitcloud/stackit-sdk-go/core/config"
|
|
||||||
{{.PackageName}} "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/{{.PackageName}}"
|
|
||||||
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
testVersion = "1.2.3"
|
|
||||||
testCustomEndpoint = "https://sqlserverflex-custom-endpoint.api.stackit.cloud"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestConfigureClient(t *testing.T) {
|
|
||||||
/* mock authentication by setting service account token env variable */
|
|
||||||
os.Clearenv()
|
|
||||||
err := os.Setenv(sdkClients.ServiceAccountToken, "mock-val")
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("error setting env variable: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
type args struct {
|
|
||||||
providerData *core.ProviderData
|
|
||||||
}
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
args args
|
|
||||||
wantErr bool
|
|
||||||
expected *sqlserverflex.APIClient
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "default endpoint",
|
|
||||||
args: args{
|
|
||||||
providerData: &core.ProviderData{
|
|
||||||
Version: testVersion,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expected: func() *sqlserverflex.APIClient {
|
|
||||||
apiClient, err := sqlserverflex.NewAPIClient(
|
|
||||||
config.WithRegion("eu01"),
|
|
||||||
utils.UserAgentConfigOption(testVersion),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("error configuring client: %v", err)
|
|
||||||
}
|
|
||||||
return apiClient
|
|
||||||
}(),
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "custom endpoint",
|
|
||||||
args: args{
|
|
||||||
providerData: &core.ProviderData{
|
|
||||||
Version: testVersion,
|
|
||||||
SQLServerFlexCustomEndpoint: testCustomEndpoint,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expected: func() *sqlserverflex.APIClient {
|
|
||||||
apiClient, err := sqlserverflex.NewAPIClient(
|
|
||||||
utils.UserAgentConfigOption(testVersion),
|
|
||||||
config.WithEndpoint(testCustomEndpoint),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("error configuring client: %v", err)
|
|
||||||
}
|
|
||||||
return apiClient
|
|
||||||
}(),
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(
|
|
||||||
tt.name, func(t *testing.T) {
|
|
||||||
ctx := context.Background()
|
|
||||||
diags := diag.Diagnostics{}
|
|
||||||
|
|
||||||
actual := ConfigureClient(ctx, tt.args.providerData, &diags)
|
|
||||||
if diags.HasError() != tt.wantErr {
|
|
||||||
t.Errorf("ConfigureClient() error = %v, want %v", diags.HasError(), tt.wantErr)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !reflect.DeepEqual(actual, tt.expected) {
|
|
||||||
t.Errorf("ConfigureClient() = %v, want %v", actual, tt.expected)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
package cmd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/generator/cmd/build"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
skipCleanup bool
|
|
||||||
skipClone bool
|
|
||||||
packagesOnly bool
|
|
||||||
verbose bool
|
|
||||||
debug bool
|
|
||||||
)
|
|
||||||
|
|
||||||
var buildCmd = &cobra.Command{
|
|
||||||
Use: "build",
|
|
||||||
Short: "Build the necessary boilerplate",
|
|
||||||
Long: `...`,
|
|
||||||
RunE: func(_ *cobra.Command, _ []string) error {
|
|
||||||
b := build.Builder{
|
|
||||||
SkipClone: skipClone,
|
|
||||||
SkipCleanup: skipCleanup,
|
|
||||||
PackagesOnly: packagesOnly,
|
|
||||||
Verbose: verbose,
|
|
||||||
Debug: debug,
|
|
||||||
}
|
|
||||||
return b.Build()
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewBuildCmd() *cobra.Command {
|
|
||||||
return buildCmd
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() { //nolint:gochecknoinits // This is the standard way to set up Cobra commands
|
|
||||||
buildCmd.Flags().BoolVarP(&skipCleanup, "skip-clean", "c", false, "Skip cleanup steps")
|
|
||||||
buildCmd.Flags().BoolVarP(&debug, "debug", "d", false, "Enable debug output")
|
|
||||||
buildCmd.Flags().BoolVarP(&skipClone, "skip-clone", "g", false, "Skip cloning from git")
|
|
||||||
buildCmd.Flags().BoolVarP(&packagesOnly, "packages-only", "p", false, "Only generate packages")
|
|
||||||
buildCmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "verbose - show more logs")
|
|
||||||
}
|
|
||||||
|
|
@ -1,247 +0,0 @@
|
||||||
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
27
generator/cmd/docs/templates/nav.md.gompl
vendored
|
|
@ -1,27 +0,0 @@
|
||||||
---
|
|
||||||
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 }}
|
|
||||||
|
|
@ -1,114 +0,0 @@
|
||||||
package cmd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
|
||||||
|
|
||||||
var examplesCmd = &cobra.Command{
|
|
||||||
Use: "examples",
|
|
||||||
Short: "create examples",
|
|
||||||
Long: `...`,
|
|
||||||
RunE: func(_ *cobra.Command, _ []string) error {
|
|
||||||
// filePathStr := "stackit/internal/services/postgresflexalpha/database/datasources_gen/database_data_source_gen.go"
|
|
||||||
//
|
|
||||||
// src, err := os.ReadFile(filePathStr)
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
// i := interp.New(
|
|
||||||
// interp.Options{
|
|
||||||
// GoPath: "/home/henselinm/.asdf/installs/golang/1.25.6/packages",
|
|
||||||
// BuildTags: nil,
|
|
||||||
// Stdin: nil,
|
|
||||||
// Stdout: nil,
|
|
||||||
// Stderr: nil,
|
|
||||||
// Args: nil,
|
|
||||||
// Env: nil,
|
|
||||||
// SourcecodeFilesystem: nil,
|
|
||||||
// Unrestricted: false,
|
|
||||||
// },
|
|
||||||
//)
|
|
||||||
// err = i.Use(i.Symbols("github.com/hashicorp/terraform-plugin-framework-validators"))
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
//}
|
|
||||||
// err = i.Use(stdlib.Symbols)
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
//}
|
|
||||||
// _, err = i.Eval(string(src))
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
// v, err := i.Eval("DatabaseDataSourceSchema")
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
// bar := v.Interface().(func(string) string)
|
|
||||||
//
|
|
||||||
// r := bar("Kung")
|
|
||||||
// println(r)
|
|
||||||
//
|
|
||||||
// evalPath, err := i.EvalPath(filePathStr)
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
// fmt.Printf("%+v\n", evalPath)
|
|
||||||
|
|
||||||
// _, err = i.Eval(`import "fmt"`)
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
//}
|
|
||||||
// _, err = i.Eval(`func Hallo() { fmt.Println("Hi!") }`)
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
//}
|
|
||||||
|
|
||||||
// v = i.Symbols("Hallo")
|
|
||||||
|
|
||||||
// fmt.Println(v)
|
|
||||||
return workServices()
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func workServices() error {
|
|
||||||
startPath := path.Join("stackit", "internal", "services")
|
|
||||||
|
|
||||||
services, err := os.ReadDir(startPath)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, entry := range services {
|
|
||||||
if !entry.IsDir() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
resources, err := os.ReadDir(path.Join(startPath, entry.Name()))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for _, res := range resources {
|
|
||||||
if !res.IsDir() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
fmt.Println("Gefunden:", startPath, "subdir", entry.Name(), "resource", res.Name())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewExamplesCmd() *cobra.Command {
|
|
||||||
return examplesCmd
|
|
||||||
}
|
|
||||||
|
|
||||||
// func init() { // nolint: gochecknoinits
|
|
||||||
// examplesCmd.Flags().BoolVarP(&example, "example", "e", false, "example")
|
|
||||||
//}
|
|
||||||
|
|
@ -1,148 +0,0 @@
|
||||||
package cmd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"go/ast"
|
|
||||||
"go/parser"
|
|
||||||
"go/token"
|
|
||||||
"path"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
inFile string
|
|
||||||
svcName string
|
|
||||||
resName string
|
|
||||||
resType string
|
|
||||||
filePath string
|
|
||||||
)
|
|
||||||
|
|
||||||
var getFieldsCmd = &cobra.Command{
|
|
||||||
Use: "get-fields",
|
|
||||||
Short: "get fields from file",
|
|
||||||
Long: `...`,
|
|
||||||
PreRunE: func(_ *cobra.Command, _ []string) error {
|
|
||||||
typeStr := "data_source"
|
|
||||||
if resType != "resource" && resType != "datasource" {
|
|
||||||
return fmt.Errorf("--type can only be resource or datasource")
|
|
||||||
}
|
|
||||||
|
|
||||||
if resType == "resource" {
|
|
||||||
typeStr = resType
|
|
||||||
}
|
|
||||||
|
|
||||||
if inFile == "" && svcName == "" && resName == "" {
|
|
||||||
return fmt.Errorf("--infile or --service and --resource must be provided")
|
|
||||||
}
|
|
||||||
|
|
||||||
if inFile != "" {
|
|
||||||
if svcName != "" || resName != "" {
|
|
||||||
return fmt.Errorf("--infile is provided and excludes --service and --resource")
|
|
||||||
}
|
|
||||||
p, err := filepath.Abs(inFile)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
filePath = p
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if svcName != "" && resName == "" {
|
|
||||||
return fmt.Errorf("if --service is provided, you MUST also provide --resource")
|
|
||||||
}
|
|
||||||
|
|
||||||
if svcName == "" && resName != "" {
|
|
||||||
return fmt.Errorf("if --resource is provided, you MUST also provide --service")
|
|
||||||
}
|
|
||||||
|
|
||||||
p, err := filepath.Abs(
|
|
||||||
path.Join(
|
|
||||||
"stackit",
|
|
||||||
"internal",
|
|
||||||
"services",
|
|
||||||
svcName,
|
|
||||||
resName,
|
|
||||||
fmt.Sprintf("%ss_gen", resType),
|
|
||||||
fmt.Sprintf("%s_%s_gen.go", resName, typeStr),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
filePath = p
|
|
||||||
|
|
||||||
//// Enum check
|
|
||||||
// switch format {
|
|
||||||
// case "json", "yaml":
|
|
||||||
//default:
|
|
||||||
// return fmt.Errorf("invalid --format: %s (want json|yaml)", format)
|
|
||||||
//}
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
RunE: func(_ *cobra.Command, _ []string) error {
|
|
||||||
return getFields(filePath)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func getFields(f string) error {
|
|
||||||
tokens, err := getTokens(f)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for _, item := range tokens {
|
|
||||||
fmt.Printf("%s \n", item)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getTokens(fileName string) ([]string, error) {
|
|
||||||
fset := token.NewFileSet()
|
|
||||||
var result []string
|
|
||||||
|
|
||||||
node, err := parser.ParseFile(fset, fileName, nil, parser.ParseComments)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
ast.Inspect(
|
|
||||||
node, func(n ast.Node) bool {
|
|
||||||
// Suche nach Typ-Deklarationen (structs)
|
|
||||||
ts, ok := n.(*ast.TypeSpec)
|
|
||||||
if ok {
|
|
||||||
if strings.Contains(ts.Name.Name, "Model") {
|
|
||||||
ast.Inspect(
|
|
||||||
ts, func(sn ast.Node) bool {
|
|
||||||
tts, tok := sn.(*ast.Field)
|
|
||||||
if tok {
|
|
||||||
result = append(result, tts.Names[0].String())
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
)
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewGetFieldsCmd() *cobra.Command {
|
|
||||||
return getFieldsCmd
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() { //nolint:gochecknoinits //this is the only way to add the command to the rootCmd
|
|
||||||
getFieldsCmd.Flags().StringVarP(&inFile, "infile", "i", "", "input filename incl path")
|
|
||||||
getFieldsCmd.Flags().StringVarP(&svcName, "service", "s", "", "service name")
|
|
||||||
getFieldsCmd.Flags().StringVarP(&resName, "resource", "r", "", "resource name")
|
|
||||||
getFieldsCmd.Flags().StringVarP(
|
|
||||||
&resType,
|
|
||||||
"type",
|
|
||||||
"t",
|
|
||||||
"resource",
|
|
||||||
"resource type (data-source or resource [default])",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
@ -1,137 +0,0 @@
|
||||||
package publish
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"net/url"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Architecture struct {
|
|
||||||
Protocols []string `json:"protocols"`
|
|
||||||
OS string `json:"os"`
|
|
||||||
Arch string `json:"arch"`
|
|
||||||
FileName string `json:"filename"`
|
|
||||||
DownloadUrl string `json:"download_url"`
|
|
||||||
ShaSumsUrl string `json:"shasums_url"`
|
|
||||||
ShaSumsSignatureUrl string `json:"shasums_signature_url"`
|
|
||||||
ShaSum string `json:"shasum"`
|
|
||||||
SigningKeys SigningKey `json:"signing_keys"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type SigningKey struct {
|
|
||||||
GpgPublicKeys []GpgPublicKey `json:"gpg_public_keys"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type GpgPublicKey struct {
|
|
||||||
KeyId string `json:"key_id"`
|
|
||||||
AsciiArmor string `json:"ascii_armor"`
|
|
||||||
TrustSignature string `json:"trust_signature"`
|
|
||||||
Source string `json:"source"`
|
|
||||||
SourceUrl string `json:"source_url"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Provider) CreateArchitectureFiles() error {
|
|
||||||
log.Println("* Creating architecture files in target directories")
|
|
||||||
|
|
||||||
prefix := path.Join("v1", "providers", p.Namespace, p.Provider, p.Version)
|
|
||||||
|
|
||||||
pathPrefix := path.Join("release", prefix)
|
|
||||||
|
|
||||||
urlPrefix, err := url.JoinPath("https://", p.Domain, prefix)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error creating base url: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
downloadUrlPrefix, err := url.JoinPath(urlPrefix, "download")
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error crearting download url: %w", err)
|
|
||||||
}
|
|
||||||
downloadPathPrefix := path.Join(pathPrefix, "download")
|
|
||||||
|
|
||||||
shasumsUrl, err := url.JoinPath(urlPrefix, fmt.Sprintf("%s_%s_SHA256SUMS", p.RepoName, p.Version))
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error creating shasums url: %w", err)
|
|
||||||
}
|
|
||||||
shasumsSigUrl := shasumsUrl + ".sig"
|
|
||||||
|
|
||||||
gpgAsciiPub, err := p.ReadGpgFile()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
shaSums, err := p.GetShaSums()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for _, sum := range shaSums {
|
|
||||||
downloadUrl, err := url.JoinPath(downloadUrlPrefix, sum.Path)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error creating url: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// get os and arch from filename
|
|
||||||
removeFileExtension := strings.Split(sum.Path, ".zip")
|
|
||||||
fileNameSplit := strings.Split(removeFileExtension[0], "_")
|
|
||||||
|
|
||||||
// Get build target and architecture from the zip file name
|
|
||||||
target := fileNameSplit[2]
|
|
||||||
arch := fileNameSplit[3]
|
|
||||||
|
|
||||||
// build filepath
|
|
||||||
archFileName := path.Join(downloadPathPrefix, target, arch)
|
|
||||||
|
|
||||||
a := Architecture{
|
|
||||||
Protocols: []string{"5.1", "6.0"},
|
|
||||||
OS: target,
|
|
||||||
Arch: arch,
|
|
||||||
FileName: sum.Path,
|
|
||||||
DownloadUrl: downloadUrl,
|
|
||||||
ShaSumsUrl: shasumsUrl,
|
|
||||||
ShaSumsSignatureUrl: shasumsSigUrl,
|
|
||||||
ShaSum: sum.Sum,
|
|
||||||
SigningKeys: SigningKey{},
|
|
||||||
}
|
|
||||||
|
|
||||||
a.SigningKeys = SigningKey{
|
|
||||||
GpgPublicKeys: []GpgPublicKey{
|
|
||||||
{
|
|
||||||
KeyId: p.GpgFingerprint,
|
|
||||||
AsciiArmor: gpgAsciiPub,
|
|
||||||
TrustSignature: "",
|
|
||||||
Source: "",
|
|
||||||
SourceUrl: "",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Printf(" - Arch file: %s", archFileName)
|
|
||||||
|
|
||||||
err = WriteArchitectureFile(archFileName, a)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func WriteArchitectureFile(filePath string, arch Architecture) error {
|
|
||||||
jsonString, err := json.Marshal(arch)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error encoding data: %w", err)
|
|
||||||
}
|
|
||||||
//nolint:gosec // this file is not sensitive, so we can use os.ModePerm
|
|
||||||
err = os.WriteFile(
|
|
||||||
filePath,
|
|
||||||
jsonString,
|
|
||||||
os.ModePerm,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error writing data: %w", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
package publish
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (p *Provider) ReadGpgFile() (string, error) {
|
|
||||||
gpgFile, err := ReadFile(p.GpgPubKeyFile)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("error reading '%s' file: %w", p.GpgPubKeyFile, err)
|
|
||||||
}
|
|
||||||
return strings.Join(gpgFile, "\n"), nil
|
|
||||||
}
|
|
||||||
|
|
@ -1,297 +0,0 @@
|
||||||
package publish
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"io/fs"
|
|
||||||
"log"
|
|
||||||
"log/slog"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"path"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Provider struct {
|
|
||||||
RootPath string
|
|
||||||
Namespace string
|
|
||||||
Provider string
|
|
||||||
DistPath string
|
|
||||||
RepoName string
|
|
||||||
Version string
|
|
||||||
GpgFingerprint string
|
|
||||||
GpgPubKeyFile string
|
|
||||||
Domain string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Provider) GetRoot() error {
|
|
||||||
cmd := exec.Command("git", "rev-parse", "--show-toplevel")
|
|
||||||
out, err := cmd.Output()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
lines := strings.Split(string(out), "\n")
|
|
||||||
p.RootPath = lines[0]
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Provider) CreateV1Dir() error {
|
|
||||||
// Path to semantic version dir
|
|
||||||
versionPath := p.providerDirs()
|
|
||||||
|
|
||||||
// Files to create under v1/providers/[namespace]/[provider_name]
|
|
||||||
err := p.createVersionsFile()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("[CreateV1Dir] - create versions file:%w", err)
|
|
||||||
} // Creates version file one above download, which is why downloadPath isn't used
|
|
||||||
|
|
||||||
// Files/Directories to create under v1/providers/[namespace]/[provider_name]/[version]
|
|
||||||
err = p.copyShaFiles(versionPath)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("[CreateV1Dir] - copy sha files: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Printf("* Creating download/ in %s directory", versionPath)
|
|
||||||
downloadsPath := path.Join(versionPath, "download")
|
|
||||||
err = CreateDir(downloadsPath)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create darwin, freebsd, linux, windows dirs
|
|
||||||
for _, v := range [4]string{"darwin", "freebsd", "linux", "windows"} {
|
|
||||||
err = CreateDir(path.Join(downloadsPath, v))
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error creating dir '%s': %w", path.Join(downloadsPath, v), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy all zips
|
|
||||||
err = p.copyBuildZips(downloadsPath)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create all individual files for build targets and each architecture for the build targets
|
|
||||||
err = p.CreateArchitectureFiles()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Provider) copyBuildZips(destPath string) error {
|
|
||||||
log.Println("* Copying build zips")
|
|
||||||
|
|
||||||
shaSums, err := p.GetShaSums()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Loop through and copy each
|
|
||||||
for _, sum := range shaSums {
|
|
||||||
zipSrcPath := path.Join(p.DistPath, sum.Path)
|
|
||||||
zipDestPath := path.Join(destPath, sum.Path)
|
|
||||||
|
|
||||||
log.Printf(" - Zip Source: %s", zipSrcPath)
|
|
||||||
log.Printf(" - Zip Dest: %s", zipDestPath)
|
|
||||||
|
|
||||||
// Copy the zip
|
|
||||||
_, err = CopyFile(zipSrcPath, zipDestPath)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error copying file '%s': %w", zipSrcPath, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Provider) copyShaFiles(destPath string) error {
|
|
||||||
log.Printf("* Copying SHA files in %s directory", p.DistPath)
|
|
||||||
|
|
||||||
// Copy files from srcPath
|
|
||||||
shaSum := p.RepoName + "_" + p.Version + "_SHA256SUMS"
|
|
||||||
shaSumPath := path.Join(p.DistPath, shaSum)
|
|
||||||
|
|
||||||
// _SHA256SUMS file
|
|
||||||
_, err := CopyFile(shaSumPath, path.Join(destPath, shaSum))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// _SHA256SUMS.sig file
|
|
||||||
_, err = CopyFile(shaSumPath+".sig", path.Join(destPath, shaSum+".sig"))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Provider) createVersionsFile() error {
|
|
||||||
log.Println("* Writing to release/v1/providers/[namespace]/[repo]/versions file")
|
|
||||||
|
|
||||||
versionPath := path.Join("release", "v1", "providers", p.Namespace, p.Provider, "versions")
|
|
||||||
|
|
||||||
shasums, err := p.GetShaSums()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error getting sha sums: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build the versions file...
|
|
||||||
version := Version{
|
|
||||||
Version: p.Version,
|
|
||||||
Protocols: []string{"5.1", "6.1"},
|
|
||||||
Platforms: nil,
|
|
||||||
}
|
|
||||||
for _, sum := range shasums {
|
|
||||||
// get os and arch from filename
|
|
||||||
removeFileExtension := strings.Split(sum.Path, ".zip")
|
|
||||||
if len(removeFileExtension) < 1 {
|
|
||||||
log.Fatalf("error: %s does not have .zip extension", sum.Path)
|
|
||||||
}
|
|
||||||
fileNameSplit := strings.Split(removeFileExtension[0], "_")
|
|
||||||
if len(fileNameSplit) < 4 {
|
|
||||||
log.Fatalf("filename does not match our regex: %s", removeFileExtension[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get build target and architecture from the zip file name
|
|
||||||
target := fileNameSplit[2]
|
|
||||||
arch := fileNameSplit[3]
|
|
||||||
|
|
||||||
version.Platforms = append(
|
|
||||||
version.Platforms, Platform{
|
|
||||||
OS: target,
|
|
||||||
Arch: arch,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
data := Data{}
|
|
||||||
|
|
||||||
downloadPath := path.Join(p.Domain, "v1", "providers", p.Namespace, p.Provider, "versions")
|
|
||||||
err = data.LoadFromUrl(fmt.Sprintf("https://%s", downloadPath))
|
|
||||||
if err != nil {
|
|
||||||
slog.Warn("error getting existing versions file, start with empty")
|
|
||||||
// TODO: create flag for first use or make it more robust
|
|
||||||
// return fmt.Errorf("error getting existing versions file: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = data.AddVersion(version)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error appending version: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = data.WriteToFile(versionPath)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error saving file '%s':%w", versionPath, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Provider) providerDirs() string {
|
|
||||||
log.Println("* Creating release/v1/providers/[namespace]/[provider]/[version] directories")
|
|
||||||
|
|
||||||
target := path.Join("release", "v1", "providers", p.Namespace, p.Provider, p.Version)
|
|
||||||
|
|
||||||
err := CreateDir(target)
|
|
||||||
if err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return target
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Provider) CreateWellKnown() error {
|
|
||||||
log.Println("* Creating .well-known directory")
|
|
||||||
pathString := path.Join(p.RootPath, "release", ".well-known")
|
|
||||||
|
|
||||||
//nolint:gosec // this file is not sensitive, so we can use ModePerm
|
|
||||||
err := os.MkdirAll(pathString, os.ModePerm)
|
|
||||||
if err != nil && !errors.Is(err, fs.ErrExist) {
|
|
||||||
return fmt.Errorf("error creating '%s' dir: %w", pathString, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Println(" - Writing to .well-known/terraform.json file")
|
|
||||||
|
|
||||||
//nolint:gosec // this file is not sensitive, so we can use 0644
|
|
||||||
err = os.WriteFile(
|
|
||||||
fmt.Sprintf("%s/terraform.json", pathString),
|
|
||||||
[]byte(`{"providers.v1": "/v1/providers/"}`),
|
|
||||||
0o644,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateDir(pathValue string) error {
|
|
||||||
log.Printf("* Creating %s directory", pathValue)
|
|
||||||
//nolint:gosec // this file is not sensitive, so we can use ModePerm
|
|
||||||
err := os.MkdirAll(pathValue, os.ModePerm)
|
|
||||||
if errors.Is(err, fs.ErrExist) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func ReadFile(filePath string) ([]string, error) {
|
|
||||||
rFile, err := os.Open(filePath)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
fileScanner := bufio.NewScanner(rFile)
|
|
||||||
fileScanner.Split(bufio.ScanLines)
|
|
||||||
var fileLines []string
|
|
||||||
|
|
||||||
for fileScanner.Scan() {
|
|
||||||
fileLines = append(fileLines, fileScanner.Text())
|
|
||||||
}
|
|
||||||
|
|
||||||
err = rFile.Close()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return fileLines, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func CopyFile(src, dst string) (int64, error) {
|
|
||||||
sourceFileStat, err := os.Stat(src)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !sourceFileStat.Mode().IsRegular() {
|
|
||||||
return 0, fmt.Errorf("%s is not a regular file", src)
|
|
||||||
}
|
|
||||||
|
|
||||||
source, err := os.Open(src)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
defer func(source *os.File) {
|
|
||||||
err := source.Close()
|
|
||||||
if err != nil {
|
|
||||||
slog.Error("error closing source file", slog.Any("err", err))
|
|
||||||
}
|
|
||||||
}(source)
|
|
||||||
|
|
||||||
destination, err := os.Create(dst)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
defer func(destination *os.File) {
|
|
||||||
err := destination.Close()
|
|
||||||
if err != nil {
|
|
||||||
slog.Error("error closing destination file", slog.Any("err", err))
|
|
||||||
}
|
|
||||||
}(destination)
|
|
||||||
nBytes, err := io.Copy(destination, source)
|
|
||||||
return nBytes, err
|
|
||||||
}
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
package publish
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log/slog"
|
|
||||||
"path"
|
|
||||||
"regexp"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (p *Provider) GetShaSums() (ShaSums, error) {
|
|
||||||
return GetShaSumContents(p.DistPath, p.RepoName, p.Version)
|
|
||||||
}
|
|
||||||
|
|
||||||
type ShaSums []ShaSum
|
|
||||||
type ShaSum struct {
|
|
||||||
Sum string
|
|
||||||
Path string
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetShaSumContents(distPath, repoName, version string) (ShaSums, error) {
|
|
||||||
shaSumFileName := repoName + "_" + version + "_SHA256SUMS"
|
|
||||||
shaSumPath := path.Join(distPath, shaSumFileName)
|
|
||||||
|
|
||||||
shaSumLine, err := ReadFile(shaSumPath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
regEx := regexp.MustCompile(`([0-9a-fA-F]+)\s+(.+)`)
|
|
||||||
shaSums := ShaSums{}
|
|
||||||
for _, line := range shaSumLine {
|
|
||||||
matches := regEx.FindAllStringSubmatch(line, -1)
|
|
||||||
if len(matches) < 1 {
|
|
||||||
slog.Warn("unable to parse SHA sum line", "line", line)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
shaSums = append(shaSums, ShaSum{Sum: matches[0][1], Path: matches[0][2]})
|
|
||||||
}
|
|
||||||
return shaSums, nil
|
|
||||||
}
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
{
|
|
||||||
log {
|
|
||||||
level debug
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
filesystem tf s3 {
|
|
||||||
bucket "terraform-provider-privatepreview"
|
|
||||||
region eu01
|
|
||||||
endpoint https://object.storage.eu01.onstackit.cloud
|
|
||||||
use_path_style
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tfregistry.sysops.stackit.rocks {
|
|
||||||
encode zstd gzip
|
|
||||||
|
|
||||||
handle_path /docs/* {
|
|
||||||
root /srv/www
|
|
||||||
templates
|
|
||||||
|
|
||||||
@md {
|
|
||||||
file {path}
|
|
||||||
path *.md
|
|
||||||
}
|
|
||||||
|
|
||||||
rewrite @md /markdown.html
|
|
||||||
|
|
||||||
file_server {
|
|
||||||
browse
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
file_server {
|
|
||||||
fs tf
|
|
||||||
browse
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="de">
|
|
||||||
<head>
|
|
||||||
<title>Forwarding | Weiterleitung</title>
|
|
||||||
<meta http-equiv="refresh" content="0; URL=index.md">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<a href="index.md">Falls Sie nicht automatisch weitergeleitet werden, klicken Sie bitte hier.</a><br />
|
|
||||||
Sie gelangen dann auf unsere Hauptseite
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
---
|
|
||||||
page_title: STACKIT provider PrivatePreview
|
|
||||||
description: none
|
|
||||||
---
|
|
||||||
|
|
||||||
# provider
|
|
||||||
[Provider](docs/index.md)
|
|
||||||
|
|
||||||
## PostGreSQL alpha
|
|
||||||
### data sources
|
|
||||||
|
|
||||||
- [Flavor](docs/data-sources/postgresflexalpha_flavor.md)
|
|
||||||
- [Database](docs/data-sources/postgresflexalpha_database.md)
|
|
||||||
- [Instance](docs/data-sources/postgresflexalpha_instance.md)
|
|
||||||
- [Flavors](docs/data-sources/postgresflexalpha_flavors.md)
|
|
||||||
- [User](docs/data-sources/postgresflexalpha_user.md)
|
|
||||||
|
|
||||||
### resources
|
|
||||||
- [Database](docs/resources/postgresflexalpha_database.md)
|
|
||||||
- [Instance](docs/resources/postgresflexalpha_instance.md)
|
|
||||||
- [User](docs/resources/postgresflexalpha_user.md)
|
|
||||||
|
|
||||||
## SQL Server alpha
|
|
||||||
### data sources
|
|
||||||
- [Database](docs/data-sources/sqlserverflexalpha_database.md)
|
|
||||||
- [Version](docs/data-sources/sqlserverflexalpha_version.md)
|
|
||||||
- [User](docs/data-sources/sqlserverflexalpha_user.md)
|
|
||||||
- [Flavor](docs/data-sources/sqlserverflexalpha_flavor.md)
|
|
||||||
- [Instance](docs/data-sources/sqlserverflexalpha_instance.md)
|
|
||||||
|
|
||||||
### resources
|
|
||||||
- [Database](docs/resources/sqlserverflexalpha_database.md)
|
|
||||||
- [User](docs/resources/sqlserverflexalpha_user.md)
|
|
||||||
- [Instance](docs/resources/sqlserverflexalpha_instance.md)
|
|
||||||
|
|
@ -1,79 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
{{ $mdFile := .OriginalReq.URL.Path | trimPrefix "/docs" }}
|
|
||||||
{{ $md := (include $mdFile | splitFrontMatter) }}
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<title>{{$md.Meta.page_title}}</title>
|
|
||||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
|
|
||||||
<link rel="stylesheet" href="/docs/terraform-registry.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>{{$md.Meta.page_title}}</h1>
|
|
||||||
<div class="provider-view">
|
|
||||||
<div class="provider-nav">
|
|
||||||
<nav class="bread-crumbs is-light" aria-label="Provider">
|
|
||||||
<div class="container is-widescreen">
|
|
||||||
<div class="level">
|
|
||||||
<ul class="provider-nav-breadcrumbs bread-crumbs-list">
|
|
||||||
<li class="bread-crumbs-item">
|
|
||||||
<a id="ember20" class="ember-view bread-crumbs-link" href="/">
|
|
||||||
Main
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
<nav class="block-border section-navbar section-header" aria-label="Provider details">
|
|
||||||
<div class="container">
|
|
||||||
<div class="columns is-vcentered">
|
|
||||||
<div class="column is-4">
|
|
||||||
<div class="provider-nav-info-header">
|
|
||||||
<div class="provider-overview-logo">
|
|
||||||
<span class="provider-logo">
|
|
||||||
<img class="github-image" src="https://avatars3.githubusercontent.com/stackitcloud" alt="stackitcloud">
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="provider-nav-info-origin">
|
|
||||||
<h1>PRIVATE PREVIEW</h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="column is-8">
|
|
||||||
|
|
||||||
<ul class="nav-tabs-list nav-tabs tabs">
|
|
||||||
|
|
||||||
<li class="nav-tabs-item">
|
|
||||||
<a id="ember30" class="ember-view navbar-item" href="/">
|
|
||||||
Overview
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<div class="provider-nav-provision-wrapper">
|
|
||||||
<!----> </div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="section block-border block-white section-content">
|
|
||||||
<div class="container">
|
|
||||||
<div class="columns columns-provider-docs">
|
|
||||||
<div class="column is-3 column-provider-docs-menu"></div>
|
|
||||||
<article id="provider-docs-content" class="column is-6 provider-docs-content">
|
|
||||||
<div class="markdown">
|
|
||||||
<div class="highlighted-code-wrapper">
|
|
||||||
{{markdown $md.Body}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</article>
|
|
||||||
<div class="column is-3 column-provider-docs-menu"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,169 +0,0 @@
|
||||||
package publish
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"log/slog"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Version struct {
|
|
||||||
Version string `json:"version"`
|
|
||||||
Protocols []string `json:"protocols"`
|
|
||||||
Platforms []Platform `json:"platforms"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Platform struct {
|
|
||||||
OS string `json:"os" yaml:"os"`
|
|
||||||
Arch string `json:"arch" yaml:"arch"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Data struct {
|
|
||||||
Id string `json:"id,omitempty"`
|
|
||||||
Versions []Version `json:"versions"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Data) WriteToFile(filePath string) error {
|
|
||||||
// TODO: make it variable
|
|
||||||
d.Id = "tfregistry.sysops.stackit.rocks/mhenselin/stackitprivatepreview"
|
|
||||||
|
|
||||||
jsonString, err := json.Marshal(d)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error encoding data: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
//nolint:gosec // this file is not sensitive, so we can use os.ModePerm
|
|
||||||
err = os.WriteFile(
|
|
||||||
filePath,
|
|
||||||
jsonString,
|
|
||||||
os.ModePerm,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error writing data: %w", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Data) AddVersion(v Version) error {
|
|
||||||
var newVersions []Version
|
|
||||||
for _, ver := range d.Versions {
|
|
||||||
if ver.Version != v.Version {
|
|
||||||
newVersions = append(newVersions, ver)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
newVersions = append(newVersions, v)
|
|
||||||
d.Versions = newVersions
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Data) Validate() error {
|
|
||||||
for _, v := range d.Versions {
|
|
||||||
err := v.Validate()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Data) LoadFromFile(filePath string) error {
|
|
||||||
plan, err := os.ReadFile(filePath)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = json.Unmarshal(plan, &d)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Data) LoadFromUrl(uri string) error {
|
|
||||||
u, err := url.ParseRequestURI(uri)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
file, err := os.CreateTemp("", "versions.*.json")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer func(name string) {
|
|
||||||
//nolint:gosec // The file path is generated by os.CreateTemp and is not user-controllable
|
|
||||||
err := os.Remove(name)
|
|
||||||
if err != nil {
|
|
||||||
slog.Error("failed to remove temporary file", slog.Any("err", err))
|
|
||||||
}
|
|
||||||
}(file.Name()) // Clean up
|
|
||||||
|
|
||||||
err = DownloadFile(
|
|
||||||
u.String(),
|
|
||||||
file.Name(),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return d.LoadFromFile(file.Name())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Version) Validate() error {
|
|
||||||
slog.Warn("validation needs to be implemented")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Version) AddPlatform(p Platform) error {
|
|
||||||
if p.OS == "" || p.Arch == "" {
|
|
||||||
return fmt.Errorf("OS and Arch MUST NOT be empty")
|
|
||||||
}
|
|
||||||
v.Platforms = append(v.Platforms, p)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Version) AddProtocol(p string) error {
|
|
||||||
if p == "" {
|
|
||||||
return fmt.Errorf("protocol MUST NOT be empty")
|
|
||||||
}
|
|
||||||
v.Protocols = append(v.Protocols, p)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DownloadFile will download a url and store it in local filepath.
|
|
||||||
// It writes to the destination file as it downloads it, without
|
|
||||||
// loading the entire file into memory.
|
|
||||||
func DownloadFile(urlValue, filepath string) error {
|
|
||||||
// Create the file
|
|
||||||
//nolint:gosec // path traversal is not a concern here, as the filepath is generated by us and not user input
|
|
||||||
out, err := os.Create(filepath)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer func(out *os.File) {
|
|
||||||
err := out.Close()
|
|
||||||
if err != nil {
|
|
||||||
slog.Error("failed to close file", slog.Any("err", err))
|
|
||||||
}
|
|
||||||
}(out)
|
|
||||||
|
|
||||||
// Get the data
|
|
||||||
|
|
||||||
//nolint:gosec,bodyclose // this is a controlled URL, not user input
|
|
||||||
resp, err := http.Get(urlValue)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer func(Body io.ReadCloser) {
|
|
||||||
_ = Body.Close()
|
|
||||||
}(resp.Body)
|
|
||||||
|
|
||||||
// Write the body to file
|
|
||||||
_, err = io.Copy(out, resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
@ -1,139 +0,0 @@
|
||||||
package cmd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io/fs"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
|
|
||||||
publish2 "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/generator/cmd/publish"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
namespace string
|
|
||||||
domain string
|
|
||||||
providerName string
|
|
||||||
distPath string
|
|
||||||
repoName string
|
|
||||||
version string
|
|
||||||
gpgFingerprint string
|
|
||||||
gpgPubKeyFile string
|
|
||||||
)
|
|
||||||
|
|
||||||
var publishCmd = &cobra.Command{
|
|
||||||
Use: "publish",
|
|
||||||
Short: "Publish terraform provider",
|
|
||||||
Long: `...`,
|
|
||||||
RunE: func(_ *cobra.Command, _ []string) error {
|
|
||||||
return publish()
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() { //nolint:gochecknoinits //this is the standard way to set up cobra commands
|
|
||||||
publishCmd.Flags().StringVarP(&namespace, "namespace", "n", "", "Namespace for the Terraform registry.")
|
|
||||||
publishCmd.Flags().StringVarP(&domain, "domain", "d", "", "Domain for the Terraform registry.")
|
|
||||||
publishCmd.Flags().StringVarP(&providerName, "providerName", "p", "", "ProviderName for the Terraform registry.")
|
|
||||||
publishCmd.Flags().StringVarP(&distPath, "distPath", "x", "dist", "Dist Path for the Terraform registry.")
|
|
||||||
publishCmd.Flags().StringVarP(&repoName, "repoName", "r", "", "RepoName for the Terraform registry.")
|
|
||||||
publishCmd.Flags().StringVarP(&version, "version", "v", "", "Version for the Terraform registry.")
|
|
||||||
publishCmd.Flags().StringVarP(
|
|
||||||
&gpgFingerprint,
|
|
||||||
"gpgFingerprint",
|
|
||||||
"f",
|
|
||||||
"",
|
|
||||||
"GPG Fingerprint for the Terraform registry.",
|
|
||||||
)
|
|
||||||
publishCmd.Flags().StringVarP(
|
|
||||||
&gpgPubKeyFile,
|
|
||||||
"gpgPubKeyFile",
|
|
||||||
"k",
|
|
||||||
"",
|
|
||||||
"GPG PubKey file name for the Terraform registry.",
|
|
||||||
)
|
|
||||||
|
|
||||||
err := publishCmd.MarkFlagRequired("namespace")
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = publishCmd.MarkFlagRequired("domain")
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = publishCmd.MarkFlagRequired("providerName")
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = publishCmd.MarkFlagRequired("gpgFingerprint")
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = publishCmd.MarkFlagRequired("gpgPubKeyFile")
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = publishCmd.MarkFlagRequired("repoName")
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = publishCmd.MarkFlagRequired("version")
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = publishCmd.MarkFlagRequired("gpgFingerprint")
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = publishCmd.MarkFlagRequired("gpgPubKeyFile")
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewPublishCmd() *cobra.Command {
|
|
||||||
return publishCmd
|
|
||||||
}
|
|
||||||
|
|
||||||
func publish() error {
|
|
||||||
log.Println("📦 Packaging Terraform Provider for private registry...")
|
|
||||||
p := publish2.Provider{
|
|
||||||
Namespace: namespace,
|
|
||||||
Provider: providerName,
|
|
||||||
DistPath: filepath.Clean(distPath) + "/",
|
|
||||||
RepoName: repoName,
|
|
||||||
Version: version,
|
|
||||||
GpgFingerprint: gpgFingerprint,
|
|
||||||
GpgPubKeyFile: gpgPubKeyFile,
|
|
||||||
Domain: domain,
|
|
||||||
}
|
|
||||||
err := p.GetRoot()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create release dir - only the contents of this need to be uploaded to S3
|
|
||||||
log.Printf("* Creating release directory")
|
|
||||||
//nolint:gosec // this directory is not sensitive, so we can use 0750
|
|
||||||
err = os.MkdirAll(path.Join(p.RootPath, "release"), os.ModePerm)
|
|
||||||
if err != nil && !errors.Is(err, fs.ErrExist) {
|
|
||||||
return fmt.Errorf("error creating '%s' dir: %w", path.Join(p.RootPath, "release"), err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create .wellKnown directory and terraform.json file
|
|
||||||
err = p.CreateWellKnown()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error creating '.well-known' dir: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = p.CreateV1Dir()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error creating 'v1' dir: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Println("📦 Packaged Terraform Provider for private registry.")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
package cmd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewRootCmd() *cobra.Command {
|
|
||||||
return &cobra.Command{
|
|
||||||
Use: "generator",
|
|
||||||
Short: "...",
|
|
||||||
Long: "...",
|
|
||||||
SilenceErrors: true, // Error is beautified in a custom way before being printed
|
|
||||||
SilenceUsage: true,
|
|
||||||
DisableAutoGenTag: true,
|
|
||||||
RunE: func(cmd *cobra.Command, _ []string) error {
|
|
||||||
err := cmd.Help()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"log/slog"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/SladkyCitron/slogcolor"
|
|
||||||
cc "github.com/ivanpirog/coloredcobra"
|
|
||||||
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/generator/cmd"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
slog.SetDefault(slog.New(slogcolor.NewHandler(os.Stderr, slogcolor.DefaultOptions)))
|
|
||||||
|
|
||||||
rootCmd := cmd.NewRootCmd()
|
|
||||||
|
|
||||||
cc.Init(&cc.Config{
|
|
||||||
RootCmd: rootCmd,
|
|
||||||
Headings: cc.HiCyan + cc.Bold + cc.Underline,
|
|
||||||
Commands: cc.HiYellow + cc.Bold,
|
|
||||||
Example: cc.Italic,
|
|
||||||
ExecName: cc.Bold,
|
|
||||||
Flags: cc.Bold,
|
|
||||||
})
|
|
||||||
rootCmd.SetOut(os.Stdout)
|
|
||||||
|
|
||||||
rootCmd.AddCommand(
|
|
||||||
cmd.NewBuildCmd(),
|
|
||||||
cmd.NewPublishCmd(),
|
|
||||||
cmd.NewGetFieldsCmd(),
|
|
||||||
cmd.NewExamplesCmd(),
|
|
||||||
cmd.NewDocsCmd(),
|
|
||||||
)
|
|
||||||
|
|
||||||
err := rootCmd.Execute()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
100
go.mod
100
go.mod
|
|
@ -1,103 +1,75 @@
|
||||||
module tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview
|
module github.com/mhenselin/terraform-provider-stackitprivatepreview
|
||||||
|
|
||||||
go 1.26.2
|
go 1.25.5
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/SladkyCitron/slogcolor v1.9.0
|
|
||||||
github.com/google/go-cmp v0.7.0
|
github.com/google/go-cmp v0.7.0
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
github.com/hashicorp/terraform-plugin-framework v1.19.0
|
github.com/hashicorp/terraform-plugin-framework v1.17.0
|
||||||
github.com/hashicorp/terraform-plugin-framework-validators v0.19.0
|
github.com/hashicorp/terraform-plugin-framework-validators v0.19.0
|
||||||
github.com/hashicorp/terraform-plugin-go v0.31.0
|
github.com/hashicorp/terraform-plugin-go v0.29.0
|
||||||
github.com/hashicorp/terraform-plugin-log v0.10.0
|
github.com/hashicorp/terraform-plugin-log v0.10.0
|
||||||
github.com/hashicorp/terraform-plugin-testing v1.16.0
|
github.com/hashicorp/terraform-plugin-testing v1.14.0
|
||||||
github.com/iancoleman/strcase v0.3.0
|
github.com/stackitcloud/stackit-sdk-go/core v0.20.1
|
||||||
github.com/ivanpirog/coloredcobra v1.0.1
|
github.com/stackitcloud/stackit-sdk-go/services/sqlserverflex v1.4.0
|
||||||
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.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
|
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
|
require (
|
||||||
|
github.com/hashicorp/go-retryablehttp v0.7.8 // indirect
|
||||||
|
github.com/kr/text v0.2.0 // indirect
|
||||||
|
golang.org/x/telemetry v0.0.0-20260109210033-bd525da824e2 // indirect
|
||||||
|
)
|
||||||
|
|
||||||
require (
|
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/agext/levenshtein v1.2.3 // indirect
|
||||||
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
|
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
|
||||||
github.com/armon/go-radix v1.0.0 // indirect
|
github.com/cloudflare/circl v1.6.2 // indirect
|
||||||
github.com/bgentry/speakeasy v0.1.0 // indirect
|
github.com/fatih/color v1.18.0 // indirect
|
||||||
github.com/bmatcuk/doublestar/v4 v4.10.0 // indirect
|
github.com/golang-jwt/jwt/v5 v5.3.0 // indirect
|
||||||
github.com/cloudflare/circl v1.6.3 // 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/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/errwrap v1.1.0 // indirect
|
||||||
github.com/hashicorp/go-checkpoint v0.5.0 // indirect
|
github.com/hashicorp/go-checkpoint v0.5.0 // indirect
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||||
github.com/hashicorp/go-cty v1.5.0 // indirect
|
github.com/hashicorp/go-cty v1.5.0 // indirect
|
||||||
github.com/hashicorp/go-hclog v1.6.3 // indirect
|
github.com/hashicorp/go-hclog v1.6.3 // indirect
|
||||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||||
github.com/hashicorp/go-plugin v1.8.0 // indirect
|
github.com/hashicorp/go-plugin v1.7.0 // indirect
|
||||||
github.com/hashicorp/go-uuid v1.0.3 // indirect
|
github.com/hashicorp/go-uuid v1.0.3 // indirect
|
||||||
github.com/hashicorp/go-version v1.9.0 // indirect
|
github.com/hashicorp/go-version v1.8.0 // indirect
|
||||||
github.com/hashicorp/hc-install v0.9.5 // indirect
|
github.com/hashicorp/hc-install v0.9.2 // indirect
|
||||||
github.com/hashicorp/hcl/v2 v2.24.0 // indirect
|
github.com/hashicorp/hcl/v2 v2.24.0 // indirect
|
||||||
github.com/hashicorp/logutils v1.0.0 // indirect
|
github.com/hashicorp/logutils v1.0.0 // indirect
|
||||||
github.com/hashicorp/terraform-exec v0.25.2 // indirect
|
github.com/hashicorp/terraform-exec v0.24.0 // indirect
|
||||||
github.com/hashicorp/terraform-json v0.27.3-0.20260213134036-298b8f6b673a // indirect
|
github.com/hashicorp/terraform-json v0.27.2 // indirect
|
||||||
github.com/hashicorp/terraform-plugin-docs v0.25.0 // indirect
|
github.com/hashicorp/terraform-plugin-sdk/v2 v2.38.1 // 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-registry-address v0.4.0 // indirect
|
||||||
github.com/hashicorp/terraform-svchost v0.2.1 // indirect
|
github.com/hashicorp/terraform-svchost v0.1.1 // indirect
|
||||||
github.com/hashicorp/yamux v0.1.2 // 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/mattn/go-colorable v0.1.14 // indirect
|
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.22 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
github.com/mattn/go-runewidth v0.0.9 // indirect
|
|
||||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||||
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
|
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
|
||||||
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
||||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||||
github.com/oklog/run v1.2.0 // indirect
|
github.com/oklog/run v1.2.0 // 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 v4.0.4+incompatible // indirect
|
||||||
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
|
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
|
||||||
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
||||||
github.com/yuin/goldmark v1.7.7 // indirect
|
github.com/zclconf/go-cty v1.17.0 // indirect
|
||||||
github.com/yuin/goldmark-meta v1.1.0 // indirect
|
golang.org/x/crypto v0.46.0 // indirect
|
||||||
github.com/zclconf/go-cty v1.18.1 // indirect
|
golang.org/x/mod v0.32.0 // indirect
|
||||||
go.abhg.dev/goldmark/frontmatter v0.2.0 // indirect
|
golang.org/x/net v0.48.0 // indirect
|
||||||
golang.org/x/crypto v0.50.0 // indirect
|
golang.org/x/sync v0.19.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect
|
golang.org/x/sys v0.40.0 // indirect
|
||||||
golang.org/x/mod v0.35.0 // indirect
|
golang.org/x/text v0.33.0 // indirect
|
||||||
golang.org/x/net v0.53.0 // indirect
|
golang.org/x/tools v0.40.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/appengine v1.6.8 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260504160031-60b97b32f348 // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect
|
||||||
google.golang.org/grpc v1.81.0 // indirect
|
google.golang.org/grpc v1.78.0 // indirect
|
||||||
google.golang.org/protobuf v1.36.11 // indirect
|
google.golang.org/protobuf v1.36.11 // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
tool golang.org/x/tools/cmd/goimports
|
||||||
|
|
|
||||||
248
go.sum
248
go.sum
|
|
@ -1,40 +1,19 @@
|
||||||
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
|
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
|
||||||
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
dario.cat/mergo v1.0.0/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 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||||
github.com/ProtonMail/go-crypto v1.4.1 h1:9RfcZHqEQUvP8RzecWEUafnZVtEvrBVL9BiF67IQOfM=
|
github.com/ProtonMail/go-crypto v1.3.0 h1:ILq8+Sf5If5DCpHQp4PbZdS1J7HDFRXz/+xKBiRGFrw=
|
||||||
github.com/ProtonMail/go-crypto v1.4.1/go.mod h1:e1OaTyu5SYVrO9gKOEhTc+5UcXtTUa+P3uLudwcgPqo=
|
github.com/ProtonMail/go-crypto v1.3.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE=
|
||||||
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 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
|
||||||
github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
|
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/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 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY=
|
||||||
github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
|
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 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw=
|
||||||
github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c=
|
github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
github.com/cloudflare/circl v1.6.2 h1:hL7VBpHHKzrV5WTfHCaBsgx/HGbBYlgrwvNXEVDYYsQ=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cloudflare/circl v1.6.2/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4=
|
||||||
github.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
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/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s=
|
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/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=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
|
@ -44,22 +23,22 @@ 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 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
|
||||||
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
|
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.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||||
github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w=
|
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
||||||
github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE=
|
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
|
||||||
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 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
|
||||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
|
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
|
||||||
github.com/go-git/go-billy/v5 v5.8.0 h1:I8hjc3LbBlXTtVuFNJuwYuMiHvQJDq1AT6u4DwDzZG0=
|
github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UNbRM=
|
||||||
github.com/go-git/go-billy/v5 v5.8.0/go.mod h1:RpvI/rw4Vr5QA+Z60c6d6LXH0rYJo0uD5SqfmrrheCY=
|
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.18.0 h1:O831KI+0PR51hM2kep6T8k+w0/LIAD490gvqMCvL5hM=
|
github.com/go-git/go-git/v5 v5.14.0 h1:/MD3lCrGjCen5WfEAzKg00MJJffKhC8gzS80ycmCi60=
|
||||||
github.com/go-git/go-git/v5 v5.18.0/go.mod h1:pW/VmeqkanRFqR6AljLcs7EA7FbZaN5MQqO7oZADXpo=
|
github.com/go-git/go-git/v5 v5.14.0/go.mod h1:Z5Xhoia5PcWA3NF8vRLURn9E5FRhSl7dGj9ItW3Wk5k=
|
||||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
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/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||||
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
|
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
|
||||||
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||||
github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY=
|
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
|
||||||
github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
|
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
|
||||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=
|
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=
|
||||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=
|
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=
|
||||||
github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
|
@ -71,11 +50,8 @@ 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.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 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
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 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
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.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 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
|
|
@ -88,93 +64,66 @@ 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-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 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
|
||||||
github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
|
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 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||||
github.com/hashicorp/go-plugin v1.8.0 h1:ie8S6RRY8RvB2usYZv+AAZ/wBvx2AU5p5QeP5j/FORs=
|
github.com/hashicorp/go-plugin v1.7.0 h1:YghfQH/0QmPNc/AZMTFE3ac8fipZyZECHdDPshfk+mA=
|
||||||
github.com/hashicorp/go-plugin v1.8.0/go.mod h1:BExt6KEaIYx804z8k4gRzRLEvxKVb+kn0NMcihqOqb8=
|
github.com/hashicorp/go-plugin v1.7.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 h1:ylXZWnqa7Lhqpk0L1P1LzDtGcCR0rPVUrx/c8Unxc48=
|
||||||
github.com/hashicorp/go-retryablehttp v0.7.8/go.mod h1:rjiScheydd+CxvumBsIrFKlx3iS0jrZ7LvzFGFmuKbw=
|
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.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 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
|
||||||
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||||
github.com/hashicorp/go-version v1.9.0 h1:CeOIz6k+LoN3qX9Z0tyQrPtiB1DFYRPfCIBtaXPSCnA=
|
github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4=
|
||||||
github.com/hashicorp/go-version v1.9.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||||
github.com/hashicorp/hc-install v0.9.5 h1:XHCjcMn2563ysuaQ9v9ec2FNc7c2PJOIEEGobAFeIx4=
|
github.com/hashicorp/hc-install v0.9.2 h1:v80EtNX4fCVHqzL9Lg/2xkp62bbvQMnvPQ0G+OmtO24=
|
||||||
github.com/hashicorp/hc-install v0.9.5/go.mod h1:ihEW4LshrNkxq2bU/MpVbKyn+yt1is2hYqUTHDGhG84=
|
github.com/hashicorp/hc-install v0.9.2/go.mod h1:XUqBQNnuT4RsxoxiM9ZaUk0NX8hi2h+Lb6/c0OZnC/I=
|
||||||
github.com/hashicorp/hcl/v2 v2.24.0 h1:2QJdZ454DSsYGoaE6QheQZjtKZSUs9Nh2izTWiwQxvE=
|
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/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 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y=
|
||||||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
||||||
github.com/hashicorp/terraform-exec v0.25.2 h1:fFLAVEtAjKdGfawGUXDnKooCnqJi+TuohT3W99AGbhk=
|
github.com/hashicorp/terraform-exec v0.24.0 h1:mL0xlk9H5g2bn0pPF6JQZk5YlByqSqrO5VoaNtAf8OE=
|
||||||
github.com/hashicorp/terraform-exec v0.25.2/go.mod h1:uaQV2oqVLqM4cixJryk6qIWS1qji3GtuwPG5pjGXYfc=
|
github.com/hashicorp/terraform-exec v0.24.0/go.mod h1:lluc/rDYfAhYdslLJQg3J0oDqo88oGQAdHR+wDqFvo4=
|
||||||
github.com/hashicorp/terraform-json v0.27.2 h1:BwGuzM6iUPqf9JYM/Z4AF1OJ5VVJEEzoKST/tRDBJKU=
|
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-json v0.27.2/go.mod h1:GzPLJ1PLdUG5xL6xn1OXWIjteQRT2CNT9o/6A9mi9hE=
|
||||||
github.com/hashicorp/terraform-json v0.27.3-0.20260213134036-298b8f6b673a h1:T7AMR21kjrbeEpN+KhGlyd31XXHsSZF5zg+ivfeYte4=
|
github.com/hashicorp/terraform-plugin-framework v1.17.0 h1:JdX50CFrYcYFY31gkmitAEAzLKoBgsK+iaJjDC8OexY=
|
||||||
github.com/hashicorp/terraform-json v0.27.3-0.20260213134036-298b8f6b673a/go.mod h1:yjb5C2W07l8lmAzdyVgOLji0/D2IoHkR3rusBzUO4O0=
|
github.com/hashicorp/terraform-plugin-framework v1.17.0/go.mod h1:4OUXKdHNosX+ys6rLgVlgklfxN3WHR5VHSOABeS/BM0=
|
||||||
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 h1:Zz3iGgzxe/1XBkooZCewS0nJAaCFPFPHdNJd8FgE4Ow=
|
||||||
github.com/hashicorp/terraform-plugin-framework-validators v0.19.0/go.mod h1:GBKTNGbGVJohU03dZ7U8wHqc2zYnMUawgCN+gC0itLc=
|
github.com/hashicorp/terraform-plugin-framework-validators v0.19.0/go.mod h1:GBKTNGbGVJohU03dZ7U8wHqc2zYnMUawgCN+gC0itLc=
|
||||||
github.com/hashicorp/terraform-plugin-go v0.31.0 h1:0Fz2r9DQ+kNNl6bx8HRxFd1TfMKUvnrOtvJPmp3Z0q8=
|
github.com/hashicorp/terraform-plugin-go v0.29.0 h1:1nXKl/nSpaYIUBU1IG/EsDOX0vv+9JxAltQyDMpq5mU=
|
||||||
github.com/hashicorp/terraform-plugin-go v0.31.0/go.mod h1:A88bDhd/cW7FnwqxQRz3slT+QY6yzbHKc6AOTtmdeS8=
|
github.com/hashicorp/terraform-plugin-go v0.29.0/go.mod h1:vYZbIyvxyy0FWSmDHChCqKvI40cFTDGSb3D8D70i9GM=
|
||||||
github.com/hashicorp/terraform-plugin-log v0.10.0 h1:eu2kW6/QBVdN4P3Ju2WiB2W3ObjkAsyfBsL3Wh1fj3g=
|
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-log v0.10.0/go.mod h1:/9RR5Cv2aAbrqcTSdNmY1NRHP4E3ekrXRGjqORpXyB0=
|
||||||
github.com/hashicorp/terraform-plugin-sdk/v2 v2.40.1 h1:2yPUd7esMOpuTaG3y1iEla1iw+tla+3ZEkkBnmOAre4=
|
github.com/hashicorp/terraform-plugin-sdk/v2 v2.38.1 h1:mlAq/OrMlg04IuJT7NpefI1wwtdpWudnEmjuQs04t/4=
|
||||||
github.com/hashicorp/terraform-plugin-sdk/v2 v2.40.1/go.mod h1:sq8qsxh+PwdvTQFcd17kfCoBgQo46ADNMvCpKE7t/gY=
|
github.com/hashicorp/terraform-plugin-sdk/v2 v2.38.1/go.mod h1:GQhpKVvvuwzD79e8/NZ+xzj+ZpWovdPAe8nfV/skwNU=
|
||||||
github.com/hashicorp/terraform-plugin-testing v1.16.0 h1:GB97nGnJ1hESpDrCjqZig38RodSF0gdRzxlDupLXP38=
|
github.com/hashicorp/terraform-plugin-testing v1.14.0 h1:5t4VKrjOJ0rg0sVuSJ86dz5K7PHsMO6OKrHFzDBerWA=
|
||||||
github.com/hashicorp/terraform-plugin-testing v1.16.0/go.mod h1:eQPYAy9xFMV7xtIFX8Y+wJGtUB++HBl329zCF6PBMZk=
|
github.com/hashicorp/terraform-plugin-testing v1.14.0/go.mod h1:1qfWkecyYe1Do2EEOK/5/WnTyvC8wQucUkkhiGLg5nk=
|
||||||
github.com/hashicorp/terraform-registry-address v0.4.0 h1:S1yCGomj30Sao4l5BMPjTGZmCNzuv7/GDTDX99E9gTk=
|
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-registry-address v0.4.0/go.mod h1:LRS1Ay0+mAiRkUyltGT+UHWkIqTFvigGn/LbMshfflE=
|
||||||
github.com/hashicorp/terraform-svchost v0.2.1 h1:ubvrTFw3Q7CsoEaX7V06PtCTKG3wu7GyyobAoN4eF3Q=
|
github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ=
|
||||||
github.com/hashicorp/terraform-svchost v0.2.1/go.mod h1:zDMheBLvNzu7Q6o9TBvPqiZToJcSuCLXjAXxBslSky4=
|
github.com/hashicorp/terraform-svchost v0.1.1/go.mod h1:mNsjQfZyf/Jhz35v6/0LWcv26+X7JPS+buii2c9/ctc=
|
||||||
github.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8=
|
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/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=
|
|
||||||
github.com/ivanpirog/coloredcobra v1.0.1 h1:aURSdEmlR90/tSiWS0dMjdwOvCVUeYLfltLfbgNxrN4=
|
|
||||||
github.com/ivanpirog/coloredcobra v1.0.1/go.mod h1:iho4nEKcnwZFiniGSdcgdvRgZNjxm+h20acv8vqmN6Q=
|
|
||||||
github.com/jarcoal/httpmock v1.4.1 h1:0Ju+VCFuARfFlhVXFc2HxlcQkfB+Xq12/EotHko+x2A=
|
|
||||||
github.com/jarcoal/httpmock v1.4.1/go.mod h1:ftW1xULwo+j0R0JJkJIIi7UKigZUXCLLanykgjwBXL0=
|
|
||||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||||
github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94=
|
github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94=
|
||||||
github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8=
|
github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8=
|
||||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
|
||||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
|
||||||
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
|
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
|
||||||
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
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/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.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/ldez/go-git-cmd-wrapper/v2 v2.9.1 h1:QJRB9Gs5i/h6TVJI6yl09Qm6rNooznRiKwIw+VIxd90=
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
github.com/ldez/go-git-cmd-wrapper/v2 v2.9.1/go.mod h1:0eUeas7XtKDPKQbB0KijfaMPbuQ/cIprtoTRiwaUoFg=
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||||
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||||
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
|
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
|
||||||
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
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.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.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||||
github.com/mattn/go-isatty v0.0.22 h1:j8l17JJ9i6VGPUFUYoTUKPSgKe/83EYU2zBC7YNKMw4=
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
github.com/mattn/go-isatty v0.0.22/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4=
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
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 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
|
||||||
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
|
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=
|
github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU=
|
||||||
|
|
@ -183,7 +132,6 @@ 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/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 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
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 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
|
||||||
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||||
github.com/oklog/run v1.2.0 h1:O8x3yXwah4A73hJdlrwo/2X6J62gE5qTMusH0dvz60E=
|
github.com/oklog/run v1.2.0 h1:O8x3yXwah4A73hJdlrwo/2X6J62gE5qTMusH0dvz60E=
|
||||||
|
|
@ -193,41 +141,20 @@ 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.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 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
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 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
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 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
|
||||||
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
|
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 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8=
|
||||||
github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY=
|
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/stackitcloud/stackit-sdk-go/core v0.20.1 h1:odiuhhRXmxvEvnVTeZSN9u98edvw2Cd3DcnkepncP3M=
|
||||||
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
|
github.com/stackitcloud/stackit-sdk-go/core v0.20.1/go.mod h1:fqto7M82ynGhEnpZU6VkQKYWYoFG5goC076JWXTUPRQ=
|
||||||
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
|
github.com/stackitcloud/stackit-sdk-go/services/sqlserverflex v1.4.0 h1:KgIRTw4gpxx8qoiaLGLbXPVDcBgCxPl60gigw+tizYc=
|
||||||
github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g=
|
github.com/stackitcloud/stackit-sdk-go/services/sqlserverflex v1.4.0/go.mod h1:fd13ANCU/Pye8uDd/6E0I605+6PYfHuVIQpPEK2Ph6c=
|
||||||
github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
|
|
||||||
github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=
|
|
||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
|
||||||
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.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/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.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
github.com/teambition/rrule-go v1.8.2 h1:lIjpjvWTj9fFUZCmuoVDrKVOtdiyzbzc93qTmRVe/J8=
|
github.com/teambition/rrule-go v1.8.2 h1:lIjpjvWTj9fFUZCmuoVDrKVOtdiyzbzc93qTmRVe/J8=
|
||||||
github.com/teambition/rrule-go v1.8.2/go.mod h1:Ieq5AbrKGciP1V//Wq8ktsTXwSwJHDD5mD/wLBGl3p4=
|
github.com/teambition/rrule-go v1.8.2/go.mod h1:Ieq5AbrKGciP1V//Wq8ktsTXwSwJHDD5mD/wLBGl3p4=
|
||||||
github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
|
github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
|
||||||
|
|
@ -240,51 +167,40 @@ 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 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
|
||||||
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
|
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/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
github.com/yuin/goldmark v1.7.7 h1:5m9rrB1sW3JUMToKFQfb+FGt1U7r57IHu5GrYrG2nqU=
|
github.com/zclconf/go-cty v1.17.0 h1:seZvECve6XX4tmnvRzWtJNHdscMtYEx5R7bnnVyd/d0=
|
||||||
github.com/yuin/goldmark v1.7.7/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
|
github.com/zclconf/go-cty v1.17.0/go.mod h1:wqFzcImaLTI6A5HfsRwB0nj5n0MRZFwmey8YoFPPs3U=
|
||||||
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 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo=
|
||||||
github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM=
|
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 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
|
||||||
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
|
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
|
||||||
go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I=
|
go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
|
||||||
go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0=
|
go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM=
|
||||||
go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM=
|
go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA=
|
||||||
go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY=
|
go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI=
|
||||||
go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg=
|
go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E=
|
||||||
go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg=
|
go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg=
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw=
|
go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM=
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A=
|
go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA=
|
||||||
go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A=
|
go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE=
|
||||||
go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0=
|
go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
|
||||||
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-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.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
|
||||||
golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI=
|
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
|
||||||
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.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM=
|
golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c=
|
||||||
golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU=
|
golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
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-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-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.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
|
||||||
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
|
golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
|
||||||
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-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-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.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
|
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||||
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
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-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
|
@ -295,37 +211,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-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-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.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
|
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
|
||||||
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
|
golang.org/x/telemetry v0.0.0-20260109210033-bd525da824e2 h1:O1cMQHRfwNpDfDJerqRoE2oD+AFlyid87D40L/OkkJo=
|
||||||
|
golang.org/x/telemetry v0.0.0-20260109210033-bd525da824e2/go.mod h1:b7fPSJ0pKZ3ccUh8gnTONJxhn3c/PS6tyzQvyqw4iA8=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
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.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q=
|
||||||
golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY=
|
golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg=
|
||||||
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.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.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.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
|
||||||
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
|
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
|
||||||
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-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.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.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c=
|
golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA=
|
||||||
golang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI=
|
golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
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=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
|
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||||
gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
|
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
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 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
|
||||||
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
|
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260504160031-60b97b32f348 h1:pfIbyB44sWzHiCpRqIen67ZQnVXSfIxWrqUMk1qwODE=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260504160031-60b97b32f348/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
|
||||||
google.golang.org/grpc v1.81.0 h1:W3G9N3KQf3BU+YuCtGKJk0CmxQNbAISICD/9AORxLIw=
|
google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc=
|
||||||
google.golang.org/grpc v1.81.0/go.mod h1:xGH9GfzOyMTGIOXBJmXt+BX/V0kcdQbdcuwQ/zNw42I=
|
google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U=
|
||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
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.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||||
|
|
@ -336,9 +252,5 @@ 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/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 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
||||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
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 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
|
|
||||||
95
golang-ci.bck.yaml
Normal file
95
golang-ci.bck.yaml
Normal file
|
|
@ -0,0 +1,95 @@
|
||||||
|
# This file contains all available configuration options
|
||||||
|
# with their default values.
|
||||||
|
|
||||||
|
# options for analysis running
|
||||||
|
run:
|
||||||
|
# default concurrency is a available CPU number
|
||||||
|
concurrency: 4
|
||||||
|
|
||||||
|
# timeout for analysis, e.g. 30s, 5m, default is 1m
|
||||||
|
timeout: 5m
|
||||||
|
linters-settings:
|
||||||
|
goimports:
|
||||||
|
# put imports beginning with prefix after 3rd-party packages;
|
||||||
|
# it's a comma-separated list of prefixes
|
||||||
|
local-prefixes: github.com/freiheit-com/nmww
|
||||||
|
depguard:
|
||||||
|
rules:
|
||||||
|
main:
|
||||||
|
list-mode: lax # Everything is allowed unless it is denied
|
||||||
|
deny:
|
||||||
|
- pkg: "github.com/stretchr/testify"
|
||||||
|
desc: Do not use a testing framework
|
||||||
|
misspell:
|
||||||
|
# Correct spellings using locale preferences for US or UK.
|
||||||
|
# Default is to use a neutral variety of English.
|
||||||
|
# Setting locale to US will correct the British spelling of 'colour' to 'color'.
|
||||||
|
locale: US
|
||||||
|
# golint:
|
||||||
|
# min-confidence: 0.8
|
||||||
|
gosec:
|
||||||
|
excludes:
|
||||||
|
# Suppressions: (see https://github.com/securego/gosec#available-rules for details)
|
||||||
|
- G104 # "Audit errors not checked" -> which we don't need and is a badly implemented version of errcheck
|
||||||
|
- G102 # "Bind to all interfaces" -> since this is normal in k8s
|
||||||
|
- G304 # "File path provided as taint input" -> too many false positives
|
||||||
|
- G307 # "Deferring unsafe method "Close" on type "io.ReadCloser" -> false positive when calling defer resp.Body.Close()
|
||||||
|
nakedret:
|
||||||
|
max-func-lines: 0
|
||||||
|
revive:
|
||||||
|
ignore-generated-header: true
|
||||||
|
severity: error
|
||||||
|
# https://github.com/mgechev/revive
|
||||||
|
rules:
|
||||||
|
- name: errorf
|
||||||
|
- name: context-as-argument
|
||||||
|
- name: error-return
|
||||||
|
- name: increment-decrement
|
||||||
|
- name: indent-error-flow
|
||||||
|
- name: superfluous-else
|
||||||
|
- name: unused-parameter
|
||||||
|
- name: unreachable-code
|
||||||
|
- name: atomic
|
||||||
|
- name: empty-lines
|
||||||
|
- name: early-return
|
||||||
|
gocritic:
|
||||||
|
enabled-tags:
|
||||||
|
- performance
|
||||||
|
- style
|
||||||
|
- experimental
|
||||||
|
disabled-checks:
|
||||||
|
- wrapperFunc
|
||||||
|
- typeDefFirst
|
||||||
|
- ifElseChain
|
||||||
|
- dupImport # https://github.com/go-critic/go-critic/issues/845
|
||||||
|
linters:
|
||||||
|
enable:
|
||||||
|
# https://golangci-lint.run/usage/linters/
|
||||||
|
# default linters
|
||||||
|
- gosimple
|
||||||
|
- govet
|
||||||
|
- ineffassign
|
||||||
|
- staticcheck
|
||||||
|
- typecheck
|
||||||
|
- unused
|
||||||
|
# additional linters
|
||||||
|
- errorlint
|
||||||
|
- gochecknoinits
|
||||||
|
- gocritic
|
||||||
|
- gofmt
|
||||||
|
- goimports
|
||||||
|
- gosec
|
||||||
|
- misspell
|
||||||
|
- nakedret
|
||||||
|
- revive
|
||||||
|
- depguard
|
||||||
|
- bodyclose
|
||||||
|
- sqlclosecheck
|
||||||
|
- wastedassign
|
||||||
|
- forcetypeassert
|
||||||
|
- errcheck
|
||||||
|
disable:
|
||||||
|
- noctx # false positive: finds errors with http.NewRequest that dont make sense
|
||||||
|
- unparam # false positives
|
||||||
|
issues:
|
||||||
|
exclude-use-default: false
|
||||||
|
|
@ -1,13 +1,6 @@
|
||||||
version: "2"
|
version: "2"
|
||||||
run:
|
run:
|
||||||
concurrency: 4
|
concurrency: 4
|
||||||
output:
|
|
||||||
formats:
|
|
||||||
text:
|
|
||||||
print-linter-name: true
|
|
||||||
print-issued-lines: true
|
|
||||||
colors: true
|
|
||||||
path: stdout
|
|
||||||
linters:
|
linters:
|
||||||
enable:
|
enable:
|
||||||
- bodyclose
|
- bodyclose
|
||||||
|
|
@ -29,8 +22,7 @@ linters:
|
||||||
depguard:
|
depguard:
|
||||||
rules:
|
rules:
|
||||||
main:
|
main:
|
||||||
list-mode: original
|
list-mode: lax
|
||||||
allow: []
|
|
||||||
deny:
|
deny:
|
||||||
- pkg: github.com/stretchr/testify
|
- pkg: github.com/stretchr/testify
|
||||||
desc: Do not use a testing framework
|
desc: Do not use a testing framework
|
||||||
|
|
@ -70,17 +62,11 @@ linters:
|
||||||
- name: empty-lines
|
- name: empty-lines
|
||||||
- name: early-return
|
- name: early-return
|
||||||
exclusions:
|
exclusions:
|
||||||
paths:
|
|
||||||
- generator/
|
|
||||||
- internal/testutils
|
|
||||||
generated: lax
|
generated: lax
|
||||||
warn-unused: true
|
paths:
|
||||||
# Excluding configuration per-path, per-linter, per-text and per-source.
|
- third_party$
|
||||||
rules:
|
- builtin$
|
||||||
# Exclude some linters from running on tests files.
|
- examples$
|
||||||
- path: _test\.go
|
|
||||||
linters:
|
|
||||||
- gochecknoinits
|
|
||||||
formatters:
|
formatters:
|
||||||
enable:
|
enable:
|
||||||
- gofmt
|
- gofmt
|
||||||
|
|
@ -88,4 +74,10 @@ formatters:
|
||||||
settings:
|
settings:
|
||||||
goimports:
|
goimports:
|
||||||
local-prefixes:
|
local-prefixes:
|
||||||
- tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview
|
- github.com/freiheit-com/nmww
|
||||||
|
exclusions:
|
||||||
|
generated: lax
|
||||||
|
paths:
|
||||||
|
- third_party$
|
||||||
|
- builtin$
|
||||||
|
- examples$
|
||||||
|
|
@ -1,97 +0,0 @@
|
||||||
|
|
||||||
version: "2"
|
|
||||||
run:
|
|
||||||
concurrency: 4
|
|
||||||
output:
|
|
||||||
formats:
|
|
||||||
text:
|
|
||||||
print-linter-name: true
|
|
||||||
print-issued-lines: true
|
|
||||||
colors: true
|
|
||||||
path: stdout
|
|
||||||
linters:
|
|
||||||
enable:
|
|
||||||
- bodyclose
|
|
||||||
- depguard
|
|
||||||
- errorlint
|
|
||||||
- forcetypeassert
|
|
||||||
- gochecknoinits
|
|
||||||
- gocritic
|
|
||||||
- gosec
|
|
||||||
- misspell
|
|
||||||
- nakedret
|
|
||||||
- revive
|
|
||||||
- sqlclosecheck
|
|
||||||
- wastedassign
|
|
||||||
disable:
|
|
||||||
- noctx
|
|
||||||
- unparam
|
|
||||||
settings:
|
|
||||||
depguard:
|
|
||||||
rules:
|
|
||||||
main:
|
|
||||||
list-mode: lax
|
|
||||||
allow:
|
|
||||||
- tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview
|
|
||||||
- github.com/hashicorp/terraform-plugin-framework
|
|
||||||
- github.com/hashicorp/terraform-plugin-log
|
|
||||||
- github.com/stackitcloud/stackit-sdk-go
|
|
||||||
deny:
|
|
||||||
- pkg: github.com/stretchr/testify
|
|
||||||
desc: Do not use a testing framework
|
|
||||||
gocritic:
|
|
||||||
disabled-checks:
|
|
||||||
- wrapperFunc
|
|
||||||
- typeDefFirst
|
|
||||||
- ifElseChain
|
|
||||||
- dupImport
|
|
||||||
- hugeParam
|
|
||||||
enabled-tags:
|
|
||||||
- performance
|
|
||||||
- style
|
|
||||||
- experimental
|
|
||||||
gosec:
|
|
||||||
excludes:
|
|
||||||
- G104
|
|
||||||
- G102
|
|
||||||
- G304
|
|
||||||
- G307
|
|
||||||
misspell:
|
|
||||||
locale: US
|
|
||||||
nakedret:
|
|
||||||
max-func-lines: 0
|
|
||||||
revive:
|
|
||||||
severity: error
|
|
||||||
rules:
|
|
||||||
- name: errorf
|
|
||||||
- name: context-as-argument
|
|
||||||
- name: error-return
|
|
||||||
- name: increment-decrement
|
|
||||||
- name: indent-error-flow
|
|
||||||
- name: superfluous-else
|
|
||||||
- name: unused-parameter
|
|
||||||
- name: unreachable-code
|
|
||||||
- name: atomic
|
|
||||||
- name: empty-lines
|
|
||||||
- name: early-return
|
|
||||||
exclusions:
|
|
||||||
paths:
|
|
||||||
- stackit-sdk-generator/
|
|
||||||
- generated/
|
|
||||||
- pkg_gen/
|
|
||||||
generated: lax
|
|
||||||
warn-unused: true
|
|
||||||
# Excluding configuration per-path, per-linter, per-text and per-source.
|
|
||||||
rules:
|
|
||||||
# Exclude some linters from running on tests files.
|
|
||||||
- path: _test\.go
|
|
||||||
linters:
|
|
||||||
- gochecknoinits
|
|
||||||
formatters:
|
|
||||||
enable:
|
|
||||||
- gofmt
|
|
||||||
- goimports
|
|
||||||
settings:
|
|
||||||
goimports:
|
|
||||||
local-prefixes:
|
|
||||||
- tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
package testutils
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"path/filepath"
|
|
||||||
"regexp"
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/jarcoal/httpmock"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestName() string {
|
|
||||||
pc, _, _, _ := runtime.Caller(1)
|
|
||||||
nameFull := runtime.FuncForPC(pc).Name()
|
|
||||||
nameEnd := filepath.Ext(nameFull)
|
|
||||||
name := strings.TrimPrefix(nameEnd, ".")
|
|
||||||
return name
|
|
||||||
}
|
|
||||||
|
|
||||||
func ActivateEnvironmentHttpMocks() {
|
|
||||||
httpmock.RegisterNoResponder(
|
|
||||||
func(req *http.Request) (*http.Response, error) {
|
|
||||||
return nil, fmt.Errorf("no responder found for %s %s, please check your http mocks", req.Method, req.URL)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
httpmock.RegisterRegexpResponder(
|
|
||||||
"GET",
|
|
||||||
regexp.MustCompile(`^https://api\.bap\.microsoft\.com/providers/Microsoft\.BusinessAppPlatform/locations/(europe|unitedstates)/environmentLanguages\?api-version=2023-06-01$`),
|
|
||||||
func(_ *http.Request) (*http.Response, error) {
|
|
||||||
return httpmock.NewStringResponse(
|
|
||||||
http.StatusOK,
|
|
||||||
httpmock.File("../../services/languages/tests/datasource/Validate_Read/get_languages.json").String(),
|
|
||||||
), nil
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
@ -1,129 +0,0 @@
|
||||||
package testutils
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"path/filepath"
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
"text/template"
|
|
||||||
)
|
|
||||||
|
|
||||||
// GetHomeEnvVariableName Helper function to obtain the home directory on different systems.
|
|
||||||
// Based on os.UserHomeDir().
|
|
||||||
func GetHomeEnvVariableName() string {
|
|
||||||
env := "HOME"
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "windows":
|
|
||||||
env = "USERPROFILE"
|
|
||||||
case "plan9":
|
|
||||||
env = "home"
|
|
||||||
}
|
|
||||||
return env
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateTemporaryHome create temporary home and initialize the credentials file as well
|
|
||||||
func CreateTemporaryHome(createValidCredentialsFile bool, t *testing.T) string {
|
|
||||||
// create a temporary file
|
|
||||||
tempHome, err := os.MkdirTemp("", "tempHome")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Failed to create temporary home directory: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// create credentials file in temp directory
|
|
||||||
stackitFolder := path.Join(tempHome, ".stackit")
|
|
||||||
if err := os.Mkdir(stackitFolder, 0o750); err != nil {
|
|
||||||
t.Fatalf("Failed to create stackit folder: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
filePath := path.Join(stackitFolder, "credentials.json")
|
|
||||||
file, err := os.Create(filePath)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Failed to create credentials file: %v", err)
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
if err := file.Close(); err != nil {
|
|
||||||
t.Fatalf("Error while closing the file: %v", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
// Define content, default = invalid token
|
|
||||||
token := "foo_token"
|
|
||||||
// if createValidCredentialsFile {
|
|
||||||
// token = GetTestProjectServiceAccountJson("")
|
|
||||||
//}
|
|
||||||
if _, err = file.WriteString(token); err != nil {
|
|
||||||
t.Fatalf("Error writing to file: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return tempHome
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetTemporaryHome Function to overwrite the home folder
|
|
||||||
func SetTemporaryHome(tempHomePath string) {
|
|
||||||
env := GetHomeEnvVariableName()
|
|
||||||
if err := os.Setenv(env, tempHomePath); err != nil {
|
|
||||||
fmt.Printf("Error setting temporary home directory %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// CleanupTemporaryHome cleanup the temporary home and reset the environment variable
|
|
||||||
func CleanupTemporaryHome(tempHomePath string, t *testing.T) {
|
|
||||||
if err := os.RemoveAll(tempHomePath); err != nil {
|
|
||||||
t.Fatalf("Error cleaning up temporary folder: %v", err)
|
|
||||||
}
|
|
||||||
originalHomeDir, err := os.UserHomeDir()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Failed to restore home directory back to normal: %v", err)
|
|
||||||
}
|
|
||||||
// revert back to original home folder
|
|
||||||
env := GetHomeEnvVariableName()
|
|
||||||
if err := os.Setenv(env, originalHomeDir); err != nil {
|
|
||||||
fmt.Printf("Error resetting temporary home directory %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ucFirst(s string) string {
|
|
||||||
if s == "" {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return strings.ToUpper(s[:1]) + s[1:]
|
|
||||||
}
|
|
||||||
|
|
||||||
func StringFromTemplateMust(tplFile string, data any) string {
|
|
||||||
res, err := StringFromTemplate(tplFile, data)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalln(err)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
func StringFromTemplate(tplFile string, data any) (string, error) {
|
|
||||||
fn := template.FuncMap{
|
|
||||||
"ucfirst": ucFirst,
|
|
||||||
}
|
|
||||||
|
|
||||||
file := filepath.Base(tplFile)
|
|
||||||
|
|
||||||
tmpl, err := template.New(file).Funcs(fn).ParseFiles(tplFile)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
tplBuf := &bytes.Buffer{}
|
|
||||||
|
|
||||||
err = tmpl.Execute(tplBuf, data)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return tplBuf.String(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ResStr(prefix, resource, name string) string {
|
|
||||||
return fmt.Sprintf("%s_%s.%s", prefix, resource, name)
|
|
||||||
}
|
|
||||||
|
|
@ -1,220 +0,0 @@
|
||||||
package testutils
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"log/slog"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/providerserver"
|
|
||||||
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
|
|
||||||
"github.com/hashicorp/terraform-plugin-testing/config"
|
|
||||||
"github.com/hashicorp/terraform-plugin-testing/echoprovider"
|
|
||||||
"github.com/joho/godotenv"
|
|
||||||
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// Default location of service account JSON
|
|
||||||
serviceAccountFilePath = "service_account.json"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// TestAccProtoV6ProviderFactories is used to instantiate a provider during
|
|
||||||
// acceptance testing. The factory function will be invoked for every Terraform
|
|
||||||
// CLI command executed to create a provider server to which the CLI can
|
|
||||||
// reattach.
|
|
||||||
TestAccProtoV6ProviderFactories = map[string]func() (tfprotov6.ProviderServer, error){
|
|
||||||
"stackitprivatepreview": providerserver.NewProtocol6WithError(stackit.New("test-version")()),
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestEphemeralAccProtoV6ProviderFactories is used to instantiate a provider during
|
|
||||||
// acceptance testing. The factory function will be invoked for every Terraform
|
|
||||||
// CLI command executed to create a provider server to which the CLI can
|
|
||||||
// reattach.
|
|
||||||
//
|
|
||||||
// See the Terraform acceptance test documentation on ephemeral resources for more information:
|
|
||||||
// https://developer.hashicorp.com/terraform/plugin/testing/acceptance-tests/ephemeral-resources
|
|
||||||
TestEphemeralAccProtoV6ProviderFactories = map[string]func() (tfprotov6.ProviderServer, error){
|
|
||||||
"stackitprivatepreview": providerserver.NewProtocol6WithError(stackit.New("test-version")()),
|
|
||||||
"echo": echoprovider.NewProviderServer(),
|
|
||||||
}
|
|
||||||
|
|
||||||
// E2ETestsEnabled checks if end-to-end tests should be run.
|
|
||||||
// It is enabled when the TF_ACC environment variable is set to "1".
|
|
||||||
E2ETestsEnabled = os.Getenv("TF_ACC") == "1"
|
|
||||||
// OrganizationId is the id of organization used for tests
|
|
||||||
OrganizationId = os.Getenv("TF_ACC_ORGANIZATION_ID")
|
|
||||||
// ProjectId is the id of project used for tests
|
|
||||||
ProjectId = os.Getenv("TF_ACC_PROJECT_ID")
|
|
||||||
Region = os.Getenv("TF_ACC_REGION")
|
|
||||||
// ServiceAccountFile is the json file of the service account
|
|
||||||
ServiceAccountFile = os.Getenv("TF_ACC_SERVICE_ACCOUNT_FILE")
|
|
||||||
// ServerId is the id of a server used for some tests
|
|
||||||
ServerId = getenv("TF_ACC_SERVER_ID", "")
|
|
||||||
// TestProjectParentContainerID is the container id of the parent resource under which projects are created as part of the resource-manager acceptance tests
|
|
||||||
TestProjectParentContainerID = os.Getenv("TF_ACC_TEST_PROJECT_PARENT_CONTAINER_ID")
|
|
||||||
// TestProjectParentUUID is the uuid of the parent resource under which projects are created as part of the resource-manager acceptance tests
|
|
||||||
TestProjectParentUUID = os.Getenv("TF_ACC_TEST_PROJECT_PARENT_UUID")
|
|
||||||
// TestProjectServiceAccountEmail is the e-mail of a service account with admin permissions on the organization under which projects are created as part of the resource-manager acceptance tests
|
|
||||||
TestProjectServiceAccountEmail = os.Getenv("TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_EMAIL")
|
|
||||||
// TestProjectUserEmail is the e-mail of a user for the project created as part of the resource-manager acceptance tests
|
|
||||||
// Default email: acc-test@sa.stackit.cloud
|
|
||||||
TestProjectUserEmail = getenv("TF_ACC_TEST_PROJECT_USER_EMAIL", "acc-test@sa.stackit.cloud")
|
|
||||||
// TestImageLocalFilePath is the local path to an image file used for image acceptance tests
|
|
||||||
TestImageLocalFilePath = getenv("TF_ACC_TEST_IMAGE_LOCAL_FILE_PATH", "default")
|
|
||||||
)
|
|
||||||
|
|
||||||
func Setup() {
|
|
||||||
root, err := getRoot()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalln(err)
|
|
||||||
}
|
|
||||||
err = godotenv.Load(fmt.Sprintf("%s/.env", *root))
|
|
||||||
if err != nil {
|
|
||||||
slog.Info("could not find .env file - not loading .env")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
slog.Info("loaded .env file", "path", *root)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getRoot() (*string, error) {
|
|
||||||
cmd := exec.Command("git", "rev-parse", "--show-toplevel")
|
|
||||||
out, err := cmd.Output()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
lines := strings.Split(string(out), "\n")
|
|
||||||
return &lines[0], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ResourceNameWithDateTime(name string) string {
|
|
||||||
dateTime := time.Now().Format(time.RFC3339)
|
|
||||||
// Remove timezone to have a smaller datetime
|
|
||||||
dateTimeTrimmed, _, _ := strings.Cut(dateTime, "+")
|
|
||||||
return fmt.Sprintf("tf-acc-%s-%s", name, dateTimeTrimmed)
|
|
||||||
}
|
|
||||||
|
|
||||||
// func GetTestProjectServiceAccountJson(path string) string {
|
|
||||||
// var err error
|
|
||||||
// json, ok := os.LookupEnv("TF_ACC_SERVICE_ACCOUNT_JSON_CONTENT")
|
|
||||||
// if !ok || json == "" {
|
|
||||||
// json, err = readTestServiceAccountJsonFromFile(path)
|
|
||||||
// if err != nil {
|
|
||||||
// return ""
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return json
|
|
||||||
//}
|
|
||||||
|
|
||||||
// func GetTestProjectServiceAccountToken(path string) string {
|
|
||||||
// var err error
|
|
||||||
// token, tokenSet := os.LookupEnv("TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_TOKEN")
|
|
||||||
// if !tokenSet || token == "" {
|
|
||||||
// token, err = readTestTokenFromCredentialsFile(path)
|
|
||||||
// if err != nil {
|
|
||||||
// return ""
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return token
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
// func readTestTokenFromCredentialsFile(path string) (string, error) {
|
|
||||||
// if path == "" {
|
|
||||||
// customPath, customPathSet := os.LookupEnv("STACKIT_CREDENTIALS_PATH")
|
|
||||||
// if !customPathSet || customPath == "" {
|
|
||||||
// path = credentialsFilePath
|
|
||||||
// home, err := os.UserHomeDir()
|
|
||||||
// if err != nil {
|
|
||||||
// return "", fmt.Errorf("getting home directory: %w", err)
|
|
||||||
// }
|
|
||||||
// path = filepath.Join(home, path)
|
|
||||||
// } else {
|
|
||||||
// path = customPath
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// credentialsRaw, err := os.ReadFile(path)
|
|
||||||
// if err != nil {
|
|
||||||
// return "", fmt.Errorf("opening file: %w", err)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// var credentials struct {
|
|
||||||
// TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_TOKEN string `json:"TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_TOKEN"`
|
|
||||||
// }
|
|
||||||
// err = json.Unmarshal(credentialsRaw, &credentials)
|
|
||||||
// if err != nil {
|
|
||||||
// return "", fmt.Errorf("unmarshalling credentials: %w", err)
|
|
||||||
// }
|
|
||||||
// return credentials.TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_TOKEN, nil
|
|
||||||
//}
|
|
||||||
|
|
||||||
// func readTestServiceAccountJsonFromFile(path string) (string, error) {
|
|
||||||
// if path == "" {
|
|
||||||
// customPath, ok := os.LookupEnv("TF_ACC_SERVICE_ACCOUNT_FILE")
|
|
||||||
// if !ok || customPath == "" {
|
|
||||||
// path = serviceAccountFilePath
|
|
||||||
// // TODO: check if we want to handle this with a home dir
|
|
||||||
// /*
|
|
||||||
// home, err := os.UserHomeDir()
|
|
||||||
// if err != nil {
|
|
||||||
// return "", fmt.Errorf("getting home directory: %w", err)
|
|
||||||
// }
|
|
||||||
// path = filepath.Join(home, path)
|
|
||||||
// */
|
|
||||||
// } else {
|
|
||||||
// path = customPath
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// credentialsRaw, err := os.ReadFile(path)
|
|
||||||
// if err != nil {
|
|
||||||
// return "", fmt.Errorf("opening file: %w", err)
|
|
||||||
// }
|
|
||||||
// return string(credentialsRaw), nil
|
|
||||||
//}
|
|
||||||
|
|
||||||
func getenv(key, defaultValue string) string {
|
|
||||||
val := os.Getenv(key)
|
|
||||||
if val == "" {
|
|
||||||
return defaultValue
|
|
||||||
}
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateDefaultLocalFile is a helper for local_file_path. No real data is created
|
|
||||||
func CreateDefaultLocalFile() os.File {
|
|
||||||
// Define the file name and size
|
|
||||||
fileName := "test-512k.img"
|
|
||||||
size := 512 * 1024 // 512 KB
|
|
||||||
|
|
||||||
// Create the file
|
|
||||||
file, err := os.Create(fileName)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Seek to the desired position (512 KB)
|
|
||||||
_, err = file.Seek(int64(size), 0)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return *file
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConvertConfigVariable(variable config.Variable) string {
|
|
||||||
tmpByteArray, _ := variable.MarshalJSON()
|
|
||||||
// In case the variable is a string, the quotes should be removed
|
|
||||||
if tmpByteArray[0] == '"' && tmpByteArray[len(tmpByteArray)-1] == '"' {
|
|
||||||
result := string(tmpByteArray[1 : len(tmpByteArray)-1])
|
|
||||||
// Replace escaped quotes which where added MarshalJSON
|
|
||||||
rawString := strings.ReplaceAll(result, `\"`, `"`)
|
|
||||||
return rawString
|
|
||||||
}
|
|
||||||
return string(tmpByteArray)
|
|
||||||
}
|
|
||||||
7
main.go
7
main.go
|
|
@ -1,3 +1,5 @@
|
||||||
|
// Copyright (c) STACKIT
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
@ -6,8 +8,7 @@ import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/providerserver"
|
"github.com/hashicorp/terraform-plugin-framework/providerserver"
|
||||||
|
"github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit"
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -20,7 +21,7 @@ func main() {
|
||||||
flag.BoolVar(&debug, "debug", false, "allows debugging the provider")
|
flag.BoolVar(&debug, "debug", false, "allows debugging the provider")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
err := providerserver.Serve(context.Background(), stackit.New(version), providerserver.ServeOpts{
|
err := providerserver.Serve(context.Background(), stackit.New(version), providerserver.ServeOpts{
|
||||||
Address: "tfregistry.sysops.stackit.rocks/mhenselin/stackitprivatepreview",
|
Address: "registry.terraform.io/mhenselin/stackitprivatepreview",
|
||||||
Debug: debug,
|
Debug: debug,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
1
pkg/postgresflexalpha/.openapi-generator/VERSION
Normal file
1
pkg/postgresflexalpha/.openapi-generator/VERSION
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
6.6.0
|
||||||
6257
pkg/postgresflexalpha/api_default.go
Normal file
6257
pkg/postgresflexalpha/api_default.go
Normal file
File diff suppressed because it is too large
Load diff
2263
pkg/postgresflexalpha/api_default_test.go
Normal file
2263
pkg/postgresflexalpha/api_default_test.go
Normal file
File diff suppressed because it is too large
Load diff
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