Skip to content

Instantly share code, notes, and snippets.

@thepatrick
Created August 6, 2009 06:41
Show Gist options
  • Save thepatrick/163179 to your computer and use it in GitHub Desktop.
Save thepatrick/163179 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
require 'rubygems'
require 'getoptlong'
require 'open-uri'
require 'json'
require 'net/http'
require 'uri'
# You can either use this, or
# set IP using some other method.
ip_source = "http://www.whatismyip.com/automation/n09230945.asp"
my_ip = open(ip_source).read
base = "http://dns.m.ac.nz/dnsconfig/api/"
key = "" # ... see below
# To get a key:
# Visit: this. #dev# doesn't matter, it's an identifier if I ever make a UI for it.
#http://dns.m.ac.nz/dnsconfig/api/key/create?device_id={#dev#}&application_name=RubyDynDNSUpdater
#you'll get back some json that looks like:
## { key: '...' }
#now, you'll need to authenticate that key, visit:
#http://dns.m.ac.nz/dnsconfig/api/key/auth?api.key={#key#}
# if the key has not been authenticated you'll get back json like:
## { auth_url: '...', 'error': 'NOT_AUTHD_YET' }
# just visit the auth_url, log in, and boom! done.
# if you have already auth'd the key you'll get back this instead:
## { status: 'ok', 'user': { 'nickname': '...' }}
# Note! The publish method will fail (although it may appear to work!)
# if your domain has not been approved. Contact patrick
# through http://patrick.geek.nz/contactme
# Domain is the domain as it appears in the left side source list,
# subdomain is the record to update.
domain = "patrick.geek.nz"
subdomain = "home.ca"
all_domains = JSON.parse(open(base + "domain/all?api.key=" + key).read)
## { status: 'ok', 'domains': [{'version':,'fqdn':, 'key':}...]}
if(all_domains.nil? or !all_domains[:status].eql?('ok'))
puts "[FAILED] Call to fetch domains failed."
exit
end
my_domain = nil
all_domains['domains'].each do |d|
if(d['fqdn'].eql?(domain))
my_domain = d
end
end
unless(my_domain)
puts "[FAILED] Domain requested not found."
exit
end
all_records = JSON.parse(open(base + "domain/get?id=" + my_domain['key'] + "&api.key=" + key).read)
## { status: , records: [{name:, weight:, id:, priority:, type:, port:, resource_type:, target:}, ...]}
if(all_records.nil? or !all_records['status'].eql?('ok'))
puts "[FAILED] Call to fetch domain records failed."
exit
end
my_record = nil
all_records['records'].each do |d|
if(d['name'].eql?(subdomain))
my_record = d
end
end
unless(my_record)
puts "[FAILED] Record requested not found."
exit
end
if(my_record['target'].eql?(my_ip))
puts "[INFO] DNS entry already points at current IP."
exit
end
def apiPost(base, method, apikey, params)
url = URI.parse(base + method)
req = Net::HTTP::Post.new(url.path + "?api.key=" + apikey)
req.set_form_data(params)
res = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) }
case res
when Net::HTTPSuccess, Net::HTTPRedirection
JSON.parse(res.body)
else
nil
end
end
my_record['target'] = my_ip
update_result = apiPost(base, 'record/modify', key, my_record)
if(update_result.nil? or !update_result['status'].eql?('ok'))
puts "[FAILED] Call to update record failed."
exit
end
publish_result = apiPost(base, 'domain/publish', key, { 'id' => my_domain['key'] })
if(publish_result.nil? or !publish_result['status'].eql?('ok'))
puts "[FAILED] Call to publish domain failed."
exit
end
puts "[SUCCESS] Updated " + subdomain + "." + domain + " to " + my_ip
puts "[SUCCESS] Domain version: " + publish_result['version'].to_s
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment