Compare commits
53 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6b5b97ac9a | |||
|
|
29cf260d56 | ||
| 4e217e20a4 | |||
|
|
2f2b5cd04a | ||
| 6c26089930 | |||
| c31a8a787a | |||
| 515b7b1357 | |||
| e6d2d3e10a | |||
| 8fee76f037 | |||
| ebb3ec051d | |||
|
|
e5b2681142 | ||
| e65c74e6e7 | |||
| afde034d64 | |||
|
|
7b911ebf70 | ||
| e320e80956 | |||
|
|
4d96cc8951 | ||
| f9a3d4265c | |||
|
|
1298c3fbf1 | ||
| fa641d29c5 | |||
|
|
dab47d4690 | ||
| a0351798e0 | |||
| f7b022ec6c | |||
|
|
6e3d2b51fa | ||
|
|
9ef7ce9029 | ||
| aac1a2ba17 | |||
| d16b97a8e9 | |||
|
|
edc5e869ce | ||
| 7b2dfaea44 | |||
| 2893a11c0a | |||
| 0b5e15d1c5 | |||
|
|
8a6d932107 | ||
| 956cedef08 | |||
|
|
d5b4e02437 | ||
|
|
bb15293dd3 | ||
|
|
6e6e771631 | ||
|
|
683bc64c12 | ||
|
|
064d2cf1db | ||
|
|
722c46b12d | ||
| 03776cc7fd | |||
| 9060aa9f6a | |||
|
|
5a1dc9cd94 | ||
| d34927537a | |||
|
|
83b0860115 | ||
|
|
97645d7a66 | ||
|
|
94f3dad963 | ||
|
|
c081f5f7bd | ||
|
|
8ab8656b5c | ||
|
|
63435e5e63 | ||
|
|
e974ccf906 | ||
|
|
1fd2df5c76 | ||
|
|
aaabadde1a | ||
|
|
0a5bc30d9c | ||
| 01deb9022d |
79 changed files with 3109 additions and 1909 deletions
125
.github/actions/acc_test/action.yaml
vendored
125
.github/actions/acc_test/action.yaml
vendored
|
|
@ -14,7 +14,7 @@ inputs:
|
||||||
|
|
||||||
go-version:
|
go-version:
|
||||||
description: "go version to install"
|
description: "go version to install"
|
||||||
default: '1.25'
|
default: '1.26'
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
project_id:
|
project_id:
|
||||||
|
|
@ -65,20 +65,18 @@ inputs:
|
||||||
description: "testfile to run"
|
description: "testfile to run"
|
||||||
default: ''
|
default: ''
|
||||||
|
|
||||||
|
outputs:
|
||||||
|
result:
|
||||||
|
value: ${{ steps.testrun.outputs.result }}
|
||||||
|
description: "the output of the tests"
|
||||||
|
|
||||||
#outputs:
|
status:
|
||||||
# random-number:
|
value: ${{ steps.status.outputs.status }}
|
||||||
# description: "Random number"
|
description: "the status of the tests"
|
||||||
# value: ${{ steps.random-number-generator.outputs.random-number }}
|
|
||||||
|
|
||||||
runs:
|
runs:
|
||||||
using: "composite"
|
using: "composite"
|
||||||
steps:
|
steps:
|
||||||
# - name: Random Number Generator
|
|
||||||
# id: random-number-generator
|
|
||||||
# run: echo "random-number=$(echo $RANDOM)" >> $GITHUB_OUTPUT
|
|
||||||
# shell: bash
|
|
||||||
|
|
||||||
- name: Install needed tools
|
- name: Install needed tools
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
|
|
@ -94,6 +92,15 @@ runs:
|
||||||
fi
|
fi
|
||||||
echo "::endgroup::"
|
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
|
- name: Setup JAVA
|
||||||
uses: actions/setup-java@v5
|
uses: actions/setup-java@v5
|
||||||
with:
|
with:
|
||||||
|
|
@ -196,11 +203,11 @@ runs:
|
||||||
ls -l stackit/"${{ inputs.service_account_json_file_path }}"
|
ls -l stackit/"${{ inputs.service_account_json_file_path }}"
|
||||||
echo "::endgroup::"
|
echo "::endgroup::"
|
||||||
|
|
||||||
- name: Run acceptance test file
|
- name: Run acceptance tests
|
||||||
if: ${{ inputs.test_file != '' }}
|
id: testrun
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
echo "::group::go test file"
|
echo "::group::go test"
|
||||||
set -e
|
set -e
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
|
|
@ -209,60 +216,22 @@ runs:
|
||||||
export TF_LOG
|
export TF_LOG
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
testfile="${{ inputs.test_file }}"
|
||||||
|
|
||||||
|
echo "result=no result before run" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
echo "Running acceptance tests for the terraform provider"
|
echo "Running acceptance tests for the terraform provider"
|
||||||
cd stackit || exit 1
|
|
||||||
TF_ACC=1 \
|
|
||||||
TF_ACC_PROJECT_ID=${TF_ACC_PROJECT_ID} \
|
|
||||||
TF_ACC_REGION=${TF_ACC_REGION} \
|
|
||||||
TF_ACC_TEST_PROJECT_USER_EMAIL=${TF_ACC_TEST_PROJECT_USER_EMAIL} \
|
|
||||||
TF_ACC_SERVICE_ACCOUNT_FILE="${PWD}/${{ inputs.service_account_json_file_path }}" \
|
|
||||||
TF_ACC_KEK_KEY_ID=${TF_ACC_KEK_KEY_ID} \
|
|
||||||
TF_ACC_KEK_KEY_RING_ID=${TF_ACC_KEK_KEY_RING_ID} \
|
|
||||||
TF_ACC_KEK_KEY_VERSION=${TF_ACC_KEK_KEY_VERSION} \
|
|
||||||
TF_ACC_KEK_SERVICE_ACCOUNT=${TF_ACC_KEK_SERVICE_ACCOUNT} \
|
|
||||||
go test -v ${{ inputs.test_file }} -timeout=${{ inputs.test_timeout_string }}
|
|
||||||
echo "::endgroup::"
|
|
||||||
env:
|
|
||||||
TF_ACC_PROJECT_ID: ${{ inputs.project_id }}
|
|
||||||
TF_ACC_REGION: ${{ inputs.region }}
|
|
||||||
TF_ACC_TEST_PROJECT_USER_EMAIL: ${{ inputs.project_user_email }}
|
|
||||||
TF_ACC_KEK_KEY_ID: ${{ inputs.tf_acc_kek_key_id }}
|
|
||||||
TF_ACC_KEK_KEY_RING_ID: ${{ inputs.tf_acc_kek_key_ring_id }}
|
|
||||||
TF_ACC_KEK_KEY_VERSION: ${{ inputs.tf_acc_kek_key_version }}
|
|
||||||
TF_ACC_KEK_SERVICE_ACCOUNT: ${{ inputs.tf_acc_kek_service_account }}
|
|
||||||
|
|
||||||
# does not work correctly
|
if [[ -z "$testfile" ]]; then
|
||||||
# - name: Run test action
|
testfile="./..."
|
||||||
# if: ${{ inputs.test_file == '' }}
|
|
||||||
# env:
|
|
||||||
# TF_ACC: 1
|
|
||||||
# TF_ACC_PROJECT_ID: ${{ inputs.project_id }}
|
|
||||||
# TF_ACC_REGION: ${{ inputs.region }}
|
|
||||||
# TF_ACC_TEST_PROJECT_USER_EMAIL: ${{ inputs.project_user_email }}
|
|
||||||
# TF_ACC_KEK_KEY_ID: ${{ inputs.tf_acc_kek_key_id }}
|
|
||||||
# TF_ACC_KEK_KEY_RING_ID: ${{ inputs.tf_acc_kek_key_ring_id }}
|
|
||||||
# TF_ACC_KEK_KEY_VERSION: ${{ inputs.tf_acc_kek_key_version }}
|
|
||||||
# TF_ACC_KEK_SERVICE_ACCOUNT: ${{ inputs.tf_acc_kek_service_account }}
|
|
||||||
# TF_ACC_SERVICE_ACCOUNT_FILE: ${{ steps.service_account.outputs.safile }}
|
|
||||||
# uses: robherley/go-test-action@v0
|
|
||||||
# with:
|
|
||||||
# testArguments: "./... -timeout ${{ inputs.test_timeout_string }}"
|
|
||||||
# moduleDirectory: "stackit"
|
|
||||||
|
|
||||||
- name: Run acceptance tests
|
|
||||||
if: ${{ inputs.test_file == '' }}
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
echo "::group::go test all"
|
|
||||||
set -e
|
|
||||||
set -o pipefail
|
|
||||||
|
|
||||||
if [[ "${{ inputs.tf_debug }}" == "true" ]]; then
|
|
||||||
TF_LOG=INFO
|
|
||||||
export TF_LOG
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Running acceptance tests for the terraform provider"
|
if [[ -z "$testfile" ]]; then
|
||||||
|
echo "ERROR: No test file provided"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
set +e
|
||||||
cd stackit || exit 1
|
cd stackit || exit 1
|
||||||
TF_ACC=1 \
|
TF_ACC=1 \
|
||||||
TF_ACC_PROJECT_ID=${TF_ACC_PROJECT_ID} \
|
TF_ACC_PROJECT_ID=${TF_ACC_PROJECT_ID} \
|
||||||
|
|
@ -273,7 +242,21 @@ runs:
|
||||||
TF_ACC_KEK_KEY_RING_ID=${TF_ACC_KEK_KEY_RING_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_KEY_VERSION=${TF_ACC_KEK_KEY_VERSION} \
|
||||||
TF_ACC_KEK_SERVICE_ACCOUNT=${TF_ACC_KEK_SERVICE_ACCOUNT} \
|
TF_ACC_KEK_SERVICE_ACCOUNT=${TF_ACC_KEK_SERVICE_ACCOUNT} \
|
||||||
go test -v ./... -timeout=${{ inputs.test_timeout_string }}
|
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::"
|
echo "::endgroup::"
|
||||||
env:
|
env:
|
||||||
TF_ACC_PROJECT_ID: ${{ inputs.project_id }}
|
TF_ACC_PROJECT_ID: ${{ inputs.project_id }}
|
||||||
|
|
@ -283,3 +266,17 @@ runs:
|
||||||
TF_ACC_KEK_KEY_RING_ID: ${{ inputs.tf_acc_kek_key_ring_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_KEY_VERSION: ${{ inputs.tf_acc_kek_key_version }}
|
||||||
TF_ACC_KEK_SERVICE_ACCOUNT: ${{ inputs.tf_acc_kek_service_account }}
|
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"
|
||||||
|
|
|
||||||
2
.github/actions/build/action.yaml
vendored
2
.github/actions/build/action.yaml
vendored
|
|
@ -3,7 +3,7 @@ description: "Build pipeline"
|
||||||
inputs:
|
inputs:
|
||||||
go-version:
|
go-version:
|
||||||
description: "Go version to install"
|
description: "Go version to install"
|
||||||
default: '1.25'
|
default: '1.26'
|
||||||
required: true
|
required: true
|
||||||
java-distribution:
|
java-distribution:
|
||||||
description: "JAVA distribution to use (default: temurin)"
|
description: "JAVA distribution to use (default: temurin)"
|
||||||
|
|
|
||||||
1
.github/actions/clean_up/README.md
vendored
Normal file
1
.github/actions/clean_up/README.md
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
# acceptance test action
|
||||||
227
.github/actions/clean_up/action.yaml
vendored
Normal file
227
.github/actions/clean_up/action.yaml
vendored
Normal file
|
|
@ -0,0 +1,227 @@
|
||||||
|
name: CleanUp Project Resources
|
||||||
|
description: "Acceptance Testing CleanUp"
|
||||||
|
|
||||||
|
inputs:
|
||||||
|
project_id:
|
||||||
|
description: "STACKIT project ID for tests"
|
||||||
|
required: true
|
||||||
|
|
||||||
|
region:
|
||||||
|
description: "STACKIT region for tests"
|
||||||
|
default: 'eu01'
|
||||||
|
required: true
|
||||||
|
|
||||||
|
tf_resource_prefix:
|
||||||
|
description: "prefix in resource names"
|
||||||
|
default: 'tf-acc-'
|
||||||
|
required: true
|
||||||
|
|
||||||
|
service_account_json_content:
|
||||||
|
description: "STACKIT service account JSON file contents"
|
||||||
|
required: true
|
||||||
|
default: ''
|
||||||
|
|
||||||
|
service_account_json_content_b64:
|
||||||
|
description: "STACKIT service account JSON file contents"
|
||||||
|
required: true
|
||||||
|
default: ''
|
||||||
|
|
||||||
|
list_only:
|
||||||
|
description: "only list resources, DO NOT delete"
|
||||||
|
required: true
|
||||||
|
default: 'true'
|
||||||
|
|
||||||
|
log_level:
|
||||||
|
description: "Log Level"
|
||||||
|
required: true
|
||||||
|
default: 'warning'
|
||||||
|
|
||||||
|
outputs:
|
||||||
|
cli-version:
|
||||||
|
description: "stackit cli version"
|
||||||
|
value: ${{ steps.stackit_version.outputs.version }}
|
||||||
|
|
||||||
|
pre_count:
|
||||||
|
description: "number of resources found"
|
||||||
|
value: ${{ steps.retrieve_pre.outputs.count }}
|
||||||
|
|
||||||
|
post_count:
|
||||||
|
description: "number of resources found"
|
||||||
|
value: ${{ steps.retrieve_post.outputs.count }}
|
||||||
|
|
||||||
|
status:
|
||||||
|
description: "status of the test"
|
||||||
|
value: ${{ steps.status.outputs.status }}
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- name: Install needed tools
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
echo "::group::apt install"
|
||||||
|
set -e
|
||||||
|
apt-get -y -qq update >apt_update.log 2>apt_update_err.log
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
cat apt_update.log apt_update_err.log
|
||||||
|
fi
|
||||||
|
apt-get -y -qq install curl gnupg jq >apt_get.log 2>apt_get_err.log
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
cat apt_get.log apt_get_err.log
|
||||||
|
fi
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
echo "::group::apt add source"
|
||||||
|
curl https://packages.stackit.cloud/keys/key.gpg | gpg --dearmor -o /usr/share/keyrings/stackit.gpg
|
||||||
|
echo "deb [signed-by=/usr/share/keyrings/stackit.gpg] https://packages.stackit.cloud/apt/cli stackit main" | tee -a /etc/apt/sources.list.d/stackit.list
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
echo "::group::apt install stackit cli"
|
||||||
|
apt-get -y -qq update >apt_update.log 2>apt_update_err.log
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
cat apt_update.log apt_update_err.log
|
||||||
|
fi
|
||||||
|
apt-get -y -qq install stackit >apt_get.log 2>apt_get_err.log
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
cat apt_get.log apt_get_err.log
|
||||||
|
fi
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
- name: Check stackit cli version
|
||||||
|
id: stackit_version
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
VERSION=$(stackit --version | grep "Version:" | cut -d " " -f 2)
|
||||||
|
echo "stackit cli version: ${VERSION}"
|
||||||
|
echo "version=${VERSION}" >> $GITHUB_OUTPUT
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
- name: Creating service_account file from json input
|
||||||
|
if: inputs.service_account_json_content != ''
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
echo "::group::create service account file"
|
||||||
|
set -e
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
echo "${{ inputs.service_account_json_content }}" > .svc_acc.json
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
- name: Creating service_account file from base64 json input
|
||||||
|
if: inputs.service_account_json_content_b64 != ''
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
echo "::group::create service account file"
|
||||||
|
set -e
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
echo "${{ inputs.service_account_json_content_b64 }}" | base64 -d > .svc_acc.json
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
- name: Check service account file exists
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
if [[ ! -s .svc_acc.json ]]; then
|
||||||
|
echo "ERROR: service account file missing or empty"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Retrieve resources before
|
||||||
|
id: retrieve_pre
|
||||||
|
run: |
|
||||||
|
echo "::group::retrieve resources"
|
||||||
|
set -e
|
||||||
|
echo "authenticating api"
|
||||||
|
STACKIT_SERVICE_ACCOUNT_KEY_PATH="${PWD}/.svc_acc.json"
|
||||||
|
export STACKIT_SERVICE_ACCOUNT_KEY_PATH
|
||||||
|
stackit auth activate-service-account --service-account-key-path .svc_acc.json
|
||||||
|
|
||||||
|
echo "SQL Server Flex resources:"
|
||||||
|
sql_res=$(stackit --verbosity ${{ inputs.log_level }} --project-id "${{ inputs.project_id }}" beta sqlserverflex instance list --output-format json | jq -r '.[] | select(.name | startswith("${{ inputs.tf_resource_prefix }}"))')
|
||||||
|
sql_count=$(echo "$sql_res" | jq -r '.id' | wc -l)
|
||||||
|
|
||||||
|
echo "PostgreSQL Flex resources:"
|
||||||
|
pg_res=$(stackit --verbosity ${{ inputs.log_level }} --project-id "${{ inputs.project_id }}" postgresflex instance list --output-format json | jq -r '.[] | select(.name | startswith("${{ inputs.tf_resource_prefix }}"))')
|
||||||
|
pg_count=$(echo "$pg_res" | jq -r '.id' | wc -l)
|
||||||
|
|
||||||
|
echo "Number of resources found: ${sql_count} SQL Server Flex, ${pg_count} PostgreSQL Flex"
|
||||||
|
echo "count=$(( ${pg_count} + ${sql_count} ))" >> $GITHUB_OUTPUT
|
||||||
|
echo "::endgroup::"
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
- name: Delete SQL Server Flex resources
|
||||||
|
if: ${{ inputs.list_only != 'true' }}
|
||||||
|
id: del_sql
|
||||||
|
run: |
|
||||||
|
echo "::group::delete SQL Server Flex resources"
|
||||||
|
stackit --verbosity ${{ inputs.log_level }} auth activate-service-account --service-account-key-path .svc_acc.json
|
||||||
|
for s in $(stackit --verbosity ${{ inputs.log_level }} --project-id ${{ inputs.project_id }} beta sqlserverflex instance list --output-format json | jq -r '.[] | select(.name | startswith("${{ inputs.tf_resource_prefix }}")) | .id');
|
||||||
|
do
|
||||||
|
stackit --verbosity ${{ inputs.log_level }} -y --project-id ${{ inputs.project_id }} beta sqlserverflex instance delete $s || echo "status=FAILURE" >> ${GITHUB_OUTPUT};
|
||||||
|
done
|
||||||
|
echo "::endgroup::"
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
- name: Skip Delete SQL Server Flex resources
|
||||||
|
if: ${{ inputs.list_only == 'true' }}
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
echo "Skip deleting: list only mode"
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
- name: Delete PostgreSQL Flex resources
|
||||||
|
if: ${{ inputs.list_only != 'true' }}
|
||||||
|
id: del_pg
|
||||||
|
run: |
|
||||||
|
echo "::group::delete PostgreSQL Flex resources"
|
||||||
|
stackit auth activate-service-account --service-account-key-path .svc_acc.json
|
||||||
|
for s in $(stackit --verbosity ${{ inputs.log_level }} --project-id ${{ inputs.project_id }} postgresflex instance list --output-format json | jq -r '.[] | select(.name | startswith("${{ inputs.tf_resource_prefix }}")) | .id');
|
||||||
|
do
|
||||||
|
stackit --verbosity ${{ inputs.log_level }} -y --project-id ${{ inputs.project_id }} postgresflex instance delete "$s" --force || echo "status=FAILURE" >> ${GITHUB_OUTPUT};
|
||||||
|
done
|
||||||
|
echo "::endgroup::"
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
- name: Skip Delete PostgreSQL Flex resources
|
||||||
|
if: ${{ inputs.list_only == 'true' }}
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
echo "Skip deleting: list only mode"
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
- name: Retrieve resources after
|
||||||
|
id: retrieve_post
|
||||||
|
run: |
|
||||||
|
echo "::group::retrieve resources"
|
||||||
|
set -e
|
||||||
|
echo "authenticating api"
|
||||||
|
STACKIT_SERVICE_ACCOUNT_KEY_PATH="${PWD}/.svc_acc.json"
|
||||||
|
export STACKIT_SERVICE_ACCOUNT_KEY_PATH
|
||||||
|
stackit auth activate-service-account --service-account-key-path .svc_acc.json
|
||||||
|
|
||||||
|
echo "SQL Server Flex resources:"
|
||||||
|
sql_res=$(stackit --verbosity ${{ inputs.log_level }} --project-id "${{ inputs.project_id }}" beta sqlserverflex instance list --output-format json | jq -r '.[] | select(.name | startswith("${{ inputs.tf_resource_prefix }}"))')
|
||||||
|
sql_count=$(echo "$sql_res" | jq -r '.id' | wc -l)
|
||||||
|
|
||||||
|
echo "PostgreSQL Flex resources:"
|
||||||
|
pg_res=$(stackit --verbosity ${{ inputs.log_level }} --project-id "${{ inputs.project_id }}" postgresflex instance list --output-format json | jq -r '.[] | select(.name | startswith("${{ inputs.tf_resource_prefix }}"))')
|
||||||
|
pg_count=$(echo "$pg_res" | jq -r '.id' | wc -l)
|
||||||
|
|
||||||
|
echo "Number of resources found: ${sql_count} SQL Server Flex, ${pg_count} PostgreSQL Flex"
|
||||||
|
echo "count=$(( ${pg_count} + ${sql_count} ))" >> $GITHUB_OUTPUT
|
||||||
|
echo "::endgroup::"
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
- name: Set status
|
||||||
|
if: always()
|
||||||
|
id: status
|
||||||
|
run: |
|
||||||
|
status="SUCCESS"
|
||||||
|
if [[ "${{ steps.del_pg.outputs.status }}" == "FAILURE" ]]; then
|
||||||
|
status=FAILURE"
|
||||||
|
elif [[ "${{ steps.del_sql.outputs.status }}" == "FAILURE" ]]; then
|
||||||
|
status=FAILURE"
|
||||||
|
fi
|
||||||
|
echo "status=$status" >> $GITHUB_OUTPUT
|
||||||
|
shell: bash
|
||||||
148
.github/actions/notify/action.yaml
vendored
Normal file
148
.github/actions/notify/action.yaml
vendored
Normal file
|
|
@ -0,0 +1,148 @@
|
||||||
|
name: Send notification via Google Chat
|
||||||
|
description: "Sends a notification to a Google Chat room when a pull request is opened."
|
||||||
|
|
||||||
|
inputs:
|
||||||
|
webhook_url:
|
||||||
|
description: "The URL of the Google Chat webhook."
|
||||||
|
required: true
|
||||||
|
|
||||||
|
title:
|
||||||
|
description: "The title of the notification."
|
||||||
|
required: true
|
||||||
|
|
||||||
|
subtitle:
|
||||||
|
description: "The subtitle of the notification."
|
||||||
|
default: 'no subtitle provided'
|
||||||
|
|
||||||
|
image_slug:
|
||||||
|
description: "The slug of the image to be included in the notification."
|
||||||
|
default: 'git'
|
||||||
|
|
||||||
|
event_author:
|
||||||
|
description: "The author of the event."
|
||||||
|
default: 'unknown'
|
||||||
|
|
||||||
|
event_title:
|
||||||
|
description: "The title of the event."
|
||||||
|
required: true
|
||||||
|
|
||||||
|
event_body:
|
||||||
|
description: "The body of the event."
|
||||||
|
default: 'no body provided'
|
||||||
|
|
||||||
|
event_number:
|
||||||
|
description: "The number of the event."
|
||||||
|
default: 'no number provided'
|
||||||
|
|
||||||
|
event_url:
|
||||||
|
description: "The url of the event."
|
||||||
|
default: 'none'
|
||||||
|
|
||||||
|
status:
|
||||||
|
description: "The status of the event."
|
||||||
|
default: 'UNKNOWN'
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- name: Install prerequisites
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
echo "::group::apt install"
|
||||||
|
set -e
|
||||||
|
apt update
|
||||||
|
apt install -y curl jq
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
- name: Determine status color
|
||||||
|
id: status
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
case "${{ inputs.status }}" in
|
||||||
|
SUCCESS)
|
||||||
|
STATUS_COLOR="006400/228b22"
|
||||||
|
ADD='{"decoratedText": {"startIcon": {"materialIcon": {"name": "check_circle"}},"text": "<b style=\"color: green;\">SUCCESS</b>"}},'
|
||||||
|
;;
|
||||||
|
FAILURE)
|
||||||
|
STATUS_COLOR="8b0000/dc143c"
|
||||||
|
ADD='{"decoratedText": {"startIcon": {"materialIcon": {"name": "stop_circle"}},"text": "<b style=\"color: red;\">FAILURE</b>"}},'
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
STATUS_COLOR="483d8b/6495ed"
|
||||||
|
ADD=''
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
echo "color=${STATUS_COLOR}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "status_add=${ADD}" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
- name: Notify via Google Chat Webhook
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
WEBHOOK: ${{ inputs.webhook_url }}
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
|
||||||
|
PAYLOAD=$(jq -n -r \
|
||||||
|
--arg header "${{ inputs.title }}" \
|
||||||
|
--arg subtitle "${{ inputs.subtitle }}" \
|
||||||
|
--arg imgurl "https://cdn.simpleicons.org/${{ inputs.image_slug }}/${{ steps.status.outputs.color }}" \
|
||||||
|
--arg title "${{ inputs.event_title || 'no event title given' }}" \
|
||||||
|
--arg body "${{ inputs.event_body || 'no event body given' }}" \
|
||||||
|
--arg author "${{ inputs.event_author || 'no event author given' }}" \
|
||||||
|
--arg url "${{ inputs.event_url || github.repositoryUrl || github.server_url }}" \
|
||||||
|
'{ "cardsV2": [ { "cardId": "notify-${{ github.run_id }}", "card": {
|
||||||
|
"header": {
|
||||||
|
"title": "\($header)",
|
||||||
|
"subtitle": "\($subtitle)",
|
||||||
|
"imageUrl": "\($imgurl)",
|
||||||
|
"imageType": "SQUARE"
|
||||||
|
},
|
||||||
|
"sections": [
|
||||||
|
{
|
||||||
|
"header": "\($title)",
|
||||||
|
"collapsible": false,
|
||||||
|
"widgets": [
|
||||||
|
${{ steps.status.outputs.status_add }}
|
||||||
|
{
|
||||||
|
"decoratedText": {
|
||||||
|
"startIcon": {
|
||||||
|
"knownIcon": "PERSON"
|
||||||
|
},
|
||||||
|
"text": "<b>\($author)</b>"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"textParagraph": {
|
||||||
|
"text": "\($body)",
|
||||||
|
"maxLines": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgets": [
|
||||||
|
{
|
||||||
|
"buttonList": {
|
||||||
|
"buttons": [
|
||||||
|
{
|
||||||
|
"text": "View Source Event",
|
||||||
|
"type": "FILLED",
|
||||||
|
"onClick": {
|
||||||
|
"openLink": {
|
||||||
|
"url": "\($url)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}} ] }')
|
||||||
|
|
||||||
|
curl \
|
||||||
|
-X POST \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
"${{ inputs.webhook_url }}&threadKey=run${{ github.run_id }}&messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD" \
|
||||||
|
-d "${PAYLOAD}"
|
||||||
2
.github/actions/setup-cache-go/action.yaml
vendored
2
.github/actions/setup-cache-go/action.yaml
vendored
|
|
@ -10,7 +10,7 @@ inputs:
|
||||||
|
|
||||||
go-version:
|
go-version:
|
||||||
description: "go version to install"
|
description: "go version to install"
|
||||||
default: '1.25'
|
default: '1.26'
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
runs:
|
runs:
|
||||||
|
|
|
||||||
25
.github/workflows/ci_new.yaml
vendored
25
.github/workflows/ci_new.yaml
vendored
|
|
@ -28,11 +28,24 @@ jobs:
|
||||||
config:
|
config:
|
||||||
if: ${{ github.event_name != 'schedule' }}
|
if: ${{ github.event_name != 'schedule' }}
|
||||||
name: Check GoReleaser config
|
name: Check GoReleaser config
|
||||||
runs-on: ubuntu-latest
|
runs-on: stackit-docker
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v6
|
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
|
- name: Check GoReleaser
|
||||||
uses: goreleaser/goreleaser-action@v7
|
uses: goreleaser/goreleaser-action@v7
|
||||||
with:
|
with:
|
||||||
|
|
@ -40,7 +53,7 @@ jobs:
|
||||||
|
|
||||||
prepare:
|
prepare:
|
||||||
name: Prepare GO cache
|
name: Prepare GO cache
|
||||||
runs-on: ubuntu-latest
|
runs-on: stackit-docker
|
||||||
permissions:
|
permissions:
|
||||||
actions: read # Required to identify workflow run.
|
actions: read # Required to identify workflow run.
|
||||||
checks: write # Required to add status summary.
|
checks: write # Required to add status summary.
|
||||||
|
|
@ -102,7 +115,7 @@ jobs:
|
||||||
needs:
|
needs:
|
||||||
- config
|
- config
|
||||||
- prepare
|
- prepare
|
||||||
runs-on: ubuntu-latest
|
runs-on: stackit-docker
|
||||||
permissions:
|
permissions:
|
||||||
actions: read # Required to identify workflow run.
|
actions: read # Required to identify workflow run.
|
||||||
checks: write # Required to add status summary.
|
checks: write # Required to add status summary.
|
||||||
|
|
@ -185,7 +198,7 @@ jobs:
|
||||||
|
|
||||||
testing:
|
testing:
|
||||||
name: CI run tests
|
name: CI run tests
|
||||||
runs-on: ubuntu-latest
|
runs-on: stackit-docker
|
||||||
needs:
|
needs:
|
||||||
- config
|
- config
|
||||||
- prepare
|
- prepare
|
||||||
|
|
@ -278,7 +291,7 @@ jobs:
|
||||||
main:
|
main:
|
||||||
if: ${{ github.event_name != 'schedule' }}
|
if: ${{ github.event_name != 'schedule' }}
|
||||||
name: CI run build and linting
|
name: CI run build and linting
|
||||||
runs-on: ubuntu-latest
|
runs-on: stackit-docker
|
||||||
needs:
|
needs:
|
||||||
- config
|
- config
|
||||||
- prepare
|
- prepare
|
||||||
|
|
@ -329,7 +342,7 @@ jobs:
|
||||||
code_coverage:
|
code_coverage:
|
||||||
name: "Code coverage report"
|
name: "Code coverage report"
|
||||||
if: github.event_name == 'pull_request' # Do not run when workflow is triggered by push to main branch
|
if: github.event_name == 'pull_request' # Do not run when workflow is triggered by push to main branch
|
||||||
runs-on: ubuntu-latest
|
runs-on: stackit-docker
|
||||||
needs:
|
needs:
|
||||||
- main
|
- main
|
||||||
- prepare
|
- prepare
|
||||||
|
|
|
||||||
72
.github/workflows/clean_up.yaml
vendored
Normal file
72
.github/workflows/clean_up.yaml
vendored
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
name: TF Acceptance Test CleanUp
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
list_only:
|
||||||
|
description: "only list resources"
|
||||||
|
type: boolean
|
||||||
|
default: true
|
||||||
|
required: true
|
||||||
|
|
||||||
|
res_prefix:
|
||||||
|
description: "resource name prefix"
|
||||||
|
type: string
|
||||||
|
default: 'tf-acc-'
|
||||||
|
required: true
|
||||||
|
|
||||||
|
log_level:
|
||||||
|
description: 'Log Level'
|
||||||
|
required: true
|
||||||
|
default: 'warning'
|
||||||
|
type: choice
|
||||||
|
options:
|
||||||
|
- info
|
||||||
|
- warning
|
||||||
|
- debug
|
||||||
|
- error
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
clean:
|
||||||
|
name: Clean up
|
||||||
|
runs-on: stackit-docker
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
|
- name: Notify
|
||||||
|
uses: ./.github/actions/notify
|
||||||
|
with:
|
||||||
|
webhook_url: ${{ secrets.GOOGLE_WEBHOOK_URL }}
|
||||||
|
title: "[START] CLEAN UP pipeline (#${{ forgejo.run_number }})"
|
||||||
|
subtitle: "${{ forgejo.repository }}"
|
||||||
|
event_title: ${{ forgejo.event_name }}
|
||||||
|
event_author: ${{ forgejo.actor }}
|
||||||
|
event_body: "try to remove all resources with prefix <b>${{ inputs.res_prefix }}</b>"
|
||||||
|
event_number: ${{ forgejo.run_number }}
|
||||||
|
event_url: "https://tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/actions/runs/${{ forgejo.run_number }}"
|
||||||
|
|
||||||
|
- name: Clean
|
||||||
|
id: clean
|
||||||
|
uses: ./.github/actions/clean_up
|
||||||
|
with:
|
||||||
|
project_id: ${{ vars.TF_ACC_PROJECT_ID }}
|
||||||
|
region: 'eu01'
|
||||||
|
tf_resource_prefix: ${{ inputs.res_prefix }}
|
||||||
|
service_account_json_content_b64: "${{ secrets.TF_ACC_SERVICE_ACCOUNT_JSON_B64 }}"
|
||||||
|
list_only: ${{ inputs.list_only }}
|
||||||
|
log_level: ${{ inputs.log_level }}
|
||||||
|
|
||||||
|
- name: Notify
|
||||||
|
if: always()
|
||||||
|
uses: ./.github/actions/notify
|
||||||
|
with:
|
||||||
|
webhook_url: ${{ secrets.GOOGLE_WEBHOOK_URL }}
|
||||||
|
title: "[END] CLEAN UP pipeline (#${{ forgejo.run_number }})"
|
||||||
|
subtitle: "${{ forgejo.repository }}"
|
||||||
|
event_title: ${{ forgejo.event_name }}
|
||||||
|
event_author: ${{ forgejo.actor }}
|
||||||
|
event_body: "count before cleaning: ${{ steps.clean.outputs.pre_count }} <br /> count after cleaning: ${{ steps.clean.outputs.post_count }}"
|
||||||
|
event_number: ${{ forgejo.run_number }}
|
||||||
|
event_url: "https://tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/actions/runs/${{ forgejo.run_number }}"
|
||||||
|
status: ${{ steps.clean.outcome == 'success' && 'SUCCESS' || 'FAILURE' }}
|
||||||
25
.github/workflows/notify_pr.yaml
vendored
Normal file
25
.github/workflows/notify_pr.yaml
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
name: Notify on new PR
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types:
|
||||||
|
- opened
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
notify:
|
||||||
|
name: Notify via Google Chat
|
||||||
|
runs-on: stackit-docker
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
|
- name: Notify
|
||||||
|
uses: ./.github/actions/notify
|
||||||
|
with:
|
||||||
|
webhook_url: ${{ secrets.GOOGLE_WEBHOOK_URL }}
|
||||||
|
title: "New Pull Request"
|
||||||
|
event_title: "${{ github.event.pull_request.title }}"
|
||||||
|
event_author: "${{ github.event.pull_request.user.login }}"
|
||||||
|
event_body: "${{ github.event.pull_request.body || 'No description provided.' }}"
|
||||||
|
event_number: "${{ github.event.pull_request.number }}"
|
||||||
|
event_url: "${{ github.event.pull_request.html_url }}"
|
||||||
35
.github/workflows/publish.yaml
vendored
35
.github/workflows/publish.yaml
vendored
|
|
@ -3,11 +3,11 @@ name: Publish
|
||||||
run-name: Publish by @${{ github.actor }}
|
run-name: Publish by @${{ github.actor }}
|
||||||
|
|
||||||
on:
|
on:
|
||||||
#workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
push:
|
push:
|
||||||
tags:
|
tags:
|
||||||
- 'v0.*'
|
- 'v*'
|
||||||
|
|
||||||
env:
|
env:
|
||||||
GO_VERSION: "1.25"
|
GO_VERSION: "1.25"
|
||||||
|
|
@ -21,6 +21,8 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v6
|
||||||
|
with:
|
||||||
|
fetch-tags: true
|
||||||
|
|
||||||
- name: Check GoReleaser
|
- name: Check GoReleaser
|
||||||
uses: goreleaser/goreleaser-action@v7
|
uses: goreleaser/goreleaser-action@v7
|
||||||
|
|
@ -44,6 +46,20 @@ jobs:
|
||||||
|
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v6
|
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
|
- name: Setup Go
|
||||||
uses: actions/setup-go@v6
|
uses: actions/setup-go@v6
|
||||||
|
|
@ -132,6 +148,7 @@ jobs:
|
||||||
--outFile nav.md
|
--outFile nav.md
|
||||||
|
|
||||||
- name: Publish provider to S3
|
- name: Publish provider to S3
|
||||||
|
id: publish_to_s3
|
||||||
run: |
|
run: |
|
||||||
set -e
|
set -e
|
||||||
cd release/
|
cd release/
|
||||||
|
|
@ -152,3 +169,17 @@ jobs:
|
||||||
# echo "${{ github.ref_name }}" >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 -r docs ubuntu@${{ vars.DOCS_SERVER_IP }}:/srv/www/
|
||||||
scp -o StrictHostKeyChecking=no nav.md 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' }}"
|
||||||
|
|
|
||||||
4
.github/workflows/release.yaml
vendored
4
.github/workflows/release.yaml
vendored
|
|
@ -16,14 +16,14 @@ permissions:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
goreleaser:
|
goreleaser:
|
||||||
runs-on: ubuntu-latest
|
runs-on: stackit-docker
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v6
|
||||||
with:
|
with:
|
||||||
# Allow goreleaser to access older tag information.
|
# Allow goreleaser to access older tag information.
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- uses: https://code.forgejo.org/actions/setup-go@v6
|
- uses: actions/setup-go@v6
|
||||||
with:
|
with:
|
||||||
go-version-file: "go.mod"
|
go-version-file: "go.mod"
|
||||||
cache: true
|
cache: true
|
||||||
|
|
|
||||||
4
.github/workflows/renovate.yaml
vendored
4
.github/workflows/renovate.yaml
vendored
|
|
@ -8,13 +8,13 @@ on:
|
||||||
jobs:
|
jobs:
|
||||||
renovate:
|
renovate:
|
||||||
name: Renovate
|
name: Renovate
|
||||||
runs-on: ubuntu-latest
|
runs-on: stackit-docker
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
- name: Self-hosted Renovate
|
- name: Self-hosted Renovate
|
||||||
uses: renovatebot/github-action@v46.1.4
|
uses: renovatebot/github-action@v46.1.5
|
||||||
with:
|
with:
|
||||||
configurationFile: .github/renovate.json
|
configurationFile: .github/renovate.json
|
||||||
# token: ${{ secrets.RENOVATE_TOKEN }}
|
# token: ${{ secrets.RENOVATE_TOKEN }}
|
||||||
|
|
|
||||||
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: ubuntu-latest
|
runs-on: stackit-docker
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
steps:
|
steps:
|
||||||
- name: "Mark old PRs as stale"
|
- name: "Mark old PRs as stale"
|
||||||
|
|
|
||||||
81
.github/workflows/tf-acc-test.yaml
vendored
81
.github/workflows/tf-acc-test.yaml
vendored
|
|
@ -13,23 +13,59 @@ on:
|
||||||
inputs:
|
inputs:
|
||||||
enable_debug:
|
enable_debug:
|
||||||
description: "enable terraform debug logs"
|
description: "enable terraform debug logs"
|
||||||
default: 'false'
|
type: boolean
|
||||||
|
default: false
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
test_timeout_string:
|
test_timeout_string:
|
||||||
description: "string that determines the timeout (default: 45m)"
|
description: "string that determines the timeout (default: '120m')"
|
||||||
default: '90m'
|
type: string
|
||||||
|
default: '120m'
|
||||||
required: true
|
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:
|
acc_test:
|
||||||
name: Acceptance Tests
|
name: Acceptance Tests
|
||||||
runs-on: ubuntu-latest
|
runs-on: stackit-docker
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
|
- name: set start time
|
||||||
|
id: start_time
|
||||||
|
continue-on-error: true
|
||||||
|
run: |
|
||||||
|
time=$(date --rfc-3339=ns)
|
||||||
|
echo "start_time=$time" >> ${GITHUB_OUTPUT}
|
||||||
|
start=$(date +%s%N)
|
||||||
|
echo "start=$start" >> ${GITHUB_OUTPUT}
|
||||||
|
|
||||||
|
- name: Notify
|
||||||
|
uses: ./.github/actions/notify
|
||||||
|
with:
|
||||||
|
webhook_url: ${{ secrets.GOOGLE_WEBHOOK_URL }}
|
||||||
|
title: "[START] Terraform Acceptance Tests (#${{ forgejo.run_number }})"
|
||||||
|
subtitle: "${{ forgejo.event_name }} on branch ${{ forgejo.ref }}"
|
||||||
|
event_title: "started: ${{ steps.start_time.outputs.start_time }}"
|
||||||
|
event_author: ${{ forgejo.actor }}
|
||||||
|
event_body: ${{ inputs.test_file }}
|
||||||
|
event_number: ${{ forgejo.run_number }}
|
||||||
|
event_url: "https://tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/actions/runs/${{ forgejo.run_number }}"
|
||||||
|
|
||||||
- name: Run Test (workflow dispatch)
|
- name: Run Test (workflow dispatch)
|
||||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
if: ${{ forgejo.event_name == 'workflow_dispatch' }}
|
||||||
|
id: manual_run
|
||||||
|
continue-on-error: true
|
||||||
uses: ./.github/actions/acc_test
|
uses: ./.github/actions/acc_test
|
||||||
with:
|
with:
|
||||||
go-version: ${{ env.GO_VERSION }}
|
go-version: ${{ env.GO_VERSION }}
|
||||||
|
|
@ -43,9 +79,12 @@ jobs:
|
||||||
tf_acc_kek_service_account: ${{ vars.TF_ACC_KEK_SERVICE_ACCOUNT }}
|
tf_acc_kek_service_account: ${{ vars.TF_ACC_KEK_SERVICE_ACCOUNT }}
|
||||||
tf_debug: ${{ inputs.enable_debug }}
|
tf_debug: ${{ inputs.enable_debug }}
|
||||||
test_timeout_string: ${{ inputs.test_timeout_string }}
|
test_timeout_string: ${{ inputs.test_timeout_string }}
|
||||||
|
test_file: ${{ inputs.test_file }}
|
||||||
|
|
||||||
- name: Run Test (automatic)
|
- name: Run Test (automatic)
|
||||||
if: ${{ github.event_name != 'workflow_dispatch' }}
|
if: ${{ forgejo.event_name != 'workflow_dispatch' }}
|
||||||
|
id: automatic_run
|
||||||
|
continue-on-error: true
|
||||||
uses: ./.github/actions/acc_test
|
uses: ./.github/actions/acc_test
|
||||||
with:
|
with:
|
||||||
go-version: ${{ env.GO_VERSION }}
|
go-version: ${{ env.GO_VERSION }}
|
||||||
|
|
@ -57,4 +96,32 @@ jobs:
|
||||||
tf_acc_kek_key_ring_id: ${{ vars.TF_ACC_KEK_KEY_RING_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_key_version: ${{ vars.TF_ACC_KEK_KEY_VERSION }}
|
||||||
tf_acc_kek_service_account: ${{ vars.TF_ACC_KEK_SERVICE_ACCOUNT }}
|
tf_acc_kek_service_account: ${{ vars.TF_ACC_KEK_SERVICE_ACCOUNT }}
|
||||||
tf_debug: ${{ inputs.enable_debug }}
|
|
||||||
|
- 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 }}"
|
||||||
|
|
|
||||||
|
|
@ -42,10 +42,16 @@ data "stackitprivatepreview_postgresflexalpha_instance" "example" {
|
||||||
- `flavor_id` (String) The id of the instance flavor.
|
- `flavor_id` (String) The id of the instance flavor.
|
||||||
- `id` (String) internal ID
|
- `id` (String) internal ID
|
||||||
- `is_deletable` (Boolean) Whether the instance can be deleted or not.
|
- `is_deletable` (Boolean) Whether the instance can be deleted or not.
|
||||||
|
- `labels` (Map of String) Key-value pairs, 63 characters max, begin and end with an alphanumerical character,
|
||||||
|
may contain dashes (-), underscores (_), dots (.), and alphanumerics between. Key MUST be at least 1 character.
|
||||||
|
Max 64 labels
|
||||||
|
Regex for keys: ^(?=.{1,63}$)([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]$
|
||||||
|
Regex for values: ^(?=.{0,63}$)(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])*$
|
||||||
|
The stackit- prefix is reserved and cannot be used for Keys.
|
||||||
- `name` (String) The name of the instance.
|
- `name` (String) The name of the instance.
|
||||||
- `network` (Attributes) The access configuration of the instance (see [below for nested schema](#nestedatt--network))
|
- `network` (Attributes) The access configuration of the instance (see [below for nested schema](#nestedatt--network))
|
||||||
- `replicas` (Number) How many replicas the instance should have.
|
- `replicas` (Number) How many replicas the instance should have.
|
||||||
- `retention_days` (Number) How long backups are retained. The value can only be between 32 and 365 days.
|
- `retention_days` (Number) How long backups are retained. The value can only be between 32 and 90 days.
|
||||||
- `status` (String) The current status of the instance.
|
- `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))
|
- `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.
|
- `tf_original_api_id` (String) The ID of the instance.
|
||||||
|
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
---
|
|
||||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
|
||||||
page_title: "stackitprivatepreview_sqlserverflexalpha_database Data Source - stackitprivatepreview"
|
|
||||||
subcategory: ""
|
|
||||||
description: |-
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# stackitprivatepreview_sqlserverflexalpha_database (Data Source)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- schema generated by tfplugindocs -->
|
|
||||||
## Schema
|
|
||||||
|
|
||||||
### Required
|
|
||||||
|
|
||||||
- `database_name` (String) The name of the database.
|
|
||||||
- `instance_id` (String) The ID of the instance.
|
|
||||||
- `project_id` (String) The STACKIT project ID.
|
|
||||||
- `region` (String) The region which should be addressed
|
|
||||||
|
|
||||||
### Read-Only
|
|
||||||
|
|
||||||
- `collation_name` (String) The collation of the database. This database collation should match the *collation_name* of one of the collations given by the **Get database collation list** endpoint.
|
|
||||||
- `compatibility_level` (Number) CompatibilityLevel of the Database.
|
|
||||||
- `id` (String) The terraform internal identifier.
|
|
||||||
- `name` (String) The name of the database.
|
|
||||||
- `owner` (String) The owner of the database.
|
|
||||||
- `tf_original_api_id` (Number) The id of the database.
|
|
||||||
|
|
@ -1,77 +0,0 @@
|
||||||
---
|
|
||||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
|
||||||
page_title: "stackitprivatepreview_sqlserverflexalpha_instance Data Source - stackitprivatepreview"
|
|
||||||
subcategory: ""
|
|
||||||
description: |-
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# stackitprivatepreview_sqlserverflexalpha_instance (Data Source)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Example Usage
|
|
||||||
|
|
||||||
```terraform
|
|
||||||
data "stackitprivatepreview_sqlserverflexalpha_instance" "example" {
|
|
||||||
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
||||||
instance_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
<!-- schema generated by tfplugindocs -->
|
|
||||||
## Schema
|
|
||||||
|
|
||||||
### Required
|
|
||||||
|
|
||||||
- `instance_id` (String) The ID of the instance.
|
|
||||||
- `project_id` (String) The STACKIT project ID.
|
|
||||||
- `region` (String) The region which should be addressed
|
|
||||||
|
|
||||||
### Read-Only
|
|
||||||
|
|
||||||
- `backup_schedule` (String) The schedule for on what time and how often the database backup will be created. The schedule is written as a cron schedule.
|
|
||||||
- `edition` (String) Edition of the MSSQL server instance
|
|
||||||
- `encryption` (Attributes) this defines which key to use for storage encryption (see [below for nested schema](#nestedatt--encryption))
|
|
||||||
- `flavor_id` (String) The id of the instance flavor.
|
|
||||||
- `is_deletable` (Boolean) Whether the instance can be deleted or not.
|
|
||||||
- `name` (String) The name of the instance.
|
|
||||||
- `network` (Attributes) The access configuration of the instance (see [below for nested schema](#nestedatt--network))
|
|
||||||
- `replicas` (Number) How many replicas the instance should have.
|
|
||||||
- `retention_days` (Number) The days for how long the backup files should be stored before cleaned up. 30 to 365
|
|
||||||
- `status` (String)
|
|
||||||
- `storage` (Attributes) The object containing information about the storage size and class. (see [below for nested schema](#nestedatt--storage))
|
|
||||||
- `tf_original_api_id` (String) The ID of the instance.
|
|
||||||
- `version` (String) The sqlserver version used for the instance.
|
|
||||||
|
|
||||||
<a id="nestedatt--encryption"></a>
|
|
||||||
### Nested Schema for `encryption`
|
|
||||||
|
|
||||||
Read-Only:
|
|
||||||
|
|
||||||
- `kek_key_id` (String) The key identifier
|
|
||||||
- `kek_key_ring_id` (String) The keyring identifier
|
|
||||||
- `kek_key_version` (String) The key version
|
|
||||||
- `service_account` (String)
|
|
||||||
|
|
||||||
|
|
||||||
<a id="nestedatt--network"></a>
|
|
||||||
### Nested Schema for `network`
|
|
||||||
|
|
||||||
Read-Only:
|
|
||||||
|
|
||||||
- `access_scope` (String) The network access scope of the instance
|
|
||||||
|
|
||||||
⚠️ **Note:** This feature is in private preview. Supplying this object is only permitted for enabled accounts. If your account does not have access, the request will be rejected.
|
|
||||||
- `acl` (List of String) List of IPV4 cidr.
|
|
||||||
- `instance_address` (String)
|
|
||||||
- `router_address` (String)
|
|
||||||
|
|
||||||
|
|
||||||
<a id="nestedatt--storage"></a>
|
|
||||||
### Nested Schema for `storage`
|
|
||||||
|
|
||||||
Read-Only:
|
|
||||||
|
|
||||||
- `class` (String) The storage class for the storage.
|
|
||||||
- `size` (Number) The storage size in Gigabytes.
|
|
||||||
|
|
@ -1,62 +0,0 @@
|
||||||
---
|
|
||||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
|
||||||
page_title: "stackitprivatepreview_sqlserverflexalpha_user Data Source - stackitprivatepreview"
|
|
||||||
subcategory: ""
|
|
||||||
description: |-
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# stackitprivatepreview_sqlserverflexalpha_user (Data Source)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Example Usage
|
|
||||||
|
|
||||||
```terraform
|
|
||||||
data "stackitprivatepreview_sqlserverflexalpha_user" "example" {
|
|
||||||
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
||||||
instance_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
||||||
user_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
<!-- schema generated by tfplugindocs -->
|
|
||||||
## Schema
|
|
||||||
|
|
||||||
### Required
|
|
||||||
|
|
||||||
- `instance_id` (String) The ID of the instance.
|
|
||||||
- `project_id` (String) The STACKIT project ID.
|
|
||||||
- `region` (String) The region which should be addressed
|
|
||||||
|
|
||||||
### Optional
|
|
||||||
|
|
||||||
- `page` (Number) Number of the page of items list to be returned.
|
|
||||||
- `size` (Number) Number of items to be returned on each page.
|
|
||||||
- `sort` (String) Sorting of the users to be returned on each page.
|
|
||||||
|
|
||||||
### Read-Only
|
|
||||||
|
|
||||||
- `pagination` (Attributes) (see [below for nested schema](#nestedatt--pagination))
|
|
||||||
- `users` (Attributes List) List of all users inside an instance (see [below for nested schema](#nestedatt--users))
|
|
||||||
|
|
||||||
<a id="nestedatt--pagination"></a>
|
|
||||||
### Nested Schema for `pagination`
|
|
||||||
|
|
||||||
Read-Only:
|
|
||||||
|
|
||||||
- `page` (Number)
|
|
||||||
- `size` (Number)
|
|
||||||
- `sort` (String)
|
|
||||||
- `total_pages` (Number)
|
|
||||||
- `total_rows` (Number)
|
|
||||||
|
|
||||||
|
|
||||||
<a id="nestedatt--users"></a>
|
|
||||||
### Nested Schema for `users`
|
|
||||||
|
|
||||||
Read-Only:
|
|
||||||
|
|
||||||
- `status` (String) The current status of the user.
|
|
||||||
- `tf_original_api_id` (Number) The ID of the user.
|
|
||||||
- `username` (String) The name of the user.
|
|
||||||
54
docs/data-sources/sqlserverflexbeta_flavor.md
Normal file
54
docs/data-sources/sqlserverflexbeta_flavor.md
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
---
|
||||||
|
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||||
|
page_title: "stackitprivatepreview_sqlserverflexbeta_flavor Data Source - stackitprivatepreview"
|
||||||
|
subcategory: ""
|
||||||
|
description: |-
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# stackitprivatepreview_sqlserverflexbeta_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
|
||||||
|
|
||||||
|
### Required
|
||||||
|
|
||||||
|
- `cpu` (Number) The cpu count of the instance.
|
||||||
|
- `node_type` (String) defines the nodeType it can be either single or HA
|
||||||
|
- `project_id` (String) The project ID of the flavor.
|
||||||
|
- `ram` (Number) The memory of the instance in Gibibyte.
|
||||||
|
- `region` (String) The region of the flavor.
|
||||||
|
- `storage_class` (String) The memory of the instance in Gibibyte.
|
||||||
|
|
||||||
|
### Read-Only
|
||||||
|
|
||||||
|
- `description` (String) The flavor description.
|
||||||
|
- `flavor_id` (String) The id of the instance flavor.
|
||||||
|
- `id` (String) The id of the instance flavor.
|
||||||
|
- `max_gb` (Number) maximum storage which can be ordered for the flavor in Gigabyte.
|
||||||
|
- `min_gb` (Number) minimum storage which is required to order in Gigabyte.
|
||||||
|
- `storage_classes` (Attributes List) maximum storage which can be ordered for the flavor in Gigabyte. (see [below for nested schema](#nestedatt--storage_classes))
|
||||||
|
|
||||||
|
<a id="nestedatt--storage_classes"></a>
|
||||||
|
### Nested Schema for `storage_classes`
|
||||||
|
|
||||||
|
Read-Only:
|
||||||
|
|
||||||
|
- `class` (String)
|
||||||
|
- `max_io_per_sec` (Number)
|
||||||
|
- `max_through_in_mb` (Number)
|
||||||
|
|
@ -13,6 +13,33 @@ description: |-
|
||||||
## Example Usage
|
## Example Usage
|
||||||
|
|
||||||
```terraform
|
```terraform
|
||||||
|
# NOTE: flavor handling will change in future
|
||||||
|
# V2 compatible flavor usage (example without encryption)
|
||||||
|
resource "stackitprivatepreview_postgresflexalpha_instance" "example-instance" {
|
||||||
|
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||||
|
name = "example-instance"
|
||||||
|
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
|
||||||
|
backup_schedule = "0 0 * * *"
|
||||||
|
retention_days = 30
|
||||||
|
flavor = {
|
||||||
|
cpu = 2
|
||||||
|
ram = 4
|
||||||
|
}
|
||||||
|
replicas = 1
|
||||||
|
storage = {
|
||||||
|
performance_class = "premium-perf2-stackit"
|
||||||
|
size = 10
|
||||||
|
}
|
||||||
|
network = {
|
||||||
|
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
|
||||||
|
access_scope = "PUBLIC"
|
||||||
|
}
|
||||||
|
version = 17
|
||||||
|
}
|
||||||
|
|
||||||
|
# future use of flavor (implemented in V3 API)
|
||||||
|
# first determine flavor and then use the flavor_id
|
||||||
|
|
||||||
resource "stackitprivatepreview_postgresflexalpha_instance" "example-instance" {
|
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"
|
||||||
|
|
@ -60,11 +87,10 @@ 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) The schedule for when the database backup will be created. Currently, ONLY daily schedules are supported (every 24 hours). The schedule is written as a cron schedule.
|
||||||
- `flavor_id` (String) The id of the instance flavor.
|
|
||||||
- `name` (String) The name of the instance.
|
- `name` (String) The name of the instance.
|
||||||
- `network` (Attributes) The access configuration of the instance (see [below for nested schema](#nestedatt--network))
|
- `network` (Attributes) The access configuration of the instance (see [below for nested schema](#nestedatt--network))
|
||||||
- `replicas` (Number) How many replicas the instance should have.
|
- `replicas` (Number) How many replicas the instance should have.
|
||||||
- `retention_days` (Number) How long backups are retained. The value can only be between 32 and 365 days.
|
- `retention_days` (Number) How long backups are retained. The value can only be between 32 and 90 days.
|
||||||
- `storage` (Attributes) The object containing information about the storage size and class. (see [below for nested schema](#nestedatt--storage))
|
- `storage` (Attributes) The object containing information about the storage size and class. (see [below for nested schema](#nestedatt--storage))
|
||||||
- `version` (String) The Postgres version used for the instance. See [Versions Endpoint](/documentation/postgres-flex-service/version/v3alpha1#tag/Version) for supported version parameters.
|
- `version` (String) The Postgres version used for the instance. See [Versions Endpoint](/documentation/postgres-flex-service/version/v3alpha1#tag/Version) for supported version parameters.
|
||||||
|
|
||||||
|
|
@ -73,6 +99,8 @@ import {
|
||||||
- `encryption` (Attributes) The configuration for instance's volume and backup storage encryption.
|
- `encryption` (Attributes) The configuration for instance's volume and backup storage encryption.
|
||||||
|
|
||||||
⚠︝ **Note:** This feature is in private preview. Supplying this object is only permitted for enabled accounts. If your account does not have access, the request will be rejected. (see [below for nested schema](#nestedatt--encryption))
|
⚠︝ **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.
|
- `instance_id` (String) The ID of the instance.
|
||||||
- `project_id` (String) The STACKIT project ID.
|
- `project_id` (String) The STACKIT project ID.
|
||||||
- `region` (String) The region which should be addressed
|
- `region` (String) The region which should be addressed
|
||||||
|
|
@ -122,6 +150,20 @@ Required:
|
||||||
- `service_account` (String)
|
- `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>
|
<a id="nestedatt--connection_info"></a>
|
||||||
### Nested Schema for `connection_info`
|
### Nested Schema for `connection_info`
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,63 +0,0 @@
|
||||||
---
|
|
||||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
|
||||||
page_title: "stackitprivatepreview_sqlserverflexalpha_database Resource - stackitprivatepreview"
|
|
||||||
subcategory: ""
|
|
||||||
description: |-
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# stackitprivatepreview_sqlserverflexalpha_database (Resource)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Example Usage
|
|
||||||
|
|
||||||
```terraform
|
|
||||||
resource "stackitprivatepreview_sqlserverflexalpha_database" "example" {
|
|
||||||
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
||||||
instance_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
||||||
collation = ""
|
|
||||||
compatibility = "160"
|
|
||||||
name = ""
|
|
||||||
owner = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
# Only use the import statement, if you want to import a existing sqlserverflex database
|
|
||||||
import {
|
|
||||||
to = stackitprivatepreview_sqlserverflexalpha_database.import-example
|
|
||||||
id = "${var.project_id},${var.region},${var.sql_instance_id},${var.sql_user_id}"
|
|
||||||
}
|
|
||||||
|
|
||||||
import {
|
|
||||||
to = stackitprivatepreview_sqlserverflexalpha_database.import-example
|
|
||||||
identity = {
|
|
||||||
project_id = "project.id"
|
|
||||||
region = "region"
|
|
||||||
instance_id = "instance.id"
|
|
||||||
database_id = "database.id"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
<!-- schema generated by tfplugindocs -->
|
|
||||||
## Schema
|
|
||||||
|
|
||||||
### Required
|
|
||||||
|
|
||||||
- `name` (String) The name of the database.
|
|
||||||
- `owner` (String) The owner of the database.
|
|
||||||
|
|
||||||
### Optional
|
|
||||||
|
|
||||||
- `collation` (String) The collation of the database. This database collation should match the *collation_name* of one of the collations given by the **Get database collation list** endpoint.
|
|
||||||
- `compatibility` (Number) CompatibilityLevel of the Database.
|
|
||||||
- `database_name` (String) The name of the database.
|
|
||||||
- `instance_id` (String) The ID of the instance.
|
|
||||||
- `project_id` (String) The STACKIT project ID.
|
|
||||||
- `region` (String) The region which should be addressed
|
|
||||||
|
|
||||||
### Read-Only
|
|
||||||
|
|
||||||
- `collation_name` (String) The collation of the database. This database collation should match the *collation_name* of one of the collations given by the **Get database collation list** endpoint.
|
|
||||||
- `compatibility_level` (Number) CompatibilityLevel of the Database.
|
|
||||||
- `id` (Number) The id of the database.
|
|
||||||
|
|
@ -1,103 +0,0 @@
|
||||||
---
|
|
||||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
|
||||||
page_title: "stackitprivatepreview_sqlserverflexalpha_instance Resource - stackitprivatepreview"
|
|
||||||
subcategory: ""
|
|
||||||
description: |-
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# stackitprivatepreview_sqlserverflexalpha_instance (Resource)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Example Usage
|
|
||||||
|
|
||||||
```terraform
|
|
||||||
resource "stackitprivatepreview_sqlserverflexalpha_instance" "example" {
|
|
||||||
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
||||||
name = "example-instance"
|
|
||||||
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
|
|
||||||
backup_schedule = "00 00 * * *"
|
|
||||||
flavor = {
|
|
||||||
cpu = 4
|
|
||||||
ram = 16
|
|
||||||
}
|
|
||||||
storage = {
|
|
||||||
class = "class"
|
|
||||||
size = 5
|
|
||||||
}
|
|
||||||
version = 2022
|
|
||||||
}
|
|
||||||
|
|
||||||
# Only use the import statement, if you want to import an existing sqlserverflex instance
|
|
||||||
import {
|
|
||||||
to = stackitprivatepreview_sqlserverflexalpha_instance.import-example
|
|
||||||
id = "${var.project_id},${var.region},${var.sql_instance_id}"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
<!-- schema generated by tfplugindocs -->
|
|
||||||
## Schema
|
|
||||||
|
|
||||||
### Required
|
|
||||||
|
|
||||||
- `backup_schedule` (String) The schedule for on what time and how often the database backup will be created. The schedule is written as a cron schedule.
|
|
||||||
- `flavor_id` (String) The id of the instance flavor.
|
|
||||||
- `name` (String) The name of the instance.
|
|
||||||
- `network` (Attributes) the network configuration of the instance. (see [below for nested schema](#nestedatt--network))
|
|
||||||
- `retention_days` (Number) The days for how long the backup files should be stored before cleaned up. 30 to 365
|
|
||||||
- `storage` (Attributes) The object containing information about the storage size and class. (see [below for nested schema](#nestedatt--storage))
|
|
||||||
- `version` (String) The sqlserver version used for the instance.
|
|
||||||
|
|
||||||
### Optional
|
|
||||||
|
|
||||||
- `encryption` (Attributes) this defines which key to use for storage encryption (see [below for nested schema](#nestedatt--encryption))
|
|
||||||
- `instance_id` (String) The ID of the instance.
|
|
||||||
- `project_id` (String) The STACKIT project ID.
|
|
||||||
- `region` (String) The region which should be addressed
|
|
||||||
|
|
||||||
### Read-Only
|
|
||||||
|
|
||||||
- `edition` (String) Edition of the MSSQL server instance
|
|
||||||
- `id` (String) The ID of the instance.
|
|
||||||
- `is_deletable` (Boolean) Whether the instance can be deleted or not.
|
|
||||||
- `replicas` (Number) How many replicas the instance should have.
|
|
||||||
- `status` (String)
|
|
||||||
|
|
||||||
<a id="nestedatt--network"></a>
|
|
||||||
### Nested Schema for `network`
|
|
||||||
|
|
||||||
Required:
|
|
||||||
|
|
||||||
- `acl` (List of String) List of IPV4 cidr.
|
|
||||||
|
|
||||||
Optional:
|
|
||||||
|
|
||||||
- `access_scope` (String) The network access scope of the instance
|
|
||||||
|
|
||||||
⚠️ **Note:** This feature is in private preview. Supplying this object is only permitted for enabled accounts. If your account does not have access, the request will be rejected.
|
|
||||||
|
|
||||||
Read-Only:
|
|
||||||
|
|
||||||
- `instance_address` (String)
|
|
||||||
- `router_address` (String)
|
|
||||||
|
|
||||||
|
|
||||||
<a id="nestedatt--storage"></a>
|
|
||||||
### Nested Schema for `storage`
|
|
||||||
|
|
||||||
Required:
|
|
||||||
|
|
||||||
- `class` (String) The storage class for the storage.
|
|
||||||
- `size` (Number) The storage size in Gigabytes.
|
|
||||||
|
|
||||||
|
|
||||||
<a id="nestedatt--encryption"></a>
|
|
||||||
### Nested Schema for `encryption`
|
|
||||||
|
|
||||||
Required:
|
|
||||||
|
|
||||||
- `kek_key_id` (String) The key identifier
|
|
||||||
- `kek_key_ring_id` (String) The keyring identifier
|
|
||||||
- `kek_key_version` (String) The key version
|
|
||||||
- `service_account` (String)
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
---
|
|
||||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
|
||||||
page_title: "stackitprivatepreview_sqlserverflexalpha_user Resource - stackitprivatepreview"
|
|
||||||
subcategory: ""
|
|
||||||
description: |-
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# stackitprivatepreview_sqlserverflexalpha_user (Resource)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Example Usage
|
|
||||||
|
|
||||||
```terraform
|
|
||||||
resource "stackitprivatepreview_sqlserverflexalpha_user" "example" {
|
|
||||||
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
||||||
instance_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
||||||
username = "username"
|
|
||||||
roles = ["role"]
|
|
||||||
}
|
|
||||||
|
|
||||||
# Only use the import statement, if you want to import an existing sqlserverflex user
|
|
||||||
import {
|
|
||||||
to = stackitprivatepreview_sqlserverflexalpha_user.import-example
|
|
||||||
id = "${var.project_id},${var.region},${var.sql_instance_id},${var.sql_user_id}"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
<!-- schema generated by tfplugindocs -->
|
|
||||||
## Schema
|
|
||||||
|
|
||||||
### Required
|
|
||||||
|
|
||||||
- `roles` (List of String) A list containing the user roles for the instance. A list with the valid user roles can be retrieved using the List Roles endpoint.
|
|
||||||
- `username` (String) The name of the user.
|
|
||||||
|
|
||||||
### Optional
|
|
||||||
|
|
||||||
- `default_database` (String) The default database for a user of the instance.
|
|
||||||
- `instance_id` (String) The ID of the instance.
|
|
||||||
- `project_id` (String) The STACKIT project ID.
|
|
||||||
- `region` (String) The region which should be addressed
|
|
||||||
- `user_id` (Number) The ID of the user.
|
|
||||||
|
|
||||||
### Read-Only
|
|
||||||
|
|
||||||
- `host` (String) The host of the instance in which the user belongs to.
|
|
||||||
- `id` (Number) The ID of the user.
|
|
||||||
- `password` (String) The password for the user.
|
|
||||||
- `port` (Number) The port of the instance in which the user belongs to.
|
|
||||||
- `status` (String) The current status of the user.
|
|
||||||
- `uri` (String) The connection string for the user to the instance.
|
|
||||||
|
|
@ -13,6 +13,31 @@ description: |-
|
||||||
## Example Usage
|
## Example Usage
|
||||||
|
|
||||||
```terraform
|
```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
|
# without encryption and SNA
|
||||||
resource "stackitprivatepreview_sqlserverflexbeta_instance" "instance" {
|
resource "stackitprivatepreview_sqlserverflexbeta_instance" "instance" {
|
||||||
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||||
|
|
@ -97,7 +122,6 @@ import {
|
||||||
### Required
|
### 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.
|
- `backup_schedule` (String) The schedule for on what time and how often the database backup will be created. The schedule is written as a cron schedule.
|
||||||
- `flavor_id` (String) The id of the instance flavor.
|
|
||||||
- `name` (String) The name of the instance.
|
- `name` (String) The name of the instance.
|
||||||
- `network` (Attributes) the network configuration of the instance. (see [below for nested schema](#nestedatt--network))
|
- `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
|
- `retention_days` (Number) The days for how long the backup files should be stored before cleaned up. 30 to 365
|
||||||
|
|
@ -107,6 +131,8 @@ import {
|
||||||
### Optional
|
### Optional
|
||||||
|
|
||||||
- `encryption` (Attributes) this defines which key to use for storage encryption (see [below for nested schema](#nestedatt--encryption))
|
- `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.
|
- `instance_id` (String) The ID of the instance.
|
||||||
- `project_id` (String) The STACKIT project ID.
|
- `project_id` (String) The STACKIT project ID.
|
||||||
- `region` (String) The region which should be addressed
|
- `region` (String) The region which should be addressed
|
||||||
|
|
@ -156,3 +182,17 @@ Required:
|
||||||
- `kek_key_ring_id` (String) The keyring identifier
|
- `kek_key_ring_id` (String) The keyring identifier
|
||||||
- `kek_key_version` (String) The key version
|
- `kek_key_version` (String) The key version
|
||||||
- `service_account` (String)
|
- `service_account` (String)
|
||||||
|
|
||||||
|
|
||||||
|
<a id="nestedatt--flavor"></a>
|
||||||
|
### Nested Schema for `flavor`
|
||||||
|
|
||||||
|
Optional:
|
||||||
|
|
||||||
|
- `cpu` (Number, Deprecated)
|
||||||
|
- `ram` (Number, Deprecated)
|
||||||
|
|
||||||
|
Read-Only:
|
||||||
|
|
||||||
|
- `description` (String)
|
||||||
|
- `id` (String)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,30 @@
|
||||||
|
# NOTE: flavor handling will change in future
|
||||||
|
# V2 compatible flavor usage (example without encryption)
|
||||||
|
resource "stackitprivatepreview_postgresflexalpha_instance" "example-instance" {
|
||||||
|
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||||
|
name = "example-instance"
|
||||||
|
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
|
||||||
|
backup_schedule = "0 0 * * *"
|
||||||
|
retention_days = 30
|
||||||
|
flavor = {
|
||||||
|
cpu = 2
|
||||||
|
ram = 4
|
||||||
|
}
|
||||||
|
replicas = 1
|
||||||
|
storage = {
|
||||||
|
performance_class = "premium-perf2-stackit"
|
||||||
|
size = 10
|
||||||
|
}
|
||||||
|
network = {
|
||||||
|
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
|
||||||
|
access_scope = "PUBLIC"
|
||||||
|
}
|
||||||
|
version = 17
|
||||||
|
}
|
||||||
|
|
||||||
|
# future use of flavor (implemented in V3 API)
|
||||||
|
# first determine flavor and then use the flavor_id
|
||||||
|
|
||||||
resource "stackitprivatepreview_postgresflexalpha_instance" "example-instance" {
|
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"
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,28 @@
|
||||||
|
# NOTE: flavor handling will change in future
|
||||||
|
# V2 compatible flavor usage
|
||||||
|
resource "stackitprivatepreview_sqlserverflexbeta_instance" "instance" {
|
||||||
|
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||||
|
name = "example-instance"
|
||||||
|
backup_schedule = "0 3 * * *"
|
||||||
|
retention_days = 31
|
||||||
|
flavor = {
|
||||||
|
cpu = 2
|
||||||
|
ram = 4
|
||||||
|
}
|
||||||
|
storage = {
|
||||||
|
class = "premium-perf2-stackit"
|
||||||
|
size = 50
|
||||||
|
}
|
||||||
|
version = 2022
|
||||||
|
network = {
|
||||||
|
acl = ["XXX.XXX.XXX.X/XX", "XX.XXX.XX.X/XX"]
|
||||||
|
access_scope = "SNA"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# future use of flavor (implemented in V3 API)
|
||||||
|
# first determine flavor and then use the flavor_id
|
||||||
|
|
||||||
# without encryption and SNA
|
# without encryption and SNA
|
||||||
resource "stackitprivatepreview_sqlserverflexbeta_instance" "instance" {
|
resource "stackitprivatepreview_sqlserverflexbeta_instance" "instance" {
|
||||||
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||||
|
|
|
||||||
|
|
@ -172,12 +172,12 @@ func workDocs() error {
|
||||||
case "data-sources":
|
case "data-sources":
|
||||||
dataSources[matches[0][1]] = append(dataSources[matches[0][1]], ResItem{
|
dataSources[matches[0][1]] = append(dataSources[matches[0][1]], ResItem{
|
||||||
ItemName: matches[0][2],
|
ItemName: matches[0][2],
|
||||||
ItemLink: fmt.Sprintf("docs/%s/%s", entry.Name(), matches[0][0]),
|
ItemLink: fmt.Sprintf("/docs/docs/%s/%s", entry.Name(), matches[0][0]),
|
||||||
})
|
})
|
||||||
case "resources":
|
case "resources":
|
||||||
resources[matches[0][1]] = append(resources[matches[0][1]], ResItem{
|
resources[matches[0][1]] = append(resources[matches[0][1]], ResItem{
|
||||||
ItemName: matches[0][2],
|
ItemName: matches[0][2],
|
||||||
ItemLink: fmt.Sprintf("docs/%s/%s", entry.Name(), matches[0][0]),
|
ItemLink: fmt.Sprintf("/docs/docs/%s/%s", entry.Name(), matches[0][0]),
|
||||||
})
|
})
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("this should never have happened")
|
return fmt.Errorf("this should never have happened")
|
||||||
|
|
|
||||||
253
go.mod
253
go.mod
|
|
@ -1,26 +1,25 @@
|
||||||
module tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview
|
module tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview
|
||||||
|
|
||||||
go 1.25.6
|
go 1.26.2
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/SladkyCitron/slogcolor v1.8.0
|
github.com/SladkyCitron/slogcolor v1.9.0
|
||||||
github.com/golang-jwt/jwt/v5 v5.3.1
|
|
||||||
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.18.0
|
github.com/hashicorp/terraform-plugin-framework v1.19.0
|
||||||
github.com/hashicorp/terraform-plugin-framework-validators v0.19.0
|
github.com/hashicorp/terraform-plugin-framework-validators v0.19.0
|
||||||
github.com/hashicorp/terraform-plugin-go v0.30.0
|
github.com/hashicorp/terraform-plugin-go v0.31.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.14.0
|
github.com/hashicorp/terraform-plugin-testing v1.16.0
|
||||||
github.com/iancoleman/strcase v0.3.0
|
github.com/iancoleman/strcase v0.3.0
|
||||||
github.com/ivanpirog/coloredcobra v1.0.1
|
github.com/ivanpirog/coloredcobra v1.0.1
|
||||||
github.com/jarcoal/httpmock v1.4.1
|
github.com/jarcoal/httpmock v1.4.1
|
||||||
github.com/joho/godotenv v1.5.1
|
github.com/joho/godotenv v1.5.1
|
||||||
github.com/ldez/go-git-cmd-wrapper/v2 v2.9.1
|
github.com/ldez/go-git-cmd-wrapper/v2 v2.9.1
|
||||||
github.com/spf13/cobra v1.10.2
|
github.com/spf13/cobra v1.10.2
|
||||||
github.com/stackitcloud/stackit-sdk-go/core v0.22.0
|
github.com/stackitcloud/stackit-sdk-go/core v0.26.0
|
||||||
github.com/stackitcloud/stackit-sdk-go/services/postgresflex v1.4.0
|
github.com/stackitcloud/stackit-sdk-go/services/postgresflex v1.8.0
|
||||||
github.com/stackitcloud/stackit-sdk-go/services/sqlserverflex v1.5.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
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
)
|
)
|
||||||
|
|
@ -28,261 +27,77 @@ require (
|
||||||
require github.com/hashicorp/go-retryablehttp v0.7.8 // indirect
|
require github.com/hashicorp/go-retryablehttp v0.7.8 // indirect
|
||||||
|
|
||||||
require (
|
require (
|
||||||
4d63.com/gocheckcompilerdirectives v1.3.0 // indirect
|
|
||||||
4d63.com/gochecknoglobals v0.2.2 // indirect
|
|
||||||
codeberg.org/chavacava/garif v0.2.0 // indirect
|
|
||||||
codeberg.org/polyfloyd/go-errorlint v1.9.0 // indirect
|
|
||||||
dario.cat/mergo v1.0.1 // indirect
|
dario.cat/mergo v1.0.1 // indirect
|
||||||
dev.gaijin.team/go/exhaustruct/v4 v4.0.0 // indirect
|
github.com/BurntSushi/toml v1.2.1 // indirect
|
||||||
dev.gaijin.team/go/golib v0.6.0 // indirect
|
|
||||||
github.com/4meepo/tagalign v1.4.3 // indirect
|
|
||||||
github.com/Abirdcfly/dupword v0.1.7 // indirect
|
|
||||||
github.com/AdminBenni/iota-mixing v1.0.0 // indirect
|
|
||||||
github.com/AlwxSin/noinlineerr v1.0.5 // indirect
|
|
||||||
github.com/Antonboom/errname v1.1.1 // indirect
|
|
||||||
github.com/Antonboom/nilnil v1.1.1 // indirect
|
|
||||||
github.com/Antonboom/testifylint v1.6.4 // indirect
|
|
||||||
github.com/BurntSushi/toml v1.6.0 // indirect
|
|
||||||
github.com/Djarvur/go-err113 v0.1.1 // indirect
|
|
||||||
github.com/Kunde21/markdownfmt/v3 v3.1.0 // indirect
|
github.com/Kunde21/markdownfmt/v3 v3.1.0 // indirect
|
||||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||||
github.com/Masterminds/semver/v3 v3.4.0 // indirect
|
github.com/Masterminds/semver/v3 v3.2.0 // indirect
|
||||||
github.com/Masterminds/sprig/v3 v3.2.3 // indirect
|
github.com/Masterminds/sprig/v3 v3.2.3 // indirect
|
||||||
github.com/MirrexOne/unqueryvet v1.5.4 // indirect
|
github.com/ProtonMail/go-crypto v1.4.1 // indirect
|
||||||
github.com/OpenPeeDeeP/depguard/v2 v2.2.1 // indirect
|
|
||||||
github.com/ProtonMail/go-crypto v1.4.0 // indirect
|
|
||||||
github.com/agext/levenshtein v1.2.3 // indirect
|
github.com/agext/levenshtein v1.2.3 // indirect
|
||||||
github.com/alecthomas/chroma/v2 v2.23.1 // indirect
|
|
||||||
github.com/alecthomas/go-check-sumtype v0.3.1 // indirect
|
|
||||||
github.com/alexkohler/nakedret/v2 v2.0.6 // indirect
|
|
||||||
github.com/alexkohler/prealloc v1.1.0 // indirect
|
|
||||||
github.com/alfatraining/structtag v1.0.0 // indirect
|
|
||||||
github.com/alingse/asasalint v0.0.11 // indirect
|
|
||||||
github.com/alingse/nilnesserr v0.2.0 // indirect
|
|
||||||
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
|
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
|
||||||
github.com/armon/go-radix v1.0.0 // indirect
|
github.com/armon/go-radix v1.0.0 // indirect
|
||||||
github.com/ashanbrown/forbidigo/v2 v2.3.0 // indirect
|
|
||||||
github.com/ashanbrown/makezero/v2 v2.1.0 // indirect
|
|
||||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
|
||||||
github.com/bgentry/speakeasy v0.1.0 // indirect
|
github.com/bgentry/speakeasy v0.1.0 // indirect
|
||||||
github.com/bkielbasa/cyclop v1.2.3 // indirect
|
github.com/bmatcuk/doublestar/v4 v4.10.0 // indirect
|
||||||
github.com/blizzy78/varnamelen v0.8.0 // indirect
|
|
||||||
github.com/bmatcuk/doublestar/v4 v4.9.1 // indirect
|
|
||||||
github.com/bombsimon/wsl/v4 v4.7.0 // indirect
|
|
||||||
github.com/bombsimon/wsl/v5 v5.6.0 // indirect
|
|
||||||
github.com/breml/bidichk v0.3.3 // indirect
|
|
||||||
github.com/breml/errchkjson v0.4.1 // indirect
|
|
||||||
github.com/butuzov/ireturn v0.4.0 // indirect
|
|
||||||
github.com/butuzov/mirror v1.3.0 // indirect
|
|
||||||
github.com/catenacyber/perfsprint v0.10.1 // indirect
|
|
||||||
github.com/ccojocar/zxcvbn-go v1.0.4 // indirect
|
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
|
||||||
github.com/charithe/durationcheck v0.0.11 // indirect
|
|
||||||
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect
|
|
||||||
github.com/charmbracelet/lipgloss v1.1.0 // indirect
|
|
||||||
github.com/charmbracelet/x/ansi v0.10.1 // indirect
|
|
||||||
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect
|
|
||||||
github.com/charmbracelet/x/term v0.2.1 // indirect
|
|
||||||
github.com/ckaznocha/intrange v0.3.1 // indirect
|
|
||||||
github.com/cloudflare/circl v1.6.3 // indirect
|
github.com/cloudflare/circl v1.6.3 // indirect
|
||||||
github.com/curioswitch/go-reassign v0.3.0 // indirect
|
github.com/fatih/color v1.19.0 // indirect
|
||||||
github.com/daixiang0/gci v0.13.7 // indirect
|
github.com/golang-jwt/jwt/v5 v5.3.1 // indirect
|
||||||
github.com/dave/dst v0.27.3 // indirect
|
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
|
||||||
github.com/denis-tingaikin/go-header v0.5.0 // indirect
|
|
||||||
github.com/dlclark/regexp2 v1.11.5 // indirect
|
|
||||||
github.com/ettle/strcase v0.2.0 // indirect
|
|
||||||
github.com/fatih/color v1.18.0 // indirect
|
|
||||||
github.com/fatih/structtag v1.2.0 // indirect
|
|
||||||
github.com/firefart/nonamedreturns v1.0.6 // indirect
|
|
||||||
github.com/fsnotify/fsnotify v1.5.4 // indirect
|
|
||||||
github.com/fzipp/gocyclo v0.6.0 // indirect
|
|
||||||
github.com/ghostiam/protogetter v0.3.20 // indirect
|
|
||||||
github.com/go-critic/go-critic v0.14.3 // indirect
|
|
||||||
github.com/go-toolsmith/astcast v1.1.0 // indirect
|
|
||||||
github.com/go-toolsmith/astcopy v1.1.0 // indirect
|
|
||||||
github.com/go-toolsmith/astequal v1.2.0 // indirect
|
|
||||||
github.com/go-toolsmith/astfmt v1.1.0 // indirect
|
|
||||||
github.com/go-toolsmith/astp v1.1.0 // indirect
|
|
||||||
github.com/go-toolsmith/strparse v1.1.0 // indirect
|
|
||||||
github.com/go-toolsmith/typep v1.1.0 // indirect
|
|
||||||
github.com/go-viper/mapstructure/v2 v2.5.0 // indirect
|
|
||||||
github.com/go-xmlfmt/xmlfmt v1.1.3 // indirect
|
|
||||||
github.com/gobwas/glob v0.2.3 // indirect
|
|
||||||
github.com/godoc-lint/godoc-lint v0.11.2 // indirect
|
|
||||||
github.com/gofrs/flock v0.13.0 // indirect
|
|
||||||
github.com/golang/protobuf v1.5.4 // indirect
|
github.com/golang/protobuf v1.5.4 // indirect
|
||||||
github.com/golangci/asciicheck v0.5.0 // indirect
|
|
||||||
github.com/golangci/dupl v0.0.0-20250308024227-f665c8d69b32 // indirect
|
|
||||||
github.com/golangci/go-printf-func-name v0.1.1 // indirect
|
|
||||||
github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d // indirect
|
|
||||||
github.com/golangci/golangci-lint/v2 v2.11.2 // indirect
|
|
||||||
github.com/golangci/golines v0.15.0 // indirect
|
|
||||||
github.com/golangci/misspell v0.8.0 // indirect
|
|
||||||
github.com/golangci/plugin-module-register v0.1.2 // indirect
|
|
||||||
github.com/golangci/revgrep v0.8.0 // indirect
|
|
||||||
github.com/golangci/swaggoswag v0.0.0-20250504205917-77f2aca3143e // indirect
|
|
||||||
github.com/golangci/unconvert v0.0.0-20250410112200-a129a6e6413e // indirect
|
|
||||||
github.com/gordonklaus/ineffassign v0.2.0 // indirect
|
|
||||||
github.com/gostaticanalysis/analysisutil v0.7.1 // indirect
|
|
||||||
github.com/gostaticanalysis/comment v1.5.0 // indirect
|
|
||||||
github.com/gostaticanalysis/forcetypeassert v0.2.0 // indirect
|
|
||||||
github.com/gostaticanalysis/nilerr v0.1.2 // indirect
|
|
||||||
github.com/hashicorp/cli v1.1.7 // indirect
|
github.com/hashicorp/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-immutable-radix/v2 v2.1.0 // 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.7.0 // indirect
|
github.com/hashicorp/go-plugin v1.8.0 // indirect
|
||||||
github.com/hashicorp/go-uuid v1.0.3 // indirect
|
github.com/hashicorp/go-uuid v1.0.3 // indirect
|
||||||
github.com/hashicorp/go-version v1.8.0 // indirect
|
github.com/hashicorp/go-version v1.9.0 // indirect
|
||||||
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
github.com/hashicorp/hc-install v0.9.5 // indirect
|
||||||
github.com/hashicorp/hc-install v0.9.3 // indirect
|
|
||||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
|
||||||
github.com/hashicorp/hcl/v2 v2.24.0 // indirect
|
github.com/hashicorp/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.0 // indirect
|
github.com/hashicorp/terraform-exec v0.25.2 // indirect
|
||||||
github.com/hashicorp/terraform-json v0.27.2 // indirect
|
github.com/hashicorp/terraform-json v0.27.3-0.20260213134036-298b8f6b673a // indirect
|
||||||
github.com/hashicorp/terraform-plugin-docs v0.24.0 // indirect
|
github.com/hashicorp/terraform-plugin-docs v0.25.0 // indirect
|
||||||
github.com/hashicorp/terraform-plugin-sdk/v2 v2.39.0 // indirect
|
github.com/hashicorp/terraform-plugin-sdk/v2 v2.40.1 // indirect
|
||||||
github.com/hashicorp/terraform-registry-address v0.4.0 // indirect
|
github.com/hashicorp/terraform-registry-address v0.4.0 // indirect
|
||||||
github.com/hashicorp/terraform-svchost v0.2.1 // indirect
|
github.com/hashicorp/terraform-svchost v0.2.1 // indirect
|
||||||
github.com/hashicorp/yamux v0.1.2 // indirect
|
github.com/hashicorp/yamux v0.1.2 // indirect
|
||||||
github.com/hexops/gotextdiff v1.0.3 // indirect
|
|
||||||
github.com/huandu/xstrings v1.3.3 // indirect
|
github.com/huandu/xstrings v1.3.3 // indirect
|
||||||
github.com/imdario/mergo v0.3.15 // indirect
|
github.com/imdario/mergo v0.3.15 // indirect
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
github.com/jgautheron/goconst v1.8.2 // indirect
|
|
||||||
github.com/jingyugao/rowserrcheck v1.1.1 // indirect
|
|
||||||
github.com/jjti/go-spancheck v0.6.5 // indirect
|
|
||||||
github.com/julz/importas v0.2.0 // indirect
|
|
||||||
github.com/karamaru-alpha/copyloopvar v1.2.2 // indirect
|
|
||||||
github.com/kisielk/errcheck v1.10.0 // indirect
|
|
||||||
github.com/kkHAIKE/contextcheck v1.1.6 // indirect
|
|
||||||
github.com/kr/text v0.2.0 // indirect
|
|
||||||
github.com/kulti/thelper v0.7.1 // indirect
|
|
||||||
github.com/kunwardeep/paralleltest v1.0.15 // indirect
|
|
||||||
github.com/lasiar/canonicalheader v1.1.2 // indirect
|
|
||||||
github.com/ldez/exptostd v0.4.5 // indirect
|
|
||||||
github.com/ldez/gomoddirectives v0.8.0 // indirect
|
|
||||||
github.com/ldez/grignotin v0.10.1 // indirect
|
|
||||||
github.com/ldez/structtags v0.6.1 // indirect
|
|
||||||
github.com/ldez/tagliatelle v0.7.2 // indirect
|
|
||||||
github.com/ldez/usetesting v0.5.0 // indirect
|
|
||||||
github.com/leonklingele/grouper v1.1.2 // indirect
|
|
||||||
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
|
||||||
github.com/macabu/inamedparam v0.2.0 // indirect
|
|
||||||
github.com/magiconair/properties v1.8.6 // indirect
|
|
||||||
github.com/manuelarte/embeddedstructfieldcheck v0.4.0 // indirect
|
|
||||||
github.com/manuelarte/funcorder v0.5.0 // indirect
|
|
||||||
github.com/maratori/testableexamples v1.0.1 // indirect
|
|
||||||
github.com/maratori/testpackage v1.1.2 // indirect
|
|
||||||
github.com/matoous/godox v1.1.0 // indirect
|
|
||||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
github.com/mattn/go-isatty v0.0.22 // indirect
|
||||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
github.com/mattn/go-runewidth v0.0.9 // indirect
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
|
|
||||||
github.com/mgechev/revive v1.15.0 // indirect
|
|
||||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
|
||||||
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
|
github.com/mitchellh/go-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/moricho/tparallel v0.3.2 // indirect
|
|
||||||
github.com/muesli/termenv v0.16.0 // indirect
|
|
||||||
github.com/nakabonne/nestif v0.3.1 // indirect
|
|
||||||
github.com/nishanths/exhaustive v0.12.0 // indirect
|
|
||||||
github.com/nishanths/predeclared v0.2.2 // indirect
|
|
||||||
github.com/nunnatsa/ginkgolinter v0.23.0 // indirect
|
|
||||||
github.com/oklog/run v1.2.0 // indirect
|
github.com/oklog/run v1.2.0 // indirect
|
||||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
|
||||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
|
||||||
github.com/posener/complete v1.2.3 // indirect
|
github.com/posener/complete v1.2.3 // indirect
|
||||||
github.com/prometheus/client_golang v1.12.1 // indirect
|
|
||||||
github.com/prometheus/client_model v0.2.0 // indirect
|
|
||||||
github.com/prometheus/common v0.32.1 // indirect
|
|
||||||
github.com/prometheus/procfs v0.7.3 // indirect
|
|
||||||
github.com/quasilyte/go-ruleguard v0.4.5 // indirect
|
|
||||||
github.com/quasilyte/go-ruleguard/dsl v0.3.23 // indirect
|
|
||||||
github.com/quasilyte/gogrep v0.5.0 // indirect
|
|
||||||
github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect
|
|
||||||
github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect
|
|
||||||
github.com/raeperd/recvcheck v0.2.0 // indirect
|
|
||||||
github.com/rivo/uniseg v0.4.7 // indirect
|
|
||||||
github.com/rogpeppe/go-internal v1.14.1 // indirect
|
|
||||||
github.com/ryancurrah/gomodguard v1.4.1 // indirect
|
|
||||||
github.com/ryanrolds/sqlclosecheck v0.5.1 // indirect
|
|
||||||
github.com/sanposhiho/wastedassign/v2 v2.1.0 // indirect
|
|
||||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect
|
|
||||||
github.com/sashamelentyev/interfacebloat v1.1.0 // indirect
|
|
||||||
github.com/sashamelentyev/usestdlibvars v1.29.0 // indirect
|
|
||||||
github.com/securego/gosec/v2 v2.24.7 // indirect
|
|
||||||
github.com/shopspring/decimal v1.3.1 // indirect
|
github.com/shopspring/decimal v1.3.1 // indirect
|
||||||
github.com/sirupsen/logrus v1.9.4 // indirect
|
|
||||||
github.com/sivchari/containedctx v1.0.3 // indirect
|
|
||||||
github.com/sonatard/noctx v0.5.0 // indirect
|
|
||||||
github.com/sourcegraph/go-diff v0.7.0 // indirect
|
|
||||||
github.com/spf13/afero v1.15.0 // indirect
|
|
||||||
github.com/spf13/cast v1.5.0 // indirect
|
github.com/spf13/cast v1.5.0 // indirect
|
||||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
|
||||||
github.com/spf13/pflag v1.0.10 // indirect
|
github.com/spf13/pflag v1.0.10 // indirect
|
||||||
github.com/spf13/viper v1.12.0 // indirect
|
|
||||||
github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect
|
|
||||||
github.com/stbenjam/no-sprintf-host-port v0.3.1 // indirect
|
|
||||||
github.com/stretchr/objx v0.5.2 // indirect
|
|
||||||
github.com/stretchr/testify v1.11.1 // indirect
|
github.com/stretchr/testify v1.11.1 // indirect
|
||||||
github.com/subosito/gotenv v1.4.1 // indirect
|
|
||||||
github.com/tetafro/godot v1.5.4 // indirect
|
|
||||||
github.com/timakin/bodyclose v0.0.0-20241222091800-1db5c5ca4d67 // indirect
|
|
||||||
github.com/timonwong/loggercheck v0.11.0 // indirect
|
|
||||||
github.com/tomarrell/wrapcheck/v2 v2.12.0 // indirect
|
|
||||||
github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect
|
|
||||||
github.com/ultraware/funlen v0.2.0 // indirect
|
|
||||||
github.com/ultraware/whitespace v0.2.0 // indirect
|
|
||||||
github.com/uudashr/gocognit v1.2.1 // indirect
|
|
||||||
github.com/uudashr/iface v1.4.1 // indirect
|
|
||||||
github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect
|
github.com/vmihailenco/msgpack 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/xen0n/gosmopolitan v1.3.0 // indirect
|
|
||||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
|
|
||||||
github.com/yagipy/maintidx v1.0.0 // indirect
|
|
||||||
github.com/yeya24/promlinter v0.3.0 // indirect
|
|
||||||
github.com/ykadowak/zerologlint v0.1.5 // indirect
|
|
||||||
github.com/yuin/goldmark v1.7.7 // indirect
|
github.com/yuin/goldmark v1.7.7 // indirect
|
||||||
github.com/yuin/goldmark-meta v1.1.0 // indirect
|
github.com/yuin/goldmark-meta v1.1.0 // indirect
|
||||||
github.com/zclconf/go-cty v1.18.0 // indirect
|
github.com/zclconf/go-cty v1.18.1 // indirect
|
||||||
gitlab.com/bosi/decorder v0.4.2 // indirect
|
|
||||||
go-simpler.org/musttag v0.14.0 // indirect
|
|
||||||
go-simpler.org/sloglint v0.11.1 // indirect
|
|
||||||
go.abhg.dev/goldmark/frontmatter v0.2.0 // indirect
|
go.abhg.dev/goldmark/frontmatter v0.2.0 // indirect
|
||||||
go.augendre.info/arangolint v0.4.0 // indirect
|
golang.org/x/crypto v0.50.0 // indirect
|
||||||
go.augendre.info/fatcontext v0.9.0 // indirect
|
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect
|
||||||
go.uber.org/multierr v1.10.0 // indirect
|
golang.org/x/mod v0.35.0 // indirect
|
||||||
go.uber.org/zap v1.27.0 // indirect
|
golang.org/x/net v0.53.0 // indirect
|
||||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
golang.org/x/sync v0.20.0 // indirect
|
||||||
golang.org/x/crypto v0.48.0 // indirect
|
golang.org/x/sys v0.43.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect
|
golang.org/x/text v0.36.0 // indirect
|
||||||
golang.org/x/exp/typeparams v0.0.0-20260209203927-2842357ff358 // indirect
|
golang.org/x/tools v0.44.0 // indirect
|
||||||
golang.org/x/mod v0.33.0 // indirect
|
|
||||||
golang.org/x/net v0.51.0 // indirect
|
|
||||||
golang.org/x/sync v0.19.0 // indirect
|
|
||||||
golang.org/x/sys v0.41.0 // indirect
|
|
||||||
golang.org/x/text v0.34.0 // indirect
|
|
||||||
golang.org/x/tools v0.42.0 // indirect
|
|
||||||
google.golang.org/appengine v1.6.8 // indirect
|
google.golang.org/appengine v1.6.8 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20260504160031-60b97b32f348 // indirect
|
||||||
google.golang.org/grpc v1.79.2 // indirect
|
google.golang.org/grpc v1.81.0 // indirect
|
||||||
google.golang.org/protobuf v1.36.11 // indirect
|
google.golang.org/protobuf v1.36.11 // indirect
|
||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
honnef.co/go/tools v0.7.0 // indirect
|
|
||||||
mvdan.cc/gofumpt v0.9.2 // indirect
|
|
||||||
mvdan.cc/unparam v0.0.0-20251027182757-5beb8c8f8f15 // indirect
|
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,101 +0,0 @@
|
||||||
# resource "stackit_kms_keyring" "keyring001" {
|
|
||||||
# project_id = var.project_id
|
|
||||||
# display_name = "msh-keyring-sna01"
|
|
||||||
# description = "This is a test keyring for private endpoints"
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
# resource "stackit_kms_key" "key001" {
|
|
||||||
# project_id = var.project_id
|
|
||||||
# keyring_id = stackit_kms_keyring.keyring001.keyring_id
|
|
||||||
# display_name = "msh-key-sna01"
|
|
||||||
# protection = "software"
|
|
||||||
# algorithm = "aes_256_gcm"
|
|
||||||
# purpose = "symmetric_encrypt_decrypt"
|
|
||||||
# access_scope = "SNA"
|
|
||||||
# }
|
|
||||||
|
|
||||||
data "stackitprivatepreview_sqlserverflexbeta_flavor" "sqlserver_flavor" {
|
|
||||||
project_id = var.project_id
|
|
||||||
region = "eu01"
|
|
||||||
cpu = 4
|
|
||||||
ram = 16
|
|
||||||
node_type = "Single"
|
|
||||||
storage_class = "premium-perf2-stackit"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "stackitprivatepreview_sqlserverflexbeta_instance" "msh-sna-001" {
|
|
||||||
project_id = var.project_id
|
|
||||||
name = "msh-sna-001"
|
|
||||||
backup_schedule = "0 3 * * *"
|
|
||||||
retention_days = 31
|
|
||||||
flavor_id = data.stackitprivatepreview_sqlserverflexbeta_flavor.sqlserver_flavor.flavor_id
|
|
||||||
storage = {
|
|
||||||
class = "premium-perf2-stackit"
|
|
||||||
size = 50
|
|
||||||
}
|
|
||||||
version = 2022
|
|
||||||
encryption = {
|
|
||||||
kek_key_version = 1
|
|
||||||
kek_key_id = var.key_id
|
|
||||||
kek_key_ring_id = var.keyring_id
|
|
||||||
service_account = var.sa_email
|
|
||||||
}
|
|
||||||
network = {
|
|
||||||
acl = ["0.0.0.0/0", "193.148.160.0/19"]
|
|
||||||
access_scope = "SNA"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#resource "stackitprivatepreview_sqlserverflexbeta_instance" "msh-nosna-001" {
|
|
||||||
# project_id = var.project_id
|
|
||||||
# name = "msh-nosna-001"
|
|
||||||
# backup_schedule = "0 3 * * *"
|
|
||||||
# retention_days = 31
|
|
||||||
# flavor_id = data.stackitprivatepreview_sqlserverflexbeta_flavor.sqlserver_flavor.flavor_id
|
|
||||||
# storage = {
|
|
||||||
# class = "premium-perf2-stackit"
|
|
||||||
# size = 50
|
|
||||||
# }
|
|
||||||
# version = 2022
|
|
||||||
# # encryption = {
|
|
||||||
# # #key_id = stackit_kms_key.key.key_id
|
|
||||||
# # #keyring_id = stackit_kms_keyring.keyring.keyring_id
|
|
||||||
# # #key_version = 1
|
|
||||||
# # #key_id = var.key_id
|
|
||||||
# # # key with scope public
|
|
||||||
# # key_id = "fe039bcf-8d7b-431a-801d-9e81371a6b7b"
|
|
||||||
# # keyring_id = var.keyring_id
|
|
||||||
# # key_version = var.key_version
|
|
||||||
# # service_account = var.sa_email
|
|
||||||
# # }
|
|
||||||
# network = {
|
|
||||||
# acl = ["0.0.0.0/0", "193.148.160.0/19"]
|
|
||||||
# access_scope = "PUBLIC"
|
|
||||||
# }
|
|
||||||
#}
|
|
||||||
|
|
||||||
# data "stackitprivatepreview_sqlserverflexbeta_instance" "test" {
|
|
||||||
# project_id = var.project_id
|
|
||||||
# instance_id = var.instance_id
|
|
||||||
# region = "eu01"
|
|
||||||
# }
|
|
||||||
|
|
||||||
# output "test" {
|
|
||||||
# value = data.stackitprivatepreview_sqlserverflexbeta_instance.test
|
|
||||||
# }
|
|
||||||
|
|
||||||
resource "stackitprivatepreview_sqlserverflexbeta_user" "ptlsdbadminuser" {
|
|
||||||
project_id = var.project_id
|
|
||||||
instance_id = stackitprivatepreview_sqlserverflexbeta_instance.msh-sna-001.instance_id
|
|
||||||
username = var.db_admin_username
|
|
||||||
#roles = ["##STACKIT_LoginManager##", "##STACKIT_DatabaseManager##"]
|
|
||||||
roles = ["##STACKIT_LoginManager##"]
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "stackitprivatepreview_sqlserverflexbeta_user" "ptlsdbuser" {
|
|
||||||
project_id = var.project_id
|
|
||||||
instance_id = stackitprivatepreview_sqlserverflexbeta_instance.msh-sna-001.instance_id
|
|
||||||
username = var.db_username
|
|
||||||
roles = ["##STACKIT_LoginManager##"]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -13,7 +13,11 @@ resource "stackitprivatepreview_postgresflexalpha_instance" "msh-sna-pe-example"
|
||||||
name = "mshpetest2"
|
name = "mshpetest2"
|
||||||
backup_schedule = "0 0 * * *"
|
backup_schedule = "0 0 * * *"
|
||||||
retention_days = 45
|
retention_days = 45
|
||||||
flavor_id = data.stackitprivatepreview_postgresflexalpha_flavor.pgsql_flavor.flavor_id
|
# flavor_id = data.stackitprivatepreview_postgresflexalpha_flavor.pgsql_flavor.flavor_id
|
||||||
|
flavor = {
|
||||||
|
cpu = 2
|
||||||
|
ram = 4
|
||||||
|
}
|
||||||
replicas = 1
|
replicas = 1
|
||||||
storage = {
|
storage = {
|
||||||
# class = "premium-perf2-stackit"
|
# class = "premium-perf2-stackit"
|
||||||
|
|
@ -66,7 +70,8 @@ resource "stackitprivatepreview_postgresflexalpha_user" "ptlsdbadminuser" {
|
||||||
project_id = var.project_id
|
project_id = var.project_id
|
||||||
instance_id = stackitprivatepreview_postgresflexalpha_instance.msh-sna-pe-example.instance_id
|
instance_id = stackitprivatepreview_postgresflexalpha_instance.msh-sna-pe-example.instance_id
|
||||||
name = var.db_admin_username
|
name = var.db_admin_username
|
||||||
roles = ["createdb", "login", "login"]
|
roles = ["createdb", "login"]
|
||||||
|
# roles = ["createdb", "login", "login"]
|
||||||
# roles = ["createdb", "login", "createrole"]
|
# roles = ["createdb", "login", "createrole"]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -110,7 +115,11 @@ output "psql_user_password" {
|
||||||
sensitive = true
|
sensitive = true
|
||||||
}
|
}
|
||||||
|
|
||||||
output "psql_user_conn" {
|
# output "psql_user_conn" {
|
||||||
value = stackitprivatepreview_postgresflexalpha_user.ptlsdbuser.connection_string
|
# value = stackitprivatepreview_postgresflexalpha_user.ptlsdbuser.connection.host
|
||||||
sensitive = true
|
# sensitive = true
|
||||||
|
# }
|
||||||
|
|
||||||
|
output "determined_flavor_id" {
|
||||||
|
value = stackitprivatepreview_postgresflexalpha_instance.msh-sna-pe-example.flavor_id
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ./tf.sh apply > >(tee -a stdout.log) 2> >(tee -a stderr.log >&2)
|
# ./tf.sh apply > >(tee -a stdout.log) 2> >(tee -a stderr.log >&2)
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
|
|
@ -12,7 +10,8 @@ usage() {
|
||||||
[ $# -eq 0 ] && usage
|
[ $# -eq 0 ] && usage
|
||||||
|
|
||||||
CONFIG_FOLDER=$(dirname "$0")
|
CONFIG_FOLDER=$(dirname "$0")
|
||||||
BINARY=terraform
|
# BINARY=terraform
|
||||||
|
BINARY=tofu
|
||||||
|
|
||||||
ADD=""
|
ADD=""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ provider:
|
||||||
name: stackitprivatepreview
|
name: stackitprivatepreview
|
||||||
|
|
||||||
data_sources:
|
data_sources:
|
||||||
collation:
|
collations:
|
||||||
read:
|
read:
|
||||||
path: /v3beta1/projects/{projectId}/regions/{region}/instances/{instanceId}/collations
|
path: /v3beta1/projects/{projectId}/regions/{region}/instances/{instanceId}/collations
|
||||||
method: GET
|
method: GET
|
||||||
|
|
@ -3,7 +3,7 @@ provider:
|
||||||
name: stackitprivatepreview
|
name: stackitprivatepreview
|
||||||
|
|
||||||
data_sources:
|
data_sources:
|
||||||
version:
|
versions:
|
||||||
read:
|
read:
|
||||||
path: /v3beta1/projects/{projectId}/regions/{region}/versions
|
path: /v3beta1/projects/{projectId}/regions/{region}/versions
|
||||||
method: GET
|
method: GET
|
||||||
|
|
|
||||||
|
|
@ -209,8 +209,8 @@ func (r *databaseResource) Create(
|
||||||
)
|
)
|
||||||
|
|
||||||
database, err := postgresflexalphaWait.GetDatabaseByIdWaitHandler(ctx, r.client.DefaultAPI, projectID, instanceID, region, databaseID).
|
database, err := postgresflexalphaWait.GetDatabaseByIdWaitHandler(ctx, r.client.DefaultAPI, projectID, instanceID, region, databaseID).
|
||||||
SetTimeout(15 * time.Minute).
|
SetTimeout(30 * time.Minute).
|
||||||
SetSleepBeforeWait(15 * time.Second).
|
SetSleepBeforeWait(10 * time.Second).
|
||||||
WaitWithContext(ctx)
|
WaitWithContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
core.LogAndAddError(
|
core.LogAndAddError(
|
||||||
|
|
@ -279,8 +279,8 @@ func (r *databaseResource) Read(
|
||||||
)
|
)
|
||||||
|
|
||||||
databaseResp, err := postgresflexalphaWait.GetDatabaseByIdWaitHandler(ctx, r.client.DefaultAPI, projectID, instanceID, region, databaseID).
|
databaseResp, err := postgresflexalphaWait.GetDatabaseByIdWaitHandler(ctx, r.client.DefaultAPI, projectID, instanceID, region, databaseID).
|
||||||
SetTimeout(15 * time.Minute).
|
SetTimeout(30 * time.Minute).
|
||||||
SetSleepBeforeWait(15 * time.Second).
|
SetSleepBeforeWait(10 * time.Second).
|
||||||
WaitWithContext(ctx)
|
WaitWithContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
core.LogAndAddError(
|
core.LogAndAddError(
|
||||||
|
|
@ -386,8 +386,8 @@ func (r *databaseResource) Update(
|
||||||
ctx = core.LogResponse(ctx)
|
ctx = core.LogResponse(ctx)
|
||||||
|
|
||||||
databaseResp, err := postgresflexalphaWait.GetDatabaseByIdWaitHandler(ctx, r.client.DefaultAPI, projectId, instanceId, region, databaseId).
|
databaseResp, err := postgresflexalphaWait.GetDatabaseByIdWaitHandler(ctx, r.client.DefaultAPI, projectId, instanceId, region, databaseId).
|
||||||
SetTimeout(15 * time.Minute).
|
SetTimeout(30 * time.Minute).
|
||||||
SetSleepBeforeWait(15 * time.Second).
|
SetSleepBeforeWait(10 * time.Second).
|
||||||
WaitWithContext(ctx)
|
WaitWithContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
core.LogAndAddError(ctx, &resp.Diagnostics, "error updating database", err.Error())
|
core.LogAndAddError(ctx, &resp.Diagnostics, "error updating database", err.Error())
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import (
|
||||||
"github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v3alpha1api"
|
"github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v3alpha1api"
|
||||||
|
|
||||||
"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/conversion"
|
||||||
postgresflexalphaGen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/flavors/datasources_gen"
|
postgresflexalphaGen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/flavor/datasources_gen"
|
||||||
postgresflexUtils "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/utils"
|
postgresflexUtils "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/utils"
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
|
||||||
|
|
||||||
|
|
@ -220,14 +220,24 @@ func (r *flavorDataSource) Read(ctx context.Context, req datasource.ReadRequest,
|
||||||
} else {
|
} else {
|
||||||
var scList []attr.Value
|
var scList []attr.Value
|
||||||
for _, sc := range f.StorageClasses {
|
for _, sc := range f.StorageClasses {
|
||||||
|
mIop := types.Int32Null()
|
||||||
|
if val, ok := sc.GetMaxIoPerSecOk(); ok {
|
||||||
|
mIop = types.Int32Value(*val)
|
||||||
|
}
|
||||||
|
|
||||||
|
mThrough := types.Int32Null()
|
||||||
|
if val, ok := sc.GetMaxThroughInMbOk(); ok {
|
||||||
|
mThrough = types.Int32Value(*val)
|
||||||
|
}
|
||||||
|
|
||||||
scList = append(
|
scList = append(
|
||||||
scList,
|
scList,
|
||||||
postgresflexalphaGen.NewStorageClassesValueMust(
|
postgresflexalphaGen.NewStorageClassesValueMust(
|
||||||
postgresflexalphaGen.StorageClassesValue{}.AttributeTypes(ctx),
|
postgresflexalphaGen.StorageClassesValue{}.AttributeTypes(ctx),
|
||||||
map[string]attr.Value{
|
map[string]attr.Value{
|
||||||
"class": types.StringValue(sc.Class),
|
"class": types.StringValue(sc.Class),
|
||||||
"max_io_per_sec": types.Int32Value(sc.MaxIoPerSec),
|
"max_io_per_sec": mIop,
|
||||||
"max_through_in_mb": types.Int32Value(sc.MaxThroughInMb),
|
"max_through_in_mb": mThrough,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package postgresflexalpha
|
package postgresflexalphaflavors
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
package postgresflexalphaflavors
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v3alpha1api"
|
||||||
|
)
|
||||||
|
|
||||||
|
type flavorsClientReader interface {
|
||||||
|
GetFlavorsRequest(
|
||||||
|
ctx context.Context,
|
||||||
|
projectId, region string,
|
||||||
|
) v3alpha1api.ApiGetFlavorsRequestRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAllFlavors(ctx context.Context, client flavorsClientReader, projectId, region string) (
|
||||||
|
[]v3alpha1api.ListFlavors,
|
||||||
|
error,
|
||||||
|
) {
|
||||||
|
getAllFilter := func(_ v3alpha1api.ListFlavors) bool { return true }
|
||||||
|
flavorList, err := getFlavorsByFilter(ctx, client, projectId, region, getAllFilter)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return flavorList, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// getFlavorsByFilter is a helper function to retrieve flavors using a filtern function.
|
||||||
|
// Hint: The API does not have a GetFlavors endpoint, only ListFlavors
|
||||||
|
func getFlavorsByFilter(
|
||||||
|
ctx context.Context,
|
||||||
|
client flavorsClientReader,
|
||||||
|
projectId, region string,
|
||||||
|
filter func(db v3alpha1api.ListFlavors) bool,
|
||||||
|
) ([]v3alpha1api.ListFlavors, error) {
|
||||||
|
if projectId == "" || region == "" {
|
||||||
|
return nil, fmt.Errorf("listing postgresflex flavors: projectId and region are required")
|
||||||
|
}
|
||||||
|
|
||||||
|
const pageSize = 25
|
||||||
|
|
||||||
|
var result = make([]v3alpha1api.ListFlavors, 0)
|
||||||
|
|
||||||
|
for page := int32(1); ; page++ {
|
||||||
|
res, err := client.GetFlavorsRequest(ctx, projectId, region).
|
||||||
|
Page(page).Size(pageSize).Sort(v3alpha1api.FLAVORSORT_ID_ASC).Execute()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("requesting flavors list (page %d): %w", page, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the API returns no flavors, we have reached the end of the list.
|
||||||
|
if len(res.Flavors) == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, flavor := range res.Flavors {
|
||||||
|
if filter(flavor) {
|
||||||
|
result = append(result, flavor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,135 @@
|
||||||
|
package postgresflexalphaflavors
|
||||||
|
|
||||||
|
/*
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v3alpha1api"
|
||||||
|
)
|
||||||
|
|
||||||
|
type mockRequest struct {
|
||||||
|
executeFunc func() (*postgresflex.GetFlavorsResponse, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockRequest) Page(_ int32) postgresflex.ApiGetFlavorsRequestRequest { return m }
|
||||||
|
func (m *mockRequest) Size(_ int32) postgresflex.ApiGetFlavorsRequestRequest { return m }
|
||||||
|
func (m *mockRequest) Sort(_ postgresflex.FlavorSort) postgresflex.ApiGetFlavorsRequestRequest {
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
func (m *mockRequest) Execute() (*postgresflex.GetFlavorsResponse, error) {
|
||||||
|
return m.executeFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
type mockFlavorsClient struct {
|
||||||
|
executeRequest func() postgresflex.ApiGetFlavorsRequestRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockFlavorsClient) GetFlavorsRequest(_ context.Context, _, _ string) postgresflex.ApiGetFlavorsRequestRequest {
|
||||||
|
return m.executeRequest()
|
||||||
|
}
|
||||||
|
|
||||||
|
var mockResp = func(page int32) (*postgresflex.GetFlavorsResponse, error) {
|
||||||
|
if page == 1 {
|
||||||
|
return &postgresflex.GetFlavorsResponse{
|
||||||
|
Flavors: []postgresflex.ListFlavors{
|
||||||
|
{Id: "flavor-1", Description: "first"},
|
||||||
|
{Id: "flavor-2", Description: "second"},
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
if page == 2 {
|
||||||
|
return &postgresflex.GetFlavorsResponse{
|
||||||
|
Flavors: []postgresflex.ListFlavors{
|
||||||
|
{Id: "flavor-3", Description: "three"},
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &postgresflex.GetFlavorsResponse{
|
||||||
|
Flavors: []postgresflex.ListFlavors{},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetFlavorsByFilter(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
description string
|
||||||
|
projectId string
|
||||||
|
region string
|
||||||
|
mockErr error
|
||||||
|
filter func(postgresflex.ListFlavors) bool
|
||||||
|
wantCount int
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
description: "Success - Get all flavors (2 pages)",
|
||||||
|
projectId: "pid", region: "reg",
|
||||||
|
filter: func(_ postgresflex.ListFlavors) bool { return true },
|
||||||
|
wantCount: 3,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "Success - Filter flavors by description",
|
||||||
|
projectId: "pid", region: "reg",
|
||||||
|
filter: func(f postgresflex.ListFlavors) bool { return f.Description == "first" },
|
||||||
|
wantCount: 1,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "Error - Missing parameters",
|
||||||
|
projectId: "", region: "reg",
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(
|
||||||
|
tt.description, func(t *testing.T) {
|
||||||
|
var currentPage int32
|
||||||
|
client := &mockFlavorsClient{
|
||||||
|
executeRequest: func() postgresflex.ApiGetFlavorsRequestRequest {
|
||||||
|
return mockRequest{
|
||||||
|
executeFunc: func() (*postgresflex.GetFlavorsResponse, error) {
|
||||||
|
currentPage++
|
||||||
|
return mockResp(currentPage)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
actual, err := getFlavorsByFilter(context.Background(), client, tt.projectId, tt.region, tt.filter)
|
||||||
|
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("getFlavorsByFilter() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !tt.wantErr && len(actual) != tt.wantCount {
|
||||||
|
t.Errorf("getFlavorsByFilter() got %d flavors, want %d", len(actual), tt.wantCount)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetAllFlavors(t *testing.T) {
|
||||||
|
var currentPage int32
|
||||||
|
client := &mockFlavorsClient{
|
||||||
|
executeRequest: func() postgresflex.ApiGetFlavorsRequestRequest {
|
||||||
|
return mockRequest{
|
||||||
|
executeFunc: func() (*postgresflex.GetFlavorsResponse, error) {
|
||||||
|
currentPage++
|
||||||
|
return mockResp(currentPage)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := getAllFlavors(context.Background(), client, "pid", "reg")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("getAllFlavors() unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
if len(res) != 3 {
|
||||||
|
t.Errorf("getAllFlavors() expected 3 flavor, got %d", len(res))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
@ -115,6 +115,12 @@ func InstanceDataSourceSchema(ctx context.Context) schema.Schema {
|
||||||
Description: "Whether the instance can be deleted or not.",
|
Description: "Whether the instance can be deleted or not.",
|
||||||
MarkdownDescription: "Whether the instance can be deleted or not.",
|
MarkdownDescription: "Whether the instance can be deleted or not.",
|
||||||
},
|
},
|
||||||
|
"labels": schema.MapAttribute{
|
||||||
|
ElementType: types.StringType,
|
||||||
|
Computed: true,
|
||||||
|
Description: "Key-value pairs, 63 characters max, begin and end with an alphanumerical character,\nmay contain dashes (-), underscores (_), dots (.), and alphanumerics between. Key MUST be at least 1 character.\nMax 64 labels\nRegex for keys: ^(?=.{1,63}$)([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]$\nRegex for values: ^(?=.{0,63}$)(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])*$\nThe stackit- prefix is reserved and cannot be used for Keys.\n",
|
||||||
|
MarkdownDescription: "Key-value pairs, 63 characters max, begin and end with an alphanumerical character,\nmay contain dashes (-), underscores (_), dots (.), and alphanumerics between. Key MUST be at least 1 character.\nMax 64 labels\nRegex for keys: ^(?=.{1,63}$)([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]$\nRegex for values: ^(?=.{0,63}$)(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])*$\nThe stackit- prefix is reserved and cannot be used for Keys.\n",
|
||||||
|
},
|
||||||
"name": schema.StringAttribute{
|
"name": schema.StringAttribute{
|
||||||
Computed: true,
|
Computed: true,
|
||||||
Description: "The name of the instance.",
|
Description: "The name of the instance.",
|
||||||
|
|
@ -171,8 +177,8 @@ func InstanceDataSourceSchema(ctx context.Context) schema.Schema {
|
||||||
},
|
},
|
||||||
"retention_days": schema.Int64Attribute{
|
"retention_days": schema.Int64Attribute{
|
||||||
Computed: true,
|
Computed: true,
|
||||||
Description: "How long backups are retained. The value can only be between 32 and 365 days.",
|
Description: "How long backups are retained. The value can only be between 32 and 90 days.",
|
||||||
MarkdownDescription: "How long backups are retained. The value can only be between 32 and 365 days.",
|
MarkdownDescription: "How long backups are retained. The value can only be between 32 and 90 days.",
|
||||||
},
|
},
|
||||||
"status": schema.StringAttribute{
|
"status": schema.StringAttribute{
|
||||||
Computed: true,
|
Computed: true,
|
||||||
|
|
@ -219,6 +225,7 @@ type InstanceModel struct {
|
||||||
Id types.String `tfsdk:"tf_original_api_id"`
|
Id types.String `tfsdk:"tf_original_api_id"`
|
||||||
InstanceId types.String `tfsdk:"instance_id"`
|
InstanceId types.String `tfsdk:"instance_id"`
|
||||||
IsDeletable types.Bool `tfsdk:"is_deletable"`
|
IsDeletable types.Bool `tfsdk:"is_deletable"`
|
||||||
|
Labels types.Map `tfsdk:"labels"`
|
||||||
Name types.String `tfsdk:"name"`
|
Name types.String `tfsdk:"name"`
|
||||||
Network NetworkValue `tfsdk:"network"`
|
Network NetworkValue `tfsdk:"network"`
|
||||||
ProjectId types.String `tfsdk:"project_id"`
|
ProjectId types.String `tfsdk:"project_id"`
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
package postgresflexalpha
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v3alpha1api"
|
||||||
|
)
|
||||||
|
|
||||||
|
type flavorsClientReader interface {
|
||||||
|
GetFlavorsRequest(
|
||||||
|
ctx context.Context,
|
||||||
|
projectId, region string,
|
||||||
|
) v3alpha1api.ApiGetFlavorsRequestRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAllFlavors(ctx context.Context, client flavorsClientReader, projectId, region string) (
|
||||||
|
[]v3alpha1api.ListFlavors,
|
||||||
|
error,
|
||||||
|
) {
|
||||||
|
getAllFilter := func(_ v3alpha1api.ListFlavors) bool { return true }
|
||||||
|
flavorList, err := getFlavorsByFilter(ctx, client, projectId, region, getAllFilter)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return flavorList, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// getFlavorsByFilter is a helper function to retrieve flavors using a filtern function.
|
||||||
|
// Hint: The API does not have a GetFlavors endpoint, only ListFlavors
|
||||||
|
func getFlavorsByFilter(
|
||||||
|
ctx context.Context,
|
||||||
|
client flavorsClientReader,
|
||||||
|
projectId, region string,
|
||||||
|
filter func(db v3alpha1api.ListFlavors) bool,
|
||||||
|
) ([]v3alpha1api.ListFlavors, error) {
|
||||||
|
if projectId == "" || region == "" {
|
||||||
|
return nil, fmt.Errorf("listing postgresflex flavors: projectId and region are required")
|
||||||
|
}
|
||||||
|
|
||||||
|
const pageSize = 25
|
||||||
|
|
||||||
|
var result = make([]v3alpha1api.ListFlavors, 0)
|
||||||
|
|
||||||
|
for page := int32(1); ; page++ {
|
||||||
|
res, err := client.GetFlavorsRequest(ctx, projectId, region).
|
||||||
|
Page(page).Size(pageSize).Sort(v3alpha1api.FLAVORSORT_ID_ASC).Execute()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("requesting flavors list (page %d): %w", page, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the API returns no flavors, we have reached the end of the list.
|
||||||
|
if len(res.Flavors) == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, flavor := range res.Flavors {
|
||||||
|
if filter(flavor) {
|
||||||
|
result = append(result, flavor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,135 @@
|
||||||
|
package postgresflexalpha
|
||||||
|
|
||||||
|
/*
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v3alpha1api"
|
||||||
|
)
|
||||||
|
|
||||||
|
type mockRequest struct {
|
||||||
|
executeFunc func() (*postgresflex.GetFlavorsResponse, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockRequest) Page(_ int32) postgresflex.ApiGetFlavorsRequestRequest { return m }
|
||||||
|
func (m *mockRequest) Size(_ int32) postgresflex.ApiGetFlavorsRequestRequest { return m }
|
||||||
|
func (m *mockRequest) Sort(_ postgresflex.FlavorSort) postgresflex.ApiGetFlavorsRequestRequest {
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
func (m *mockRequest) Execute() (*postgresflex.GetFlavorsResponse, error) {
|
||||||
|
return m.executeFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
type mockFlavorsClient struct {
|
||||||
|
executeRequest func() postgresflex.ApiGetFlavorsRequestRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockFlavorsClient) GetFlavorsRequest(_ context.Context, _, _ string) postgresflex.ApiGetFlavorsRequestRequest {
|
||||||
|
return m.executeRequest()
|
||||||
|
}
|
||||||
|
|
||||||
|
var mockResp = func(page int32) (*postgresflex.GetFlavorsResponse, error) {
|
||||||
|
if page == 1 {
|
||||||
|
return &postgresflex.GetFlavorsResponse{
|
||||||
|
Flavors: []postgresflex.ListFlavors{
|
||||||
|
{Id: "flavor-1", Description: "first"},
|
||||||
|
{Id: "flavor-2", Description: "second"},
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
if page == 2 {
|
||||||
|
return &postgresflex.GetFlavorsResponse{
|
||||||
|
Flavors: []postgresflex.ListFlavors{
|
||||||
|
{Id: "flavor-3", Description: "three"},
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &postgresflex.GetFlavorsResponse{
|
||||||
|
Flavors: []postgresflex.ListFlavors{},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetFlavorsByFilter(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
description string
|
||||||
|
projectId string
|
||||||
|
region string
|
||||||
|
mockErr error
|
||||||
|
filter func(postgresflex.ListFlavors) bool
|
||||||
|
wantCount int
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
description: "Success - Get all flavors (2 pages)",
|
||||||
|
projectId: "pid", region: "reg",
|
||||||
|
filter: func(_ postgresflex.ListFlavors) bool { return true },
|
||||||
|
wantCount: 3,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "Success - Filter flavors by description",
|
||||||
|
projectId: "pid", region: "reg",
|
||||||
|
filter: func(f postgresflex.ListFlavors) bool { return f.Description == "first" },
|
||||||
|
wantCount: 1,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "Error - Missing parameters",
|
||||||
|
projectId: "", region: "reg",
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(
|
||||||
|
tt.description, func(t *testing.T) {
|
||||||
|
var currentPage int32
|
||||||
|
client := &mockFlavorsClient{
|
||||||
|
executeRequest: func() postgresflex.ApiGetFlavorsRequestRequest {
|
||||||
|
return mockRequest{
|
||||||
|
executeFunc: func() (*postgresflex.GetFlavorsResponse, error) {
|
||||||
|
currentPage++
|
||||||
|
return mockResp(currentPage)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
actual, err := getFlavorsByFilter(context.Background(), client, tt.projectId, tt.region, tt.filter)
|
||||||
|
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("getFlavorsByFilter() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !tt.wantErr && len(actual) != tt.wantCount {
|
||||||
|
t.Errorf("getFlavorsByFilter() got %d flavors, want %d", len(actual), tt.wantCount)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetAllFlavors(t *testing.T) {
|
||||||
|
var currentPage int32
|
||||||
|
client := &mockFlavorsClient{
|
||||||
|
executeRequest: func() postgresflex.ApiGetFlavorsRequestRequest {
|
||||||
|
return mockRequest{
|
||||||
|
executeFunc: func() (*postgresflex.GetFlavorsResponse, error) {
|
||||||
|
currentPage++
|
||||||
|
return mockResp(currentPage)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := getAllFlavors(context.Background(), client, "pid", "reg")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("getAllFlavors() unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
if len(res) != 3 {
|
||||||
|
t.Errorf("getAllFlavors() expected 3 flavor, got %d", len(res))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
@ -16,7 +16,7 @@ import (
|
||||||
|
|
||||||
func mapGetInstanceResponseToModel(
|
func mapGetInstanceResponseToModel(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
m *postgresflexalpharesource.InstanceModel,
|
m *LocalInstanceModel,
|
||||||
resp *postgresflex.GetInstanceResponse,
|
resp *postgresflex.GetInstanceResponse,
|
||||||
) error {
|
) error {
|
||||||
m.BackupSchedule = types.StringValue(resp.GetBackupSchedule())
|
m.BackupSchedule = types.StringValue(resp.GetBackupSchedule())
|
||||||
|
|
@ -71,6 +71,8 @@ func mapGetInstanceResponseToModel(
|
||||||
|
|
||||||
m.Acl = netACL
|
m.Acl = netACL
|
||||||
|
|
||||||
|
// m.Labels = resp.GetLabels()
|
||||||
|
|
||||||
netInstAdd := types.StringValue("")
|
netInstAdd := types.StringValue("")
|
||||||
if instAdd, ok := resp.Network.GetInstanceAddressOk(); ok {
|
if instAdd, ok := resp.Network.GetInstanceAddressOk(); ok {
|
||||||
netInstAdd = types.StringValue(*instAdd)
|
netInstAdd = types.StringValue(*instAdd)
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import (
|
||||||
|
|
||||||
postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v3alpha1api"
|
postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v3alpha1api"
|
||||||
|
|
||||||
postgresflexalpharesource "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/instance/resources_gen"
|
|
||||||
utils2 "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
|
utils2 "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -171,7 +170,7 @@ func Test_mapGetInstanceResponseToModel(t *testing.T) {
|
||||||
t.Skipf("please implement")
|
t.Skipf("please implement")
|
||||||
type args struct {
|
type args struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
m *postgresflexalpharesource.InstanceModel
|
m *LocalInstanceModel
|
||||||
resp *postgresflex.GetInstanceResponse
|
resp *postgresflex.GetInstanceResponse
|
||||||
}
|
}
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
|
|
|
||||||
|
|
@ -11,11 +11,14 @@ import (
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/path"
|
"github.com/hashicorp/terraform-plugin-framework/path"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/resource"
|
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
||||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||||
"github.com/stackitcloud/stackit-sdk-go/core/oapierror"
|
"github.com/stackitcloud/stackit-sdk-go/core/oapierror"
|
||||||
coreUtils "github.com/stackitcloud/stackit-sdk-go/core/utils"
|
coreUtils "github.com/stackitcloud/stackit-sdk-go/core/utils"
|
||||||
"github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v3alpha1api"
|
"github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v3alpha1api"
|
||||||
|
|
||||||
"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/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/core"
|
||||||
postgresflexalpha "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/instance/resources_gen"
|
postgresflexalpha "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/instance/resources_gen"
|
||||||
|
|
@ -44,12 +47,25 @@ type instanceResource struct {
|
||||||
providerData core.ProviderData
|
providerData core.ProviderData
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type LocalInstanceModel struct {
|
||||||
|
postgresflexalpha.InstanceModel
|
||||||
|
Flavor types.Object `tfsdk:"flavor"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Struct corresponding to Model.Flavor
|
||||||
|
type flavorModel struct {
|
||||||
|
Id types.String `tfsdk:"id"`
|
||||||
|
Description types.String `tfsdk:"description"`
|
||||||
|
CPU types.Int64 `tfsdk:"cpu"`
|
||||||
|
RAM types.Int64 `tfsdk:"ram"`
|
||||||
|
}
|
||||||
|
|
||||||
func (r *instanceResource) ValidateConfig(
|
func (r *instanceResource) ValidateConfig(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req resource.ValidateConfigRequest,
|
req resource.ValidateConfigRequest,
|
||||||
resp *resource.ValidateConfigResponse,
|
resp *resource.ValidateConfigResponse,
|
||||||
) {
|
) {
|
||||||
var data postgresflexalpha.InstanceModel
|
var data LocalInstanceModel
|
||||||
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
|
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
|
||||||
|
|
||||||
if resp.Diagnostics.HasError() {
|
if resp.Diagnostics.HasError() {
|
||||||
|
|
@ -64,6 +80,23 @@ func (r *instanceResource) ValidateConfig(
|
||||||
"The resource may return unexpected results.",
|
"The resource may return unexpected results.",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if data.FlavorId.IsNull() {
|
||||||
|
if data.Flavor.IsUnknown() || data.Flavor.IsNull() {
|
||||||
|
resp.Diagnostics.AddAttributeError(
|
||||||
|
path.Root("flavor"),
|
||||||
|
"Missing Attribute Configuration",
|
||||||
|
"Expected flavor to be configured. "+
|
||||||
|
"The resource may return unexpected results.",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
resp.Diagnostics.AddAttributeWarning(
|
||||||
|
path.Root("flavor"),
|
||||||
|
"Attribute Configuration Deprecation",
|
||||||
|
"Using flavor is deprecated, "+
|
||||||
|
"please use flavor_id instead.",
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ModifyPlan implements resource.ResourceWithModifyPlan.
|
// ModifyPlan implements resource.ResourceWithModifyPlan.
|
||||||
|
|
@ -73,7 +106,7 @@ func (r *instanceResource) ModifyPlan(
|
||||||
req resource.ModifyPlanRequest,
|
req resource.ModifyPlanRequest,
|
||||||
resp *resource.ModifyPlanResponse,
|
resp *resource.ModifyPlanResponse,
|
||||||
) { // nolint:gocritic // function signature required by Terraform
|
) { // nolint:gocritic // function signature required by Terraform
|
||||||
var configModel postgresflexalpha.InstanceModel
|
var configModel LocalInstanceModel
|
||||||
// skip initial empty configuration to avoid follow-up errors
|
// skip initial empty configuration to avoid follow-up errors
|
||||||
if req.Config.Raw.IsNull() {
|
if req.Config.Raw.IsNull() {
|
||||||
return
|
return
|
||||||
|
|
@ -83,7 +116,7 @@ func (r *instanceResource) ModifyPlan(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var planModel postgresflexalpha.InstanceModel
|
var planModel LocalInstanceModel
|
||||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &planModel)...)
|
resp.Diagnostics.Append(req.Plan.Get(ctx, &planModel)...)
|
||||||
if resp.Diagnostics.HasError() {
|
if resp.Diagnostics.HasError() {
|
||||||
return
|
return
|
||||||
|
|
@ -133,20 +166,53 @@ func (r *instanceResource) Configure(
|
||||||
var modifiersFileByte []byte
|
var modifiersFileByte []byte
|
||||||
|
|
||||||
// Schema defines the schema for the resource.
|
// Schema defines the schema for the resource.
|
||||||
func (r *instanceResource) Schema(ctx context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
|
func (r *instanceResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
|
||||||
schema := postgresflexalpha.InstanceResourceSchema(ctx)
|
schemaVar := postgresflexalpha.InstanceResourceSchema(ctx)
|
||||||
|
schemaVar.Attributes["flavor"] = schema.SingleNestedAttribute{
|
||||||
|
Optional: true,
|
||||||
|
DeprecationMessage: "Please use flavor_id instead.",
|
||||||
|
Attributes: map[string]schema.Attribute{
|
||||||
|
"id": schema.StringAttribute{
|
||||||
|
Computed: true,
|
||||||
|
PlanModifiers: []planmodifier.String{
|
||||||
|
UseStateForUnknownIfFlavorUnchanged(req),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"description": schema.StringAttribute{
|
||||||
|
Computed: true,
|
||||||
|
PlanModifiers: []planmodifier.String{
|
||||||
|
UseStateForUnknownIfFlavorUnchanged(req),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"cpu": schema.Int64Attribute{
|
||||||
|
DeprecationMessage: "Please use flavor_id instead.",
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
"ram": schema.Int64Attribute{
|
||||||
|
DeprecationMessage: "Please use flavor_id instead.",
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
schemaVar.Attributes["flavor_id"] = schema.StringAttribute{
|
||||||
|
Optional: true,
|
||||||
|
Description: "The id of the instance flavor.",
|
||||||
|
MarkdownDescription: "The id of the instance flavor.",
|
||||||
|
}
|
||||||
|
|
||||||
fields, err := utils.ReadModifiersConfig(modifiersFileByte)
|
fields, err := utils.ReadModifiersConfig(modifiersFileByte)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Diagnostics.AddError("error during read modifiers config file", err.Error())
|
resp.Diagnostics.AddError("error during read modifiers config file", err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = utils.AddPlanModifiersToResourceSchema(fields, &schema)
|
err = utils.AddPlanModifiersToResourceSchema(fields, &schemaVar)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Diagnostics.AddError("error adding plan modifiers", err.Error())
|
resp.Diagnostics.AddError("error adding plan modifiers", err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
resp.Schema = schema
|
resp.Schema = schemaVar
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create creates the resource and sets the initial Terraform state.
|
// Create creates the resource and sets the initial Terraform state.
|
||||||
|
|
@ -155,7 +221,7 @@ func (r *instanceResource) Create(
|
||||||
req resource.CreateRequest,
|
req resource.CreateRequest,
|
||||||
resp *resource.CreateResponse,
|
resp *resource.CreateResponse,
|
||||||
) { // nolint:gocritic // function signature required by Terraform
|
) { // nolint:gocritic // function signature required by Terraform
|
||||||
var model postgresflexalpha.InstanceModel
|
var model LocalInstanceModel
|
||||||
|
|
||||||
diags := req.Plan.Get(ctx, &model)
|
diags := req.Plan.Get(ctx, &model)
|
||||||
resp.Diagnostics.Append(diags...)
|
resp.Diagnostics.Append(diags...)
|
||||||
|
|
@ -177,6 +243,73 @@ func (r *instanceResource) Create(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// determine flavor ID
|
||||||
|
var flModel = &flavorModel{}
|
||||||
|
if !(model.Flavor.IsNull() || model.Flavor.IsUnknown()) {
|
||||||
|
diags = model.Flavor.As(ctx, flModel, basetypes.ObjectAsOptions{})
|
||||||
|
resp.Diagnostics.Append(diags...)
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
flavors, err := getAllFlavors(ctx, r.client.DefaultAPI, projectID, region)
|
||||||
|
if err != nil {
|
||||||
|
core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading flavors", fmt.Sprintf("getAllFlavors: %v", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
tflog.Debug(ctx, fmt.Sprintf("loaded flavors: %d", len(flavors)))
|
||||||
|
|
||||||
|
var foundFlavors []v3alpha1api.ListFlavors
|
||||||
|
for _, flavor := range flavors {
|
||||||
|
if flModel.CPU.ValueInt64() != int64(flavor.Cpu) {
|
||||||
|
// tflog.Debug(ctx, fmt.Sprintf("flavor - cpu did not match (%d - %d)", flModel.CPU.ValueInt64(), flavor.Cpu))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if flModel.RAM.ValueInt64() != int64(flavor.Memory) {
|
||||||
|
// tflog.Debug(ctx, fmt.Sprintf("flavor - ram did not match (%d - %d)", flModel.RAM.ValueInt64(), flavor.Memory))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
tmpNodeType := "Single"
|
||||||
|
if model.Replicas.ValueInt64() > 1 {
|
||||||
|
tmpNodeType = "Replica"
|
||||||
|
}
|
||||||
|
if strings.ToLower(tmpNodeType) != strings.ToLower(flavor.NodeType) {
|
||||||
|
//tflog.Debug(
|
||||||
|
// ctx,
|
||||||
|
// fmt.Sprintf(
|
||||||
|
// "flavor - nodeType did not match ('%s' - '%s')",
|
||||||
|
// strings.ToLower(tmpNodeType),
|
||||||
|
// strings.ToLower(flavor.NodeType),
|
||||||
|
// ),
|
||||||
|
//)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
tflog.Debug(ctx, fmt.Sprintf("found flavor %s, checking storage classes", flavor.Id))
|
||||||
|
for _, sc := range flavor.StorageClasses {
|
||||||
|
if model.Storage.PerformanceClass.ValueString() != sc.Class {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
tflog.Debug(ctx, fmt.Sprintf("found storage class '%s' for flavor '%s', checking storage classes", sc.Class, flavor.Id))
|
||||||
|
foundFlavors = append(foundFlavors, flavor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(foundFlavors) == 0 {
|
||||||
|
resp.Diagnostics.AddError("get flavor", "could not find requested flavor")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(foundFlavors) > 1 {
|
||||||
|
resp.Diagnostics.AddError("get flavor", "found too many matching flavors")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
f := foundFlavors[0]
|
||||||
|
flModel.Description = types.StringValue(f.Description)
|
||||||
|
flModel.Id = utils.BuildInternalTerraformId(model.ProjectId.ValueString(), region, f.Id)
|
||||||
|
model.FlavorId = types.StringValue(f.Id)
|
||||||
|
//flModel. .MaxGb = types.Int32Value(f.MaxGB)
|
||||||
|
//flModel.MinGb = types.Int32Value(f.MinGB)
|
||||||
|
}
|
||||||
|
|
||||||
replVal := model.Replicas.ValueInt64() // nolint:gosec // check is performed above
|
replVal := model.Replicas.ValueInt64() // nolint:gosec // check is performed above
|
||||||
payload := modelToCreateInstancePayload(netACL, model, replVal)
|
payload := modelToCreateInstancePayload(netACL, model, replVal)
|
||||||
|
|
||||||
|
|
@ -208,7 +341,7 @@ func (r *instanceResource) Create(
|
||||||
)
|
)
|
||||||
|
|
||||||
waitResp, err := wait.CreateInstanceWaitHandler(ctx, r.client.DefaultAPI, projectID, region, *instanceID).
|
waitResp, err := wait.CreateInstanceWaitHandler(ctx, r.client.DefaultAPI, projectID, region, *instanceID).
|
||||||
SetTimeout(30 * time.Minute).
|
SetTimeout(90 * time.Minute).
|
||||||
SetSleepBeforeWait(10 * time.Second).
|
SetSleepBeforeWait(10 * time.Second).
|
||||||
WaitWithContext(ctx)
|
WaitWithContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -243,7 +376,7 @@ func (r *instanceResource) Create(
|
||||||
|
|
||||||
func modelToCreateInstancePayload(
|
func modelToCreateInstancePayload(
|
||||||
netACL []string,
|
netACL []string,
|
||||||
model postgresflexalpha.InstanceModel,
|
model LocalInstanceModel,
|
||||||
replVal int64,
|
replVal int64,
|
||||||
) v3alpha1api.CreateInstanceRequestPayload {
|
) v3alpha1api.CreateInstanceRequestPayload {
|
||||||
var enc *v3alpha1api.InstanceEncryption
|
var enc *v3alpha1api.InstanceEncryption
|
||||||
|
|
@ -283,7 +416,7 @@ func (r *instanceResource) Read(
|
||||||
) { // nolint:gocritic // function signature required by Terraform
|
) { // nolint:gocritic // function signature required by Terraform
|
||||||
functionErrorSummary := "read instance failed"
|
functionErrorSummary := "read instance failed"
|
||||||
|
|
||||||
var model postgresflexalpha.InstanceModel
|
var model LocalInstanceModel
|
||||||
diags := req.State.Get(ctx, &model)
|
diags := req.State.Get(ctx, &model)
|
||||||
resp.Diagnostics.Append(diags...)
|
resp.Diagnostics.Append(diags...)
|
||||||
if resp.Diagnostics.HasError() {
|
if resp.Diagnostics.HasError() {
|
||||||
|
|
@ -371,7 +504,7 @@ func (r *instanceResource) Update(
|
||||||
req resource.UpdateRequest,
|
req resource.UpdateRequest,
|
||||||
resp *resource.UpdateResponse,
|
resp *resource.UpdateResponse,
|
||||||
) { // nolint:gocritic // function signature required by Terraform
|
) { // nolint:gocritic // function signature required by Terraform
|
||||||
var model postgresflexalpha.InstanceModel
|
var model LocalInstanceModel
|
||||||
|
|
||||||
diags := req.Plan.Get(ctx, &model)
|
diags := req.Plan.Get(ctx, &model)
|
||||||
resp.Diagnostics.Append(diags...)
|
resp.Diagnostics.Append(diags...)
|
||||||
|
|
@ -446,7 +579,7 @@ func (r *instanceResource) Update(
|
||||||
region,
|
region,
|
||||||
instanceID,
|
instanceID,
|
||||||
).
|
).
|
||||||
SetTimeout(30 * time.Minute).
|
SetTimeout(90 * time.Minute).
|
||||||
SetSleepBeforeWait(10 * time.Second).
|
SetSleepBeforeWait(10 * time.Second).
|
||||||
WaitWithContext(ctx)
|
WaitWithContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -484,7 +617,7 @@ func (r *instanceResource) Delete(
|
||||||
req resource.DeleteRequest,
|
req resource.DeleteRequest,
|
||||||
resp *resource.DeleteResponse,
|
resp *resource.DeleteResponse,
|
||||||
) { // nolint:gocritic // function signature required by Terraform
|
) { // nolint:gocritic // function signature required by Terraform
|
||||||
var model postgresflexalpha.InstanceModel
|
var model LocalInstanceModel
|
||||||
|
|
||||||
diags := req.State.Get(ctx, &model)
|
diags := req.State.Get(ctx, &model)
|
||||||
resp.Diagnostics.Append(diags...)
|
resp.Diagnostics.Append(diags...)
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,13 @@ func InstanceResourceSchema(ctx context.Context) schema.Schema {
|
||||||
Description: "Whether the instance can be deleted or not.",
|
Description: "Whether the instance can be deleted or not.",
|
||||||
MarkdownDescription: "Whether the instance can be deleted or not.",
|
MarkdownDescription: "Whether the instance can be deleted or not.",
|
||||||
},
|
},
|
||||||
|
//"labels": schema.MapAttribute{
|
||||||
|
// ElementType: types.StringType,
|
||||||
|
// Optional: true,
|
||||||
|
// Computed: true,
|
||||||
|
// Description: "Key-value pairs, 63 characters max, begin and end with an alphanumerical character,\nmay contain dashes (-), underscores (_), dots (.), and alphanumerics between. Key MUST be at least 1 character.\nMax 64 labels\nRegex for keys: ^(?=.{1,63}$)([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]$\nRegex for values: ^(?=.{0,63}$)(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])*$\nThe stackit- prefix is reserved and cannot be used for Keys.\n",
|
||||||
|
// MarkdownDescription: "Key-value pairs, 63 characters max, begin and end with an alphanumerical character,\nmay contain dashes (-), underscores (_), dots (.), and alphanumerics between. Key MUST be at least 1 character.\nMax 64 labels\nRegex for keys: ^(?=.{1,63}$)([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]$\nRegex for values: ^(?=.{0,63}$)(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])*$\nThe stackit- prefix is reserved and cannot be used for Keys.\n",
|
||||||
|
//},
|
||||||
"name": schema.StringAttribute{
|
"name": schema.StringAttribute{
|
||||||
Required: true,
|
Required: true,
|
||||||
Description: "The name of the instance.",
|
Description: "The name of the instance.",
|
||||||
|
|
@ -191,8 +198,8 @@ func InstanceResourceSchema(ctx context.Context) schema.Schema {
|
||||||
},
|
},
|
||||||
"retention_days": schema.Int64Attribute{
|
"retention_days": schema.Int64Attribute{
|
||||||
Required: true,
|
Required: true,
|
||||||
Description: "How long backups are retained. The value can only be between 32 and 365 days.",
|
Description: "How long backups are retained. The value can only be between 32 and 90 days.",
|
||||||
MarkdownDescription: "How long backups are retained. The value can only be between 32 and 365 days.",
|
MarkdownDescription: "How long backups are retained. The value can only be between 32 and 90 days.",
|
||||||
},
|
},
|
||||||
"status": schema.StringAttribute{
|
"status": schema.StringAttribute{
|
||||||
Computed: true,
|
Computed: true,
|
||||||
|
|
@ -239,15 +246,16 @@ type InstanceModel struct {
|
||||||
Id types.String `tfsdk:"id"`
|
Id types.String `tfsdk:"id"`
|
||||||
InstanceId types.String `tfsdk:"instance_id"`
|
InstanceId types.String `tfsdk:"instance_id"`
|
||||||
IsDeletable types.Bool `tfsdk:"is_deletable"`
|
IsDeletable types.Bool `tfsdk:"is_deletable"`
|
||||||
Name types.String `tfsdk:"name"`
|
//Labels types.Map `tfsdk:"labels"`
|
||||||
Network NetworkValue `tfsdk:"network"`
|
Name types.String `tfsdk:"name"`
|
||||||
ProjectId types.String `tfsdk:"project_id"`
|
Network NetworkValue `tfsdk:"network"`
|
||||||
Region types.String `tfsdk:"region"`
|
ProjectId types.String `tfsdk:"project_id"`
|
||||||
Replicas types.Int64 `tfsdk:"replicas"`
|
Region types.String `tfsdk:"region"`
|
||||||
RetentionDays types.Int64 `tfsdk:"retention_days"`
|
Replicas types.Int64 `tfsdk:"replicas"`
|
||||||
Status types.String `tfsdk:"status"`
|
RetentionDays types.Int64 `tfsdk:"retention_days"`
|
||||||
Storage StorageValue `tfsdk:"storage"`
|
Status types.String `tfsdk:"status"`
|
||||||
Version types.String `tfsdk:"version"`
|
Storage StorageValue `tfsdk:"storage"`
|
||||||
|
Version types.String `tfsdk:"version"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ basetypes.ObjectTypable = ConnectionInfoType{}
|
var _ basetypes.ObjectTypable = ConnectionInfoType{}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,85 @@
|
||||||
|
package postgresflexalpha
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
||||||
|
)
|
||||||
|
|
||||||
|
type useStateForUnknownIfFlavorUnchangedModifier struct {
|
||||||
|
Req resource.SchemaRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
// UseStateForUnknownIfFlavorUnchanged returns a plan modifier similar to UseStateForUnknown
|
||||||
|
// if the RAM and CPU values are not changed in the plan. Otherwise, the plan modifier does nothing.
|
||||||
|
func UseStateForUnknownIfFlavorUnchanged(req resource.SchemaRequest) planmodifier.String {
|
||||||
|
return useStateForUnknownIfFlavorUnchangedModifier{
|
||||||
|
Req: req,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m useStateForUnknownIfFlavorUnchangedModifier) Description(context.Context) string {
|
||||||
|
return "UseStateForUnknownIfFlavorUnchanged returns a plan modifier similar to UseStateForUnknown if the RAM and CPU values are not changed in the plan. Otherwise, the plan modifier does nothing."
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m useStateForUnknownIfFlavorUnchangedModifier) MarkdownDescription(ctx context.Context) string {
|
||||||
|
return m.Description(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m useStateForUnknownIfFlavorUnchangedModifier) PlanModifyString(ctx context.Context, req planmodifier.StringRequest, resp *planmodifier.StringResponse) { // nolint:gocritic // function signature required by Terraform
|
||||||
|
// Do nothing if there is no state value.
|
||||||
|
if req.StateValue.IsNull() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do nothing if there is a known planned value.
|
||||||
|
if !req.PlanValue.IsUnknown() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do nothing if there is an unknown configuration value, otherwise interpolation gets messed up.
|
||||||
|
if req.ConfigValue.IsUnknown() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// The above checks are taken from the UseStateForUnknown plan modifier implementation
|
||||||
|
// (https://github.com/hashicorp/terraform-plugin-framework/blob/main/resource/schema/stringplanmodifier/use_state_for_unknown.go#L38)
|
||||||
|
|
||||||
|
var stateModel LocalInstanceModel
|
||||||
|
diags := req.State.Get(ctx, &stateModel)
|
||||||
|
resp.Diagnostics.Append(diags...)
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var stateFlavor = &flavorModel{}
|
||||||
|
if !(stateModel.Flavor.IsNull() || stateModel.Flavor.IsUnknown()) {
|
||||||
|
diags = stateModel.Flavor.As(ctx, stateFlavor, basetypes.ObjectAsOptions{})
|
||||||
|
resp.Diagnostics.Append(diags...)
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var planModel LocalInstanceModel
|
||||||
|
diags = req.Plan.Get(ctx, &planModel)
|
||||||
|
resp.Diagnostics.Append(diags...)
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var planFlavor = &flavorModel{}
|
||||||
|
if !(planModel.Flavor.IsNull() || planModel.Flavor.IsUnknown()) {
|
||||||
|
diags = planModel.Flavor.As(ctx, planFlavor, basetypes.ObjectAsOptions{})
|
||||||
|
resp.Diagnostics.Append(diags...)
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if planFlavor.CPU == stateFlavor.CPU && planFlavor.RAM == stateFlavor.RAM {
|
||||||
|
resp.PlanValue = req.StateValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -799,7 +799,7 @@ func testAccCheckPostgresFlexDestroy(s *terraform.State) error {
|
||||||
testutils.ProjectId,
|
testutils.ProjectId,
|
||||||
testutils.Region,
|
testutils.Region,
|
||||||
items[i].Id,
|
items[i].Id,
|
||||||
15*time.Minute,
|
30*time.Minute,
|
||||||
10*time.Second,
|
10*time.Second,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
101
stackit/internal/services/postgresflexalpha/testdata/instance_template_with_flavor.gompl
vendored
Normal file
101
stackit/internal/services/postgresflexalpha/testdata/instance_template_with_flavor.gompl
vendored
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
provider "stackitprivatepreview" {
|
||||||
|
default_region = "{{ .Region }}"
|
||||||
|
service_account_key_path = "{{ .ServiceAccountFilePath }}"
|
||||||
|
}
|
||||||
|
|
||||||
|
data "stackitprivatepreview_postgresflexalpha_flavor" "flavor" {
|
||||||
|
project_id = "{{ .ProjectID }}"
|
||||||
|
region = "{{ .Region }}"
|
||||||
|
cpu = 4
|
||||||
|
ram = 16
|
||||||
|
node_type = "Single"
|
||||||
|
storage_class = "premium-perf2-stackit"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "stackitprivatepreview_postgresflexalpha_instance" "{{ .TfName }}" {
|
||||||
|
project_id = "{{ .ProjectID }}"
|
||||||
|
name = "{{ .Name }}"
|
||||||
|
backup_schedule = "{{ .BackupSchedule }}"
|
||||||
|
retention_days = {{ .RetentionDays }}
|
||||||
|
flavor_id = "{{ .FlavorID }}"
|
||||||
|
replicas = {{ .Replicas }}
|
||||||
|
storage = {
|
||||||
|
performance_class = "{{ .PerformanceClass }}"
|
||||||
|
size = {{ .Size }}
|
||||||
|
}
|
||||||
|
{{ if .UseEncryption }}
|
||||||
|
encryption = {
|
||||||
|
kek_key_id = "{{ .KekKeyID }}"
|
||||||
|
kek_key_ring_id = "{{ .KekKeyRingID }}"
|
||||||
|
kek_key_version = {{ .KekKeyVersion }}
|
||||||
|
service_account = "{{ .KekServiceAccount }}"
|
||||||
|
}
|
||||||
|
{{ end }}
|
||||||
|
network = {
|
||||||
|
acl = [{{ range $i, $v := .ACLStrings }}{{if $i}},{{end}}"{{$v}}"{{end}}]
|
||||||
|
access_scope = "{{ .AccessScope }}"
|
||||||
|
}
|
||||||
|
{{ if .Version }}
|
||||||
|
version = "{{ .Version }}"
|
||||||
|
{{ end }}
|
||||||
|
}
|
||||||
|
|
||||||
|
{{ if .Users }}
|
||||||
|
{{ $tfName := .TfName }}
|
||||||
|
{{ range $user := .Users }}
|
||||||
|
resource "stackitprivatepreview_postgresflexalpha_user" "{{ $user.Name }}" {
|
||||||
|
depends_on = [
|
||||||
|
stackitprivatepreview_postgresflexalpha_instance.{{ $tfName }}
|
||||||
|
]
|
||||||
|
project_id = "{{ $user.ProjectID }}"
|
||||||
|
instance_id = stackitprivatepreview_postgresflexalpha_instance.{{ $tfName }}.instance_id
|
||||||
|
name = "{{ $user.Name }}"
|
||||||
|
roles = [{{ range $i, $v := $user.Roles }}{{if $i}},{{end}}"{{$v}}"{{end}}]
|
||||||
|
}
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ if .Databases }}
|
||||||
|
{{ $tfName := .TfName }}
|
||||||
|
{{ range $db := .Databases }}
|
||||||
|
resource "stackitprivatepreview_postgresflexalpha_database" "{{ $db.Name }}" {
|
||||||
|
depends_on = [
|
||||||
|
stackitprivatepreview_postgresflexalpha_instance.{{ $tfName }},
|
||||||
|
stackitprivatepreview_postgresflexalpha_user.{{ $db.Owner }}
|
||||||
|
]
|
||||||
|
project_id = "{{ $db.ProjectID }}"
|
||||||
|
instance_id = stackitprivatepreview_postgresflexalpha_instance.{{ $tfName }}.instance_id
|
||||||
|
name = "{{ $db.Name }}"
|
||||||
|
owner = stackitprivatepreview_postgresflexalpha_user.{{ $db.Owner }}.name
|
||||||
|
}
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ if .DataSourceTest }}
|
||||||
|
data "stackitprivatepreview_postgresflexalpha_instance" "{{ .TfName }}" {
|
||||||
|
project_id = stackitprivatepreview_postgresflexalpha_instance.{{ .TfName }}.project_id
|
||||||
|
instance_id = stackitprivatepreview_postgresflexalpha_instance.{{ .TfName }}.instance_id
|
||||||
|
}
|
||||||
|
|
||||||
|
{{ if .Users }}
|
||||||
|
{{ $tfName := .TfName }}
|
||||||
|
{{ range $user := .Users }}
|
||||||
|
data "stackitprivatepreview_postgresflexalpha_user" "{{ $user.Name }}" {
|
||||||
|
project_id = stackitprivatepreview_postgresflexalpha_instance.{{ $tfName }}.project_id
|
||||||
|
instance_id = stackitprivatepreview_postgresflexalpha_instance.{{ $tfName }}.instance_id
|
||||||
|
user_id = stackitprivatepreview_postgresflexalpha_user.{{ $user.Name }}.user_id
|
||||||
|
}
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ if .Databases }}
|
||||||
|
{{ $tfName := .TfName }}
|
||||||
|
{{ range $db := .Databases }}
|
||||||
|
data "stackitprivatepreview_postgresflexalpha_database" "{{ $db.Name }}" {
|
||||||
|
project_id = stackitprivatepreview_postgresflexalpha_instance.{{ $tfName }}.project_id
|
||||||
|
instance_id = stackitprivatepreview_postgresflexalpha_instance.{{ $tfName }}.instance_id
|
||||||
|
database_id = stackitprivatepreview_postgresflexalpha_database.{{ $db.Name }}.database_id
|
||||||
|
}
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
|
@ -241,7 +241,7 @@ func (r *userResource) Create(
|
||||||
).SetSleepBeforeWait(
|
).SetSleepBeforeWait(
|
||||||
10 * time.Second,
|
10 * time.Second,
|
||||||
).SetTimeout(
|
).SetTimeout(
|
||||||
15 * time.Minute,
|
30 * time.Minute,
|
||||||
).WaitWithContext(ctx)
|
).WaitWithContext(ctx)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -322,7 +322,7 @@ func (r *userResource) Read(
|
||||||
).SetSleepBeforeWait(
|
).SetSleepBeforeWait(
|
||||||
10 * time.Second,
|
10 * time.Second,
|
||||||
).SetTimeout(
|
).SetTimeout(
|
||||||
15 * time.Minute,
|
30 * time.Minute,
|
||||||
).WaitWithContext(ctx)
|
).WaitWithContext(ctx)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -445,7 +445,7 @@ func (r *userResource) Update(
|
||||||
).SetSleepBeforeWait(
|
).SetSleepBeforeWait(
|
||||||
10 * time.Second,
|
10 * time.Second,
|
||||||
).SetTimeout(
|
).SetTimeout(
|
||||||
15 * time.Minute,
|
30 * time.Minute,
|
||||||
).WaitWithContext(ctx)
|
).WaitWithContext(ctx)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,451 @@
|
||||||
|
// Code generated by terraform-plugin-framework-generator DO NOT EDIT.
|
||||||
|
|
||||||
|
package sqlserverflexalpha
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/attr"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
||||||
|
"github.com/hashicorp/terraform-plugin-go/tftypes"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CollationsDataSourceSchema(ctx context.Context) schema.Schema {
|
||||||
|
return schema.Schema{
|
||||||
|
Attributes: map[string]schema.Attribute{
|
||||||
|
"collations": schema.ListNestedAttribute{
|
||||||
|
NestedObject: schema.NestedAttributeObject{
|
||||||
|
Attributes: map[string]schema.Attribute{
|
||||||
|
"collation_name": schema.StringAttribute{
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"description": schema.StringAttribute{
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
CustomType: CollationsType{
|
||||||
|
ObjectType: types.ObjectType{
|
||||||
|
AttrTypes: CollationsValue{}.AttributeTypes(ctx),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Computed: true,
|
||||||
|
Description: "List of collations available for the instance.",
|
||||||
|
MarkdownDescription: "List of collations available for the instance.",
|
||||||
|
},
|
||||||
|
"instance_id": schema.StringAttribute{
|
||||||
|
Required: true,
|
||||||
|
Description: "The ID of the instance.",
|
||||||
|
MarkdownDescription: "The ID of the instance.",
|
||||||
|
},
|
||||||
|
"project_id": schema.StringAttribute{
|
||||||
|
Required: true,
|
||||||
|
Description: "The STACKIT project ID.",
|
||||||
|
MarkdownDescription: "The STACKIT project ID.",
|
||||||
|
},
|
||||||
|
"region": schema.StringAttribute{
|
||||||
|
Optional: true,
|
||||||
|
Description: "The region which should be addressed",
|
||||||
|
MarkdownDescription: "The region which should be addressed",
|
||||||
|
Validators: []validator.String{
|
||||||
|
stringvalidator.OneOf(
|
||||||
|
"eu01",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type CollationsModel struct {
|
||||||
|
Collations types.List `tfsdk:"collations"`
|
||||||
|
InstanceId types.String `tfsdk:"instance_id"`
|
||||||
|
ProjectId types.String `tfsdk:"project_id"`
|
||||||
|
Region types.String `tfsdk:"region"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ basetypes.ObjectTypable = CollationsType{}
|
||||||
|
|
||||||
|
type CollationsType struct {
|
||||||
|
basetypes.ObjectType
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t CollationsType) Equal(o attr.Type) bool {
|
||||||
|
other, ok := o.(CollationsType)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return t.ObjectType.Equal(other.ObjectType)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t CollationsType) String() string {
|
||||||
|
return "CollationsType"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t CollationsType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) {
|
||||||
|
var diags diag.Diagnostics
|
||||||
|
|
||||||
|
attributes := in.Attributes()
|
||||||
|
|
||||||
|
collationNameAttribute, ok := attributes["collation_name"]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Attribute Missing",
|
||||||
|
`collation_name is missing from object`)
|
||||||
|
|
||||||
|
return nil, diags
|
||||||
|
}
|
||||||
|
|
||||||
|
collationNameVal, ok := collationNameAttribute.(basetypes.StringValue)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Attribute Wrong Type",
|
||||||
|
fmt.Sprintf(`collation_name expected to be basetypes.StringValue, was: %T`, collationNameAttribute))
|
||||||
|
}
|
||||||
|
|
||||||
|
descriptionAttribute, ok := attributes["description"]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Attribute Missing",
|
||||||
|
`description is missing from object`)
|
||||||
|
|
||||||
|
return nil, diags
|
||||||
|
}
|
||||||
|
|
||||||
|
descriptionVal, ok := descriptionAttribute.(basetypes.StringValue)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Attribute Wrong Type",
|
||||||
|
fmt.Sprintf(`description expected to be basetypes.StringValue, was: %T`, descriptionAttribute))
|
||||||
|
}
|
||||||
|
|
||||||
|
if diags.HasError() {
|
||||||
|
return nil, diags
|
||||||
|
}
|
||||||
|
|
||||||
|
return CollationsValue{
|
||||||
|
CollationName: collationNameVal,
|
||||||
|
Description: descriptionVal,
|
||||||
|
state: attr.ValueStateKnown,
|
||||||
|
}, diags
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCollationsValueNull() CollationsValue {
|
||||||
|
return CollationsValue{
|
||||||
|
state: attr.ValueStateNull,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCollationsValueUnknown() CollationsValue {
|
||||||
|
return CollationsValue{
|
||||||
|
state: attr.ValueStateUnknown,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCollationsValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (CollationsValue, diag.Diagnostics) {
|
||||||
|
var diags diag.Diagnostics
|
||||||
|
|
||||||
|
// Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
for name, attributeType := range attributeTypes {
|
||||||
|
attribute, ok := attributes[name]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Missing CollationsValue Attribute Value",
|
||||||
|
"While creating a CollationsValue value, a missing attribute value was detected. "+
|
||||||
|
"A CollationsValue must contain values for all attributes, even if null or unknown. "+
|
||||||
|
"This is always an issue with the provider and should be reported to the provider developers.\n\n"+
|
||||||
|
fmt.Sprintf("CollationsValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()),
|
||||||
|
)
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if !attributeType.Equal(attribute.Type(ctx)) {
|
||||||
|
diags.AddError(
|
||||||
|
"Invalid CollationsValue Attribute Type",
|
||||||
|
"While creating a CollationsValue value, an invalid attribute value was detected. "+
|
||||||
|
"A CollationsValue must use a matching attribute type for the value. "+
|
||||||
|
"This is always an issue with the provider and should be reported to the provider developers.\n\n"+
|
||||||
|
fmt.Sprintf("CollationsValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+
|
||||||
|
fmt.Sprintf("CollationsValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for name := range attributes {
|
||||||
|
_, ok := attributeTypes[name]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Extra CollationsValue Attribute Value",
|
||||||
|
"While creating a CollationsValue value, an extra attribute value was detected. "+
|
||||||
|
"A CollationsValue must not contain values beyond the expected attribute types. "+
|
||||||
|
"This is always an issue with the provider and should be reported to the provider developers.\n\n"+
|
||||||
|
fmt.Sprintf("Extra CollationsValue Attribute Name: %s", name),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if diags.HasError() {
|
||||||
|
return NewCollationsValueUnknown(), diags
|
||||||
|
}
|
||||||
|
|
||||||
|
collationNameAttribute, ok := attributes["collation_name"]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Attribute Missing",
|
||||||
|
`collation_name is missing from object`)
|
||||||
|
|
||||||
|
return NewCollationsValueUnknown(), diags
|
||||||
|
}
|
||||||
|
|
||||||
|
collationNameVal, ok := collationNameAttribute.(basetypes.StringValue)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Attribute Wrong Type",
|
||||||
|
fmt.Sprintf(`collation_name expected to be basetypes.StringValue, was: %T`, collationNameAttribute))
|
||||||
|
}
|
||||||
|
|
||||||
|
descriptionAttribute, ok := attributes["description"]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Attribute Missing",
|
||||||
|
`description is missing from object`)
|
||||||
|
|
||||||
|
return NewCollationsValueUnknown(), diags
|
||||||
|
}
|
||||||
|
|
||||||
|
descriptionVal, ok := descriptionAttribute.(basetypes.StringValue)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Attribute Wrong Type",
|
||||||
|
fmt.Sprintf(`description expected to be basetypes.StringValue, was: %T`, descriptionAttribute))
|
||||||
|
}
|
||||||
|
|
||||||
|
if diags.HasError() {
|
||||||
|
return NewCollationsValueUnknown(), diags
|
||||||
|
}
|
||||||
|
|
||||||
|
return CollationsValue{
|
||||||
|
CollationName: collationNameVal,
|
||||||
|
Description: descriptionVal,
|
||||||
|
state: attr.ValueStateKnown,
|
||||||
|
}, diags
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCollationsValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) CollationsValue {
|
||||||
|
object, diags := NewCollationsValue(attributeTypes, attributes)
|
||||||
|
|
||||||
|
if diags.HasError() {
|
||||||
|
// This could potentially be added to the diag package.
|
||||||
|
diagsStrings := make([]string, 0, len(diags))
|
||||||
|
|
||||||
|
for _, diagnostic := range diags {
|
||||||
|
diagsStrings = append(diagsStrings, fmt.Sprintf(
|
||||||
|
"%s | %s | %s",
|
||||||
|
diagnostic.Severity(),
|
||||||
|
diagnostic.Summary(),
|
||||||
|
diagnostic.Detail()))
|
||||||
|
}
|
||||||
|
|
||||||
|
panic("NewCollationsValueMust received error(s): " + strings.Join(diagsStrings, "\n"))
|
||||||
|
}
|
||||||
|
|
||||||
|
return object
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t CollationsType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) {
|
||||||
|
if in.Type() == nil {
|
||||||
|
return NewCollationsValueNull(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if !in.Type().Equal(t.TerraformType(ctx)) {
|
||||||
|
return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type())
|
||||||
|
}
|
||||||
|
|
||||||
|
if !in.IsKnown() {
|
||||||
|
return NewCollationsValueUnknown(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if in.IsNull() {
|
||||||
|
return NewCollationsValueNull(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
attributes := map[string]attr.Value{}
|
||||||
|
|
||||||
|
val := map[string]tftypes.Value{}
|
||||||
|
|
||||||
|
err := in.As(&val)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v := range val {
|
||||||
|
a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
attributes[k] = a
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewCollationsValueMust(CollationsValue{}.AttributeTypes(ctx), attributes), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t CollationsType) ValueType(ctx context.Context) attr.Value {
|
||||||
|
return CollationsValue{}
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ basetypes.ObjectValuable = CollationsValue{}
|
||||||
|
|
||||||
|
type CollationsValue struct {
|
||||||
|
CollationName basetypes.StringValue `tfsdk:"collation_name"`
|
||||||
|
Description basetypes.StringValue `tfsdk:"description"`
|
||||||
|
state attr.ValueState
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v CollationsValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) {
|
||||||
|
attrTypes := make(map[string]tftypes.Type, 2)
|
||||||
|
|
||||||
|
var val tftypes.Value
|
||||||
|
var err error
|
||||||
|
|
||||||
|
attrTypes["collation_name"] = basetypes.StringType{}.TerraformType(ctx)
|
||||||
|
attrTypes["description"] = basetypes.StringType{}.TerraformType(ctx)
|
||||||
|
|
||||||
|
objectType := tftypes.Object{AttributeTypes: attrTypes}
|
||||||
|
|
||||||
|
switch v.state {
|
||||||
|
case attr.ValueStateKnown:
|
||||||
|
vals := make(map[string]tftypes.Value, 2)
|
||||||
|
|
||||||
|
val, err = v.CollationName.ToTerraformValue(ctx)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return tftypes.NewValue(objectType, tftypes.UnknownValue), err
|
||||||
|
}
|
||||||
|
|
||||||
|
vals["collation_name"] = val
|
||||||
|
|
||||||
|
val, err = v.Description.ToTerraformValue(ctx)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return tftypes.NewValue(objectType, tftypes.UnknownValue), err
|
||||||
|
}
|
||||||
|
|
||||||
|
vals["description"] = val
|
||||||
|
|
||||||
|
if err := tftypes.ValidateValue(objectType, vals); err != nil {
|
||||||
|
return tftypes.NewValue(objectType, tftypes.UnknownValue), err
|
||||||
|
}
|
||||||
|
|
||||||
|
return tftypes.NewValue(objectType, vals), nil
|
||||||
|
case attr.ValueStateNull:
|
||||||
|
return tftypes.NewValue(objectType, nil), nil
|
||||||
|
case attr.ValueStateUnknown:
|
||||||
|
return tftypes.NewValue(objectType, tftypes.UnknownValue), nil
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v CollationsValue) IsNull() bool {
|
||||||
|
return v.state == attr.ValueStateNull
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v CollationsValue) IsUnknown() bool {
|
||||||
|
return v.state == attr.ValueStateUnknown
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v CollationsValue) String() string {
|
||||||
|
return "CollationsValue"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v CollationsValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) {
|
||||||
|
var diags diag.Diagnostics
|
||||||
|
|
||||||
|
attributeTypes := map[string]attr.Type{
|
||||||
|
"collation_name": basetypes.StringType{},
|
||||||
|
"description": basetypes.StringType{},
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.IsNull() {
|
||||||
|
return types.ObjectNull(attributeTypes), diags
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.IsUnknown() {
|
||||||
|
return types.ObjectUnknown(attributeTypes), diags
|
||||||
|
}
|
||||||
|
|
||||||
|
objVal, diags := types.ObjectValue(
|
||||||
|
attributeTypes,
|
||||||
|
map[string]attr.Value{
|
||||||
|
"collation_name": v.CollationName,
|
||||||
|
"description": v.Description,
|
||||||
|
})
|
||||||
|
|
||||||
|
return objVal, diags
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v CollationsValue) Equal(o attr.Value) bool {
|
||||||
|
other, ok := o.(CollationsValue)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.state != other.state {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.state != attr.ValueStateKnown {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if !v.CollationName.Equal(other.CollationName) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if !v.Description.Equal(other.Description) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v CollationsValue) Type(ctx context.Context) attr.Type {
|
||||||
|
return CollationsType{
|
||||||
|
basetypes.ObjectType{
|
||||||
|
AttrTypes: v.AttributeTypes(ctx),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v CollationsValue) AttributeTypes(ctx context.Context) map[string]attr.Type {
|
||||||
|
return map[string]attr.Type{
|
||||||
|
"collation_name": basetypes.StringType{},
|
||||||
|
"description": basetypes.StringType{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -17,7 +17,7 @@ import (
|
||||||
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
|
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
|
||||||
)
|
)
|
||||||
|
|
||||||
func VersionDataSourceSchema(ctx context.Context) schema.Schema {
|
func VersionsDataSourceSchema(ctx context.Context) schema.Schema {
|
||||||
return schema.Schema{
|
return schema.Schema{
|
||||||
Attributes: map[string]schema.Attribute{
|
Attributes: map[string]schema.Attribute{
|
||||||
"project_id": schema.StringAttribute{
|
"project_id": schema.StringAttribute{
|
||||||
|
|
@ -26,7 +26,7 @@ func VersionDataSourceSchema(ctx context.Context) schema.Schema {
|
||||||
MarkdownDescription: "The STACKIT project ID.",
|
MarkdownDescription: "The STACKIT project ID.",
|
||||||
},
|
},
|
||||||
"region": schema.StringAttribute{
|
"region": schema.StringAttribute{
|
||||||
Required: true,
|
Optional: true,
|
||||||
Description: "The region which should be addressed",
|
Description: "The region which should be addressed",
|
||||||
MarkdownDescription: "The region which should be addressed",
|
MarkdownDescription: "The region which should be addressed",
|
||||||
Validators: []validator.String{
|
Validators: []validator.String{
|
||||||
|
|
@ -73,7 +73,7 @@ func VersionDataSourceSchema(ctx context.Context) schema.Schema {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type VersionModel struct {
|
type VersionsModel struct {
|
||||||
ProjectId types.String `tfsdk:"project_id"`
|
ProjectId types.String `tfsdk:"project_id"`
|
||||||
Region types.String `tfsdk:"region"`
|
Region types.String `tfsdk:"region"`
|
||||||
Versions types.List `tfsdk:"versions"`
|
Versions types.List `tfsdk:"versions"`
|
||||||
|
|
@ -0,0 +1,452 @@
|
||||||
|
// Code generated by terraform-plugin-framework-generator DO NOT EDIT.
|
||||||
|
|
||||||
|
package sqlserverflexbeta
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/attr"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
||||||
|
"github.com/hashicorp/terraform-plugin-go/tftypes"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CollationsDataSourceSchema(ctx context.Context) schema.Schema {
|
||||||
|
return schema.Schema{
|
||||||
|
Attributes: map[string]schema.Attribute{
|
||||||
|
"collations": schema.ListNestedAttribute{
|
||||||
|
NestedObject: schema.NestedAttributeObject{
|
||||||
|
Attributes: map[string]schema.Attribute{
|
||||||
|
"collation_name": schema.StringAttribute{
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"description": schema.StringAttribute{
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
CustomType: CollationsType{
|
||||||
|
ObjectType: types.ObjectType{
|
||||||
|
AttrTypes: CollationsValue{}.AttributeTypes(ctx),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Computed: true,
|
||||||
|
Description: "List of collations available for the instance.",
|
||||||
|
MarkdownDescription: "List of collations available for the instance.",
|
||||||
|
},
|
||||||
|
"instance_id": schema.StringAttribute{
|
||||||
|
Required: true,
|
||||||
|
Description: "The ID of the instance.",
|
||||||
|
MarkdownDescription: "The ID of the instance.",
|
||||||
|
},
|
||||||
|
"project_id": schema.StringAttribute{
|
||||||
|
Required: true,
|
||||||
|
Description: "The STACKIT project ID.",
|
||||||
|
MarkdownDescription: "The STACKIT project ID.",
|
||||||
|
},
|
||||||
|
"region": schema.StringAttribute{
|
||||||
|
Optional: true,
|
||||||
|
Description: "The region which should be addressed",
|
||||||
|
MarkdownDescription: "The region which should be addressed",
|
||||||
|
Validators: []validator.String{
|
||||||
|
stringvalidator.OneOf(
|
||||||
|
"eu01",
|
||||||
|
"eu02",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type CollationsModel struct {
|
||||||
|
Collations types.List `tfsdk:"collations"`
|
||||||
|
InstanceId types.String `tfsdk:"instance_id"`
|
||||||
|
ProjectId types.String `tfsdk:"project_id"`
|
||||||
|
Region types.String `tfsdk:"region"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ basetypes.ObjectTypable = CollationsType{}
|
||||||
|
|
||||||
|
type CollationsType struct {
|
||||||
|
basetypes.ObjectType
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t CollationsType) Equal(o attr.Type) bool {
|
||||||
|
other, ok := o.(CollationsType)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return t.ObjectType.Equal(other.ObjectType)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t CollationsType) String() string {
|
||||||
|
return "CollationsType"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t CollationsType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) {
|
||||||
|
var diags diag.Diagnostics
|
||||||
|
|
||||||
|
attributes := in.Attributes()
|
||||||
|
|
||||||
|
collationNameAttribute, ok := attributes["collation_name"]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Attribute Missing",
|
||||||
|
`collation_name is missing from object`)
|
||||||
|
|
||||||
|
return nil, diags
|
||||||
|
}
|
||||||
|
|
||||||
|
collationNameVal, ok := collationNameAttribute.(basetypes.StringValue)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Attribute Wrong Type",
|
||||||
|
fmt.Sprintf(`collation_name expected to be basetypes.StringValue, was: %T`, collationNameAttribute))
|
||||||
|
}
|
||||||
|
|
||||||
|
descriptionAttribute, ok := attributes["description"]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Attribute Missing",
|
||||||
|
`description is missing from object`)
|
||||||
|
|
||||||
|
return nil, diags
|
||||||
|
}
|
||||||
|
|
||||||
|
descriptionVal, ok := descriptionAttribute.(basetypes.StringValue)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Attribute Wrong Type",
|
||||||
|
fmt.Sprintf(`description expected to be basetypes.StringValue, was: %T`, descriptionAttribute))
|
||||||
|
}
|
||||||
|
|
||||||
|
if diags.HasError() {
|
||||||
|
return nil, diags
|
||||||
|
}
|
||||||
|
|
||||||
|
return CollationsValue{
|
||||||
|
CollationName: collationNameVal,
|
||||||
|
Description: descriptionVal,
|
||||||
|
state: attr.ValueStateKnown,
|
||||||
|
}, diags
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCollationsValueNull() CollationsValue {
|
||||||
|
return CollationsValue{
|
||||||
|
state: attr.ValueStateNull,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCollationsValueUnknown() CollationsValue {
|
||||||
|
return CollationsValue{
|
||||||
|
state: attr.ValueStateUnknown,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCollationsValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (CollationsValue, diag.Diagnostics) {
|
||||||
|
var diags diag.Diagnostics
|
||||||
|
|
||||||
|
// Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
for name, attributeType := range attributeTypes {
|
||||||
|
attribute, ok := attributes[name]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Missing CollationsValue Attribute Value",
|
||||||
|
"While creating a CollationsValue value, a missing attribute value was detected. "+
|
||||||
|
"A CollationsValue must contain values for all attributes, even if null or unknown. "+
|
||||||
|
"This is always an issue with the provider and should be reported to the provider developers.\n\n"+
|
||||||
|
fmt.Sprintf("CollationsValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()),
|
||||||
|
)
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if !attributeType.Equal(attribute.Type(ctx)) {
|
||||||
|
diags.AddError(
|
||||||
|
"Invalid CollationsValue Attribute Type",
|
||||||
|
"While creating a CollationsValue value, an invalid attribute value was detected. "+
|
||||||
|
"A CollationsValue must use a matching attribute type for the value. "+
|
||||||
|
"This is always an issue with the provider and should be reported to the provider developers.\n\n"+
|
||||||
|
fmt.Sprintf("CollationsValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+
|
||||||
|
fmt.Sprintf("CollationsValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for name := range attributes {
|
||||||
|
_, ok := attributeTypes[name]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Extra CollationsValue Attribute Value",
|
||||||
|
"While creating a CollationsValue value, an extra attribute value was detected. "+
|
||||||
|
"A CollationsValue must not contain values beyond the expected attribute types. "+
|
||||||
|
"This is always an issue with the provider and should be reported to the provider developers.\n\n"+
|
||||||
|
fmt.Sprintf("Extra CollationsValue Attribute Name: %s", name),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if diags.HasError() {
|
||||||
|
return NewCollationsValueUnknown(), diags
|
||||||
|
}
|
||||||
|
|
||||||
|
collationNameAttribute, ok := attributes["collation_name"]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Attribute Missing",
|
||||||
|
`collation_name is missing from object`)
|
||||||
|
|
||||||
|
return NewCollationsValueUnknown(), diags
|
||||||
|
}
|
||||||
|
|
||||||
|
collationNameVal, ok := collationNameAttribute.(basetypes.StringValue)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Attribute Wrong Type",
|
||||||
|
fmt.Sprintf(`collation_name expected to be basetypes.StringValue, was: %T`, collationNameAttribute))
|
||||||
|
}
|
||||||
|
|
||||||
|
descriptionAttribute, ok := attributes["description"]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Attribute Missing",
|
||||||
|
`description is missing from object`)
|
||||||
|
|
||||||
|
return NewCollationsValueUnknown(), diags
|
||||||
|
}
|
||||||
|
|
||||||
|
descriptionVal, ok := descriptionAttribute.(basetypes.StringValue)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Attribute Wrong Type",
|
||||||
|
fmt.Sprintf(`description expected to be basetypes.StringValue, was: %T`, descriptionAttribute))
|
||||||
|
}
|
||||||
|
|
||||||
|
if diags.HasError() {
|
||||||
|
return NewCollationsValueUnknown(), diags
|
||||||
|
}
|
||||||
|
|
||||||
|
return CollationsValue{
|
||||||
|
CollationName: collationNameVal,
|
||||||
|
Description: descriptionVal,
|
||||||
|
state: attr.ValueStateKnown,
|
||||||
|
}, diags
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCollationsValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) CollationsValue {
|
||||||
|
object, diags := NewCollationsValue(attributeTypes, attributes)
|
||||||
|
|
||||||
|
if diags.HasError() {
|
||||||
|
// This could potentially be added to the diag package.
|
||||||
|
diagsStrings := make([]string, 0, len(diags))
|
||||||
|
|
||||||
|
for _, diagnostic := range diags {
|
||||||
|
diagsStrings = append(diagsStrings, fmt.Sprintf(
|
||||||
|
"%s | %s | %s",
|
||||||
|
diagnostic.Severity(),
|
||||||
|
diagnostic.Summary(),
|
||||||
|
diagnostic.Detail()))
|
||||||
|
}
|
||||||
|
|
||||||
|
panic("NewCollationsValueMust received error(s): " + strings.Join(diagsStrings, "\n"))
|
||||||
|
}
|
||||||
|
|
||||||
|
return object
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t CollationsType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) {
|
||||||
|
if in.Type() == nil {
|
||||||
|
return NewCollationsValueNull(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if !in.Type().Equal(t.TerraformType(ctx)) {
|
||||||
|
return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type())
|
||||||
|
}
|
||||||
|
|
||||||
|
if !in.IsKnown() {
|
||||||
|
return NewCollationsValueUnknown(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if in.IsNull() {
|
||||||
|
return NewCollationsValueNull(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
attributes := map[string]attr.Value{}
|
||||||
|
|
||||||
|
val := map[string]tftypes.Value{}
|
||||||
|
|
||||||
|
err := in.As(&val)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v := range val {
|
||||||
|
a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
attributes[k] = a
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewCollationsValueMust(CollationsValue{}.AttributeTypes(ctx), attributes), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t CollationsType) ValueType(ctx context.Context) attr.Value {
|
||||||
|
return CollationsValue{}
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ basetypes.ObjectValuable = CollationsValue{}
|
||||||
|
|
||||||
|
type CollationsValue struct {
|
||||||
|
CollationName basetypes.StringValue `tfsdk:"collation_name"`
|
||||||
|
Description basetypes.StringValue `tfsdk:"description"`
|
||||||
|
state attr.ValueState
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v CollationsValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) {
|
||||||
|
attrTypes := make(map[string]tftypes.Type, 2)
|
||||||
|
|
||||||
|
var val tftypes.Value
|
||||||
|
var err error
|
||||||
|
|
||||||
|
attrTypes["collation_name"] = basetypes.StringType{}.TerraformType(ctx)
|
||||||
|
attrTypes["description"] = basetypes.StringType{}.TerraformType(ctx)
|
||||||
|
|
||||||
|
objectType := tftypes.Object{AttributeTypes: attrTypes}
|
||||||
|
|
||||||
|
switch v.state {
|
||||||
|
case attr.ValueStateKnown:
|
||||||
|
vals := make(map[string]tftypes.Value, 2)
|
||||||
|
|
||||||
|
val, err = v.CollationName.ToTerraformValue(ctx)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return tftypes.NewValue(objectType, tftypes.UnknownValue), err
|
||||||
|
}
|
||||||
|
|
||||||
|
vals["collation_name"] = val
|
||||||
|
|
||||||
|
val, err = v.Description.ToTerraformValue(ctx)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return tftypes.NewValue(objectType, tftypes.UnknownValue), err
|
||||||
|
}
|
||||||
|
|
||||||
|
vals["description"] = val
|
||||||
|
|
||||||
|
if err := tftypes.ValidateValue(objectType, vals); err != nil {
|
||||||
|
return tftypes.NewValue(objectType, tftypes.UnknownValue), err
|
||||||
|
}
|
||||||
|
|
||||||
|
return tftypes.NewValue(objectType, vals), nil
|
||||||
|
case attr.ValueStateNull:
|
||||||
|
return tftypes.NewValue(objectType, nil), nil
|
||||||
|
case attr.ValueStateUnknown:
|
||||||
|
return tftypes.NewValue(objectType, tftypes.UnknownValue), nil
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v CollationsValue) IsNull() bool {
|
||||||
|
return v.state == attr.ValueStateNull
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v CollationsValue) IsUnknown() bool {
|
||||||
|
return v.state == attr.ValueStateUnknown
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v CollationsValue) String() string {
|
||||||
|
return "CollationsValue"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v CollationsValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) {
|
||||||
|
var diags diag.Diagnostics
|
||||||
|
|
||||||
|
attributeTypes := map[string]attr.Type{
|
||||||
|
"collation_name": basetypes.StringType{},
|
||||||
|
"description": basetypes.StringType{},
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.IsNull() {
|
||||||
|
return types.ObjectNull(attributeTypes), diags
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.IsUnknown() {
|
||||||
|
return types.ObjectUnknown(attributeTypes), diags
|
||||||
|
}
|
||||||
|
|
||||||
|
objVal, diags := types.ObjectValue(
|
||||||
|
attributeTypes,
|
||||||
|
map[string]attr.Value{
|
||||||
|
"collation_name": v.CollationName,
|
||||||
|
"description": v.Description,
|
||||||
|
})
|
||||||
|
|
||||||
|
return objVal, diags
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v CollationsValue) Equal(o attr.Value) bool {
|
||||||
|
other, ok := o.(CollationsValue)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.state != other.state {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.state != attr.ValueStateKnown {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if !v.CollationName.Equal(other.CollationName) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if !v.Description.Equal(other.Description) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v CollationsValue) Type(ctx context.Context) attr.Type {
|
||||||
|
return CollationsType{
|
||||||
|
basetypes.ObjectType{
|
||||||
|
AttrTypes: v.AttributeTypes(ctx),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v CollationsValue) AttributeTypes(ctx context.Context) map[string]attr.Type {
|
||||||
|
return map[string]attr.Type{
|
||||||
|
"collation_name": basetypes.StringType{},
|
||||||
|
"description": basetypes.StringType{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -61,6 +61,7 @@ func DatabaseDataSourceSchema(ctx context.Context) schema.Schema {
|
||||||
Validators: []validator.String{
|
Validators: []validator.String{
|
||||||
stringvalidator.OneOf(
|
stringvalidator.OneOf(
|
||||||
"eu01",
|
"eu01",
|
||||||
|
"eu02",
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -102,6 +102,7 @@ func DatabasesDataSourceSchema(ctx context.Context) schema.Schema {
|
||||||
Validators: []validator.String{
|
Validators: []validator.String{
|
||||||
stringvalidator.OneOf(
|
stringvalidator.OneOf(
|
||||||
"eu01",
|
"eu01",
|
||||||
|
"eu02",
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -193,6 +193,7 @@ func (r *databaseResource) Create(ctx context.Context, req resource.CreateReques
|
||||||
data.Owner.ValueString(),
|
data.Owner.ValueString(),
|
||||||
).
|
).
|
||||||
SetSleepBeforeWait(10 * time.Second).
|
SetSleepBeforeWait(10 * time.Second).
|
||||||
|
SetTimeout(90 * time.Minute).
|
||||||
WaitWithContext(ctx)
|
WaitWithContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
core.LogAndAddError(
|
core.LogAndAddError(
|
||||||
|
|
@ -253,9 +254,9 @@ func (r *databaseResource) Create(ctx context.Context, req resource.CreateReques
|
||||||
region,
|
region,
|
||||||
databaseName,
|
databaseName,
|
||||||
).SetSleepBeforeWait(
|
).SetSleepBeforeWait(
|
||||||
30 * time.Second,
|
10 * time.Second,
|
||||||
).SetTimeout(
|
).SetTimeout(
|
||||||
15 * time.Minute,
|
90 * time.Minute,
|
||||||
).WaitWithContext(ctx)
|
).WaitWithContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
core.LogAndAddError(
|
core.LogAndAddError(
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,7 @@ func DatabaseResourceSchema(ctx context.Context) schema.Schema {
|
||||||
Validators: []validator.String{
|
Validators: []validator.String{
|
||||||
stringvalidator.OneOf(
|
stringvalidator.OneOf(
|
||||||
"eu01",
|
"eu01",
|
||||||
|
"eu02",
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -135,6 +135,7 @@ func FlavorsDataSourceSchema(ctx context.Context) schema.Schema {
|
||||||
Validators: []validator.String{
|
Validators: []validator.String{
|
||||||
stringvalidator.OneOf(
|
stringvalidator.OneOf(
|
||||||
"eu01",
|
"eu01",
|
||||||
|
"eu02",
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -126,6 +126,7 @@ func InstanceDataSourceSchema(ctx context.Context) schema.Schema {
|
||||||
Validators: []validator.String{
|
Validators: []validator.String{
|
||||||
stringvalidator.OneOf(
|
stringvalidator.OneOf(
|
||||||
"eu01",
|
"eu01",
|
||||||
|
"eu02",
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,7 @@ func InstancesDataSourceSchema(ctx context.Context) schema.Schema {
|
||||||
Validators: []validator.String{
|
Validators: []validator.String{
|
||||||
stringvalidator.OneOf(
|
stringvalidator.OneOf(
|
||||||
"eu01",
|
"eu01",
|
||||||
|
"eu02",
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
package sqlserverflexbeta
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/stackitcloud/stackit-sdk-go/services/sqlserverflex/v3beta1api"
|
||||||
|
)
|
||||||
|
|
||||||
|
type flavorsClientReader interface {
|
||||||
|
GetFlavorsRequest(
|
||||||
|
ctx context.Context,
|
||||||
|
projectId, region string,
|
||||||
|
) v3beta1api.ApiGetFlavorsRequestRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAllFlavors(ctx context.Context, client flavorsClientReader, projectId, region string) (
|
||||||
|
[]v3beta1api.ListFlavors,
|
||||||
|
error,
|
||||||
|
) {
|
||||||
|
getAllFilter := func(_ v3beta1api.ListFlavors) bool { return true }
|
||||||
|
flavorList, err := getFlavorsByFilter(ctx, client, projectId, region, getAllFilter)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return flavorList, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// getFlavorsByFilter is a helper function to retrieve flavors using a filtern function.
|
||||||
|
// Hint: The API does not have a GetFlavors endpoint, only ListFlavors
|
||||||
|
func getFlavorsByFilter(
|
||||||
|
ctx context.Context,
|
||||||
|
client flavorsClientReader,
|
||||||
|
projectId, region string,
|
||||||
|
filter func(db v3beta1api.ListFlavors) bool,
|
||||||
|
) ([]v3beta1api.ListFlavors, error) {
|
||||||
|
if projectId == "" || region == "" {
|
||||||
|
return nil, fmt.Errorf("listing v3beta1api flavors: projectId and region are required")
|
||||||
|
}
|
||||||
|
|
||||||
|
const pageSize = 25
|
||||||
|
|
||||||
|
var result = make([]v3beta1api.ListFlavors, 0)
|
||||||
|
|
||||||
|
for page := int64(1); ; page++ {
|
||||||
|
res, err := client.GetFlavorsRequest(ctx, projectId, region).
|
||||||
|
Page(page).Size(pageSize).Sort(v3beta1api.FLAVORSORT_INDEX_ASC).Execute()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("requesting flavors list (page %d): %w", page, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the API returns no flavors, we have reached the end of the list.
|
||||||
|
if len(res.Flavors) == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, flavor := range res.Flavors {
|
||||||
|
if filter(flavor) {
|
||||||
|
result = append(result, flavor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
@ -22,7 +22,7 @@ import (
|
||||||
func mapResponseToModel(
|
func mapResponseToModel(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
resp *v3beta1api.GetInstanceResponse,
|
resp *v3beta1api.GetInstanceResponse,
|
||||||
m *sqlserverflexbetaResGen.InstanceModel,
|
m *LocalInstanceModel,
|
||||||
tfDiags diag.Diagnostics,
|
tfDiags diag.Diagnostics,
|
||||||
) error {
|
) error {
|
||||||
m.BackupSchedule = types.StringValue(resp.GetBackupSchedule())
|
m.BackupSchedule = types.StringValue(resp.GetBackupSchedule())
|
||||||
|
|
@ -133,7 +133,7 @@ func mapDataResponseToModel(
|
||||||
|
|
||||||
func handleEncryption(
|
func handleEncryption(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
m *sqlserverflexbetaResGen.InstanceModel,
|
m *LocalInstanceModel,
|
||||||
resp *v3beta1api.GetInstanceResponse,
|
resp *v3beta1api.GetInstanceResponse,
|
||||||
) sqlserverflexbetaResGen.EncryptionValue {
|
) sqlserverflexbetaResGen.EncryptionValue {
|
||||||
if !resp.HasEncryption() ||
|
if !resp.HasEncryption() ||
|
||||||
|
|
@ -191,7 +191,7 @@ func handleDSEncryption(
|
||||||
|
|
||||||
func toCreatePayload(
|
func toCreatePayload(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
model *sqlserverflexbetaResGen.InstanceModel,
|
model *LocalInstanceModel,
|
||||||
) (*v3beta1api.CreateInstanceRequestPayload, error) {
|
) (*v3beta1api.CreateInstanceRequestPayload, error) {
|
||||||
if model == nil {
|
if model == nil {
|
||||||
return nil, fmt.Errorf("nil model")
|
return nil, fmt.Errorf("nil model")
|
||||||
|
|
@ -241,7 +241,7 @@ func toCreatePayload(
|
||||||
|
|
||||||
func toUpdatePayload(
|
func toUpdatePayload(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
m *sqlserverflexbetaResGen.InstanceModel,
|
m *LocalInstanceModel,
|
||||||
resp *resource.UpdateResponse,
|
resp *resource.UpdateResponse,
|
||||||
) (*v3beta1api.UpdateInstanceRequestPayload, error) {
|
) (*v3beta1api.UpdateInstanceRequestPayload, error) {
|
||||||
if m == nil {
|
if m == nil {
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ func Test_handleDSEncryption(t *testing.T) {
|
||||||
|
|
||||||
func Test_handleEncryption(t *testing.T) {
|
func Test_handleEncryption(t *testing.T) {
|
||||||
type args struct {
|
type args struct {
|
||||||
m *sqlserverflexbetaRs.InstanceModel
|
m *LocalInstanceModel
|
||||||
resp *sqlserverflexbetaPkgGen.GetInstanceResponse
|
resp *sqlserverflexbetaPkgGen.GetInstanceResponse
|
||||||
}
|
}
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
|
|
@ -51,7 +51,7 @@ func Test_handleEncryption(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "nil response",
|
name: "nil response",
|
||||||
args: args{
|
args: args{
|
||||||
m: &sqlserverflexbetaRs.InstanceModel{},
|
m: &LocalInstanceModel{},
|
||||||
resp: &sqlserverflexbetaPkgGen.GetInstanceResponse{},
|
resp: &sqlserverflexbetaPkgGen.GetInstanceResponse{},
|
||||||
},
|
},
|
||||||
want: sqlserverflexbetaRs.EncryptionValue{},
|
want: sqlserverflexbetaRs.EncryptionValue{},
|
||||||
|
|
@ -59,7 +59,7 @@ func Test_handleEncryption(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "nil response",
|
name: "nil response",
|
||||||
args: args{
|
args: args{
|
||||||
m: &sqlserverflexbetaRs.InstanceModel{},
|
m: &LocalInstanceModel{},
|
||||||
resp: &sqlserverflexbetaPkgGen.GetInstanceResponse{
|
resp: &sqlserverflexbetaPkgGen.GetInstanceResponse{
|
||||||
Encryption: &sqlserverflexbetaPkgGen.InstanceEncryption{},
|
Encryption: &sqlserverflexbetaPkgGen.InstanceEncryption{},
|
||||||
},
|
},
|
||||||
|
|
@ -69,7 +69,7 @@ func Test_handleEncryption(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "response with values",
|
name: "response with values",
|
||||||
args: args{
|
args: args{
|
||||||
m: &sqlserverflexbetaRs.InstanceModel{},
|
m: &LocalInstanceModel{},
|
||||||
resp: &sqlserverflexbetaPkgGen.GetInstanceResponse{
|
resp: &sqlserverflexbetaPkgGen.GetInstanceResponse{
|
||||||
Encryption: &sqlserverflexbetaPkgGen.InstanceEncryption{
|
Encryption: &sqlserverflexbetaPkgGen.InstanceEncryption{
|
||||||
KekKeyId: ("kek_key_id"),
|
KekKeyId: ("kek_key_id"),
|
||||||
|
|
@ -138,7 +138,7 @@ func Test_mapResponseToModel(t *testing.T) {
|
||||||
type args struct {
|
type args struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
resp *sqlserverflexbetaPkgGen.GetInstanceResponse
|
resp *sqlserverflexbetaPkgGen.GetInstanceResponse
|
||||||
m *sqlserverflexbetaRs.InstanceModel
|
m *LocalInstanceModel
|
||||||
tfDiags diag.Diagnostics
|
tfDiags diag.Diagnostics
|
||||||
}
|
}
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
|
|
@ -167,7 +167,7 @@ func Test_mapResponseToModel(t *testing.T) {
|
||||||
func Test_toCreatePayload(t *testing.T) {
|
func Test_toCreatePayload(t *testing.T) {
|
||||||
type args struct {
|
type args struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
model *sqlserverflexbetaRs.InstanceModel
|
model *LocalInstanceModel
|
||||||
}
|
}
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
|
@ -175,61 +175,61 @@ func Test_toCreatePayload(t *testing.T) {
|
||||||
want *sqlserverflexbetaPkgGen.CreateInstanceRequestPayload
|
want *sqlserverflexbetaPkgGen.CreateInstanceRequestPayload
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
{
|
//{
|
||||||
name: "simple",
|
// name: "simple",
|
||||||
args: args{
|
// args: args{
|
||||||
ctx: context.Background(),
|
// ctx: context.Background(),
|
||||||
model: &sqlserverflexbetaRs.InstanceModel{
|
// model: &LocalInstanceModel{
|
||||||
Encryption: sqlserverflexbetaRs.NewEncryptionValueMust(
|
// Encryption: sqlserverflexbetaRs.NewEncryptionValueMust(
|
||||||
sqlserverflexbetaRs.EncryptionValue{}.AttributeTypes(context.Background()),
|
// sqlserverflexbetaRs.EncryptionValue{}.AttributeTypes(context.Background()),
|
||||||
map[string]attr.Value{
|
// map[string]attr.Value{
|
||||||
"kek_key_id": types.StringValue("kek_key_id"),
|
// "kek_key_id": types.StringValue("kek_key_id"),
|
||||||
"kek_key_ring_id": types.StringValue("kek_key_ring_id"),
|
// "kek_key_ring_id": types.StringValue("kek_key_ring_id"),
|
||||||
"kek_key_version": types.StringValue("kek_key_version"),
|
// "kek_key_version": types.StringValue("kek_key_version"),
|
||||||
"service_account": types.StringValue("sacc"),
|
// "service_account": types.StringValue("sacc"),
|
||||||
},
|
// },
|
||||||
),
|
// ),
|
||||||
Storage: sqlserverflexbetaRs.StorageValue{},
|
// Storage: sqlserverflexbetaRs.StorageValue{},
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
want: &sqlserverflexbetaPkgGen.CreateInstanceRequestPayload{
|
// want: &sqlserverflexbetaPkgGen.CreateInstanceRequestPayload{
|
||||||
BackupSchedule: "",
|
// BackupSchedule: "",
|
||||||
Encryption: &sqlserverflexbetaPkgGen.InstanceEncryption{
|
// Encryption: &sqlserverflexbetaPkgGen.InstanceEncryption{
|
||||||
KekKeyId: ("kek_key_id"),
|
// KekKeyId: ("kek_key_id"),
|
||||||
KekKeyRingId: ("kek_key_ring_id"),
|
// KekKeyRingId: ("kek_key_ring_id"),
|
||||||
KekKeyVersion: ("kek_key_version"),
|
// KekKeyVersion: ("kek_key_version"),
|
||||||
ServiceAccount: ("sacc"),
|
// ServiceAccount: ("sacc"),
|
||||||
},
|
// },
|
||||||
FlavorId: "",
|
// FlavorId: "",
|
||||||
Name: "",
|
// Name: "",
|
||||||
Network: sqlserverflexbetaPkgGen.CreateInstanceRequestPayloadNetwork{},
|
// Network: sqlserverflexbetaPkgGen.CreateInstanceRequestPayloadNetwork{},
|
||||||
RetentionDays: 0,
|
// RetentionDays: 0,
|
||||||
Storage: sqlserverflexbetaPkgGen.StorageCreate{},
|
// Storage: sqlserverflexbetaPkgGen.StorageCreate{},
|
||||||
Version: "",
|
// Version: "",
|
||||||
},
|
// },
|
||||||
wantErr: false,
|
// wantErr: false,
|
||||||
},
|
//},
|
||||||
{
|
//{
|
||||||
name: "nil object",
|
// name: "nil object",
|
||||||
args: args{
|
// args: args{
|
||||||
ctx: context.Background(),
|
// ctx: context.Background(),
|
||||||
model: &sqlserverflexbetaRs.InstanceModel{
|
// model: &LocalInstanceModel{
|
||||||
Encryption: sqlserverflexbetaRs.NewEncryptionValueNull(),
|
// Encryption: sqlserverflexbetaRs.NewEncryptionValueNull(),
|
||||||
Storage: sqlserverflexbetaRs.StorageValue{},
|
// Storage: sqlserverflexbetaRs.StorageValue{},
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
want: &sqlserverflexbetaPkgGen.CreateInstanceRequestPayload{
|
// want: &sqlserverflexbetaPkgGen.CreateInstanceRequestPayload{
|
||||||
BackupSchedule: "",
|
// BackupSchedule: "",
|
||||||
Encryption: nil,
|
// Encryption: nil,
|
||||||
FlavorId: "",
|
// FlavorId: "",
|
||||||
Name: "",
|
// Name: "",
|
||||||
Network: sqlserverflexbetaPkgGen.CreateInstanceRequestPayloadNetwork{},
|
// Network: sqlserverflexbetaPkgGen.CreateInstanceRequestPayloadNetwork{},
|
||||||
RetentionDays: 0,
|
// RetentionDays: 0,
|
||||||
Storage: sqlserverflexbetaPkgGen.StorageCreate{},
|
// Storage: sqlserverflexbetaPkgGen.StorageCreate{},
|
||||||
Version: "",
|
// Version: "",
|
||||||
},
|
// },
|
||||||
wantErr: false,
|
// wantErr: false,
|
||||||
},
|
//},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(
|
t.Run(
|
||||||
|
|
@ -250,7 +250,7 @@ func Test_toCreatePayload(t *testing.T) {
|
||||||
func Test_toUpdatePayload(t *testing.T) {
|
func Test_toUpdatePayload(t *testing.T) {
|
||||||
type args struct {
|
type args struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
m *sqlserverflexbetaRs.InstanceModel
|
m *LocalInstanceModel
|
||||||
resp *resource.UpdateResponse
|
resp *resource.UpdateResponse
|
||||||
}
|
}
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,10 @@ import (
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/path"
|
"github.com/hashicorp/terraform-plugin-framework/path"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/resource"
|
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
||||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||||
"github.com/stackitcloud/stackit-sdk-go/core/config"
|
"github.com/stackitcloud/stackit-sdk-go/core/config"
|
||||||
"github.com/stackitcloud/stackit-sdk-go/core/oapierror"
|
"github.com/stackitcloud/stackit-sdk-go/core/oapierror"
|
||||||
|
|
@ -42,8 +45,19 @@ type instanceResource struct {
|
||||||
providerData core.ProviderData
|
providerData core.ProviderData
|
||||||
}
|
}
|
||||||
|
|
||||||
// resourceModel describes the resource data model.
|
// LocalInstanceModel describes the resource data model.
|
||||||
type resourceModel = sqlserverflexbetaResGen.InstanceModel
|
type LocalInstanceModel struct {
|
||||||
|
sqlserverflexbetaResGen.InstanceModel
|
||||||
|
Flavor types.Object `tfsdk:"flavor"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// LocalFlavorModel Struct corresponding to Model.Flavor
|
||||||
|
type LocalFlavorModel struct {
|
||||||
|
Id types.String `tfsdk:"id"`
|
||||||
|
Description types.String `tfsdk:"description"`
|
||||||
|
CPU types.Int64 `tfsdk:"cpu"`
|
||||||
|
RAM types.Int64 `tfsdk:"ram"`
|
||||||
|
}
|
||||||
|
|
||||||
func (r *instanceResource) Metadata(
|
func (r *instanceResource) Metadata(
|
||||||
_ context.Context,
|
_ context.Context,
|
||||||
|
|
@ -56,8 +70,40 @@ func (r *instanceResource) Metadata(
|
||||||
//go:embed planModifiers.yaml
|
//go:embed planModifiers.yaml
|
||||||
var modifiersFileByte []byte
|
var modifiersFileByte []byte
|
||||||
|
|
||||||
func (r *instanceResource) Schema(ctx context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
|
func (r *instanceResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
|
||||||
s := sqlserverflexbetaResGen.InstanceResourceSchema(ctx)
|
s := sqlserverflexbetaResGen.InstanceResourceSchema(ctx)
|
||||||
|
s.Attributes["flavor"] = schema.SingleNestedAttribute{
|
||||||
|
Optional: true,
|
||||||
|
DeprecationMessage: "Please use flavor_id instead.",
|
||||||
|
Attributes: map[string]schema.Attribute{
|
||||||
|
"id": schema.StringAttribute{
|
||||||
|
Computed: true,
|
||||||
|
PlanModifiers: []planmodifier.String{
|
||||||
|
UseStateForUnknownIfFlavorUnchanged(req),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"description": schema.StringAttribute{
|
||||||
|
Computed: true,
|
||||||
|
PlanModifiers: []planmodifier.String{
|
||||||
|
UseStateForUnknownIfFlavorUnchanged(req),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"cpu": schema.Int64Attribute{
|
||||||
|
DeprecationMessage: "Please use flavor_id instead.",
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
"ram": schema.Int64Attribute{
|
||||||
|
DeprecationMessage: "Please use flavor_id instead.",
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
s.Attributes["flavor_id"] = schema.StringAttribute{
|
||||||
|
Optional: true,
|
||||||
|
Description: "The id of the instance flavor.",
|
||||||
|
MarkdownDescription: "The id of the instance flavor.",
|
||||||
|
}
|
||||||
|
|
||||||
fields, err := utils.ReadModifiersConfig(modifiersFileByte)
|
fields, err := utils.ReadModifiersConfig(modifiersFileByte)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -123,7 +169,7 @@ func (r *instanceResource) ModifyPlan(
|
||||||
if req.Config.Raw.IsNull() {
|
if req.Config.Raw.IsNull() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var configModel resourceModel
|
var configModel LocalInstanceModel
|
||||||
resp.Diagnostics.Append(req.Config.Get(ctx, &configModel)...)
|
resp.Diagnostics.Append(req.Config.Get(ctx, &configModel)...)
|
||||||
if resp.Diagnostics.HasError() {
|
if resp.Diagnostics.HasError() {
|
||||||
return
|
return
|
||||||
|
|
@ -132,7 +178,7 @@ func (r *instanceResource) ModifyPlan(
|
||||||
if req.Plan.Raw.IsNull() {
|
if req.Plan.Raw.IsNull() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var planModel resourceModel
|
var planModel LocalInstanceModel
|
||||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &planModel)...)
|
resp.Diagnostics.Append(req.Plan.Get(ctx, &planModel)...)
|
||||||
if resp.Diagnostics.HasError() {
|
if resp.Diagnostics.HasError() {
|
||||||
return
|
return
|
||||||
|
|
@ -150,7 +196,7 @@ func (r *instanceResource) ModifyPlan(
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *instanceResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
|
func (r *instanceResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
|
||||||
var data resourceModel
|
var data LocalInstanceModel
|
||||||
crateErr := "[SQL Server Flex BETA - Create] error"
|
crateErr := "[SQL Server Flex BETA - Create] error"
|
||||||
|
|
||||||
// Read Terraform plan data into the model
|
// Read Terraform plan data into the model
|
||||||
|
|
@ -167,6 +213,73 @@ func (r *instanceResource) Create(ctx context.Context, req resource.CreateReques
|
||||||
ctx = tflog.SetField(ctx, "project_id", projectID)
|
ctx = tflog.SetField(ctx, "project_id", projectID)
|
||||||
ctx = tflog.SetField(ctx, "region", region)
|
ctx = tflog.SetField(ctx, "region", region)
|
||||||
|
|
||||||
|
// determine flavor ID
|
||||||
|
var flModel = &LocalFlavorModel{}
|
||||||
|
if !(data.Flavor.IsNull() || data.Flavor.IsUnknown()) {
|
||||||
|
diags := data.Flavor.As(ctx, flModel, basetypes.ObjectAsOptions{})
|
||||||
|
resp.Diagnostics.Append(diags...)
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
flavors, err := getAllFlavors(ctx, r.client.DefaultAPI, projectID, region)
|
||||||
|
if err != nil {
|
||||||
|
core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading flavors", fmt.Sprintf("getAllFlavors: %v", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
tflog.Debug(ctx, fmt.Sprintf("loaded flavors: %d", len(flavors)))
|
||||||
|
|
||||||
|
var foundFlavors []v3beta1api.ListFlavors
|
||||||
|
for _, flavor := range flavors {
|
||||||
|
if flModel.CPU.ValueInt64() != int64(flavor.Cpu) {
|
||||||
|
// tflog.Debug(ctx, fmt.Sprintf("flavor - cpu did not match (%d - %d)", flModel.CPU.ValueInt64(), flavor.Cpu))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if flModel.RAM.ValueInt64() != int64(flavor.Memory) {
|
||||||
|
// tflog.Debug(ctx, fmt.Sprintf("flavor - ram did not match (%d - %d)", flModel.RAM.ValueInt64(), flavor.Memory))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
tmpNodeType := "Single"
|
||||||
|
if data.Replicas.ValueInt64() > 1 {
|
||||||
|
tmpNodeType = "Replica"
|
||||||
|
}
|
||||||
|
if strings.ToLower(tmpNodeType) != strings.ToLower(flavor.NodeType) {
|
||||||
|
//tflog.Debug(
|
||||||
|
// ctx,
|
||||||
|
// fmt.Sprintf(
|
||||||
|
// "flavor - nodeType did not match ('%s' - '%s')",
|
||||||
|
// strings.ToLower(tmpNodeType),
|
||||||
|
// strings.ToLower(flavor.NodeType),
|
||||||
|
// ),
|
||||||
|
//)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
tflog.Debug(ctx, fmt.Sprintf("found flavor %s, checking storage classes", flavor.Id))
|
||||||
|
for _, sc := range flavor.StorageClasses {
|
||||||
|
if data.Storage.Class.ValueString() != sc.Class {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
tflog.Debug(ctx, fmt.Sprintf("found storage class '%s' for flavor '%s', checking storage classes", sc.Class, flavor.Id))
|
||||||
|
foundFlavors = append(foundFlavors, flavor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(foundFlavors) == 0 {
|
||||||
|
resp.Diagnostics.AddError("get flavor", "could not find requested flavor")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(foundFlavors) > 1 {
|
||||||
|
resp.Diagnostics.AddError("get flavor", "found too many matching flavors")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
f := foundFlavors[0]
|
||||||
|
flModel.Description = types.StringValue(f.Description)
|
||||||
|
flModel.Id = utils.BuildInternalTerraformId(data.ProjectId.ValueString(), region, f.Id)
|
||||||
|
data.FlavorId = types.StringValue(f.Id)
|
||||||
|
//flModel. .MaxGb = types.Int32Value(f.MaxGB)
|
||||||
|
//flModel.MinGb = types.Int32Value(f.MinGB)
|
||||||
|
}
|
||||||
|
|
||||||
// Generate API request body from model
|
// Generate API request body from model
|
||||||
payload, err := toCreatePayload(ctx, &data)
|
payload, err := toCreatePayload(ctx, &data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -256,7 +369,7 @@ func (r *instanceResource) Create(ctx context.Context, req resource.CreateReques
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
|
func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
|
||||||
var data resourceModel
|
var data LocalInstanceModel
|
||||||
|
|
||||||
// Read Terraform prior state data into the model
|
// Read Terraform prior state data into the model
|
||||||
resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
|
resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
|
||||||
|
|
@ -309,7 +422,7 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *instanceResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
|
func (r *instanceResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
|
||||||
var data resourceModel
|
var data LocalInstanceModel
|
||||||
updateInstanceError := "Error updating instance"
|
updateInstanceError := "Error updating instance"
|
||||||
|
|
||||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
|
resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
|
||||||
|
|
@ -354,8 +467,8 @@ func (r *instanceResource) Update(ctx context.Context, req resource.UpdateReques
|
||||||
|
|
||||||
waitResp, err := wait.
|
waitResp, err := wait.
|
||||||
UpdateInstanceWaitHandler(ctx, r.client.DefaultAPI, projectID, instanceID, region).
|
UpdateInstanceWaitHandler(ctx, r.client.DefaultAPI, projectID, instanceID, region).
|
||||||
SetSleepBeforeWait(15 * time.Second).
|
SetSleepBeforeWait(10 * time.Second).
|
||||||
SetTimeout(45 * time.Minute).
|
SetTimeout(90 * time.Minute).
|
||||||
WaitWithContext(ctx)
|
WaitWithContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
core.LogAndAddError(
|
core.LogAndAddError(
|
||||||
|
|
@ -389,7 +502,7 @@ func (r *instanceResource) Update(ctx context.Context, req resource.UpdateReques
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *instanceResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
|
func (r *instanceResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
|
||||||
var data resourceModel
|
var data LocalInstanceModel
|
||||||
|
|
||||||
// Read Terraform prior state data into the model
|
// Read Terraform prior state data into the model
|
||||||
resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
|
resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
|
||||||
|
|
@ -416,7 +529,10 @@ func (r *instanceResource) Delete(ctx context.Context, req resource.DeleteReques
|
||||||
|
|
||||||
ctx = core.LogResponse(ctx)
|
ctx = core.LogResponse(ctx)
|
||||||
|
|
||||||
delResp, err := wait.DeleteInstanceWaitHandler(ctx, r.client.DefaultAPI, projectID, instanceID, region).WaitWithContext(ctx)
|
delResp, err := wait.DeleteInstanceWaitHandler(ctx, r.client.DefaultAPI, projectID, instanceID, region).
|
||||||
|
SetSleepBeforeWait(10 * time.Second).
|
||||||
|
SetTimeout(90 * time.Minute).
|
||||||
|
WaitWithContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
core.LogAndAddError(
|
core.LogAndAddError(
|
||||||
ctx,
|
ctx,
|
||||||
|
|
|
||||||
|
|
@ -139,6 +139,7 @@ func InstanceResourceSchema(ctx context.Context) schema.Schema {
|
||||||
Validators: []validator.String{
|
Validators: []validator.String{
|
||||||
stringvalidator.OneOf(
|
stringvalidator.OneOf(
|
||||||
"eu01",
|
"eu01",
|
||||||
|
"eu02",
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,85 @@
|
||||||
|
package sqlserverflexbeta
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
||||||
|
)
|
||||||
|
|
||||||
|
type useStateForUnknownIfFlavorUnchangedModifier struct {
|
||||||
|
Req resource.SchemaRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
// UseStateForUnknownIfFlavorUnchanged returns a plan modifier similar to UseStateForUnknown
|
||||||
|
// if the RAM and CPU values are not changed in the plan. Otherwise, the plan modifier does nothing.
|
||||||
|
func UseStateForUnknownIfFlavorUnchanged(req resource.SchemaRequest) planmodifier.String {
|
||||||
|
return useStateForUnknownIfFlavorUnchangedModifier{
|
||||||
|
Req: req,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m useStateForUnknownIfFlavorUnchangedModifier) Description(context.Context) string {
|
||||||
|
return "UseStateForUnknownIfFlavorUnchanged returns a plan modifier similar to UseStateForUnknown if the RAM and CPU values are not changed in the plan. Otherwise, the plan modifier does nothing."
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m useStateForUnknownIfFlavorUnchangedModifier) MarkdownDescription(ctx context.Context) string {
|
||||||
|
return m.Description(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m useStateForUnknownIfFlavorUnchangedModifier) PlanModifyString(ctx context.Context, req planmodifier.StringRequest, resp *planmodifier.StringResponse) { // nolint:gocritic // function signature required by Terraform
|
||||||
|
// Do nothing if there is no state value.
|
||||||
|
if req.StateValue.IsNull() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do nothing if there is a known planned value.
|
||||||
|
if !req.PlanValue.IsUnknown() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do nothing if there is an unknown configuration value, otherwise interpolation gets messed up.
|
||||||
|
if req.ConfigValue.IsUnknown() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// The above checks are taken from the UseStateForUnknown plan modifier implementation
|
||||||
|
// (https://github.com/hashicorp/terraform-plugin-framework/blob/main/resource/schema/stringplanmodifier/use_state_for_unknown.go#L38)
|
||||||
|
|
||||||
|
var stateModel LocalInstanceModel
|
||||||
|
diags := req.State.Get(ctx, &stateModel)
|
||||||
|
resp.Diagnostics.Append(diags...)
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var stateFlavor = &LocalFlavorModel{}
|
||||||
|
if !(stateModel.Flavor.IsNull() || stateModel.Flavor.IsUnknown()) {
|
||||||
|
diags = stateModel.Flavor.As(ctx, stateFlavor, basetypes.ObjectAsOptions{})
|
||||||
|
resp.Diagnostics.Append(diags...)
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var planModel LocalInstanceModel
|
||||||
|
diags = req.Plan.Get(ctx, &planModel)
|
||||||
|
resp.Diagnostics.Append(diags...)
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var planFlavor = &LocalFlavorModel{}
|
||||||
|
if !(planModel.Flavor.IsNull() || planModel.Flavor.IsUnknown()) {
|
||||||
|
diags = planModel.Flavor.As(ctx, planFlavor, basetypes.ObjectAsOptions{})
|
||||||
|
resp.Diagnostics.Append(diags...)
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if planFlavor.CPU == stateFlavor.CPU && planFlavor.RAM == stateFlavor.RAM {
|
||||||
|
resp.PlanValue = req.StateValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -158,7 +158,8 @@ func TestAccInstance(t *testing.T) {
|
||||||
PreConfig: func() {
|
PreConfig: func() {
|
||||||
t.Logf("testing: %s - %s", t.Name(), "create and verify")
|
t.Logf("testing: %s - %s", t.Name(), "create and verify")
|
||||||
},
|
},
|
||||||
ExpectNonEmptyPlan: true,
|
// empty refresh plan
|
||||||
|
ExpectNonEmptyPlan: false,
|
||||||
Config: testutils.StringFromTemplateMust(
|
Config: testutils.StringFromTemplateMust(
|
||||||
"testdata/instance_template.gompl",
|
"testdata/instance_template.gompl",
|
||||||
exData,
|
exData,
|
||||||
|
|
@ -181,7 +182,7 @@ func TestAccInstance(t *testing.T) {
|
||||||
PreConfig: func() {
|
PreConfig: func() {
|
||||||
t.Logf("testing: %s - %s", t.Name(), "update name and verify")
|
t.Logf("testing: %s - %s", t.Name(), "update name and verify")
|
||||||
},
|
},
|
||||||
ExpectNonEmptyPlan: true,
|
ExpectNonEmptyPlan: false,
|
||||||
Config: testutils.StringFromTemplateMust(
|
Config: testutils.StringFromTemplateMust(
|
||||||
"testdata/instance_template.gompl",
|
"testdata/instance_template.gompl",
|
||||||
updNameData,
|
updNameData,
|
||||||
|
|
@ -195,12 +196,23 @@ func TestAccInstance(t *testing.T) {
|
||||||
defaultNoEncInstanceTestChecks(testInstanceID, updNameData),
|
defaultNoEncInstanceTestChecks(testInstanceID, updNameData),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
// Expect empty plan after update
|
||||||
|
{
|
||||||
|
PreConfig: func() {
|
||||||
|
t.Logf("testing: %s - %s", t.Name(), "expect empty plan")
|
||||||
|
},
|
||||||
|
ExpectNonEmptyPlan: false,
|
||||||
|
Config: testutils.StringFromTemplateMust(
|
||||||
|
"testdata/instance_template.gompl",
|
||||||
|
updNameData,
|
||||||
|
),
|
||||||
|
},
|
||||||
// Update size and verify
|
// Update size and verify
|
||||||
{
|
{
|
||||||
PreConfig: func() {
|
PreConfig: func() {
|
||||||
t.Logf("testing: %s - %s", t.Name(), "update storage.size and verify")
|
t.Logf("testing: %s - %s", t.Name(), "update storage.size and verify")
|
||||||
},
|
},
|
||||||
ExpectNonEmptyPlan: true,
|
ExpectNonEmptyPlan: false,
|
||||||
Config: testutils.StringFromTemplateMust(
|
Config: testutils.StringFromTemplateMust(
|
||||||
"testdata/instance_template.gompl",
|
"testdata/instance_template.gompl",
|
||||||
updSizeData,
|
updSizeData,
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,7 @@ func UserDataSourceSchema(ctx context.Context) schema.Schema {
|
||||||
Validators: []validator.String{
|
Validators: []validator.String{
|
||||||
stringvalidator.OneOf(
|
stringvalidator.OneOf(
|
||||||
"eu01",
|
"eu01",
|
||||||
|
"eu02",
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -308,7 +308,7 @@ func (r *userResource) Create(
|
||||||
region,
|
region,
|
||||||
userId,
|
userId,
|
||||||
).SetSleepBeforeWait(
|
).SetSleepBeforeWait(
|
||||||
90 * time.Second,
|
10 * time.Second,
|
||||||
).SetTimeout(
|
).SetTimeout(
|
||||||
90 * time.Minute,
|
90 * time.Minute,
|
||||||
).WaitWithContext(ctx)
|
).WaitWithContext(ctx)
|
||||||
|
|
@ -459,23 +459,23 @@ func (r *userResource) Delete(
|
||||||
|
|
||||||
ctx = core.InitProviderContext(ctx)
|
ctx = core.InitProviderContext(ctx)
|
||||||
|
|
||||||
projectId := model.ProjectId.ValueString()
|
projectID := model.ProjectId.ValueString()
|
||||||
instanceId := model.InstanceId.ValueString()
|
instanceID := model.InstanceId.ValueString()
|
||||||
userId := model.UserId.ValueInt64()
|
userID := model.UserId.ValueInt64()
|
||||||
region := model.Region.ValueString()
|
region := model.Region.ValueString()
|
||||||
ctx = tflog.SetField(ctx, "project_id", projectId)
|
ctx = tflog.SetField(ctx, "project_id", projectID)
|
||||||
ctx = tflog.SetField(ctx, "instance_id", instanceId)
|
ctx = tflog.SetField(ctx, "instance_id", instanceID)
|
||||||
ctx = tflog.SetField(ctx, "user_id", userId)
|
ctx = tflog.SetField(ctx, "user_id", userID)
|
||||||
ctx = tflog.SetField(ctx, "region", region)
|
ctx = tflog.SetField(ctx, "region", region)
|
||||||
|
|
||||||
// Delete existing record set
|
// Delete existing record set
|
||||||
// err := r.client.DeleteUserRequest(ctx, projectId, region, instanceId, userId).Execute()
|
// err := r.client.DeleteUserRequest(ctx, projectId, region, instanceId, userId).Execute()
|
||||||
err := r.client.DefaultAPI.DeleteUserRequest(ctx, projectId, region, instanceId, userId).Execute()
|
err := r.client.DefaultAPI.DeleteUserRequest(ctx, projectID, region, instanceID, userID).Execute()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
var oapiErr *oapierror.GenericOpenAPIError
|
var oapiErr *oapierror.GenericOpenAPIError
|
||||||
ok := errors.As(err, &oapiErr)
|
ok := errors.As(err, &oapiErr)
|
||||||
if !ok {
|
if !ok {
|
||||||
// TODO err handling
|
core.LogAndAddError(ctx, &resp.Diagnostics, "User Delete Error", fmt.Sprintf("error is no oapi error: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -487,12 +487,14 @@ func (r *userResource) Delete(
|
||||||
// tflog.Warn(ctx, "[delete user] Wait handler got error 500")
|
// tflog.Warn(ctx, "[delete user] Wait handler got error 500")
|
||||||
// return false, nil, nil
|
// return false, nil, nil
|
||||||
default:
|
default:
|
||||||
// TODO err handling
|
core.LogAndAddError(ctx, &resp.Diagnostics, "User Delete Error", fmt.Sprintf("Unexpected API error: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Delete existing record set
|
// Delete existing record set
|
||||||
_, err = sqlserverflexbetaWait.DeleteUserWaitHandler(ctx, r.client.DefaultAPI, projectId, region, instanceId, userId).
|
_, err = sqlserverflexbetaWait.DeleteUserWaitHandler(ctx, r.client.DefaultAPI, projectID, region, instanceID, userID).
|
||||||
|
SetTimeout(90 * time.Minute).
|
||||||
|
SetSleepBeforeWait(10 * time.Second).
|
||||||
WaitWithContext(ctx)
|
WaitWithContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
core.LogAndAddError(ctx, &resp.Diagnostics, "User Delete Error", fmt.Sprintf("Calling API: %v", err))
|
core.LogAndAddError(ctx, &resp.Diagnostics, "User Delete Error", fmt.Sprintf("Calling API: %v", err))
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,7 @@ func UserResourceSchema(ctx context.Context) schema.Schema {
|
||||||
Validators: []validator.String{
|
Validators: []validator.String{
|
||||||
stringvalidator.OneOf(
|
stringvalidator.OneOf(
|
||||||
"eu01",
|
"eu01",
|
||||||
|
"eu02",
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ import (
|
||||||
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
|
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
|
||||||
)
|
)
|
||||||
|
|
||||||
func VersionDataSourceSchema(ctx context.Context) schema.Schema {
|
func VersionsDataSourceSchema(ctx context.Context) schema.Schema {
|
||||||
return schema.Schema{
|
return schema.Schema{
|
||||||
Attributes: map[string]schema.Attribute{
|
Attributes: map[string]schema.Attribute{
|
||||||
"project_id": schema.StringAttribute{
|
"project_id": schema.StringAttribute{
|
||||||
|
|
@ -26,12 +26,13 @@ func VersionDataSourceSchema(ctx context.Context) schema.Schema {
|
||||||
MarkdownDescription: "The STACKIT project ID.",
|
MarkdownDescription: "The STACKIT project ID.",
|
||||||
},
|
},
|
||||||
"region": schema.StringAttribute{
|
"region": schema.StringAttribute{
|
||||||
Required: true,
|
Optional: true,
|
||||||
Description: "The region which should be addressed",
|
Description: "The region which should be addressed",
|
||||||
MarkdownDescription: "The region which should be addressed",
|
MarkdownDescription: "The region which should be addressed",
|
||||||
Validators: []validator.String{
|
Validators: []validator.String{
|
||||||
stringvalidator.OneOf(
|
stringvalidator.OneOf(
|
||||||
"eu01",
|
"eu01",
|
||||||
|
"eu02",
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -73,7 +74,7 @@ func VersionDataSourceSchema(ctx context.Context) schema.Schema {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type VersionModel struct {
|
type VersionsModel struct {
|
||||||
ProjectId types.String `tfsdk:"project_id"`
|
ProjectId types.String `tfsdk:"project_id"`
|
||||||
Region types.String `tfsdk:"region"`
|
Region types.String `tfsdk:"region"`
|
||||||
Versions types.List `tfsdk:"versions"`
|
Versions types.List `tfsdk:"versions"`
|
||||||
|
|
@ -58,10 +58,10 @@ func CreateInstanceWaitHandler(
|
||||||
) *wait.AsyncActionHandler[v3alpha1api.GetInstanceResponse] {
|
) *wait.AsyncActionHandler[v3alpha1api.GetInstanceResponse] {
|
||||||
instanceCreated := false
|
instanceCreated := false
|
||||||
var instanceGetResponse *v3alpha1api.GetInstanceResponse
|
var instanceGetResponse *v3alpha1api.GetInstanceResponse
|
||||||
maxWait := time.Minute * 45
|
maxWait := time.Minute * 90
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
extendedTimeout := 0
|
extendedTimeout := 0
|
||||||
maxFailedCount := 3
|
maxFailedCount := 10
|
||||||
failedCount := 0
|
failedCount := 0
|
||||||
|
|
||||||
handler := wait.New(
|
handler := wait.New(
|
||||||
|
|
@ -129,7 +129,7 @@ func CreateInstanceWaitHandler(
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
var waitCounter int64 = 1
|
var waitCounter int64 = 1
|
||||||
maxWaitInt := big.NewInt(7)
|
maxWaitInt := big.NewInt(10)
|
||||||
n, randErr := rand.Int(rand.Reader, maxWaitInt)
|
n, randErr := rand.Int(rand.Reader, maxWaitInt)
|
||||||
if randErr == nil {
|
if randErr == nil {
|
||||||
waitCounter = n.Int64() + 1
|
waitCounter = n.Int64() + 1
|
||||||
|
|
@ -281,8 +281,8 @@ func GetDatabaseByIdWaitHandler(
|
||||||
if databaseID > math.MaxInt32 {
|
if databaseID > math.MaxInt32 {
|
||||||
return false, nil, fmt.Errorf("databaseID too large for int32")
|
return false, nil, fmt.Errorf("databaseID too large for int32")
|
||||||
}
|
}
|
||||||
dbId32 := int32(databaseID) //nolint:gosec // is checked above
|
dbID32 := int32(databaseID) //nolint:gosec // is checked above
|
||||||
s, err := a.GetDatabaseRequest(ctx, projectID, region, instanceID, dbId32).Execute()
|
s, err := a.GetDatabaseRequest(ctx, projectID, region, instanceID, dbID32).Execute()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
var oapiErr *oapierror.GenericOpenAPIError
|
var oapiErr *oapierror.GenericOpenAPIError
|
||||||
ok := errors.As(err, &oapiErr)
|
ok := errors.As(err, &oapiErr)
|
||||||
|
|
@ -290,6 +290,7 @@ func GetDatabaseByIdWaitHandler(
|
||||||
return false, nil, fmt.Errorf("could not convert error to oapierror.GenericOpenAPIError")
|
return false, nil, fmt.Errorf("could not convert error to oapierror.GenericOpenAPIError")
|
||||||
}
|
}
|
||||||
switch oapiErr.StatusCode {
|
switch oapiErr.StatusCode {
|
||||||
|
// TODO: work-around
|
||||||
case http.StatusBadGateway, http.StatusGatewayTimeout, http.StatusServiceUnavailable:
|
case http.StatusBadGateway, http.StatusGatewayTimeout, http.StatusServiceUnavailable:
|
||||||
tflog.Warn(
|
tflog.Warn(
|
||||||
ctx, "api responded with 50[2,3,4] status", map[string]interface{}{
|
ctx, "api responded with 50[2,3,4] status", map[string]interface{}{
|
||||||
|
|
|
||||||
|
|
@ -89,9 +89,16 @@ func CreateInstanceWaitHandler(
|
||||||
return false, nil, fmt.Errorf("could not convert error to oapierror.GenericOpenAPIError: %w", err)
|
return false, nil, fmt.Errorf("could not convert error to oapierror.GenericOpenAPIError: %w", err)
|
||||||
}
|
}
|
||||||
switch oapiErr.StatusCode {
|
switch oapiErr.StatusCode {
|
||||||
|
case http.StatusOK:
|
||||||
|
return false, nil, nil
|
||||||
case http.StatusNotFound:
|
case http.StatusNotFound:
|
||||||
return false, nil, nil
|
return false, nil, nil
|
||||||
default:
|
default:
|
||||||
|
// TODO: work-around
|
||||||
|
if strings.Contains(err.Error(), "is not a valid InstanceEdition") {
|
||||||
|
tflog.Info(ctx, "API WORKAROUND", map[string]interface{}{"err": err})
|
||||||
|
return false, nil, nil
|
||||||
|
}
|
||||||
return false, nil, fmt.Errorf("api error: %w", err)
|
return false, nil, fmt.Errorf("api error: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -257,7 +264,6 @@ func DeleteInstanceWaitHandler(
|
||||||
return true, nil, nil
|
return true, nil, nil
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
handler.SetTimeout(30 * time.Minute)
|
|
||||||
return handler
|
return handler
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -399,7 +405,5 @@ func DeleteUserWaitHandler(
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
handler.SetTimeout(15 * time.Minute)
|
|
||||||
handler.SetSleepBeforeWait(15 * time.Second)
|
|
||||||
return handler
|
return handler
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,11 @@ import (
|
||||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||||
sdkauth "github.com/stackitcloud/stackit-sdk-go/core/auth"
|
sdkauth "github.com/stackitcloud/stackit-sdk-go/core/auth"
|
||||||
"github.com/stackitcloud/stackit-sdk-go/core/config"
|
"github.com/stackitcloud/stackit-sdk-go/core/config"
|
||||||
|
sqlserverFlexBetaFlavor "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexbeta/flavor"
|
||||||
|
|
||||||
sqlserverflexalphaDatabase "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/database"
|
//sqlserverflexalphaDatabase "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/database"
|
||||||
sqlserverflexalphaInstance "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/instance"
|
//sqlserverflexalphaInstance "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/instance"
|
||||||
sqlserverflexalphaUser "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/user"
|
//sqlserverflexalphaUser "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/user"
|
||||||
sqlserverflexbetaUser "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexbeta/user"
|
|
||||||
|
|
||||||
"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/core"
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/features"
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/features"
|
||||||
|
|
@ -36,7 +36,7 @@ import (
|
||||||
|
|
||||||
sqlserverFlexBetaDatabase "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexbeta/database"
|
sqlserverFlexBetaDatabase "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexbeta/database"
|
||||||
sqlserverflexBetaInstance "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexbeta/instance"
|
sqlserverflexBetaInstance "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexbeta/instance"
|
||||||
// sqlserverFlexBetaUser "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexbetaUser/user"
|
sqlserverflexbetaUser "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexbeta/user"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Ensure the implementation satisfies the expected interfaces
|
// Ensure the implementation satisfies the expected interfaces
|
||||||
|
|
@ -536,14 +536,14 @@ func (p *Provider) DataSources(_ context.Context) []func() datasource.DataSource
|
||||||
postgresflexalphaFlavors.NewFlavorsDataSource,
|
postgresflexalphaFlavors.NewFlavorsDataSource,
|
||||||
|
|
||||||
// sqlserverFlexAlphaFlavor.NewFlavorDataSource,
|
// sqlserverFlexAlphaFlavor.NewFlavorDataSource,
|
||||||
sqlserverflexalphaInstance.NewInstanceDataSource,
|
//sqlserverflexalphaInstance.NewInstanceDataSource,
|
||||||
sqlserverflexalphaUser.NewUserDataSource,
|
//sqlserverflexalphaUser.NewUserDataSource,
|
||||||
sqlserverflexalphaDatabase.NewDatabaseDataSource,
|
//sqlserverflexalphaDatabase.NewDatabaseDataSource,
|
||||||
|
|
||||||
sqlserverFlexBetaDatabase.NewDatabaseDataSource,
|
sqlserverFlexBetaDatabase.NewDatabaseDataSource,
|
||||||
sqlserverflexBetaInstance.NewInstanceDataSource,
|
sqlserverflexBetaInstance.NewInstanceDataSource,
|
||||||
sqlserverflexbetaUser.NewUserDataSource,
|
sqlserverflexbetaUser.NewUserDataSource,
|
||||||
// sqlserverFlexBetaFlavor.NewFlavorDataSource,
|
sqlserverFlexBetaFlavor.NewFlavorDataSource,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -554,9 +554,9 @@ func (p *Provider) Resources(_ context.Context) []func() resource.Resource {
|
||||||
postgresFlexAlphaUser.NewUserResource,
|
postgresFlexAlphaUser.NewUserResource,
|
||||||
postgresFlexAlphaDatabase.NewDatabaseResource,
|
postgresFlexAlphaDatabase.NewDatabaseResource,
|
||||||
|
|
||||||
sqlserverflexalphaInstance.NewInstanceResource,
|
//sqlserverflexalphaInstance.NewInstanceResource,
|
||||||
sqlserverflexalphaUser.NewUserResource,
|
//sqlserverflexalphaUser.NewUserResource,
|
||||||
sqlserverflexalphaDatabase.NewDatabaseResource,
|
//sqlserverflexalphaDatabase.NewDatabaseResource,
|
||||||
|
|
||||||
sqlserverflexBetaInstance.NewInstanceResource,
|
sqlserverflexBetaInstance.NewInstanceResource,
|
||||||
sqlserverflexbetaUser.NewUserResource,
|
sqlserverflexbetaUser.NewUserResource,
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,6 @@ import (
|
||||||
|
|
||||||
"github.com/google/go-cmp/cmp"
|
"github.com/google/go-cmp/cmp"
|
||||||
|
|
||||||
sqlserverflexalphaDatabase "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/database"
|
|
||||||
|
|
||||||
//nolint:staticcheck // used for acceptance testing
|
//nolint:staticcheck // used for acceptance testing
|
||||||
postgresFlexAlphaFlavor "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/flavor"
|
postgresFlexAlphaFlavor "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/flavor"
|
||||||
|
|
||||||
|
|
@ -23,8 +21,6 @@ import (
|
||||||
postgresflexalphaFlavors "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/flavors"
|
postgresflexalphaFlavors "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/flavors"
|
||||||
postgresFlexAlphaInstance "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/instance"
|
postgresFlexAlphaInstance "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/instance"
|
||||||
postgresFlexAlphaUser "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/user"
|
postgresFlexAlphaUser "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/user"
|
||||||
sqlserverFlexAlphaInstance "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/instance"
|
|
||||||
sqlserverFlexAlphaUser "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/user"
|
|
||||||
sqlserverflexBetaDatabase "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexbeta/database"
|
sqlserverflexBetaDatabase "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexbeta/database"
|
||||||
sqlserverFlexBetaInstance "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexbeta/instance"
|
sqlserverFlexBetaInstance "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexbeta/instance"
|
||||||
sqlserverFlexBetaUser "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexbeta/user"
|
sqlserverFlexBetaUser "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexbeta/user"
|
||||||
|
|
@ -63,9 +59,9 @@ func TestUnitProviderHasChildDataSources_Basic(t *testing.T) {
|
||||||
postgresflexalphaFlavors.NewFlavorsDataSource(),
|
postgresflexalphaFlavors.NewFlavorsDataSource(),
|
||||||
|
|
||||||
// sqlserverFlexAlphaFlavor.NewFlavorDataSource(),
|
// sqlserverFlexAlphaFlavor.NewFlavorDataSource(),
|
||||||
sqlserverFlexAlphaInstance.NewInstanceDataSource(),
|
//sqlserverFlexAlphaInstance.NewInstanceDataSource(),
|
||||||
sqlserverFlexAlphaUser.NewUserDataSource(),
|
//sqlserverFlexAlphaUser.NewUserDataSource(),
|
||||||
sqlserverflexalphaDatabase.NewDatabaseDataSource(),
|
//sqlserverflexalphaDatabase.NewDatabaseDataSource(),
|
||||||
|
|
||||||
sqlserverflexBetaDatabase.NewDatabaseDataSource(),
|
sqlserverflexBetaDatabase.NewDatabaseDataSource(),
|
||||||
sqlserverFlexBetaInstance.NewInstanceDataSource(),
|
sqlserverFlexBetaInstance.NewInstanceDataSource(),
|
||||||
|
|
@ -99,9 +95,9 @@ func TestUnitProviderHasChildResources_Basic(t *testing.T) {
|
||||||
postgresFlexAlphaUser.NewUserResource(),
|
postgresFlexAlphaUser.NewUserResource(),
|
||||||
postgresFlexAlphaDatabase.NewDatabaseResource(),
|
postgresFlexAlphaDatabase.NewDatabaseResource(),
|
||||||
|
|
||||||
sqlserverFlexAlphaInstance.NewInstanceResource(),
|
//sqlserverFlexAlphaInstance.NewInstanceResource(),
|
||||||
sqlserverFlexAlphaUser.NewUserResource(),
|
//sqlserverFlexAlphaUser.NewUserResource(),
|
||||||
sqlserverflexalphaDatabase.NewDatabaseResource(),
|
//sqlserverflexalphaDatabase.NewDatabaseResource(),
|
||||||
|
|
||||||
sqlserverFlexBetaInstance.NewInstanceResource(),
|
sqlserverFlexBetaInstance.NewInstanceResource(),
|
||||||
sqlserverFlexBetaUser.NewUserResource(),
|
sqlserverFlexBetaUser.NewUserResource(),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue