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.



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/openstack/connection.rb', line 77

def initialize(options = {:retry_auth => true})
  @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"
  @region = options[:region] || @region = nil
  @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]
  @authok = false
  @http = {}
end

Instance Attribute Details

#auth_hostObject (readonly)

Returns the value of attribute auth_host.



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

def auth_host
  @auth_host
end

#auth_methodObject (readonly)

Returns the value of attribute auth_method.



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

def auth_method
  @auth_method
end

#auth_pathObject (readonly)

Returns the value of attribute auth_path.



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

def auth_path
  @auth_path
end

#auth_portObject (readonly)

Returns the value of attribute auth_port.



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

def auth_port
  @auth_port
end

#auth_schemeObject (readonly)

Returns the value of attribute auth_scheme.



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

def auth_scheme
  @auth_scheme
end

#authkeyObject (readonly)

Returns the value of attribute authkey.



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

def authkey
  @authkey
end

#authokObject

Returns the value of attribute authok.



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

def authok
  @authok
end

#authtenantObject (readonly)

Returns the value of attribute authtenant.



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

def authtenant
  @authtenant
end

#authtokenObject

Returns the value of attribute authtoken.



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

def authtoken
  @authtoken
end

#authuserObject (readonly)

Returns the value of attribute authuser.



5
6
7
# File 'lib/openstack/connection.rb', line 5

def authuser
  @authuser
end

#httpObject (readonly)

Returns the value of attribute http.



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

def http
  @http
end

#is_debugObject (readonly)

Returns the value of attribute is_debug.



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

def is_debug
  @is_debug
end

#proxy_hostObject (readonly)

Returns the value of attribute proxy_host.



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

def proxy_host
  @proxy_host
end

#proxy_portObject (readonly)

Returns the value of attribute proxy_port.



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

def proxy_port
  @proxy_port
end

#regionObject (readonly)

Returns the value of attribute region.



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

def region
  @region
end

#service_hostObject

Returns the value of attribute service_host.



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

def service_host
  @service_host
end

#service_nameObject (readonly)

Returns the value of attribute service_name.



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

def service_name
  @service_name
end

#service_pathObject

Returns the value of attribute service_path.



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

def service_path
  @service_path
end

#service_portObject

Returns the value of attribute service_port.



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

def service_port
  @service_port
end

#service_schemeObject

Returns the value of attribute service_scheme.



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

def service_scheme
  @service_scheme
end

#service_typeObject (readonly)

Returns the value of attribute service_type.



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

def service_type
  @service_type
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:

:auth_method - Type of authentication - 'password', 'key', 'rax-kskey' - defaults to 'password'
:username - Your OpenStack username or public key, depending on auth_method. *required*
: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"
: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

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.



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/openstack/connection.rb', line 58

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)
   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



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

def csreq(method,server,path,port,scheme,headers = {},data = nil,attempts = 0, &block) # :nodoc:
  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
  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
  if @is_debug
      puts "REQUEST: #{method} => #{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
  raise OpenStack::Exception::Connection, "Unable to reconnect to #{server} after #{attempts} attempts" if attempts >= 5
  attempts += 1
  @http[server].finish if @http[server].started?
  start_http(server,path,port,scheme,headers)
  retry
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



106
107
108
109
110
111
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
# File 'lib/openstack/connection.rb', line 106

def put_object(server,path,port,scheme,headers = {},data = nil,attempts = 0) # :nodoc:
  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 = @http[server].request(request)
  if @is_debug
      puts "REQUEST: #{method} => #{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
  raise OpenStack::Exception::Connection, "Unable to reconnect to #{server} after #{attempts} attempts" if attempts >= 5
  attempts += 1
  @http[server].finish if @http[server].started?
  start_http(server,path,port,scheme,headers)
  retry
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”)



181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/openstack/connection.rb', line 181

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 + path
  res = csreq(method,server,path,port,scheme,headers,data,attempts)
  if not res.code.match(/^20.$/)
    OpenStack::Exception.raise_exception(res)
  end
  return res
end