Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- require "net/https"
- require "optparse"
- require "json"
- require "uri"
- options = {:ttl => "3600", :records => {}}
- req_headers = {"Content-Type" => "application/json"}
- OptionParser.new do |opts|
- opts.banner = "Usage: ddns.rb -a -p -f file/path -t 3600 -r example.com"
- opts.on("-f", "--token TOKEN_PATH", "Absolute path of file containing a Cloudflare API token.") do |path|
- if File.file?(path) then
- if File.readable?(path) then
- cf_token = File.read(path)
- cf_token = cf_token.gsub("\s", "")
- req_headers["Authorization"] = "Bearer " + cf_token
- else
- warn "Token file not readable."
- exit 11
- end
- else
- warn "Failed to find token file."
- exit 10
- end
- end
- opts.on("-t", "--ttl TTL", "TTL") do |ttl|
- options[:ttl] = ttl
- end
- opts.on("-a", "--aaaa", "Update AAAA records as well as A records.") do |aaaa|
- options[:update_aaaa] = aaaa
- end
- opts.on("-p", "--proxy", "Enable proxy on updated DNS records.") do |proxy|
- options[:enable_proxy] = proxy
- end
- opts.on("-r", "--record RECORD", "Add record name to update.") do |record|
- options[:records][record] = true
- end
- end.parse!
- print "Fetching external IP... "
- ip_res, external_ip = Net::HTTP.get_response("checkip.amazonaws.com", "/")
- if ip_res.code == "200" then
- external_ip = ip_res.body.tr("\n", "")
- puts "#{external_ip}."
- else
- puts "Failed."
- puts "#{ip_res.code}: #{ip_res.body}"
- exit 20
- end
- puts "Updating DDNS records."
- zone_uri = URI.parse("https://api.cloudflare.com/client/v4/zones")
- https = Net::HTTP.new(zone_uri.host, zone_uri.port)
- https.use_ssl = true
- zone_req = Net::HTTP::Get.new(zone_uri, req_headers)
- zone_res = JSON.parse(https.request(zone_req).body)
- if zone_res["success"] == true then
- puts "Found #{zone_res["result"].count()} zone(s) to update."
- zone_res["result"].each do |zone|
- puts "Fetching records from zone '#{zone["name"]}'."
- zone_id = zone["id"]
- record_uri = URI.parse("https://api.cloudflare.com/client/v4/zones/#{zone_id}/dns_records")
- https = Net::HTTP.new(record_uri.host, record_uri.port)
- https.use_ssl = true
- record_req = Net::HTTP::Get.new(record_uri, req_headers)
- record_res = JSON.parse(https.request(record_req).body)
- if record_res["success"] == true then
- record_res["result"].each do |record|
- record_name = record["name"]
- record_type = record["type"]
- if options[:records][record_name] && (record_type == "A" or (options[:update_aaaa] && record_type == "AAAA")) then
- print "Updating record '#{record_name}'... "
- if record["content"] == external_ip then
- puts "Content doesn't need updating, skipping record."
- else
- update = {
- "type" => record_type,
- "name" => record_name,
- "content" => external_ip,
- "ttl" => options[:ttl],
- "proxied" => options[:enable_proxy]
- }
- update_uri = URI.parse("https://api.cloudflare.com/client/v4/zones/#{zone_id}/dns_records/#{record["id"]}")
- https = Net::HTTP.new(update_uri.host, update_uri.port)
- https.use_ssl = true
- update_req = Net::HTTP::Put.new(update_uri, req_headers)
- update_req.body = update.to_json
- update_res = JSON.parse(https.request(update_req).body)
- if update_res["success"] == true then
- puts "Updated successfully!"
- else
- puts "Update failed!"
- pp update_res
- end
- end
- end
- end
- else
- puts record_res
- exit 22
- end
- end
- else
- puts zone_res
- exit 21
- end
- puts "Updated DDNS records successfully."
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement