elba 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.rbc
2
+ .bundle
3
+ .config
4
+ coverage
5
+ InstalledFiles
6
+ lib/bundler/man
7
+ pkg
8
+ rdoc
9
+ spec/reports
10
+ test/tmp
11
+ test/version_tmp
12
+ tmp
13
+
14
+ # YARD artifacts
15
+ .yardoc
16
+ _yardoc
17
+ doc/
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 1.9.3-p385
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ - 1.9.3
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'http://housetripgems.herokuapp.com'
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,87 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ elba (0.0.4)
5
+ fog
6
+ thor
7
+
8
+ GEM
9
+ remote: http://housetripgems.herokuapp.com/
10
+ specs:
11
+ builder (3.2.2)
12
+ celluloid (0.15.2)
13
+ timers (~> 1.1.0)
14
+ coderay (1.0.9)
15
+ diff-lcs (1.2.4)
16
+ excon (0.27.6)
17
+ ffi (1.9.0)
18
+ fog (1.16.0)
19
+ builder
20
+ excon (~> 0.27.0)
21
+ formatador (~> 0.2.0)
22
+ mime-types
23
+ multi_json (~> 1.0)
24
+ net-scp (~> 1.1)
25
+ net-ssh (>= 2.1.3)
26
+ nokogiri (~> 1.5)
27
+ ruby-hmac
28
+ unicode (~> 0.4.4)
29
+ formatador (0.2.4)
30
+ guard (2.2.2)
31
+ formatador (>= 0.2.4)
32
+ listen (~> 2.1)
33
+ lumberjack (~> 1.0)
34
+ pry (>= 0.9.12)
35
+ thor (>= 0.18.1)
36
+ guard-rspec (3.0.2)
37
+ guard (>= 1.8)
38
+ rspec (~> 2.13)
39
+ listen (2.1.1)
40
+ celluloid (>= 0.15.2)
41
+ rb-fsevent (>= 0.9.3)
42
+ rb-inotify (>= 0.9)
43
+ lumberjack (1.0.4)
44
+ method_source (0.8.2)
45
+ mime-types (1.25)
46
+ mini_portile (0.5.1)
47
+ multi_json (1.8.2)
48
+ net-scp (1.1.2)
49
+ net-ssh (>= 2.6.5)
50
+ net-ssh (2.7.0)
51
+ nokogiri (1.6.0)
52
+ mini_portile (~> 0.5.0)
53
+ pry (0.9.12.2)
54
+ coderay (~> 1.0.5)
55
+ method_source (~> 0.8)
56
+ slop (~> 3.4)
57
+ pry-nav (0.2.3)
58
+ pry (~> 0.9.10)
59
+ rake (10.1.0)
60
+ rb-fsevent (0.9.3)
61
+ rb-inotify (0.9.1)
62
+ ffi (>= 0.5.0)
63
+ rspec (2.14.1)
64
+ rspec-core (~> 2.14.0)
65
+ rspec-expectations (~> 2.14.0)
66
+ rspec-mocks (~> 2.14.0)
67
+ rspec-core (2.14.6)
68
+ rspec-expectations (2.14.3)
69
+ diff-lcs (>= 1.1.3, < 2.0)
70
+ rspec-mocks (2.14.4)
71
+ ruby-hmac (0.4.0)
72
+ slop (3.4.6)
73
+ thor (0.18.1)
74
+ timers (1.1.0)
75
+ unicode (0.4.4)
76
+
77
+ PLATFORMS
78
+ ruby
79
+
80
+ DEPENDENCIES
81
+ bundler
82
+ elba!
83
+ guard-rspec
84
+ pry
85
+ pry-nav
86
+ rake
87
+ rspec
data/Guardfile ADDED
@@ -0,0 +1,5 @@
1
+ guard :rspec, :cli => "--color --format progress" do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
4
+ watch('spec/spec_helper.rb') { "spec" }
5
+ end
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 HouseTrip
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,57 @@
1
+ # Elba [![Build Status](https://travis-ci.org/HouseTrip/elba.png?branch=master)](https://travis-ci.org/HouseTrip/elba)
2
+
3
+ Command-line interface for Amazon's ELB
4
+
5
+ ## Getting started
6
+
7
+ Elba relies on the excellent [Fog gem](http://fog.io/) to connect to Amazon's APIs.
8
+ Start by setting up your `~/.fog`:
9
+
10
+ # ~/.fog
11
+ :default:
12
+ :aws_access_key_id: ABCDEF....
13
+ :aws_secret_access_key: 123456....
14
+
15
+ ## Available Commands
16
+
17
+ elba help # prints this message
18
+ elba list # list available load balancers, pass option -i to list instances attached
19
+ elba attach [INSTANCES] # attach INSTANCES to an ELB, pass option --to to specify which one
20
+ elba detach [INSTANCES] # detach INSTANCES from their ELB
21
+
22
+ Adding or removing a server will prompt the user which load balancer they wish the server to be removed from.
23
+ Your AWS Access Key defines which environments you have access to and thus which load balancers will be listed and available.
24
+
25
+ ## Examples
26
+
27
+ $ elba list
28
+ 2 ELB found:
29
+ * staging
30
+ * production
31
+
32
+ $ elba list -i
33
+ 2 ELB found:
34
+ * staging
35
+ - i-xxxxxxxx
36
+ - i-yyyyyyyy
37
+ * production
38
+ - i-aaaaaaaa
39
+ - i-bbbbbbbb
40
+ - i-cccccccc
41
+
42
+ $ elba attach i-xxxxxxxx --to staging
43
+ i-xxxxxxxx successfully added to staging
44
+
45
+ $ elba attach i-xxxxxxxx
46
+ More than one ELB available, pick one in the list
47
+ 0 staging
48
+ 1 production
49
+ Use: ["0", "1"] 0
50
+ i-xxxxxxxx is already attached to staging
51
+
52
+ $ elba detach i-xxxxxxxx
53
+ i-xxxxxxxx successfully detached from staging
54
+
55
+ $ elba detach i-xxxxxxxx
56
+ i-xxxxxxxx isn't attached to any known ELB
57
+
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env rake
2
+ require 'bundler/gem_tasks'
3
+ require 'rspec/core/rake_task'
4
+
5
+ desc 'Run all specs'
6
+ RSpec::Core::RakeTask.new(:spec) do |t|
7
+ t.pattern = "spec/**/*_spec.rb"
8
+ end
9
+ task :default => :spec
data/bin/elba ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ lib = File.expand_path('lib')
4
+ $:.unshift(lib) unless $:.include?(lib)
5
+
6
+ require 'elba/cli'
7
+ Elba::Cli.start
data/elba.gemspec ADDED
@@ -0,0 +1,31 @@
1
+ # encoding: UTF-8
2
+
3
+ lib = File.expand_path('lib')
4
+ $:.unshift(lib) unless $:.include?(lib)
5
+
6
+ require 'elba'
7
+
8
+ Gem::Specification.new do |s|
9
+ s.name = "elba"
10
+ s.version = Elba::VERSION
11
+ s.authors = ["Marcus Mitchell", "Mark Connell", "Thibault Gautriaud"]
12
+ s.email = ["marcusleemitchell@gmail.com", "mark@neo.com", "hubbbbb@gmail.com"]
13
+ s.homepage = "https://github.com/housetrip/elba"
14
+ s.summary = "Command-line interface for Amazon's ELB"
15
+ s.description = "Command-line interface for Amazon's ELB"
16
+
17
+ s.add_development_dependency "bundler"
18
+ s.add_development_dependency "rspec"
19
+ s.add_development_dependency "guard-rspec"
20
+ s.add_development_dependency "rake"
21
+ s.add_development_dependency "pry"
22
+ s.add_development_dependency "pry-nav"
23
+
24
+ s.add_dependency "fog"
25
+ s.add_dependency "thor"
26
+
27
+ s.files = `git ls-files`.split("\n")
28
+ s.test_files = `git ls-files -- spec/*/*_spec*`.split("\n")
29
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
30
+ s.require_path = "lib"
31
+ end
data/lib/elba/cli.rb ADDED
@@ -0,0 +1,124 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'thor'
4
+ require 'yaml'
5
+ require 'elba/client'
6
+
7
+ module Elba
8
+ # The Command Line Interface for Elba.
9
+ class Cli < Thor
10
+ include Thor::Actions
11
+
12
+ no_tasks do
13
+ # Parse config stored in ~/.fog
14
+ # Use :default environment
15
+ def config(env = :default)
16
+ @config ||= {}.tap do |c|
17
+ c.merge! YAML.load(File.open File.expand_path('.fog', Dir.home))[env]
18
+ c.merge! region: 'eu-west-1'
19
+ end
20
+ end
21
+
22
+ # A permanent access to a Client
23
+ def client
24
+ @client ||= Client.new config
25
+ end
26
+
27
+ # Helper method to store the ELBs
28
+ def elbs
29
+ @elbs ||= client.load_balancers
30
+ end
31
+
32
+ def elbs_names
33
+ elbs.map(&:id)
34
+ end
35
+
36
+ def elbs_with_index
37
+ elbs.map.with_index { |elb, i| [i, elb.id] }
38
+ end
39
+
40
+ def find_elb(options = {})
41
+ name = options.fetch(:name) { elbs_with_index[options[:choice]].last }
42
+ elbs.find { |elb| elb.id == name }
43
+ end
44
+
45
+ def for_choice
46
+ elbs_with_index.map(&:first).map(&:to_s)
47
+ end
48
+
49
+ def success(message = "")
50
+ say message, :green
51
+ end
52
+
53
+ def warn(message = "")
54
+ say message, :yellow
55
+ end
56
+
57
+ def error(message = "")
58
+ say message, :red
59
+ end
60
+ end
61
+
62
+
63
+ desc "list", "Prints the list of available load balancers"
64
+ option :instances, type: :boolean, aliases: :i, desc: "Prints instances id attached to each load balancer"
65
+ def list(with_instances = options[:instances])
66
+ say "#{elbs.size} ELB found:"
67
+ elbs.map do |elb|
68
+ say " * #{elb.id}"
69
+ elb.instances.map { |i| success " - #{i}" } if with_instances
70
+ end
71
+ end
72
+
73
+
74
+ desc "attach INSTANCES", "Attaches given instances ids to a load balancer"
75
+ option :to, type: :string, aliases: :t, desc: "Specifies which load balancer to use"
76
+ def attach(*instances)
77
+ elb = if options[:to]
78
+ find_elb(name: options[:to])
79
+ else
80
+ case
81
+ when elbs.size == 0
82
+ error "No load balancer available"
83
+ return
84
+ when elbs.size == 1
85
+ warn "Using default load balancer: #{elbs.first.id}"
86
+ elbs.first
87
+ when elbs.size > 1
88
+ warn "You must specify an ELB"
89
+ print_table elbs_with_index
90
+ choice = ask("Use:", :yellow, limited_to: for_choice).to_i
91
+ find_elb(choice: choice)
92
+ end
93
+ end
94
+
95
+ instances.map do |instance|
96
+ client.attach(instance, elb,
97
+ on_success: -> { success "#{instance} successfully attached to #{elb.id}" },
98
+ on_failure: ->(reason) {
99
+ error "Unable to attach #{instance} to #{elb.id}"
100
+ warn "Reason: #{reason}"
101
+ }
102
+ )
103
+ end
104
+ end
105
+
106
+
107
+ desc "detach INSTANCES", "Detach INSTANCES from their Load Balancer"
108
+ def detach(*instances)
109
+ elbs.reload.select { |elb| (elb.instances & instances).any? }.tap do |lbs|
110
+ warn "Unable to find any ELB to detach #{instances.join(', ')}" if lbs.empty?
111
+ lbs.map do |elb|
112
+ target_instances = elb.instances & instances
113
+ client.detach(target_instances, elb,
114
+ on_success: -> { success "#{target_instances.join(', ')} successfully detached from #{elb.id}" },
115
+ on_failure: ->(reason) {
116
+ error "Unable to detach #{target_instances.join(', ')} from #{elb.id}"
117
+ warn "Reason: #{reason}"
118
+ }
119
+ )
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,39 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'fog'
4
+ require 'forwardable'
5
+
6
+ module Elba
7
+ class Client
8
+ extend Forwardable
9
+ attr_reader :connection
10
+
11
+ def initialize(config = {})
12
+ raise "Missing AWS credentials" unless valid_config?(config)
13
+ @connection = Fog::AWS::ELB.new(config)
14
+ end
15
+
16
+ def_delegator :connection, :load_balancers
17
+
18
+ def attach(instance, load_balancer, callbacks = {})
19
+ load_balancer = load_balancer.register_instances instance
20
+ callbacks[:on_success].call if callbacks[:on_success]
21
+ rescue Exception => ex
22
+ callbacks[:on_failure].call(ex) if callbacks[:on_failure]
23
+ end
24
+
25
+ def detach(instances, load_balancer, callbacks = {})
26
+ load_balancer = load_balancer.deregister_instances instances
27
+ callbacks[:on_success].call if callbacks[:on_success]
28
+ rescue Exception => ex
29
+ callbacks[:on_failure].call(ex) if callbacks[:on_failure]
30
+ end
31
+
32
+
33
+ private
34
+
35
+ def valid_config?(config)
36
+ (config.keys & [:aws_secret_access_key, :aws_access_key_id, :region]).any?
37
+ end
38
+ end
39
+ end
data/lib/elba.rb ADDED
@@ -0,0 +1,5 @@
1
+ # encoding: UTF-8
2
+
3
+ module Elba
4
+ VERSION = "0.0.4"
5
+ end
@@ -0,0 +1,212 @@
1
+ require 'spec_helper'
2
+ require 'elba/cli'
3
+
4
+ describe Elba::Cli do
5
+ include Elba::Mocks
6
+
7
+ before :each do
8
+ # Use test config
9
+ subject.stub config: test_config
10
+
11
+ # Create an ELB
12
+ subject.client.connection.create_load_balancer([test_config[:region]], 'elba-test')
13
+ end
14
+
15
+ after :each do
16
+ subject.client.load_balancers.map(&:destroy)
17
+ end
18
+
19
+ let(:elb) { subject.elbs.first }
20
+ let(:instance1) { test_ec2_connection.servers.create region: test_config[:region] }
21
+ let(:instance2) { test_ec2_connection.servers.create region: test_config[:region] }
22
+
23
+ describe 'help' do
24
+
25
+ let(:output) { capture(:stdout) { subject.help } }
26
+
27
+ it "can list" do
28
+ output.should include "list"
29
+ end
30
+
31
+ it "can attach" do
32
+ output.should include "attach"
33
+ end
34
+
35
+ it "can detach" do
36
+ output.should include "detach"
37
+ end
38
+ end
39
+
40
+ describe 'list' do
41
+ it 'prints the list of available ELB' do
42
+ output = capture(:stdout) {
43
+ subject.list
44
+ }
45
+
46
+ output.should include "1 ELB found"
47
+ output.should include " * #{elb.id}"
48
+ end
49
+
50
+ context '--instances' do
51
+ it 'prints instances attached to each load balancer' do
52
+ elb.stub instances: [instance1.id]
53
+
54
+ output = capture(:stdout) {
55
+ subject.list('--instances')
56
+ }
57
+
58
+ output.should include "1 ELB found"
59
+ output.should include " * #{elb.id}"
60
+ output.should include " - #{instance1.id}"
61
+ end
62
+ end
63
+ end
64
+
65
+ describe 'attach' do
66
+ shared_examples_for "asking user" do
67
+ before do
68
+ subject.client.connection.create_load_balancer([test_config[:region]], 'elba-test-2')
69
+ end
70
+
71
+ it 'which load balancer to use' do
72
+ allow(subject).to receive(:ask).and_return("0")
73
+
74
+ output.should include "You must specify an ELB"
75
+ output.should include "successfully"
76
+ end
77
+ end
78
+
79
+ context 'instance1' do
80
+ let(:perform) { subject.attach instance1.id }
81
+ let(:output) { capture(:stdout) { perform } }
82
+
83
+ it 'exits if no ELB available' do
84
+ subject.stub elbs: []
85
+
86
+ output.should include "No load balancer available"
87
+ end
88
+
89
+ it 'uses default ELB when only 1 available' do
90
+ output.should include "Using default load balancer: #{elb.id}"
91
+ output.should include "#{instance1.id} successfully attached to #{elb.id}"
92
+ end
93
+
94
+ it_should_behave_like "asking user"
95
+ end
96
+
97
+ context 'instance1 instance2' do
98
+ let(:perform) { subject.attach instance1.id, instance2.id }
99
+ let(:output) { capture(:stdout) { perform } }
100
+
101
+ it_should_behave_like "asking user"
102
+
103
+ it 'works and reports success' do
104
+ allow(subject).to receive(:ask).and_return("0")
105
+
106
+ output.should include "#{instance1.id} successfully attached to #{elb.id}"
107
+ output.should include "#{instance2.id} successfully attached to #{elb.id}"
108
+ end
109
+ end
110
+
111
+ shared_examples_for "not asking user" do
112
+ before do
113
+ subject.client.connection.create_load_balancer([test_config[:region]], 'elba-test-2')
114
+ end
115
+
116
+ it 'which load balancer to use' do
117
+ allow(subject).to receive(:ask)
118
+
119
+ output.should_not include "No load balancer available"
120
+ output.should_not include "Using default load balancer"
121
+ output.should_not include "You must specify an ELB"
122
+ expect(subject).to_not have_received(:ask)
123
+ end
124
+ end
125
+
126
+ context '--to elb instance1' do
127
+ let(:perform) do
128
+ subject.stub options: {to: elb.id}
129
+ subject.attach instance1.id
130
+ end
131
+
132
+ let(:output) { capture(:stdout) { perform } }
133
+
134
+ it_should_behave_like "not asking user"
135
+
136
+ it 'works and reports success' do
137
+ output.should include "#{instance1.id} successfully attached to #{elb.id}"
138
+ end
139
+ end
140
+
141
+ context '--to elb instance1 instance2' do
142
+ let(:perform) do
143
+ subject.stub options: {to: elb.id}
144
+ subject.attach instance1.id, instance2.id
145
+ end
146
+
147
+ let(:output) { capture(:stdout) { perform } }
148
+
149
+ it_should_behave_like "not asking user"
150
+
151
+ it 'works and reports success' do
152
+ output.should include "#{instance1.id} successfully attached to #{elb.id}"
153
+ output.should include "#{instance2.id} successfully attached to #{elb.id}"
154
+ end
155
+ end
156
+
157
+ end
158
+
159
+ describe 'detach' do
160
+ before do
161
+ silence(:stdout) { subject.client.attach(instance1.id, elb, {}) }
162
+ end
163
+
164
+ let(:output) { capture(:stdout) { perform } }
165
+
166
+ context 'instance1' do
167
+ let(:perform) { subject.detach instance1.id }
168
+
169
+ it 'works and reports success' do
170
+ output.should include "#{instance1.id} successfully detached from #{elb.id}"
171
+ end
172
+ end
173
+
174
+ context 'instance1 instance2' do
175
+ before do
176
+ silence(:stdout) { subject.client.attach(instance2.id, elb) }
177
+ end
178
+
179
+ let(:perform) { subject.detach instance1.id, instance2.id }
180
+
181
+ it 'works and reports success' do
182
+ output.should include "#{instance1.id}, #{instance2.id} successfully detached from #{elb.id}"
183
+ end
184
+
185
+ it 'warn if instances not attached to any ELB' do
186
+ silence(:stdout) { subject.detach instance1.id, instance2.id }
187
+ output.should include "Unable to find any ELB to detach #{instance1.id}, #{instance2.id}"
188
+ end
189
+ end
190
+
191
+ context 'with 3 instances attached to 2 ELBs' do
192
+ let(:instance3) { test_ec2_connection.servers.create region: test_config[:region] }
193
+ let(:elb2) { subject.client.load_balancers.find { |lb| lb.id == 'elba-test-2' } }
194
+
195
+ describe 'detaching all instances at once' do
196
+ before do
197
+ subject.client.connection.create_load_balancer([test_config[:region]], 'elba-test-2')
198
+ silence(:stdout) { subject.client.attach(instance2.id, elb) }
199
+ silence(:stdout) { subject.client.attach(instance3.id, elb2) }
200
+ end
201
+
202
+ let(:output) { capture(:stdout) { subject.detach instance1.id, instance3.id, instance2.id } }
203
+
204
+ it 'works like a charm' do
205
+ output.should include "#{instance1.id}, #{instance2.id} successfully detached from #{elb.id}"
206
+ output.should include "#{instance3.id} successfully detached from #{elb2.id}"
207
+ end
208
+ end
209
+ end
210
+
211
+ end
212
+ end
@@ -0,0 +1,80 @@
1
+ require 'spec_helper'
2
+ require 'elba/client'
3
+
4
+ describe Elba::Client do
5
+ include Elba::Mocks
6
+
7
+ context '.new' do
8
+ it 'raises an error when missing credentials' do
9
+ expect { described_class.new }.to raise_error
10
+ end
11
+ end
12
+
13
+
14
+ describe '(an instance)' do
15
+ subject { described_class.new(test_config) }
16
+ let(:elb) { subject.load_balancers.first }
17
+ let(:ec2) { test_ec2_connection.servers.create region: test_config[:region] }
18
+
19
+ before :each do
20
+ if subject.load_balancers.empty?
21
+ subject.connection.create_load_balancer([test_config[:region]], 'elba-test')
22
+ end
23
+ end
24
+
25
+
26
+ describe '#load_balancers' do
27
+ it 'does not raise NoMethodError' do
28
+ expect(subject).to respond_to(:load_balancers)
29
+ end
30
+
31
+ it 'is delegated to the connection' do
32
+ expect(subject.connection).to receive(:load_balancers)
33
+ subject.load_balancers
34
+ end
35
+ end
36
+
37
+
38
+ describe '#attach' do
39
+ let(:perform) do
40
+ subject.attach(ec2.id, elb,
41
+ on_success: -> { puts 'yay!' },
42
+ on_failure: ->(x) { puts 'doh!' }
43
+ )
44
+ end
45
+
46
+ it '(on success) executes success callback' do
47
+ capture(:stdout) { perform }.should include 'yay!'
48
+ end
49
+
50
+ it '(on failure) executes failure callback' do
51
+ allow(elb).to receive(:register_instances).and_raise(Exception)
52
+ capture(:stdout) { perform }.should include 'doh!'
53
+ end
54
+ end
55
+
56
+
57
+ describe '#detach' do
58
+ before :each do
59
+ subject.attach(ec2.id, elb, {})
60
+ end
61
+
62
+ let(:perform) do
63
+ subject.detach(ec2.id, elb,
64
+ on_success: -> { puts 'yay!' },
65
+ on_failure: ->(x) { puts 'doh!' }
66
+ )
67
+ end
68
+
69
+ it '(on success) executes success callback' do
70
+ capture(:stdout) { perform }.should include 'yay!'
71
+ end
72
+
73
+ it '(on failure) executes failure callback' do
74
+ allow(elb).to receive(:deregister_instances).and_raise(Exception)
75
+ capture(:stdout) { perform }.should include 'doh!'
76
+ end
77
+ end
78
+
79
+ end
80
+ end
@@ -0,0 +1,47 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'rspec'
4
+ require 'elba'
5
+ require 'support/mocks'
6
+
7
+ RSpec.configure do |config|
8
+ config.before(:each) do
9
+ # Pretend we're running as 'elba'
10
+ $0 = "elba"
11
+
12
+ # Tell Fog to use mocks
13
+ Fog.mock! unless Fog.mocking?
14
+ end
15
+
16
+ # Captures the output for analysis later
17
+ #
18
+ # @example Capture `$stderr`
19
+ #
20
+ # output = capture(:stderr) { $stderr.puts "this is captured" }
21
+ #
22
+ # @param [Symbol] stream `:stdout` or `:stderr`
23
+ # @yield The block to capture stdout/stderr for.
24
+ # @return [String] The contents of $stdout or $stderr
25
+ def capture(stream)
26
+ begin
27
+ stream = stream.to_s
28
+ eval "$#{stream} = StringIO.new"
29
+ yield
30
+ result = eval("$#{stream}").string
31
+ ensure
32
+ eval("$#{stream} = #{stream.upcase}")
33
+ end
34
+
35
+ result
36
+ end
37
+
38
+ # Silences the output stream
39
+ #
40
+ # @example Silence `$stdout`
41
+ #
42
+ # silence(:stdout) { $stdout.puts "hi" }
43
+ #
44
+ # @param [IO] stream The stream to use such as $stderr or $stdout
45
+ # @return [nil]
46
+ alias :silence :capture
47
+ end
@@ -0,0 +1,20 @@
1
+ module Elba
2
+ module Mocks
3
+ def test_config
4
+ {
5
+ region: 'eu-west-1',
6
+ aws_access_key_id: 'JUST',
7
+ aws_secret_access_key: 'TESTING'
8
+ }
9
+ end
10
+
11
+ def test_elb_connection
12
+ @connection ||= Fog::AWS::ELB.new(test_config)
13
+ end
14
+
15
+ def test_ec2_connection
16
+ @ec2 ||= Fog::Compute::AWS.new(test_config)
17
+ end
18
+
19
+ end
20
+ end
Binary file
metadata ADDED
@@ -0,0 +1,205 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: elba
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.4
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Marcus Mitchell
9
+ - Mark Connell
10
+ - Thibault Gautriaud
11
+ autorequire:
12
+ bindir: bin
13
+ cert_chain: []
14
+ date: 2014-01-10 00:00:00.000000000 Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: bundler
18
+ requirement: !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ! '>='
22
+ - !ruby/object:Gem::Version
23
+ version: '0'
24
+ type: :development
25
+ prerelease: false
26
+ version_requirements: !ruby/object:Gem::Requirement
27
+ none: false
28
+ requirements:
29
+ - - ! '>='
30
+ - !ruby/object:Gem::Version
31
+ version: '0'
32
+ - !ruby/object:Gem::Dependency
33
+ name: rspec
34
+ requirement: !ruby/object:Gem::Requirement
35
+ none: false
36
+ requirements:
37
+ - - ! '>='
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ - !ruby/object:Gem::Dependency
49
+ name: guard-rspec
50
+ requirement: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ! '>='
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ - !ruby/object:Gem::Dependency
65
+ name: rake
66
+ requirement: !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ! '>='
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ type: :development
73
+ prerelease: false
74
+ version_requirements: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ! '>='
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ - !ruby/object:Gem::Dependency
81
+ name: pry
82
+ requirement: !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ! '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ - !ruby/object:Gem::Dependency
97
+ name: pry-nav
98
+ requirement: !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ! '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ! '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ - !ruby/object:Gem::Dependency
113
+ name: fog
114
+ requirement: !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ! '>='
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ type: :runtime
121
+ prerelease: false
122
+ version_requirements: !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ! '>='
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
128
+ - !ruby/object:Gem::Dependency
129
+ name: thor
130
+ requirement: !ruby/object:Gem::Requirement
131
+ none: false
132
+ requirements:
133
+ - - ! '>='
134
+ - !ruby/object:Gem::Version
135
+ version: '0'
136
+ type: :runtime
137
+ prerelease: false
138
+ version_requirements: !ruby/object:Gem::Requirement
139
+ none: false
140
+ requirements:
141
+ - - ! '>='
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ description: Command-line interface for Amazon's ELB
145
+ email:
146
+ - marcusleemitchell@gmail.com
147
+ - mark@neo.com
148
+ - hubbbbb@gmail.com
149
+ executables:
150
+ - elba
151
+ extensions: []
152
+ extra_rdoc_files: []
153
+ files:
154
+ - .gitignore
155
+ - .ruby-version
156
+ - .travis.yml
157
+ - Gemfile
158
+ - Gemfile.lock
159
+ - Guardfile
160
+ - LICENSE
161
+ - README.md
162
+ - Rakefile
163
+ - bin/elba
164
+ - elba.gemspec
165
+ - lib/elba.rb
166
+ - lib/elba/cli.rb
167
+ - lib/elba/client.rb
168
+ - spec/lib/elba/cli_spec.rb
169
+ - spec/lib/elba/client_spec.rb
170
+ - spec/spec_helper.rb
171
+ - spec/support/mocks.rb
172
+ - vendor/excon-0.27.6.gem
173
+ homepage: https://github.com/housetrip/elba
174
+ licenses: []
175
+ post_install_message:
176
+ rdoc_options: []
177
+ require_paths:
178
+ - lib
179
+ required_ruby_version: !ruby/object:Gem::Requirement
180
+ none: false
181
+ requirements:
182
+ - - ! '>='
183
+ - !ruby/object:Gem::Version
184
+ version: '0'
185
+ segments:
186
+ - 0
187
+ hash: 4477547734981746383
188
+ required_rubygems_version: !ruby/object:Gem::Requirement
189
+ none: false
190
+ requirements:
191
+ - - ! '>='
192
+ - !ruby/object:Gem::Version
193
+ version: '0'
194
+ segments:
195
+ - 0
196
+ hash: 4477547734981746383
197
+ requirements: []
198
+ rubyforge_project:
199
+ rubygems_version: 1.8.25
200
+ signing_key:
201
+ specification_version: 3
202
+ summary: Command-line interface for Amazon's ELB
203
+ test_files:
204
+ - spec/lib/elba/cli_spec.rb
205
+ - spec/lib/elba/client_spec.rb