rhc 1.4.8 → 1.5.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/features/application.feature +1 -0
- data/features/lib/rhc_helper/app.rb +5 -3
- data/features/lib/rhc_helper/commandify.rb +2 -1
- data/features/step_definitions/application_steps.rb +2 -1
- data/features/support/env.rb +4 -1
- data/lib/rhc/auth/basic.rb +18 -13
- data/lib/rhc/auth/token.rb +98 -0
- data/lib/rhc/auth/token_store.rb +51 -0
- data/lib/rhc/auth.rb +3 -1
- data/lib/rhc/command_runner.rb +1 -0
- data/lib/rhc/commands/account.rb +47 -1
- data/lib/rhc/commands/alias.rb +2 -4
- data/lib/rhc/commands/app.rb +23 -18
- data/lib/rhc/commands/authorization.rb +93 -0
- data/lib/rhc/commands/base.rb +11 -3
- data/lib/rhc/commands/cartridge.rb +8 -16
- data/lib/rhc/commands/git_clone.rb +2 -3
- data/lib/rhc/commands/port_forward.rb +10 -11
- data/lib/rhc/commands/setup.rb +4 -1
- data/lib/rhc/commands/snapshot.rb +4 -3
- data/lib/rhc/commands/tail.rb +3 -4
- data/lib/rhc/commands/threaddump.rb +1 -2
- data/lib/rhc/commands.rb +37 -3
- data/lib/rhc/config.rb +10 -1
- data/lib/rhc/context_helper.rb +5 -1
- data/lib/rhc/core_ext.rb +10 -0
- data/lib/rhc/exceptions.rb +0 -12
- data/lib/rhc/git_helpers.rb +12 -0
- data/lib/rhc/helpers.rb +31 -1
- data/lib/rhc/output_helpers.rb +19 -3
- data/lib/rhc/rest/api.rb +2 -1
- data/lib/rhc/rest/application.rb +5 -4
- data/lib/rhc/rest/authorization.rb +10 -0
- data/lib/rhc/rest/base.rb +6 -1
- data/lib/rhc/rest/client.rb +243 -122
- data/lib/rhc/rest/domain.rb +0 -15
- data/lib/rhc/rest/gear_group.rb +0 -1
- data/lib/rhc/rest/mock.rb +118 -16
- data/lib/rhc/rest/user.rb +0 -1
- data/lib/rhc/rest.rb +28 -8
- data/lib/rhc/ssh_helpers.rb +5 -2
- data/lib/rhc/tar_gz.rb +16 -5
- data/lib/rhc/usage_templates/help.erb +1 -1
- data/lib/rhc/wizard.rb +54 -10
- data/spec/coverage_helper.rb +9 -0
- data/spec/rhc/auth_spec.rb +229 -22
- data/spec/rhc/cli_spec.rb +15 -0
- data/spec/rhc/command_spec.rb +100 -8
- data/spec/rhc/commands/account_spec.rb +75 -1
- data/spec/rhc/commands/app_spec.rb +23 -5
- data/spec/rhc/commands/authorization_spec.rb +120 -0
- data/spec/rhc/commands/domain_spec.rb +2 -2
- data/spec/rhc/commands/git_clone_spec.rb +24 -0
- data/spec/rhc/commands/port_forward_spec.rb +22 -23
- data/spec/rhc/commands/server_spec.rb +2 -2
- data/spec/rhc/commands/setup_spec.rb +12 -0
- data/spec/rhc/config_spec.rb +7 -3
- data/spec/rhc/helpers_spec.rb +62 -9
- data/spec/rhc/rest_application_spec.rb +24 -0
- data/spec/rhc/rest_client_spec.rb +66 -56
- data/spec/rhc/rest_spec.rb +11 -2
- data/spec/rhc/wizard_spec.rb +61 -12
- data/spec/spec_helper.rb +125 -42
- data/spec/wizard_spec_helper.rb +1 -0
- 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 -  | 
| 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. | 
| 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 | 
            -
                   | 
| 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)
         | 
    
        data/features/support/env.rb
    CHANGED
    
    | @@ -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 = " | 
| 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)
         | 
    
        data/lib/rhc/auth/basic.rb
    CHANGED
    
    | @@ -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 | 
            -
                     | 
| 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, : | 
| 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
    
    
    
        data/lib/rhc/command_runner.rb
    CHANGED
    
    | @@ -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"
         | 
    
        data/lib/rhc/commands/account.rb
    CHANGED
    
    | @@ -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
         | 
    
        data/lib/rhc/commands/alias.rb
    CHANGED
    
    | @@ -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 | 
            -
                   | 
| 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 | 
            -
                   | 
| 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
         | 
    
        data/lib/rhc/commands/app.rb
    CHANGED
    
    | @@ -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 | 
| 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 | 
            -
                     | 
| 270 | 
            -
                       | 
| 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 | 
            -
                   | 
| 292 | 
            -
                  app = domain.find_application(app_name)
         | 
| 289 | 
            +
                  rest_app = rest_client.find_application(options.namespace, app_name)
         | 
| 293 290 |  | 
| 294 | 
            -
                  say "Connecting to #{ | 
| 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} #{ | 
| 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 #{ | 
| 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 | 
            -
                     | 
| 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
         | 
    
        data/lib/rhc/commands/base.rb
    CHANGED
    
    | @@ -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 ||=  | 
| 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 | 
            -
                   | 
| 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 | 
            -
                   | 
| 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 | 
            -
                   | 
| 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 | 
            -
                   | 
| 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 | 
            -
                   | 
| 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 | 
            -
                     | 
| 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 | 
| 256 | 
            +
                    resp = [result, rest_cartridge, rest_app]
         | 
| 265 257 | 
             
                    yield resp if block_given?
         | 
| 266 258 | 
             
                    resp
         | 
| 267 259 | 
             
                  end
         |