diff --git a/Gemfile.lock b/Gemfile.lock index 130d0d2..bad00f3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,33 +3,16 @@ PATH specs: aws-missing-tools (0.0.1) aws-sdk - trollop GEM remote: https://rubygems.org/ specs: - aruba (0.5.3) - childprocess (>= 0.3.6) - cucumber (>= 1.1.1) - rspec-expectations (>= 2.7.0) - aws-sdk (1.8.5) + aws-sdk (1.11.0) json (~> 1.4) nokogiri (>= 1.4.4) uuidtools (~> 2.1) - builder (3.2.1) - childprocess (0.3.9) - ffi (~> 1.0, >= 1.0.11) - cucumber (1.3.2) - builder (>= 2.1.2) - diff-lcs (>= 1.1.3) - gherkin (~> 2.12.0) - multi_json (~> 1.3) diff-lcs (1.1.3) - ffi (1.8.1) - gherkin (2.12.0) - multi_json (~> 1.3) - json (1.7.7) - multi_json (1.7.4) + json (1.8.0) nokogiri (1.5.9) rspec (2.12.0) rspec-core (~> 2.12.0) @@ -39,13 +22,11 @@ GEM rspec-expectations (2.12.1) diff-lcs (~> 1.1.3) rspec-mocks (2.12.2) - trollop (2.0) - uuidtools (2.1.3) + uuidtools (2.1.4) PLATFORMS ruby DEPENDENCIES - aruba aws-missing-tools! rspec diff --git a/aws-missing-tools.gemspec b/aws-missing-tools.gemspec index 5530458..f7901d2 100644 --- a/aws-missing-tools.gemspec +++ b/aws-missing-tools.gemspec @@ -16,8 +16,6 @@ Gem::Specification.new do |gem| gem.version = AwsMissingTools::VERSION gem.add_dependency 'aws-sdk' - gem.add_dependency 'trollop' - gem.add_development_dependency 'aruba' gem.add_development_dependency 'rspec' end diff --git a/bin/aws-ha-release.rb b/bin/aws-ha-release.rb index 9af2945..c31fee5 100755 --- a/bin/aws-ha-release.rb +++ b/bin/aws-ha-release.rb @@ -1,29 +1,4 @@ #!/usr/bin/env ruby -begin - require 'trollop' -rescue LoadError => e - puts "The #{e.message.split('-').last.strip} gem must be installed." - raise -end - -opts = Trollop::options do - opt :as_group_name, 'AutoScaling Group Name', type: :string, short: '-a' - opt :region, 'Region', default: 'us-east-1', type: :string, short: '-r' - opt :elb_timeout, 'ELB Timeout', type: :int, default: 60, short: '-t' - opt :inservice_time_allowed, 'InService Time Allowed', type: :int, default: 300, short: '-i' - opt :aws_access_key, 'AWS Access Key', type: :string, short: '-o' - opt :aws_secret_key, 'AWS Secret Key', type: :string, short: '-s' -end - -Trollop::die :as_group_name, 'You must specify the AutoScaling Group Name: aws-ha-release.rb -a ' unless opts[:as_group_name] -Trollop::die :aws_access_key, 'If you specify the AWS Secret Key, you must also specify the Access Key with -o .' if opts[:aws_secret_key] && opts[:aws_access_key].nil? -Trollop::die :aws_secret_key, 'If you specify the AWS Access Key, you must also specify the Secret Key with -s .' if opts[:aws_access_key] && opts[:aws_secret_key].nil? - -if opts[:aws_access_key].nil? || opts[:aws_secret_key].nil? - opts[:aws_access_key] = ENV['AWS_ACCESS_KEY'] - opts[:aws_secret_key] = ENV['AWS_SECRET_KEY'] -end - require 'aws-missing-tools' -AwsHaRelease.new(opts).execute! +AwsHaRelease.new(ARGV.dup).execute! diff --git a/features/aws-ha-release.feature b/features/aws-ha-release.feature deleted file mode 100644 index cc4a23a..0000000 --- a/features/aws-ha-release.feature +++ /dev/null @@ -1,41 +0,0 @@ -Feature: AWS High-Availibility Release - Scenario: Requires the autoscaling group name to be passed in - When I run `aws-ha-release.rb` - Then the output should contain "You must specify the AutoScaling Group Name: aws-ha-release.rb -a " - And the exit status should not be 0 - When I run `aws-ha-release.rb -a test_group` - Then the exit status should be 0 - When I run `aws-ha-release.rb --as-group-name test_group` - Then the exit status should be 0 - - Scenario: Optionally allows the user to specify an ELB timeout - When I run `aws-ha-release.rb -a test_group -t not_valid_input` - Then the exit status should not be 0 - When I run `aws-ha-release.rb -a test_group -t 100` - Then the exit status should be 0 - When I run `aws-ha-release.rb -a test_group --elb-timeout 100` - Then the exit status should be 0 - - Scenario: Optionally allows the user to specify a region - When I run `aws-ha-release.rb -a test_group -r` - Then the exit status should not be 0 - When I run `aws-ha-release.rb -a test_group -r test_region` - Then the exit status should be 0 - When I run `aws-ha-release.rb -a test_group --region test_region` - Then the exit status should be 0 - - Scenario: Optionally allows the user to specify an inservice time allowed - When I run `aws-ha-release.rb -a test_group -i not_valid_input` - Then the exit status should not be 0 - When I run `aws-ha-release.rb -a test_group -i 100` - Then the exit status should be 0 - When I run `aws-ha-release.rb -a test_group --inservice-time-allowed 100` - Then the exit status should be 0 - - Scenario: Optionally allows the user to pass in the aws_access_key and aws_secret_key - When I run `aws-ha-release.rb -a test_group -o testaccesskey` - Then the exit status should not be 0 - When I run `aws-ha-release.rb -a test_group -o testaccesskey -s testsecretkey` - Then the exit status should be 0 - When I run `aws-ha-release.rb -a test_group --aws-access-key testaccesskey --aws-secret-key testsecretkey` - Then the exit status should be 0 diff --git a/features/support/env.rb b/features/support/env.rb deleted file mode 100644 index 96bece2..0000000 --- a/features/support/env.rb +++ /dev/null @@ -1,6 +0,0 @@ -require 'aruba/cucumber' -require 'aws-sdk' - -Before do - AWS.stub! -end diff --git a/lib/aws-missing-tools.rb b/lib/aws-missing-tools.rb index 87d7556..2aea5ea 100644 --- a/lib/aws-missing-tools.rb +++ b/lib/aws-missing-tools.rb @@ -2,7 +2,6 @@ require 'aws-missing-tools/version' module AwsMissingTools require 'aws-sdk' - require 'trollop' require 'aws-missing-tools/aws-ha-release/aws-ha-release' end diff --git a/lib/aws-missing-tools/aws-ha-release/aws-ha-release.rb b/lib/aws-missing-tools/aws-ha-release/aws-ha-release.rb index 09d1dc7..306d8b4 100755 --- a/lib/aws-missing-tools/aws-ha-release/aws-ha-release.rb +++ b/lib/aws-missing-tools/aws-ha-release/aws-ha-release.rb @@ -1,25 +1,73 @@ -require 'aws-sdk' require 'timeout' +require 'optparse' class AwsHaRelease attr_reader :group - def initialize(opts) - AWS.config(access_key_id: opts[:aws_access_key], secret_access_key: opts[:aws_secret_key], region: opts[:region]) + def initialize(argv) + @opts = AwsHaRelease.parse_options(argv) + + AWS.config(access_key_id: @opts[:aws_access_key], secret_access_key: @opts[:aws_secret_key], region: @opts[:region]) @as = AWS::AutoScaling.new - @group = @as.groups[opts[:as_group_name]] + @group = @as.groups[@opts[:as_group_name]] if @group.nil? - raise ArgumentError, "The Auto Scaling Group named #{opts[:as_group_name]} does not exist in #{opts[:region]}." + raise ArgumentError, "The Auto Scaling Group named #{@opts[:as_group_name]} does not exist in #{@opts[:region]}." end @max_size_change = 0 @inservice_polling_time = 10 - @opts = opts @processes_to_suspend = %w(ReplaceUnhealthy AlarmNotification ScheduledActions AZRebalance) end + def self.parse_options(arguments) + options = { + region: 'us-east-1', + elb_timeout: 60, + inservice_time_allowed: 300 + } + + OptionParser.new do |opts| + opts.banner = 'Usage: aws-ha-release.rb -a [options]' + + opts.on('-a', '--as-group-name GROUP_NAME', 'AutoScaling Group Name') do |v| + options[:as_group_name] = v + end + + opts.on('-r', '--region REGION', 'Region') do |v| + options[:region] = v + end + + opts.on('-t', '--elb-timeout TIME', 'ELB Timeout (seconds)') do |v| + options[:elb_timeout] = v.to_i + end + + opts.on('-i', '--inservice-time-allowed TIME', 'Time allowed for instance to come in service (seconds)') do |v| + options[:inservice_time_allowed] = v.to_i + end + + opts.on('-o', '--aws_access_key AWS_ACCESS_KEY', 'AWS Access Key') do |v| + options[:aws_access_key] = v + end + + opts.on('-s', '--aws_secret_key AWS_SECRET_KEY', 'AWS Secret Key') do |v| + options[:aws_secret_key] = v + end + end.parse!(arguments) + + raise OptionParser::MissingArgument, 'You must specify the AutoScaling Group Name: aws-ha-release.rb -a ' if options[:as_group_name].nil? + + if options[:aws_secret_key] && options[:aws_access_key].nil? || options[:aws_access_key] && options[:aws_secret_key].nil? + raise OptionParser::MissingArgument, 'If specifying either the AWS Access or Secret Key, then the other must also be specified. aws-ha-release.rb -a -o access_key -s secret_key' + elsif options[:aws_secret_key].nil? && options[:aws_access_key].nil? + options[:aws_access_key] = ENV['AWS_ACCESS_KEY'] + options[:aws_secret_key] = ENV['AWS_SECRET_KEY'] + end + + options + end + def execute! %w(RemoveFromLoadBalancerLowPriority Terminate Launch HealthCheck AddToLoadBalancer).each do |process| if @group.suspended_processes.keys.include? process diff --git a/spec/aws-missing-tools/aws-ha-release/aws-ha-release_spec.rb b/spec/aws-missing-tools/aws-ha-release/aws-ha-release_spec.rb index 4dbe0e2..464092d 100644 --- a/spec/aws-missing-tools/aws-ha-release/aws-ha-release_spec.rb +++ b/spec/aws-missing-tools/aws-ha-release/aws-ha-release_spec.rb @@ -1,16 +1,7 @@ require 'spec_helper' describe 'aws-ha-release' do - let(:opts) do - { - as_group_name: 'test_group', - aws_access_key: 'testaccesskey', - aws_secret_key: 'testsecretkey', - region: 'test-region', - inservice_time_allowed: 300, - elb_timeout: 0 - } - end + let(:opts) { %w(-a test_group -o testaccesskey -s testsecretkey -r test_region -i 1 -t 0) } let(:as) { AWS::FakeAutoScaling.new } @@ -25,22 +16,69 @@ describe 'aws-ha-release' do describe '#initialize' do it 'initializes the AWS connection' do - as.groups.create opts[:as_group_name] + as.groups.create opts[1] - AWS.should_receive(:config).with(access_key_id: 'testaccesskey', secret_access_key: 'testsecretkey', region: 'test-region') + AWS.should_receive(:config).with(access_key_id: 'testaccesskey', secret_access_key: 'testsecretkey', region: 'test_region') AwsHaRelease.new(opts) end it 'ensures the as group exists' do lambda { - AwsHaRelease.new(opts.merge!(as_group_name: 'fake_group')) + opts[1] = 'fake_group' + AwsHaRelease.new(opts) }.should raise_error end end + describe '#parse_options' do + it 'requires the autoscaling group name to be passed in' do + expect{ AwsHaRelease.parse_options([]) }.to raise_error OptionParser::MissingArgument + expect(AwsHaRelease.parse_options(%w(-a test_group))[:as_group_name]).to eq 'test_group' + expect(AwsHaRelease.parse_options(%w(--as-group-name test_group))[:as_group_name]).to eq 'test_group' + end + + it 'sets default options' do + options = AwsHaRelease.parse_options(%w(-a test_group)) + expect(options[:elb_timeout]).not_to be_nil + expect(options[:region]).not_to be_nil + expect(options[:inservice_time_allowed]).not_to be_nil + expect(options[:aws_access_key]).not_to be_nil + expect(options[:aws_secret_key]).not_to be_nil + end + + context 'optional params' do + it 'ELB timeout' do + [%w(-a test_group -t 10), %w(-a test_group --elb-timeout 10)].each do |options| + expect(AwsHaRelease.parse_options(options)[:elb_timeout]).to eq 10 + end + end + + it 'region' do + [%w(-a test_group -r test_region), %w(-a test_group --region test_region)].each do |options| + expect(AwsHaRelease.parse_options(options)[:region]).to eq 'test_region' + end + end + + it 'inservice time allowed' do + [%w(-a test_group -i 300), %w(-a test_group --inservice-time-allowed 300)].each do |options| + expect(AwsHaRelease.parse_options(options)[:inservice_time_allowed]).to eq 300 + end + end + + it 'aws_access_key and aws_secret_key' do + expect{ AwsHaRelease.parse_options(%w(-a test_group -o testkey)) }.to raise_error OptionParser::MissingArgument + expect{ AwsHaRelease.parse_options(%w(-a test_group -s testsecretkey)) }.to raise_error OptionParser::MissingArgument + + options = AwsHaRelease.parse_options(%w(-a test_group -o testkey -s testsecretkey)) + expect(options[:aws_access_key]).to eq 'testkey' + expect(options[:aws_secret_key]).to eq 'testsecretkey' + end + end + end + describe '#execute!' do before do - @group = as.groups.create opts[:as_group_name] + @group = as.groups.create opts[1] @aws_ha_release = AwsHaRelease.new(opts) end @@ -74,7 +112,7 @@ describe 'aws-ha-release' do describe 'determining if instances are in service' do before do - @group = as.groups.create opts[:as_group_name] + @group = as.groups.create opts[1] @group.update(desired_capacity: 2) @aws_ha_release = AwsHaRelease.new(opts) end @@ -155,7 +193,7 @@ describe 'aws-ha-release' do describe '#deregister_instance' do before do - @group = as.groups.create opts[:as_group_name] + @group = as.groups.create opts[1] @aws_ha_release = AwsHaRelease.new(opts) end