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.



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

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"
  @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]
  @authok = false
  @http = {}
  @quantum_version = 'v2.0' if @service_type == 'network'
end

Instance Attribute Details

#auth_hostObject (readonly)

Returns the value of attribute auth_host.



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

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.



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

def auth_path
  @auth_path
end

#auth_portObject (readonly)

Returns the value of attribute auth_port.



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

def auth_port
  @auth_port
end

#auth_schemeObject (readonly)

Returns the value of attribute auth_scheme.



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

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.



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

def http
  @http
end

#is_debugObject (readonly)

Returns the value of attribute is_debug.



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

def is_debug
  @is_debug
end

#proxy_hostObject (readonly)

Returns the value of attribute proxy_host.



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

def proxy_host
  @proxy_host
end

#proxy_portObject (readonly)

Returns the value of attribute proxy_port.



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

def proxy_port
  @proxy_port
end

#quantum_versionObject

Returns the value of attribute quantum_version.



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

def quantum_version
  @quantum_version
end

#regionObject (readonly)

Returns the value of attribute region.



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

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”] }



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

def regions_list
  @regions_list
end

#retriesObject (readonly)

Returns the value of attribute retries.



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

def retries
  @retries
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.



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

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.



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

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.



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/openstack/connection.rb', line 61

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



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

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

  tries = @retries
  time = 3

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



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

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 = @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
  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”)



198
199
200
201
202
203
204
205
206
207
208
# File 'lib/openstack/connection.rb', line 198

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 + @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