clouddns 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -9,10 +9,16 @@ options = {
9
9
  :force => false
10
10
  }
11
11
 
12
- OptionParser.new do |opts|
13
- opts.banner = "Usage: #{$0} [OPTIONS] [ACTION] FILES"
12
+ option_parser = OptionParser.new do |opts|
13
+ opts.banner = [
14
+ "Usage: #{$0} [OPTIONS] print FILES # Pretty print contents of FILES",
15
+ " #{$0} [OPTIONS] migrate FILES # Update DNS servers",
16
+ " #{$0} [OPTIONS] zonefile FILES # Print FILES as zone files",
17
+ "",
18
+ ""
19
+ ].join("\n")
14
20
 
15
- opts.on('-p', '--provider provider', "Override DNS provider (AWS, Zerigo, etc)") do |provider|
21
+ opts.on('-p', '--provider provider', "Override DNS provider (AWS, bluebox, dnsimple, dnsmadeeasy, linode, slicehost, zerigo)") do |provider|
16
22
  options[:fog][:provider] = provider
17
23
  end
18
24
 
@@ -29,13 +35,26 @@ OptionParser.new do |opts|
29
35
  puts opts
30
36
  exit
31
37
  end
32
- end.parse!
38
+ end
39
+
40
+ option_parser.parse!
33
41
 
34
42
  action = ARGV.slice!(0)
35
43
  files = ARGV
36
44
 
37
- raise "No action specified" unless action
38
- raise "No files specified" if files.empty?
45
+ if !action
46
+ error = "No action specified"
47
+ elsif files.empty?
48
+ error = "No files specified"
49
+ else
50
+ error = nil
51
+ end
52
+
53
+ if error
54
+ puts error
55
+ puts option_parser
56
+ exit 1
57
+ end
39
58
 
40
59
  action = Clouddns::Actions.by_name(action)
41
60
 
@@ -14,4 +14,7 @@ Gem::Specification.new do |gem|
14
14
  gem.name = "clouddns"
15
15
  gem.require_paths = ['lib']
16
16
  gem.version = Clouddns::VERSION
17
+
18
+ # 0.9.0 changed Record#ip to Record#value
19
+ gem.add_dependency('fog', '>= 0.9.0')
17
20
  end
@@ -1,11 +1,10 @@
1
- require "fog"
2
-
3
1
  require "clouddns/actions"
4
2
  require "clouddns/dsl"
5
3
  require "clouddns/record"
4
+ require "clouddns/utils"
6
5
  require "clouddns/version"
7
6
  require "clouddns/zone"
8
7
  require "clouddns/zone_migration"
9
8
 
10
- module Clouddns
11
- end
9
+ require 'clouddns/railtie' if defined?(Rails)
10
+
@@ -2,6 +2,7 @@
2
2
  require 'clouddns/actions/generic_action'
3
3
  require 'clouddns/actions/print'
4
4
  require 'clouddns/actions/migrate'
5
+ require 'clouddns/actions/zonefile'
5
6
 
6
7
  module Clouddns
7
8
  module Actions
@@ -9,6 +10,7 @@ module Clouddns
9
10
  case name.downcase
10
11
  when 'print' then Print
11
12
  when 'migrate' then Migrate
13
+ when 'zonefile' then Zonefile
12
14
  else
13
15
  raise "Unknown action: #{name}"
14
16
  end
@@ -1,11 +1,10 @@
1
- require 'clouddns/actions/print_record'
2
1
 
3
2
  module Clouddns
4
3
  module Actions
5
4
  class Migrate < GenericAction
6
- include PrintRecord
7
-
8
5
  def run
6
+ require 'fog'
7
+
9
8
  @fog = Fog::DNS.new(@options[:fog])
10
9
  @fog_zone = @fog.zones.find { |z| z.domain == @zone.name }
11
10
 
@@ -52,15 +51,15 @@ module Clouddns
52
51
  end
53
52
 
54
53
  def print_changes
55
- namelength = @migration.changes.map do |(action, record)|
56
- record.name.length
54
+ namelength = @migration.changes.map do |change|
55
+ change.record.name.length
57
56
  end.max
58
57
 
59
58
  puts
60
59
  puts "Changes:"
61
60
 
62
- @migration.changes.each do |(action, record)|
63
- print_record record, namelength, action
61
+ @migration.changes.each do |change|
62
+ puts change.to_s(namelength)
64
63
  end
65
64
  end
66
65
 
@@ -1,10 +1,7 @@
1
- require 'clouddns/actions/print_record'
2
1
 
3
2
  module Clouddns
4
3
  module Actions
5
4
  class Print < GenericAction
6
- include PrintRecord
7
-
8
5
  def run
9
6
  print_all
10
7
  end
@@ -14,7 +11,7 @@ module Clouddns
14
11
  puts "Zone '#{@zone.name}'"
15
12
  namelength = @zone.records.map{ |x| x.name.length }.max
16
13
  @zone.records.each do |record|
17
- print_record record, namelength
14
+ puts Utils::format_record record, :namelength => namelength
18
15
  end
19
16
  end
20
17
  end
@@ -0,0 +1,29 @@
1
+
2
+ module Clouddns
3
+ module Actions
4
+ class Zonefile < GenericAction
5
+ def run
6
+ print_all
7
+ end
8
+
9
+ protected
10
+ def print_all
11
+ puts "$ORIGIN #{@zone.name}"
12
+
13
+ namelength = @zone.records.map{ |x| x.name.length }.max
14
+ @zone.records.each do |record|
15
+ record.value.each_with_index do |value, i|
16
+ print "%-18s " % record.name
17
+ print "%5i " % record.ttl
18
+ print "IN "
19
+ print "%-5s " % record.type
20
+ print "%s " % value
21
+ puts
22
+ end
23
+ end
24
+ puts
25
+ end
26
+ end
27
+ end
28
+ end
29
+
@@ -3,9 +3,6 @@ module Clouddns
3
3
  attr_reader :zones
4
4
  attr_reader :fog_options
5
5
 
6
- # This need not be too strict. Only exists to help catch typos.
7
- DNS_REGEX = /\A.*\..*\.\z/
8
-
9
6
  def initialize
10
7
  @zones = []
11
8
  @zone = nil
@@ -32,7 +29,8 @@ module Clouddns
32
29
  end
33
30
 
34
31
  def add_record type, name, value, options={}
35
- name = domainname(name)
32
+ name = Utils::parse_domain(name)
33
+ options = @defaults.merge(options)
36
34
 
37
35
  value = "\"#{value}\"" if type == 'TXT'
38
36
 
@@ -45,7 +43,7 @@ module Clouddns
45
43
  def zone name
46
44
  raise "zones cannot be nested" if @zone
47
45
 
48
- @zone = Zone.new(domainname(name))
46
+ @zone = Zone.new(Utils::parse_domain(name))
49
47
  @zones << @zone
50
48
  yield
51
49
  @zone = nil
@@ -66,15 +64,6 @@ module Clouddns
66
64
  def provider name, options={}
67
65
  @fog_options = options.merge({:provider => name})
68
66
  end
69
-
70
- private
71
- def domainname name
72
- if name.end_with? '.'
73
- name
74
- else
75
- "#{name}."
76
- end
77
- end
78
67
  end
79
68
  end
80
69
 
@@ -0,0 +1,9 @@
1
+
2
+ module Clouddns
3
+ class Railtie < ::Rails::Railtie
4
+ rake_tasks do
5
+ load 'clouddns/tasks.rb'
6
+ end
7
+ end
8
+ end
9
+
@@ -0,0 +1,33 @@
1
+
2
+ require 'clouddns'
3
+ require 'pathname'
4
+
5
+ namespace :dns do
6
+ desc "Print DNS entries from config/dns/*.rb"
7
+ task :print do
8
+ run_action Clouddns::Actions::Print
9
+ end
10
+ desc "Update DNS service with config/dns/*.rb"
11
+ task :migrate do
12
+ run_action Clouddns::Actions::Migrate
13
+ end
14
+ desc "Print config/dns/*.rb as zonefiles"
15
+ task :zonefile do
16
+ run_action Clouddns::Actions::Zonefile
17
+ end
18
+ def run_action action
19
+ root_path = defined?(Rails) ? Rails.root : Pathname.new('.')
20
+ dns_path = root_path.join('config', 'dns')
21
+ files = Dir[dns_path.join('**','*.rb')]
22
+ if files.empty?
23
+ raise "No DNS configuration. Please create config/dns/yourdomain.rb"
24
+ end
25
+ files.each do |file|
26
+ dsl = Clouddns::DSL.parse_file(file)
27
+ dsl.zones.each do |zone|
28
+ action.run(zone)
29
+ end
30
+ end
31
+ end
32
+ end
33
+
@@ -0,0 +1,31 @@
1
+ module Clouddns
2
+ module Utils
3
+ extend self
4
+
5
+ def parse_domain name
6
+ if name =~ /\A(.*?\..*?)\.?\z/
7
+ "#{$1}."
8
+ else
9
+ raise "Invalid domain: '#{name}'"
10
+ end
11
+ end
12
+
13
+ def format_record record, options={}
14
+ namelength = options[:namelength] || 20
15
+ prefix = options[:prefix] || ''
16
+
17
+ output = []
18
+
19
+ record.value.each_with_index do |value, i|
20
+ if i.zero?
21
+ args = [prefix, record.type, record.ttl, record.name, value]
22
+ else
23
+ args = [prefix, '', '', '', value]
24
+ end
25
+ output << "%s%5s %5s %#{namelength}s %s" % args
26
+ end
27
+
28
+ output.join("\n")
29
+ end
30
+ end
31
+ end
@@ -1,3 +1,3 @@
1
1
  module Clouddns
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -1,5 +1,28 @@
1
1
  module Clouddns
