dns_linode_v4.sh 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. #!/usr/bin/env sh
  2. #Original Author: Philipp Grosswiler <philipp.grosswiler@swiss-design.net>
  3. #v4 Update Author: Aaron W. Swenson <aaron@grandmasfridge.org>
  4. LINODE_V4_API_URL="https://api.linode.com/v4/domains"
  5. ######## Public functions #####################
  6. #Usage: dns_linode_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
  7. dns_linode_v4_add() {
  8. fulldomain="${1}"
  9. txtvalue="${2}"
  10. if ! _Linode_API; then
  11. return 1
  12. fi
  13. _info "Using Linode"
  14. _debug "Calling: dns_linode_add() '${fulldomain}' '${txtvalue}'"
  15. _debug "First detect the root zone"
  16. if ! _get_root "$fulldomain"; then
  17. _err "Domain does not exist."
  18. return 1
  19. fi
  20. _debug _domain_id "$_domain_id"
  21. _debug _sub_domain "$_sub_domain"
  22. _debug _domain "$_domain"
  23. _payload="{
  24. \"type\": \"TXT\",
  25. \"name\": \"$_sub_domain\",
  26. \"target\": \"$txtvalue\"
  27. }"
  28. if _rest POST "/$_domain_id/records" "$_payload" && [ -n "$response" ]; then
  29. _resource_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\s*[0-9]+" | cut -d : -f 2 | tr -d " " | _head_n 1)
  30. _debug _resource_id "$_resource_id"
  31. if [ -z "$_resource_id" ]; then
  32. _err "Error adding the domain resource."
  33. return 1
  34. fi
  35. _info "Domain resource successfully added."
  36. return 0
  37. fi
  38. return 1
  39. }
  40. #Usage: dns_linode_rm _acme-challenge.www.domain.com
  41. dns_linode_v4_rm() {
  42. fulldomain="${1}"
  43. if ! _Linode_API; then
  44. return 1
  45. fi
  46. _info "Using Linode"
  47. _debug "Calling: dns_linode_rm() '${fulldomain}'"
  48. _debug "First detect the root zone"
  49. if ! _get_root "$fulldomain"; then
  50. _err "Domain does not exist."
  51. return 1
  52. fi
  53. _debug _domain_id "$_domain_id"
  54. _debug _sub_domain "$_sub_domain"
  55. _debug _domain "$_domain"
  56. if _rest GET "/$_domain_id/records" && [ -n "$response" ]; then
  57. response="$(echo "$response" | tr -d "\n" | tr '{' "|" | sed 's/|/&{/g' | tr "|" "\n")"
  58. resource="$(echo "$response" | _egrep_o "{.*\"name\":\s*\"$_sub_domain\".*}")"
  59. if [ "$resource" ]; then
  60. _resource_id=$(printf "%s\n" "$resource" | _egrep_o "\"id\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ )
  61. if [ "$_resource_id" ]; then
  62. _debug _resource_id "$_resource_id"
  63. if _rest DELETE "/$_domain_id/records/$_resource_id" && [ -n "$response" ]; then
  64. # On 200/OK, empty set is returned. Check for error, if any.
  65. _error_response=$(printf "%s\n" "$response" | _egrep_o "\"errors\"" | cut -d : -f 2 | tr -d " " | _head_n 1)
  66. if [ -n "$_error_response" ]; then
  67. _err "Error deleting the domain resource: $_error_response"
  68. return 1
  69. fi
  70. _info "Domain resource successfully deleted."
  71. return 0
  72. fi
  73. fi
  74. return 1
  75. fi
  76. return 0
  77. fi
  78. return 1
  79. }
  80. #################### Private functions below ##################################
  81. _Linode_API() {
  82. if [ -z "$LINODE_V4_API_KEY" ]; then
  83. LINODE_V4_API_KEY=""
  84. _err "You didn't specify the Linode v4 API key yet."
  85. _err "Please create your key and try again."
  86. return 1
  87. fi
  88. _saveaccountconf LINODE_V4_API_KEY "$LINODE_V4_API_KEY"
  89. }
  90. #################### Private functions below ##################################
  91. #_acme-challenge.www.domain.com
  92. #returns
  93. # _sub_domain=_acme-challenge.www
  94. # _domain=domain.com
  95. # _domain_id=12345
  96. _get_root() {
  97. domain=$1
  98. i=2
  99. p=1
  100. if _rest GET; then
  101. response="$(echo "$response" | tr -d "\n" | tr '{' "|" | sed 's/|/&{/g' | tr "|" "\n")"
  102. while true; do
  103. h=$(printf "%s" "$domain" | cut -d . -f $i-100)
  104. _debug h "$h"
  105. if [ -z "$h" ]; then
  106. #not valid
  107. return 1
  108. fi
  109. hostedzone="$(echo "$response" | _egrep_o "{.*\"domain\":\s*\"$h\".*}")"
  110. if [ "$hostedzone" ]; then
  111. _domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o "\"id\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ )
  112. if [ "$_domain_id" ]; then
  113. _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
  114. _domain=$h
  115. return 0
  116. fi
  117. return 1
  118. fi
  119. p=$i
  120. i=$(_math "$i" + 1)
  121. done
  122. fi
  123. return 1
  124. }
  125. #method method action data
  126. _rest() {
  127. mtd="$1"
  128. ep="$2"
  129. data="$3"
  130. _debug mtd "$mtd"
  131. _debug ep "$ep"
  132. export _H1="Accept: application/json"
  133. export _H2="Content-Type: application/json"
  134. export _H3="Authorization: Bearer $LINODE_V4_API_KEY"
  135. if [ "$mtd" != "GET" ]; then
  136. # both POST and DELETE.
  137. _debug data "$data"
  138. response="$(_post "$data" "$LINODE_V4_API_URL$ep" "" "$mtd")"
  139. else
  140. response="$(_get "$LINODE_V4_API_URL$ep$data")"
  141. fi
  142. if [ "$?" != "0" ]; then
  143. _err "error $ep"
  144. return 1
  145. fi
  146. _debug2 response "$response"
  147. return 0
  148. }