├── Gemfile ├── Gemfile.lock ├── README.markdown └── slicedns2linode.rb /Gemfile: -------------------------------------------------------------------------------- 1 | source :rubygems 2 | 3 | gem 'activeresource', '2.3.9' 4 | gem 'linode', '0.7.5' 5 | gem 'httparty', '0.6.1' 6 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: http://rubygems.org/ 3 | specs: 4 | activeresource (2.3.9) 5 | activesupport (= 2.3.9) 6 | activesupport (2.3.9) 7 | crack (0.1.8) 8 | httparty (0.6.1) 9 | crack (= 0.1.8) 10 | linode (0.7.5) 11 | httparty 12 | httparty (>= 0.4.4) 13 | 14 | PLATFORMS 15 | ruby 16 | 17 | DEPENDENCIES 18 | activeresource (= 2.3.9) 19 | httparty (= 0.6.1) 20 | linode (= 0.7.5) 21 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | # Slicehost DNS to Linode Script 2 | 3 | 4 | # Installation 5 | 6 | Grab script from Github open it and replace your SLICEHOST\_API\_KEY, LINODE\_API\_KEY and EMAIL_ADDRESS 7 | 8 | And then run 9 | 10 | $ bundle install 11 | 12 | # Usage 13 | 14 | bundle exec ./slicedns2linode.rb domain1.com. [domain2.com.] 15 | 16 | There is only 1 required argument for the script. The name of your domain with the trailing period [.]. You can add additional domains to be transferred in a single run just separate them with a space 17 | 18 | # Requirements 19 | You need to have a working ruby and rubygems installation 20 | 21 | # Ubuntu Install 22 | $ [sudo] aptitude install ruby rubygems 23 | # Ubuntu Server might also need the ruby OpenSSL libraries installed. 24 | $ [sudo] aptitude install libopenssl-ruby 25 | # Fedora Install 26 | $ [sudo] yum install ruby rubygems 27 | 28 | You need to make sure you have bundler installed 29 | 30 | $ [sudo] gem install bundler 31 | 32 | # TODO 33 | Create GEM 34 | Create Test coverage -------------------------------------------------------------------------------- /slicedns2linode.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'rubygems' 3 | require 'active_resource' 4 | require 'logger' 5 | require 'linode' 6 | 7 | $LOG = Logger.new($stdout) 8 | 9 | def error(message) 10 | $LOG.fatal(message) 11 | exit 12 | end 13 | 14 | SLICEHOST_API_KEY = "SLICEHOST API KEY" 15 | LINODE_API_KEY = "LINODE API KEY" 16 | EMAIL_ADDRESS = "SOA Email address for Linode" #required for linode.com 17 | 18 | class Zone < ActiveResource::Base 19 | self.site = "https://#{SLICEHOST_API_KEY}@api.slicehost.com" 20 | def records 21 | Record.find(:all, :params => { :zone_id => self.id }) 22 | end 23 | 24 | def self.exists?(name) 25 | !Zone.find(:all, :params => { :origin => name}).empty? 26 | end 27 | 28 | def self.find_by_name(name) 29 | Zone.find(:first, :params => { :origin => name }) 30 | end 31 | 32 | def domain 33 | origin.sub(/\.$/,'') 34 | end 35 | end 36 | 37 | class Record < ActiveResource::Base 38 | self.site = "https://#{SLICEHOST_API_KEY}@api.slicehost.com" 39 | 40 | def kind 41 | record_type.downcase 42 | end 43 | 44 | [:a,:mx,:cname,:srv,:ns,:txt].each do |kind| 45 | define_method "#{kind}?" do 46 | self.kind == "#{kind}" 47 | end 48 | end 49 | 50 | # This is to cleanup slicehost data that ends with '.' 51 | def data 52 | attributes['data'].end_with?('.') && !self.ns? ? attributes['data'].sub(/\.$/,'') : attributes['data'] 53 | end 54 | end 55 | 56 | error "Usage: slice2linode.rb domain.com. [domain2.com.] ..." if ARGV.empty? || ARGV.detect { |name| !name.end_with?('.') } 57 | 58 | ARGV.each do |arg| 59 | # Slicehost requires . at the end of the domain name 60 | zone = Zone.find_by_name(arg) 61 | if zone.nil? then 62 | $LOG.warn "No valid zone named #{arg} found" 63 | next 64 | end 65 | 66 | # Initiate Linode gem 67 | l = Linode.new(:api_key => LINODE_API_KEY) 68 | error "#{arg} already exists at linode please delete" if l.domain.list.find {|domain| domain.domain == zone.domain } 69 | 70 | # create linode domain - set it to INACTIVE by default 71 | puts "Creating #{zone.domain} @ linode.com" 72 | domain = l.domain.create(:Domain => zone.domain, :Type => 'Master', :SOA_Email => EMAIL_ADDRESS, :TTL_sec => zone.ttl, :status => 0) 73 | 74 | records = zone.records 75 | 76 | # Delete NS records as Linode's api creates them by default when create a domain 77 | records.delete_if { |record| record.ns? } 78 | 79 | records.each do |record| 80 | begin 81 | case record.kind 82 | when 'srv' 83 | puts "Creating SRV record" 84 | srvce, protocol = record.name.split(/\./) 85 | weight, port, target = record.data.split(' ') 86 | l.domain.resource.create(:DomainID => domain.domainid, :Type => 'SRV', :Name => srvce, :Priority => record.aux, :Target => target, 87 | :Priority => record.aux, :Weight => weight, :Port => port, :Protocol => protocol.sub('_',''), :TTL_sec => record.ttl) 88 | when 'mx' 89 | puts "Creating MX record" 90 | l.domain.resource.create(:DomainID => domain.domainid, :Type => 'MX', :Target => record.data, :Priority => record.aux, :TTL_sec => record.ttl) 91 | when 'txt', 'cname', 'a' 92 | puts "Creating #{record.record_type} record" 93 | name = record.a? && record.name == zone.origin ? '' : record.name 94 | l.domain.resource.create(:DomainID => domain.domainid, :Type => record.record_type, :Name => name, :Target => record.data, :TTL_sec => record.ttl) 95 | end 96 | rescue RuntimeError 97 | $LOG.warn "Failed to import record #{name} of type #{record.record_type}, you will need to manually import this record" 98 | end 99 | end 100 | puts "Done importing #{zone.domain}" 101 | end --------------------------------------------------------------------------------