Skip to content

Instantly share code, notes, and snippets.

@bouzuya
Created September 28, 2013 23:47
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 bouzuya/6747877 to your computer and use it in GitHub Desktop.
Save bouzuya/6747877 to your computer and use it in GitHub Desktop.
#
# Usage:
#
# export AMAZON_ACCESS_KEY_ID='xxxxxxxxxxxxxxxxxxxx'
# export AMAZON_SECRET_ACCESS_KEY='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
# export BASE_DOMAIN='example.com'
# export RECORD_VALUE='www.example.com'
#
# ruby route53_user_manager.rb add bouzuya
# #=> bouzuya.example.com. CNAME www.example.com.
# ruby route53_user_manager.rb add aws
# #=> aws.example.com. CNAME www.example.com.
# ruby route53_user_manager.rb list
# #=> bouzuya
# #=> aws
# ruby route53_user_manager.rb remove bouzuya
# ruby route53_user_manager.rb list
# #=> aws
require 'rubygems'
require 'aws-sdk'
BASE_DOMAIN = ENV['ROUTE53_USER_MANAGER_BASE_DOMAIN']
RECORD_VALUE = ENV['ROUTE53_USER_MANAGER_RECORD_VALUE']
class Route53UserManager
RECORD_TYPE = 'CNAME'
RECORD_TTL = 300
def initialize(base_domain, record_value)
@r53 = AWS::Route53.new
@hosted_zone = fetch_hosted_zones.select {|zone| zone[:name] == (base_domain + '.') }.first
@record_value = record_value
raise if @hosted_zone.nil?
end
def add(user)
validate_user(user)
name = user + '.' + @hosted_zone[:name]
type = RECORD_TYPE
options = { resource_records: [{ value: @record_value }], ttl: RECORD_TTL }
request = AWS::Route53::CreateRequest.new(name, type, options)
batch = AWS::Route53::ChangeBatch.new @hosted_zone[:id]
batch << request
batch.call
end
def remove(user)
validate_user(user)
name = user + '.' + @hosted_zone[:name]
record = fetch_resource_record_sets.select {|r| r[:type] == RECORD_TYPE }.select {|r| r[:name] == name }.first
return nil if record.nil?
type = record[:type]
options = record
options.delete :name
options.delete :type
request = AWS::Route53::DeleteRequest.new(name, type, options)
batch = AWS::Route53::ChangeBatch.new @hosted_zone[:id]
batch << request
batch.call
end
def users
p = Regexp.new(Regexp.quote('.' + @hosted_zone[:name]) + '$')
fetch_resource_record_sets.select {|r| r[:type] == RECORD_TYPE }.map {|r| r[:name].sub(p, '') }
end
private
def fetch_resource_record_sets
res = @r53.client.list_resource_record_sets hosted_zone_id: @hosted_zone[:id]
res[:resource_record_sets]
end
def fetch_hosted_zones
res = @r53.client.list_hosted_zones
res[:hosted_zones]
end
def validate_user(user)
raise if user.nil?
raise if user.empty?
raise if user.match(/\./)
end
end
commands = {}
commands['add'] = lambda do |users|
manager = Route53UserManager.new BASE_DOMAIN, RECORD_VALUE
users.each do |user|
manager.add user
end
end
commands['remove'] = lambda do |users|
manager = Route53UserManager.new BASE_DOMAIN, RECORD_VALUE
users.each do |user|
manager.remove user
end
end
commands['list'] = lambda do |_|
manager = Route53UserManager.new BASE_DOMAIN, RECORD_VALUE
puts manager.users
end
command = commands[ARGV.shift]
command.call ARGV
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment