rhc 1.4.8 → 1.5.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. data/features/application.feature +1 -0
  2. data/features/lib/rhc_helper/app.rb +5 -3
  3. data/features/lib/rhc_helper/commandify.rb +2 -1
  4. data/features/step_definitions/application_steps.rb +2 -1
  5. data/features/support/env.rb +4 -1
  6. data/lib/rhc/auth/basic.rb +18 -13
  7. data/lib/rhc/auth/token.rb +98 -0
  8. data/lib/rhc/auth/token_store.rb +51 -0
  9. data/lib/rhc/auth.rb +3 -1
  10. data/lib/rhc/command_runner.rb +1 -0
  11. data/lib/rhc/commands/account.rb +47 -1
  12. data/lib/rhc/commands/alias.rb +2 -4
  13. data/lib/rhc/commands/app.rb +23 -18
  14. data/lib/rhc/commands/authorization.rb +93 -0
  15. data/lib/rhc/commands/base.rb +11 -3
  16. data/lib/rhc/commands/cartridge.rb +8 -16
  17. data/lib/rhc/commands/git_clone.rb +2 -3
  18. data/lib/rhc/commands/port_forward.rb +10 -11
  19. data/lib/rhc/commands/setup.rb +4 -1
  20. data/lib/rhc/commands/snapshot.rb +4 -3
  21. data/lib/rhc/commands/tail.rb +3 -4
  22. data/lib/rhc/commands/threaddump.rb +1 -2
  23. data/lib/rhc/commands.rb +37 -3
  24. data/lib/rhc/config.rb +10 -1
  25. data/lib/rhc/context_helper.rb +5 -1
  26. data/lib/rhc/core_ext.rb +10 -0
  27. data/lib/rhc/exceptions.rb +0 -12
  28. data/lib/rhc/git_helpers.rb +12 -0
  29. data/lib/rhc/helpers.rb +31 -1
  30. data/lib/rhc/output_helpers.rb +19 -3
  31. data/lib/rhc/rest/api.rb +2 -1
  32. data/lib/rhc/rest/application.rb +5 -4
  33. data/lib/rhc/rest/authorization.rb +10 -0
  34. data/lib/rhc/rest/base.rb +6 -1
  35. data/lib/rhc/rest/client.rb +243 -122
  36. data/lib/rhc/rest/domain.rb +0 -15
  37. data/lib/rhc/rest/gear_group.rb +0 -1
  38. data/lib/rhc/rest/mock.rb +118 -16
  39. data/lib/rhc/rest/user.rb +0 -1
  40. data/lib/rhc/rest.rb +28 -8
  41. data/lib/rhc/ssh_helpers.rb +5 -2
  42. data/lib/rhc/tar_gz.rb +16 -5
  43. data/lib/rhc/usage_templates/help.erb +1 -1
  44. data/lib/rhc/wizard.rb +54 -10
  45. data/spec/coverage_helper.rb +9 -0
  46. data/spec/rhc/auth_spec.rb +229 -22
  47. data/spec/rhc/cli_spec.rb +15 -0
  48. data/spec/rhc/command_spec.rb +100 -8
  49. data/spec/rhc/commands/account_spec.rb +75 -1
  50. data/spec/rhc/commands/app_spec.rb +23 -5
  51. data/spec/rhc/commands/authorization_spec.rb +120 -0
  52. data/spec/rhc/commands/domain_spec.rb +2 -2
  53. data/spec/rhc/commands/git_clone_spec.rb +24 -0
  54. data/spec/rhc/commands/port_forward_spec.rb +22 -23
  55. data/spec/rhc/commands/server_spec.rb +2 -2
  56. data/spec/rhc/commands/setup_spec.rb +12 -0
  57. data/spec/rhc/config_spec.rb +7 -3
  58. data/spec/rhc/helpers_spec.rb +62 -9
  59. data/spec/rhc/rest_application_spec.rb +24 -0
  60. data/spec/rhc/rest_client_spec.rb +66 -56
  61. data/spec/rhc/rest_spec.rb +11 -2
  62. data/spec/rhc/wizard_spec.rb +61 -12
  63. data/spec/spec_helper.rb +125 -42
  64. data/spec/wizard_spec_helper.rb +1 -0
  65. metadata +9 -3
@@ -19,6 +19,7 @@ Feature: Application Operations
19
19
  | running | snapshot | the snapshot | be found |
20
20
  | running | tidied | it | succeed |
21
21
  | running | shown | it | succeed |
22
+ | running | visualized| it | succeed |
22
23
  | running | stopped | the application | not be accessible |
23
24
  | stopped | started | the application | be accessible |
24
25
  # After the app is deleted, it is resolving to the OpenShift server
@@ -36,9 +36,11 @@ module RHCHelper
36
36
  # Setup questions asked by wizard which are passed in below:
37
37
  # 1 - username
38
38
  # 2 - password
39
- # 3 - upload SSH keys
39
+ # 3 - should we support an api token, if server supports it
40
+ # 4 - upload SSH keys
40
41
  # 4 - if no namespace is found, create namespace? (blank is no)
41
42
  args = [$username, $password]
43
+ args << 'no' if $supports_auth_tokens
42
44
  args << 'yes' unless ($keyed_users ||= []).include?($username)
43
45
  args << '' # always skip namespace
44
46
  if $namespace
@@ -103,9 +105,9 @@ module RHCHelper
103
105
 
104
106
  # Get a REST client to verify the application is on the server
105
107
  def is_created?
106
- new_client.domains[0].find_application(name)
108
+ new_client.find_application($namespace,name)
107
109
  true
108
- rescue RHC::ApplicationNotFoundException
110
+ rescue RHC::Rest::ApplicationNotFoundException
109
111
  false
110
112
  end
111
113
 
@@ -43,8 +43,9 @@ module RHCHelper
43
43
  cmd.gsub!('add alias', 'add-alias')
44
44
  cmd.gsub!('remove alias', 'remove-alias')
45
45
  cmd.gsub!('force stop', 'force-stop')
46
+ cmd.gsub!('show gears', 'show --gears')
46
47
 
47
- return cmd
48
+ cmd
48
49
  end
49
50
 
50
51
  # Print out the command arguments based on the state of the application instance
@@ -70,7 +70,8 @@ When /^the application is (\w+)$/ do |command|
70
70
  :shown => :show,
71
71
  :tidied => :tidy,
72
72
  :snapshot => :snapshot_save,
73
- :deleted => :delete
73
+ :deleted => :delete,
74
+ :visualized => :show_gears,
74
75
  }
75
76
 
76
77
  # Use an alias if it exists, or just remove 'ed' (like from started)
@@ -67,7 +67,7 @@ set_endpoint
67
67
  raise "Username not found in environment (RHC_USERNAME)" unless $username
68
68
  raise "Password not found in environment (RHC_PASSWORD)" unless $password
69
69
 
70
- $user_register_script_format = "/usr/bin/ss-register-user -l admin -p admin --username %s --userpass %s"
70
+ $user_register_script_format = "oo-register-user -l admin -p admin --username %s --userpass %s"
71
71
  if ENV['REGISTER_USER']
72
72
  command = $user_register_script_format % [$username,$password]
73
73
  %x[#{command}]
@@ -97,6 +97,9 @@ def clean_applications(leave_domain = false)
97
97
  $namespace = nil unless leave_domain
98
98
  $keyed_users = []
99
99
 
100
+ client = RHC::Rest::Client.new(:url => $end_point, :user => $username, :password => $password, :verify_mode => OpenSSL::SSL::VERIFY_NONE)
101
+ $supports_auth_tokens = client.supports_sessions?
102
+
100
103
  users.each do |user|
101
104
  _log "\tUser: #{user}"
102
105
  client = RHC::Rest::Client.new(:url => $end_point, :user => user, :password => $password, :verify_mode => OpenSSL::SSL::VERIFY_NONE)
@@ -1,7 +1,5 @@
1
1
  module RHC::Auth
2
2
  class Basic
3
- attr_reader :cookie
4
-
5
3
  def initialize(*args)
6
4
  if args[0].is_a?(String) or args.length > 1
7
5
  @username, @password = args
@@ -15,30 +13,37 @@ module RHC::Auth
15
13
  end
16
14
 
17
15
  def to_request(request)
18
- (request[:cookies] ||= {})[:rh_sso] = cookie if cookie
19
16
  request[:user] ||= username || (request[:lazy_auth] != true && ask_username) || nil
20
17
  request[:password] ||= password || (username? && request[:lazy_auth] != true && ask_password) || nil
21
18
  request
22
19
  end
23
20
 
24
- def retry_auth?(response)
21
+ def retry_auth?(response, client)
25
22
  if response.status == 401
26
- @cookie = nil
27
- error "Username or password is not correct" if username? && password
28
- unless @skip_interactive or @no_interactive
29
- ask_username unless username?
30
- ask_password
31
- true
32
- end
23
+ credentials_rejected
33
24
  else
34
- @cookie ||= Array(response.cookies).inject(nil){ |v, c| c.name == 'rh_sso' ? c.value : v }
35
25
  false
36
26
  end
37
27
  end
38
28
 
29
+ def can_authenticate?
30
+ username? and not (password.nil? and @skip_interactive and @no_interactive)
31
+ end
32
+
33
+ attr_reader :username
34
+
39
35
  protected
40
36
  include RHC::Helpers
41
- attr_reader :options, :username, :password
37
+ attr_reader :options, :password
38
+
39
+ def credentials_rejected
40
+ error "Username or password is not correct" if username? && password
41
+ unless @skip_interactive or @no_interactive
42
+ ask_username unless username?
43
+ ask_password
44
+ true
45
+ end
46
+ end
42
47
 
43
48
  def ask_username
44
49
  @username = ask("Login to #{openshift_server}: ") unless @no_interactive
@@ -0,0 +1,98 @@
1
+ module RHC::Auth
2
+ class Token
3
+ def initialize(opt, auth=nil, store=nil)
4
+ if opt.is_a?(String)
5
+ @token = opt
6
+ else
7
+ @options = opt || Commander::Command::Options.new
8
+ @token = options[:token]
9
+ @no_interactive = options[:noprompt]
10
+ @allows_tokens = options[:use_authorization_tokens]
11
+ end
12
+ @auth = auth
13
+ @store = store
14
+ read_token
15
+ end
16
+
17
+ def to_request(request)
18
+ if token
19
+ (request[:headers] ||= {})['authorization'] = "Bearer #{token}"
20
+ elsif auth and (!@allows_tokens or @can_get_token == false)
21
+ auth.to_request(request)
22
+ end
23
+ request
24
+ end
25
+
26
+ def retry_auth?(response, client)
27
+ if response.status == 401
28
+ token_rejected(response, client)
29
+ else
30
+ false
31
+ end
32
+ end
33
+
34
+ def username
35
+ auth && auth.respond_to?(:username) && auth.username || options[:username]
36
+ end
37
+
38
+ def save(token)
39
+ store.put(username, openshift_server, token) if store
40
+ @token = token
41
+ end
42
+
43
+ def can_authenticate?
44
+ token || auth && auth.can_authenticate?
45
+ end
46
+
47
+ protected
48
+ include RHC::Helpers
49
+ attr_reader :options, :token, :auth, :store
50
+
51
+ def token_rejected(response, client)
52
+ has_token = !!token
53
+ @token = nil
54
+
55
+ unless auth && auth.can_authenticate?
56
+ if has_token
57
+ raise RHC::Rest::TokenExpiredOrInvalid, "Your authorization token is expired or invalid."
58
+ end
59
+ return false
60
+ end
61
+
62
+ if has_token
63
+ if cannot_retry?
64
+ raise RHC::Rest::TokenExpiredOrInvalid, "Your authorization token is expired or invalid."
65
+ end
66
+ if not client.supports_sessions?
67
+ raise RHC::Rest::AuthorizationsNotSupported
68
+ end
69
+ end
70
+
71
+ @can_get_token = client.supports_sessions? && @allows_tokens
72
+
73
+ if has_token
74
+ warn "Your authorization token has expired. Please sign in now to continue."
75
+ elsif @can_get_token
76
+ info "Please sign in to start a new session to #{openshift_server}."
77
+ end
78
+
79
+ return auth.retry_auth?(response, client) unless @can_get_token
80
+
81
+ if auth_token = client.new_session(:auth => auth)
82
+ @fetch_once = true
83
+ save(auth_token.token)
84
+ true
85
+ else
86
+ auth.retry_auth?(response, client)
87
+ end
88
+ end
89
+
90
+ def read_token
91
+ @token ||= store.get(username, openshift_server) if store
92
+ end
93
+
94
+ def cannot_retry?
95
+ !@fetch_once && @no_interactive
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,51 @@
1
+ module RHC::Auth
2
+ class TokenStore
3
+ def initialize(dir)
4
+ @dir = dir
5
+ end
6
+
7
+ def get(login, server)
8
+ self[key(login,server)]
9
+ end
10
+
11
+ def put(login, server, token)
12
+ self[key(login,server)] = token
13
+ end
14
+
15
+ def clear
16
+ Dir[File.join(@dir, "token_*")].
17
+ each{ |f| File.delete(f) unless File.directory?(f) }.
18
+ present?
19
+ end
20
+
21
+ private
22
+ def path(key)
23
+ File.join(@dir, filename(key))
24
+ end
25
+
26
+ def filename(key)
27
+ "token_#{Base64.encode64(Digest::MD5.digest(key)).gsub(/[^\w\@]/,'')}"
28
+ end
29
+
30
+ def []=(key, value)
31
+ file = path(key)
32
+ FileUtils.mkdir_p File.dirname(file)
33
+ File.open(file, 'w'){ |f| f.write(value) }
34
+ File.chmod(0600, file)
35
+ value
36
+ end
37
+
38
+ def [](key)
39
+ s = IO.read(path(key)).presence
40
+ s = s.strip.gsub(/[\n\r\t]/,'') if s
41
+ s
42
+ rescue Errno::ENOENT
43
+ nil
44
+ end
45
+
46
+ def key(login, server)
47
+ "#{login || ''}@#{server}"
48
+ end
49
+
50
+ end
51
+ end
data/lib/rhc/auth.rb CHANGED
@@ -1,3 +1,5 @@
1
1
  module RHC::Auth
2
- autoload :Basic, 'rhc/auth/basic'
2
+ autoload :Basic, 'rhc/auth/basic'
3
+ autoload :Token, 'rhc/auth/token'
4
+ autoload :TokenStore, 'rhc/auth/token_store'
3
5
  end
@@ -61,6 +61,7 @@ module RHC
61
61
  run_active_command
62
62
  rescue InvalidCommandError => e
63
63
  if provided_arguments.empty?
64
+ return RHC::Wizard.new.run unless RHC::Wizard.has_configuration?
64
65
  say RHC::HelpFormatter.new(self).render
65
66
  else
66
67
  RHC::Helpers.error "The command '#{program :name} #{provided_arguments.join(' ')}' is not recognized.\n"
@@ -12,7 +12,7 @@ module RHC::Commands
12
12
  def run
13
13
  user = rest_client.user
14
14
 
15
- say_table nil, get_properties(user, :login, :plan_id, :consumed_gears, :max_gears) + get_properties(user.capabilities, :gear_sizes), :delete => true
15
+ say_table nil, get_properties(user, :login, :plan_id, :consumed_gears, :max_gears) + get_properties(user.capabilities, :gear_sizes).unshift(['Server', openshift_server]), :delete => true
16
16
 
17
17
  if openshift_online_server?
18
18
  else
@@ -20,5 +20,51 @@ module RHC::Commands
20
20
 
21
21
  0
22
22
  end
23
+
24
+ summary "End the current session"
25
+ description <<-DESC
26
+ Logout ends your current session on the server and then removes
27
+ all of the local session files. If you are using multiple
28
+ servers and configurations this will remove all of your local
29
+ session files.
30
+
31
+ The --all option will terminate all authorizations on your
32
+ account. Any previously generated authorizations will be
33
+ deleted and external tools that integrate with your account
34
+ will no longer be able to log in.
35
+ DESC
36
+ option '--all', "Remove all authorizations on your account."
37
+ alias_action 'logout', :root_command => true
38
+ def logout
39
+ if options.all
40
+ rest_client.user # force authentication
41
+ say "Deleting all authorizations associated with your account ... "
42
+ begin
43
+ rest_client.delete_authorizations
44
+ success "done"
45
+ rescue RHC::Rest::AuthorizationsNotSupported
46
+ info "not supported"
47
+ end
48
+ elsif options.token
49
+ options.noprompt = true
50
+ say "Ending session on server ... "
51
+ begin
52
+ rest_client.delete_authorization(options.token)
53
+ success "deleted"
54
+ rescue RHC::Rest::AuthorizationsNotSupported
55
+ info "not supported"
56
+ rescue RHC::Rest::TokenExpiredOrInvalid
57
+ info "already closed"
58
+ rescue => e
59
+ debug_error(e)
60
+ warn e.message
61
+ end
62
+ end
63
+
64
+ 0
65
+ ensure
66
+ token_store.clear
67
+ success "All local sessions removed."
68
+ end
23
69
  end
24
70
  end
@@ -14,8 +14,7 @@ module RHC::Commands
14
14
  option ["-n", "--namespace namespace"], "Namespace of your application", :context => :namespace_context, :required => true
15
15
  alias_action :"app add-alias", :root_command => true, :deprecated => true
16
16
  def add(app, app_alias)
17
- rest_domain = rest_client.find_domain(options.namespace)
18
- rest_app = rest_domain.find_application(app)
17
+ rest_app = rest_client.find_application(options.namespace, app)
19
18
  response = rest_app.add_alias(app_alias)
20
19
  results { say response.messages.first } if response.messages
21
20
  0
@@ -28,8 +27,7 @@ module RHC::Commands
28
27
  option ["-n", "--namespace namespace"], "Namespace of your application", :context => :namespace_context, :required => true
29
28
  alias_action :"app remove-alias", :root_command => true, :deprecated => true
30
29
  def remove(app, app_alias)
31
- rest_domain = rest_client.find_domain(options.namespace)
32
- rest_app = rest_domain.find_application(app)
30
+ rest_app = rest_client.find_application(options.namespace, app)
33
31
  response = rest_app.remove_alias(app_alias)
34
32
  results { say response.messages.first } if response.messages
35
33
  0
@@ -59,7 +59,7 @@ module RHC::Commands
59
59
 
60
60
  raise ArgumentError, "You have named both your main application and your Jenkins application '#{name}'. In order to continue you'll need to specify a different name with --enable-jenkins or choose a different application name." if jenkins_app_name == name && enable_jenkins?
61
61
 
62
- raise RHC::DomainNotFoundException.new("No domains found. Please create a domain with 'rhc domain create <namespace>' before creating applications.") if rest_client.domains.empty?
62
+ raise RHC::Rest::DomainNotFoundException.new("No domains found. Please create a domain with 'rhc domain create <namespace>' before creating applications.") if rest_client.domains.empty?
63
63
  rest_domain = rest_client.find_domain(options.namespace)
64
64
  rest_app = nil
65
65
 
@@ -177,9 +177,7 @@ module RHC::Commands
177
177
  argument :app, "The application you wish to delete", ["-a", "--app name"], :context => :app_context
178
178
  alias_action :destroy, :deprecated => true
179
179
  def delete(app)
180
-
181
- rest_domain = rest_client.find_domain(options.namespace)
182
- rest_app = rest_domain.find_application(app)
180
+ rest_app = rest_client.find_application(options.namespace, app)
183
181
 
184
182
  confirm_action "#{color("This is a non-reversible action! Your application code and data will be permanently deleted if you continue!", :yellow)}\n\nAre you sure you want to delete the application '#{app}'?"
185
183
 
@@ -260,18 +258,18 @@ module RHC::Commands
260
258
  syntax "<app> [--namespace namespace]"
261
259
  argument :app, "The name of the application you are getting information on", ["-a", "--app app"], :context => :app_context
262
260
  option ["-n", "--namespace namespace"], "Namespace of the application the cartridge belongs to", :context => :namespace_context, :required => true
263
- option ["--state"], "Get the current state of the application's gears"
261
+ option ["--state"], "Get the current state of the cartridges in this application"
262
+ option ["--gears"], "Show the ID, state, and cartridges on each gear in this application"
264
263
  def show(app_name)
265
- domain = rest_client.find_domain(options.namespace)
266
- app = domain.find_application(app_name)
267
264
 
268
265
  if options.state
269
- results do
270
- app.gear_groups.each do |gg|
271
- say "Gear group #{gg.cartridges.collect { |c| c['name'] }.join('+')} is #{gg.gears.first['state']}"
272
- end
266
+ gear_groups_for_app(app_name).each do |gg|
267
+ say "Cartridge #{gg.cartridges.collect { |c| c['name'] }.join(', ')} is #{gear_group_state(gg.gears.map{ |g| g['state'] })}"
273
268
  end
269
+ elsif options.gears
270
+ say table(gear_groups_for_app(app_name).map{ |gg| gg.gears.map{ |g| [g['id'], g['state'], gg.cartridges.map{ |c| c['name'] }.join(", ")] } }.flatten(1))
274
271
  else
272
+ app = rest_client.find_application(options.namespace, app_name, :include => :cartridges)
275
273
  display_app(app, app.cartridges)
276
274
  end
277
275
 
@@ -288,16 +286,15 @@ module RHC::Commands
288
286
  raise ArgumentError, "No application specified" unless app_name.present?
289
287
  raise OptionParser::InvalidOption, "No system SSH available. Please use the --ssh option to specify the path to your SSH executable, or install SSH." unless options.ssh or has_ssh?
290
288
 
291
- domain = rest_client.find_domain(options.namespace)
292
- app = domain.find_application(app_name)
289
+ rest_app = rest_client.find_application(options.namespace, app_name)
293
290
 
294
- say "Connecting to #{app.ssh_string.to_s} ..."
291
+ say "Connecting to #{rest_app.ssh_string.to_s} ..."
295
292
  if options.ssh
296
293
  debug "Using user specified SSH: #{options.ssh}"
297
- Kernel.send(:system, "#{options.ssh} #{app.ssh_string.to_s}")
294
+ Kernel.send(:system, "#{options.ssh} #{rest_app.ssh_string.to_s}")
298
295
  else
299
296
  debug "Using system ssh"
300
- Kernel.send(:system, "ssh #{app.ssh_string.to_s}")
297
+ Kernel.send(:system, "ssh #{rest_app.ssh_string.to_s}")
301
298
  end
302
299
  end
303
300
 
@@ -337,9 +334,17 @@ module RHC::Commands
337
334
  RHC::SSHWizard.new(rest_client, config, options).run
338
335
  end
339
336
 
337
+ def gear_groups_for_app(app_name)
338
+ rest_client.find_application_gear_groups(options.namespace, app_name)
339
+ end
340
+
341
+ def gear_group_state(states)
342
+ return states[0] if states.length == 1 || states.uniq.length == 1
343
+ "#{states.select{ |s| s == 'started' }.count}/#{states.length} started"
344
+ end
345
+
340
346
  def app_action(app, action, *args)
341
- rest_domain = rest_client.find_domain(options.namespace)
342
- rest_app = rest_domain.find_application(app)
347
+ rest_app = rest_client.find_application(options.namespace, app)
343
348
  result = rest_app.send action, *args
344
349
  result
345
350
  end
@@ -0,0 +1,93 @@
1
+ module RHC::Commands
2
+ class Authorization < Base
3
+
4
+ summary "Display the authorization tokens created under your account"
5
+ description <<-DESC
6
+ Shows the full list of authorization tokens on your account. You
7
+ can add, edit, or delete authorizations with subcommands.
8
+
9
+ An authorization token grants access to the OpenShift REST API with
10
+ a set of privleges called 'scopes' for a limited time. You can
11
+ add an optional note to each authorization token to assist you in
12
+ remembering what is available.
13
+ DESC
14
+ def run
15
+ rest_client.authorizations.each{ |auth| paragraph{ display_authorization(auth, options.token) } } or info "No authorizations"
16
+
17
+ 0
18
+ end
19
+
20
+ option "--scopes SCOPES", "A comma delimited list of scopes (e.g. 'scope1,scope2')"
21
+ option "--note NOTE", "A description of this authorization (optional)"
22
+ option "--expires-in SECONDS", "The number of seconds before this authorization expires (optional)"
23
+ summary "Add an authorization to your account"
24
+ description <<-DESC
25
+ Add an authorization to your account. An authorization token grants
26
+ access to the OpenShift REST API with a set of privleges called 'scopes'
27
+ for a limited time. You can add an optional note to each authorization
28
+ token to assist you in remembering what is available.
29
+
30
+ To view the list of scopes supported by this server, run this command
31
+ without any options.
32
+
33
+ You may pass multiple scopes to the --scopes option inside of double
34
+ quotes (--scopes \"scope1 scope2\") or by separating them with commas
35
+ (--scopes scope1,scope2).
36
+
37
+ The server will enforce a maximum and default expiration that may
38
+ differ for each scope. If you request an expiration longer than the
39
+ server maximum, you will be given the default value.
40
+ DESC
41
+ def add
42
+ unless options.scopes
43
+ say "When adding an authorization, you must specify which permissions clients will have."
44
+ scope_help
45
+ say "Run 'rhc authorization add --help' to see more options"
46
+ return 0
47
+ end
48
+
49
+ say "Adding authorization ... "
50
+ auth = rest_client.add_authorization(:scope => options.scopes, :note => options.note, :expires_in => options.expires_in)
51
+ success "done"
52
+ paragraph{ display_authorization(auth) }
53
+
54
+ 0
55
+ end
56
+
57
+ summary "Delete one or more authorization tokens"
58
+ syntax "<token_or_id> [...<token_or_id>]"
59
+ description <<-DESC
60
+ Delete one or more of the authorization tokens associated with
61
+ your account. After deletion, any clients using the token will
62
+ no longer have access to OpenShift and will need to reauthenticate.
63
+ DESC
64
+ argument :auth_token, "The token you wish to delete", ['--auth-token TOKEN'], :arg_type => :list
65
+ def delete(tokens)
66
+ raise ArgumentError, "You must specify one or more tokens to delete" if tokens.blank?
67
+ say "Deleting authorization ... "
68
+ tokens.each{ |token| rest_client.delete_authorization(token) }
69
+ success "done"
70
+ 0
71
+ end
72
+
73
+ summary "Delete all authorization tokens from your account"
74
+ description <<-DESC
75
+ Delete all the authorization tokens associated with your account.
76
+ After deletion, any clients using those tokens will need to
77
+ reauthenticate.
78
+ DESC
79
+ def delete_all
80
+ say "Deleting all authorizations ... "
81
+ rest_client.delete_authorizations
82
+ success "done"
83
+ 0
84
+ end
85
+
86
+ protected
87
+ def scope_help
88
+ descriptions = rest_client.authorization_scope_list
89
+ paragraph{ say table(descriptions, :header => ['Scope', 'Description']) }
90
+ paragraph{ say "You may pass multiple scopes to the --scopes option inside of double quotes (--scopes \"scope1 scope2\") or by separating them with commas (--scopes scope1,scope2)." }
91
+ end
92
+ end
93
+ end
@@ -28,8 +28,16 @@ class RHC::Commands::Base
28
28
  # the output (or failures) into exceptions and
29
29
  # formatted object output. Most interactions
30
30
  # should be through this call pattern.
31
- def rest_client
32
- @rest_client ||= client_from_options(:auth => RHC::Auth::Basic.new(options))
31
+ def rest_client(opts={})
32
+ @rest_client ||= begin
33
+ auth = RHC::Auth::Basic.new(options)
34
+ auth = RHC::Auth::Token.new(options, auth, token_store)
35
+ client_from_options(:auth => auth)
36
+ end
37
+ end
38
+
39
+ def token_store
40
+ @token_store ||= RHC::Auth::TokenStore.new(config.home_conf_path)
33
41
  end
34
42
 
35
43
  def help(*args)
@@ -79,7 +87,7 @@ class RHC::Commands::Base
79
87
  indent = o.scan(/^[ \t]*(?=\S)/).min.size || 0
80
88
  options[:description] =
81
89
  o.gsub(/^[ \t]{#{indent}}/, '').
82
- gsub(/(\b)\s*\n(?!\s*\n)(\S)/m, '\1 \2').
90
+ gsub(/(\b|')\s*\n(?!\s*\n)(\S)/m, '\1 \2').
83
91
  gsub(/\n+\Z/, '').
84
92
  gsub(/\n{3,}/, "\n\n")
85
93
  end
@@ -46,8 +46,7 @@ module RHC::Commands
46
46
 
47
47
  say "Adding #{cart.name} to application '#{options.app}' ... "
48
48
 
49
- rest_domain = rest_client.find_domain(options.namespace)
50
- rest_app = rest_domain.find_application(options.app)
49
+ rest_app = rest_client.find_application(options.namespace, options.app, :include => :cartridges)
51
50
  rest_cartridge = rest_app.add_cartridge(cart.name)
52
51
 
53
52
  success "Success"
@@ -65,8 +64,7 @@ module RHC::Commands
65
64
  option ["-a", "--app app"], "Application you are adding the cartridge to", :context => :app_context, :required => true
66
65
  argument :cartridge, "The name of the cartridge", ["-c", "--cartridge cart_type"]
67
66
  def show(cartridge)
68
- rest_domain = rest_client.find_domain(options.namespace)
69
- rest_app = rest_domain.find_application(options.app)
67
+ rest_app = rest_client.find_application(options.namespace, options.app, :include => :cartridges)
70
68
  rest_cartridge = check_cartridges(cartridge, :from => rest_app.cartridges).first
71
69
 
72
70
  display_cart(rest_cartridge)
@@ -82,9 +80,7 @@ module RHC::Commands
82
80
  option ["--confirm"], "Pass to confirm removing the cartridge"
83
81
  alias_action :"app cartridge remove", :root_command => true, :deprecated => true
84
82
  def remove(cartridge)
85
-
86
- rest_domain = rest_client.find_domain(options.namespace)
87
- rest_app = rest_domain.find_application(options.app)
83
+ rest_app = rest_client.find_application(options.namespace, options.app, :include => :cartridges)
88
84
  rest_cartridge = check_cartridges(cartridge, :from => rest_app.cartridges).first
89
85
 
90
86
  confirm_action "Removing a cartridge is a destructive operation that may result in loss of data associated with the cartridge.\n\nAre you sure you wish to remove #{rest_cartridge.name} from '#{rest_app.name}'?"
@@ -136,8 +132,7 @@ module RHC::Commands
136
132
  option ["-a", "--app app"], "Application the cartridge belongs to", :context => :app_context, :required => true
137
133
  alias_action :"app cartridge status", :root_command => true, :deprecated => true
138
134
  def status(cartridge)
139
- rest_domain = rest_client.find_domain(options.namespace)
140
- rest_app = rest_domain.find_application(options.app)
135
+ rest_app = rest_client.find_application(options.namespace, options.app, :include => :cartridges)
141
136
  rest_cartridge = check_cartridges(cartridge, :from => rest_app.cartridges).first
142
137
  results { rest_cartridge.status.each{ |msg| say msg['message'] } }
143
138
  0
@@ -164,8 +159,7 @@ module RHC::Commands
164
159
  def scale(cartridge)
165
160
  raise RHC::MissingScalingValueException unless options.min || options.max
166
161
 
167
- rest_domain = rest_client.find_domain(options.namespace)
168
- rest_app = rest_domain.find_application(options.app)
162
+ rest_app = rest_client.find_application(options.namespace, options.app, :include => :cartridges)
169
163
  rest_cartridge = check_cartridges(cartridge, :from => rest_app.cartridges).first
170
164
 
171
165
  raise RHC::CartridgeNotScalableException unless rest_cartridge.scalable?
@@ -195,8 +189,7 @@ module RHC::Commands
195
189
  option ["-f", "--force"], "Force the action"
196
190
  def storage(cartridge)
197
191
  cartridges = Array(cartridge)
198
- rest_domain = rest_client.find_domain(options.namespace)
199
- rest_app = rest_domain.find_application(options.app)
192
+ rest_app = rest_client.find_application(options.namespace, options.app, :include => :cartridges)
200
193
 
201
194
  # Pull the desired action
202
195
  #
@@ -257,11 +250,10 @@ module RHC::Commands
257
250
  include RHC::CartridgeHelpers
258
251
 
259
252
  def cartridge_action(cartridge, action, &block)
260
- rest_domain = rest_client.find_domain(options.namespace)
261
- rest_app = rest_domain.find_application(options.app)
253
+ rest_app = rest_client.find_application(options.namespace, options.app, :include => :cartridges)
262
254
  rest_cartridge = check_cartridges(cartridge, :from => rest_app.cartridges).first
263
255
  result = rest_cartridge.send action
264
- resp = [result, rest_cartridge, rest_app, rest_domain]
256
+ resp = [result, rest_cartridge, rest_app]
265
257
  yield resp if block_given?
266
258
  resp
267
259
  end