dew 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +22 -0
- data/README.md +38 -0
- data/Rakefile +26 -0
- data/bin/dew +87 -0
- data/config/cucumber.yaml +4 -0
- data/features/create-ami.feature +16 -0
- data/features/create-environments.feature +46 -0
- data/features/deploy-puge.feature +16 -0
- data/features/step_definitions/aws-steps.rb +101 -0
- data/features/step_definitions/deploy-puge-steps.rb +27 -0
- data/features/support/env.rb +38 -0
- data/features/support/hooks.rb +10 -0
- data/lib/dew.rb +7 -0
- data/lib/dew/aws_resources.yaml +122 -0
- data/lib/dew/base_command.rb +24 -0
- data/lib/dew/cloud.rb +79 -0
- data/lib/dew/commands.rb +6 -0
- data/lib/dew/commands/ami.rb +67 -0
- data/lib/dew/commands/console.rb +17 -0
- data/lib/dew/commands/console/irb_override.rb +24 -0
- data/lib/dew/commands/deploy.rb +114 -0
- data/lib/dew/commands/deploy/templates/apache.conf.erb +28 -0
- data/lib/dew/commands/deploy/templates/known_hosts +2 -0
- data/lib/dew/commands/deploy/templates/rvmrc +2 -0
- data/lib/dew/commands/environments.rb +110 -0
- data/lib/dew/commands/tidy.rb +35 -0
- data/lib/dew/controllers.rb +3 -0
- data/lib/dew/controllers/amis_controller.rb +82 -0
- data/lib/dew/controllers/deploy_controller.rb +10 -0
- data/lib/dew/controllers/environments_controller.rb +48 -0
- data/lib/dew/models.rb +7 -0
- data/lib/dew/models/account.rb +30 -0
- data/lib/dew/models/database.rb +32 -0
- data/lib/dew/models/deploy.rb +2 -0
- data/lib/dew/models/deploy/puge.rb +61 -0
- data/lib/dew/models/deploy/run.rb +19 -0
- data/lib/dew/models/environment.rb +199 -0
- data/lib/dew/models/fog_model.rb +23 -0
- data/lib/dew/models/profile.rb +60 -0
- data/lib/dew/models/server.rb +134 -0
- data/lib/dew/password.rb +7 -0
- data/lib/dew/tasks/spec.rake +14 -0
- data/lib/dew/validations.rb +8 -0
- data/lib/dew/version.rb +3 -0
- data/lib/dew/view.rb +39 -0
- data/lib/tasks/spec.rake +14 -0
- data/spec/dew/cloud_spec.rb +90 -0
- data/spec/dew/controllers/amis_controller_spec.rb +137 -0
- data/spec/dew/controllers/deploy_controller_spec.rb +38 -0
- data/spec/dew/controllers/environments_controller_spec.rb +133 -0
- data/spec/dew/models/account_spec.rb +47 -0
- data/spec/dew/models/database_spec.rb +58 -0
- data/spec/dew/models/deploy/puge_spec.rb +72 -0
- data/spec/dew/models/deploy/run_spec.rb +38 -0
- data/spec/dew/models/environment_spec.rb +374 -0
- data/spec/dew/models/fog_model_spec.rb +24 -0
- data/spec/dew/models/profile_spec.rb +85 -0
- data/spec/dew/models/server_spec.rb +190 -0
- data/spec/dew/password_spec.rb +11 -0
- data/spec/dew/spec_helper.rb +22 -0
- data/spec/dew/view_spec.rb +38 -0
- metadata +284 -0
@@ -0,0 +1,47 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '../spec_helper'))
|
2
|
+
|
3
|
+
describe Account do
|
4
|
+
|
5
|
+
describe :initialize do
|
6
|
+
it "should look for the named account file in the ~/.dew/accounts dir" do
|
7
|
+
name = 'a_development_name'
|
8
|
+
File.should_receive(:read).with("#{ENV['HOME']}/.dew/accounts/#{name}.yaml").and_return("---")
|
9
|
+
Account.read(name)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "parsing yaml" do
|
14
|
+
before :each do
|
15
|
+
yaml =
|
16
|
+
"aws:
|
17
|
+
user_id: 9999-3333-2222
|
18
|
+
access_key_id: foo
|
19
|
+
secret_access_key: bar"
|
20
|
+
|
21
|
+
File.stub(:read).and_return(yaml)
|
22
|
+
@account = Account.read('foo')
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should have a user_id stripped of dashes" do
|
26
|
+
@account.aws_user_id.should == '999933332222'
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should have an aws access key id" do
|
30
|
+
@account.aws_access_key_id.should == 'foo'
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should have an aws secret access key" do
|
34
|
+
@account.aws_secret_access_key.should == 'bar'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe ".user_ids" do
|
39
|
+
it "should return the user_ids of each account file in config/accounts" do
|
40
|
+
Dir.should_receive(:[]).with("#{ENV['HOME']}/.dew/accounts/*.yaml").and_return(["accounts/file1.yaml", "accounts/file2.yaml"])
|
41
|
+
Account.should_receive(:read).with("file1").and_return(double('account', :aws_user_id => 'id1'))
|
42
|
+
Account.should_receive(:read).with("file2").and_return(double('account', :aws_user_id => 'id2'))
|
43
|
+
Account.user_ids.sort.should == ['id1', 'id2']
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '../spec_helper'))
|
2
|
+
|
3
|
+
describe Database do
|
4
|
+
|
5
|
+
let (:rds) { double('RDS', :servers => double('RDSServers')) }
|
6
|
+
let (:id) { 'mydatabase' }
|
7
|
+
let (:fog_database) { double('FogDatabase', :id => id) }
|
8
|
+
|
9
|
+
before :each do
|
10
|
+
Cloud.stub(:rds => rds)
|
11
|
+
rds.servers.stub(:create => fog_database)
|
12
|
+
end
|
13
|
+
|
14
|
+
describe ".create!" do
|
15
|
+
it "should ask Fog to create a new RDS with the provided name, size, username and password" do
|
16
|
+
rds.servers.should_receive(:create).with(hash_including(:id => id, :flavor_id => 'db.m1.small', :master_username => 'root', :password => 'password'))
|
17
|
+
Database.create!(id, 'db.m1.small', 'password')
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should return a new Database object with an ID" do
|
21
|
+
database = Database.create!(id, 'b', 'd')
|
22
|
+
database.id.should == id
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe ".get" do
|
27
|
+
it "should return nil if the database doesn't exist" do
|
28
|
+
rds.servers.should_receive(:get).with(id).and_return nil
|
29
|
+
Database.get(id).should == nil
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should return a Database object if the database does exist" do
|
33
|
+
rds.servers.should_receive(:get).with(id).and_return fog_database
|
34
|
+
Database.get(id).id.should == id
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
context "with a database created" do
|
40
|
+
before :each do
|
41
|
+
@database = Database.create!(id, 'db.m1.small', 'password')
|
42
|
+
fog_database.stub(:endpoint => {'Address' => '127.0.0.1'}, :master_username => 'root')
|
43
|
+
end
|
44
|
+
describe "db_environment_file" do
|
45
|
+
it "should return the contents of a file to use as /etc/environment that can be used to connct to this database" do
|
46
|
+
data = @database.db_environment_file('password')
|
47
|
+
data.should =~ /PUGE_DB_NAME=#{id}/
|
48
|
+
data.should =~ /PUGE_DB_USERNAME=root/
|
49
|
+
data.should =~ /PUGE_DB_PASSWORD=password/
|
50
|
+
data.should =~ /PUGE_DB_HOST=127.0.0.1/
|
51
|
+
end
|
52
|
+
end
|
53
|
+
describe :public_address do
|
54
|
+
it {@database.public_address.should == '127.0.0.1'}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '../../spec_helper'))
|
2
|
+
|
3
|
+
describe Deploy::Puge do
|
4
|
+
|
5
|
+
let (:tag) { 'puge-1.16.1' }
|
6
|
+
let (:rails_env) { 'development' }
|
7
|
+
let (:gofer) { double('Gofer').as_null_object }
|
8
|
+
let (:servers) { (0..1).map { |i| double("Server #{i}").as_null_object} }
|
9
|
+
let (:environment) {double('Environment', :servers => servers, :database => database)}
|
10
|
+
let (:opts) { { 'tag' => tag, 'rails_env' => rails_env } }
|
11
|
+
let (:run_on_servers) { servers }
|
12
|
+
let (:base_path) { [ ENV['HOME'], '.dew', 'deploy', 'puge' ]}
|
13
|
+
|
14
|
+
shared_examples_for "script runner" do
|
15
|
+
it "should upload the script to the EC2 instance" do
|
16
|
+
run_on_servers.each do |server|
|
17
|
+
server.ssh.should_receive(:upload).with(File.join(base_path, script), File.join('.'))
|
18
|
+
end
|
19
|
+
Deploy::Puge.new(servers, opts).deploy
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should run the script" do
|
23
|
+
run_on_servers.each do |server|
|
24
|
+
server.ssh.should_receive(:run).with(['./' + script, arguments.map { |a| "'#{a}'"}].flatten.join(" "))
|
25
|
+
end
|
26
|
+
Deploy::Puge.new(servers, opts).deploy
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe :run do
|
31
|
+
|
32
|
+
describe "Discrete actions" do
|
33
|
+
|
34
|
+
describe "Clone PUGE" do
|
35
|
+
let (:script) { 'clone_puge.sh' }
|
36
|
+
let (:arguments) { [tag] }
|
37
|
+
it_should_behave_like "script runner"
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "Bundle install" do
|
41
|
+
let (:script) { 'bundle_install.sh' }
|
42
|
+
let (:arguments) { [] }
|
43
|
+
it_should_behave_like "script runner"
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "Setup Rails database" do
|
47
|
+
let (:run_on_servers) { servers.first }
|
48
|
+
let (:script) { 'setup_rails_database.sh' }
|
49
|
+
let (:arguments) { [rails_env] }
|
50
|
+
it_should_behave_like "script runner"
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "Generate PUGE WAR" do
|
54
|
+
let (:script) { 'generate_puge_war.sh' }
|
55
|
+
let (:arguments) { [rails_env] }
|
56
|
+
it_should_behave_like "script runner"
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "Copy PUGE WAR into Tomcat directory" do
|
60
|
+
let (:script) { 'copy_puge_war_into_tomcat.sh' }
|
61
|
+
let (:arguments) { [] }
|
62
|
+
it_should_behave_like "script runner"
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "Restart Tomcat" do
|
66
|
+
let (:script) { 'restart_tomcat.sh' }
|
67
|
+
let (:arguments) { [] }
|
68
|
+
it_should_behave_like "script runner"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper'))
|
2
|
+
|
3
|
+
describe Deploy::Run do
|
4
|
+
|
5
|
+
let (:deploy_type) { 'puge' }
|
6
|
+
let (:tag) { 'puge-1.16.1' }
|
7
|
+
let (:rails_env) { 'development' }
|
8
|
+
let (:servers) { (0..1).map { |i| double("Server #{i}").as_null_object} }
|
9
|
+
let (:database) { double('Database')}
|
10
|
+
let (:environment) {double('Environment', :servers => servers, :database => database)}
|
11
|
+
let (:opts) { { 'tag' => tag, 'rails_env' => rails_env } }
|
12
|
+
|
13
|
+
before :each do
|
14
|
+
@deploy_run = Deploy::Run.new(deploy_type, environment, opts)
|
15
|
+
Cloud.stub(:region => 'ap-southeast-1', :account_name => 'myaccount', :profile_name => 'development')
|
16
|
+
end
|
17
|
+
|
18
|
+
it { @deploy_run.deploy_type.should == deploy_type }
|
19
|
+
it { @deploy_run.environment.should == environment }
|
20
|
+
it { @deploy_run.opts['tag'].should == tag }
|
21
|
+
it { @deploy_run.opts['rails_env'].should == rails_env }
|
22
|
+
|
23
|
+
describe :deploy do
|
24
|
+
before :each do
|
25
|
+
Deploy::Puge.stub(:run => nil)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should perform a deploy run for each associated server" do
|
29
|
+
deloy_puge_class_name = 'Deploy::Puge'
|
30
|
+
deploy_puge = double(deloy_puge_class_name)
|
31
|
+
|
32
|
+
Deploy.should_receive(:const_get).with(deploy_type.capitalize).and_return(deloy_puge_class_name)
|
33
|
+
deloy_puge_class_name.should_receive(:new).with(servers, opts).and_return(deploy_puge)
|
34
|
+
deploy_puge.should_receive(:deploy)
|
35
|
+
@deploy_run.deploy
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,374 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '../spec_helper'))
|
2
|
+
|
3
|
+
describe Environment do
|
4
|
+
|
5
|
+
let (:name) { 'my-environment' }
|
6
|
+
let (:bad_name) { 'my_environment' }
|
7
|
+
let (:server) { double('Server', :id => 'i-12345', :add_tag => nil, :wait_until_ready => nil, :availability_zone => 'ap-southeast-1') }
|
8
|
+
let(:groups) { %w(non_default) }
|
9
|
+
let (:server) { double('Server', :id => 'i-12345', :add_tag => nil, :wait_until_ready => nil, :availability_zone => 'ap-southeast-1', :groups => groups) }
|
10
|
+
let (:servers) { [] }
|
11
|
+
let(:an_elb) { double('elb1', :id => 'my-environment') }
|
12
|
+
let (:elb) { double('ELB', :load_balancers => [an_elb]) }
|
13
|
+
let (:database) { double('Database') }
|
14
|
+
let(:keypair_available_in_aws) { true }
|
15
|
+
let(:profile_count) { 2 }
|
16
|
+
let (:profile) do
|
17
|
+
double('Profile',
|
18
|
+
:ami => 'ami-12345', :size => 'm1.large',
|
19
|
+
:keypair => 'devops', :count => profile_count,
|
20
|
+
:has_rds? => false, :has_elb? => false
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
before :each do
|
25
|
+
@environment = Environment.new(name, servers)
|
26
|
+
Cloud.connect(name, 'development')
|
27
|
+
Cloud.stub(:elb => elb, :keypair_exists? => keypair_available_in_aws)
|
28
|
+
end
|
29
|
+
|
30
|
+
it { @environment.name.should == name }
|
31
|
+
it { @environment.servers.should == [] }
|
32
|
+
it { @environment.database.should == nil }
|
33
|
+
|
34
|
+
describe ".get" do
|
35
|
+
before :each do
|
36
|
+
Server.stub(:find => [])
|
37
|
+
Database.stub(:get => nil)
|
38
|
+
end
|
39
|
+
it "should discover servers belonging to this environment" do
|
40
|
+
Server.should_receive(:find).with('Environment', name).and_return [server]
|
41
|
+
Environment.get(name).servers.should == [server]
|
42
|
+
end
|
43
|
+
it "should discover a database belonging to this environment" do
|
44
|
+
Database.should_receive(:get).with(name).and_return 'database'
|
45
|
+
Environment.get(name).database.should == 'database'
|
46
|
+
end
|
47
|
+
it "should return nil if no servers nor database is discovered for this environment" do
|
48
|
+
Environment.get(name).should == nil
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe ".create" do
|
53
|
+
let (:security_groups) { %w(non_default) }
|
54
|
+
let(:profile) { double(:profile, :keypair => 'default', :security_groups => security_groups, :ami => 'i-1234', :has_rds? => false, :has_elb? => false, :count => 2, :size => 'small' ) }
|
55
|
+
|
56
|
+
context "when environment name is invalid" do
|
57
|
+
it "should raise an error" do
|
58
|
+
lambda { Environment.create(bad_name, profile) }.should raise_error /does not match/
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "when profile keypair is not available in AWS" do
|
63
|
+
let(:keypair_available_in_aws) { false }
|
64
|
+
|
65
|
+
it "should raise an error" do
|
66
|
+
lambda { Environment.create(name, profile) }.should raise_error /is not available/
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context "when profile keypair is available in AWS" do
|
71
|
+
|
72
|
+
before {
|
73
|
+
@env = double(:environment, :name => name, :add_database => true, :wait_until_ready => true, :add_server => true)
|
74
|
+
Environment.should_receive(:new).with(name).and_return(@env)
|
75
|
+
}
|
76
|
+
|
77
|
+
after { Environment.create(name, profile) }
|
78
|
+
|
79
|
+
context "with a profile count of 2" do
|
80
|
+
let(:profile_count) { 2 }
|
81
|
+
|
82
|
+
it "should add two instances to that environment with the chosen AMI, size and keypair" do
|
83
|
+
@env.should_receive(:add_server).with(profile.ami, profile.size, profile.keypair, profile.security_groups).twice
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should wait for our environment to become ready" do
|
88
|
+
@env.should_receive(:wait_until_ready)
|
89
|
+
end
|
90
|
+
|
91
|
+
describe "with an ELB specified in the profile" do
|
92
|
+
before :each do
|
93
|
+
profile.stub(:has_elb? => true, :elb_listener_ports => [80])
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should add an ELB to the environment with the required ports" do
|
97
|
+
@env.should_receive(:add_elb).with([80])
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "with an RDS specified in the profile" do
|
102
|
+
before :each do
|
103
|
+
profile.stub(:has_rds? => true, :rds_size => 'db.m1.small')
|
104
|
+
@env.stub(:add_database => nil, :configure_servers_for_database => nil)
|
105
|
+
Password.stub(:random => 'abcdef')
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should add an RDS to the environment with the required size and a random password" do
|
109
|
+
@env.should_receive(:add_database).with('db.m1.small', 'abcdef')
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should ask the environment to update the database configuration on the servers" do
|
113
|
+
@env.should_receive(:configure_servers_for_database).with('abcdef')
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe ".names" do
|
121
|
+
before {
|
122
|
+
Cloud.should_receive(:valid_servers).at_least(1).and_return( [
|
123
|
+
double(:server, :tags => {"Environment" => "test-1", "Creator" => "chris" }),
|
124
|
+
double(:server, :tags => {"Environment" => "test-2", "Creator" => "ash" })
|
125
|
+
])
|
126
|
+
}
|
127
|
+
|
128
|
+
it { Environment.owners.should == [{:name=>"test-1", :owner=>"chris"}, {:name=>"test-2", :owner=>"ash"}] }
|
129
|
+
end
|
130
|
+
|
131
|
+
describe ".index" do
|
132
|
+
before {
|
133
|
+
Cloud.should_receive(:valid_servers).at_least(1).and_return( [
|
134
|
+
double(:server, :tags => {"Environment" => "test-1", "Creator" => "chris" }),
|
135
|
+
double(:server, :tags => {"Environment" => "test-2", "Creator" => "ash" })
|
136
|
+
])
|
137
|
+
}
|
138
|
+
after { Environment.index }
|
139
|
+
|
140
|
+
# TODO: Have the model return what is to be displayed rather than display it itself.
|
141
|
+
it "should index the environments" do
|
142
|
+
Inform.should_receive(:info).at_least(1).with( <<EOF
|
143
|
+
Environments:
|
144
|
+
+----------+---------+
|
145
|
+
| name | owner |
|
146
|
+
+----------+---------+
|
147
|
+
| "test-1" | "chris" |
|
148
|
+
| "test-2" | "ash" |
|
149
|
+
+----------+---------+
|
150
|
+
EOF
|
151
|
+
)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
describe :show do
|
156
|
+
before {
|
157
|
+
Cloud.stub_chain(:account, :aws_user_id).and_return('12345')
|
158
|
+
}
|
159
|
+
after { @environment.show }
|
160
|
+
|
161
|
+
context "with servers" do
|
162
|
+
let(:servers) { [server] }
|
163
|
+
|
164
|
+
before { @environment.stub(:elb => nil) }
|
165
|
+
it "should show the servers" do
|
166
|
+
View.should_receive(:new).with(
|
167
|
+
"SERVERS", [server], %w(id flavor_id public_ip_address state created_at groups key_name availability_zone creator)
|
168
|
+
).and_return(double(:servers_view, :index => 'servers'))
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
context "with an elb" do
|
173
|
+
it "should show the elb" do
|
174
|
+
elb_view = double(:elb_view)
|
175
|
+
View.should_receive(:new).with(
|
176
|
+
"ELB", [an_elb], %w(created_at dns_name instances availability_zones)
|
177
|
+
).and_return(elb_view)
|
178
|
+
elb_view.should_receive(:show).and_return('stuff')
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
context "with a database" do
|
183
|
+
before {
|
184
|
+
@environment.stub(:database => database)
|
185
|
+
@environment.stub(:elb => nil)
|
186
|
+
}
|
187
|
+
|
188
|
+
it "should show the database" do
|
189
|
+
View.should_receive(:new).with(
|
190
|
+
"DATABASE", [database], %w(flavor_id state created_at availability_zone db_security_groups)
|
191
|
+
).and_return(double(:database_view, :index => 'database', :show => "some_ stuff"))
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
end
|
196
|
+
|
197
|
+
describe :destroy do
|
198
|
+
before :each do
|
199
|
+
@environment.stub(:has_elb? => false)
|
200
|
+
end
|
201
|
+
it "should destroy the database if there is one" do
|
202
|
+
@environment.stub(:database => database)
|
203
|
+
database.should_receive(:destroy)
|
204
|
+
@environment.destroy
|
205
|
+
end
|
206
|
+
it "should destroy the servers if there are any" do
|
207
|
+
@environment.stub(:servers => [server])
|
208
|
+
server.should_receive(:destroy)
|
209
|
+
@environment.destroy
|
210
|
+
end
|
211
|
+
it "should destroy the ELB if there is one" do
|
212
|
+
@environment.stub(:has_elb? => true)
|
213
|
+
elb.should_receive(:delete_load_balancer).with(name)
|
214
|
+
@environment.destroy
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
describe :add_server do
|
219
|
+
before :each do
|
220
|
+
@args = 'ami', 'size', 'keypair', %w(non_default)
|
221
|
+
Server.stub(:create!).and_return(server)
|
222
|
+
end
|
223
|
+
|
224
|
+
it "should create a Server from the provided ami, size and keypair" do
|
225
|
+
Server.should_receive(:create!).with(*@args)
|
226
|
+
@environment.add_server(*@args)
|
227
|
+
end
|
228
|
+
|
229
|
+
it "should add the Server to its servers array" do
|
230
|
+
@environment.add_server(*@args)
|
231
|
+
@environment.add_server(*@args)
|
232
|
+
@environment.servers.should == [server, server]
|
233
|
+
end
|
234
|
+
|
235
|
+
it "should tag the server with the environment name and creator" do
|
236
|
+
server.should_receive(:add_tag).with('Environment', name)
|
237
|
+
server.should_receive(:add_tag).with('Creator', ENV['USER'])
|
238
|
+
@environment.add_server(*@args)
|
239
|
+
end
|
240
|
+
|
241
|
+
it "should tag the server with an indexed name" do
|
242
|
+
server.should_receive(:add_tag).with('Name', "#{name} 1")
|
243
|
+
@environment.add_server(*@args)
|
244
|
+
|
245
|
+
server.should_receive(:add_tag).with('Name', "#{name} 2")
|
246
|
+
@environment.add_server(*@args)
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
describe :remove_server_from_elb do
|
251
|
+
it "should remove the server from the ELB" do
|
252
|
+
elb.should_receive(:deregister_instances_from_load_balancer).with([server.id], name)
|
253
|
+
@environment.remove_server_from_elb(server)
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
describe :add_server_to_elb do
|
258
|
+
it "should add the server to the ELB" do
|
259
|
+
elb.should_receive(:register_instances_with_load_balancer).with([server.id], name)
|
260
|
+
@environment.add_server_to_elb(server)
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
context "with one server" do
|
265
|
+
before :each do
|
266
|
+
@environment.stub(:servers => [server])
|
267
|
+
end
|
268
|
+
|
269
|
+
describe :add_elb do
|
270
|
+
before :each do
|
271
|
+
server.stub(:availability_zone => 'ap-southeast-1a')
|
272
|
+
elb.stub(:create_load_balancer => nil, :register_instances_with_load_balancer => nil)
|
273
|
+
end
|
274
|
+
it "should create the ELB using the provided listeners, environment name and the availability zones of the current servers" do
|
275
|
+
server.should_receive(:availability_zone).and_return('ap-southeast-1a')
|
276
|
+
|
277
|
+
elb.should_receive(:create_load_balancer).with(
|
278
|
+
['ap-southeast-1a'], name,
|
279
|
+
[{'Protocol' => 'TCP', 'LoadBalancerPort' => 80, 'InstancePort' => 80}]
|
280
|
+
)
|
281
|
+
@environment.add_elb [80]
|
282
|
+
end
|
283
|
+
it "should add the servers to the elb" do
|
284
|
+
elb.should_receive(:register_instances_with_load_balancer).with([server.id], name)
|
285
|
+
@environment.add_elb [80]
|
286
|
+
end
|
287
|
+
|
288
|
+
end
|
289
|
+
|
290
|
+
describe :add_database do
|
291
|
+
before :each do
|
292
|
+
Database.stub(:create! => database)
|
293
|
+
end
|
294
|
+
|
295
|
+
it "should create an RDS of the requested size, using the environment name and a random password" do
|
296
|
+
Database.should_receive(:create!).with(name, 'db.m1.small', 'password')
|
297
|
+
@environment.add_database 'db.m1.small', 'password'
|
298
|
+
end
|
299
|
+
|
300
|
+
it "should make the database available on the 'database' accessor" do
|
301
|
+
@environment.add_database 'db.m1.small', 'password'
|
302
|
+
@environment.database.should == database
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
describe :wait_until_ready do
|
307
|
+
before {
|
308
|
+
Cloud.stub(:security_groups => { 'non_default' => double(:group, :ip_permissions => ip_permissions) } )
|
309
|
+
}
|
310
|
+
after { @environment.wait_until_ready }
|
311
|
+
|
312
|
+
context "with no ip_permissions" do
|
313
|
+
let(:ip_permissions) { [:some_ip_permissions] }
|
314
|
+
|
315
|
+
it "should wait for each server to be ready" do
|
316
|
+
server.should_receive(:wait_until_ready)
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
context "with ip_permissions" do
|
321
|
+
let(:ip_permissions) { [] }
|
322
|
+
|
323
|
+
it "should not wait for each server to be ready" do
|
324
|
+
server.should_not_receive(:wait_until_ready)
|
325
|
+
end
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
context "with an RDS" do
|
330
|
+
before :each do
|
331
|
+
Cloud.stub(:security_groups => { 'non_default' => double(:group, :ip_permissions => true) } )
|
332
|
+
@environment.stub(:database => database)
|
333
|
+
end
|
334
|
+
|
335
|
+
describe :wait_until_ready do
|
336
|
+
it "should wait for the database to be ready" do
|
337
|
+
database.should_receive(:wait_until_ready)
|
338
|
+
@environment.wait_until_ready
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
describe :configure_servers_for_database do
|
343
|
+
it "should ask each server to apply credentials from our database" do
|
344
|
+
server.should_receive(:configure_for_database).with(database, 'password')
|
345
|
+
@environment.configure_servers_for_database 'password'
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
def mock_describe_load_balancers load_balancers, name=nil
|
353
|
+
response = double('ELB Response', :body => { 'DescribeLoadBalancersResult' => { 'LoadBalancerDescriptions' => load_balancers }})
|
354
|
+
if name
|
355
|
+
elb.should_receive(:describe_load_balancers).with(name).and_return(response)
|
356
|
+
else
|
357
|
+
elb.should_receive(:describe_load_balancers).and_return(response)
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
describe :has_elb? do
|
362
|
+
it "return true if we have a load balancer" do
|
363
|
+
mock_describe_load_balancers([{'LoadBalancerName' => name}])
|
364
|
+
@environment.has_elb?.should be_true
|
365
|
+
end
|
366
|
+
|
367
|
+
it "return false if we don't" do
|
368
|
+
mock_describe_load_balancers([{'LoadBalancerName' => "XXXX"}])
|
369
|
+
@environment.has_elb?.should be_false
|
370
|
+
end
|
371
|
+
|
372
|
+
end
|
373
|
+
|
374
|
+
end
|