Class: CloudProviders::ElasticLoadBalancer

Inherits:
Ec2Helper show all
Defined in:
lib/cloud_providers/ec2/helpers/elastic_load_balancer.rb

Instance Attribute Summary

Attributes inherited from CloudProvider

#init_opts, #name

Instance Method Summary collapse

Methods inherited from Ec2Helper

#as, #ec2, #elb, #initialize, #pool, property, #rds

Methods inherited from CloudProvider

#after_initialized, #bootstrap_nodes!, #default_keypair_path, default_keypair_path, #initialize, #method_missing

Constructor Details

This class inherits a constructor from CloudProviders::Ec2Helper

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class CloudProviders::CloudProvider

Instance Method Details

#attach_instances_if_necessaryObject



64
65
66
67
68
# File 'lib/cloud_providers/ec2/helpers/elastic_load_balancer.rb', line 64

def attach_instances_if_necessary
  parent.reset!
  instances = parent.nodes.map {|a| a.instance_id } # ec2 gem requires this be an array of names
  elb.register_instances_with_load_balancer(:instances => instances, :load_balancer_name => "#{name}") unless instances.empty?
end

#configure_health_check!(hc) ⇒ Object



88
89
90
91
# File 'lib/cloud_providers/ec2/helpers/elastic_load_balancer.rb', line 88

def configure_health_check!(hc)
  # puts "Configuring health_check: #{hc.to_hash.inspect}"
  elb.configure_health_check(:health_check => hc.to_hash, :load_balancer_name => name)
end

#create!Object



6
7
8
9
10
11
# File 'lib/cloud_providers/ec2/helpers/elastic_load_balancer.rb', line 6

def create!
  if should_create_load_balancer?
    puts "-----> Creating ElasticLoadBalancer: #{name}"
    create_load_balancer!
  end
end

#create_load_balancer!Object



80
81
82
83
84
85
86
87
# File 'lib/cloud_providers/ec2/helpers/elastic_load_balancer.rb', line 80

def create_load_balancer!
  elb.delete_load_balancer(:load_balancer_name => name)
  elb.create_load_balancer(
    :availability_zones => parent.availability_zones,
    :load_balancer_name => real_name,
    :listeners => _listeners.map {|l| l.to_hash }
  )
end

#detach_instances_if_necessaryObject



69
70
71
72
73
74
75
76
# File 'lib/cloud_providers/ec2/helpers/elastic_load_balancer.rb', line 69

def detach_instances_if_necessary
  parent.reset!
  begin
    instances = parent.all_nodes.select {|a| !a.running? }.map {|a| a.instance_id }
    elb.deregister_instances_from_load_balancer(:instances => instances, :load_balancer_name => "#{name}") unless instances.empty?
  rescue Exception => e
  end
end

#elastic_load_balancersObject



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/cloud_providers/ec2/helpers/elastic_load_balancer.rb', line 115

def elastic_load_balancers
  begin
    @elastic_load_balancers ||= elb.describe_load_balancers.DescribeLoadBalancersResult.LoadBalancerDescriptions.member.map do |lb|
      {
        :created_time => lb["CreatedTime"],
        :availability_zones => (lb["AvailabilityZones"]["member"] rescue []),
        :dns_name => lb["DNSName"],
        :name => lb["LoadBalancerName"],
        :instances => (g["Instances"]["member"] rescue []).map {|i| {:instance_id => i["InstanceId"]}},
        :health_check => ([lb["HealthCheck"]] rescue []).map do |hc|
          {
            :healthy_threshold => hc["HealthyThreshold"],
            :timeout => hc["Timeout"],
            :unhealthy_threshold => hc["UnhealthyThreshold"],
            :interval => hc["Interval"],
            :target => hc["Target"]
          }
        end,
        :listeners => (lb["Listeners"]["member"] rescue []).map do |listener|
          {
            :instance_port => listener["InstancePort"],
            :protocol => listener["Protocol"],
            :load_balancer_port => listener["LoadBalancerPort"]
          }
        end
      }
    end
  rescue Exception => e
    []
  end      
end

#health_check(*health_check_hashes) ⇒ Object



47
48
49
50
51
# File 'lib/cloud_providers/ec2/helpers/elastic_load_balancer.rb', line 47

def health_check(*health_check_hashes)
  health_check_hashes.each do |hsh|
    _health_checks << HealthCheck.new(hsh)
  end
end

#instance_healthsObject



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/cloud_providers/ec2/helpers/elastic_load_balancer.rb', line 146

def instance_healths
  @instance_healths ||= 
  begin
    elb.describe_instance_health(:load_balancer_name => name).DescribeInstanceHealthResult.InstanceStates.member.map do |i|
      {
        :instance_id => i["InstanceId"],
        :reason_code => i["ReasonCode"],
        :state => i["State"],
        :description => i["Description"]
      }
    end
  rescue Exception => e
    []
  end
end

#listener(*listener_hashes) ⇒ Object



41
42
43
44
45
# File 'lib/cloud_providers/ec2/helpers/elastic_load_balancer.rb', line 41

def listener(*listener_hashes)
  listener_hashes.each do |hsh|
    _listeners << ElasticListener.new(hsh)
  end
end

#runObject



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/cloud_providers/ec2/helpers/elastic_load_balancer.rb', line 13

def run
  create! # Just for now, while we migrate to 2 commands
  if should_update_load_balancer?
    create_load_balancer!
  end
  _health_checks.each do |ck|
    configure_health_check!(ck)
  end
  # Remove old nodes that are no longer alive
  detach_instances_if_necessary
  # Try to unregister and reregister nodes that are out of service, perhaps it was just a setup bug that the setup took too long
  out_of_service_node_listing = instance_healths.select {|a| a[:state] == "OutOfService" }.map {|a| a[:instance_id] }
  reset!
  out_of_service_nodes = nodes.select {|n| out_of_service_node_listing.include?(n.instance_id)}
  unless out_of_service_nodes.empty?
    puts "Uh oh. Out of service instance!: #{out_of_service_nodes.inspect}"
    elb.deregister_instances_from_load_balancer(:load_balancer_name => name, :instances => out_of_service_nodes)
    elb.register_instances_with_load_balancer(:load_balancer_name => name, :instances => out_of_service_nodes)
  end
  # Attach new nodes if there are any new nodes
  attach_instances_if_necessary
end

#running_load_balancersObject



112
113
114
# File 'lib/cloud_providers/ec2/helpers/elastic_load_balancer.rb', line 112

def running_load_balancers
  elastic_load_balancers.select {|lc| lc.name =~ /#{name}/ }.flatten
end

#should_create_load_balancer?Boolean

Returns:

  • (Boolean)


77
78
79
# File 'lib/cloud_providers/ec2/helpers/elastic_load_balancer.rb', line 77

def should_create_load_balancer?
  elastic_load_balancers.select {|lb| lb.name == name }.empty?
end

#should_update_load_balancer?Boolean

Returns:

  • (Boolean)


92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/cloud_providers/ec2/helpers/elastic_load_balancer.rb', line 92

def should_update_load_balancer?
  known = elastic_load_balancers.select {|lc| lc.name =~ /#{name}/ }.flatten
  if known.empty?
    true
  else
    known_listeners = known.map {|a| a[:listeners]}.flatten
    # Take the known listeners (that are defined on the cloud_provider)
    # and compare their describable values to those that are defined in
    # the clouds.rb. Select only those that are different.
    differences = _listeners.reject do |listener|
      known_listeners.reject {|kl| listener.diff(kl).empty? }.empty?
    end.flatten
    if differences.empty?
      false
    else
      true
    end
  end
end

#teardownObject



36
37
38
39
# File 'lib/cloud_providers/ec2/helpers/elastic_load_balancer.rb', line 36

def teardown
  puts "-----> Tearing down load balancer: #{name}"
  elb.delete_load_balancer(:load_balancer_name => name)
end