summaryrefslogtreecommitdiffstats
path: root/net/ddns-scripts/files/update_CloudFlare.sh
blob: 15f3afd3218fab342bbc9553bdafc4a19c71de6a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#
#.Distributed under the terms of the GNU General Public License (GPL) version 2.0
#
# script for sending updates to cloudflare.com
#.2014-2015 Christian Schoenebeck <christian dot schoenebeck at gmail dot com>
# many thanks to Paul for testing and feedback during development
#
# This script is parsed by dynamic_dns_functions.sh inside send_update() function
#
# using following options from /etc/config/ddns
# option username - your cloudflare e-mail
# option password - cloudflare api key, you can get it from cloudflare.com/my-account/
# option domain   - your full hostname to update, in cloudflare its subdomain.domain
#			i.e. myhost.example.com where myhost is the subdomain and example.com is your domain
#
# variable __IP already defined with the ip-address to use for update
#
[ $use_https -eq 0 ] && write_log 14 "Cloudflare only support updates via Secure HTTP (HTTPS). Please correct configuration!"
[ -z "$username" ] && write_log 14 "Service section not configured correctly! Missing 'username'"
[ -z "$password" ] && write_log 14 "Service section not configured correctly! Missing 'password'"

local __RECID __URL __KEY __KEYS __FOUND __SUBDOM __DOMAIN __TLD

# split given Host/Domain into TLD, registrable domain, and subdomain
split_FQDN $domain __TLD __DOMAIN __SUBDOM
[ $? -ne 0 -o -z "$__DOMAIN" ] && \
	write_log 14 "Wrong Host/Domain configuration ($domain). Please correct configuration!"

# put together what we need
__DOMAIN="$__DOMAIN.$__TLD"

# parse OpenWrt script with
# functions for parsing and generating json
. /usr/share/libubox/jshn.sh

# function copied from /usr/share/libubox/jshn.sh
# from BB14.09 for backward compatibility to AA12.09
grep -i "json_get_keys" /usr/share/libubox/jshn.sh >/dev/null 2>&1 || json_get_keys() {
	local __dest="$1"
	local _tbl_cur

	if [ -n "$2" ]; then
		json_get_var _tbl_cur "$2"
	else
		_json_get_var _tbl_cur JSON_CUR
	fi
	local __var="${JSON_PREFIX}KEYS_${_tbl_cur}"
	eval "export -- \"$__dest=\${$__var}\"; [ -n \"\${$__var+x}\" ]"
}

# function to "sed" unwanted string parts from DATFILE
cleanup() {
	# based on the sample output on cloudflare.com homepage we need to do some cleanup
	sed -i 's/^[ \t]*//;s/[ \t]*$//' $DATFILE	# remove invisible chars at beginning and end of lines
	sed -i '/^-$/d' $DATFILE			# remove lines with "-" (dash)
	sed -i '/^$/d' $DATFILE				# remove empty lines
	sed -i "#'##g" $DATFILE				# remove "'" (single quote)
}

[ -n "$rec_id" ] && __RECID="$rec_id" || {
	# build url according to cloudflare client api at https://www.cloudflare.com/docs/client-api.html
	# to "rec_load_all" to detect rec_id needed for update
	__URL="https://www.cloudflare.com/api_json.html"	# https://www.cloudflare.com/api_json.html
	__URL="${__URL}?a=rec_load_all"				#  -d 'a=rec_load_all'
	__URL="${__URL}&tkn=$password"				#  -d 'tkn=8afbe6dea02407989af4dd4c97bb6e25'
	__URL="${__URL}&email=$username"			#  -d 'email=sample@example.com'
	__URL="${__URL}&z=$__DOMAIN"				#  -d 'z=example.com'

	# lets request the data
	do_transfer "$__URL" || return 1

	cleanup				# cleanup dat file
	json_load "$(cat $DATFILE)"	# lets extract data
	__FOUND=0			# found record indicator
	json_get_var __RES "result"	# cloudflare result of last request
	json_get_var __MSG "msg"	# cloudflare error message
	[ "$__RES" != "success" ] && {
		write_log 4 "'rec_load_all' failed with error: \n$__MSG"
		return 1
	}

	json_select "response"
	json_select "recs"
	json_select "objs"
	json_get_keys __KEYS
	for __KEY in $__KEYS; do
		local __ZONE __DISPLAY __NAME __TYPE
		json_select "$__KEY"
	#	json_get_var __ZONE "zone_name"		# for debugging
	#	json_get_var __DISPLAY "display_name"	# for debugging
		json_get_var __NAME "name"
		json_get_var __TYPE "type"
		if [ "$__NAME" = "$domain" ]; then
			# we must verify IPv4 and IPv6 because there might be both for the same host
			[ \( $use_ipv6 -eq 0 -a "$__TYPE" = "A" \) -o \( $use_ipv6 -eq 1 -a "$__TYPE" = "AAAA" \) ] && {
				__FOUND=1	# mark found
				break		# found leave for loop
			}
		fi
		json_select ..
	done
	[ $__FOUND -eq 0 ] && {
		# we don't need to continue trying to update cloudflare because record to update does not exist
		# user has to setup record first outside ddns-scripts
		write_log 14 "No valid record found at Cloudflare setup. Please create first!"
	}
	json_get_var __RECID "rec_id"	# last thing to do get rec_id
	json_cleanup			# cleanup
	write_log 7 "rec_id '$__RECID' detected for host/domain '$domain'"
}

# build url according to cloudflare client api at https://www.cloudflare.com/docs/client-api.html
# for "rec_edit" to update IP address
__URL="https://www.cloudflare.com/api_json.html"	# https://www.cloudflare.com/api_json.html
__URL="${__URL}?a=rec_edit"				#  -d 'a=rec_edit'
__URL="${__URL}&tkn=$password"				#  -d 'tkn=8afbe6dea02407989af4dd4c97bb6e25'
__URL="${__URL}&id=$__RECID"				#  -d 'id=9001'
__URL="${__URL}&email=$username"			#  -d 'email=sample@example.com'
__URL="${__URL}&z=$__DOMAIN"				#  -d 'z=example.com'

[ $use_ipv6 -eq 0 ] && __URL="${__URL}&type=A"		#  -d 'type=A'		(IPv4)
[ $use_ipv6 -eq 1 ] && __URL="${__URL}&type=AAAA"	#  -d 'type=AAAA'	(IPv6)

# handle subdomain or domain record
[ -n "$__SUBDOM" ] && __URL="${__URL}&name=$__SUBDOM"	#  -d 'name=sub'	(HOST/SUBDOMAIN)
[ -z "$__SUBDOM" ] && __URL="${__URL}&name=$__DOMAIN"	#  -d 'name=example.com'(DOMAIN)

__URL="${__URL}&content=$__IP"				#  -d 'content=1.2.3.4'
__URL="${__URL}&service_mode=0"				#  -d 'service_mode=0'
__URL="${__URL}&ttl=1"					#  -d 'ttl=1'

# lets do the update
do_transfer "$__URL" || return 1

cleanup				# cleanup tmp file
json_load "$(cat $DATFILE)"	# lets extract data
json_get_var __RES "result"	# cloudflare result of last request
json_get_var __MSG "msg"	# cloudflare error message
[ "$__RES" != "success" ] && {
	write_log 4 "'rec_edit' failed with error:\n$__MSG"
	return 1
}
write_log 7 "Update of rec_id '$__RECID' successful"
return 0