Skip to content

Instantly share code, notes, and snippets.

@MG2R
Last active February 16, 2023 12:07
Show Gist options
  • Save MG2R/52d0cf98635723f6485aa69785cb9831 to your computer and use it in GitHub Desktop.
Save MG2R/52d0cf98635723f6485aa69785cb9831 to your computer and use it in GitHub Desktop.
Create a token for an arbitrary Rancher 2 user with Terraform.
#!/bin/bash
# Used to get Rancher USER tokens from the API.
#
# Workaround for https://github.com/rancher/terraform-provider-rancher2/issues/315
#
# Use this with Terraform by exploiting the external data provider:
# terraform {
# required_providers {
# external = {
# source = "scottwinkler/shell"
# version = "1.7.7"
# }
# }
# }
# resource "shell_script" "sa_token" {
# lifecycle_commands {
# create = "bash '${path.module}/get_sa_token.sh'"
# delete = "bash '${path.module}/get_sa_token.sh' DELETE_TOKEN"
# }
#
# environment = {
# USER = var.username
# SERVER = var.rancher_server_url
# CLUSTER_ID = var.sa_token_scope_cluster_id
# }
#
# sensitive_environment = {
# PASS = var.password
# }
#
# depends_on = [rancher2_user.service_account]
# }
DESCRIPTION='Terraform created Token for CI/CD. DO NOT DELETE.'
API_TOKEN=':'
PAYLOAD_FILE="/tmp/payload-${$}.json"
([[ "${USER}x" == 'x' ]] \
|| [[ "${PASS}x" == 'x' ]] \
|| [[ "${SERVER}x" == 'x' ]] \
|| [[ "${CLUSTER_ID}x" == 'x' ]] \
) && {
>&2 echo "Wrong arguments. Need 'USER', 'PASS', 'SERVER', and 'CLUSTER_ID' env vars."
exit 1
}
function do_curl {
[[ $1 == 'POST' ]] && data="-d @${PAYLOAD_FILE}" || data=''
result=$(curl -s -u "${API_TOKEN}" -X "${1}" \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
${data} \
"${SERVER}/${2}")
ret=$?
[[ $1 == 'POST' ]] && rm -f "${PAYLOAD_FILE}"
echo "${result}"
return $ret
}
function do_login {
echo "{ \"username\": \"${USER}\", \"password\": \"${PASS}\", \"ttl\": 20 }" > ${PAYLOAD_FILE}
API_TOKEN=$(do_curl 'POST' 'v3-public/localProviders/local?action=login' | jq -r '.token')
[[ "${API_TOKEN}" == 'null' ]] && >&2 echo 'Could not authenticate with Rancher' && echo '{"token": "Could not authenticate with Rancher"}' && exit
}
function create_token {
echo "{ \"description\": \"${DESCRIPTION}\", \"ttl\": 0 }" > ${PAYLOAD_FILE}
do_curl 'POST' 'v3/tokens' | jq -r '.token'
}
# Fetches the token ID if it exists, if id doesn't exists calls create_token and returns the result of that.
function fetch_token {
token=$(do_curl 'GET' 'v3/tokens' | jq -r ".data[] | select(.description==\"${DESCRIPTION}\") | .name")
ret=$?
[[ "${token}x" == "x" ]] && { token=$(create_token); ret=$(( $ret + $?)); }
echo "${token}"
return $ret
}
function delete_token {
local token="${1}"
do_curl 'DELETE' "v3/tokens/${token}"
}
# Log in and fetch a token.
do_login
token=$(fetch_token) || { ret=$?; >&2 echo 'Problem fetching token.'; exit $ret; }
if [[ "${1}" == "DELETE_TOKEN" ]]; then
delete_token "${token}"
else
# Safely produce a JSON object containing the result value.
# jq will ensure that the value is properly quoted
# and escaped to produce a valid JSON string.
jq -n --arg token "${token}" '{ "token": $token }'
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment