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.
		
		
		
		
		
			
		
			
				
					
					
						
							182 lines
						
					
					
						
							5.9 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							182 lines
						
					
					
						
							5.9 KiB
						
					
					
				| #!/usr/bin/env sh | |
| # shellcheck disable=SC2034 | |
| dns_constellix_info='Constellix.com | |
| Site: Constellix.com | |
| Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_constellix | |
| Options: | |
|  CONSTELLIX_Key API Key | |
|  CONSTELLIX_Secret API Secret | |
| Issues: github.com/acmesh-official/acme.sh/issues/2724 | |
| Author: Wout Decre <wout@canodus.be> | |
| ' | |
| 
 | |
| CONSTELLIX_Api="https://api.dns.constellix.com/v1" | |
| 
 | |
| ########  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 | |
| }
 |