Class: OpenStack::Connection

Inherits:
Object
  • Object
show all
Defined in:
lib/openstack/connection.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {:retry_auth => true}) ⇒ Connection

Returns a new instance of Connection.



112
113
114
115
116
117
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
# File 'lib/openstack/connection.rb', line 112

def initialize(options = {:retry_auth => true})
  @retries = options[:retries] || 3
  @authuser = options[:username] || (raise Exception::MissingArgument, "Must supply a :username")
  @authkey = options[:api_key] || (raise Exception::MissingArgument, "Must supply an :api_key")
  @auth_url = options[:auth_url] || (raise Exception::MissingArgument, "Must supply an :auth_url")
  @authtenant = (options[:authtenant_id])? {:type => "tenantId", :value=>options[:authtenant_id]} : {:type=>"tenantName", :value=>(options[:authtenant_name] || options[:authtenant] || @authuser)}
  @auth_method = options[:auth_method] || "password"
  @service_name = options[:service_name] || nil
  @service_type = options[:service_type] || "compute"
  @user_domain_id = options[:user_domain_id] || "default"
  @user_domain = options[:user_domain] || nil
  @project_id = options[:project_id] || nil
  @project_name = options[:project_name] || nil
  @logger = options[:logger] || nil
  @project_domain_name = options[:project_domain_name] || nil
  @project_domain_id = options[:project_domain_id] || nil
  @domain_name = options[:domain_name] || nil
  @domain_id = options[:domain_id] || nil
  @region = options[:region] || @region = nil
  @regions_list = {} # this is populated during authentication - from the returned service catalogue
  @is_debug = options[:is_debug]
  auth_uri=nil
  begin
    auth_uri=URI.parse(@auth_url)
  rescue Exception => e
    raise Exception::InvalidArgument, "Invalid :auth_url parameter: #{e.message}"
  end
  raise Exception::InvalidArgument, "Invalid :auth_url parameter." if auth_uri.nil? or auth_uri.host.nil?
  @auth_host = auth_uri.host
  @auth_port = auth_uri.port
  @auth_scheme = auth_uri.scheme
  @auth_path = auth_uri.path
  @retry_auth = options[:retry_auth]
  @proxy_host = options[:proxy_host]
  @proxy_port = options[:proxy_port]
  @ca_cert = options[:ca_cert]
  @ssl_version = options[:ssl_version]
  @authok = false
  @http = {}
  @quantum_version = 'v2.0' if @service_type == 'network'
  @quantum_version = 'v2' if @service_type == 'metering'
  @endpoint_type = options[:endpoint_type] || "publicURL"
  @semaphore = Mutex.new
end

Instance Attribute Details

#auth_hostObject (readonly)

Returns the value of attribute auth_host.



19
20
21
# File 'lib/openstack/connection.rb', line 19

def auth_host
  @auth_host
end

#auth_methodObject (readonly)

Returns the value of attribute auth_method.



10
11
12
# File 'lib/openstack/connection.rb', line 10

def auth_method
  @auth_method
end

#auth_pathObject (readonly)

Returns the value of attribute auth_path.



22
23
24
# File 'lib/openstack/connection.rb', line 22

def auth_path
  @auth_path
end

#auth_portObject (readonly)

Returns the value of attribute auth_port.



20
21
22
# File 'lib/openstack/connection.rb', line 20

def auth_port
  @auth_port
end

#auth_schemeObject (readonly)

Returns the value of attribute auth_scheme.



21
22
23
# File 'lib/openstack/connection.rb', line 21

def auth_scheme
  @auth_scheme
end

#authkeyObject (readonly)

Returns the value of attribute authkey.



9
10
11
# File 'lib/openstack/connection.rb', line 9

def authkey
  @authkey
end

#authokObject

Returns the value of attribute authok.



12
13
14
# File 'lib/openstack/connection.rb', line 12

def authok
  @authok
end

#authtenantObject (readonly)

Returns the value of attribute authtenant.



8
9
10
# File 'lib/openstack/connection.rb', line 8

def authtenant
  @authtenant
end

#authtokenObject

Returns the value of attribute authtoken.



11
12
13
# File 'lib/openstack/connection.rb', line 11

def authtoken
  @authtoken
end

#authuserObject (readonly)

Returns the value of attribute authuser.



7
8
9
# File 'lib/openstack/connection.rb', line 7

def authuser
  @authuser
end

#ca_certObject (readonly)

Returns the value of attribute ca_cert.



35
36
37
# File 'lib/openstack/connection.rb', line 35

def ca_cert
  @ca_cert
end

#domain_idObject (readonly)

Returns the value of attribute domain_id.



32
33
34
# File 'lib/openstack/connection.rb', line 32

def domain_id
  @domain_id
end

#domain_nameObject (readonly)

Returns the value of attribute domain_name.



31
32
33
# File 'lib/openstack/connection.rb', line 31

def domain_name
  @domain_name
end

#endpoint_typeObject (readonly)

Returns the value of attribute endpoint_type.



42
43
44
# File 'lib/openstack/connection.rb', line 42

def endpoint_type
  @endpoint_type
end

#httpObject (readonly)

Returns the value of attribute http.



40
41
42
# File 'lib/openstack/connection.rb', line 40

def http
  @http
end

#is_debugObject (readonly)

Returns the value of attribute is_debug.



41
42
43
# File 'lib/openstack/connection.rb', line 41

def is_debug
  @is_debug
end

#project_domain_idObject (readonly)

Returns the value of attribute project_domain_id.



30
31
32
# File 'lib/openstack/connection.rb', line 30

def project_domain_id
  @project_domain_id
end

#project_domain_nameObject (readonly)

Returns the value of attribute project_domain_name.



29
30
31
# File 'lib/openstack/connection.rb', line 29

def project_domain_name
  @project_domain_name
end

#project_idObject (readonly)

Returns the value of attribute project_id.



27
28
29
# File 'lib/openstack/connection.rb', line 27

def project_id
  @project_id
end

#project_nameObject (readonly)

Returns the value of attribute project_name.



28
29
30
# File 'lib/openstack/connection.rb', line 28

def project_name
  @project_name
end

#proxy_hostObject (readonly)

Returns the value of attribute proxy_host.



33
34
35
# File 'lib/openstack/connection.rb', line 33

def proxy_host
  @proxy_host
end

#proxy_portObject (readonly)

Returns the value of attribute proxy_port.



34
35
36
# File 'lib/openstack/connection.rb', line 34

def proxy_port
  @proxy_port
end

#quantum_versionObject

Returns the value of attribute quantum_version.



17
18
19
# File 'lib/openstack/connection.rb', line 17

def quantum_version
  @quantum_version
end

#regionObject (readonly)

Returns the value of attribute region.



37
38
39
# File 'lib/openstack/connection.rb', line 37

def region
  @region
end

#regions_listObject (readonly)

e.g. os.connection.regions_list == => [ {:service=>“object-store”, :versionId=>“1.0”, :versionId=>“2.0”], “region-b.geo-1”=>[:versionId=>“2.0”] }



38
39
40
# File 'lib/openstack/connection.rb', line 38

def regions_list
  @regions_list
end

#retriesObject (readonly)

Returns the value of attribute retries.



18
19
20
# File 'lib/openstack/connection.rb', line 18

def retries
  @retries
end

#service_hostObject

Returns the value of attribute service_host.



13
14
15
# File 'lib/openstack/connection.rb', line 13

def service_host
  @service_host
end

#service_nameObject (readonly)

Returns the value of attribute service_name.



23
24
25
# File 'lib/openstack/connection.rb', line 23

def service_name
  @service_name
end

#service_pathObject

Returns the value of attribute service_path.



14
15
16
# File 'lib/openstack/connection.rb', line 14

def service_path
  @service_path
end

#service_portObject

Returns the value of attribute service_port.



15
16
17
# File 'lib/openstack/connection.rb', line 15

def service_port
  @service_port
end

#service_schemeObject

Returns the value of attribute service_scheme.



16
17
18
# File 'lib/openstack/connection.rb', line 16

def service_scheme
  @service_scheme
end

#service_typeObject (readonly)

Returns the value of attribute service_type.



24
25
26
# File 'lib/openstack/connection.rb', line 24

def service_type
  @service_type
end

#ssl_versionObject (readonly)

Returns the value of attribute ssl_version.



36
37
38
# File 'lib/openstack/connection.rb', line 36

def ssl_version
  @ssl_version
end

#user_domainObject (readonly)

Returns the value of attribute user_domain.



25
26
27
# File 'lib/openstack/connection.rb', line 25

def user_domain
  @user_domain
end

#user_domain_idObject (readonly)

Returns the value of attribute user_domain_id.



26
27
28
# File 'lib/openstack/connection.rb', line 26

def user_domain_id
  @user_domain_id
end

Class Method Details

.create(options = {:retry_auth => true}) ⇒ Object

Creates and returns a new Connection object, depending on the service_type passed in the options:

e.g: os = OpenStack::Connection.create({:username => “[email protected]”, :api_key=>“password”,

:auth_url => "https://region-a.geo-1.identity.cloudsvc.com:35357/v2.0/",
:authtenant=>"[email protected]", :service_type=>"object-store")

Will return an OpenStack::Swift::Connection object.

options hash:

:username - Your OpenStack username or public key, depending on auth_method. *required*
:auth_method - Type of authentication - 'password', 'key', 'rax-kskey', 'token' - defaults to 'password'.
  For auth v3.0 valid options are 'password', 'token', 'password_user_id'
:authtenant_name OR :authtenant_id - Your OpenStack tenant name or id *required*. Defaults to username.
  passing :authtenant will default to using that parameter as tenant name.
:api_key - Your OpenStack API key *required* (either private key or password, depending on auth_method)
:auth_url - Configurable auth_url endpoint.
:service_name - (Optional for v2.0 auth only). The optional name of the compute service to use.
:service_type - (Optional for v2.0 auth only). Defaults to "compute"
:user_domain - (Optional for v3.0 auth only). The optional name of the user domain.
:user_domain_id - (Optional for v3.0 auth only). Defaults to "default"
:project_id - (Optional for v3.0 auth only). For authorization scoping
:project_name - (Optional for v3.0 auth only). For authorization scoping
:project_domain_name - (Optional for v3.0 auth only). For authorization scoping
:project_domain_id - (Optional for v3.0 auth only). For authorization scoping
:domain_name - (Optional for v3.0 auth only). For authorization scoping
:domain_id - (Optional for v3.0 auth only). For authorization scoping
:region - (Optional for v2.0 auth only). The specific service region to use. Defaults to first returned region.
:retry_auth - Whether to retry if your auth token expires (defaults to true)
:proxy_host - If you need to connect through a proxy, supply the hostname here
:proxy_port - If you need to connect through a proxy, supply the port here
:ca_cert - path to a CA chain in PEM format
:ssl_version - explicitly set an version (:SSLv3 etc, see  OpenSSL::SSL::SSLContext::METHODS)
:is_debug - Only for development purpose for debug output
:endpoint_type - Type of endpoint. Optional. 'publicURL', 'internalURL', 'adminURL'

The options hash is used to create a new OpenStack::Connection object (private constructor) and this is passed to the constructor of OpenStack::Compute::Connection or OpenStack::Swift::Connection (depending on :service_type) where authentication is done using OpenStack::Authentication.



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/openstack/connection.rb', line 87

def self.create(options = {:retry_auth => true})
  #call private constructor and grab instance vars
  connection = new(options)
  case connection.service_type
    when "compute"
      OpenStack::Compute::Connection.new(connection)
    when "object-store"
      OpenStack::Swift::Connection.new(connection)
    when "volume"
      OpenStack::Volume::Connection.new(connection)
    when "image"
      OpenStack::Image::Connection.new(connection)
    when "network"
      OpenStack::Network::Connection.new(connection)
    when "metering"
      OpenStack::Metering::Connection.new(connection)
    when "identity"
      OpenStack::Identity::Connection.new(connection)
   else
      raise Exception::InvalidArgument, "Invalid :service_type parameter: #{@service_type}"
  end
end

Instance Method Details

#csreq(method, server, path, port, scheme, headers = {}, data = nil, attempts = 0, &block) ⇒ Object

This method actually makes the HTTP REST calls out to the server



204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
# File 'lib/openstack/connection.rb', line 204

def csreq(method,server,path,port,scheme,headers = {},data = nil,attempts = 0, &block) # :nodoc:
  tries = @retries
  time = 3

  request_id = "req-#{SecureRandom.uuid}"
  started_timestamp = Time.now.to_f * 1000
  log_request(request_id, "REQUEST: #{method.to_s} => #{scheme}://#{server}#{path}")
  headers.store('X-Openstack-Request-Id', request_id)

  hdrhash = headerprep(headers)
  start_http(server,path,port,scheme,hdrhash)
  request = Net::HTTP.const_get(method.to_s.capitalize).new(path,hdrhash)
  request.body = data
  response = nil
  @semaphore.synchronize do
    if block_given?
      response =  @http[server].request(request) do |res|
        res.read_body do |b|
          yield b
        end
      end
    else
      response = @http[server].request(request)
    end
  end
  log_request(request_id, "RESPONSE: Code => #{response.code} Time => #{(Time.now.to_f * 1000) - started_timestamp}ms")
  if @is_debug
    puts "REQUEST: #{method.to_s} => #{scheme}://#{server}#{path}"
    puts data if data
    puts "RESPONSE: #{response.body}"
    puts '----------------------------------------'
  end
  raise OpenStack::Exception::ExpiredAuthToken if response.code == "401"
  response
rescue Errno::EPIPE, Timeout::Error, Errno::EINVAL, EOFError
  # Server closed the connection, retry
  puts "Can't connect to the server: #{tries} tries to reconnect" if @is_debug
  sleep time += 1
  @http[server].finish if @http[server].started?
  retry unless (tries -= 1) <= 0
  raise OpenStack::Exception::Connection, "Unable to connect to #{server} after #{@retries} retries"
rescue OpenStack::Exception::ExpiredAuthToken
  raise OpenStack::Exception::Connection, "Authentication token expired and you have requested not to retry" if @retry_auth == false
  OpenStack::Authentication.init(self)
  retry
end

#put_object(server, path, port, scheme, headers = {}, data = nil, attempts = 0) ⇒ Object

specialised from of csreq for PUT object… uses body_stream if possible



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
199
200
# File 'lib/openstack/connection.rb', line 158

def put_object(server,path,port,scheme,headers = {},data = nil,attempts = 0) # :nodoc:

  tries = @retries
  time = 3

  if data.respond_to? :read
    headers['Transfer-Encoding'] = 'chunked'
    hdrhash = headerprep(headers)
    request = Net::HTTP::Put.new(path,hdrhash)
    chunked = OpenStack::Swift::ChunkedConnectionWrapper.new(data, 65535)
    request.body_stream = chunked
  else
    headers['Content-Length'] = (data.respond_to?(:lstat))? data.lstat.size.to_s : ((data.respond_to?(:size))? data.size.to_s : "0")
    hdrhash = headerprep(headers)
    request = Net::HTTP::Put.new(path,hdrhash)
    request.body = data
  end
  start_http(server,path,port,scheme,hdrhash)
  response = nil
  @semaphore.synchronize do
    response = @http[server].request(request)
  end
  if @is_debug
    puts "REQUEST: PUT => #{path}"
    puts data if data
    puts "RESPONSE: #{response.body}"
    puts '----------------------------------------'
  end
  raise OpenStack::Exception::ExpiredAuthToken if response.code == "401"
  response
rescue Errno::EPIPE, Timeout::Error, Errno::EINVAL, EOFError
  # Server closed the connection, retry
  puts "Can't connect to the server: #{tries} tries to reconnect" if @is_debug
  sleep time += 1
  @http[server].finish if @http[server].started?
  retry unless (tries -= 1) <= 0
  raise OpenStack::Exception::Connection, "Unable to connect to #{server} after #{@retries} retries"

rescue OpenStack::Exception::ExpiredAuthToken
  raise OpenStack::Exception::Connection, "Authentication token expired and you have requested not to retry" if @retry_auth == false
  OpenStack::Authentication.init(self)
  retry
end

#req(method, path, options = {}) ⇒ Object

This is a much more sane way to make a http request to the api. Example: res = conn.req(‘GET’, “/servers/#id”)



253
254
255
256
257
258
259
260
261
262
263
# File 'lib/openstack/connection.rb', line 253

def req(method, path, options = {})
  server   = options[:server]   || @service_host
  port     = options[:port]     || @service_port
  scheme   = options[:scheme]   || @service_scheme
  headers  = options[:headers]  || {'content-type' => 'application/json'}
  data     = options[:data]
  attempts = options[:attempts] || 0
  path = (@service_path.empty? ? "/" : @service_path) + @quantum_version.to_s + path
  res = csreq(method,server,path,port,scheme,headers,data,attempts)
  res.code.match(/^20.$/) ? (return res) : OpenStack::Exception.raise_exception(res)
end