Skip to content

Commit

Permalink
Adding omg.lol DNS API
Browse files Browse the repository at this point in the history
  • Loading branch information
as-kholin committed Sep 24, 2024
1 parent c20b016 commit e6b3e42
Showing 1 changed file with 363 additions and 0 deletions.
363 changes: 363 additions & 0 deletions dnsapi/dns_omglol.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,363 @@
#!/usr/bin/env sh
# shellcheck disable=SC2034
dns_myapi_info='omg.lol
Based on the omg.lol API, defined at https://api.omg.lol/

This comment has been minimized.

Copy link
@stokito

stokito Nov 9, 2024

Contributor

The description is in fact useless, it would be better to remove it

This comment has been minimized.

Copy link
@as-kholin

as-kholin Nov 9, 2024

Author Contributor

Submitting PR to Dev for missed documentation updates, per your feedback.

This comment has been minimized.

Copy link
@stokito

stokito Nov 9, 2024

Contributor

I had a free minute so I fixed myself. Will send a PR. I'll try to document better how the structured info should be made.

Domains: omg.lol
Site: github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide

This comment has been minimized.

Copy link
@stokito

stokito Nov 9, 2024

Contributor

The Site: should be just a domain

Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_duckdns
Options:
omglolapikey API Key from omg.lol. This is accesible from the bottom of the account page at https://home.omg.lol/account

This comment has been minimized.

Copy link
@as-kholin

as-kholin Nov 9, 2024

Author Contributor

This is not the final commit - when this was documented, it was accurate. Final commit where documentation here matches the updated variables is f6698d4.

omgloladdress This is your omg.lol address, without the preceding @ - you can see your list on your dashboard at https://home.omg.lol/dashboard
Issues: github.com/acmesh-official/acme.sh
Author: @Kholin <kholin+omglolapi@omg.lol>
'

#returns 0 means success, otherwise error.

######## Public functions #####################

# Please Read this guide first: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide

#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_omglol_add() {
fulldomain=$1
txtvalue=$2
omglol_apikey="${omglol_apikey:-$(_readaccountconf_mutable omglol_apikey)}"
omglol_address="${omglol_address:-$(_readaccountconf_mutable omglol_address)}"

# As omg.lol includes a leading @ for their addresses, pre-strip this before save
omglol_address="$(echo "$omglol_address" | tr -d '@')"

_saveaccountconf_mutable omglol_apikey "$omglol_apikey"
_saveaccountconf_mutable omglol_address "$omglol_address"

_info "Using omg.lol."
_debug "Function" "dns_omglol_add()"
_debug "Full Domain Name" "$fulldomain"
_debug "txt Record Value" "$txtvalue"
_secure_debug "omg.lol API key" "$omglol_apikey"
_debug "omg.lol Address" "$omglol_address"

omglol_validate "$omglol_apikey" "$omglol_address" "$fulldomain"

dnsName=$(_getDnsRecordName "$fulldomain" "$omglol_address")
authHeader="$(_createAuthHeader "$omglol_apikey")"

_debug2 " dns_omglol_add(): Address" "$dnsName"

omglol_add "$omglol_address" "$authHeader" "$dnsName" "$txtvalue"

}

#Usage: fulldomain txtvalue
#Remove the txt record after validation.
dns_omglol_rm() {
fulldomain=$1
txtvalue=$2
omglol_apikey="${omglol_apikey:-$(_readaccountconf_mutable omglol_apikey)}"
omglol_address="${omglol_address:-$(_readaccountconf_mutable omglol_address)}"

# As omg.lol includes a leading @ for their addresses, strip this in case provided
omglol_address="$(echo "$omglol_address" | tr -d '@')"

_info "Using omg.lol"
_debug fulldomain "$fulldomain"
_secure_debug ApiKey "$omglol_apikey"
_debug address "$omglol_address"

omglol_validate "$omglol_apikey" "$omglol_address" "$fulldomain"

dnsName=$(_getDnsRecordName "$fulldomain" "$omglol_address")
authHeader="$(_createAuthHeader "$omglol_apikey")"

omglol_delete "$omglol_address" "$authHeader" "$dnsName" "$txtvalue"
}

