Guest User

dns_vultr.sh

a guest
Sep 5th, 2018
736
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 6.48 KB | None | 0 0
  1. #!/usr/bin/env sh
  2.  
  3. # dns_vultr.sh: VULTR DNS script for acme.sh
  4. # Place it in acme.h's 'dnsapi' directory
  5. #
  6. # Share, use and modify freely as needed
  7. #
  8. # Ensure your environment variable contains your API key:
  9. # VULTR_API_KEY="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  10.  
  11. VULTR_API_BASEURL="https://api.vultr.com/v1"
  12.  
  13. ########  Public functions #####################
  14.  
  15. # add txt record to dns server
  16. dns_vultr_add() {
  17.   fulldomain=$1
  18.   txtvalue=$2
  19.   _info "Using VULTR"
  20.  
  21.   _info "Checking VULTR_API_KEY environment variable is set"
  22.   if [ -z "$VULTR_API_KEY" ]; then
  23.     _err "Missing VULTR API key"
  24.     return 1
  25.   fi
  26.   _info "VULTR API key found"
  27.  
  28.   _debug "First detect the root zone"
  29.   if ! _get_root "$fulldomain"; then
  30.     _err "Invalid domain"
  31.     return 1
  32.   fi
  33.  
  34.   _debug "domain: $_domain"
  35.   _debug "subdomain: $_sub_domain"
  36.  
  37.   # add our record to dns server
  38.   _info "Attempting to add TXT record to DNS server"
  39.   if ! _vultr_call_api POST "/dns/create_record" "domain=$_domain&name=$_sub_domain&type=TXT&ttl=300&data=\"$txtvalue\""; then
  40.     _err "API call failed: $response"
  41.     return 1
  42.   fi
  43.  
  44.   # make sure we don't hit api rate limits
  45.   sleep 1
  46.  
  47.   # check list of records for domain to see if we've added our txt record successfully
  48.   _debug "Verifying we've added our TXT record"
  49.   if ! _vultr_call_api GET "/dns/records?domain=$_domain"; then
  50.     _err "API call failed: $response"
  51.     return 1
  52.   fi
  53.   if [ $(echo $response | grep -c "\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"data\":\"\\\\\"$txtvalue\\\\\"\"") -ne 0 ]; then
  54.     _info "Successfully added TXT record: $fulldomain"
  55.     return 0
  56.   fi
  57.   # if order of values returned from api changes, we can match each line against each individual name value pair
  58.   #response=`echo "$response" | sed "s/},{/\n/g"`
  59.   #read -r -a hosted_records <<< $response
  60.   #for rec in "${hosted_records[@]}"; do
  61.   #  if [ $(echo $rec | grep "\"type\":\"TXT\"" | grep "\"name\":\"$_sub_domain\"" | grep -c "\"data\":\"\\\\\"$txtvalue\\\\\"\"") -ne 0 ]; then
  62.   #    _info "Successfully added TXT record: $fulldomain"
  63.   #    return 0
  64.   #  fi
  65.   #done
  66.  
  67.   _err "Failed to create TXT record: $fulldomain"
  68.   return 1
  69. }
  70.  
  71. # remove txt record from dns server
  72. dns_vultr_rm() {
  73.   fulldomain=$1
  74.   txtvalue=$2
  75.   _info "Using VULTR"
  76.  
  77.   _info "Checking VULTR_API_KEY environment variable is set"
  78.   if [ -z "$VULTR_API_KEY" ]; then
  79.     _err "Missing VULTR API key"
  80.     return 1
  81.   fi
  82.   _info "VULTR API key found"
  83.  
  84.   _debug "First detect the root zone"
  85.   if ! _get_root "$fulldomain"; then
  86.     _err "Invalid domain"
  87.     return 1
  88.   fi
  89.  
  90.   # get record id of TXT record matching $_sub_domain
  91.   _debug "Searching for existing TXT record"
  92.   if ! _vultr_call_api GET "/dns/records?domain=$_domain"; then
  93.     _err "API call failed: $response"
  94.     return 1
  95.   fi
  96.   _record_id=`echo "$response" | sed "s/},{/\n/g" | grep -P "\"type\":\"TXT\",\"name\":\"$_sub_domain\"" | grep -oP "\"RECORDID\":\K\d+"`
  97.   if [ -z "$_record_id" ]; then
  98.     _err "Unable to find existing TXT record"
  99.     return 1
  100.   fi
  101.  
  102.   # use record id to delete the existing TXT record
  103.   _info "Attempting to delete TXT record from DNS server"
  104.   if ! _vultr_call_api POST "/dns/delete_record" "domain=$_domain&RECORDID=$_record_id"; then
  105.     _err "API call failed: $response"
  106.     return 1
  107.   fi
  108.  
  109.   # make sure we don't hit api rate limits
  110.   sleep 1
  111.  
  112.   # check list of records for domain to see if we've successfully removed our temporary txt record
  113.   _debug "Verifying deletion of our TXT record"
  114.   if ! _vultr_call_api GET "/dns/records?domain=$_domain"; then
  115.     _err "API call failed: $response"
  116.     return 1
  117.   fi
  118.   if [ $(echo $response | grep -c "\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"data\":\"\\\\\"$txtvalue\\\\\"\"") -ne 0 ]; then
  119.     _err "Failed to remove TXT record: $fulldomain"
  120.     return 1
  121.   fi
  122.   # if order of values returned from api changes, we can match each line against each individual name value pair
  123.   #response=`echo "$response" | sed "s/},{/\n/g"`
  124.   #read -r -a hosted_records <<< $response
  125.   #for rec in "${hosted_records[@]}"; do
  126.   #  if [ $(echo $rec | grep "\"type\":\"TXT\"" | grep "\"name\":\"$_sub_domain\"" | grep -c "\"data\":\"\\\\\"$txtvalue\\\\\"\"") -ne 0 ]; then
  127.   #    _err "Failed to remove TXT record: $fulldomain"
  128.   #    return 1
  129.   #  fi
  130.   #done
  131.  
  132.   _info "Successfully removed TXT record: $fulldomain"
  133.   return 0
  134. }
  135.  
  136. ####################  Private functions below ##################################
  137.  
  138. # get domain and subdomain parts from full domain
  139. #  
  140. # param
  141. #   domain=_acme-challenge.www.domain.com
  142. # returns
  143. #   _sub_domain=_acme-challenge.www
  144. #   _domain=domain.com
  145. _get_root() {
  146.   domain=$1
  147.  
  148.   # get list of domains hosted by the dns server
  149.   _debug "Getting list of existing domains"
  150.   if ! _vultr_call_api GET "/dns/list"; then
  151.     _err "API failure: Could not get list of domains"
  152.     return 1
  153.   fi;
  154.  
  155.   if [ -z "$response" ]; then
  156.     _err "No domains hosted on DNS server"
  157.     return 1
  158.   fi;
  159.  
  160.   # parse response to get an array of domain names
  161.   response=`echo "$response" | grep -oP '"domain":"\K[^"]+'`
  162.   read -r -a hosted_domains <<< $response
  163.  
  164.   # compare different parts of fulldomain with the list of domains hosted by dns server
  165.   i=2
  166.   p=1
  167.   while true; do
  168.     h=$(printf "%s" "$domain" | cut -d . -f $i-100)
  169.     # no more parts left
  170.     if [ -z "$h" ]; then
  171.       return 1
  172.     fi
  173.    
  174.     for dom in "${hosted_domains[@]}"; do
  175.       if [ $dom == $h ]; then
  176.         _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
  177.         _domain=$h
  178.         return 0
  179.       fi
  180.     done
  181.    
  182.     p=$i
  183.     i=$(_math "$i" + 1)
  184.   done
  185.   return 1
  186. }
  187.  
  188. # main vultr api method
  189. #
  190. # param
  191. #   method=POST
  192. #   call=/dns/create_record
  193. #   data=var1="val1"&var2="var2"
  194. # method api_call data
  195. #   returns
  196. #     response
  197. _vultr_call_api() {
  198.   method=$1
  199.   api_call="$2"
  200.   data="$3"
  201.   _debug "API call: $api_call"
  202.  
  203.   _vultr_url="$VULTR_API_BASEURL$api_call"
  204.   _debug2 _vultr_url "$_vultr_url"
  205.   _secure_debug VULTR_API_KEY "$VULTR_API_KEY"
  206.  
  207.   # auth
  208.   export _H1="API-Key: $VULTR_API_KEY"
  209.   unset _H2 _H3 _H4 _H5
  210.   if [ "$data" ] || [ "$method" = "POST" ]; then
  211.     _debug data "$data"
  212.     response="$(_post "$data" "$_vultr_url" "" "$method")"
  213.   else
  214.     response="$(_get "$_vultr_url")"
  215.   fi
  216.  
  217.   if [ "$?" != "0" ] || _contains "$response" "Invalid API key"; then
  218.     _err "Error: $response"
  219.     return 1
  220.   fi
  221.   _debug2 response "$response"
  222.   return 0
  223. }
Advertisement
Add Comment
Please, Sign In to add comment