You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

205 lines
6.3 KiB

  1. #!/usr/bin/env sh
  2. # Here is a script to deploy certificates to CloudHub V2 using Anypoint Platform REST APIs via curl
  3. # A TLS Context is created and the certificates deployed on it
  4. # (https://docs.mulesoft.com/cloudhub-2/ps-config-domains/)
  5. #
  6. # This script will use Connected Apps - Client Credentials
  7. # The App must have "Cloudhub Network Administrator" or "Cloudhub Organization Admin" scope
  8. # (https://docs.mulesoft.com/access-management/connected-apps-developers#developers)
  9. #
  10. # It requires following environment variables:
  11. #
  12. # CH2_CLIENT_ID - Connected App Client ID
  13. # CH2_CLIENT_SECRET - Connected App Client Secret
  14. # ORGANIZATION_ID - Anypoint Platform Organization ID
  15. # CH2_PRIVATE_SPACE_ID - Private Space ID where the TLS Context will be created
  16. #
  17. #
  18. #returns 0 means success, otherwise error.
  19. ######## Public functions #####################
  20. #!/usr/bin/env sh
  21. #Here is a sample custom api script.
  22. #This file name is "myapi.sh"
  23. #So, here must be a method myapi_deploy()
  24. #Which will be called by acme.sh to deploy the cert
  25. #returns 0 means success, otherwise error.
  26. ######## Public functions #####################
  27. #domain keyfile certfile cafile fullchain
  28. cloudhub_v2_deploy() {
  29. _cdomain="$1"
  30. _ckey="$2"
  31. _ccert="$3"
  32. _cca="$4"
  33. _cfullchain="$5"
  34. _debug _cdomain "$_cdomain"
  35. _debug _ckey "$_ckey"
  36. _debug _ccert "$_ccert"
  37. _debug _cca "$_cca"
  38. _debug _cfullchain "$_cfullchain"
  39. _getdeployconf CH2_CLIENT_ID
  40. _getdeployconf CH2_CLIENT_SECRET
  41. _getdeployconf ORGANIZATION_ID
  42. _getdeployconf CH2_PRIVATE_SPACE_ID
  43. # Validate required env vars
  44. if [ -z "$CH2_CLIENT_ID" ]; then
  45. _err "Connected App CH2_CLIENT_ID not defined."
  46. return 1
  47. fi
  48. if [ -z "$CH2_CLIENT_SECRET" ]; then
  49. _err "Connected App CH2_CLIENT_SECRET not defined."
  50. return 1
  51. fi
  52. if [ -z "$ORGANIZATION_ID" ]; then
  53. _err "ORGANIZATION_ID not defined."
  54. return 1
  55. fi
  56. if [ -z "$CH2_PRIVATE_SPACE_ID" ]; then
  57. _err "CH2_PRIVATE_SPACE_ID not defined."
  58. return 1
  59. fi
  60. # Set Anypoint Platform URL
  61. if [ -z "$ANYPOINT_URL" ]; then
  62. _debug "ANYPOINT_URL Not set, using default https://anypoint.mulesoft.com"
  63. ANYPOINT_URL="https://anypoint.mulesoft.com"
  64. fi
  65. _savedeployconf CH2_CLIENT_ID "$CH2_CLIENT_ID"
  66. _savedeployconf CH2_CLIENT_SECRET "$CH2_CLIENT_SECRET"
  67. _savedeployconf ORGANIZATION_ID "$ORGANIZATION_ID"
  68. _savedeployconf CH2_PRIVATE_SPACE_ID "$CH2_PRIVATE_SPACE_ID"
  69. _savedeployconf ANYPOINT_URL "$ANYPOINT_URL"
  70. # Anypoint Platform access token
  71. _info "Obtaining a Anypoint Platform access token"
  72. token_data="{\"grant_type\": \"client_credentials\", \"client_id\": \"${CH2_CLIENT_ID}\", \"client_secret\": \"${CH2_CLIENT_SECRET}\"}"
  73. _debug token_data "$token_data"
  74. token_response="$(_cloudhub_rest "POST" "/accounts/api/v2/oauth2/token" "$token_data")"
  75. _ret="$?"
  76. if [ "$_ret" != 0 ]; then
  77. _err "Error while creating token"
  78. return 1
  79. fi
  80. regex_token=".*\"access_token\":\"\([-._0-9A-Za-z]*\)\".*$"
  81. _debug regex_token "$regex_token"
  82. access_token=$(echo "$token_response" | _json_decode | sed -n "s/$regex_token/\1/p")
  83. _debug access_token "$access_token"
  84. export _H1="Authorization: Bearer ${access_token}"
  85. # Get TLS-Context
  86. tls_context_name=$(echo "$_cdomain" | tr '.' '-' | tr '*' 'x')
  87. tls_context_id=$(_get_tls_context_id "$tls_context_name")
  88. _ret="$?"
  89. if [ "$_ret" != 0 ]; then
  90. _err "Error while retrieving TLS-Context"
  91. return 1
  92. fi
  93. _debug tls_context_id "$tls_context_id"
  94. cert_data="{\"name\":\"$tls_context_name\", \"tlsConfig\": {\"keyStore\":{\"source\":\"PEM\",\"certificate\":\"$(_json_encode <"$_ccert")\", \"key\":\"$(_json_encode <"$_ckey")\", \"capath\":\"$(_json_encode <"$_cca")\"}}}"
  95. if [ -z "$tls_context_id" ]; then
  96. #Post certificate to Private Space
  97. _info "Creating a new TLS-Context with name: $tls_context_name"
  98. cert_response="$(_cloudhub_rest "POST" "/runtimefabric/api/organizations/$ORGANIZATION_ID/privatespaces/$CH2_PRIVATE_SPACE_ID/tlsContexts" "$cert_data")"
  99. else
  100. #Patch certificate to Private Space
  101. _info "Updating TLS-Context with name: $tls_context_name and id: $tls_context_id"
  102. cert_response="$(_cloudhub_rest "PATCH" "/runtimefabric/api/organizations/$ORGANIZATION_ID/privatespaces/$CH2_PRIVATE_SPACE_ID/tlsContexts/$tls_context_id" "$cert_data")"
  103. fi
  104. _debug cert_response "$cert_response"
  105. _ret="$?"
  106. if [ "$_ret" != 0 ]; then
  107. _err "Error while creating/updating TLS-Context"
  108. return 1
  109. fi
  110. _info "Certificate deployed!"
  111. }
  112. #################### Private functions below ##################################
  113. # Retrieve TLS Context If from Private Space
  114. #returns
  115. # tls_context_id
  116. _get_tls_context_id() {
  117. _domain=$1
  118. # Get Tls-Context
  119. tls_context_response="$(_cloudhub_rest "GET" "/runtimefabric/api/organizations/$ORGANIZATION_ID/privatespaces/$CH2_PRIVATE_SPACE_ID/tlsContexts" | _normalizeJson)"
  120. _ret="$?"
  121. if [ "$_ret" != 0 ]; then
  122. return 1
  123. fi
  124. if _contains "$tls_context_response" "\"name\":\"$_domain\"" >/dev/null; then
  125. tlscontext_list=$(echo "$tls_context_response" | _egrep_o "\"id\":\".*\",\"name\":\"$_domain\"")
  126. if [ "$tlscontext_list" ]; then
  127. regex_id=".*\"id\":\"\([-._0-9A-Za-z]*\)\".*$"
  128. tls_context_id=$(echo "$tlscontext_list" | sed -n "s/$regex_id/\1/p")
  129. if [ "$tls_context_id" ]; then
  130. _debug "TLS-Context id: $tls_context_id found! The script will update it."
  131. printf "%s" "$tls_context_id"
  132. return 0
  133. fi
  134. _err "Can't extract TLS-Context id from: $tlscontext_list"
  135. return 1
  136. fi
  137. fi
  138. return 0
  139. }
  140. _cloudhub_rest() {
  141. _method=$1
  142. _path="$2"
  143. _data="$3"
  144. # clear headers from previous request to avoid getting wrong http code
  145. : >"$HTTP_HEADER"
  146. _debug data "$_data"
  147. if [ "$_method" != "GET" ]; then
  148. response="$(_post "$_data" "$ANYPOINT_URL""$_path" "" "$_method" "application/json")"
  149. else
  150. response="$(_get "$ANYPOINT_URL""$_path")"
  151. fi
  152. _ret="$?"
  153. http_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")"
  154. _debug "HTTP status $http_code"
  155. _debug response "$response"
  156. _debug _ret "$_ret"
  157. if [ "$_ret" = "0" ] && { [ "$http_code" -ge 200 ] && [ "$http_code" -le 299 ]; }; then
  158. printf "%s" "$response"
  159. return 0
  160. else
  161. _err "Error sending request to $_path"
  162. _err "HTTP Status $http_code"
  163. _err "Response $response"
  164. return 1
  165. fi
  166. }