awsborn 0.8.1 → 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.mdown CHANGED
@@ -113,6 +113,9 @@ Mandatory keys for load_balancer:
113
113
 
114
114
  Optional keys for load_balancer:
115
115
 
116
+ * `:dns_alias` -- a domain name to be tied to the load balancer in Route 53.
117
+ May be a simple name (`www`) in which case the cluster domain will be added,
118
+ or a full domain name.
116
119
  * `:only` -- a list of server names to which the load balancer is
117
120
  restricted.
118
121
  * `:except` -- a list of servers that the load balancer should ignore.
data/Rakefile CHANGED
@@ -10,7 +10,7 @@ begin
10
10
  gem.email = "david@icehouse.se"
11
11
  gem.homepage = "http://github.com/icehouse/awsborn"
12
12
  gem.authors = ["David Vrensk", "Jean-Louis Giordano"]
13
- gem.add_dependency "right_aws", ">= 2.1.0"
13
+ gem.add_dependency "icehouse-right_aws", ">= 2.2.0"
14
14
  gem.add_dependency "json_pure", ">= 1.2.3"
15
15
  gem.add_dependency "rake"
16
16
  gem.add_development_dependency "rspec", ">= 2.6.0"
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.8.1
1
+ 0.8.2
data/awsborn.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{awsborn}
8
- s.version = "0.8.1"
8
+ s.version = "0.8.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["David Vrensk", "Jean-Louis Giordano"]
12
- s.date = %q{2011-08-16}
12
+ s.date = %q{2011-08-23}
13
13
  s.description = %q{Awsborn lets you define and launch a server cluster on Amazon EC2.}
14
14
  s.email = %q{david@icehouse.se}
15
15
  s.extra_rdoc_files = [
@@ -37,12 +37,15 @@ Gem::Specification.new do |s|
37
37
  "lib/awsborn/known_hosts_updater.rb",
38
38
  "lib/awsborn/load_balancer.rb",
39
39
  "lib/awsborn/rake.rb",
40
+ "lib/awsborn/route53.rb",
40
41
  "lib/awsborn/server.rb",
41
42
  "lib/awsborn/server_cluster.rb",
42
43
  "spec/aws_constants_spec.rb",
43
44
  "spec/ec2_spec.rb",
44
45
  "spec/elb_spec.rb",
45
46
  "spec/load_balancer_spec.rb",
47
+ "spec/route53_spec.rb",
48
+ "spec/server_cluster_spec.rb",
46
49
  "spec/server_spec.rb",
47
50
  "spec/spec.opts",
48
51
  "spec/spec_helper.rb"
@@ -57,20 +60,20 @@ Gem::Specification.new do |s|
57
60
  s.specification_version = 3
58
61
 
59
62
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
60
- s.add_runtime_dependency(%q<right_aws>, [">= 2.1.0"])
63
+ s.add_runtime_dependency(%q<icehouse-right_aws>, [">= 2.2.0"])
61
64
  s.add_runtime_dependency(%q<json_pure>, [">= 1.2.3"])
62
65
  s.add_runtime_dependency(%q<rake>, [">= 0"])
63
66
  s.add_development_dependency(%q<rspec>, [">= 2.6.0"])
64
67
  s.add_development_dependency(%q<webmock>, [">= 1.3.0"])
65
68
  else
66
- s.add_dependency(%q<right_aws>, [">= 2.1.0"])
69
+ s.add_dependency(%q<icehouse-right_aws>, [">= 2.2.0"])
67
70
  s.add_dependency(%q<json_pure>, [">= 1.2.3"])
68
71
  s.add_dependency(%q<rake>, [">= 0"])
69
72
  s.add_dependency(%q<rspec>, [">= 2.6.0"])
70
73
  s.add_dependency(%q<webmock>, [">= 1.3.0"])
71
74
  end
72
75
  else
73
- s.add_dependency(%q<right_aws>, [">= 2.1.0"])
76
+ s.add_dependency(%q<icehouse-right_aws>, [">= 2.2.0"])
74
77
  s.add_dependency(%q<json_pure>, [">= 1.2.3"])
75
78
  s.add_dependency(%q<rake>, [">= 0"])
76
79
  s.add_dependency(%q<rspec>, [">= 2.6.0"])
data/lib/awsborn/elb.rb CHANGED
@@ -50,6 +50,10 @@ module Awsborn
50
50
  describe_load_balancer(balancer_name)[:availability_zones]
51
51
  end
52
52
 
53
+ def canonical_hosted_zone_name_id (balancer_name)
54
+ describe_load_balancer(balancer_name)[:canonical_hosted_zone_name_id]
55
+ end
56
+
53
57
  def create_load_balancer (balancer_name)
54
58
  logger.debug "Creating load balancer #{balancer_name}"
55
59
  connection.create_load_balancer(balancer_name, [@region+'a'], [])
@@ -2,7 +2,7 @@ module Awsborn
2
2
  class LoadBalancer
3
3
 
4
4
  include Awsborn::AwsConstants
5
- attr_accessor :name, :only, :except, :region, :listeners, :sticky_cookies, :health_check_config
5
+ attr_accessor :name, :only, :except, :region, :listeners, :sticky_cookies, :health_check_config, :dns_alias
6
6
 
7
7
  DEFAULT_LISTENERS = [ { :protocol => :http, :load_balancer_port => 80, :instance_port => 80} ]
8
8
  DEFAULT_HEALTH_CONFIG = {
@@ -12,6 +12,7 @@ module Awsborn
12
12
  :timeout => 5,
13
13
  :interval => 30
14
14
  }
15
+
15
16
  def initialize (name, options={})
16
17
  @name = name
17
18
  @only = options[:only] || []
@@ -20,13 +21,14 @@ module Awsborn
20
21
  @listeners = options[:listeners] || DEFAULT_LISTENERS
21
22
  @sticky_cookies = options[:sticky_cookies] || []
22
23
  @health_check_config = DEFAULT_HEALTH_CONFIG.merge(options[:health_check] || {})
24
+ @dns_alias = options[:dns_alias]
23
25
  end
24
26
 
25
27
  def elb
26
28
  @elb ||= Elb.new(@region)
27
29
  end
28
30
 
29
- def dns_name
31
+ def aws_dns_name
30
32
  elb.dns_name(@name)
31
33
  end
32
34
 
@@ -34,11 +36,14 @@ module Awsborn
34
36
  elb.instances(@name)
35
37
  end
36
38
 
39
+ def canonical_hosted_zone_name_id
40
+ elb.canonical_hosted_zone_name_id(@name)
41
+ end
42
+
37
43
  def instances= (new_instances)
38
44
  previous_instances = self.instances
39
45
  register_instances(new_instances - previous_instances)
40
46
  deregister_instances(previous_instances - new_instances)
41
- self.instances
42
47
  end
43
48
 
44
49
  def zones
@@ -49,7 +54,6 @@ module Awsborn
49
54
  previous_zones = self.zones
50
55
  enable_zones(new_zones - previous_zones)
51
56
  disable_zones(previous_zones - new_zones)
52
- self.zones
53
57
  end
54
58
 
55
59
  def description
@@ -94,27 +98,58 @@ module Awsborn
94
98
  elb.configure_health_check(@name, @health_check_config)
95
99
  end
96
100
 
97
- def update_with (new_servers)
101
+ def launch_or_update (running_servers)
98
102
  launch unless running?
99
103
 
100
- servers_to_be_balanced = new_servers
101
- servers_to_be_balanced =
102
- servers_to_be_balanced.select{|s| @only.include?(s.name)} unless @only.empty?
103
- servers_to_be_balanced =
104
- servers_to_be_balanced.reject{|s| @except.include?(s.name)} unless @except.empty?
104
+ set_instances_to_selected(running_servers)
105
+ update_settings
105
106
 
106
- self.instances = servers_to_be_balanced.map{|s| s.instance_id }
107
- self.zones = servers_to_be_balanced.map{|s| symbol_to_aws_zone(s.zone) }.uniq
107
+ configure_dns if @dns_alias
108
+ end
108
109
 
109
- update_listeners
110
- update_sticky_cookies
111
- update_health_config
110
+ def configure_dns
111
+ route53.create_zone @dns_alias unless route53.zone_exists?(@dns_alias)
112
+ case route53.alias_target(@dns_alias)
113
+ when aws_dns_name
114
+ # It is already good
115
+ when nil
116
+ route53.add_alias_record(:alias => @dns_alias, :lb_fqdn => aws_dns_name, :lb_zone => canonical_hosted_zone_name_id)
117
+ else
118
+ route53.remove_alias_records(@dns_alias)
119
+ route53.add_alias_record(:alias => @dns_alias, :lb_fqdn => aws_dns_name, :lb_zone => canonical_hosted_zone_name_id)
120
+ end
121
+ end
112
122
 
113
- self.description
123
+ def route53
124
+ @route53 ||= Route53.new
125
+ end
126
+
127
+ def dns_info
128
+ if dns_alias
129
+ route53.zone_for(dns_alias)
130
+ end
114
131
  end
115
132
 
116
133
  protected
117
134
 
135
+ def set_instances_to_selected (running_servers)
136
+ servers_to_be_balanced = select_servers(running_servers)
137
+ self.instances = servers_to_be_balanced.map {|s| s.instance_id }
138
+ self.zones = servers_to_be_balanced.map {|s| symbol_to_aws_zone(s.zone) }.uniq
139
+ end
140
+
141
+ def select_servers (servers)
142
+ servers = servers.select {|s| @only.include?(s.name)} unless @only.empty?
143
+ servers = servers.reject {|s| @except.include?(s.name)} unless @except.empty?
144
+ servers
145
+ end
146
+
147
+ def update_settings
148
+ update_listeners
149
+ update_sticky_cookies
150
+ update_health_config
151
+ end
152
+
118
153
  def set_disabled_cookie_policy(ports)
119
154
  # Do nothing
120
155
  end
data/lib/awsborn/rake.rb CHANGED
@@ -26,7 +26,19 @@ module Awsborn
26
26
 
27
27
  desc "Start all servers (or host=name1,name2) but don't run chef."
28
28
  task :start do |t,args|
29
- cluster(args).launch get_hosts(args)
29
+ c = cluster(args)
30
+ c.launch get_hosts(args)
31
+ info = c.load_balancer_info
32
+ print_required_dns_setting(info) if info
33
+ end
34
+
35
+ def print_required_dns_setting (info)
36
+ puts "Make sure those NS records are present in your DNS settings:"
37
+ puts(info.map do |dns_entry|
38
+ dns_entry[:name_servers].map do |ns|
39
+ "#{dns_entry[:name]}\tIN\tNS\t#{ns}."
40
+ end
41
+ end.join("\n"))
30
42
  end
31
43
 
32
44
  desc "Update .ssh/known_hosts with data from all servers (or host=host1,host2)"
@@ -132,4 +144,4 @@ EOH
132
144
 
133
145
  end
134
146
  end
135
- end
147
+ end
@@ -0,0 +1,70 @@
1
+ module Awsborn
2
+ class Route53
3
+ extend Forwardable
4
+ def_delegators :Awsborn, :logger
5
+ include Awsborn::AwsConstants
6
+ attr_reader :connection
7
+
8
+ def connection
9
+ unless @connection
10
+ @connection = RightAws::Route53Interface.new(Awsborn.access_key_id, Awsborn.secret_access_key, :logger => Awsborn.logger)
11
+ end
12
+ @connection
13
+ end
14
+
15
+ def initialize (zone = nil)
16
+ end
17
+
18
+ def zone_exists? (name)
19
+ !! zone_overview_for(name)
20
+ end
21
+
22
+ def zone_for (name)
23
+ zone_id = zone_id_for(name)
24
+ connection.get_hosted_zone(zone_id) if zone_id
25
+ end
26
+
27
+ def zone_id_for (name)
28
+ overview = zone_overview_for(name)
29
+ overview[:aws_id] if overview
30
+ end
31
+
32
+ def create_zone (name)
33
+ connection.create_hosted_zone({:name => with_final_dot(name), :config => {:comment => ''}})
34
+ end
35
+
36
+ def alias_target (name)
37
+ name = with_final_dot(name)
38
+ zone = zone_id_for(name)
39
+ alias_record = connection.list_resource_record_sets(zone).detect { |rr| rr[:name] == name && rr[:alias_target] }
40
+ alias_record && alias_record[:alias_target]
41
+ end
42
+
43
+ def add_alias_record (options)
44
+ name = with_final_dot(options[:alias])
45
+ zone = zone_id_for(name)
46
+ alias_target = { :hosted_zone_id => options[:lb_zone], :dns_name => options[:lb_fqdn] }
47
+ alias_record = { :name => options[:alias], :type => 'A', :alias_target => alias_target }
48
+ connection.create_resource_record_sets(zone, [alias_record])
49
+ end
50
+
51
+ def remove_alias_records (name)
52
+ name = with_final_dot(name)
53
+ zone = zone_id_for(name)
54
+ alias_records = connection.list_resource_record_sets(zone).select { |rr| rr[:name] == name && rr[:alias_target] }
55
+ connection.delete_resource_record_sets(zone, alias_records)
56
+ end
57
+
58
+ private
59
+
60
+ def zone_overview_for (name)
61
+ name = with_final_dot(name)
62
+ zones = connection.list_hosted_zones
63
+ zone = zones.detect { |zone| zone[:name] == name }
64
+ end
65
+
66
+ def with_final_dot (name)
67
+ name =~ /\.$/ ? name : "#{name}."
68
+ end
69
+ end
70
+ end
@@ -2,7 +2,7 @@ module Awsborn
2
2
  class ServerCluster
3
3
  include Enumerable
4
4
 
5
- attr_accessor :name
5
+ attr_accessor :name, :load_balancers
6
6
 
7
7
  def self.build (klass, name, &block)
8
8
  cluster = new(klass, name)
@@ -44,6 +44,7 @@ module Awsborn
44
44
  end
45
45
 
46
46
  def load_balancer (name, options={})
47
+ options = add_domain_to_dns_alias(options)
47
48
  @load_balancers << Awsborn::LoadBalancer.new(name, options)
48
49
  end
49
50
 
@@ -73,10 +74,17 @@ module Awsborn
73
74
 
74
75
  def update_load_balancing(running)
75
76
  @load_balancers.each do |lb|
76
- lb.update_with(running).inspect
77
+ lb.launch_or_update(running)
77
78
  end
78
79
  end
79
80
 
81
+ def load_balancer_info
82
+ info = load_balancers.map do |lb|
83
+ lb.dns_info
84
+ end.compact
85
+ info.empty? ? nil : info
86
+ end
87
+
80
88
  def generate_key_pair (instances)
81
89
  @key_pair = instances.first.ec2.generate_key_pair
82
90
  end
@@ -96,9 +104,15 @@ module Awsborn
96
104
  protected
97
105
 
98
106
  def add_domain_to_ip (hash)
99
- if @domain && hash.has_key?(:ip) && ! hash[:ip].include?('.')
100
- ip = [hash[:ip], @domain].join('.')
101
- hash.merge(:ip => ip)
107
+ add_domain_to_key(:ip, hash)
108
+ end
109
+ def add_domain_to_dns_alias (hash)
110
+ add_domain_to_key(:dns_alias, hash)
111
+ end
112
+ def add_domain_to_key (key, hash)
113
+ if @domain && hash.has_key?(key) && ! hash[key].include?('.')
114
+ expanded = [hash[key], @domain].join('.')
115
+ hash.merge(key => expanded)
102
116
  else
103
117
  hash
104
118
  end
data/spec/elb_spec.rb CHANGED
@@ -74,6 +74,13 @@ describe Awsborn::Elb do
74
74
  end
75
75
  end
76
76
 
77
+ describe "canonical_hosted_zone_name_id" do
78
+ it "extracts zone id from description" do
79
+ @mock_interface.should_receive(:describe_load_balancers).with('some-name').and_return([{:canonical_hosted_zone_name_id => 'Z000'}])
80
+ @elb.canonical_hosted_zone_name_id('some-name').should == 'Z000'
81
+ end
82
+ end
83
+
77
84
  describe "create_load_balancer" do
78
85
  it "forwards to ElbInterface with a temporary zone and no listeners" do
79
86
  @mock_interface.should_receive(:create_load_balancer).with('some-name', ['eu-west-1a'], [])
@@ -12,7 +12,17 @@ describe Awsborn::LoadBalancer do
12
12
  :enable_zones => true,
13
13
  :set_load_balancer_listeners => true,
14
14
  :describe_load_balancer => "description",
15
- :configure_health_check => true)
15
+ :dns_name => 'asdf',
16
+ :configure_health_check => true)
17
+ Awsborn::Elb.stub!(:new).and_return(@mocked_elb)
18
+
19
+ @mocked_route53 = mock(:route53,
20
+ :zone_exists? => true,
21
+ :add_alias_record => true,
22
+ :alias_target => 'some-name-0001.lb.amz.com'
23
+ )
24
+ Awsborn::Route53.stub!(:new).and_return(@mocked_route53)
25
+
16
26
  @listener_fixture = [ { :protocol => :tcp, :load_balancer_port => 123, :instance_port => 123} ]
17
27
  @cookies_fixture = [ { :ports => [123], :policy => :disabled } ]
18
28
  @health_check_fixture = {
@@ -22,8 +32,8 @@ describe Awsborn::LoadBalancer do
22
32
  :timeout => 6,
23
33
  :interval => 31
24
34
  }
25
- Awsborn::Elb.stub!(:new).and_return(@mocked_elb)
26
35
  end
36
+
27
37
  describe "initialize" do
28
38
  it "requires a valid region option" do
29
39
  expect { Awsborn::LoadBalancer.new('some-name') }.to raise_error
@@ -33,7 +43,8 @@ describe Awsborn::LoadBalancer do
33
43
  subject do
34
44
  @balancer = Awsborn::LoadBalancer.new(
35
45
  'some-name',
36
- :region => :eu_west_1a,
46
+ :dns_alias => 'www.example.net',
47
+ :region => :eu_west_1,
37
48
  :only => [:server1, :server2],
38
49
  :except => [:server2],
39
50
  :listeners => @listener_fixture,
@@ -42,6 +53,7 @@ describe Awsborn::LoadBalancer do
42
53
  )
43
54
  end
44
55
  its(:name) { should == 'some-name' }
56
+ its(:dns_alias) { should == 'www.example.net' }
45
57
  its(:region) { should == 'eu-west-1' }
