rhc 1.27.4 → 1.28.5
Sign up to get free protection for your applications and to get access to all the features.
- data/autocomplete/rhc_bash +87 -23
- data/lib/rhc/auth.rb +1 -0
- data/lib/rhc/auth/basic.rb +8 -0
- data/lib/rhc/auth/token.rb +16 -7
- data/lib/rhc/auth/x509.rb +53 -0
- data/lib/rhc/autocomplete.rb +8 -0
- data/lib/rhc/autocomplete_templates/bash.erb +4 -4
- data/lib/rhc/commands/app.rb +21 -8
- data/lib/rhc/commands/base.rb +16 -2
- data/lib/rhc/commands/env.rb +2 -1
- data/lib/rhc/commands/region.rb +27 -0
- data/lib/rhc/commands/server.rb +19 -10
- data/lib/rhc/commands/sshkey.rb +1 -0
- data/lib/rhc/config.rb +1 -0
- data/lib/rhc/context_helper.rb +13 -11
- data/lib/rhc/exceptions.rb +12 -0
- data/lib/rhc/helpers.rb +26 -7
- data/lib/rhc/output_helpers.rb +21 -0
- data/lib/rhc/rest.rb +1 -0
- data/lib/rhc/rest/application.rb +5 -0
- data/lib/rhc/rest/client.rb +21 -0
- data/lib/rhc/rest/domain.rb +2 -1
- data/lib/rhc/rest/membership.rb +2 -0
- data/lib/rhc/rest/mock.rb +31 -0
- data/lib/rhc/rest/region.rb +25 -0
- data/lib/rhc/servers.rb +6 -4
- data/lib/rhc/wizard.rb +17 -5
- data/spec/rhc/auth_spec.rb +77 -5
- data/spec/rhc/command_spec.rb +14 -2
- data/spec/rhc/commands/app_spec.rb +14 -1
- data/spec/rhc/commands/env_spec.rb +2 -2
- data/spec/rhc/commands/member_spec.rb +7 -0
- data/spec/rhc/commands/region_spec.rb +50 -0
- data/spec/rhc/helpers_spec.rb +14 -0
- data/spec/rhc/wizard_spec.rb +31 -0
- metadata +10 -5
data/lib/rhc/rest/mock.rb
CHANGED
@@ -271,6 +271,10 @@ module RHC::Rest::Mock
|
|
271
271
|
stub_api_request(:get, 'broker/rest/cartridges', with_auth).to_return(simple_carts)
|
272
272
|
end
|
273
273
|
|
274
|
+
def stub_simple_regions(empty=false, with_auth=mock_user_auth)
|
275
|
+
stub_api_request(:get, 'broker/rest/regions', with_auth).to_return(simple_regions(empty))
|
276
|
+
end
|
277
|
+
|
274
278
|
def define_exceptional_test_on_wizard
|
275
279
|
RHC::Wizard.module_eval <<-EOM
|
276
280
|
private
|
@@ -322,6 +326,19 @@ module RHC::Rest::Mock
|
|
322
326
|
}.to_json
|
323
327
|
}
|
324
328
|
end
|
329
|
+
|
330
|
+
def simple_regions(empty=false)
|
331
|
+
{
|
332
|
+
:body => {
|
333
|
+
:type => 'regions',
|
334
|
+
:data => empty ? [] : [
|
335
|
+
{:id => 'region0001', :default => false, :name => 'north', :description => 'Servers in the north of US', :zones => [{:name => 'west', :created_at => '2014-01-01T01:00:00Z', :updated_at => '2014-01-01T01:00:00Z'}, {:name => 'east', :created_at => '2014-01-01T01:00:00Z', :updated_at => '2014-01-01T01:00:00Z'}]},
|
336
|
+
{:id => 'region0002', :default => true, :name => 'south', :zones => [{:name => 'east', :created_at => '2014-01-01T01:00:00Z', :updated_at => '2014-01-01T01:00:00Z'}]},
|
337
|
+
],
|
338
|
+
}.to_json
|
339
|
+
}
|
340
|
+
end
|
341
|
+
|
325
342
|
def simple_user(login)
|
326
343
|
{
|
327
344
|
:body => {
|
@@ -435,6 +452,7 @@ module RHC::Rest::Mock
|
|
435
452
|
['LIST_DOMAINS', "broker/rest/domains", 'GET'],
|
436
453
|
['ADD_DOMAIN', "broker/rest/domains", 'POST', ({'optional_params' => [{'name' => 'allowed_gear_sizes'}]} if example_allows_gear_sizes?)].compact,
|
437
454
|
['LIST_CARTRIDGES', "broker/rest/cartridges", 'GET'],
|
455
|
+
['LIST_REGIONS', "broker/rest/regions", 'GET'],
|
438
456
|
])
|
439
457
|
end
|
440
458
|
|
@@ -636,6 +654,14 @@ module RHC::Rest::Mock
|
|
636
654
|
raise RHC::Rest::ApplicationNotFoundException.new("Application #{name} does not exist")
|
637
655
|
end
|
638
656
|
|
657
|
+
def find_application_gear_groups_endpoints(domain, name, options = {})
|
658
|
+
find_domain(domain).applications.each do |app|
|
659
|
+
return app.gear_groups if app.name.downcase == name.downcase
|
660
|
+
end
|
661
|
+
|
662
|
+
raise RHC::Rest::ApplicationNotFoundException.new("Application #{name} does not exist")
|
663
|
+
end
|
664
|
+
|
639
665
|
def find_application_gear_groups(domain, name, options = {})
|
640
666
|
find_domain(domain).applications.each do |app|
|
641
667
|
return app.gear_groups if app.name.downcase == name.downcase
|
@@ -844,6 +870,7 @@ module RHC::Rest::Mock
|
|
844
870
|
if scale
|
845
871
|
@scalable = true
|
846
872
|
end
|
873
|
+
@region = nil
|
847
874
|
self.attributes = {:links => mock_response_links(mock_app_links('mock_domain_0', 'mock_app_0')), :messages => []}
|
848
875
|
self.gear_count = 5
|
849
876
|
types = Array(type)
|
@@ -995,6 +1022,10 @@ module RHC::Rest::Mock
|
|
995
1022
|
@keep_deployments
|
996
1023
|
end
|
997
1024
|
|
1025
|
+
def region
|
1026
|
+
@region
|
1027
|
+
end
|
1028
|
+
|
998
1029
|
def deployments
|
999
1030
|
base_time1 = Time.local(2000,1,1,1,0,0).strftime('%Y-%m-%dT%H:%M:%S%z')
|
1000
1031
|
base_time2 = Time.local(2000,1,1,2,0,0).strftime('%Y-%m-%dT%H:%M:%S%z')
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module RHC::Rest
|
2
|
+
class Region < Base
|
3
|
+
define_attr :id, :name, :description, :default
|
4
|
+
|
5
|
+
def default?
|
6
|
+
!!default
|
7
|
+
end
|
8
|
+
|
9
|
+
def uuid
|
10
|
+
client.api_version_negotiated >= 1.6 ? attributes['id'] : attributes['uuid']
|
11
|
+
end
|
12
|
+
|
13
|
+
def zones
|
14
|
+
@zones ||= attributes['zones'].map{|z| z['name']}.sort
|
15
|
+
end
|
16
|
+
|
17
|
+
def <=>(other)
|
18
|
+
return self.name <=> other.name
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
self.name
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/rhc/servers.rb
CHANGED
@@ -8,7 +8,7 @@ module RHC
|
|
8
8
|
include RHC::ServerHelpers
|
9
9
|
attr_accessor :hostname, :nickname, :login
|
10
10
|
attr_accessor :use_authorization_tokens, :insecure, :timeout
|
11
|
-
attr_accessor :ssl_version, :ssl_client_cert_file, :ssl_ca_file
|
11
|
+
attr_accessor :ssl_version, :ssl_client_cert_file, :ssl_client_key_file, :ssl_ca_file
|
12
12
|
attr_accessor :default
|
13
13
|
|
14
14
|
def self.from_yaml_hash(hash)
|
@@ -23,8 +23,9 @@ module RHC
|
|
23
23
|
@use_authorization_tokens = RHC::Helpers.to_boolean(args[:use_authorization_tokens], true)
|
24
24
|
@insecure = RHC::Helpers.to_boolean(args[:insecure], true)
|
25
25
|
@timeout = Integer(args[:timeout]) if args[:timeout].present?
|
26
|
-
@ssl_version = args[:ssl_version]
|
26
|
+
@ssl_version = RHC::Helpers.parse_ssl_version(args[:ssl_version])
|
27
27
|
@ssl_client_cert_file = args[:ssl_client_cert_file]
|
28
|
+
@ssl_client_key_file = args[:ssl_client_key_file]
|
28
29
|
@ssl_ca_file = args[:ssl_ca_file]
|
29
30
|
@default = args[:default]
|
30
31
|
end
|
@@ -42,7 +43,7 @@ module RHC
|
|
42
43
|
instance_variables.each do |k|
|
43
44
|
h[k.to_s.delete('@')] = instance_variable_get(k)
|
44
45
|
end
|
45
|
-
end.reject{|k, v| v.nil? || k == 'default'}.inject({}){|h, (k, v)| h[k] = v.is_a?(String) ? v.to_s : v; h }
|
46
|
+
end.reject{|k, v| v.nil? || k == 'default'}.inject({}){|h, (k, v)| h[k] = v.is_a?(String) || v.is_a?(Symbol) ? v.to_s : v; h }
|
46
47
|
end
|
47
48
|
|
48
49
|
def to_config
|
@@ -152,6 +153,7 @@ module RHC
|
|
152
153
|
:timeout => o[:timeout],
|
153
154
|
:ssl_version => o[:ssl_version],
|
154
155
|
:ssl_client_cert_file => o[:ssl_client_cert_file],
|
156
|
+
:ssl_client_key_file => o[:ssl_client_key_file],
|
155
157
|
:ssl_ca_file => o[:ssl_ca_file])
|
156
158
|
list.each{|server| server.default = server.hostname == o[:server]}
|
157
159
|
end
|
@@ -189,4 +191,4 @@ module RHC
|
|
189
191
|
s.present? && s.hostname != hostname ? nil : suggestion
|
190
192
|
end
|
191
193
|
end
|
192
|
-
end
|
194
|
+
end
|
data/lib/rhc/wizard.rb
CHANGED
@@ -97,7 +97,13 @@ module RHC
|
|
97
97
|
end
|
98
98
|
|
99
99
|
def core_auth
|
100
|
-
@core_auth ||=
|
100
|
+
@core_auth ||= begin
|
101
|
+
if options.ssl_client_cert_file && options.ssl_client_key_file
|
102
|
+
RHC::Auth::X509.new(options)
|
103
|
+
else
|
104
|
+
RHC::Auth::Basic.new(options)
|
105
|
+
end
|
106
|
+
end
|
101
107
|
end
|
102
108
|
|
103
109
|
def token_auth
|
@@ -144,6 +150,10 @@ module RHC
|
|
144
150
|
ssh_keys.present? && ssh_keys.any? { |k| k.fingerprint.present? && k.fingerprint == fingerprint_for_default_key }
|
145
151
|
end
|
146
152
|
|
153
|
+
def non_ssh_key_uploaded?
|
154
|
+
ssh_keys.present? && !ssh_keys.all?(&:is_ssh?)
|
155
|
+
end
|
156
|
+
|
147
157
|
def existing_keys_info
|
148
158
|
return unless ssh_keys
|
149
159
|
indent{ ssh_keys.each{ |key| paragraph{ display_key(key) } } }
|
@@ -221,10 +231,12 @@ module RHC
|
|
221
231
|
self.user = rest_client.user
|
222
232
|
options.rhlogin = self.user.login unless username
|
223
233
|
|
224
|
-
if
|
234
|
+
if options.create_token == false
|
235
|
+
say "Skipping token generation..."
|
236
|
+
elsif rest_client.supports_sessions? && !options.token
|
225
237
|
paragraph do
|
226
238
|
info "OpenShift can create and store a token on disk which allows to you to access the server without using your password. The key is stored in your home directory and should be kept secret. You can delete the key at any time by running 'rhc logout'."
|
227
|
-
if
|
239
|
+
if agree "Generate a token now? (yes|no) "
|
228
240
|
say "Generating an authorization token for this client ... "
|
229
241
|
token = rest_client.new_session
|
230
242
|
options.token = token.token
|
@@ -303,7 +315,7 @@ module RHC
|
|
303
315
|
end
|
304
316
|
|
305
317
|
def upload_ssh_key_stage
|
306
|
-
return true if ssh_key_uploaded?
|
318
|
+
return true if ssh_key_uploaded? || non_ssh_key_uploaded?
|
307
319
|
|
308
320
|
upload = paragraph do
|
309
321
|
agree "Your public SSH key must be uploaded to the OpenShift server to access code. Upload now? (yes|no) "
|
@@ -530,7 +542,7 @@ module RHC
|
|
530
542
|
|
531
543
|
# test connectivity an app
|
532
544
|
def test_ssh_connectivity
|
533
|
-
return true unless ssh_key_uploaded?
|
545
|
+
return true unless ssh_key_uploaded? || non_ssh_key_uploaded?
|
534
546
|
|
535
547
|
applications.take(1).each do |app|
|
536
548
|
begin
|
data/spec/rhc/auth_spec.rb
CHANGED
@@ -16,6 +16,8 @@ describe RHC::Auth::Basic do
|
|
16
16
|
its(:options){ should_not be_nil }
|
17
17
|
its(:can_authenticate?){ should be_false }
|
18
18
|
its(:openshift_server){ should == 'openshift.redhat.com' }
|
19
|
+
its( :expired_token_message) { should == "Your authorization token has expired. Please sign in now to continue on #{subject.openshift_server}." }
|
20
|
+
its( :get_token_message) { should == "Please sign in to start a new session to #{subject.openshift_server}." }
|
19
21
|
|
20
22
|
def resolved(hash)
|
21
23
|
hash.each_pair do |k,v|
|
@@ -221,6 +223,68 @@ describe RHC::Auth::Basic do
|
|
221
223
|
end
|
222
224
|
end
|
223
225
|
|
226
|
+
describe RHC::Auth::X509 do
|
227
|
+
subject{ described_class.new(options) }
|
228
|
+
|
229
|
+
let(:default_options){ {} }
|
230
|
+
let(:options){ (o = Commander::Command::Options.new).default(default_options); o }
|
231
|
+
let(:a_cert){ OpenSSL::X509::Certificate.new }
|
232
|
+
let(:a_key){ OpenSSL::PKey::RSA.new }
|
233
|
+
its(:options){ should_not be_nil }
|
234
|
+
its(:can_authenticate?){ should be_true }
|
235
|
+
its(:openshift_server){ should == 'openshift.redhat.com' }
|
236
|
+
its(:expired_token_message) { should == "Your authorization token has expired. Fetching a new token from #{subject.openshift_server}."}
|
237
|
+
its(:get_token_message) { should == "Fetching a new token from #{subject.openshift_server}." }
|
238
|
+
|
239
|
+
describe "#retry_auth?" do
|
240
|
+
context "should return true if the response was 401" do
|
241
|
+
let(:response){ double(:status => 401) }
|
242
|
+
let(:client){ double }
|
243
|
+
it { subject.retry_auth?(response, client).should == true }
|
244
|
+
end
|
245
|
+
|
246
|
+
context "should return false if the response was 403" do
|
247
|
+
let(:response){ double }
|
248
|
+
let(:client){ double }
|
249
|
+
let(:response){ double(:status => 403) }
|
250
|
+
it { subject.retry_auth?(response, client).should == false }
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
describe "#to_request" do
|
255
|
+
let(:request){ {} }
|
256
|
+
let(:auth_hash){ {:client_cert => a_cert, :client_key => a_key} }
|
257
|
+
|
258
|
+
context "when a certificate exists" do
|
259
|
+
it "should use x509 auth" do
|
260
|
+
OpenSSL::X509::Certificate.should_receive(:new).exactly(1).times.and_return(a_cert)
|
261
|
+
OpenSSL::PKey::RSA.should_receive(:new).exactly(1).times.and_return(a_key)
|
262
|
+
subject.to_request(request).should == auth_hash
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
context "when a certificate can't be loaded" do
|
267
|
+
it "should send a debug message and raise an error" do
|
268
|
+
options.should_receive(:ssl_client_cert_file).and_return("a bogus path")
|
269
|
+
subject.should_receive(:debug)
|
270
|
+
expect do
|
271
|
+
subject.to_request(request)
|
272
|
+
end.to raise_error
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
context "when a key can't be loaded" do
|
277
|
+
it "should send a debug message and raise an error" do
|
278
|
+
options.should_receive(:ssl_client_key_file).and_return("a bogus path")
|
279
|
+
subject.should_receive(:debug)
|
280
|
+
expect do
|
281
|
+
subject.to_request(request)
|
282
|
+
end.to raise_error
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
224
288
|
describe RHC::Auth::Token do
|
225
289
|
subject{ described_class.new(options) }
|
226
290
|
|
@@ -317,7 +381,7 @@ describe RHC::Auth::Token do
|
|
317
381
|
context "when token is not provided" do
|
318
382
|
subject{ described_class.new(nil) }
|
319
383
|
|
320
|
-
it("should
|
384
|
+
it("should submit an empty bearer token to the server to trigger the 401 retry flow for OpenShift Enterprise"){ subject.to_request(request).should == {:headers => {'authorization' => "Bearer "}} }
|
321
385
|
end
|
322
386
|
|
323
387
|
context "when a parent auth class is passed" do
|
@@ -383,23 +447,28 @@ describe RHC::Auth::Token do
|
|
383
447
|
before{ client.should_receive(:new_session).with(:auth => auth).and_return(auth_token) }
|
384
448
|
|
385
449
|
it("should print a message") do
|
386
|
-
subject.should_receive(:info).with("
|
450
|
+
subject.should_receive(:info).with("get token message")
|
387
451
|
auth.should_receive(:retry_auth?).with(response, client).and_return true
|
452
|
+
auth.should_receive(:get_token_message).and_return("get token message")
|
388
453
|
subject.retry_auth?(response, client).should be_true
|
389
454
|
end
|
390
455
|
|
391
456
|
context "with a token" do
|
392
457
|
let(:default_options){ {:use_authorization_tokens => true, :token => 'foo'} }
|
393
458
|
it("should invoke raise an error on retry because sessions are not supported") do
|
394
|
-
subject.should_receive(:warn).with("
|
459
|
+
subject.should_receive(:warn).with("expired token message")
|
395
460
|
auth.should_receive(:retry_auth?).with(response, client).and_return true
|
461
|
+
auth.should_receive(:expired_token_message).and_return("expired token message")
|
396
462
|
subject.retry_auth?(response, client).should be_true
|
397
463
|
#expect{ subject.retry_auth?(response, client) }.to raise_error RHC::Rest::AuthorizationsNotSupported
|
398
464
|
end
|
399
465
|
end
|
400
466
|
|
401
467
|
context "when the token request fails" do
|
402
|
-
before
|
468
|
+
before do
|
469
|
+
subject.should_receive(:info).with("get token message")
|
470
|
+
auth.should_receive(:get_token_message).and_return("get token message")
|
471
|
+
end
|
403
472
|
it("should invoke retry on the parent") do
|
404
473
|
auth.should_receive(:retry_auth?).with(response, client).and_return false
|
405
474
|
subject.retry_auth?(response, client).should be_false
|
@@ -408,7 +477,10 @@ describe RHC::Auth::Token do
|
|
408
477
|
|
409
478
|
context "when the token request succeeds" do
|
410
479
|
let(:auth_token){ double('auth_token', :token => 'bar') }
|
411
|
-
before
|
480
|
+
before do
|
481
|
+
subject.should_receive(:info).with("get token message")
|
482
|
+
auth.should_receive(:get_token_message).and_return("get token message")
|
483
|
+
end
|
412
484
|
it("should save the token and return true") do
|
413
485
|
subject.should_receive(:save).with(auth_token.token).and_return true
|
414
486
|
subject.retry_auth?(response, client).should be_true
|
data/spec/rhc/command_spec.rb
CHANGED
@@ -325,12 +325,15 @@ describe RHC::Commands::Base do
|
|
325
325
|
|
326
326
|
describe "rest_client" do
|
327
327
|
let(:instance){ subject }
|
328
|
+
let(:options){ subject.send(:options) }
|
328
329
|
before{ RHC::Rest::Client.any_instance.stub(:api_version_negotiated).and_return(1.4) }
|
329
330
|
|
330
331
|
context "when initializing the object" do
|
331
332
|
let(:auth){ double('auth') }
|
332
333
|
let(:basic_auth){ double('basic_auth') }
|
333
|
-
|
334
|
+
let(:x509_auth){ double('x509_auth') }
|
335
|
+
before{ RHC::Auth::Basic.stub(:new).with{ |arg| arg.should == instance.send(:options) }.and_return(basic_auth) }
|
336
|
+
before{ RHC::Auth::X509.stub(:new).with{ |arg| arg.should == instance.send(:options) }.and_return(x509_auth) }
|
334
337
|
before{ RHC::Auth::Token.stub(:new).with{ |arg, arg2, arg3| [arg, arg2, arg3].should == [instance.send(:options), basic_auth, instance.send(:token_store)] }.and_return(auth) }
|
335
338
|
|
336
339
|
context "with no options" do
|
@@ -338,6 +341,15 @@ describe RHC::Commands::Base do
|
|
338
341
|
it("should create only a basic auth object"){ subject.send(:rest_client) }
|
339
342
|
end
|
340
343
|
|
344
|
+
context "with x509" do
|
345
|
+
before do
|
346
|
+
options.should_receive(:ssl_client_cert_file).and_return("a cert")
|
347
|
+
options.should_receive(:ssl_client_key_file).and_return("a key")
|
348
|
+
subject.should_receive(:client_from_options).with(:auth => x509_auth)
|
349
|
+
end
|
350
|
+
it("should create an x509 auth object"){ subject.send(:rest_client) }
|
351
|
+
end
|
352
|
+
|
341
353
|
context "with use_authorization_tokens" do
|
342
354
|
before{ subject.send(:options).use_authorization_tokens = true }
|
343
355
|
before{ subject.should_receive(:client_from_options).with(:auth => auth) }
|
@@ -413,7 +425,7 @@ describe RHC::Commands::Base do
|
|
413
425
|
let(:auth_token){ double(:token => 'a_token') }
|
414
426
|
let(:arguments){ ['test', '-l', username, '--server', mock_uri] }
|
415
427
|
before{ instance.send(:token_store).should_receive(:get).with{ |user, server| user.should == username; server.should == instance.send(:openshift_server) }.and_return(nil) }
|
416
|
-
before{ stub_api(false, true); stub_api_request(:get, 'broker/rest/user', false).to_return{ |request| request.headers['Authorization'] =~ /Bearer
|
428
|
+
before{ stub_api(false, true); stub_api_request(:get, 'broker/rest/user', false).to_return{ |request| request.headers['Authorization'] =~ /Bearer\s\w+/ ? simple_user(username) : {:status => 401} } }
|
417
429
|
it("should attempt to create a new token") do
|
418
430
|
rest_client.should_receive(:new_session).ordered.and_return(auth_token)
|
419
431
|
rest_client.user
|
@@ -164,6 +164,7 @@ describe RHC::Commands::App do
|
|
164
164
|
before{ RHC::Config.any_instance.stub(:has_local_config?).and_return(false) }
|
165
165
|
before{ described_class.any_instance.stub(:interactive?).and_return(true) }
|
166
166
|
before{ rest_client.domains.clear }
|
167
|
+
before{ rest_client.sshkeys.delete_if {|k| !k.is_ssh? } }
|
167
168
|
let(:arguments) { ['app', 'create', 'app1', 'mock_standalone_cart-1'] }
|
168
169
|
# skips login stage and insecure check because of mock rest client, doesn't check keys
|
169
170
|
it { run_output(['mydomain', 'y', 'mykey']).should match(/This wizard.*Checking for a domain.*You will not be able to create an application without completing this step.*Your domain 'mydomain' has been successfully created.*Creating application.*Your public SSH key.*Uploading key 'mykey'.*Your application 'app1' is now available.*Cloned to/m) }
|
@@ -730,16 +731,28 @@ describe RHC::Commands::App do
|
|
730
731
|
end
|
731
732
|
|
732
733
|
describe 'app show --gears' do
|
733
|
-
let(:arguments) { ['app', 'show', 'app1', '--gears'] }
|
734
|
+
let(:arguments) { ['app', 'show', 'app1', '--gears', '--raw'] }
|
734
735
|
|
735
736
|
context 'when run' do
|
736
737
|
before do
|
737
738
|
@domain = rest_client.add_domain("mockdomain")
|
738
739
|
@domain.add_application("app1", "mock_type")
|
739
740
|
end
|
741
|
+
it { run_output.should match(/ID\s+State\s+Cartridges\s+Size\s+SSH URL/) }
|
740
742
|
it { run_output.should match("fakegearid0 started mock_type small fakegearid0@fakesshurl.com") }
|
741
743
|
it { expect{ run }.to exit_with_code(0) }
|
742
744
|
end
|
745
|
+
|
746
|
+
context 'with regions and zones' do
|
747
|
+
before do
|
748
|
+
@domain = rest_client.add_domain("mockdomain")
|
749
|
+
@app = @domain.add_application("app1", "mock_type")
|
750
|
+
@app.gears.each{|g| g['region'] = 'south'; g['zone'] = 'west'}
|
751
|
+
end
|
752
|
+
it { run_output.should match(/ID\s+State\s+Cartridges\s+Size\s+Region\s+Zone\s+SSH URL/) }
|
753
|
+
it { run_output.should match(/fakegearid0\s+started\s+mock_type\s+small\s+south\s+west\s+fakegearid0@fakesshurl.com/) }
|
754
|
+
it { expect{ run }.to exit_with_code(0) }
|
755
|
+
end
|
743
756
|
end
|
744
757
|
|
745
758
|
describe 'app show --gears quota' do
|
@@ -246,7 +246,7 @@ describe RHC::Commands::Env do
|
|
246
246
|
let(:arguments) { args }
|
247
247
|
it { succeed_with_message /TEST_ENV_VAR/ }
|
248
248
|
it { succeed_with_message /Removing environment variable\(s\) \.\.\./ }
|
249
|
-
it { succeed_with_message /
|
249
|
+
it { succeed_with_message /done/ }
|
250
250
|
end
|
251
251
|
end
|
252
252
|
|
@@ -259,7 +259,7 @@ describe RHC::Commands::Env do
|
|
259
259
|
it { succeed_with_message /TEST_ENV_VAR2/ }
|
260
260
|
it { succeed_with_message /TEST_ENV_VAR3/ }
|
261
261
|
it { succeed_with_message /Removing environment variable\(s\) \.\.\./ }
|
262
|
-
it { succeed_with_message /
|
262
|
+
it { succeed_with_message /done/ }
|
263
263
|
end
|
264
264
|
end
|
265
265
|
|
@@ -71,6 +71,13 @@ describe RHC::Commands::Member do
|
|
71
71
|
it("should include the login value") { run_output.should =~ /alice.*Bob.*carol.*doug@doug\.com/m }
|
72
72
|
end
|
73
73
|
|
74
|
+
context 'without membership support' do
|
75
|
+
let(:arguments) { ['domain', 'show', 'mock-domain-0'] }
|
76
|
+
before{ with_mock_domain }
|
77
|
+
let(:supports_members){ false }
|
78
|
+
it { expect { run }.to exit_with_code(0) }
|
79
|
+
it { run_output.should_not =~ /owned by/ }
|
80
|
+
end
|
74
81
|
end
|
75
82
|
|
76
83
|
describe 'list-member' do
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rest_spec_helper'
|
3
|
+
require 'rhc/commands/region'
|
4
|
+
require 'rhc/config'
|
5
|
+
|
6
|
+
describe RHC::Commands::Region do
|
7
|
+
before{ user_config }
|
8
|
+
|
9
|
+
describe 'region list' do
|
10
|
+
let(:arguments){ ['region', 'list'] }
|
11
|
+
let(:username){ nil }
|
12
|
+
let(:password){ nil }
|
13
|
+
let(:server){ mock_uri }
|
14
|
+
let(:user_auth){ false }
|
15
|
+
|
16
|
+
context 'with server regions' do
|
17
|
+
before do
|
18
|
+
stub_api
|
19
|
+
stub_simple_regions
|
20
|
+
end
|
21
|
+
|
22
|
+
it{ run_output.should match /Server test\.domain\.com$/ }
|
23
|
+
it{ run_output.should match /Region 'north' \(uuid: region0001\)$/ }
|
24
|
+
it{ run_output.should match /Description:\s+Servers in the north of US$/ }
|
25
|
+
it{ run_output.should match /Available Zones:\s+east, west$/ }
|
26
|
+
it{ run_output.should match /Region 'south' \(uuid: region0002\) \(default\)/ }
|
27
|
+
it{ run_output.should match /Available Zones: east$/ }
|
28
|
+
it{ expect{ run }.to exit_with_code(0) }
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'without server regions' do
|
32
|
+
before do
|
33
|
+
stub_api
|
34
|
+
stub_simple_regions(true)
|
35
|
+
end
|
36
|
+
|
37
|
+
it{ run_output.should_not match /Available Zones$/ }
|
38
|
+
it{ run_output.should match /Server doesn't have any regions or zones configured/ }
|
39
|
+
it{ expect{ run }.to exit_with_code(169) }
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'regions not supported on server' do
|
43
|
+
let!(:rest_client){ MockRestClient.new }
|
44
|
+
it{ run_output.should_not match /Available Zones$/ }
|
45
|
+
it{ run_output.should match /Server does not support regions and zones/ }
|
46
|
+
it{ expect{ run }.to exit_with_code(168) }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|