177 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Bash
		
	
	
			
		
		
	
	
			177 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Bash
		
	
	
| #!/usr/bin/env sh
 | |
| 
 | |
| # Author: Wout Decre <wout@canodus.be>
 | |
| 
 | |
| CONSTELLIX_Api="https://api.dns.constellix.com/v1"
 | |
| #CONSTELLIX_Key="XXX"
 | |
| #CONSTELLIX_Secret="XXX"
 | |
| 
 | |
| ########  Public functions #####################
 | |
| 
 | |
| # Usage: add  _acme-challenge.www.domain.com   "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
 | |
| # Used to add txt record
 | |
| dns_constellix_add() {
 | |
|   fulldomain=$1
 | |
|   txtvalue=$2
 | |
| 
 | |
|   CONSTELLIX_Key="${CONSTELLIX_Key:-$(_readaccountconf_mutable CONSTELLIX_Key)}"
 | |
|   CONSTELLIX_Secret="${CONSTELLIX_Secret:-$(_readaccountconf_mutable CONSTELLIX_Secret)}"
 | |
| 
 | |
|   if [ -z "$CONSTELLIX_Key" ] || [ -z "$CONSTELLIX_Secret" ]; then
 | |
|     _err "You did not specify the Contellix API key and secret yet."
 | |
|     return 1
 | |
|   fi
 | |
| 
 | |
|   _saveaccountconf_mutable CONSTELLIX_Key "$CONSTELLIX_Key"
 | |
|   _saveaccountconf_mutable CONSTELLIX_Secret "$CONSTELLIX_Secret"
 | |
| 
 | |
|   if ! _get_root "$fulldomain"; then
 | |
|     _err "Invalid domain"
 | |
|     return 1
 | |
|   fi
 | |
| 
 | |
|   # The TXT record might already exist when working with wildcard certificates. In that case, update the record by adding the new value.
 | |
|   _debug "Search TXT record"
 | |
|   if _constellix_rest GET "domains/${_domain_id}/records/TXT/search?exact=${_sub_domain}"; then
 | |
|     if printf -- "%s" "$response" | grep "{\"errors\":\[\"Requested record was not found\"\]}" >/dev/null; then
 | |
|       _info "Adding TXT record"
 | |
|       if _constellix_rest POST "domains/${_domain_id}/records" "[{\"type\":\"txt\",\"add\":true,\"set\":{\"name\":\"${_sub_domain}\",\"ttl\":60,\"roundRobin\":[{\"value\":\"${txtvalue}\"}]}}]"; then
 | |
|         if printf -- "%s" "$response" | grep "{\"success\":\"1 record(s) added, 0 record(s) updated, 0 record(s) deleted\"}" >/dev/null; then
 | |
|           _info "Added"
 | |
|           return 0
 | |
|         else
 | |
|           _err "Error adding TXT record"
 | |
|         fi
 | |
|       fi
 | |
|     else
 | |
|       _record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[0-9]*" | cut -d ':' -f 2)
 | |
|       if _constellix_rest GET "domains/${_domain_id}/records/TXT/${_record_id}"; then
 | |
|         _new_rr_values=$(printf "%s\n" "$response" | _egrep_o '"roundRobin":\[[^]]*\]' | sed "s/\]$/,{\"value\":\"${txtvalue}\"}]/")
 | |
|         _debug _new_rr_values "$_new_rr_values"
 | |
|         _info "Updating TXT record"
 | |
|         if _constellix_rest PUT "domains/${_domain_id}/records/TXT/${_record_id}" "{\"name\":\"${_sub_domain}\",\"ttl\":60,${_new_rr_values}}"; then
 | |
|           if printf -- "%s" "$response" | grep "{\"success\":\"Record.*updated successfully\"}" >/dev/null; then
 | |
|             _info "Updated"
 | |
|             return 0
 | |
|           elif printf -- "%s" "$response" | grep "{\"errors\":\[\"Contents are identical\"\]}" >/dev/null; then
 | |
|             _info "Already exists, no need to update"
 | |
|             return 0
 | |
|           else
 | |
|             _err "Error updating TXT record"
 | |
|           fi
 | |
|         fi
 | |
|       fi
 | |
|     fi
 | |
|   fi
 | |
| 
 | |
|   return 1
 | |
| }
 | |
| 
 | |
| # Usage: fulldomain txtvalue
 | |
| # Used to remove the txt record after validation
 | |
| dns_constellix_rm() {
 | |
|   fulldomain=$1
 | |
|   txtvalue=$2
 | |
| 
 | |
|   CONSTELLIX_Key="${CONSTELLIX_Key:-$(_readaccountconf_mutable CONSTELLIX_Key)}"
 | |
|   CONSTELLIX_Secret="${CONSTELLIX_Secret:-$(_readaccountconf_mutable CONSTELLIX_Secret)}"
 | |
| 
 | |
|   if [ -z "$CONSTELLIX_Key" ] || [ -z "$CONSTELLIX_Secret" ]; then
 | |
|     _err "You did not specify the Contellix API key and secret yet."
 | |
|     return 1
 | |
|   fi
 | |
| 
 | |
|   if ! _get_root "$fulldomain"; then
 | |
|     _err "Invalid domain"
 | |
|     return 1
 | |
|   fi
 | |
| 
 | |
|   # The TXT record might have been removed already when working with some wildcard certificates.
 | |
|   _debug "Search TXT record"
 | |
|   if _constellix_rest GET "domains/${_domain_id}/records/TXT/search?exact=${_sub_domain}"; then
 | |
|     if printf -- "%s" "$response" | grep "{\"errors\":\[\"Requested record was not found\"\]}" >/dev/null; then
 | |
|       _info "Removed"
 | |
|       return 0
 | |
|     else
 | |
|       _info "Removing TXT record"
 | |
|       if _constellix_rest POST "domains/${_domain_id}/records" "[{\"type\":\"txt\",\"delete\":true,\"filter\":{\"field\":\"name\",\"op\":\"eq\",\"value\":\"${_sub_domain}\"}}]"; then
 | |
|         if printf -- "%s" "$response" | grep "{\"success\":\"0 record(s) added, 0 record(s) updated, 1 record(s) deleted\"}" >/dev/null; then
 | |
|           _info "Removed"
 | |
|           return 0
 | |
|         else
 | |
|           _err "Error removing TXT record"
 | |
|         fi
 | |
|       fi
 | |
|     fi
 | |
|   fi
 | |
| 
 | |
|   return 1
 | |
| }
 | |
| 
 | |
| ####################  Private functions below ##################################
 | |
| 
 | |
| _get_root() {
 | |
|   domain=$1
 | |
|   i=2
 | |
|   p=1
 | |
|   _debug "Detecting root zone"
 | |
|   while true; do
 | |
|     h=$(printf "%s" "$domain" | cut -d . -f $i-100)
 | |
|     if [ -z "$h" ]; then
 | |
|       return 1
 | |
|     fi
 | |
| 
 | |
|     if ! _constellix_rest GET "domains/search?exact=$h"; then
 | |
|       return 1
 | |
|     fi
 | |
| 
 | |
|     if _contains "$response" "\"name\":\"$h\""; then
 | |
|       _domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[0-9]*" | cut -d ':' -f 2)
 | |
|       if [ "$_domain_id" ]; then
 | |
|         _sub_domain=$(printf "%s" "$domain" | cut -d '.' -f 1-$p)
 | |
|         _domain="$h"
 | |
| 
 | |
|         _debug _domain_id "$_domain_id"
 | |
|         _debug _sub_domain "$_sub_domain"
 | |
|         _debug _domain "$_domain"
 | |
|         return 0
 | |
|       fi
 | |
|       return 1
 | |
|     fi
 | |
|     p=$i
 | |
|     i=$(_math "$i" + 1)
 | |
|   done
 | |
|   return 1
 | |
| }
 | |
| 
 | |
| _constellix_rest() {
 | |
|   m=$1
 | |
|   ep="$2"
 | |
|   data="$3"
 | |
|   _debug "$ep"
 | |
| 
 | |
|   rdate=$(date +"%s")"000"
 | |
|   hmac=$(printf "%s" "$rdate" | _hmac sha1 "$(printf "%s" "$CONSTELLIX_Secret" | _hex_dump | tr -d ' ')" | _base64)
 | |
| 
 | |
|   export _H1="x-cnsdns-apiKey: $CONSTELLIX_Key"
 | |
|   export _H2="x-cnsdns-requestDate: $rdate"
 | |
|   export _H3="x-cnsdns-hmac: $hmac"
 | |
|   export _H4="Accept: application/json"
 | |
|   export _H5="Content-Type: application/json"
 | |
| 
 | |
|   if [ "$m" != "GET" ]; then
 | |
|     _debug data "$data"
 | |
|     response="$(_post "$data" "$CONSTELLIX_Api/$ep" "" "$m")"
 | |
|   else
 | |
|     response="$(_get "$CONSTELLIX_Api/$ep")"
 | |
|   fi
 | |
| 
 | |
|   if [ "$?" != "0" ]; then
 | |
|     _err "Error $ep"
 | |
|     return 1
 | |
|   fi
 | |
| 
 | |
|   _debug response "$response"
 | |
|   return 0
 | |
| }
 |