blimpy 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,4 +1,5 @@
1
1
  # Blimpy
2
+ [![Build Status](https://buildhive.cloudbees.com/job/rtyler/job/blimpy/badge/icon)](https://buildhive.cloudbees.com/job/rtyler/job/blimpy/)
2
3
 
3
4
  ![Excelsior!](http://strongspace.com/rtyler/public/excelsior.png)
4
5
 
@@ -17,7 +18,7 @@ Here's an example Blimpfile:
17
18
 
18
19
  ```ruby
19
20
  Blimpy.fleet do |fleet|
20
- fleet.add do |ship|
21
+ fleet.add(:aws) do |ship|
21
22
  ship.image_id = 'ami-349b495d'
22
23
  ship.livery = 'rails'
23
24
  ship.group = 'Simple' # [Required] The name of the desired Security Group
data/Rakefile CHANGED
@@ -28,3 +28,5 @@ namespace :test do
28
28
  task :all => [:spec, :'cucumber:basic', :'cucumber:integration']
29
29
  end
30
30
 
31
+
32
+ task :default => :test
@@ -7,7 +7,7 @@ Feature: SCP a file into a named VM
7
7
  Given I have the Blimpfile:
8
8
  """
9
9
  Blimpy.fleet do |f|
10
- f.add do |host|
10
+ f.add(:aws) do |host|
11
11
  host.name = 'Cucumber Host'
12
12
  end
13
13
  end
@@ -27,7 +27,7 @@ Feature: SCP a file into a named VM
27
27
  Given I have the Blimpfile:
28
28
  """
29
29
  Blimpy.fleet do |f|
30
- f.add do |host|
30
+ f.add(:aws) do |host|
31
31
  host.name = 'Cucumber Host'
32
32
  end
33
33
  end
@@ -7,7 +7,7 @@ Feature: SSH into a named VM
7
7
  Given I have the Blimpfile:
8
8
  """
9
9
  Blimpy.fleet do |f|
10
- f.add do |host|
10
+ f.add(:aws) do |host|
11
11
  host.name = 'Cucumber Host'
12
12
  end
13
13
  end
@@ -27,7 +27,7 @@ Feature: SSH into a named VM
27
27
  Given I have the Blimpfile:
28
28
  """
29
29
  Blimpy.fleet do |f|
30
- f.add do |host|
30
+ f.add(:aws) do |host|
31
31
  host.group = 'Simple'
32
32
  host.name = 'Cucumber Host'
33
33
  end
@@ -13,7 +13,7 @@ Feature: Start a VM or cluster of VMs in the cloud
13
13
  Given I have the Blimpfile:
14
14
  """
15
15
  Blimpy.fleet do |f|
16
- f.add do |host|
16
+ f.add(:aws) do |host|
17
17
  host.group = 'Simple'
18
18
  host.name = 'Cucumber Host'
19
19
  end
@@ -31,7 +31,7 @@ Feature: Start a VM or cluster of VMs in the cloud
31
31
  Given I have the Blimpfile:
32
32
  """
33
33
  Blimpy.fleet do |f|
34
- f.add do |host|
34
+ f.add(:aws) do |host|
35
35
  host.group = 'Simple'
36
36
  host.name = 'Cucumber Host'
37
37
  end
@@ -47,3 +47,24 @@ Feature: Start a VM or cluster of VMs in the cloud
47
47
  """
48
48
  online at:
49
49
  """
50
+
51
+ @slow @destroy @openstack @wip
52
+ Scenario: start with an OpenStack Blimpfile
53
+ Given I have the Blimpfile:
54
+ """
55
+ Blimpy.fleet do |f|
56
+ f.add(:openstack) do |host|
57
+ host.name = 'Cucumber Host'
58
+ end
59
+ end
60
+ """
61
+ When I run `blimpy start`
62
+ Then the exit status should be 0
63
+ And the output should contain:
64
+ """
65
+ Up, up and away!
66
+ """
67
+ And the output should contain:
68
+ """
69
+ online at:
70
+ """
data/lib/blimpy.rb CHANGED
@@ -21,4 +21,6 @@ module Blimpy
21
21
  end
22
22
  class SSHKeyNotFoundError < Exception
23
23
  end
24
+ class InvalidShipException < Exception
25
+ end
24
26
  end
data/lib/blimpy/box.rb CHANGED
@@ -1,42 +1,37 @@
1
1
  require 'blimpy/helpers/state'
2
2
  require 'blimpy/livery'
3
3
  require 'blimpy/keys'
4
+ require 'blimpy/boxes'
4
5
 
5
6
  module Blimpy
6
7
  class Box
7
8
  include Blimpy::Helpers::State
8
9
 
9
- # Default to US West (Oregon)
10
- DEFAULT_REGION = 'us-west-2'
11
- # Default to 10.04 64-bit
12
- DEFAULT_IMAGE_ID = 'ami-ec0b86dc'
13
-
14
10
  attr_reader :allowed_regions, :region
15
11
  attr_accessor :image_id, :livery, :group, :server
16
12
  attr_accessor :name, :tags, :fleet_id, :username
17
13
 
18
- def self.fog_server_for_instance(id, blimpdata)
19
- region = blimpdata['region'] || DEFAULT_REGION
20
- fog = Fog::Compute.new(:provider => 'AWS', :region => region)
21
- fog.servers.get(id)
22
- end
23
14
 
24
15
  def self.from_instance_id(an_id, data)
25
- server = self.fog_server_for_instance(an_id, data)
16
+ return if data['type'].nil?
17
+
18
+ name = data['type'].upcase.to_sym
19
+ return unless Blimpy::Boxes.const_defined? name
20
+
21
+ klass = Blimpy::Boxes.const_get(name)
22
+
23
+ server = klass.fog_server_for_instance(an_id, data)
26
24
  return if server.nil?
27
- box = self.new(server)
25
+
26
+ box = klass.new(server)
28
27
  box.name = data['name']
29
28
  box
30
29
  end
31
30
 
32
31
  def initialize(server=nil)
33
- @allowed_regions = ['us-west-1', 'us-west-2', 'us-east-1']
34
- @region = DEFAULT_REGION
35
- @image_id = DEFAULT_IMAGE_ID
36
32
  @livery = nil
37
33
  @group = nil
38
34
  @name = 'Unnamed Box'
39
- @username = 'ubuntu'
40
35
  @tags = {}
41
36
  @server = server
42
37
  @fleet_id = 0
@@ -45,18 +40,12 @@ module Blimpy
45
40
  end
46
41
 
47
42
  def region=(newRegion)
48
- unless @allowed_regions.include? newRegion
43
+ unless (@allowed_regions.nil?) || (@allowed_regions.include?(newRegion))
49
44
  raise InvalidRegionError
50
45
  end
51
46
  @region = newRegion
52
47
  end
53
48
 
54
- def validate!
55
- if Fog::Compute[:aws].security_groups.get(@group).nil?
56
- raise BoxValidationError
57
- end
58
- end
59
-
60
49
  def online!
61
50
  File.open(state_file, 'a') do |f|
62
51
  f.write("dns: #{@server.dns_name}\n")
@@ -64,6 +53,10 @@ module Blimpy
64
53
  end
65
54
  end
66
55
 
56
+ def validate!
57
+ raise NotImplementedError, '#validate! should be defined in a subclass of Blimpy::Box'
58
+ end
59
+
67
60
  def start
68
61
  ensure_state_folder
69
62
  @server = create_host
@@ -99,6 +92,9 @@ module Blimpy
99
92
 
100
93
  def write_state_file
101
94
  File.open(state_file, 'w') do |f|
95
+ # We only really care about the class name as part of the Blimpy::Boxes
96
+ # module
97
+ f.write("type: #{self.class.to_s.split('::').last}\n")
102
98
  f.write("name: #{@name}\n")
103
99
  f.write("region: #{@region}\n")
104
100
  end
@@ -0,0 +1,5 @@
1
+
2
+ module Blimpy
3
+ module Boxes
4
+ end
5
+ end
@@ -0,0 +1,31 @@
1
+ require 'blimpy/box'
2
+ require 'blimpy/boxes'
3
+
4
+ module Blimpy::Boxes
5
+ class AWS < Blimpy::Box
6
+ # Default to US West (Oregon)
7
+ DEFAULT_REGION = 'us-west-2'
8
+ # Default to 10.04 64-bit
9
+ DEFAULT_IMAGE_ID = 'ami-ec0b86dc'
10
+
11
+ def self.fog_server_for_instance(id, blimpdata)
12
+ region = blimpdata['region'] || DEFAULT_REGION
13
+ fog = Fog::Compute.new(:provider => 'AWS', :region => region)
14
+ fog.servers.get(id)
15
+ end
16
+
17
+ def initialize(server=nil)
18
+ super(server)
19
+ @allowed_regions = ['us-west-1', 'us-west-2', 'us-east-1']
20
+ @region = DEFAULT_REGION
21
+ @image_id = DEFAULT_IMAGE_ID
22
+ @username = 'ubuntu'
23
+ end
24
+
25
+ def validate!
26
+ if Fog::Compute[:aws].security_groups.get(@group).nil?
27
+ raise Blimpy::BoxValidationError
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,12 @@
1
+ require 'blimpy/box'
2
+ require 'blimpy/boxes'
3
+
4
+ module Blimpy::Boxes
5
+ class OpenStack < Blimpy::Box
6
+ def self.fog_server_for_instance(id, blimpdata)
7
+ region = blimpdata['region']
8
+ fog = Fog::Compute.new(:provider => 'OpenStack', :region => region)
9
+ fog.servers.get(id)
10
+ end
11
+ end
12
+ end
data/lib/blimpy/fleet.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'blimpy/helpers/state'
2
+ require 'blimpy/boxes/aws'
2
3
 
3
4
  module Blimpy
4
5
  class Fleet
@@ -11,11 +12,23 @@ module Blimpy
11
12
  @id = Time.now.utc.to_i
12
13
  end
13
14
 
14
- def add(&block)
15
+ def valid_types
16
+ [:aws]
17
+ end
18
+
19
+ def add(box_type, &block)
20
+ unless valid_types.include? box_type
21
+ raise Blimpy::InvalidShipException
22
+ end
15
23
  if block.nil?
16
24
  return false
17
25
  end
18
- box = Blimpy::Box.new
26
+
27
+ box = Blimpy::Boxes::AWS.new
28
+
29
+ if box.nil?
30
+ return false
31
+ end
19
32
  box.fleet_id = @id
20
33
  @ships << box
21
34
  block.call(box)
@@ -1,3 +1,3 @@
1
1
  module Blimpy
2
- VERSION = "0.2.1"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -1,11 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Blimpy::Box do
4
- describe '#image_id' do
5
- it 'should be the Ubuntu 10.04 AMI ID by default' do
6
- subject.image_id.should == Blimpy::Box::DEFAULT_IMAGE_ID
7
- end
8
- end
9
4
 
10
5
  describe '#livery' do
11
6
  it 'should be unset by default' do
@@ -25,65 +20,11 @@ describe Blimpy::Box do
25
20
  end
26
21
  end
27
22
 
28
- describe '#allowed_regions' do
29
- it 'should be an Array' do
30
- subject.allowed_regions.should be_instance_of Array
31
- end
32
- it 'should not be empty' do
33
- subject.allowed_regions.should_not be_empty
34
- end
35
- end
36
-
37
- describe '#region' do
38
- it 'should return the default region' do
39
- subject.region.should == 'us-west-2'
40
- end
41
- end
42
-
43
- describe '#region=' do
44
- it 'should raise an InvalidRegionError if the region is not allowed' do
45
- expect {
46
- subject.region = :elbonia
47
- }.to raise_error(Blimpy::InvalidRegionError)
48
- end
49
-
50
- it 'should change the value of @region' do
51
- subject.region = 'us-east-1'
52
- subject.region.should == 'us-east-1'
53
- end
54
- end
55
-
56
23
  describe '#validate!' do
57
- let(:security_group) do
58
- group = double('Fog::Compute::AWS::SecurityGroup')
59
- group.stub(:name).and_return('MockedGroup')
60
- group
61
- end
62
- let(:groups) { double('Fog::Compute::AWS::SecurityGroups') }
63
-
64
- before :each do
65
- # Fog::Compute[:aws] will return a *new* instance of
66
- # Fog::Compute::Aws::Real every time (apparently) it is invoked
67
- Fog::Compute::AWS::Real.any_instance.should_receive(:security_groups).and_return(groups)
68
- end
69
-
70
- context 'with invalid settings' do
71
- it 'should raise with a bad security group' do
72
- groups.should_receive(:get).and_return(nil)
73
- expect {
74
- subject.validate!
75
- }.to raise_error(Blimpy::BoxValidationError)
76
- end
77
- end
78
-
79
- context 'with valid settings' do
80
- it 'should validate with a good security group' do
81
- groups.should_receive(:get).with('MockedGroup').and_return(security_group)
82
- expect {
83
- subject.group = 'MockedGroup'
84
- subject.validate!
85
- }.not_to raise_error(Blimpy::BoxValidationError)
86
- end
24
+ it 'should raise a NotImplementedError, since this should be defined by subclasses' do
25
+ expect {
26
+ subject.validate!
27
+ }.to raise_error(NotImplementedError)
87
28
  end
88
29
  end
89
30
 
@@ -136,14 +77,27 @@ describe Blimpy::Box do
136
77
 
137
78
  describe '#from_instance_id' do
138
79
  let(:fog) { double('Fog::Compute') }
139
- before :each do
140
- fog.stub_chain(:servers, :get).and_return(server)
141
- Fog::Compute.should_receive(:new).and_return(fog)
142
- end
143
80
 
144
- it 'should create a new Box instance' do
81
+ it 'should fail if no "type" exists' do
145
82
  result = Blimpy::Box.from_instance_id('someid', {})
146
- result.should be_instance_of Blimpy::Box
83
+ result.should be_nil
84
+ end
85
+
86
+ it 'should fail if the "type" is not a defined Box class' do
87
+ result = Blimpy::Box.from_instance_id('someid', {'type' => 'MAGIC'})
88
+ result.should be_nil
89
+ end
90
+
91
+ context 'with an AWS box type' do
92
+ before :each do
93
+ fog.stub_chain(:servers, :get).and_return(server)
94
+ Fog::Compute.should_receive(:new).and_return(fog)
95
+ end
96
+
97
+ it 'should create a new AWS Box instance' do
98
+ result = Blimpy::Box.from_instance_id('someid', {'type' => 'AWS'})
99
+ result.should be_instance_of Blimpy::Boxes::AWS
100
+ end
147
101
  end
148
102
 
149
103
  end
@@ -0,0 +1,70 @@
1
+ require 'spec_helper'
2
+ require 'blimpy/boxes/aws'
3
+
4
+ describe Blimpy::Boxes::AWS do
5
+ describe '#image_id' do
6
+ it 'should be the Ubuntu 10.04 AMI ID by default' do
7
+ subject.image_id.should == Blimpy::Boxes::AWS::DEFAULT_IMAGE_ID
8
+ end
9
+ end
10
+
11
+ describe '#allowed_regions' do
12
+ it 'should be an Array' do
13
+ subject.allowed_regions.should be_instance_of Array
14
+ end
15
+ it 'should not be empty' do
16
+ subject.allowed_regions.should_not be_empty
17
+ end
18
+ end
19
+
20
+ describe '#region' do
21
+ it 'should return the default region' do
22
+ subject.region.should == 'us-west-2'
23
+ end
24
+ end
25
+
26
+ describe '#region=' do
27
+ it 'should raise an InvalidRegionError if the region is not allowed' do
28
+ expect {
29
+ subject.region = :elbonia
30
+ }.to raise_error(Blimpy::InvalidRegionError)
31
+ end
32
+
33
+ it 'should change the value of @region' do
34
+ subject.region = 'us-east-1'
35
+ subject.region.should == 'us-east-1'
36
+ end
37
+ end
38
+
39
+ describe '#validate!' do
40
+ let(:security_group) do
41
+ group = double('Fog::Compute::AWS::SecurityGroup')
42
+ group.stub(:name).and_return('MockedGroup')
43
+ group
44
+ end
45
+ let(:groups) { double('Fog::Compute::AWS::SecurityGroups') }
46
+
47
+ before :each do
48
+ Fog::Compute.stub_chain(:[], :security_groups).and_return(groups)
49
+ end
50
+
51
+ context 'with invalid settings' do
52
+ it 'should raise with a bad security group' do
53
+ groups.should_receive(:get).and_return(nil)
54
+ expect {
55
+ subject.validate!
56
+ }.to raise_error(Blimpy::BoxValidationError)
57
+ end
58
+ end
59
+
60
+ context 'with valid settings' do
61
+ it 'should validate with a good security group' do
62
+ groups.should_receive(:get).with('MockedGroup').and_return(security_group)
63
+ expect {
64
+ subject.group = 'MockedGroup'
65
+ subject.validate!
66
+ }.not_to raise_error(Blimpy::BoxValidationError)
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+ require 'blimpy/boxes/openstack'
3
+
4
+ describe Blimpy::Boxes::OpenStack do
5
+ describe '#image_id' do
6
+ it 'should be nil by default' do
7
+ subject.image_id.should be_nil
8
+ end
9
+ end
10
+
11
+ describe '#allowed_regions' do
12
+ it 'should be nil by default' do
13
+ subject.allowed_regions.should be_nil
14
+ end
15
+ end
16
+
17
+ describe '#region=' do
18
+ it 'should not raise an InvalidRegionError if no allowed_regions exist' do
19
+ subject.stub(:allowed_regions).and_return(nil)
20
+ subject.region = :elbonia
21
+ subject.region.should == :elbonia
22
+ end
23
+ end
24
+ end
@@ -31,7 +31,7 @@ describe Blimpy::Engine do
31
31
  let(:content) do
32
32
  """
33
33
  Blimpy.fleet do |fleet|
34
- fleet.add do |ship|
34
+ fleet.add(:aws) do |ship|
35
35
  ship.image_id = 'ami-349b495d'
36
36
  ship.livery = 'rails'
37
37
  ship.group = 'Simple'
@@ -9,29 +9,39 @@ describe Blimpy::Fleet do
9
9
  end
10
10
 
11
11
  describe '#add' do
12
- it 'should return false if no Box was properly added' do
13
- subject.add.should == false
12
+ context 'with invalid parameters' do
13
+ it 'should raise an InvalidShipException' do
14
+ expect {
15
+ subject.add(:submarine)
16
+ }.to raise_error(Blimpy::InvalidShipException)
17
+ end
14
18
  end
15
19
 
16
- it 'should pass a Box instance to the block' do
17
- invoked_block = false
18
- subject.add do |box|
19
- invoked_block = true
20
- box.should be_instance_of Blimpy::Box
20
+ context 'with valid parameters' do
21
+ it 'should return false if no Box was properly added' do
22
+ subject.add(:aws).should == false
21
23
  end
22
- invoked_block.should be true
23
- end
24
24
 
25
- context 'with a block' do
26
- before :each do
27
- subject.add do |b|
28
- @box = b
25
+ it 'should pass a Box instance to the block' do
26
+ invoked_block = false
27
+ subject.add(:aws) do |box|
28
+ invoked_block = true
29
+ box.should be_a Blimpy::Box
29
30
  end
31
+ invoked_block.should be true
30
32
  end
31
33
 
32
- it 'should add the box the fleet' do
33
- @box.should_not be nil
34
- subject.ships.should include(@box)
34
+ context 'with a block' do
35
+ before :each do
36
+ subject.add(:aws) do |b|
37
+ @box = b
38
+ end
39
+ end
40
+
41
+ it 'should add the box the fleet' do
42
+ @box.should_not be nil
43
+ subject.ships.should include(@box)
44
+ end
35
45
  end
36
46
  end
37
47
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: blimpy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-29 00:00:00.000000000Z
12
+ date: 2012-05-19 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: fog
16
- requirement: &5775980 !ruby/object:Gem::Requirement
16
+ requirement: &20178020 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *5775980
24
+ version_requirements: *20178020
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: thor
27
- requirement: &5775440 !ruby/object:Gem::Requirement
27
+ requirement: &20177600 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *5775440
35
+ version_requirements: *20177600
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: minitar
38
- requirement: &5774900 !ruby/object:Gem::Requirement
38
+ requirement: &20177180 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,7 +43,7 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *5774900
46
+ version_requirements: *20177180
47
47
  description: Blimpy is a tool for managing a fleet of machines in the CLOUD!
48
48
  email:
49
49
  - tyler@monkeypox.org
@@ -69,6 +69,9 @@ files:
69
69
  - features/support/hooks.rb
70
70
  - lib/blimpy.rb
71
71
  - lib/blimpy/box.rb
72
+ - lib/blimpy/boxes.rb
73
+ - lib/blimpy/boxes/aws.rb
74
+ - lib/blimpy/boxes/openstack.rb
72
75
  - lib/blimpy/cli.rb
73
76
  - lib/blimpy/engine.rb
74
77
  - lib/blimpy/fleet.rb
@@ -77,6 +80,8 @@ files:
77
80
  - lib/blimpy/livery.rb
78
81
  - lib/blimpy/version.rb
79
82
  - spec/blimpy/box_spec.rb
83
+ - spec/blimpy/boxes/aws_spec.rb
84
+ - spec/blimpy/boxes/openstack_spec.rb
80
85
  - spec/blimpy/engine_spec.rb
81
86
  - spec/blimpy/fleet_spec.rb
82
87
  - spec/blimpy/helpers/state_spec.rb
@@ -118,6 +123,8 @@ test_files:
118
123
  - features/support/env.rb
119
124
  - features/support/hooks.rb
120
125
  - spec/blimpy/box_spec.rb
126
+ - spec/blimpy/boxes/aws_spec.rb
127
+ - spec/blimpy/boxes/openstack_spec.rb
121
128
  - spec/blimpy/engine_spec.rb
122
129
  - spec/blimpy/fleet_spec.rb
123
130
  - spec/blimpy/helpers/state_spec.rb