46
58
  its(:only) { should == [:server1, :server2] }
47
59
  its(:except) { should == [:server2] }
@@ -76,17 +88,16 @@ describe Awsborn::LoadBalancer do
76
88
  end
77
89
  end
78
90
 
79
- describe "dns_name" do
91
+ describe "aws_dns_name" do
80
92
  it "delegates to elb" do
81
93
  @mocked_elb.should_receive(:dns_name).with('some-name').and_return('dns-name')
82
94
  @balancer = Awsborn::LoadBalancer.new(
83
95
  'some-name',
84
96
  :region => :eu_west_1
85
- ).dns_name.should == 'dns-name'
97
+ ).aws_dns_name.should == 'dns-name'
86
98
  end
87
99
  end
88
100
 
89
-
90
101
  describe "instances" do
91
102
  it "delegates to elb" do
92
103
  @mocked_elb.should_receive(:instances).with('some-name').and_return('instances')
@@ -275,7 +286,7 @@ describe Awsborn::LoadBalancer do
275
286
  end
276
287
  end
277
288
 
278
- describe "update_with" do
289
+ describe "launch_or_update" do
279
290
  before do
280
291
  @balancer = Awsborn::LoadBalancer.new(
281
292
  'some-name',
@@ -291,12 +302,12 @@ describe Awsborn::LoadBalancer do
291
302
  it "launches the load balancer if not running" do
292
303
  @mocked_elb.should_receive(:running?).with('some-name').and_return(false)
293
304
  @mocked_elb.should_receive(:create_load_balancer).with('some-name').and_return(nil)
294
- @balancer.update_with(@new_servers)
305
+ @balancer.launch_or_update(@new_servers)
295
306
  end
296
307
  it "does not launch the load balancer if running" do
297
308
  @mocked_elb.should_receive(:running?).with('some-name').and_return(true)
298
309
  @mocked_elb.should_not_receive(:create_load_balancer)
299
- @balancer.update_with(@new_servers)
310
+ @balancer.launch_or_update(@new_servers)
300
311
  end
301
312
  it "sets instances and new zones and updates listeners, sticky cookies and health config" do
302
313
  @balancer.should_receive(:instances=).with(['i-00000001', 'i-00000002'])
@@ -304,8 +315,7 @@ describe Awsborn::LoadBalancer do
304
315
  @balancer.should_receive(:update_listeners)
305
316
  @balancer.should_receive(:update_sticky_cookies)
306
317
  @balancer.should_receive(:update_health_config)
307
- @balancer.should_receive(:description).and_return('description')
308
- @balancer.update_with(@new_servers).should == 'description'
318
+ @balancer.launch_or_update(@new_servers)
309
319
  end
310
320
  it "takes into account the :only option" do
311
321
  @balancer.only = [:server1]
@@ -315,8 +325,7 @@ describe Awsborn::LoadBalancer do
315
325
  @balancer.should_receive(:update_listeners)
316
326
  @balancer.should_receive(:update_sticky_cookies)
317
327
  @balancer.should_receive(:update_health_config)
318
- @balancer.should_receive(:description).and_return('description')
319
- @balancer.update_with(@new_servers).should == 'description'
328
+ @balancer.launch_or_update(@new_servers)
320
329
  end
321
330
  it "takes into account the :except option" do
322
331
  @balancer.except = [:server1]
@@ -327,9 +336,68 @@ describe Awsborn::LoadBalancer do
327
336
  @balancer.should_receive(:update_sticky_cookies)
328
337
  @balancer.should_receive(:update_health_config)
329
338
  @balancer.should_receive(:description).and_return('description')
330
- @balancer.update_with(@new_servers).should == 'description'
339
+ @balancer.launch_or_update(@new_servers)
340
+ @balancer.description.should == 'description'
341
+ end
342
+ it "configures dns" do
343
+ @balancer.dns_alias = 'www.example.net'
344
+ @balancer.should_receive(:configure_dns)
345
+ @balancer.launch_or_update(@new_servers)
331
346
  end
332
347
  end
333
348
 
334
- end
349
+ describe "configure_dns" do
350
+ before do
351
+ @balancer = Awsborn::LoadBalancer.new('some-name', :region => :eu_west_1, :dns_alias => 'www.example.net')
352
+ @balancer.stub!(:aws_dns_name).and_return('some-name-0001.lb.amz.com')
353
+ @balancer.stub!(:canonical_hosted_zone_name_id).and_return('Z0000000000')
354
+ end
355
+
356
+ it "creates the zone if it does not exist" do
357
+ @mocked_route53.should_receive(:create_zone).with('www.example.net')
358
+ @mocked_route53.should_receive(:zone_exists?).with('www.example.net').and_return(false)
359
+ @balancer.configure_dns
360
+ end
361
+
362
+ it "doesn't create the zone if it already exists" do
363
+ @mocked_route53.should_not_receive(:create_zone)
364
+ @mocked_route53.should_receive(:zone_exists?).with('www.example.net').and_return(true)
365
+ @balancer.configure_dns
366
+ end
367
+
368
+ it "adds the load balancer name as an Alias record" do
369
+ @mocked_route53.should_receive(:alias_target).with('www.example.net').and_return(nil)
370
+ @mocked_route53.should_receive(:add_alias_record).with(:alias => 'www.example.net',
371
+ :lb_fqdn => 'some-name-0001.lb.amz.com', :lb_zone => 'Z0000000000')
372
+ @balancer.configure_dns
373
+ end
374
+
375
+ it "removes an outdated alias record" do
376
+ @mocked_route53.should_receive(:alias_target).with('www.example.net').and_return('old-name-1.lb.amz.com')
377
+ @mocked_route53.should_receive(:remove_alias_records).with('www.example.net')
378
+ @mocked_route53.should_receive(:add_alias_record).with(:alias => 'www.example.net',
379
+ :lb_fqdn => 'some-name-0001.lb.amz.com', :lb_zone => 'Z0000000000')
380
+ @balancer.configure_dns
381
+ end
382
+
383
+ it "doesn't touch the records if they are OK" do
384
+ @mocked_route53.should_not_receive(:add_alias_record)
385
+ @mocked_route53.should_not_receive(:remove_alias_records)
386
+ @balancer.configure_dns
387
+ end
388
+ end
335
389
 
390
+ describe "dns_info" do
391
+ it "forwards to route53 if dns_alias is present" do
392
+ @balancer = Awsborn::LoadBalancer.new(
393
+ 'some-name',
394
+ :region => :eu_west_1a,
395
+ :dns_alias => 'my-awesome-site.example.com.'
396
+ )
397
+ @mocked_route53.should_receive(:zone_for).
398
+ with('my-awesome-site.example.com.').
399
+ and_return('pasta banana')
400
+ @balancer.dns_info.should == 'pasta banana'
401
+ end
402
+ end
403
+ end
@@ -0,0 +1,145 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Awsborn::Route53 do
4
+ before do
5
+ @mock_interface = mock(:route53_interface)
6
+ RightAws::Route53Interface.stub!(:new).and_return(@mock_interface)
7
+ Awsborn.stub!(:access_key_id).and_return('access_key_id')
8
+ Awsborn.stub!(:secret_access_key).and_return('secret_access_key')
9
+ end
10
+
11
+ describe "connection" do
12
+ before do
13
+ @r53 = Awsborn::Route53.new
14
+ end
15
+ it "setup a connection the first time" do
16
+ RightAws::Route53Interface.should_receive(:new).
17
+ with('access_key_id', 'secret_access_key', :logger => Awsborn.logger).
18
+ exactly(:once)
19
+ @r53.connection
20
+ @r53.connection
21
+ end
22
+ end
23
+
24
+ context "for a valid r53" do
25
+ before do
26
+ @r53 = Awsborn::Route53.new(:eu_west_1b)
27
+ @zone_list_fixture = [
28
+ {
29
+ :aws_id=>"/hostedzone/Z1111111111111",
30
+ :caller_reference=>"1295422234-657482-hfkeo-JFKid-Ldfle-Sdrty",
31
+ :config=>{:comment=>"My test site!"},
32
+ :name=>"my-awesome-site.com."
33
+ },
34
+ {
35
+ :aws_id=>"/hostedzone/Z2222222222222",
36
+ :caller_reference=>"1234567890",
37
+ :config=>{:comment=>"My second test site!"},
38
+ :name=>"my-other-awesome-site.com."
39
+ }
40
+ ]
41
+ @zone_detail_fixture = {
42
+ :config=>{:comment=>"My test site!"},
43
+ :aws_id=>"/hostedzone/Z1111111111111",
44
+ :caller_reference=>"1295422234-657482-hfkeo-JFKid-Ldfle-Sdrty",
45
+ :name_servers=>
46
+ [ "ns-794.awsdns-35.net",
47
+ "ns-459.awsdns-57.com",
48
+ "ns-1537.awsdns-00.co.uk",
49
+ "ns-1165.awsdns-17.org"],
50
+ :name=>"my-awesome-site.com."}
51
+ end
52
+
53
+ describe "zone_exists?" do
54
+ before do
55
+ @mock_interface.stub!(:list_hosted_zones).and_return(@zone_list_fixture)
56
+ end
57
+ it "checks the result from Route53Interface" do
58
+ @r53.zone_exists?('my-awesome-site.com.').should == true
59
+ @r53.zone_exists?('my-awesome-site.com').should == true
60
+ @r53.zone_exists?('horrible.com').should == false
61
+ end
62
+ end
63
+
64
+ describe "zone_for" do
65
+ before do
66
+ @mock_interface.stub!(:list_hosted_zones).and_return(@zone_list_fixture)
67
+ end
68
+ it "retrieves zone description from Route53Interface if a zone matches the given name" do
69
+ @mock_interface.should_receive(:get_hosted_zone).
70
+ with("/hostedzone/Z1111111111111").
71
+ and_return(@zone_detail_fixture)
72
+ @r53.zone_for('my-awesome-site.com.').should == @zone_detail_fixture
73
+ end
74
+ it "retrieves zone description from Route53Interface even for a name without ending dot" do
75
+ @mock_interface.should_receive(:get_hosted_zone).
76
+ with("/hostedzone/Z1111111111111").
77
+ and_return(@zone_detail_fixture)
78
+ @r53.zone_for('my-awesome-site.com').should == @zone_detail_fixture
79
+ end
80
+ it "returns nil if no zone match the given name" do
81
+ @mock_interface.should_not_receive(:get_hosted_zone)
82
+ @r53.zone_for('horrible.com').should be_nil
83
+ end
84
+ end
85
+
86
+ describe "zone_id_for" do
87
+ before do
88
+ @mock_interface.stub!(:list_hosted_zones).and_return(@zone_list_fixture)
89
+ end
90
+ it "checks the result from Route53Interface" do
91
+ @r53.zone_id_for('my-awesome-site.com.').should == "/hostedzone/Z1111111111111"
92
+ @r53.zone_id_for('my-awesome-site.com').should == "/hostedzone/Z1111111111111"
93
+ @r53.zone_id_for('horrible.com').should be_nil
94
+ end
95
+
96
+ end
97
+
98
+ describe "create_zone" do
99
+ it "delegates to Route53Interface" do
100
+ @mock_interface.should_receive(:create_hosted_zone).with({:name => 'example.net.', :config => {:comment => ''}})
101
+ @r53.create_zone 'example.net'
102
+ end
103
+ end
104
+
105
+ describe "alias_target" do
106
+ it "delegates cleverly to Route53Interface" do
107
+ @mock_interface.should_receive(:list_hosted_zones).and_return(@zone_list_fixture)
108
+ alias_target = { :hosted_zone_id => 'Z2222222222', :dns_name => 'example-1111111111.us-east-1.elb.amazonaws.com.' }
109
+ alias_record = { :name => 'example.net.', :type => 'A', :alias_target => alias_target }
110
+ @mock_interface.should_receive(:list_resource_record_sets).with(/Z111111111111/).and_return([alias_record])
111
+
112
+ @r53.alias_target('my-awesome-site.com')
113
+ end
114
+ end
115
+
116
+ describe "add_alias_record" do
117
+ it "delegates to Route53Interface" do
118
+ zones = [{:aws_id=>"/hostedzone/Z111111111111", :name=>"example.net."}]
119
+ @mock_interface.stub!(:list_hosted_zones).and_return(zones)
120
+
121
+ alias_target = { :hosted_zone_id => 'Z2222222222', :dns_name => 'example-1111111111.us-east-1.elb.amazonaws.com.' }
122
+ alias_record = { :name => 'example.net.', :type => 'A', :alias_target => alias_target }
123
+
124
+ # .dup since it will get :action => :create
125
+ @mock_interface.should_receive(:create_resource_record_sets).with(/Z111111111111/, [alias_record.dup])
126
+
127
+ @r53.add_alias_record(:alias => 'example.net.', :lb_fqdn => alias_target[:dns_name], :lb_zone => 'Z2222222222')
128
+ end
129
+ end
130
+
131
+ describe "remove_alias_records" do
132
+ it "delegates to Route53Interface" do
133
+ zones = [{:aws_id=>"/hostedzone/Z111111111111", :name=>"example.net."}]
134
+ @mock_interface.stub!(:list_hosted_zones).and_return(zones)
135
+
136
+ alias_target = { :hosted_zone_id => 'Z2222222222', :dns_name => 'example-1111111111.us-east-1.elb.amazonaws.com.' }
137
+ alias_record = { :name => 'example.net.', :type => 'A', :alias_target => alias_target }
138
+ @mock_interface.should_receive(:list_resource_record_sets).with(/Z111111111111/).and_return([alias_record])
139
+ @mock_interface.should_receive(:delete_resource_record_sets).with(/Z111111111111/, [alias_record.dup])
140
+
141
+ @r53.remove_alias_records('example.net')
142
+ end
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,33 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ class SampleServer < Awsborn::Server
4
+ instance_type :m1_small
5
+ image_id 'ami-2fc2e95b'
6
+ keys :all
7
+ end
8
+
9
+ describe Awsborn::ServerCluster do
10
+
11
+ before(:each) do
12
+ Awsborn.verbose = false
13
+ end
14
+
15
+ describe "build" do
16
+ it "adds the domain to servers" do
17
+ c = Awsborn::ServerCluster.build SampleServer, 'foo' do
18
+ domain 'example.org'
19
+ server :name, :ip => 'www'
20
+ end
21
+ c.first.elastic_ip.should == 'www.example.org'
22
+ end
23
+ it "adds the domain to load balancers" do
24
+ c = Awsborn::ServerCluster.build SampleServer, 'foo' do
25
+ domain 'example.org'
26
+ load_balancer 'elbe', :dns_alias => 'www', :region => 'eu-west-1'
27
+ end
28
+ c.load_balancers.first.dns_alias.should == 'www.example.org'
29
+ end
30
+ end
31
+
32
+
33
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: awsborn
3
3
  version: !ruby/object:Gem::Version
4
- hash: 61
4
+ hash: 59
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 8
9
- - 1
10
- version: 0.8.1
9
+ - 2
10
+ version: 0.8.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - David Vrensk
@@ -16,23 +16,23 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2011-08-16 00:00:00 +02:00
19
+ date: 2011-08-23 00:00:00 +02:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
23
- name: right_aws
23
+ name: icehouse-right_aws
24
24
  prerelease: false
25
25
  requirement: &id001 !ruby/object:Gem::Requirement
26
26
  none: false
27
27
  requirements:
28
28
  - - ">="
29
29
  - !ruby/object:Gem::Version
30
- hash: 11
30
+ hash: 7
31
31
  segments:
32
32
  - 2
33
- - 1
33
+ - 2
34
34
  - 0
35
- version: 2.1.0
35
+ version: 2.2.0
36
36
  type: :runtime
37
37
  version_requirements: *id001
38
38
  - !ruby/object:Gem::Dependency
@@ -127,12 +127,15 @@ files:
127
127
  - lib/awsborn/known_hosts_updater.rb
128
128
  - lib/awsborn/load_balancer.rb
129
129
  - lib/awsborn/rake.rb
130
+ - lib/awsborn/route53.rb
130
131
  - lib/awsborn/server.rb
131
132
  - lib/awsborn/server_cluster.rb
132
133
  - spec/aws_constants_spec.rb
133
134
  - spec/ec2_spec.rb
134
135
  - spec/elb_spec.rb
135
136
  - spec/load_balancer_spec.rb
137
+ - spec/route53_spec.rb
138
+ - spec/server_cluster_spec.rb
136
139
  - spec/server_spec.rb
137
140
  - spec/spec.opts
138
141
  - spec/spec_helper.rb