helpers.sh 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. #! /bin/bash
  2. cache_dir=
  3. if [[ -v $XDG_CACHE_HOME ]]; then
  4. cache_dir="$XDG_CACHE_HOME"/openstack
  5. else
  6. cache_dir="$HOME/.cache/openstack"
  7. fi
  8. [[ -d "$cache_dir" ]] || mkdir -p "$cache_dir"
  9. token_response_file=$cache_dir/$(uriparse "$OS_AUTH_URL" | awk '/^hostText/ {print $2}')
  10. token_response_tmp="${token_response_file}-$(uuidgen)"
  11. get_password_token() {
  12. # usually -s and -L shouldn't be combined, but they are needed for devcloud due to keystone redirect
  13. curl -sL -D- -X POST \
  14. --json '{"auth": {
  15. "identity": {
  16. "methods": [
  17. "password"
  18. ],
  19. "password": {
  20. "user": {
  21. "domain": {
  22. "name": "'"$OS_USER_DOMAIN_NAME"'"
  23. },
  24. "name": "'"$OS_USERNAME"'",
  25. "password": "'"$OS_PASSWORD"'"
  26. }
  27. }
  28. },
  29. "scope": {
  30. "project": {
  31. "domain": {
  32. "name": "'"$OS_PROJECT_DOMAIN_NAME"'"
  33. },
  34. "name": "'"$OS_PROJECT_NAME"'",
  35. "id": "'"$OS_PROJECT_ID"'"
  36. }
  37. }
  38. }}' "${OS_AUTH_URL}/auth/tokens" \
  39. -o "$token_response_tmp" \
  40. | awk -v IGNORECASE=1 '/x-subject-token/ {gsub(/\x0d/,"",$0); print $2}'
  41. }
  42. get_v3applicationcredential_token() {
  43. curl -sL -D- -X POST \
  44. -H "Content-Type: application/json" \
  45. -d '{"auth": {
  46. "identity": {
  47. "methods": [
  48. "application_credential"
  49. ],
  50. "application_credential": {
  51. "id": "'"$OS_APPLICATION_CREDENTIAL_ID"'",
  52. "secret": "'"$OS_APPLICATION_CREDENTIAL_SECRET"'"
  53. }
  54. }
  55. }}' "${OS_AUTH_URL}auth/tokens" \
  56. -o "$token_response_tmp" \
  57. | awk -v IGNORECASE=1 '/x-subject-token/ {gsub(/\x0d/,"",$0); print $2}'
  58. }
  59. CURL_OS_TOKEN=
  60. expiry=0
  61. if [[ -f $token_response_file ]]; then
  62. expiry="$(jq -r '.token.expires_at' < $token_response_file | xargs date +%s --date)"
  63. fi
  64. now=$(date +%s)
  65. renewal_warning_seconds=600
  66. if [[ $expiry -gt $(( now + renewal_warning_seconds )) ]]; then
  67. CURL_OS_TOKEN="$(jq -r '.token.token' < $token_response_file)"
  68. else
  69. CURL_OS_TOKEN=$(get_"${OS_AUTH_TYPE}"_token)
  70. jq -r '.token += {"token": "'"${CURL_OS_TOKEN}"'"}' < "$token_response_tmp" > "$token_response_file"
  71. rm "$token_response_tmp"
  72. fi
  73. export CURL_OS_TOKEN
  74. get_catalog() {
  75. region_filter=
  76. if [[ -n $OS_REGION_NAME ]]; then
  77. region_filter=' and .region == "'"$OS_REGION_NAME"'"'
  78. fi
  79. jq -r '["-----", "-----", "-----", "-----"], (.token.catalog[] | [.id, .type, .name, ([.endpoints[] | select(.interface == "'"$OS_INTERFACE"'"'"$region_filter"') | .url] | join(" "))]) | @tsv' < "$token_response_file" \
  80. | column -s$'\t' -o' | ' --table-columns id,type,name,endpoints --table-wrap endpoints -t
  81. }
  82. get_service_endpoint() {
  83. iface="$OS_INTERFACE"
  84. if [[ -z $iface ]]; then
  85. iface=public
  86. fi
  87. if [[ -n $OS_REGION_NAME ]]; then
  88. region_filter=' and .region == "'"$OS_REGION_NAME"'"'
  89. fi
  90. jq -r '.token.catalog[] | select(.type == "'"$1"'") | .endpoints[] | select(.interface == "'"$iface"'"'"$region_filter"') | .url' < "$token_response_file"
  91. }
  92. check_project_id() {
  93. curl -s -o /dev/null -w "%{http_code}\n" \
  94. -H "X-Auth-Token: $CURL_OS_TOKEN" \
  95. "${OS_AUTH_URL}/projects/$1"
  96. }
  97. check_user_id() {
  98. curl -s -o /dev/null -w "%{http_code}\n" \
  99. -H "X-Auth-Token: $CURL_OS_TOKEN" \
  100. "${OS_AUTH_URL}/users/$1"
  101. }
  102. get_project_id() {
  103. # Converts a project name to the project id
  104. curl -s \
  105. -H "X-Auth-Token: $CURL_OS_TOKEN" \
  106. "${OS_AUTH_URL}/projects?name=$1" \
  107. | jq -r '.projects[].id'
  108. }
  109. get_user_id() {
  110. # Converts a user name to the user id
  111. curl -s \
  112. -H "X-Auth-Token: $CURL_OS_TOKEN" \
  113. "${OS_AUTH_URL}/users?name=$1" \
  114. | jq -r '.users[].id'
  115. }
  116. get_role_id() {
  117. curl -s \
  118. -H "X-Auth-Token: $CURL_OS_TOKEN" \
  119. "${OS_AUTH_URL}/roles?name=$1" \
  120. | jq -r '.roles[].id'
  121. }
  122. get_aggregates() {
  123. local endpoint=$(get_service_endpoint compute)
  124. curl -s \
  125. -H "X-Auth-Token: $CURL_OS_TOKEN" \
  126. -H "X-OpenStack-Nova-API-Version: 2.42" \
  127. "${endpoint}/os-aggregates"
  128. }
  129. get_instance() {
  130. local endpoint=$(get_service_endpoint compute)
  131. curl -s \
  132. -H "X-Auth-Token: $CURL_OS_TOKEN" \
  133. -H "X-OpenStack-Nova-API-Version: 2.42" \
  134. "${endpoint}/servers/$1"
  135. }
  136. get_server_list_detailed() {
  137. local endpoint=$(get_service_endpoint compute)
  138. proj=$(coerce_project_id "$1")
  139. curl -s \
  140. -H "X-Auth-Token: $CURL_OS_TOKEN" \
  141. -H "X-OpenStack-Nova-API-Version: 2.42" \
  142. "${endpoint}/servers/detail?all_tenants=1&project_id=${proj}"
  143. }
  144. coerce_project_id() {
  145. # Many API queries require project id, but we want to be able to call them using project name.
  146. # This function takes either an id or a name; ids are passed through, while names are coerced to ids.
  147. case $(check_project_id $1) in
  148. 200)
  149. printf "%s\n" "$1"
  150. ;;
  151. *)
  152. get_project_id "$1"
  153. ;;
  154. esac
  155. }
  156. coerce_user_id() {
  157. # Many API queries require user id, but we want to be able to call them using user name.
  158. # This function takes either an id or a name; ids are passed through, while names are coerced to ids.
  159. case $(check_user_id $1) in
  160. 200)
  161. printf "%s\n" "$1"
  162. ;;
  163. *)
  164. get_user_id "$1"
  165. ;;
  166. esac
  167. }
  168. filterify_arguments() {
  169. # https://stackoverflow.com/a/34802471
  170. (( $# )) || return
  171. local res
  172. printf -v res '"%s",' "$@"
  173. printf "%s\n" "${res%,}"
  174. }