Janos Lenart
7 years ago
3 changed files with 189 additions and 0 deletions
@ -0,0 +1,167 @@ |
|||
#!/usr/bin/env sh |
|||
|
|||
# Author: Janos Lenart <janos@lenart.io> |
|||
|
|||
######## Public functions ##################### |
|||
|
|||
# Usage: dns_gcloud_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" |
|||
dns_gcloud_add() { |
|||
fulldomain=$1 |
|||
txtvalue=$2 |
|||
_info "Using gcloud" |
|||
_debug fulldomain "$fulldomain" |
|||
_debug txtvalue "$txtvalue" |
|||
|
|||
_dns_gcloud_find_zone || return $? |
|||
|
|||
# Add an extra RR |
|||
_dns_gcloud_start_tr || return $? |
|||
_dns_gcloud_get_rrdatas || return $? |
|||
echo "$rrdatas" | _dns_gcloud_remove_rrs || return $? |
|||
echo -e "$rrdatas\n\"$txtvalue\"" | grep -v '^$' | _dns_gcloud_add_rrs || return $? |
|||
_dns_gcloud_execute_tr || return $? |
|||
|
|||
_info "$fulldomain record added" |
|||
} |
|||
|
|||
# Usage: dns_gcloud_rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" |
|||
# Remove the txt record after validation. |
|||
dns_gcloud_rm() { |
|||
fulldomain=$1 |
|||
txtvalue=$2 |
|||
_info "Using gcloud" |
|||
_debug fulldomain "$fulldomain" |
|||
_debug txtvalue "$txtvalue" |
|||
|
|||
_dns_gcloud_find_zone || return $? |
|||
|
|||
# Remove one RR |
|||
_dns_gcloud_start_tr || return $? |
|||
_dns_gcloud_get_rrdatas || return $? |
|||
echo "$rrdatas" | _dns_gcloud_remove_rrs || return $? |
|||
echo "$rrdatas" | fgrep -v "\"$txtvalue\"" | _dns_gcloud_add_rrs || return $? |
|||
_dns_gcloud_execute_tr || return $? |
|||
|
|||
_info "$fulldomain record added" |
|||
} |
|||
|
|||
#################### Private functions below ################################## |
|||
|
|||
_dns_gcloud_start_tr() { |
|||
if ! trd=`mktemp -d`; then |
|||
_err "_dns_gcloud_start_tr: failed to create temporary directory" |
|||
return 1 |
|||
fi |
|||
tr="$trd/tr.yaml" |
|||
_debug tr "$tr" |
|||
|
|||
if ! gcloud dns record-sets transaction start \ |
|||
--transaction-file="$tr" \ |
|||
--zone="$managedZone"; then |
|||
rm -r "$trd" |
|||
_err "_dns_gcloud_start_tr: failed to execute transaction" |
|||
return 1 |
|||
fi |
|||
} |
|||
|
|||
_dns_gcloud_execute_tr() { |
|||
if ! gcloud dns record-sets transaction execute \ |
|||
--transaction-file="$tr" \ |
|||
--zone="$managedZone"; then |
|||
_debug tr "`cat \"$tr\"`" |
|||
rm -r "$trd" |
|||
_err "_dns_gcloud_execute_tr: failed to execute transaction" |
|||
return 1 |
|||
fi |
|||
rm -r "$trd" |
|||
|
|||
for i in `seq 1 120`; do |
|||
if gcloud dns record-sets changes list \ |
|||
--zone=lenart \ |
|||
--filter='status != done' \ |
|||
| grep -q '.*'; then |
|||
_info "_dns_gcloud_execute_tr: waiting for transaction to be comitted ..." |
|||
sleep 5 |
|||
else |
|||
return 0 |
|||
fi |
|||
done |
|||
|
|||
_err "_dns_gcloud_execute_tr: transaction is still pending after 10 minutes" |
|||
rm -r "$trd" |
|||
return 1 |
|||
} |
|||
|
|||
_dns_gcloud_remove_rrs() { |
|||
if ! xargs --no-run-if-empty gcloud dns record-sets transaction remove \ |
|||
--name="$fulldomain." \ |
|||
--ttl="$ttl" \ |
|||
--type=TXT \ |
|||
--zone="$managedZone" \ |
|||
--transaction-file="$tr"; then |
|||
_debug tr "`cat \"$tr\"`" |
|||
rm -r "$trd" |
|||
_err "_dns_gcloud_remove_rrs: failed to remove RRs" |
|||
return 1 |
|||
fi |
|||
} |
|||
|
|||
_dns_gcloud_add_rrs() { |
|||
ttl=60 |
|||
if ! xargs --no-run-if-empty gcloud dns record-sets transaction add \ |
|||
--name="$fulldomain." \ |
|||
--ttl="$ttl" \ |
|||
--type=TXT \ |
|||
--zone="$managedZone" \ |
|||
--transaction-file="$tr"; then |
|||
_debug tr "`cat \"$tr\"`" |
|||
rm -r "$trd" |
|||
_err "_dns_gcloud_add_rrs: failed to add RRs" |
|||
return 1 |
|||
fi |
|||
} |
|||
|
|||
_dns_gcloud_find_zone() { |
|||
# Prepare a filter that matches zones that are suiteable for this entry. |
|||
# For example, _acme-challenge.something.domain.com might need to go into something.domain.com or domain.com; |
|||
# this function finds the longest postfix that has a managed zone. |
|||
part="$fulldomain" |
|||
filter="dnsName=( " |
|||
while [ "$part" != "" ]; do |
|||
filter="$filter$part. " |
|||
part="`echo \"$part\" | sed 's/[^.]*\.*//'`" |
|||
done |
|||
filter="$filter)" |
|||
_debug filter "$filter" |
|||
|
|||
# List domains and find the longest match (in case of some levels of delegation) |
|||
if ! match=$(gcloud dns managed-zones list \ |
|||
--format="value(name, dnsName)" \ |
|||
--filter="$filter" \ |
|||
| while read dnsName name; do |
|||
echo -e "${#dnsName}\t$dnsName\t$name" |
|||
done \ |
|||
| sort -n -r | head -n1 | cut -f2,3 | grep '.*'); then |
|||
_err "_dns_gcloud_find_zone: Can't find a matching managed zone! Perhaps wrong project or gcloud credentials?" |
|||
return 1 |
|||
fi |
|||
|
|||
dnsName=$(echo "$match" | cut -f2) |
|||
_debug dnsName "$dnsName" |
|||
managedZone=$(echo "$match" | cut -f1) |
|||
_debug managedZone "$managedZone" |
|||
} |
|||
|
|||
_dns_gcloud_get_rrdatas() { |
|||
if ! rrdatas=$(gcloud dns record-sets list \ |
|||
--zone="$managedZone" \ |
|||
--name="$fulldomain." \ |
|||
--type=TXT \ |
|||
--format="value(ttl,rrdatas)"); then |
|||
_err "_dns_gcloud_get_rrdatas: Failed to list record-sets" |
|||
rm -r "$trd" |
|||
return 1 |
|||
fi |
|||
ttl=$(echo "$rrdatas" | cut -f1) |
|||
rrdatas=$(echo "$rrdatas" | cut -f2 | sed 's/","/"\n"/g') |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue