committed by
GitHub
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 298 additions and 8 deletions
-
8Dockerfile
-
17README.md
-
12acme.sh
-
23deploy/panos.sh
-
2dnsapi/dns_aws.sh
-
244dnsapi/dns_infoblox_uddi.sh
@ -0,0 +1,244 @@ |
|||||
|
#!/usr/bin/env sh |
||||
|
# shellcheck disable=SC2034 |
||||
|
dns_infoblox_uddi_info='Infoblox UDDI |
||||
|
Site: Infoblox.com |
||||
|
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_infoblox_uddi |
||||
|
Options: |
||||
|
Infoblox_UDDI_Key API Key for Infoblox UDDI |
||||
|
Infoblox_Portal URL, e.g. "csp.infoblox.com" or "csp.eu.infoblox.com" |
||||
|
Issues: github.com/acmesh-official/acme.sh/issues |
||||
|
Author: Stefan Riegel |
||||
|
' |
||||
|
|
||||
|
Infoblox_UDDI_Api="https://" |
||||
|
|
||||
|
######## Public functions ##################### |
||||
|
|
||||
|
#Usage: dns_infoblox_uddi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" |
||||
|
dns_infoblox_uddi_add() { |
||||
|
fulldomain=$1 |
||||
|
txtvalue=$2 |
||||
|
|
||||
|
Infoblox_UDDI_Key="${Infoblox_UDDI_Key:-$(_readaccountconf_mutable Infoblox_UDDI_Key)}" |
||||
|
Infoblox_Portal="${Infoblox_Portal:-$(_readaccountconf_mutable Infoblox_Portal)}" |
||||
|
|
||||
|
_info "Using Infoblox UDDI API" |
||||
|
_debug fulldomain "$fulldomain" |
||||
|
_debug txtvalue "$txtvalue" |
||||
|
|
||||
|
if [ -z "$Infoblox_UDDI_Key" ] || [ -z "$Infoblox_Portal" ]; then |
||||
|
Infoblox_UDDI_Key="" |
||||
|
Infoblox_Portal="" |
||||
|
_err "You didn't specify the Infoblox UDDI key or server (Infoblox_UDDI_Key; Infoblox_Portal)." |
||||
|
_err "Please set them via EXPORT Infoblox_UDDI_Key=your_key, EXPORT Infoblox_Portal=csp.infoblox.com and try again." |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
_saveaccountconf_mutable Infoblox_UDDI_Key "$Infoblox_UDDI_Key" |
||||
|
_saveaccountconf_mutable Infoblox_Portal "$Infoblox_Portal" |
||||
|
|
||||
|
export _H1="Authorization: Token $Infoblox_UDDI_Key" |
||||
|
export _H2="Content-Type: application/json" |
||||
|
|
||||
|
_debug "First detect the root zone" |
||||
|
if ! _get_root "$fulldomain"; then |
||||
|
_err "invalid domain" |
||||
|
return 1 |
||||
|
fi |
||||
|
_debug _domain_id "$_domain_id" |
||||
|
_debug _sub_domain "$_sub_domain" |
||||
|
_debug _domain "$_domain" |
||||
|
|
||||
|
_debug "Getting existing txt records" |
||||
|
_infoblox_rest GET "dns/record?_filter=type%20eq%20'TXT'%20and%20name_in_zone%20eq%20'$_sub_domain'%20and%20zone%20eq%20'$_domain_id'" |
||||
|
|
||||
|
_info "Adding record" |
||||
|
body="{\"type\":\"TXT\",\"name_in_zone\":\"$_sub_domain\",\"zone\":\"$_domain_id\",\"ttl\":120,\"inheritance_sources\":{\"ttl\":{\"action\":\"override\"}},\"rdata\":{\"text\":\"$txtvalue\"}}" |
||||
|
|
||||
|
if _infoblox_rest POST "dns/record" "$body"; then |
||||
|
if _contains "$response" "$txtvalue"; then |
||||
|
_info "Added, OK" |
||||
|
return 0 |
||||
|
elif _contains "$response" '"error"'; then |
||||
|
# Check if record already exists |
||||
|
if _contains "$response" "already exists" || _contains "$response" "duplicate"; then |
||||
|
_info "Already exists, OK" |
||||
|
return 0 |
||||
|
else |
||||
|
_err "Add txt record error." |
||||
|
_err "Response: $response" |
||||
|
return 1 |
||||
|
fi |
||||
|
else |
||||
|
_info "Added, OK" |
||||
|
return 0 |
||||
|
fi |
||||
|
fi |
||||
|
_err "Add txt record error." |
||||
|
return 1 |
||||
|
} |
||||
|
|
||||
|
#Usage: dns_infoblox_uddi_rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" |
||||
|
dns_infoblox_uddi_rm() { |
||||
|
fulldomain=$1 |
||||
|
txtvalue=$2 |
||||
|
|
||||
|
Infoblox_UDDI_Key="${Infoblox_UDDI_Key:-$(_readaccountconf_mutable Infoblox_UDDI_Key)}" |
||||
|
Infoblox_Portal="${Infoblox_Portal:-$(_readaccountconf_mutable Infoblox_Portal)}" |
||||
|
|
||||
|
if [ -z "$Infoblox_UDDI_Key" ] || [ -z "$Infoblox_Portal" ]; then |
||||
|
_err "Credentials not found" |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
_info "Using Infoblox UDDI API" |
||||
|
_debug fulldomain "$fulldomain" |
||||
|
_debug txtvalue "$txtvalue" |
||||
|
|
||||
|
export _H1="Authorization: Token $Infoblox_UDDI_Key" |
||||
|
export _H2="Content-Type: application/json" |
||||
|
|
||||
|
_debug "First detect the root zone" |
||||
|
if ! _get_root "$fulldomain"; then |
||||
|
_err "invalid domain" |
||||
|
return 1 |
||||
|
fi |
||||
|
_debug _domain_id "$_domain_id" |
||||
|
_debug _sub_domain "$_sub_domain" |
||||
|
_debug _domain "$_domain" |
||||
|
|
||||
|
_debug "Getting txt records to delete" |
||||
|
# Filter by txtvalue to support wildcard certs (multiple TXT records) |
||||
|
filter="type%20eq%20'TXT'%20and%20name_in_zone%20eq%20'$_sub_domain'%20and%20zone%20eq%20'$_domain_id'%20and%20rdata.text%20eq%20'$txtvalue'" |
||||
|
_infoblox_rest GET "dns/record?_filter=$filter" |
||||
|
|
||||
|
if ! _contains "$response" '"results"'; then |
||||
|
_info "Don't need to remove, record not found." |
||||
|
return 0 |
||||
|
fi |
||||
|
|
||||
|
record_id=$(echo "$response" | _egrep_o '"id":[[:space:]]*"[^"]*"' | _head_n 1 | cut -d '"' -f 4) |
||||
|
_debug "record_id" "$record_id" |
||||
|
|
||||
|
if [ -z "$record_id" ]; then |
||||
|
_info "Don't need to remove, record not found." |
||||
|
return 0 |
||||
|
fi |
||||
|
|
||||
|
# Extract UUID from the full record ID (format: dns/record/uuid) |
||||
|
record_uuid=$(echo "$record_id" | sed 's|.*/||') |
||||
|
_debug "record_uuid" "$record_uuid" |
||||
|
|
||||
|
if ! _infoblox_rest DELETE "dns/record/$record_uuid"; then |
||||
|
_err "Delete record error." |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
_info "Removed record successfully" |
||||
|
return 0 |
||||
|
} |
||||
|
|
||||
|
#################### Private functions below ################################## |
||||
|
|
||||
|
#_acme-challenge.www.domain.com |
||||
|
#returns |
||||
|
# _sub_domain=_acme-challenge.www |
||||
|
# _domain=domain.com |
||||
|
# _domain_id=dns/auth_zone/xxxx-xxxx |
||||
|
_get_root() { |
||||
|
domain=$1 |
||||
|
i=1 |
||||
|
p=1 |
||||
|
|
||||
|
# Remove _acme-challenge prefix if present |
||||
|
domain_no_acme=$(echo "$domain" | sed 's/^_acme-challenge\.//') |
||||
|
|
||||
|
while true; do |
||||
|
h=$(printf "%s" "$domain_no_acme" | cut -d . -f "$i"-100) |
||||
|
_debug h "$h" |
||||
|
if [ -z "$h" ]; then |
||||
|
# not valid |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
# Query for the zone with both trailing dot and without |
||||
|
filter="fqdn%20eq%20'$h.'%20or%20fqdn%20eq%20'$h'" |
||||
|
if ! _infoblox_rest GET "dns/auth_zone?_filter=$filter"; then |
||||
|
# API error - don't continue if we get auth errors |
||||
|
if _contains "$response" "401" || _contains "$response" "Authorization"; then |
||||
|
_err "Authentication failed. Please check your Infoblox_UDDI_Key." |
||||
|
return 1 |
||||
|
fi |
||||
|
# For other errors, continue to parent domain |
||||
|
p=$i |
||||
|
i=$((i + 1)) |
||||
|
continue |
||||
|
fi |
||||
|
|
||||
|
# Check if response contains results (even if empty) |
||||
|
if _contains "$response" '"results"'; then |
||||
|
# Extract zone ID - must match the pattern dns/auth_zone/... |
||||
|
zone_id=$(echo "$response" | _egrep_o '"id":[[:space:]]*"dns/auth_zone/[^"]*"' | _head_n 1 | cut -d '"' -f 4) |
||||
|
if [ -n "$zone_id" ]; then |
||||
|
# Found the zone |
||||
|
_domain="$h" |
||||
|
_domain_id="$zone_id" |
||||
|
|
||||
|
# Calculate subdomain |
||||
|
if [ "$_domain" = "$domain" ]; then |
||||
|
_sub_domain="" |
||||
|
else |
||||
|
_cutlength=$((${#domain} - ${#_domain} - 1)) |
||||
|
_sub_domain=$(printf "%s" "$domain" | cut -c "1-$_cutlength") |
||||
|
fi |
||||
|
|
||||
|
return 0 |
||||
|
fi |
||||
|
fi |
||||
|
|
||||
|
p=$i |
||||
|
i=$((i + 1)) |
||||
|
done |
||||
|
|
||||
|
return 1 |
||||
|
} |
||||
|
|
||||
|
# _infoblox_rest GET "dns/record?_filter=..." |
||||
|
# _infoblox_rest POST "dns/record" "{json body}" |
||||
|
# _infoblox_rest DELETE "dns/record/uuid" |
||||
|
_infoblox_rest() { |
||||
|
method=$1 |
||||
|
ep="$2" |
||||
|
data="$3" |
||||
|
|
||||
|
_debug "$ep" |
||||
|
|
||||
|
# Ensure credentials are available (when called from _get_root) |
||||
|
Infoblox_UDDI_Key="${Infoblox_UDDI_Key:-$(_readaccountconf_mutable Infoblox_UDDI_Key)}" |
||||
|
Infoblox_Portal="${Infoblox_Portal:-$(_readaccountconf_mutable Infoblox_Portal)}" |
||||
|
|
||||
|
Infoblox_UDDI_Api="https://$Infoblox_Portal/api/ddi/v1" |
||||
|
export _H1="Authorization: Token $Infoblox_UDDI_Key" |
||||
|
export _H2="Content-Type: application/json" |
||||
|
|
||||
|
# Debug (masked) |
||||
|
_tok_len=$(printf "%s" "$Infoblox_UDDI_Key" | wc -c | tr -d ' \n') |
||||
|
_debug2 "Auth header set" "Token len=${_tok_len} on $Infoblox_Portal" |
||||
|
|
||||
|
if [ "$method" != "GET" ]; then |
||||
|
_debug data "$data" |
||||
|
response="$(_post "$data" "$Infoblox_UDDI_Api/$ep" "" "$method")" |
||||
|
else |
||||
|
response="$(_get "$Infoblox_UDDI_Api/$ep")" |
||||
|
fi |
||||
|
|
||||
|
_ret="$?" |
||||
|
_debug2 response "$response" |
||||
|
|
||||
|
if [ "$_ret" != "0" ]; then |
||||
|
_err "Error: $ep" |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
return 0 |
||||
|
} |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue