rhc 1.28.5 → 1.29.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -12,7 +12,7 @@ module RHC::Auth
12
12
  @skip_interactive = !@password.nil?
13
13
  end
14
14
 
15
- def to_request(request)
15
+ def to_request(request, client=nil)
16
16
  request[:user] ||=
17
17
  lambda{ username || (request[:lazy_auth] != true && ask_username) || nil }
18
18
  request[:password] ||=
@@ -21,10 +21,10 @@ module RHC::Auth
21
21
  end
22
22
 
23
23
  def retry_auth?(response, client)
24
- if response.status == 401
25
- credentials_rejected
26
- else
24
+ if response && response.status != 401
27
25
  false
26
+ else
27
+ credentials_rejected
28
28
  end
29
29
  end
30
30
 
@@ -40,6 +40,10 @@ module RHC::Auth
40
40
  "Please sign in to start a new session to #{openshift_server}."
41
41
  end
42
42
 
43
+ def token_store_user_key
44
+ username
45
+ end
46
+
43
47
  attr_reader :username
44
48
 
45
49
  protected
@@ -14,31 +14,27 @@ module RHC::Auth
14
14
  read_token
15
15
  end
16
16
 
17
- def to_request(request)
18
- if auth and !token and (!@allows_tokens or @can_get_token == false)
19
- debug "Bypassing token auth"
20
- auth.to_request(request)
21
- else
22
- # If no token is available an empty one will be submitted at this
23
- # point. This is actually required in order for the retry logic to be
24
- # triggered in all cases.
25
- #
26
- # Previously a request with no authentication was submitted to trigger
27
- # this behavior but it was found not to work in certain scenarios where
28
- # Broker authentication is handled by Apache. In those cases a 403 is
29
- # returned and not secondary authentication attempt is made.
17
+ def to_request(request, client=nil)
18
+ if !token and auth and @allows_tokens and client and client.supports_sessions?
19
+ debug "Attempting to generate token"
20
+ token_rejected(nil, client)
21
+ end
22
+
23
+ if token
30
24
  debug "Using token authentication"
31
25
  (request[:headers] ||= {})['authorization'] = "Bearer #{token}"
26
+ elsif auth
27
+ debug "Bypassing token auth"
28
+ auth.to_request(request, client)
32
29
  end
33
30
  request
34
31
  end
35
32
 
36
33
  def retry_auth?(response, client)
37
- case response.status
38
- when 401
39
- token_rejected(response, client)
40
- else
34
+ if response && response.status != 401
41
35
  false
36
+ else
37
+ token_rejected(response, client)
42
38
  end
43
39
  end
44
40
 
@@ -46,8 +42,12 @@ module RHC::Auth
46
42
  auth && auth.respond_to?(:username) && auth.username || options[:username]
47
43
  end
48
44
 
45
+ def token_store_user_key
46
+ auth && auth.respond_to?(:token_store_user_key) && auth.token_store_user_key || username
47
+ end
48
+
49
49
  def save(token)
50
- store.put(username, openshift_server, token) if store
50
+ store.put(token_store_user_key, openshift_server, token) if store
51
51
  @token = token
52
52
  end
53
53
 
@@ -101,7 +101,7 @@ module RHC::Auth
101
101
  end
102
102
 
103
103
  def read_token
104
- @token ||= store.get(username, openshift_server) if store
104
+ @token ||= store.get(token_store_user_key, openshift_server) if store
105
105
  end
106
106
 
107
107
  def cannot_retry?
@@ -4,33 +4,23 @@ module RHC::Auth
4
4
  @options = args[0] || Commander::Command::Options.new
5
5
  end
6
6
 
7
- def to_request(request)
7
+ def to_request(request, client=nil)
8
8
  request[:client_cert] = certificate_file(options.ssl_client_cert_file)
9
- request[:client_key] = rsa_key_file(options.ssl_client_key_file)
9
+ request[:client_key] = certificate_key(options.ssl_client_key_file)
10
10
  request
11
11
  end
12
12
 
13
- def certificate_file(file)
14
- file && OpenSSL::X509::Certificate.new(IO.read(File.expand_path(file)))
15
- rescue => e
16
- debug e
17
- raise OptionParser::InvalidOption.new(nil, "The certificate '#{file}' cannot be loaded: #{e.message} (#{e.class})")
18
- end
19
-
20
- def rsa_key_file(file)
21
- file && OpenSSL::PKey::RSA.new(IO.read(File.expand_path(file)))
22
- rescue => e
23
- debug e
24
- raise OptionParser::InvalidOption.new(nil, "The RSA key '#{file}' cannot be loaded: #{e.message} (#{e.class})")
13
+ def token_store_user_key
14
+ certificate_fingerprint(options.ssl_client_cert_file)
25
15
  end
26
16
 
27
17
  def retry_auth?(response, client)
28
18
  # This is really only hit in the case of token auth falling back to x509.
29
19
  # x509 auth doesn't usually get 401s.
30
- if response.status == 401
31
- true
32
- else
20
+ if response && response.status != 401
33
21
  false
22
+ else
23
+ true
34
24
  end
35
25
  end
36
26
 
@@ -18,8 +18,13 @@ module RHC::Commands
18
18
  display_region(region)
19
19
  end
20
20
 
21
- paragraph{ say "To create an app in a specific region use 'rhc create-app <name> <cartridge> --region <region>'." }
22
-
21
+ paragraph do
22
+ if regions.find{|r| r.allow_selection?}.blank?
23
+ warn "Regions can't be explicitly provided by users and will be automatically selected by the system."
24
+ else
25
+ say "To create an app in a specific region use 'rhc create-app <name> <cartridge> --region <region>'."
26
+ end
27
+ end
23
28
  0
24
29
  end
25
30
 
@@ -86,6 +86,7 @@ module RHC::Commands
86
86
  option ["--timeout SECONDS"], "The default timeout for operations on this server", :type => Integer
87
87
  option ["--ssl-ca-file FILE"], "An SSL certificate CA file (may contain multiple certs) to be used on this server", :type => CertificateFile, :optional => true
88
88
  option ["--ssl-client-cert-file FILE"], "An SSL x509 client certificate file to be used on this server", :type => CertificateFile, :optional => true
89
+ option ["--ssl-client-key-file FILE"], "An RSA client certificate key", :type => CertificateKey, :optional => true
89
90
  option ["--ssl-version VERSION"], "The version of SSL to use to be used on this server", :type => SSLVersion, :optional => true
90
91
  def add(hostname, nickname)
91
92
  raise ArgumentError, "The --use and --skip-wizard options cannot be used together." if options.use && options.skip_wizard
@@ -177,6 +178,7 @@ module RHC::Commands
177
178
  option ["--timeout SECONDS"], "The default timeout for operations on this server", :type => Integer
178
179
  option ["--ssl-ca-file FILE"], "An SSL certificate CA file (may contain multiple certs) to be used on this server", :type => CertificateFile, :optional => true
179
180
  option ["--ssl-client-cert-file FILE"], "An SSL x509 client certificate file to be used on this server", :type => CertificateFile, :optional => true
181
+ option ["--ssl-client-key-file FILE"], "An RSA client certificate key", :type => CertificateKey, :optional => true
180
182
  option ["--ssl-version VERSION"], "The version of SSL to use to be used on this server", :type => SSLVersion, :optional => true
181
183
  def configure(server)
182
184
  raise ArgumentError, "The --use and --skip-wizard options cannot be used together." if options.use && options.skip_wizard
@@ -130,7 +130,6 @@ module RHC
130
130
 
131
131
  @default_proxy = nil
132
132
 
133
- @defaults.add('insecure', false)
134
133
  @defaults.add('libra_server', openshift_online_server)
135
134
 
136
135
  @env_config.add('libra_server', libra_server_env) if libra_server_env
@@ -367,7 +366,12 @@ module RHC
367
366
 
368
367
  def servers_config
369
368
  lazy_init
370
- (servers.find(self['libra_server']).to_config rescue nil) || (servers.list.first.to_config rescue nil)
369
+ libra_server_conf = (@local_config['libra_server'] rescue nil) || (@global_config['libra_server'] rescue nil)
370
+ if libra_server_conf
371
+ servers.find(libra_server_conf).to_config rescue nil
372
+ else
373
+ servers.list.first.to_config rescue nil
374
+ end
371
375
  end
372
376
 
373
377
  def lazy_init
@@ -154,6 +154,7 @@ module RHC
154
154
  end
155
155
 
156
156
  OptionParser.accept(CertificateFile = Class.new) {|s| certificate_file(s); s}
157
+ OptionParser.accept(CertificateKey = Class.new) {|s| certificate_key(s); s}
157
158
 
158
159
  def role_name(s)
159
160
  ROLES[s.downcase]
@@ -186,7 +187,17 @@ module RHC
186
187
  end
187
188
 
188
189
  def token_for_user
189
- options.token or (token_store.get(options.rhlogin, options.server) if options.rhlogin && options.use_authorization_tokens)
190
+ return options.token if options.token
191
+ return nil unless options.use_authorization_tokens
192
+
193
+ token_store_user_key = if options.ssl_client_cert_file
194
+ certificate_fingerprint(options.ssl_client_cert_file)
195
+ else
196
+ options.rhlogin
197
+ end
198
+
199
+ return nil if token_store_user_key.nil?
200
+ token_store.get(token_store_user_key, options.server)
190
201
  end
191
202
 
192
203
  def client_from_options(opts)
@@ -213,11 +224,15 @@ module RHC
213
224
  raise OptionParser::InvalidOption.new(nil, "The certificate '#{file}' cannot be loaded: #{e.message} (#{e.class})")
214
225
  end
215
226
 
227
+ def certificate_fingerprint(file)
228
+ Digest::SHA1.hexdigest(certificate_file(file).to_der)
229
+ end
230
+
216
231
  def certificate_key(file)
217
232
  file && OpenSSL::PKey::RSA.new(IO.read(File.expand_path(file)))
218
233
  rescue => e
219
234
  debug e
220
- raise OptionParser::InvalidOption.new(nil, "The key '#{file}' cannot be loaded: #{e.message} (#{e.class})")
235
+ raise OptionParser::InvalidOption.new(nil, "The RSA key '#{file}' cannot be loaded: #{e.message} (#{e.class})")
221
236
  end
222
237
 
223
238
  def parse_ssl_version(version)
@@ -73,7 +73,7 @@ module RHC
73
73
 
74
74
  def display_server(server)
75
75
  paragraph do
76
- header ["Server '#{server.nickname || to_host(server.hostname)}'", ("(in use)" if server.default?)], {:color => (:green if server.default?)} do
76
+ header ["Server '#{server.nickname || to_host(server.hostname)}'", (server.persisted? ? ("(in use)" if server.default?) : "(not configured, run 'rhc setup')")], {:color => (server.persisted? ? (:green if server.default?) : :yellow)} do
77
77
  section(:bottom => 1) do
78
78
  say format_table \
79
79
  nil,
@@ -90,7 +90,7 @@ module RHC
90
90
  ),
91
91
  {
92
92
  :delete => true,
93
- :color => (:green if server.default?)
93
+ :color => (server.persisted? ? (:green if server.default?) : :yellow)
94
94
  }
95
95
  end
96
96
  end
@@ -14,7 +14,7 @@ module RHC
14
14
  :url => client.url,
15
15
  :method => :get,
16
16
  :accept => :json,
17
- :lazy_auth => true,
17
+ :no_auth => true,
18
18
  })
19
19
  debug "Server supports API versions #{@server_api_versions.join(', ')}"
20
20
 
@@ -28,7 +28,7 @@ module RHC
28
28
  :method => :get,
29
29
  :accept => :json,
30
30
  :api_version => api_version_negotiated,
31
- :lazy_auth => true,
31
+ :no_auth => true,
32
32
  })
33
33
  end
34
34
  else
@@ -564,8 +564,9 @@ module RHC
564
564
  options[:send_timeout] ||= options[:timeout] || 0
565
565
  options[:timeout] = nil
566
566
 
567
- if auth = options[:auth] || self.auth
568
- auth.to_request(options)
567
+ auth = (options[:auth] || self.auth) unless options[:no_auth]
568
+ if auth
569
+ auth.to_request(options, self)
569
570
  end
570
571
 
571
572
  headers = (self.headers.to_a + (options.delete(:headers) || []).to_a).inject({}) do |h,(k,v)|
@@ -597,6 +598,7 @@ module RHC
597
598
 
598
599
  # remove all unnecessary options
599
600
  options.delete(:lazy_auth)
601
+ options.delete(:no_auth)
600
602
  options.delete(:accept)
601
603
 
602
604
  args = [options.delete(:method), options.delete(:url), query, payload, headers, true]
@@ -271,8 +271,8 @@ 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))
274
+ def stub_simple_regions(empty=false, allow_selection=true, with_auth=mock_user_auth)
275
+ stub_api_request(:get, 'broker/rest/regions', with_auth).to_return(simple_regions(empty, allow_selection))
276
276
  end
277
277
 
278
278
  def define_exceptional_test_on_wizard
@@ -327,13 +327,13 @@ module RHC::Rest::Mock
327
327
  }
328
328
  end
329
329
 
330
- def simple_regions(empty=false)
330
+ def simple_regions(empty=false, allow_selection=true)
331
331
  {
332
332
  :body => {
333
333
  :type => 'regions',
334
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'}]},
335
+ {:id => 'region0001', :default => false, :name => 'north', :allow_selection => allow_selection, :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', :allow_selection => allow_selection, :zones => [{:name => 'east', :created_at => '2014-01-01T01:00:00Z', :updated_at => '2014-01-01T01:00:00Z'}]},
337
337
  ],
338
338
  }.to_json
339
339
  }
@@ -1,11 +1,15 @@
1
1
  module RHC::Rest
2
2
  class Region < Base
3
- define_attr :id, :name, :description, :default
3
+ define_attr :id, :name, :description, :default, :allow_selection
4
4
 
5
5
  def default?
6
6
  !!default
7
7
  end
8
8
 
9
+ def allow_selection?
10
+ !!allow_selection
11
+ end
12
+
9
13
  def uuid
10
14
  client.api_version_negotiated >= 1.6 ? attributes['id'] : attributes['uuid']
11
15
  end
@@ -10,10 +10,11 @@ module RHC
10
10
  attr_accessor :use_authorization_tokens, :insecure, :timeout
11
11
  attr_accessor :ssl_version, :ssl_client_cert_file, :ssl_client_key_file, :ssl_ca_file
12
12
  attr_accessor :default
13
+ attr_accessor :persisted
13
14
 
14
15
  def self.from_yaml_hash(hash)
15
16
  hash.symbolize_keys!
16
- Server.new(hash.delete(:hostname), hash)
17
+ Server.new(hash.delete(:hostname), hash.merge(:persisted => true))
17
18
  end
18
19
 
19
20
  def initialize(hostname, args={})
@@ -28,12 +29,17 @@ module RHC
28
29
  @ssl_client_key_file = args[:ssl_client_key_file]
29
30
  @ssl_ca_file = args[:ssl_ca_file]
30
31
  @default = args[:default]
32
+ @persisted = args[:persisted]
31
33
  end
32
34
 
33
35
  def default?
34
36
  !!@default
35
37
  end
36
38
 
39
+ def persisted?
40
+ !!@persisted
41
+ end
42
+
37
43
  def designation
38
44
  @nickname || @hostname
39
45
  end
@@ -43,7 +49,7 @@ module RHC
43
49
  instance_variables.each do |k|
44
50
  h[k.to_s.delete('@')] = instance_variable_get(k)
45
51
  end
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 }
52
+ end.reject{|k, v| v.nil? || k == 'default' || k == 'persisted'}.inject({}){|h, (k, v)| h[k] = v.is_a?(String) || v.is_a?(Symbol) ? v.to_s : v; h }
47
53
  end
48
54
 
49
55
  def to_config
@@ -155,14 +161,17 @@ module RHC
155
161
  :ssl_client_cert_file => o[:ssl_client_cert_file],
156
162
  :ssl_client_key_file => o[:ssl_client_key_file],
157
163
  :ssl_ca_file => o[:ssl_ca_file])
158
- list.each{|server| server.default = server.hostname == o[:server]}
164
+ list.each do |server|
165
+ server.default = server.hostname == o[:server]
166
+ server.persisted = true if !present?
167
+ end
159
168
  end
160
169
  end
161
170
 
162
171
  def save!
163
172
  FileUtils.mkdir_p File.dirname(path)
164
173
  File.open(path, 'w') do |c|
165
- c.puts list.collect{|s| {'server' => s.to_yaml_hash}}.to_yaml
174
+ c.puts list.collect{|s| s.persisted = true; {'server' => s.to_yaml_hash}}.to_yaml
166
175
  end
167
176
  self
168
177
  end
@@ -251,6 +251,28 @@ describe RHC::Auth::X509 do
251
251
  end
252
252
  end
253
253
 
254
+ describe "#token_store_user_key" do
255
+ let(:cert) do
256
+ file = Tempfile.new('cert')
257
+ cert = OpenSSL::X509::Certificate.new
258
+ cert.version = 2
259
+ cert.serial = 1
260
+ cert.subject = OpenSSL::X509::Name.parse "/DC=org/DC=ruby-lang/CN=Ruby CA"
261
+ cert.issuer = cert.subject
262
+ cert.not_before = Time.now
263
+ cert.not_after = cert.not_before + 2 * 365 * 24 * 60 * 60
264
+ file.write(cert)
265
+ file.flush
266
+ file
267
+ end
268
+ let(:options){ Commander::Command::Options.new(:ssl_client_cert_file => cert.path) }
269
+ context "when the client cert is set", :focus => true do
270
+ it("should return the fingerprint") do
271
+ subject.token_store_user_key.length.should == 40
272
+ end
273
+ end
274
+ end
275
+
254
276
  describe "#to_request" do
255
277
  let(:request){ {} }
256
278
  let(:auth_hash){ {:client_cert => a_cert, :client_key => a_key} }
@@ -340,7 +362,8 @@ describe RHC::Auth::Token do
340
362
  end
341
363
 
342
364
  context "when initialized with a store" do
343
- subject{ described_class.new(nil, nil, store) }
365
+ subject{ described_class.new(nil, auth, store) }
366
+ let(:auth){ double(:token_store_user_key => nil) }
344
367
  let(:store){ double }
345
368
  before{ store.should_receive(:get).with(nil, 'openshift.redhat.com').and_return(token) }
346
369
  it("should read the token for the user") do
@@ -349,11 +372,11 @@ describe RHC::Auth::Token do
349
372
  end
350
373
 
351
374
  describe "#save" do
352
- subject{ described_class.new(nil, nil, store) }
375
+ subject{ described_class.new(nil, auth, store) }
353
376
  context "when store is set" do
377
+ let(:auth){ double(:token_store_user_key => 'foo') }
354
378
  let(:store){ double(:get => nil) }
355
379
  it("should call put on store") do
356
- subject.should_receive(:username).and_return('foo')
357
380
  subject.should_receive(:openshift_server).and_return('bar')
358
381
  store.should_receive(:put).with('foo', 'bar', token)
359
382
  subject.save(token)
@@ -378,17 +401,51 @@ describe RHC::Auth::Token do
378
401
  end
379
402
  end
380
403
 
381
- context "when token is not provided" do
382
- subject{ described_class.new(nil) }
404
+ context "when a token is not provided when secondary auth is provided" do
405
+ let(:auth) { double(:can_authenticate? => true, :get_token_message => '') }
406
+ let(:default_options){ {:use_authorization_tokens => true} }
407
+ subject{ described_class.new(default_options, auth) }
408
+
409
+ context "without session support" do
410
+ let(:client){ double('client', :supports_sessions? => false) }
411
+ it("should delegate to secondary auth") do
412
+ auth.should_receive(:to_request).with(request, client).and_return(request)
413
+ subject.should_receive(:token_rejected).never
414
+ subject.to_request(request, client).should == {}
415
+ end
416
+ end
417
+
418
+ context "with session support" do
419
+ let(:client){ double('client', :supports_sessions? => true) }
420
+ before do
421
+ client.should_receive(:new_session).with(:auth => auth).and_return(auth_token)
422
+ end
423
+
424
+ context "when a token request fails" do
425
+ let(:auth_token){ nil }
426
+ it("should delegate to secondary auth") do
427
+ auth.should_receive(:retry_auth?).once.and_return(true)
428
+ auth.should_receive(:to_request).once.and_return(request)
429
+ subject.to_request(request, client).should == {}
430
+ end
431
+ end
383
432
 
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 "}} }
433
+ context "when a token request succeeds" do
434
+ let(:auth_token){ double('auth_token', :token => token) }
435
+ it("should should use the newly created token") do
436
+ auth.should_receive(:to_request).never
437
+ subject.to_request(request, client).should == {:headers => {'authorization' => "Bearer #{token}"}}
438
+ end
439
+ end
440
+
441
+ end
385
442
  end
386
443
 
387
444
  context "when a parent auth class is passed" do
388
445
  subject{ described_class.new(nil, auth) }
389
446
  let(:auth){ double }
390
447
  it("should invoke the parent") do
391
- auth.should_receive(:to_request).with(request).and_return(request)
448
+ auth.should_receive(:to_request).with(request, nil).and_return(request)
392
449
  subject.to_request(request).should == request
393
450
  end
394
451
  end
@@ -2,6 +2,7 @@ require 'spec_helper'
2
2
  require 'rhc/commands/base'
3
3
  require 'rhc/exceptions'
4
4
  require 'rest_spec_helper'
5
+ require 'tempfile'
5
6
 
6
7
  describe RHC::Commands::Base do
7
8
 
@@ -432,6 +433,29 @@ describe RHC::Commands::Base do
432
433
  end
433
434
  end
434
435
 
436
+ context "with tokens enabled and a certificate" do
437
+ let(:config){ base_config{ |c, d| d.add('use_authorization_tokens', 'true') } }
438
+ let(:cert) do
439
+ file = Tempfile.new('cert')
440
+ cert = OpenSSL::X509::Certificate.new
441
+ cert.version = 2
442
+ cert.serial = 1
443
+ cert.subject = OpenSSL::X509::Name.parse "/DC=org/DC=ruby-lang/CN=Ruby CA"
444
+ cert.issuer = cert.subject
445
+ cert.not_before = Time.now
446
+ cert.not_after = cert.not_before + 2 * 365 * 24 * 60 * 60
447
+ file.write(cert)
448
+ file.flush
449
+ file
450
+ end
451
+ let(:arguments){ ['test', '--server', mock_uri, '--ssl-client-cert-file', cert.path] }
452
+ it("it should generate a certificate fingerprint") do
453
+ command = command_for(*arguments)
454
+ command.should_receive(:certificate_fingerprint).with(cert.path)
455
+ command.send(:token_for_user)
456
+ end
457
+ end
458
+
435
459
  context "with username and tokens enabled against a server without tokens" do
436
460
  let!(:config){ base_config{ |c, d| d.add('use_authorization_tokens', 'true') } }
437
461
  let(:username){ 'foo' }
@@ -28,6 +28,24 @@ describe RHC::Commands::Region do
28
28
  it{ expect{ run }.to exit_with_code(0) }
29
29
  end
30
30
 
31
+ context 'when allowing region selection' do
32
+ before do
33
+ stub_api
34
+ stub_simple_regions(false, true)
35
+ end
36
+ it{ run_output.should match /To create an app in a specific region use/ }
37
+ it{ expect{ run }.to exit_with_code(0) }
38
+ end
39
+
40
+ context 'when not allowing region selection' do
41
+ before do
42
+ stub_api
43
+ stub_simple_regions(false, false)
44
+ end
45
+ it{ run_output.should match /Regions can't be explicitly provided by users/ }
46
+ it{ expect{ run }.to exit_with_code(0) }
47
+ end
48
+
31
49
  context 'without server regions' do
32
50
  before do
33
51
  stub_api
@@ -9,8 +9,8 @@ describe RHC::Commands::Server do
9
9
  let(:rest_client) { MockRestClient.new }
10
10
  let(:default_options){}
11
11
  let(:options){ Commander::Command::Options.new(default_options) }
12
- let(:config){ RHC::Config.new.tap{ |c| c.stub(:home_dir).and_return('/home/mock_user') } }
13
12
  let(:servers){ RHC::Servers.new.tap{|c| c.stub(:home_dir).and_return('/home/mock_user') } }
13
+ let(:config){ RHC::Config.new.tap{ |c| c.stub(:home_dir).and_return('/home/mock_user') } }
14
14
  before do
15
15
  FakeFS.activate!
16
16
  FakeFS::FileSystem.clear
@@ -108,8 +108,6 @@ describe RHC::Commands::Server do
108
108
  end
109
109
 
110
110
  context "from express.conf and servers.yml" do
111
- let(:local_config_username){ 'local_config_user' }
112
- let(:local_config_password){ 'password' }
113
111
  let(:local_config_server){ 'openshift.redhat.com' }
114
112
  before do
115
113
  local_config
@@ -117,9 +115,8 @@ describe RHC::Commands::Server do
117
115
  end
118
116
  let(:arguments) { ['servers'] }
119
117
  it 'should output correctly' do
120
- run_output.should =~ /Server 'online' \(in use\)/
118
+ run_output.should =~ /Server 'online' \(not configured, run 'rhc setup'\)/
121
119
  run_output.should =~ /Hostname:\s+#{local_config_server}/
122
- run_output.should =~ /Login:\s+#{local_config_username}/
123
120
  run_output.should =~ /Server 'server1'/
124
121
  run_output.should =~ /Hostname:\s+openshift1.server.com/
125
122
  run_output.should =~ /Login:\s+user1/
@@ -131,9 +128,28 @@ describe RHC::Commands::Server do
131
128
  end
132
129
 
133
130
  context "from express.conf and several entries on servers.yml" do
131
+ let(:local_config_server){ 'openshift.redhat.com' }
132
+ let(:entries){ 3 }
133
+ before do
134
+ local_config
135
+ stub_servers_yml(entries)
136
+ end
137
+ let(:arguments) { ['servers'] }
138
+ it 'should output correctly' do
139
+ run_output.should =~ /Server 'online' \(not configured, run 'rhc setup'\)/
140
+ run_output.should =~ /Hostname:\s+#{local_config_server}/
141
+ Array(1..entries).each do |i|
142
+ run_output.should =~ /Server 'server#{i}'/
143
+ run_output.should =~ /Hostname:\s+openshift#{i}.server.com/
144
+ end
145
+ end
146
+ it { expect { run }.to exit_with_code(0) }
147
+ end
148
+
149
+ context "from express.conf and several entries on servers.yml, matching servers" do
150
+ let(:local_config_server){ 'openshift1.server.com' }
134
151
  let(:local_config_username){ 'local_config_user' }
135
152
  let(:local_config_password){ 'password' }
136
- let(:local_config_server){ 'openshift.redhat.com' }
137
153
  let(:entries){ 3 }
138
154
  before do
139
155
  local_config
@@ -141,7 +157,27 @@ describe RHC::Commands::Server do
141
157
  end
142
158
  let(:arguments) { ['servers'] }
143
159
  it 'should output correctly' do
144
- run_output.should =~ /Server 'online' \(in use\)/
160
+ run_output.should =~ /Server 'server1' \(in use\)/
161
+ run_output.should =~ /Hostname:\s+#{local_config_server}/
162
+ run_output.should =~ /Login:\s+#{local_config_username}/
163
+ Array(1..entries).each do |i|
164
+ run_output.should =~ /Server 'server#{i}'/
165
+ run_output.should =~ /Hostname:\s+openshift#{i}.server.com/
166
+ end
167
+ end
168
+ it { expect { run }.to exit_with_code(0) }
169
+ end
170
+
171
+ context "when express.conf server is not present in servers.yml" do
172
+ let(:local_config_server){ 'some.openshift.mycompany.com' }
173
+ let(:entries){ 3 }
174
+ before do
175
+ local_config
176
+ stub_servers_yml(entries)
177
+ end
178
+ let(:arguments) { ['servers'] }
179
+ it 'should output correctly' do
180
+ run_output.should =~ /Server '#{local_config_server}' \(not configured, run 'rhc setup'\)/
145
181
  run_output.should =~ /Hostname:\s+#{local_config_server}/
146
182
  Array(1..entries).each do |i|
147
183
  run_output.should =~ /Server 'server#{i}'/
@@ -501,7 +537,6 @@ describe RHC::Commands::Server do
501
537
 
502
538
  protected
503
539
  def stub_servers_yml(entries=1, &block)
504
- RHC::Servers.any_instance.stub(:save!)
505
540
  RHC::Servers.any_instance.stub(:present?).and_return(true)
506
541
  RHC::Servers.any_instance.stub(:load).and_return(
507
542
  Array(1..entries).collect do |i|
@@ -509,7 +544,8 @@ describe RHC::Commands::Server do
509
544
  :nickname => "server#{i}",
510
545
  :login => "user#{i}",
511
546
  :use_authorization_tokens => true,
512
- :insecure => false)
547
+ :insecure => false,
548
+ :persisted => true)
513
549
  end.tap{|i| yield i if block_given?})
