Class: RightApi::Client

Inherits:
Object
  • Object
show all
Includes:
Helper
Defined in:
lib/right_api_client/client.rb,
lib/right_api_client/version.rb

Defined Under Namespace

Classes: ErrorDetails

Constant Summary collapse

DEFAULT_OPEN_TIMEOUT =
nil
DEFAULT_TIMEOUT =
6 * 60
DEFAULT_MAX_ATTEMPTS =
5
DEFAULT_SSL_VERSION =
'TLSv1_2'
ROOT_RESOURCE =
'/api/session'
OAUTH_ENDPOINT =
'/api/oauth2'
ROOT_INSTANCE_RESOURCE =
'/api/session/instance'
DEFAULT_API_URL =
'https://my.rightscale.com'
AUTH_PARAMS =

permitted parameters for initializing

%w[
  email password_base64 password
  instance_token
  refresh_token access_token
  cookies
  account_id api_url api_version
  timeout open_timeout max_attempts
  enable_retry rest_client_class
  rl10
]
VERSION =
File.read(File.expand_path('../../../VERSION', __FILE__)).strip
API_VERSION =
"1.5"
CLIENT_VERSION =
VERSION.split('.')[1..-1].join('.')

Constants included from Helper

Helper::INCONSISTENT_RESOURCE_TYPES, Helper::INSTANCE_FACING_RESOURCES, Helper::RESOURCE_SPECIAL_ACTIONS

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Helper

#add_id_and_params_to_path, #api_methods, #define_instance_method, #fix_array_of_hashes, #get_and_delete_href_from_links, #get_associated_resources, #get_href_from_links, #get_singular, #has_id, #insert_in_path, #is_singular?, #simple_singularize

Constructor Details

#initialize(args) ⇒ Client

Instantiate a new Client, then login if necessary.



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/right_api_client/client.rb', line 118

def initialize(args)
  raise 'This API client is only compatible with Ruby 1.8.7 and upwards.' if (RUBY_VERSION < '1.8.7')

  @api_url, @api_version = DEFAULT_API_URL, API_VERSION
  @open_timeout, @timeout, @max_attempts = DEFAULT_OPEN_TIMEOUT, DEFAULT_TIMEOUT, DEFAULT_MAX_ATTEMPTS
  @ssl_version = DEFAULT_SSL_VERSION
  @enable_retry = false

  # Initializing all instance variables from hash
  args.each { |key,value|
    instance_variable_set("@#{key}", value) if AUTH_PARAMS.include?(key.to_s)
  } if args.is_a? Hash

  raise 'This API client is only compatible with the RightScale API 1.5 and upwards.' if (Float(@api_version) < 1.5)

  # If rl10 parameter was passed true, read secrets file to set @local_token, and @api_url
  if @rl10
    case RbConfig::CONFIG['host_os']
    when /mswin|mingw|cygwin/
      local_secret_file = File.join(ENV['ProgramData'] || 'C:/ProgramData', 'RightScale/RightLink/secret')
    else
      local_secret_file = '/var/run/rightlink/secret'
    end
    local_auth_info = Hash[File.readlines(local_secret_file).map{ |line| line.chomp.split('=', 2) }]
    @local_token = local_auth_info['RS_RLL_SECRET']
    @api_url = "http://localhost:#{local_auth_info['RS_RLL_PORT']}"
  end

  # allow a custom resource-style REST client (for special logging, etc.)
  @rest_client_class ||= ::RestClient::Resource
  @rest_client = @rest_client_class.new(@api_url, :open_timeout => @open_timeout, :timeout => @timeout, :ssl_version => @ssl_version)
  @last_request = {}

  # There are five options for login:
  #  - user email/password (using plaintext or base64-obfuscated password)
  #  - user OAuth refresh token
  #  - instance API token
  #  - existing user-supplied cookies
  #  - existing user-supplied OAuth access token
  #
  # The latter two options are not really login; they imply that the user logged in out of band.
  # See config/login.yml.example for more info.
  () if need_login?

  timestamp_cookies

  # Add the top level links for instance_facing_calls
  if @instance_token || @local_token
    resource_type, path, data = self.do_get(ROOT_INSTANCE_RESOURCE)
    instance_href = get_href_from_links(data['links'])
    cloud_href = instance_href.split('/instances')[0]

    define_instance_method(:get_instance) do |*params|
      type, instance_path, instance_data = self.do_get(ROOT_INSTANCE_RESOURCE)
      RightApi::ResourceDetail.new(self, type, instance_path, instance_data)
    end

    Helper::INSTANCE_FACING_RESOURCES.each do |meth|
      define_instance_method(meth) do |*args|
        obj_path = cloud_href + '/' + meth.to_s
        # Following are special cases that need to over-ride the obj_path
        obj_path = '/api/backups'                if meth == :backups
        obj_path = instance_href + '/live/tasks' if meth == :live_tasks
        obj_path = '/api/tags'                   if meth == :tags
        if has_id(*args)
          obj_path = add_id_and_params_to_path(obj_path, *args)
          RightApi::Resource.process(self, get_singular(meth), obj_path)
        else
          RightApi::Resources.new(self, obj_path, meth.to_s)
        end
      end
    end
  else
    # Session is the root resource that has links to all the base resources
    define_instance_method(:session) do |*params|
      RightApi::Resources.new(self, ROOT_RESOURCE, 'session')
    end
    # Allow the base resources to be accessed directly
    get_associated_resources(self, session.index.links, nil)
  end