2
2
  class ZoneMigration
3
+ module Change
4
+ class None < Struct.new(:record)
5
+ def perform! fog_zone
6
+ end
7
+ def print_prefix; ' '; end
8
+ def to_s length=30
9
+ Utils::format_record record, :prefix => print_prefix, :namelength => length
10
+ end
11
+ end
12
+ class Create < None
13
+ def perform! fog_zone
14
+ fog_zone.records.create(:type => record.type, :name => record.name, :value => record.value, :ttl => record.ttl)
15
+ end
16
+ def print_prefix; '+'; end
17
+ end
18
+ class Remove < None
19
+ def perform! fog_zone
20
+ record.destroy
21
+ end
22
+ def print_prefix; '-'; end
23
+ end
24
+ end
25
+
3
26
  def initialize zone, fog_zone
4
27
  @zone = zone
5
28
  @fog_zone = fog_zone
@@ -12,35 +35,31 @@ module Clouddns
12
35
  @zone.records.each do |record|
13
36
  if (fog_record = fog_records.delete([record.name, record.type]))
14
37
  if records_equal?(record, fog_record)
15
- @changes << [' ', record]
38
+ @changes << Change::None.new(record)
16
39
  else
17
- @changes << ['-', fog_record]
18
- @changes << ['+', record]
40
+ @changes << Change::Remove.new(fog_record)
41
+ @changes << Change::Create.new(record)
19
42
  end
20
43
  else
21
- @changes << ['+', record]
44
+ @changes << Change::Create.new(record)
22
45
  end
23
46
  end
24
47
 
25
48
  fog_records.each do |name, record|
26
- @changes << ['-', record]
49
+ @changes << Change::Remove.new(record)
27
50
  end
28
51
  @changes
29
52
  end
30
53
 
31
54
  def perform!
32
- changes.each do |(action, record)|
33
- if action == '+'
34
- @fog_zone.records.create(:type => record.type, :name => record.name, :ip => record.value, :ttl => record.ttl)
35
- elsif action == '-'
36
- record.destroy
37
- end
55
+ changes.each do |change|
56
+ change.perform! @fog_zone
38
57
  end
39
58
  end
40
59
 
41
60
  def completed?
42
- changes.all? do |(action, record)|
43
- action == ' '
61
+ changes.all? do |change|
62
+ change.class == Change::None
44
63
  end
45
64
  end
46
65
 
@@ -53,9 +72,8 @@ module Clouddns
53
72
  # AWS replaces * with \052
54
73
  record.name == fog_record_name(fog_record) &&
55
74
  record.type == fog_record.type &&
56
- record.value == fog_record.ip &&
75
+ record.value == fog_record.value &&
57
76
  record.ttl.to_i == fog_record.ttl.to_i
58
77
  end
59
-
60
78
  end
61
79
  end
@@ -20,14 +20,20 @@ class DslTest < Test::Unit::TestCase
20
20
  assert_equal ['1.2.3.4'], record.value
21
21
  end
22
22
  def test_trailing_dot_is_implied
23
- dsl = Clouddns::DSL.parse_string <<-EOL
24
- zone "example.com" do
25
- A 'www.example.com', '1.2.3.4'
23
+ for zonename in %w{example.com example.com.}
24
+ dsl = Clouddns::DSL.parse_string <<-EOL
25
+ zone "#{zonename}" do
26
+ A 'test1.example.com', '1.2.3.4'
27
+ A 'test2.example.com.', '1.2.3.4'
26
28
  end