514
550
  end
515
551
 
@@ -218,13 +218,13 @@ describe AllRhcHelpers do
218
218
  context "on the command line" do
219
219
  let(:arguments){ ['help', '--ssl-client-key-file=not_a_file'] }
220
220
  it{ expect{ run }.to exit_with_code(1) }
221
- it{ run_output.should match("The key 'not_a_file' cannot be loaded: No such") }
221
+ it{ run_output.should match("The RSA key 'not_a_file' cannot be loaded: No such") }
222
222
  end
223
223
  context "via the config" do
224
224
  before{ base_config{ |c, d| d.add 'ssl_client_key_file', 'not_a_file' } }
225
225
  let(:arguments){ ['help'] }
226
226
  it{ expect{ run }.to exit_with_code(1) }
227
- it{ run_output.should match("The key 'not_a_file' cannot be loaded: No such") }
227
+ it{ run_output.should match("The RSA key 'not_a_file' cannot be loaded: No such") }
228
228
  end
229
229
  end
230
230
 
@@ -404,6 +404,7 @@ module ClassSpecHelpers
404
404
  local_config.add('libra_server', server) if server
405
405
 
406
406
  c.instance_variable_set(:@local_config, local_config)
407
+ c.instance_variable_set(:@servers, RHC::Servers.new)
407
408
  opts = c.to_options
408
409
  opts[:rhlogin].should == user
409
410
  opts[:password].should == password
metadata CHANGED
@@ -5,9 +5,9 @@ version: !ruby/object:Gem::Version
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
- - 28
9
- - 5
10
- version: 1.28.5
8
+ - 29
9
+ - 7
10
+ version: 1.29.7
11
11
  platform: ruby
12
12
  authors:
13
13
  - Red Hat
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2014-08-02 00:00:00 Z
18
+ date: 2014-09-02 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: net-ssh