check that number of instances in load balancer matches desired capacity
This commit is contained in:
		
							parent
							
								
									0554f6eb74
								
							
						
					
					
						commit
						601f6087ec
					
				@ -94,9 +94,11 @@ class AwsHaRelease
 | 
				
			|||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def instances_inservice?(load_balancer)
 | 
					  def instances_inservice?(load_balancer)
 | 
				
			||||||
    load_balancer.instances.health.each do |health|
 | 
					    return false if load_balancer.instances.count != @group.desired_capacity
 | 
				
			||||||
      unless health[:state] == 'InService'
 | 
					
 | 
				
			||||||
        puts "Instance #{health[:instance].id} is currently #{health[:state]} on load balancer #{load_balancer.name}."
 | 
					    load_balancer.instances.health.each do |instance_health|
 | 
				
			||||||
 | 
					      unless instance_health[:state] == 'InService'
 | 
				
			||||||
 | 
					        puts "Instance #{instance_health[:instance].id} is currently #{instance_health[:state]} on load balancer #{load_balancer.name}."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return false
 | 
					        return false
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
				
			|||||||
@ -14,6 +14,10 @@ describe 'aws-ha-release' do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  let(:as) { AWS::FakeAutoScaling.new }
 | 
					  let(:as) { AWS::FakeAutoScaling.new }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let(:instance_one) { AWS::FakeEC2::Instance.new }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let(:instance_two) { AWS::FakeEC2::Instance.new }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  before do
 | 
					  before do
 | 
				
			||||||
    AWS::AutoScaling.stub(:new).and_return(as)
 | 
					    AWS::AutoScaling.stub(:new).and_return(as)
 | 
				
			||||||
    IO.any_instance.stub(:puts)
 | 
					    IO.any_instance.stub(:puts)
 | 
				
			||||||