#################### Private functions below ##################################
# Check that the minimum requirements are present. Close ungracefully if not
omglol_validate() {
omglol_apikey=$1
omglol_address=$2
fulldomain=$3

if [ "" = "$omglol_address" ]; then
_err "omg.lol base address not provided. Exiting"
exit 1
fi

if [ "" = "$omglol_apikey" ]; then
_err "omg.lol API key not provided. Exiting"
exit 1
fi

_endswith "$fulldomain" "omg.lol"
if [ ! $? ]; then
_err "Domain name requested is not under omg.lol"
exit 1
fi

_endswith "$fulldomain" "$omglol_address.omg.lol"
if [ ! $? ]; then
_err "Domain name is not a subdomain of provided omg.lol address $omglol_address"
exit 1
fi

_debug "omglol_validate(): Required environment parameters are all present"
}

# Add (or modify) an entry for a new ACME query
omglol_add() {
address=$1
authHeader=$2
dnsName=$3
txtvalue=$4

_info " Creating DNS entry for $dnsName"
_debug2 " omglol_add()"
_debug2 " omg.lol Address: " "$address"
_secure_debug2 " omg.lol authorization header: " "$authHeader"
_debug2 " Full Domain name:" "$dnsName.$address.omg.lol"
_debug2 " TXT value to set:" "$txtvalue"

export _H1="$authHeader"

endpoint="https://api.omg.lol/address/$address/dns"
_debug2 " Endpoint" "$endpoint"

payload='{"type": "TXT", "name":"'"$dnsName"'", "data":"'"$txtvalue"'", "ttl":30}'
_debug2 " Payload" "$payload"

response=$(_post "$payload" "$endpoint" "" "POST" "application/json")

omglol_validate_add "$response" "$dnsName.$address" "$txtvalue"
}

omglol_validate_add() {
response=$1
name=$2
content=$3

_info " Validating DNS record addition"
_debug2 " omglol_validate_add()"
_debug2 " Response" "$response"
_debug2 " DNS Name" "$name"
_debug2 " DNS value" "$content"

_jsonResponseCheck "$response" "success" "true"
if [ "1" = "$?" ]; then
_err "Response did not report success"
return 1
fi

_jsonResponseCheck "$response" "message" "Your DNS record was created successfully."
if [ "1" = "$?" ]; then
_err "Response message did not indicate DNS record was successfully created"
return 1
fi

_jsonResponseCheck "$response" "name" "$name"
if [ "1" = "$?" ]; then
_err "Response DNS Name did not match the response received"
return 1
fi

_jsonResponseCheck "$response" "content" "$content"
if [ "1" = "$?" ]; then
_err "Response DNS Name did not match the response received"
return 1
fi

_debug " Record Created successfully"
return 0
}

omglol_getRecords() {
address=$1
authHeader=$2
dnsName=$3
txtValue=$4

_debug2 " omglol_getRecords()"
_debug2 " omg.lol Address: " "$address"
_secure_debug2 " omg.lol Auth Header: " "$authHeader"
_debug2 " omg.lol DNS name:" "$dnsName"
_debug2 " txt Value" "$txtValue"

export _H1="$authHeader"

endpoint="https://api.omg.lol/address/$address/dns"
_debug2 " Endpoint" "$endpoint"

payload=$(_get "$endpoint")

_debug2 " Received Payload:" "$payload"

# Reformat the JSON to be more parseable
recordID=$(echo "$payload" | _stripWhitespace)
recordID=$(echo "$recordID" | _exposeJsonArray)

# Now find the one with the right value, and caputre its ID
recordID=$(echo "$recordID" | grep -- "$txtValue" | grep -i -- "$dnsName.$address")
_getJsonElement "$recordID" "id"
}

omglol_delete() {
address=$1
authHeader=$2
dnsName=$3
txtValue=$4

_info " Deleting DNS entry for $dnsName with value $txtValue"
_debug2 " omglol_delete()"
_debug2 " omg.lol Address: " "$address"
_secure_debug2 " omg.lol Auth Header: " "$authHeader"
_debug2 " Full Domain name:" "$dnsName.$address.omg.lol"
_debug2 " txt Value" "$txtValue"

record=$(omglol_getRecords "$address" "$authHeader" "$dnsName" "$txtvalue")

endpoint="https://api.omg.lol/address/$address/dns/$record"
_debug2 " Endpoint" "$endpoint"

export _H1="$authHeader"
output=$(_post "" "$endpoint" "" "DELETE")

_debug2 " Response" "$output"

omglol_validate_delete "$output"
}

