rhc 1.5.13 → 1.6.8
Sign up to get free protection for your applications and to get access to all the features.
- data/features/application.feature +1 -1
- data/features/cartridge.feature +10 -9
- data/features/geared_application.feature +3 -6
- data/features/lib/rhc_helper/app.rb +2 -2
- data/features/multiple_cartridge.feature +9 -8
- data/features/scaled_application.feature +5 -5
- data/features/step_definitions/application_steps.rb +4 -3
- data/features/step_definitions/cartridge_steps.rb +8 -1
- data/features/support/before_hooks.rb +12 -6
- data/features/support/env.rb +8 -1
- data/features/support/platform_support.rb +29 -0
- data/lib/rhc/command_runner.rb +33 -21
- data/lib/rhc/commands/account.rb +1 -1
- data/lib/rhc/commands/alias.rb +90 -7
- data/lib/rhc/commands/app.rb +15 -11
- data/lib/rhc/commands/cartridge.rb +9 -2
- data/lib/rhc/exceptions.rb +6 -0
- data/lib/rhc/helpers.rb +3 -0
- data/lib/rhc/output_helpers.rb +12 -3
- data/lib/rhc/rest.rb +3 -0
- data/lib/rhc/rest/alias.rb +50 -0
- data/lib/rhc/rest/application.rb +26 -2
- data/lib/rhc/rest/cartridge.rb +16 -1
- data/lib/rhc/rest/client.rb +24 -4
- data/lib/rhc/rest/mock.rb +66 -2
- data/lib/rhc/ssh_helpers.rb +2 -3
- data/lib/rhc/wizard.rb +6 -3
- data/spec/rhc/assets/cert.crt +22 -0
- data/spec/rhc/assets/cert_key_rsa +27 -0
- data/spec/rhc/assets/empty.txt +0 -0
- data/spec/rhc/cli_spec.rb +5 -0
- data/spec/rhc/commands/account_spec.rb +6 -6
- data/spec/rhc/commands/alias_spec.rb +179 -5
- data/spec/rhc/commands/app_spec.rb +2 -1
- data/spec/rhc/commands/authorization_spec.rb +9 -0
- data/spec/rhc/commands/cartridge_spec.rb +27 -0
- data/spec/rhc/commands/setup_spec.rb +2 -0
- data/spec/rhc/commands/sshkey_spec.rb +20 -1
- data/spec/rhc/helpers_spec.rb +1 -2
- data/spec/rhc/rest_client_spec.rb +26 -5
- data/spec/rhc/wizard_spec.rb +22 -0
- data/spec/spec_helper.rb +25 -2
- data/spec/wizard_spec_helper.rb +1 -1
- metadata +153 -144
data/lib/rhc/ssh_helpers.rb
CHANGED
@@ -122,7 +122,7 @@ module RHC
|
|
122
122
|
error e.message
|
123
123
|
nil
|
124
124
|
rescue => e
|
125
|
-
|
125
|
+
debug e.message
|
126
126
|
nil
|
127
127
|
end
|
128
128
|
|
@@ -135,13 +135,12 @@ module RHC
|
|
135
135
|
# which is basically the space-separated list of the SSH public key content
|
136
136
|
def ssh_key_triple_for(key)
|
137
137
|
begin
|
138
|
-
|
138
|
+
IO.read(key).chomp.split
|
139
139
|
rescue Errno::ENOENT => e
|
140
140
|
raise ::RHC::KeyFileNotExistentException.new("File '#{key}' does not exist.")
|
141
141
|
rescue Errno::EACCES => e
|
142
142
|
raise ::RHC::KeyFileAccessDeniedException.new("Access denied to '#{key}'.")
|
143
143
|
end
|
144
|
-
file.gets.chomp.split
|
145
144
|
end
|
146
145
|
|
147
146
|
def ssh_key_triple_for_default_key
|
data/lib/rhc/wizard.rb
CHANGED
@@ -245,7 +245,7 @@ module RHC
|
|
245
245
|
key_fingerprint = fingerprint_for_default_key
|
246
246
|
unless key_fingerprint
|
247
247
|
paragraph do
|
248
|
-
|
248
|
+
warn "Your ssh public key at #{system_path(RHC::Config.ssh_pub_key_file_path)} is invalid or unreadable. "\
|
249
249
|
"Setup can not continue until you manually remove or fix your "\
|
250
250
|
"public and private keys id_rsa keys."
|
251
251
|
end
|
@@ -420,9 +420,8 @@ module RHC
|
|
420
420
|
# Thus, we force an order with #sort to ensure spec passage on both.
|
421
421
|
def setup_test_stage
|
422
422
|
say "Checking common problems "
|
423
|
-
tests = private_methods.select {|m| m.to_s.start_with? 'test_'}
|
424
423
|
failed = false
|
425
|
-
|
424
|
+
all_test_methods.sort.each do |test|
|
426
425
|
begin
|
427
426
|
send(test)
|
428
427
|
print_dot unless failed
|
@@ -440,6 +439,10 @@ module RHC
|
|
440
439
|
true
|
441
440
|
end
|
442
441
|
|
442
|
+
def all_test_methods
|
443
|
+
private_methods.select {|m| m.to_s.start_with? 'test_'}
|
444
|
+
end
|
445
|
+
|
443
446
|
# cached list of applications needed for test stage
|
444
447
|
def applications
|
445
448
|
@applications ||= rest_client.domains.map(&:applications).flatten
|
@@ -0,0 +1,22 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIDoDCCAogCCQDzF8AJCHnrbjANBgkqhkiG9w0BAQUFADCBkTELMAkGA1UEBhMC
|
3
|
+
VVMxCzAJBgNVBAgMAkNBMRIwEAYDVQQHDAlTdW5ueXZhbGUxDzANBgNVBAoMBnJl
|
4
|
+
ZGhhdDESMBAGA1UECwwJb3BlbnNoaWZ0MRIwEAYDVQQDDAlvcGVuc2hpZnQxKDAm
|
5
|
+
BgkqhkiG9w0BCQEWGWluZm9Ab3BlbnNoaWZ0LnJlZGhhdC5jb20wHhcNMTMwMjE5
|
6
|
+
MjExMTQ4WhcNMTQwMjE5MjExMTQ4WjCBkTELMAkGA1UEBhMCVVMxCzAJBgNVBAgM
|
7
|
+
AkNBMRIwEAYDVQQHDAlTdW5ueXZhbGUxDzANBgNVBAoMBnJlZGhhdDESMBAGA1UE
|
8
|
+
CwwJb3BlbnNoaWZ0MRIwEAYDVQQDDAlvcGVuc2hpZnQxKDAmBgkqhkiG9w0BCQEW
|
9
|
+
GWluZm9Ab3BlbnNoaWZ0LnJlZGhhdC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IB
|
10
|
+
DwAwggEKAoIBAQDAEbH4MCi3iIDP1HS+/Xwu8SjdSc5WJX6htV7hJpmFZ8HohV/8
|
11
|
+
ba0v6aM9IJIIt+sIe2J62t/9G3leOdIHBxeACN4fV2l/iA/fvxvlnFKeD7sHm9Oc
|
12
|
+
Yj1H6YYJ57sIOf/oLDpJl6l3Rw8VC3+3W0/lzlVpA8qt7fpkiW7XQJCPplUSrdVC
|
13
|
+
3okQ2T5NAod5+wVIOqELgE5bLX1LRs5VPsjytHkJ7rKXs55FHR3kpsoImn5xD0Ky
|
14
|
+
6lRn8cIMolQoyN5HIGr8f5P+07hrHibve8jje/DKTssb5yEUAEmh6iGHQsRAnsUW
|
15
|
+
QoIEUOLqQCu9re2No4G52Kl2xQIjyJF7rCfxAgMBAAEwDQYJKoZIhvcNAQEFBQAD
|
16
|
+
ggEBAGHrya/ZkiAje2kHsOajXMlO2+y1iLfUDcRLuEWpUa8sI5EM4YtemQrsupFp
|
17
|
+
8lVYG5C4Vh8476oF9t8Wex5eH3ocwbSvPIUqE07hdmrubiMq4wxFVRYq7g9lHAnx
|
18
|
+
l+bABuN/orbAcPcGAGg7AkXVoAc3Fza/ZcgMcw7NOtDTEss70V9OdgCfQUJL0KdO
|
19
|
+
hCO8bQ1EaEiq6zEh8RpZe8mu+f/GYATX1I+eJUc6F6cn83oJjE9bqAVzk7TzTHeK
|
20
|
+
EBKN50C14wWtXeG7n2+ugaVO+0xnvHeUrQBLHSRyOHqxXrQQ5XmzcaBiyI0f2IQM
|
21
|
+
Hst1BVXyX0n/L/ZoYYsv5juJmDo=
|
22
|
+
-----END CERTIFICATE-----
|
@@ -0,0 +1,27 @@
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
2
|
+
MIIEogIBAAKCAQEAwBGx+DAot4iAz9R0vv18LvEo3UnOViV+obVe4SaZhWfB6IVf
|
3
|
+
/G2tL+mjPSCSCLfrCHtietrf/Rt5XjnSBwcXgAjeH1dpf4gP378b5ZxSng+7B5vT
|
4
|
+
nGI9R+mGCee7CDn/6Cw6SZepd0cPFQt/t1tP5c5VaQPKre36ZIlu10CQj6ZVEq3V
|
5
|
+
Qt6JENk+TQKHefsFSDqhC4BOWy19S0bOVT7I8rR5Ce6yl7OeRR0d5KbKCJp+cQ9C
|
6
|
+
supUZ/HCDKJUKMjeRyBq/H+T/tO4ax4m73vI43vwyk7LG+chFABJoeohh0LEQJ7F
|
7
|
+
FkKCBFDi6kArva3tjaOBudipdsUCI8iRe6wn8QIDAQABAoIBAG/on4JVRRQSw8LU
|
8
|
+
LiWt+jI7ryyoOUH2XL8JtzuGSwLwvomlVJT2rmbxQXx3Qr8zsgziHzIn30RRQrkF
|
9
|
+
BXu0xRuDjzBBtSVqeJ1Mc4uoNncEAVxgjb5bewswZDnXPCGB8bosMtX4OPRXgdEo
|
10
|
+
PwTtfjMOsrMaU3hd5Xu4m81tQA2BvwOlx8aYDyH0jeTnervc5uRGbeTBQG4Bu40E
|
11
|
+
rWNmXvgNq2EzTAwbbN6Ma97gw9KgXnM4Nlh29Fxb5TBeUU9lkzuTZAZIDXKIm7AG
|
12
|
+
UwMbj/A038yAumYQtThTE/3e4W3rn7F2Vko900bC4aAC1KQOAzjIeQqzqkVxWTWq
|
13
|
+
4SUFQAECgYEA/ODwifOTuI6hdZK6JRgc4wp6Rc0fkqHuxLzABXoIGuSVlWyimqIN
|
14
|
+
ZySAkpo5EW6DNraRJxNCOBmWeGPEhHGrea+JPiPEwCK0F7SxvSmg3jzNzw3Es31T
|
15
|
+
ecET7eDwuSOY9v4XDzLyiXXkEUUReD7Ng2hEYL+HaQrl5jWj4lxgq/ECgYEAwnCb
|
16
|
+
Krz7FwX8AqtFAEi6uUrc12k1xYKQfrwSxbfdK2vBBUpgB71Iq/fqP+1BittEljDG
|
17
|
+
8f4jEtMBFfEPhLzGIHaI3UiHUHXS4GetA77TRgR8lnKKpj1FcMIY2iKU479707O5
|
18
|
+
Q08pgWRUDQ8BVg2ePgbo5QjLMc/rv7UF3AHvPAECgYB/auAIwqDGN6gHU/1TP4ke
|
19
|
+
pWLi1O55tfpXSzv+BnUbB96PQgPUop7aP7xBIlBrBiI7aVZOOBf/qHT3CF421geu
|
20
|
+
8tHWa7NxlIrl/vgn9lfGYyDYmXlpb1amXLEsBVGGF/e1TGZWFDe9J5fZU9HvosVu
|
21
|
+
1xTNIvSZ6xHYI2MGZcGYIQKBgEYeebaV5C7PV6xWu1F46O19U9rS9DM//H/XryVi
|
22
|
+
Qv4vo7IWuj7QQe7SPsXC98ntfPR0rqoCLf/R3ChfgGsr8H8wf/bc+v9HHj8S5E/f
|
23
|
+
dy1e3Nccg2ej3PDm7jNsGSlwmmUkAQGHAL7KwYzcBm1UB+bycvZ1j2FtS+UckPpg
|
24
|
+
MDgBAoGALD8PkxHb4U4DtbNFSYRrUdvS9heav/yph3lTMfifNkOir36io6v8RPgb
|
25
|
+
D2bHKKZgmYlTgJrxD45Er9agC5jclJO35QRU/OfGf3GcnABkBI7vlvUKADAo65Sq
|
26
|
+
weZkdJnbrIadcvLOHOzkKC9m+rxFTC9VoN1dwK2zwYvUXfa1VJA=
|
27
|
+
-----END RSA PRIVATE KEY-----
|
File without changes
|
data/spec/rhc/cli_spec.rb
CHANGED
@@ -95,6 +95,11 @@ describe RHC::CLI do
|
|
95
95
|
context 'with --help' do
|
96
96
|
before(:each){ @arguments = ['--help'] }
|
97
97
|
it_should_behave_like 'a global help page'
|
98
|
+
|
99
|
+
context 'without a config file' do
|
100
|
+
before{ RHC::Wizard.stub(:has_configuration?).and_return(false) }
|
101
|
+
it_should_behave_like 'a global help page'
|
102
|
+
end
|
98
103
|
end
|
99
104
|
|
100
105
|
context 'with -h' do
|
@@ -23,14 +23,14 @@ describe RHC::Commands::Account do
|
|
23
23
|
it('should show the maximum gears') { run_output.should =~ /Gears Allowed:\s*3/ }
|
24
24
|
it { expect { run }.should exit_with_code(0) }
|
25
25
|
|
26
|
-
context 'with a
|
27
|
-
let(:user_plan_id){ '
|
28
|
-
it('should show') { run_output.should =~ /Plan:\s*
|
26
|
+
context 'with a free plan' do
|
27
|
+
let(:user_plan_id){ 'free' }
|
28
|
+
it('should show') { run_output.should =~ /Plan:\s*Free/ }
|
29
29
|
end
|
30
30
|
|
31
|
-
context 'with a
|
32
|
-
let(:user_plan_id){ '
|
33
|
-
it('should show') { run_output.should =~ /Plan:\s*
|
31
|
+
context 'with a silver plan' do
|
32
|
+
let(:user_plan_id){ 'silver' }
|
33
|
+
it('should show') { run_output.should =~ /Plan:\s*Silver/ }
|
34
34
|
end
|
35
35
|
|
36
36
|
context 'with a arbitrary plan' do
|
@@ -8,10 +8,13 @@ describe RHC::Commands::Alias do
|
|
8
8
|
let(:domain_0_links) { mock_response_links(mock_domain_links('mock_domain_0')) }
|
9
9
|
let(:domain_1_links) { mock_response_links(mock_domain_links('mock_domain_1')) }
|
10
10
|
let(:app_0_links) { mock_response_links(mock_app_links('mock_domain_0', 'mock_app_0')) }
|
11
|
+
let(:alias_0_links) { mock_response_links(mock_alias_links('mock_domain_0', 'mock_app_0', 'www.foo.bar')) }
|
11
12
|
let!(:rest_client){ MockRestClient.new }
|
12
13
|
before(:each) do
|
13
14
|
user_config
|
14
|
-
rest_client.add_domain("mock_domain_0")
|
15
|
+
domain = rest_client.add_domain("mock_domain_0")
|
16
|
+
domain.add_application("mock_app_0", "ruby-1.8.7").add_alias("www.foo.bar")
|
17
|
+
domain.add_application("mock_app_1", "ruby-1.8.7")
|
15
18
|
stub_api_request(:any, client_links['LIST_DOMAINS']['relative']).
|
16
19
|
to_return({ :body => {
|
17
20
|
:type => 'domains',
|
@@ -74,6 +77,20 @@ describe RHC::Commands::Alias do
|
|
74
77
|
}.to_json,
|
75
78
|
:status => 200
|
76
79
|
})
|
80
|
+
stub_api_request(:any, app_0_links['LIST_ALIASES']['relative'], false).
|
81
|
+
to_return({ :body => {
|
82
|
+
:type => 'aliases',
|
83
|
+
:data =>
|
84
|
+
[{ :domain_id => 'mock_domain_0',
|
85
|
+
:application_id => 'mock_app_0',
|
86
|
+
:id => 'www.foo.bar',
|
87
|
+
:certificate_added_at => nil,
|
88
|
+
:has_private_ssl_certificate => false,
|
89
|
+
:links => mock_response_links(mock_alias_links('mock_domain_0','mock_app_0', 'www.foo.bar')),
|
90
|
+
}]
|
91
|
+
}.to_json,
|
92
|
+
:status => 200
|
93
|
+
})
|
77
94
|
|
78
95
|
end
|
79
96
|
|
@@ -110,15 +127,172 @@ describe RHC::Commands::Alias do
|
|
110
127
|
end
|
111
128
|
end
|
112
129
|
|
130
|
+
describe 'alias update-cert --help' do
|
131
|
+
let(:arguments) { ['alias', 'update-cert', '--help'] }
|
132
|
+
|
133
|
+
context 'help is run' do
|
134
|
+
it "should display help" do
|
135
|
+
expect { run }.should exit_with_code(0)
|
136
|
+
end
|
137
|
+
it('should output usage') { run_output.should match("Usage: rhc alias update-cert <application> <alias> --certificate FILE --private-key FILE [--passphrase passphrase]") }
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
describe 'alias delete-cert --help' do
|
142
|
+
let(:arguments) { ['alias', 'delete-cert', '--help'] }
|
143
|
+
|
144
|
+
context 'help is run' do
|
145
|
+
it "should display help" do
|
146
|
+
expect { run }.should exit_with_code(0)
|
147
|
+
end
|
148
|
+
it('should output usage') { run_output.should match("Usage: rhc alias delete-cert <application> <alias>") }
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
describe 'alias list --help' do
|
153
|
+
let(:arguments) { ['alias', 'list', '--help'] }
|
154
|
+
|
155
|
+
context 'help is run' do
|
156
|
+
it "should display help" do
|
157
|
+
expect { run }.should exit_with_code(0)
|
158
|
+
end
|
159
|
+
it('should output usage') { run_output.should match("Usage: rhc alias list <application>") }
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
113
163
|
describe 'add alias' do
|
114
164
|
let(:arguments) { ['alias', 'add', 'mock_app_0', 'www.foo.bar' ] }
|
115
165
|
it { expect { run }.should exit_with_code(0) }
|
116
|
-
it { run_output.should =~ /'
|
166
|
+
it { run_output.should =~ /Alias 'www.foo.bar' has been added/m }
|
117
167
|
end
|
118
168
|
|
119
169
|
describe 'remove alias' do
|
120
|
-
|
121
|
-
|
122
|
-
|
170
|
+
before do
|
171
|
+
rest_client.stub(:api_version_negotiated).and_return(1.4)
|
172
|
+
end
|
173
|
+
context 'remove alias successfully' do
|
174
|
+
let(:arguments) { ['alias', 'remove', 'mock_app_0', 'www.foo.bar' ] }
|
175
|
+
it { expect { run }.should exit_with_code(0) }
|
176
|
+
it { run_output.should =~ /Alias 'www.foo.bar' has been removed/m }
|
177
|
+
end
|
178
|
+
context 'remove alias with server api <= 1.3' do
|
179
|
+
let(:arguments) { ['alias', 'remove', 'mock_app_0', 'www.foo.bar' ] }
|
180
|
+
before do
|
181
|
+
rest_client.stub(:api_version_negotiated).and_return(1.3)
|
182
|
+
end
|
183
|
+
it { expect { run }.should exit_with_code(0) }
|
184
|
+
it { run_output.should =~ /Alias 'www.foo.bar' has been removed/m }
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
describe 'alias update-cert' do
|
189
|
+
before do
|
190
|
+
rest_client.stub(:api_version_negotiated).and_return(1.4)
|
191
|
+
end
|
192
|
+
context 'add valid certificate with valid private key without pass phrase' do
|
193
|
+
let(:arguments) { ['alias', 'update-cert', 'mock_app_0', 'www.foo.bar',
|
194
|
+
'--certificate', File.expand_path('../../assets/cert.crt', __FILE__),
|
195
|
+
'--private-key', File.expand_path('../../assets/cert_key_rsa', __FILE__) ] }
|
196
|
+
it { expect { run }.should exit_with_code(0) }
|
197
|
+
it { run_output.should =~ /SSL certificate successfully added/m }
|
198
|
+
end
|
199
|
+
context 'cert file not found' do
|
200
|
+
let(:arguments) { ['alias', 'update-cert', 'mock_app_0', 'www.foo.bar',
|
201
|
+
'--certificate', File.expand_path('../../assets/nothing.foo', __FILE__),
|
202
|
+
'--private-key', File.expand_path('../../assets/cert_key_rsa', __FILE__) ] }
|
203
|
+
it { expect { run }.should exit_with_code(1) }
|
204
|
+
it { run_output.should =~ /Certificate file not found/m }
|
205
|
+
end
|
206
|
+
context 'private key file not found' do
|
207
|
+
let(:arguments) { ['alias', 'update-cert', 'mock_app_0', 'www.foo.bar',
|
208
|
+
'--certificate', File.expand_path('../../assets/cert.crt', __FILE__),
|
209
|
+
'--private-key', File.expand_path('../../assets/nothing.foo', __FILE__) ] }
|
210
|
+
it { expect { run }.should exit_with_code(1) }
|
211
|
+
it { run_output.should =~ /Private key file not found/m }
|
212
|
+
end
|
213
|
+
context 'not existing certificate alias' do
|
214
|
+
let(:arguments) { ['alias', 'update-cert', 'mock_app_0', 'www.unicorns.com',
|
215
|
+
'--certificate', File.expand_path('../../assets/cert.crt', __FILE__),
|
216
|
+
'--private-key', File.expand_path('../../assets/cert_key_rsa', __FILE__) ] }
|
217
|
+
it { expect { run }.should exit_with_code(156) }
|
218
|
+
it { run_output.should =~ /Alias www.unicorns.com can't be found in application/m }
|
219
|
+
end
|
220
|
+
context 'fails if server does not support' do
|
221
|
+
let(:arguments) { ['alias', 'update-cert', 'mock_app_0', 'www.foo.bar',
|
222
|
+
'--certificate', File.expand_path('../../assets/cert.crt', __FILE__),
|
223
|
+
'--private-key', File.expand_path('../../assets/cert_key_rsa', __FILE__) ] }
|
224
|
+
before do
|
225
|
+
rest_client.stub(:api_version_negotiated).and_return(1.3)
|
226
|
+
end
|
227
|
+
it { expect { run }.should exit_with_code(1) }
|
228
|
+
it { run_output.should =~ /The server does not support SSL certificates for custom aliases/m }
|
229
|
+
end
|
230
|
+
context 'invalid certificate file (empty)' do
|
231
|
+
let(:arguments) { ['alias', 'update-cert', 'mock_app_0', 'www.foo.bar',
|
232
|
+
'--certificate', File.expand_path('../../assets/empty.txt', __FILE__),
|
233
|
+
'--private-key', File.expand_path('../../assets/cert_key_rsa', __FILE__) ] }
|
234
|
+
it { expect { run }.should exit_with_code(1) }
|
235
|
+
it { run_output.should =~ /Invalid certificate file/m }
|
236
|
+
end
|
237
|
+
context 'invalid private key file (empty)' do
|
238
|
+
let(:arguments) { ['alias', 'update-cert', 'mock_app_0', 'www.foo.bar',
|
239
|
+
'--certificate', File.expand_path('../../assets/cert.crt', __FILE__),
|
240
|
+
'--private-key', File.expand_path('../../assets/empty.txt', __FILE__) ] }
|
241
|
+
it { expect { run }.should exit_with_code(1) }
|
242
|
+
it { run_output.should =~ /Invalid private key file/m }
|
243
|
+
end
|
123
244
|
end
|
245
|
+
|
246
|
+
describe 'alias delete-cert' do
|
247
|
+
before do
|
248
|
+
rest_client.stub(:api_version_negotiated).and_return(1.4)
|
249
|
+
end
|
250
|
+
context 'delete existing certificate' do
|
251
|
+
let(:arguments) { ['alias', 'delete-cert', 'mock_app_0', 'www.foo.bar', '--confirm'] }
|
252
|
+
it { expect { run }.should exit_with_code(0) }
|
253
|
+
it { run_output.should =~ /SSL certificate successfully deleted/m }
|
254
|
+
end
|
255
|
+
context 'delete not existing certificate' do
|
256
|
+
let(:arguments) { ['alias', 'delete-cert', 'mock_app_0', 'www.unicorns.com', '--confirm'] }
|
257
|
+
it { expect { run }.should exit_with_code(156) }
|
258
|
+
it { run_output.should =~ /Alias www.unicorns.com can't be found in application mock_app_0/m }
|
259
|
+
end
|
260
|
+
context 'fails if server does not support' do
|
261
|
+
let(:arguments) { ['alias', 'delete-cert', 'mock_app_0', 'www.foo.bar', '--confirm'] }
|
262
|
+
before do
|
263
|
+
rest_client.stub(:api_version_negotiated).and_return(1.3)
|
264
|
+
end
|
265
|
+
it { expect { run }.should exit_with_code(1) }
|
266
|
+
it { run_output.should =~ /The server does not support SSL certificates for custom aliases/m }
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
describe 'alias list' do
|
271
|
+
before do
|
272
|
+
rest_client.stub(:api_version_negotiated).and_return(1.4)
|
273
|
+
end
|
274
|
+
context 'list app with existing certificate' do
|
275
|
+
let(:arguments) { ['alias', 'list', 'mock_app_0'] }
|
276
|
+
it { expect { run }.should exit_with_code(0) }
|
277
|
+
it { run_output.should =~ /Has Certificate?/m }
|
278
|
+
it { run_output.should =~ /Certificate Added/m }
|
279
|
+
it { run_output.should =~ /www.foo.bar/m }
|
280
|
+
end
|
281
|
+
context 'list app without certificates' do
|
282
|
+
let(:arguments) { ['alias', 'list', 'mock_app_1'] }
|
283
|
+
it { expect { run }.should exit_with_code(0) }
|
284
|
+
it { run_output.should =~ /No aliases associated with the application mock_app_1/m }
|
285
|
+
end
|
286
|
+
context 'simple list is server does not support ssl certs' do
|
287
|
+
let(:arguments) { ['alias', 'list', 'mock_app_0'] }
|
288
|
+
before do
|
289
|
+
rest_client.stub(:api_version_negotiated).and_return(1.3)
|
290
|
+
end
|
291
|
+
it { expect { run }.should exit_with_code(0) }
|
292
|
+
it { run_output.should =~ /no/m }
|
293
|
+
it { run_output.should =~ /-/m }
|
294
|
+
it { run_output.should =~ /www.foo.bar/m }
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
124
298
|
end
|
@@ -74,7 +74,7 @@ describe RHC::Commands::App do
|
|
74
74
|
Resolv::Hosts.should_receive(:new).and_return(resolver)
|
75
75
|
resolver.should_receive(:getaddress).with('app1-mockdomain.fake.foo').and_raise(ArgumentError)
|
76
76
|
end
|
77
|
-
|
77
|
+
|
78
78
|
it { expect { run }.should exit_with_code(0) }
|
79
79
|
it { run_output.should match("Success") }
|
80
80
|
end
|
@@ -109,6 +109,7 @@ describe RHC::Commands::App do
|
|
109
109
|
it { expect { run }.should raise_error(RHC::CartridgeNotFoundException, "There are no cartridges that match 'nomatch_cart'.") }
|
110
110
|
end
|
111
111
|
end
|
112
|
+
|
112
113
|
end
|
113
114
|
|
114
115
|
describe 'cart matching behavior' do
|
@@ -42,6 +42,15 @@ describe RHC::Commands::Authorization do
|
|
42
42
|
|
43
43
|
expect_an_unsupported_message
|
44
44
|
end
|
45
|
+
|
46
|
+
describe '#run' do
|
47
|
+
let(:arguments) { ['authorization', '--h']}
|
48
|
+
context 'given --h' do
|
49
|
+
it 'should not raise SystemStackError' do
|
50
|
+
expect{ run }.should_not raise_error(SystemStackError)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
45
54
|
|
46
55
|
describe "#delete" do
|
47
56
|
let(:arguments) { ['authorization', 'delete', 'foo', 'bar'] }
|
@@ -49,6 +49,7 @@ describe RHC::Commands::Cartridge do
|
|
49
49
|
it{ run_output.should match /mock_standalone_cart\-1\s+Mock1 Cart\s+web/ }
|
50
50
|
it{ run_output.should match /mock_standalone_cart\-2\s+web/ }
|
51
51
|
it{ run_output.should match /mock_embedded_cart\-1\s+Mock1 Embedded Cart\s+addon/ }
|
52
|
+
it{ run_output.should match /premium_cart\-1 \(\*\)\s+Premium Cart\s+web/ }
|
52
53
|
it{ expect{ run }.should exit_with_code(0) }
|
53
54
|
|
54
55
|
context 'with verbose list' do
|
@@ -164,6 +165,17 @@ describe RHC::Commands::Cartridge do
|
|
164
165
|
fail_with_code 155
|
165
166
|
}
|
166
167
|
end
|
168
|
+
|
169
|
+
context 'when cart is premium' do
|
170
|
+
let(:arguments) { ['cartridge', 'add', 'premium_cart', '-a', 'app1','--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
|
171
|
+
before(:each) do
|
172
|
+
domain = rest_client.add_domain("mock_domain")
|
173
|
+
app = domain.add_application("app1", "mock_type")
|
174
|
+
end
|
175
|
+
it {
|
176
|
+
succeed_with_message /This gear costs an additional \$0\.05 per gear after the first 3 gears\./
|
177
|
+
}
|
178
|
+
end
|
167
179
|
end
|
168
180
|
|
169
181
|
describe 'cartridge remove' do
|
@@ -306,6 +318,21 @@ describe RHC::Commands::Cartridge do
|
|
306
318
|
end
|
307
319
|
end
|
308
320
|
|
321
|
+
describe 'cartridge show' do
|
322
|
+
let(:arguments) { ['cartridge', 'show', 'premium_cart', '-a', 'app1', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
|
323
|
+
|
324
|
+
before(:each) do
|
325
|
+
@rc = MockRestClient.new
|
326
|
+
domain = @rc.add_domain("mock_domain")
|
327
|
+
app = domain.add_application("app1", "mock_type")
|
328
|
+
app.cartridges << @rc.cartridges.find {|c| c.name == 'premium_cart'}
|
329
|
+
end
|
330
|
+
|
331
|
+
context 'when run with a premium cartridge' do
|
332
|
+
it { run_output.should match(/This gear costs an additional \$0\.05 per gear after the first 3 gears./) }
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
309
336
|
describe 'cartridge show scaled' do
|
310
337
|
let!(:rest_client){ MockRestClient.new }
|
311
338
|
let(:arguments) { ['cartridge', 'show', 'mock_type', '-a', 'app1', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
|
@@ -8,6 +8,8 @@ describe RHC::Commands::Setup do
|
|
8
8
|
let(:instance){ subject.new }
|
9
9
|
let!(:config){ base_config }
|
10
10
|
before{ described_class.send(:public, *described_class.protected_instance_methods) }
|
11
|
+
before{ FakeFS::FileSystem.clear }
|
12
|
+
before{ RHC::Config.stub(:home_dir).and_return('/home/mock_user') }
|
11
13
|
|
12
14
|
describe '#run' do
|
13
15
|
it{ expects_running('setup').should call(:run).on(instance).with(no_args) }
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'rest_spec_helper'
|
2
3
|
require 'rhc/commands/sshkey'
|
3
4
|
require 'rhc/config'
|
4
5
|
|
@@ -58,6 +59,24 @@ describe RHC::Commands::Sshkey do
|
|
58
59
|
rest_client.sshkeys.length.should == num_keys
|
59
60
|
end
|
60
61
|
end
|
62
|
+
|
63
|
+
it "does not throw an error on an empty file" do
|
64
|
+
FakeFS do
|
65
|
+
keys = rest_client.sshkeys
|
66
|
+
num_keys = keys.length
|
67
|
+
File.open('id_rsa.pub', 'w') do |f|
|
68
|
+
f << ''
|
69
|
+
end
|
70
|
+
expect { run }.should exit_with_code(128)
|
71
|
+
expect { run_output.should match(/Name:.* mockkey/) }
|
72
|
+
rest_client.sshkeys.length.should == num_keys
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
it "exits with status code Errno::EACCES::Errno" do
|
77
|
+
IO.should_receive(:read).and_return("ssh_foo bar")
|
78
|
+
expect { run }.should exit_with_code(128)
|
79
|
+
end
|
61
80
|
end
|
62
81
|
|
63
82
|
context "when adding an invalid key with --confirm" do
|
@@ -99,7 +118,7 @@ describe RHC::Commands::Sshkey do
|
|
99
118
|
#end
|
100
119
|
|
101
120
|
it "exits with status code Errno::EACCES::Errno" do
|
102
|
-
|
121
|
+
IO.should_receive(:read).and_raise(Errno::EACCES)
|
103
122
|
expect { run }.should exit_with_code(128)
|
104
123
|
end
|
105
124
|
|