27
- EOL
29
+ EOL
30
+
31
+ assert_equal 'example.com.', dsl.zones.first.name
28
32
 
29
- assert_equal 'example.com.', dsl.zones.first.name
30
- assert_equal 'www.example.com.', dsl.zones.first.records.first.name
33
+ records = dsl.zones.first.records
34
+ assert_equal 'test1.example.com.', records[0].name
35
+ assert_equal 'test2.example.com.', records[1].name
36
+ end
31
37
  end
32
38
  end
33
39
 
metadata CHANGED
@@ -1,33 +1,35 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: clouddns
3
- version: !ruby/object:Gem::Version
4
- hash: 27
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 0
9
- - 2
10
- version: 0.0.2
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - John Hawthorn
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2011-07-14 00:00:00 Z
19
- dependencies: []
20
-
12
+ date: 2011-11-07 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: fog
16
+ requirement: &18817680 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 0.9.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *18817680
21
25
  description: A DSL for managing DNS through cloud services
22
- email:
26
+ email:
23
27
  - john.hawthorn@gmail.com
24
- executables:
28
+ executables:
25
29
  - clouddns
26
30
  extensions: []
27
-
28
31
  extra_rdoc_files: []
29
-
30
- files:
32
+ files:
31
33
  - .gitignore
32
34
  - Gemfile
33
35
  - README.md
@@ -39,9 +41,12 @@ files:
39
41
  - lib/clouddns/actions/generic_action.rb
40
42
  - lib/clouddns/actions/migrate.rb
41
43
  - lib/clouddns/actions/print.rb
42
- - lib/clouddns/actions/print_record.rb
44
+ - lib/clouddns/actions/zonefile.rb
43
45
  - lib/clouddns/dsl.rb
46
+ - lib/clouddns/railtie.rb
44
47
  - lib/clouddns/record.rb
48
+ - lib/clouddns/tasks.rb
49
+ - lib/clouddns/utils.rb
45
50
  - lib/clouddns/version.rb
46
51
  - lib/clouddns/zone.rb
47
52
  - lib/clouddns/zone_migration.rb
@@ -49,37 +54,30 @@ files:
49
54
  - test/test_helper.rb
50
55
  homepage: https://github.com/jhawthorn/clouddns
51
56
  licenses: []
52
-
53
57
  post_install_message:
54
58
  rdoc_options: []
55
-
56
- require_paths:
59
+ require_paths:
57
60
  - lib
58
- required_ruby_version: !ruby/object:Gem::Requirement
61
+ required_ruby_version: !ruby/object:Gem::Requirement
59
62
  none: false
60
- requirements:
61
- - - ">="
62
- - !ruby/object:Gem::Version
63
- hash: 3
64
- segments:
65
- - 0
66
- version: "0"
67
- required_rubygems_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
68
  none: false
69
- requirements:
70
- - - ">="
71
- - !ruby/object:Gem::Version
72
- hash: 3
73
- segments:
74
- - 0
75
- version: "0"
69
+ requirements:
70
+ - - ! '>='
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
76
73
  requirements: []
77
-
78
74
  rubyforge_project:
79
- rubygems_version: 1.8.5
75
+ rubygems_version: 1.8.10
80
76
  signing_key:
81
77
  specification_version: 3
82
- summary: A DSL and tools for managing DNS through any of the services supported by fog. Currently, this is Amazon Route 53, bluebox, DNSimple, DNS Made Easy, Linode DNS, Slicehost DNS and Zerigo DNS
83
- test_files:
78
+ summary: A DSL and tools for managing DNS through any of the services supported by
79
+ fog. Currently, this is Amazon Route 53, bluebox, DNSimple, DNS Made Easy, Linode
80
+ DNS, Slicehost DNS and Zerigo DNS
81
+ test_files:
84
82
  - test/dsl_test.rb
85
83
  - test/test_helper.rb
@@ -1,19 +0,0 @@
1
- module Clouddns
2
- module Actions
3
- module PrintRecord
4
- protected
5
- def print_record record, namelength, prefix=''
6
- values = record.respond_to?(:value) ? record.value : record.ip
7
- values.each_with_index do |value, i|
8
- if i.zero?
9
- args = [prefix, record.type, record.ttl, record.name, value]
10
- else
11
- args = [prefix, '', '', '', value]
12
- end
13
- puts "%s%5s %5s %#{namelength}s %s" % args
14
- end
15
- end
16
- end
17
- end
18
- end
19
-