0
0
mirror of https://github.com/bpg/terraform-provider-proxmox.git synced 2025-06-30 02:31:10 +00:00

chore(tests): add script to test/view api-authentication successes/failures (#1562)

feat(Makefile): add script to test/view api-authentication successes/failures

Signed-off-by: vanillaSprinkles <vanillaSprinkles@users.noreply.github.com>
This commit is contained in:
vanillaSprinkles 2024-10-15 14:38:47 +00:00 committed by GitHub
parent ac3ab1e66f
commit bce2ceb522
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 676 additions and 1 deletions

View File

@ -31,10 +31,11 @@ clean:
rm -rf ./dist
rm -rf ./cache
rm -rf ./build
rm -f ./example/test-api-creds-auth/outs_cred-tester__expect_*
.PHONY: build
build:
mkdir -p "$(TERRAFORM_PLUGIN_OUTPUT_DIRECTORY)"
mkdir -p "$(TERRAFORM_PLUGIN_OUTPUT_DIRECTORY)" "$(TERRAFORM_PLUGIN_CACHE_DIRECTORY)"
rm -f "$(TERRAFORM_PLUGIN_EXECUTABLE)"
go build -o "$(TERRAFORM_PLUGIN_EXECUTABLE)"
@ -80,6 +81,15 @@ example-plan:
&& cd ./example \
&& $(TERRAFORM_EXECUTABLE) plan
.PHONY: test-api-creds-auth
test-api-creds-auth:
rm -f ./example/test-api-creds-auth/outs_cred-tester__expect_*
export TF_CLI_CONFIG_FILE="$(shell pwd -P)/example/test-api-creds-auth/example.tfrc" \
&& export TF_DISABLE_CHECKPOINT="true" \
&& export TF_PLUGIN_CACHE_DIR="$(TERRAFORM_PLUGIN_CACHE_DIRECTORY)" \
&& cd ./example/test-api-creds-auth \
&& ./api-creds-tester.sh $(TERRAFORM_EXECUTABLE)
.PHONY: fmt
fmt:
gofmt -s -w $$(find . -name '*.go')

View File

@ -0,0 +1,2 @@
cred-tester.config.sh*
outs_cred-tester__expect_*.log

View File

@ -0,0 +1,623 @@
#!/usr/bin/env bash
## requires: python, pyotp, gawk, jq, curl, tofu/terraform
##### arg1 (optional) is the TF Binary (tofu, terraform, /path/to/...)
## TODO:
## remove PROXMOX_VE_OTP support
## test credential presidence in 'fake' section
## remove less-important fake tests
## handle python requirements.txt (pyotp)
this_shell_config_file="cred-tester.config.sh"
TF_PLAN_EXTRA_ARGS=()
##### create cred-tester config-shell-file if it does not exist
if [[ -e "${this_shell_config_file}" ]]; then
source "${this_shell_config_file}"
else
printf '\ncred tester config file does not exist; creating sample file: "%s"\n' "${this_shell_config_file}"
cat <<'EOF' > "${this_shell_config_file}"
#/usr/bin/env bash
##### this file is sourced by the cred-tester script
export PROXMOX_VE_ENDPOINT="${PROXMOX_VE_ENDPOINT:-https://127.0.0.1:8006/}" ## if unset, use localhost
TF_Output_colorized=1 ## 0 disables color, 1 enables
#### real/fake start/end overrides are inclusive (allows for skipping tests)
### test-sets begin numbering with '1'
### skip real/fake by setting the start-override to a large number
# real_start_override=1
# real_end_override=3
# fake_start_override=1
# fake_end_override=10
curl_connect_timeout=5
# debug_print_env_var_values=0 ## 1 enables; any other value disables
# debug_print_arg_var_values=0 ## 1 enables; any other value disables
#### required: admin creds should have power to unlock a users totp
### topt user(s) will get locked out due to too many failures
admin_un='admin@pam'
admin_pw='secrets'
admin_totp_s=''
#### test cred sets
### real creds
real_type_1='api_token [pve]'
real_api_token_1='test1@pve!tokenName=hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh'
real_type_2='user [pam] + pass'
real_un_2='test2@pam'
real_pw_2='secrets'
real_type_3='user [pve] + pass + otp (aka totpS via totp-secret to otp)'
real_un_3='test3@pve'
real_pw_3='secrets'
real_totp_s_3='HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH'
# real_type_4='pre-auth auth-ticket + csrf-token'
# real_auth_ticket_4=''
# real_csrf_token_4=''
fake_totp_s='CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC'
fake_csrf='19870727:TmV2ckdvbm5hR2l2VVVwTmV2ckdvbm5hTGV0VURvd24'
fake_ticket='PVE:base64@pve:19870727::UmljayBBc3RsZXk6IEkganVzdCB3YW5uYSB0ZWxsIHlvdSBob3cgSSdtIGZlZWxpbmcuIEdvdHRhIG1ha2UgeW91IHVuZGVyc3RhbmQuIE5ldmVyIGdvbm5hIGdpdmUgeW91IHVwLiBOZXZlciBnb25uYSBsZXQgeW91IGRvd24uIE5ldmVyIGdvbm5hIHJ1biBhcm91bmQgYW5kIGRlc2VydCB5b3UuIE5ldmVyIGdvbm5hIG1ha2UgeW91IGNyeS4gTmV2ZXIgZ29ubmEgc2F5IGdvb2RieWUuIE5ldmVyIGdvbm5hIHRlbGwgYSBsaWUgYW5kIGh1cnQgeW91Lg=='
### fake creds
## TODO
## filter out less-interesting tests
## add all cred methods to tests ( user+pass, api-token, auth-ticket+csrf ) with combinations to fail with [to test credential precidence]
fake_type_1='api_token [fake]'
fake_api_token_1='fake@pve!faker=aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'
fake_type_2='un+pw [real] + totpS [real] + csrf [fake]'
fake_un_2=$real_un_3
fake_pw_2=$real_pw_3
fake_totp_s_2=$real_totp_s_3
fake_csrf_2=$fake_csrf
fake_type_3='ticket [fake] + csrf [fake]'
fake_auth_ticket_3=$fake_ticket
fake_csrf_token_3=$fake_csrf
fake_type_4='user [real pam] + pass [fake]'
fake_un_4=$real_un_2
fake_pw_4='this_dont_work'
fake_type_5='user [fake pam] + pass [fake]'
fake_un_5='nope@pam'
fake_pw_5='this_dont_work'
fake_type_6='user [fake pve] + pass [fake]'
fake_un_6='nope@pve'
fake_pw_6='this_dont_work'
## less interesting-ish
fake_type_7='user [pve] + pass + otp [fake] (aka totpS via totp-secret to otp)'
fake_un_7=$real_un_3
fake_pw_7=$real_pw_3
fake_totp_s_7=$fake_totp_s
fake_type_8='user [pve] + pass - otp (aka totpS via totp-secret to otp)'
fake_un_8=$real_un_3
fake_pw_8=$real_pw_3
fake_type_9='user [pve] + pass [fake] + otp [fake] (aka totpS via totp-secret to otp)'
fake_un_9=$real_un_3
fake_pw_9='this_dont_work'
fake_totp_s_9=$fake_totp_s
fake_type_10='user [fake pve] + pass [fake] + otp [fake] (aka totpS via totp-secret to otp)'
fake_un_10='nope@pve'
fake_pw_10='this_dont_work'
fake_totp_s_10=$fake_totp_s
EOF
exit
fi
##### helper funcs
### same logic as makefile to determine tofu or terraform
### then override with arg1 if applicable
if [[ "$(tofu -version 2>/dev/null)" == "" ]]; then
TF_APP=terraform
else
TF_APP=tofu
fi
export TF_APP="${1:-"${TF_APP}"}"
## TODO: check app is run-able (-x needs full path)
#if [[ ! -x "${TF_APP}" ]]; then
# printf 'ERROR: TF App is not executable or does not exit: %s\n' "${TF_APP}"
# exit 1
#fi
### function to print TF arg-var names for in-line provider testing
### optional toggle-var (debug_print_arg_var_values) to print values
print_proxmox_arg_var_names() {
## required argvars/list of args sent to TF ( "${@}" )
printf ' set arg-vars: '
if [[ -n "${debug_print_arg_var_values}" && "${debug_print_arg_var_values}" == 1 ]]; then
##
printf '%s ' $( for x in "$@"; do if [[ "$x" != "-var" ]]; then echo "${x}"; fi ; done | sort )
else
printf '%s ' $( for x in "$@"; do if [[ "$x" != "-var" ]]; then echo "${x%%=*}"; fi ; done | sort )
fi
printf '\n'
}
### function to print TF variable names (excluding PROXMOX_VE_ENDPOINT)
### optional toggle-var (debug_print_env_var_values) to print values
print_proxmox_env_var_names() {
printf ' set cred-vars: '
if [[ -n "${debug_print_env_var_values}" && "${debug_print_env_var_values}" == 1 ]]; then
printf '%s ' $(env -0 | sort -z | xargs -0 -n1 | awk -F'=' '/^PROXMOX_/ && !/PROXMOX_VE_ENDPOINT/ && $2 > 0 {print $0}')
else
printf '%s ' $(env -0 | sort -z | xargs -0 -n1 | awk -F'=' '/^PROXMOX_/ && !/PROXMOX_VE_ENDPOINT/ && $2 > 0 {print $1}')
fi
printf '\n'
}
### function to send the unlock api call to a particular user
### especially handy when testing a legit user and fake pass (too many failures locks the totp)
curl_api_unlock_user_tfa() {
## required argvar: username@realm
local userid="$1" ## user@realm
local ticket
local csrf
if [[ -z "${userid}" ]]; then return; fi
## use read to set variables 'ticket' and 'csrf' from the bash-func api_auth with env-vars set and totpx
read -d $'\0' ticket csrf <<<"$( PROXMOX_VE_USERNAME=${admin_un} PROXMOX_VE_PASSWORD=${admin_pw} api_auth $( totp_secret_to_otp_func "${admin_totp_s}" ) )"
curl --connect-timeout ${curl_connect_timeout:-5} -q -s -k -H "X-API-AUTH-TOKEN: ${ticket}" -H "X-CSRF-TOKEN: ${csrf}" -X PUT "${PROXMOX_VE_ENDPOINT}api2/json/access/users/${userid}/unlock-tfa"
}
### function calling python to generate a TOTP token from a totp-secret
totp_secret_to_otp_func(){ STR=${1} python -c 'import pyotp; import os; import time; STR=os.getenv("STR", ""); totp = pyotp.TOTP(STR); print( totp.now() );' ; }
### function to call proxmox-api with a user+pass, and optional totp to get an auth_ticket and csrf_token
### endpoint, username, password are passed in via provider env-vars (PROXMOX_VE_ENDPOINT, PROXMOX_VE_USERNAME, PROXMOX_VE_PASSWORD)
api_auth() {
## optional arg1: totp value
local _user_totp_password=$1
local proxmox_api_ticket_path='api2/json/access/ticket' ## cannot have double "//" - ensure endpoint ends with a "/" and this string does not begin with a "/", or vice-versa
local api_resp=$( curl -q -s -k --data-urlencode "username=${PROXMOX_VE_USERNAME}" --data-urlencode "password=${PROXMOX_VE_PASSWORD}" "${PROXMOX_VE_ENDPOINT}${proxmox_api_ticket_path}" )
local auth_ticket=$( jq -r '.data.ticket' <<<"${api_resp}" )
local auth_csrf=$( jq -r '.data.CSRFPreventionToken' <<<"${api_resp}" )
if [[ $(jq -r '.data.NeedTFA' <<<"${api_resp}") == 1 ]]; then
api_resp=$( curl -q -s -k -H "CSRFPreventionToken: ${auth_csrf}" --data-urlencode "username=${PROXMOX_VE_USERNAME}" --data-urlencode "tfa-challenge=${auth_ticket}" --data-urlencode "password=totp:${_user_totp_password}" "${PROXMOX_VE_ENDPOINT}${proxmox_api_ticket_path}" )
auth_ticket=$( jq -r '.data.ticket' <<<"${api_resp}" )
auth_csrf=$( jq -r '.data.CSRFPreventionToken' <<<"${api_resp}" )
fi
printf '%s\n' "${auth_ticket}" "${auth_csrf}"
}
### optional color flag for TF
if [[ -n "${TF_Output_colorized}" && "${TF_Output_colorized}" == 0 ]]; then
TF_PLAN_EXTRA_ARGS+=('-no-color')
fi
### function which calls TF cmd
### arg-order matters; first 3 args are required test-output; remaining args are passed directly to TF
test_cmd() {
## required: pass/fail itr_num itr_part_num
local should_pass_or_fail=${1:pass}
shift
local test_iteration=${1:-itr-1}
shift
local test_part=${1:-part-1}
shift
local ret_expt=0
local res
local ret
local timenow=$(date --iso=s)
timenow=${timenow//:/_}
res=$( "${TF_APP}" plan "${TF_PLAN_EXTRA_ARGS[@]}" "$@" 2>&1 )
ret=$?
local msg_pass
local msg_fail
#msg_pass="passed ${should_pass_or_fail}-as-expected" # successfully pass-as-expected
#msg_fail="failed ${should_pass_or_fail}-as-expected" # failed pass-as-expected
if [[ "${should_pass_or_fail,,}" == "pass" ]]; then ## TODO: word these better
msg_pass="passed ${should_pass_or_fail}-check (expected pass and passed)" # successfully pass-as-expected
msg_fail="failed ${should_pass_or_fail}-check (expected pass; got an error) " # failed pass-as-expected
else
msg_pass="passed ${should_pass_or_fail}-check (expected error and errored)" # successfully fail-as-expected
msg_fail="failed ${should_pass_or_fail}-check (expected error; got no-errors)" # failed fail-as-expected
fi
local got_pass_or_fail
if [[ "${should_pass_or_fail,,}" == "pass" && "${ret}" == 0 ]] || [[ "${should_pass_or_fail,,}" != "pass" && "${ret}" != 0 ]]; then
printf ' test %i part %i %s\n' ${test_iteration} ${test_part} "${msg_pass}"
got_pass_or_fail='passed'
else
printf ' test %i part %i %s\n' ${test_iteration} ${test_part} "${msg_fail}"
got_pass_or_fail='failed'
fi
local logfile="outs_cred-tester__expect_${should_pass_or_fail}__${got_pass_or_fail}.${timenow}.log"
printf '%s\n' "${res}" > "${logfile}" ## write TF output to logfile
printf ' see TF-output in file: %s\n' "${logfile}"
## use gawk to capture the Errors and print to screen; colored vs not makes a monster
if [[ -n "${TF_Output_colorized}" && "${TF_Output_colorized}" == 0 ]]; then
<<<"${res}" gawk -v out_spaces=" " '/^Error:/ { S=1; BLOB=out_spaces $0 ; next } /^$/ { if(S==1){ nl++; if(nl>1){S=0;nl=0; print BLOB"\n" }else{ BLOB=BLOB"\n"out_spaces $0} } } !/^$/ { if(S==1){ BLOB=BLOB"\n"out_spaces $0} } END { if(S==1){ print BLOB } } '
else
## ansi-color friendly awk'er for tf-outputs (print Error blocks; can be expanded to include any word (eg Warning); change: "+Error:" to "+([A-Za-z]+:" )
## print only the errors ( use outs_spaces ) as line prefix (expect to be empty when test-for-failure and plan-passes (eg no tf-files)
<<<"${res}" gawk -v outs_spaces=" " -v str_bar=$'\xe2\x94\x82' -v str_bar_end=$'\xe2\x95\xb5' '{ raw=$0; gsub(/\x1b\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]/,""); } {if(S==1 && match($0,str_bar_end)) {S=0; print outs_spaces raw} } ; S==1 {print outs_spaces raw } { if(match($0, "^"str_bar" +Error:")) { S=1; print outs_spaces raw } } '
fi
}
printf 'test endpoint: %s\n' "${PROXMOX_VE_ENDPOINT}"
#### test real+fake UN + PW
### message formats + hard-code number of check-types per auth-set
_set_parts=4 ## aka number of "checks" per auth-set
real_test_msg_fmt='\npass-test (expect auth-success): set %i/%i %s/'${_set_parts}'; using %s %s: %s\n'
fake_test_msg_fmt='\nfail-test (expect auth-failure): set %i/%i %s/'${_set_parts}'; using %s %s: %s\n'
## expect: set-# fake/real_end-# "part 1/2" "env OR in-line" "raw-credentials OR auth-ticket" ${type}
## todo: ensure comment fmt-opts are correct
test_pre_auth_inline_empty_creds=0 ## want to test this once per run (many 'fake' tests cause this to be re-test if not caught)
#### while loop determining real/fake "end" numbers; starting at 1, checks consecutive vars and bails when both are set
real_start=1
real_end=
fake_start=1
fake_end=
_i=1
while :; do ## infinite loop; maybe break after i gets too high?
_real="real_type_${_i}"
_fake="fake_type_${_i}"
## bash indirect expansion / dynamic variables
## check if _real is a variable and that the value real expands to is not an empty value
## once i (real_type_2) is out of bounds/does not exist, sets real_too_far
## repeat for fake_type
## once both real and fake 'too_far' variables are set, break out of loop
if [[ -v "${_real}" && -n "${!_real}" ]]; then
real_end=$_i
else
real_too_far=$_i
fi
if [[ -v "${_fake}" && -n "${!_fake}" ]]; then
fake_end=$_i
else
fake_too_far=$_i
fi
if [[ -n "${real_too_far}" && -n "${fake_too_far}" ]]; then
break
fi
((_i++))
done
unset _i _real _fake real_too_far fake_too_far
#### nested for-loop
## first for-loop over "real" and "fake" as variable name prefixes
## then loop over each real/fake credential set
## cred tests order:
## raw-creds via env-vars
## raw-creds via in-line (using tf provider-block)
## pre-auth via env-vars
## pre-auth via in-line (using tf provider-block)
for loop_real_fake in "real" "fake" ; do
if [[ "${loop_real_fake}" == "real" ]]; then
loop_rf_pass_fail="pass"
else
loop_rf_pass_fail="fail"
fi
loop_rf_test_msg_fmt="${loop_real_fake}_test_msg_fmt" ## eg: loop_rf_test_msg_fmt="real_test_msg_fmt" (literal text)
loop_rf_test_msg_fmt="${!loop_rf_test_msg_fmt}" ## eg: loop_rf_test_msg_fmt= value of real_test_msg_fmt (variable expansion)
loop_rf_start="${loop_real_fake}_start"
loop_rf_start="${!loop_rf_start}"
loop_rf_end="${loop_real_fake}_end"
loop_rf_end="${!loop_rf_end}"
loop_rf_start_override="${loop_real_fake}_start_override"
loop_rf_start_override="${!loop_rf_start_override}"
loop_rf_end_override="${loop_real_fake}_end_override"
loop_rf_end_override="${!loop_rf_end_override}"
printf '\nShould %s:\n' "${loop_rf_pass_fail^}"
for (( i=${loop_rf_start}; i < ((loop_rf_end+1)) ; i++ )); do
#### if conditions: allow start/end overrides to skip select tests in order
if [[ -n "${loop_rf_start_override}" && "${loop_rf_start_override}" -gt "${i}" ]]; then
continue
fi
if [[ -n "${loop_rf_end_override}" && "${loop_rf_end_override}" -lt "${i}" ]]; then
printf '\nscript loop complete via real_end_override; range %i to %i inclusive\n' ${loop_rf_start_override} ${loop_rf_end_override}
break
fi
## enforce vars are not set
unset PROXMOX_VE_USERNAME PROXMOX_VE_PASSWORD PROXMOX_VE_OTP PROXMOX_VE_API_TOKEN PROXMOX_VE_AUTH_TICKET PROXMOX_VE_CSRF_PREVENTION_TOKEN test_cmd_args
## bash indirect expansions for fake/real values set in config (aka dynamic variables)
type="${loop_real_fake}_type_${i}" ## type="real_type_1
type="${!type}" ## indirect expansion, type set to value from real_type_1
un="${loop_real_fake}_un_${i}"
un="${!un}"
pw="${loop_real_fake}_pw_${i}"
pw="${!pw}"
totp_s="${loop_real_fake}_totp_s_${i}"
totp_s=${!totp_s}
auth_ticket="${loop_real_fake}_auth_ticket_${i}"
auth_ticket="${!auth_ticket}"
csrf_token="${loop_real_fake}_csrf_token_${i}"
csrf_token="${!csrf_token}"
apitok="${loop_real_fake}_api_token_${i}"
apitok="${!apitok}"
printf "\n##"
### raw-creds via env-vars
printf "${loop_rf_test_msg_fmt}" $i ${loop_rf_end} "part 1" "env" "raw-creds" "${type}"
curl_api_unlock_user_tfa "${un}"
if [ -n "${totp_s}" ]; then
export PROXMOX_VE_OTP=$( totp_secret_to_otp_func "${totp_s}" )
fi
export PROXMOX_VE_USERNAME=${un}
export PROXMOX_VE_PASSWORD=${pw}
if [[ -n "${apitok}" ]]; then
export PROXMOX_VE_API_TOKEN="${apitok}"
fi
print_proxmox_env_var_names
print_proxmox_arg_var_names "${test_cmd_args[@]}"
test_cmd ${loop_rf_pass_fail} ${i} 1 ## test with args: "real/fake" "itr" and part "1"
### raw-creds via in-line
printf "${loop_rf_test_msg_fmt}" $i ${loop_rf_end} "part 2" "in-line" "raw-creds" "${type}"
curl_api_unlock_user_tfa "${un}"
### array of TF cli credential-arguments (to ultimately set provider-config vars:
## username, password, otp, api_token
test_cmd_args=(
## ternary-ish; if cred-type var is set, create the TF cli-arg to pass in a variable override
## eg: if this loop's 'un' is set, append to the arg-array: -var username="$un"
# $( [[ -n "${auth_ticket}" ]] && printf '%s\n' "-var" auth_ticket="${auth_ticket}" ) ## consolidate test types would include ticket+csrf here
# $( [[ -n "${csrf_token}" ]] && printf '%s\n' "-var" csrf_prevention_token="${csrf_prevention_token}" )
$( [[ -n "${un}" ]] && printf '%s\n' "-var" username="${un}" )
$( [[ -n "${pw}" ]] && printf '%s\n' "-var" password="${pw}" )
$( [[ -n "${totp_s}" ]] && printf '%s\n' "-var" otp="$( totp_secret_to_otp_func "${totp_s}" )" )
$( [[ -n "${apitok}" ]] && printf '%s\n' "-var" api_token="${apitok}" )
)
unset PROXMOX_VE_USERNAME PROXMOX_VE_PASSWORD PROXMOX_VE_API_TOKEN PROXMOX_VE_OTP
print_proxmox_env_var_names
print_proxmox_arg_var_names "${test_cmd_args[@]}"
test_cmd ${loop_rf_pass_fail} ${i} 2 "${test_cmd_args[@]}"
### pre-auth via env-vars
printf "${loop_rf_test_msg_fmt}" $i ${loop_rf_end} "part 3" "env" "pre-auth" "${type}"
if [[ -n "${apitok}" ]] && [[ -z "${un}" && -z "${PROXMOX_VE_AUTH_TICKET}" ]]; then
printf ' skip testing api_token with pre-auth ticket+csrf; invalid test (cannot get auth-ticket and csrf with api-token)\n'
else
curl_api_unlock_user_tfa "${un}"
## call the api_auth function with the totp-password generated from the totp-secret
read -d $'\0' pre_auth_ticket pre_auth_csrf <<<"$( PROXMOX_VE_USERNAME="${un}" PROXMOX_VE_PASSWORD="${pw}" api_auth $( totp_secret_to_otp_func "${totp_s}" ) )"
unset PROXMOX_VE_AUTH_TICKET PROXMOX_VE_CSRF_PREVENTION_TOKEN PROXMOX_VE_USERNAME PROXMOX_VE_PASSWORD PROXMOX_VE_API_TOKEN PROXMOX_VE_OTP test_cmd_args
if [[ -n "${pre_auth_ticket}" && "${pre_auth_ticket}" != "null" ]]; then
export PROXMOX_VE_AUTH_TICKET="${pre_auth_ticket}"
fi
if [[ -n "${pre_auth_csrf}" && "${pre_auth_csrf}" != "null" ]]; then
export PROXMOX_VE_CSRF_PREVENTION_TOKEN="${pre_auth_csrf}"
fi
if [[ -n "${apitok}" ]]; then
export PROXMOX_VE_API_TOKEN="${apitok}"
fi
print_proxmox_env_var_names
print_proxmox_arg_var_names "${test_cmd_args[@]}"
test_cmd ${loop_rf_pass_fail} ${i} 3
fi
### pre-auth via in-line
printf "${loop_rf_test_msg_fmt}" $i ${loop_rf_end} "part 4" "in-line" "pre-auth" "${type}"
## if apitoken is set and username and env-var auth_ticket are unset, skip test
## else-if skip test if test-scenario has been tested before (case when expect-to-fail and auth_ticket or csrf are empty/unset
if [[ -n "${apitok}" ]] && [[ -z "${un}" && -z "${PROXMOX_VE_AUTH_TICKET}" ]]; then
printf ' skip testing api_token with pre-auth ticket+csrf; invalid test (cannot get auth-ticket and csrf with api-token)\n'
elif [[ "${test_pre_auth_inline_empty_creds}" != 0 && "${loop_rf_pass_fail}" == "fail" ]] && [[ -z "${PROXMOX_VE_AUTH_TICKET}" || -z "${PROXMOX_VE_CSRF_PREVENTION_TOKEN}" ]]; then
printf ' skip testing: fail test has no pre-auth creds and was already tested with no creds; see std-out for: test_pre_auth_inline_empty_creds\n'
else
printf ' Note: setting test_pre_auth_empty_creds as to not re-test empty pre-auth creds with in-line config\n'
test_pre_auth_inline_empty_creds=1 ## flag with var to test no more than once this condition (when pre-auth creds are empty/unset with in-line config)
curl_api_unlock_user_tfa "${un}"
test_cmd_args=(
## if auth_ticket / csrf is not set, set to values generated in test above
$( [[ -z "${auth_ticket}" ]] && printf '%s\n' "-var" auth_ticket="${PROXMOX_VE_AUTH_TICKET}" ) ## assume auth-ticket above in REAL was generated successfully
$( [[ -z "${csrf_token}" ]] && printf '%s\n' "-var" csrf_prevention_token="${PROXMOX_VE_CSRF_PREVENTION_TOKEN}" )
## if auth_ticket / csrf is set, use them
$( [[ -n "${auth_ticket}" ]] && printf '%s\n' "-var" auth_ticket="${auth_ticket}" )
$( [[ -n "${csrf_token}" ]] && printf '%s\n' "-var" csrf_prevention_token="${csrf_prevention_token}" )
)
unset PROXMOX_VE_AUTH_TICKET PROXMOX_VE_CSRF_PREVENTION_TOKEN
print_proxmox_env_var_names
print_proxmox_arg_var_names "${test_cmd_args[@]}"
test_cmd ${loop_rf_pass_fail} ${i} 4 "${test_cmd_args[@]}"
fi
printf '\n'
done ## end real/fake sets
done ## end "real" vs "fake" variable-prefixes

View File

@ -0,0 +1,8 @@
#### two data objects to help show when an auth-failure will fail immediatly with provider or with each TF-request
data "proxmox_virtual_environment_nodes" "available_nodes_01" {}
data "proxmox_virtual_environment_nodes" "available_nodes_02" {}

View File

@ -0,0 +1,14 @@
provider "proxmox" {
insecure = true
auth_ticket = var.auth_ticket
csrf_prevention_token = var.csrf_prevention_token
api_token = var.api_token
otp = var.otp
username = var.username
password = var.password
}

View File

@ -0,0 +1,11 @@
variable "auth_ticket" { default = null }
variable "csrf_prevention_token" { default = null }
variable "api_token" { default = null }
variable "otp" { default = null }
variable "username" { default = null }
variable "password" { default = null }

View File

@ -0,0 +1,7 @@
terraform {
required_providers {
proxmox = {
source = "bpg/proxmox"
}
}
}