# Validate the response on request to delete. Confirm stastus is success and
# Message indicates deletion was successful
# Input: Response - HTTP response received from delete request
omglol_validate_delete() {
response=$1

_info " Validating DNS record deletion"
_debug2 " omglol_validate_delete()"
_debug " Response" "$response"

_jsonResponseCheck "$output" "success" "true"
if [ "1" = "$?" ]; then
_err "Response did not report success"
return 1
fi

_jsonResponseCheck "$output" "message" "OK, your DNS record has been deleted."
if [ "1" = "$?" ]; then
_err "Response message did not indicate DNS record was successfully deleted"
return 1
fi

_info " Record deleted successfully"
return 0
}

########## Utility Functions #####################################
# All utility functions only log at debug3
_jsonResponseCheck() {
response=$1
field=$2
correct=$3

correct=$(echo "$correct" | _lower_case)

_debug3 " jsonResponseCheck()"
_debug3 " Response to parse" "$response"
_debug3 " Field to get response from" "$field"
_debug3 " What is the correct response" "$correct"

responseValue=$(_jsonGetLastResponse "$response" "$field")

if [ "$responseValue" != "$correct" ]; then
_debug3 " Expected: $correct"
_debug3 " Actual: $responseValue"
return 1
else
_debug3 " Matched: $responseValue"
fi
return 0
}

_jsonGetLastResponse() {
response=$1
field=$2

_debug3 " jsonGetLastResponse()"
_debug3 " Response provided" "$response"
_debug3 " Field to get responses for" "$field"
responseValue=$(echo "$response" | grep -- "\"$field\"" | cut -f2 -d":")

_debug3 " Response lines found:" "$responseValue"

responseValue=$(echo "$responseValue" | sed 's/^ //g' | sed 's/^"//g' | sed 's/\\"//g')
responseValue=$(echo "$responseValue" | sed 's/,$//g' | sed 's/"$//g')
responseValue=$(echo "$responseValue" | _lower_case)

_debug3 " Responses found" "$responseValue"
_debug3 " Response Selected" "$(echo "$responseValue" | tail -1)"

echo "$responseValue" | tail -1
}

_stripWhitespace() {
tr -d '\n' | tr -d '\r' | tr -d '\t' | sed -r 's/ +/ /g' | sed 's/\\"//g'
}

_exposeJsonArray() {
sed -r 's/.*\[//g' | tr '}' '|' | tr '{' '|' | sed 's/|, |/|/g' | tr '|' '\n'
}

_getJsonElement() {
content=$1
field=$2

# With a single JSON entry to parse, convert commas to newlines puts each element on
# its own line - which then allows us to just grep teh name, remove the key, and
# isolate the value
output=$(echo "$content" | tr ',' '\n' | grep -- "\"$field\":" | sed 's/.*: //g')

_debug3 " String before unquoting: $output"

_unquoteString "$output"
}

_createAuthHeader() {
apikey=$1

authheader="Authorization: Bearer $apikey"
_secure_debug2 " Authorization Header" "$authheader"
echo "$authheader"
}

_getDnsRecordName() {
fqdn=$1
address=$2

echo "$fqdn" | sed 's/\.omg\.lol//g' | sed 's/\.'"$address"'$//g'
}

_unquoteString() {
output=$1
quotes=0

_startswith "$output" "\""
if [ $? ]; then
quotes=$((quotes + 1))
fi

_endswith "$output" "\""
if [ $? ]; then
quotes=$((quotes + 1))
fi

_debug3 " Original String: $output"
_debug3 " Quotes found: $quotes"

if [ $((quotes)) -gt 1 ]; then
output=$(echo "$output" | sed 's/^"//g' | sed 's/"$//g')
_debug3 " Quotes removed: $output"
fi

echo "$output"
}

0 comments on commit e6b3e42

Please sign in to comment.