end

Instance Attribute Details

#access_tokenString (readonly)

Returns OAuth 2.0 access token, if present.

Returns:

  • (String)

    OAuth 2.0 access token, if present



85
86
87
# File 'lib/right_api_client/client.rb', line 85

def access_token
  @access_token
end

#access_token_expires_atTime (readonly)

Returns expiry timestamp for OAuth 2.0 access token.

Returns:

  • (Time)

    expiry timestamp for OAuth 2.0 access token



88
89
90
# File 'lib/right_api_client/client.rb', line 88

def access_token_expires_at
  @access_token_expires_at
end

#account_idObject

Returns the value of attribute account_id.



90
91
92
# File 'lib/right_api_client/client.rb', line 90

def 
  @account_id
end

#api_urlString

Returns Base API url, e.g. us-3.rightscale.com.

Returns:



93
94
95
# File 'lib/right_api_client/client.rb', line 93

def api_url
  @api_url
end

#cookiesHash (readonly)

Deprecated.

please use OAuth 2.0 refresh tokens instead of password-based authentication

Returns collection of API cookies.

Returns:

  • (Hash)

    collection of API cookies



100
101
102
# File 'lib/right_api_client/client.rb', line 100

def cookies
  @cookies
end

#enable_retryBoolean (readonly)

Returns whether to retry idempotent requests that fail.

Returns:

  • (Boolean)

    whether to retry idempotent requests that fail



115
116
117
# File 'lib/right_api_client/client.rb', line 115

def enable_retry
  @enable_retry
end

#instance_tokenString (readonly)

Returns instance API token as included in user-data.

Returns:

  • (String)

    instance API token as included in user-data



96
97
98
# File 'lib/right_api_client/client.rb', line 96

def instance_token
  @instance_token
end

#last_requestHash (readonly)

Returns debug information about the last request and response.

Returns:

  • (Hash)

    debug information about the last request and response



103
104
105
# File 'lib/right_api_client/client.rb', line 103

def last_request
  @last_request
end

#max_attemptsInteger (readonly)

Returns number of times to retry idempotent requests (iff enable_retry == true).

Returns:

  • (Integer)

    number of times to retry idempotent requests (iff enable_retry == true)



112
113
114
# File 'lib/right_api_client/client.rb', line 112

def max_attempts
  @max_attempts
end

#open_timeoutInteger (readonly)

Returns number of seconds to wait for socket open.

Returns:

  • (Integer)

    number of seconds to wait for socket open



106
107
108
# File 'lib/right_api_client/client.rb', line 106

def open_timeout
  @open_timeout
end

#refresh_tokenString (readonly)

Returns OAuth 2.0 refresh token if provided.

Returns:

  • (String)

    OAuth 2.0 refresh token if provided



82
83
84
# File 'lib/right_api_client/client.rb', line 82

def refresh_token
  @refresh_token
end

#timeoutInteger (readonly)

Returns number of seconds to wait for API response.

Returns:

  • (Integer)

    number of seconds to wait for API response



109
110
111
# File 'lib/right_api_client/client.rb', line 109

def timeout
  @timeout
end

Instance Method Details

#log(file) ⇒ Object

Log HTTP calls to file (file can be STDOUT as well)



208
209
210
# File 'lib/right_api_client/client.rb', line 208

def log(file)
  RestClient.log = file
end

#resource(path, params = {}) ⇒ Object

Given a path returns a RightApiClient::Resource instance.



214
215
216
217
218
219
220
221
222
# File 'lib/right_api_client/client.rb', line 214

def resource(path, params={})
  r = Resource.process_detailed(self, *do_get(path, params))

  # note that process_detailed will make a best-effort to return an already
  # detailed resource or array of detailed resources but there may still be
  # legacy cases where #show is still needed. calling #show on an already
  # detailed resource is a no-op.
  r.respond_to?(:show) ? r.show : r
end

#resources(type, path) ⇒ Object

Seems #resource tends to expand (call index) on Resources instances, so this is a workaround.



227
228
229
# File 'lib/right_api_client/client.rb', line 227

def resources(type, path)
  Resources.new(self, path, type)
end

#to_sObject Also known as: inspect



200
201
202
203
# File 'lib/right_api_client/client.rb', line 200

def to_s
  api_host = URI.parse(api_url).host.split('.').first rescue 'unknown'
  "#<RightApi::Client host=#{api_host} account=#{@account_id}>"
end