@ -71,47 +75,82 @@ describe 'aws-ha-release' do
 | 
				
			|||||||
  describe 'determining if instances are in service' do
 | 
					  describe 'determining if instances are in service' do
 | 
				
			||||||
    before do
 | 
					    before do
 | 
				
			||||||
      @group = as.groups.create opts[:as_group_name]
 | 
					      @group = as.groups.create opts[:as_group_name]
 | 
				
			||||||
 | 
					      @group.update(desired_capacity: 2)
 | 
				
			||||||
      @aws_ha_release = AwsHaRelease.new(opts)
 | 
					      @aws_ha_release = AwsHaRelease.new(opts)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it 'checks all instances across a given load balancer' do
 | 
					    it 'checks all instances across a given load balancer' do
 | 
				
			||||||
      load_balancer = AWS::FakeELB::LoadBalancer.new 'test_load_balancer_01'
 | 
					      load_balancer = AWS::FakeELB::LoadBalancer.new 'test_load_balancer_01', [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          instance: instance_one,
 | 
				
			||||||
 | 
					          healthy: true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          instance: instance_two,
 | 
				
			||||||
 | 
					          healthy: false
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      expect(@aws_ha_release.instances_inservice?(load_balancer)).to eq false
 | 
					      expect(@aws_ha_release.instances_inservice?(load_balancer)).to eq false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      load_balancer.instances.health[1] = {
 | 
					      load_balancer.instances.make_instance_healthy(instance_two)
 | 
				
			||||||
        instance: AWS::FakeEC2::Instance.new,
 | 
					 | 
				
			||||||
        description: 'N/A',
 | 
					 | 
				
			||||||
        state: 'InService',
 | 
					 | 
				
			||||||
        reason_code: 'N/A'
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      expect(@aws_ha_release.instances_inservice?(load_balancer)).to eq true
 | 
					      expect(@aws_ha_release.instances_inservice?(load_balancer)).to eq true
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it 'checks all instances across an array of load balancers' do
 | 
					    it 'checks all instances across an array of load balancers' do
 | 
				
			||||||
      load_balancers = [AWS::FakeELB::LoadBalancer.new('test_load_balancer_01'), AWS::FakeELB::LoadBalancer.new('test_load_balancer_02')]
 | 
					      load_balancers = [
 | 
				
			||||||
 | 
					        AWS::FakeELB::LoadBalancer.new('test_load_balancer_01', [
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            instance: instance_one,
 | 
				
			||||||
 | 
					            healthy: true
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            instance: instance_two,
 | 
				
			||||||
 | 
					            healthy: false
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        ]), AWS::FakeELB::LoadBalancer.new('test_load_balancer_02', [
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            instance: instance_one,
 | 
				
			||||||
 | 
					            healthy: true
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            instance: instance_two,
 | 
				
			||||||
 | 
					            healthy: false
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        ])
 | 
				
			||||||
 | 
					      ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      expect(@aws_ha_release.all_instances_inservice?(load_balancers)).to eq false
 | 
					      expect(@aws_ha_release.all_instances_inservice?(load_balancers)).to eq false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      load_balancers[0].instances.health[1] = {
 | 
					      load_balancers[0].instances.make_instance_healthy(instance_two)
 | 
				
			||||||
        instance: AWS::FakeEC2::Instance.new,
 | 
					 | 
				
			||||||
        description: 'N/A',
 | 
					 | 
				
			||||||
        state: 'InService',
 | 
					 | 
				
			||||||
        reason_code: 'N/A'
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      expect(@aws_ha_release.all_instances_inservice?(load_balancers)).to eq false
 | 
					      expect(@aws_ha_release.all_instances_inservice?(load_balancers)).to eq false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      load_balancers[1].instances.health[1] = {
 | 
					      load_balancers[1].instances.make_instance_healthy(instance_two)
 | 
				
			||||||
        instance: AWS::FakeEC2::Instance.new,
 | 
					 | 
				
			||||||
        description: 'N/A',
 | 
					 | 
				
			||||||
        state: 'InService',
 | 
					 | 
				
			||||||
        reason_code: 'N/A'
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      expect(@aws_ha_release.all_instances_inservice?(load_balancers)).to eq true
 | 
					      expect(@aws_ha_release.all_instances_inservice?(load_balancers)).to eq true
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it 'requires the number of inservice instances to match the desired capacity' do
 | 
				
			||||||
 | 
					      load_balancer = AWS::FakeELB::LoadBalancer.new 'test_load_balancer_01', [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          instance: instance_one,
 | 
				
			||||||
 | 
					          healthy: true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          instance: instance_two,
 | 
				
			||||||
 | 
					          healthy: true
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      @group.update(desired_capacity: 3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      expect(@aws_ha_release.instances_inservice?(load_balancer)).to eq false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      instance_three = AWS::FakeEC2::Instance.new
 | 
				
			||||||
 | 
					      load_balancer.instances.register instance_three
 | 
				
			||||||
 | 
					      load_balancer.instances.make_instance_healthy(instance_three)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      expect(@aws_ha_release.instances_inservice?(load_balancer)).to eq true
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  describe '#deregister_instance' do
 | 
					  describe '#deregister_instance' do
 | 
				
			||||||
@ -121,11 +160,26 @@ describe 'aws-ha-release' do
 | 
				
			|||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it 'deregisters an instance across all load balancers' do
 | 
					    it 'deregisters an instance across all load balancers' do
 | 
				
			||||||
      instance_one = AWS::FakeEC2::Instance.new
 | 
					      elb_one = AWS::FakeELB::LoadBalancer.new 'test_load_balancer_01', [
 | 
				
			||||||
      instance_two = AWS::FakeEC2::Instance.new
 | 
					        {
 | 
				
			||||||
 | 
					          instance: instance_one,
 | 
				
			||||||
      elb_one = AWS::FakeELB::LoadBalancer.new 'test_load_balancer_01'
 | 
					          healthy: true
 | 
				
			||||||
      elb_two = AWS::FakeELB::LoadBalancer.new 'test_load_balancer_02'
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          instance: instance_two,
 | 
				
			||||||
 | 
					          healthy: true
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      ]
 | 
				
			||||||
 | 
					      elb_two = AWS::FakeELB::LoadBalancer.new 'test_load_balancer_02', [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          instance: instance_one,
 | 
				
			||||||
 | 
					          healthy: true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          instance: instance_two,
 | 
				
			||||||
 | 
					          healthy: true
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      elb_one.instances.register instance_one
 | 
					      elb_one.instances.register instance_one
 | 
				
			||||||
      elb_one.instances.register instance_two
 | 
					      elb_one.instances.register instance_two
 | 
				
			||||||
 | 
				
			|||||||
@ -4,14 +4,11 @@ module AWS
 | 
				
			|||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class LoadBalancer
 | 
					    class LoadBalancer
 | 
				
			||||||
      attr_reader :name
 | 
					      attr_reader :name, :instances
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      def initialize(name, options = {})
 | 
					      def initialize(name, instances_and_healths)
 | 
				
			||||||
        @name = name
 | 
					        @name = name
 | 
				
			||||||
      end
 | 
					        @instances ||= InstanceCollection.new(instances_and_healths)
 | 
				
			||||||
 | 
					 | 
				
			||||||
      def instances
 | 
					 | 
				
			||||||
        @instances ||= InstanceCollection.new
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -21,7 +18,15 @@ module AWS
 | 
				
			|||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class InstanceCollection < Array
 | 
					    class InstanceCollection < Array
 | 
				
			||||||
      def initialize
 | 
					      attr_reader :health
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      def initialize(instances_and_healths)
 | 
				
			||||||
 | 
					        @health = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        instances_and_healths.each do |instance_and_health|
 | 
				
			||||||
 | 
					          self << instance_and_health[:instance]
 | 
				
			||||||
 | 
					          instance_and_health[:healthy] ? make_instance_healthy(instance_and_health[:instance]) : make_instance_unhealthy(instance_and_health[:instance])
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      def register(*instances)
 | 
					      def register(*instances)
 | 
				
			||||||
@ -34,21 +39,40 @@ module AWS
 | 
				
			|||||||
        end
 | 
					        end
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      def health
 | 
					      def make_instance_healthy(instance)
 | 
				
			||||||
        @health ||= [
 | 
					        opts = {
 | 
				
			||||||
          {
 | 
					          instance: instance,
 | 
				
			||||||
            instance: AWS::FakeEC2::Instance.new,
 | 
					 | 
				
			||||||
          description: 'N/A',
 | 
					          description: 'N/A',
 | 
				
			||||||
          state: 'InService',
 | 
					          state: 'InService',
 | 
				
			||||||
          reason_code: 'N/A'
 | 
					          reason_code: 'N/A'
 | 
				
			||||||
          },
 | 
					        }
 | 
				
			||||||
          {
 | 
					
 | 
				
			||||||
            instance: AWS::FakeEC2::Instance.new,
 | 
					        @health.each_with_index do |health, i|
 | 
				
			||||||
 | 
					          if health[:instance] == instance
 | 
				
			||||||
 | 
					            @health[i] = opts
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @health << opts
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      def make_instance_unhealthy(instance)
 | 
				
			||||||
 | 
					        opts = {
 | 
				
			||||||
 | 
					          instance: instance,
 | 
				
			||||||
          description: 'Instance has failed at least the UnhealthyThreshold number of health checks consecutively.',
 | 
					          description: 'Instance has failed at least the UnhealthyThreshold number of health checks consecutively.',
 | 
				
			||||||
          state: 'OutOfService',
 | 
					          state: 'OutOfService',
 | 
				
			||||||
          reason_code: 'Instance'
 | 
					          reason_code: 'Instance'
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        ]
 | 
					
 | 
				
			||||||
 | 
					        @health.each_with_index do |health, i|
 | 
				
			||||||
 | 
					          if health[:instance] == instance
 | 
				
			||||||
 | 
					            @health[i] = opts
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @health << opts
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user