Skip to content

Instantly share code, notes, and snippets.

@pastleo
Created June 1, 2023 16:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pastleo/46224bf3d1acf884b010b70d78b81dc3 to your computer and use it in GitHub Desktop.
Save pastleo/46224bf3d1acf884b010b70d78b81dc3 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
require 'date'
require 'net/http'
require 'uri'
require 'json'
# crontab -e
# */30 * * * * path/to/dynamic-ip.rb
IP_REPORT = 'https://_____________'
CLOUDFLARE_API_TOKEN = '________________________________________'
CLOUDFLARE_ZONE_ID = '________________________________'
DNS_RECORD_NAME = '_______________'
DIR = File.expand_path(File.dirname(__FILE__))
STATE_JSON_FILE = File.join(DIR, "dynamic-ip.json")
IP_CHANGE_LOG_FILE = File.join(DIR, "dynamic-ip-changed.log")
time_now = DateTime.now().to_s
puts ":: Time: #{time_now}"
if File.exist?(STATE_JSON_FILE)
state = JSON.parse(File.read(STATE_JSON_FILE))
else
state = {}
end
puts ">> getting IP..."
ip = Net::HTTP.get(URI(IP_REPORT)).strip
puts ":: IP: #{ip}"
if state["last_ip"] == ip
puts ":: IP is the same, skipping..."
exit 0
end
puts ">> getting record id of #{DNS_RECORD_NAME}..."
record_list_uri = URI("https://api.cloudflare.com/client/v4/zones/#{CLOUDFLARE_ZONE_ID}/dns_records?name=#{DNS_RECORD_NAME}")
dns_record_id = Net::HTTP.start(record_list_uri.hostname, record_list_uri.port, use_ssl: true) do |http|
req = Net::HTTP::Get.new(record_list_uri)
req["Content-Type"] = "application/json"
req["Authorization"] = "Bearer #{CLOUDFLARE_API_TOKEN}"
JSON.parse(http.request(req).body)["result"][0]["id"] rescue nil
end
if dns_record_id
puts ":: dns_record_id: #{dns_record_id}"
else
puts ":: can not get dns_record_id, exiting..."
exit 1
end
puts ">> updating IP to cloudflare..."
patch_ip_uri = URI("https://api.cloudflare.com/client/v4/zones/#{CLOUDFLARE_ZONE_ID}/dns_records/#{dns_record_id}")
res = Net::HTTP.start(patch_ip_uri.hostname, patch_ip_uri.port, use_ssl: true) do |http|
req = Net::HTTP::Patch.new(patch_ip_uri)
req["Content-Type"] = "application/json"
req["Authorization"] = "Bearer #{CLOUDFLARE_API_TOKEN}"
req.body = {
"type" => "A",
"content" => ip,
}.to_json
http.request(req)
end
puts ':: req sent, result:'
pp res
pp res.body
state["last_ip"] = ip
puts ">> writing state to file..."
File.write(STATE_JSON_FILE, state.to_json)
puts ':: state file written'
puts ">> writing IP_CHANGE_LOG_FILE: #{IP_CHANGE_LOG_FILE}"
ip_change_log = File.open(IP_CHANGE_LOG_FILE, 'a')
ip_change_log.write("#{time_now} :: #{ip}\n")
ip_change_log.close
puts ':: state file written'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment