|
#!/bin/env ruby |
|
|
|
require 'rubygems' |
|
gem 'aws-sdk' |
|
require 'aws-sdk' |
|
require 'optparse' |
|
|
|
access_key_id = nil |
|
secret_access_key = nil |
|
hosted_zone_name = nil |
|
record_name = nil |
|
record_ttl = 300 |
|
record_value = `wget -q -O - checkip.dyndns.org|sed -e 's/.*Current IP Address: //' -e 's/<.*$//'`.chomp |
|
record_kind = "A" |
|
timeout_count = 10 |
|
timeout_wait = 5 |
|
|
|
opt = OptionParser.new |
|
opt.on('-a', '--access-key-id=VAL') { |v| access_key_id = v } |
|
opt.on('-s', '--secret-access-key=VAL') { |v| secret_access_key = v } |
|
opt.on('-z', '--hosted-zone-name=VAL') { |v| hosted_zone_name = v } |
|
opt.on('-r', '--record-name=VAL') { |v| record_name = v } |
|
opt.on('-v', '--record-value=VAL', "default:#{record_value}") { |v| record_value = v } |
|
opt.on('-t', '--record-ttl=VAL', "default:#{record_ttl}") { |v| record_ttl = v } |
|
opt.on('-k', '--record-kind=VAL', "default:#{record_kind}") { |v| record_kind = v } |
|
opt.on('-c', '--timeout-count=VAL', "default:#{timeout_count}") { |v| timeout_count = v.to_i } |
|
opt.on('-w', '--timeout-wait=VAL', "default:#{timeout_wait}") { |v| timeout_wait = v.to_i } |
|
opt.parse!(ARGV) |
|
|
|
if hosted_zone_name.nil? || record_name.nil? |
|
raise "option is necessary, use --help option" |
|
end |
|
|
|
if record_value.empty? |
|
raise "can't get public ip" |
|
end |
|
|
|
r53 = AWS::Route53.new(:access_key_id => access_key_id, |
|
:secret_access_key => secret_access_key, |
|
:proxy_uri => ENV['HTTP_PROXY'] || ENV['http_proxy']) |
|
resp = r53.client.list_hosted_zones |
|
target_id = resp[:hosted_zones].find { |x| x[:name] == hosted_zone_name }[:id] |
|
record_list = r53.client.list_resource_record_sets(:hosted_zone_id => target_id, |
|
:start_record_name => record_name) |
|
target_record = record_list[:resource_record_sets].find { |record| record[:name] == record_name } |
|
if target_record && (target_record[:resource_records].nil? || |
|
target_record[:resource_records].size != 1 || |
|
target_record[:type] != record_kind) |
|
raise "record is already exist and can't override" |
|
end |
|
|
|
if target_record && (target_record[:resource_records][0][:value] == record_value) |
|
puts "record already exist and setting is unnecessary, you should delete exist record by hand" |
|
exit |
|
end |
|
|
|
request = { |
|
:hosted_zone_id => target_id, |
|
:change_batch => { |
|
:changes => [{ |
|
:action => "CREATE", |
|
:resource_record_set => { |
|
:name => record_name, |
|
:type => record_kind, |
|
:ttl => record_ttl, |
|
:resource_records => [{ |
|
:value => record_value |
|
}] |
|
} |
|
}] |
|
} |
|
} |
|
if target_record |
|
request[:change_batch][:changes].unshift({ |
|
:action => "DELETE", |
|
:resource_record_set => target_record |
|
}) |
|
end |
|
|
|
change_result = r53.client.change_resource_record_sets(request) |
|
change_result[:change_info][:id] |
|
timeout_count.times do |
|
break if change_result[:change_info][:status] == "INSYNC" |
|
sleep timeout_wait |
|
change_result = r53.client.get_change(:id => change_result[:change_info][:id]) |
|
end |
|
|
|
if change_result[:change_info][:status] != "INSYNC" |
|
raise "timeout to update record, status is #{change_result[:change_info][:status]}" |
|
end |
|
|