Class: OpenStack::Compute::Connection

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

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

Creates a new OpenStack::Compute::Connection object. Uses OpenStack::Compute::Authentication to perform the login for the connection.

The constructor takes a hash of options, including:

:username - Your Openstack username *required*
:tenant - Your Openstack tenant *required*. Defaults to username.
:api_key - Your Openstack API key *required*
: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

cs = OpenStack::Compute::Connection.new(:username => 'USERNAME', :api_key => 'API_KEY', :auth_url => 'AUTH_URL')


41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/openstack/compute/connection.rb', line 41

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] || @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 = {}
  OpenStack::Compute::Authentication.init(self)
end

Instance Attribute Details

#auth_hostObject (readonly)

Returns the value of attribute auth_host.



15
16
17
# File 'lib/openstack/compute/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/compute/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/compute/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/compute/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/compute/connection.rb', line 17

def auth_scheme
  @auth_scheme
end

#authkeyObject (readonly)

Returns the value of attribute authkey.



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

def authkey
  @authkey
end

#authokObject

Returns the value of attribute authok.



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

def authok
  @authok
end

#authtenantObject (readonly)

Returns the value of attribute authtenant.



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

def authtenant
  @authtenant
end

#authtokenObject

Returns the value of attribute authtoken.



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

def authtoken
  @authtoken
end

#authuserObject (readonly)

Returns the value of attribute authuser.



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

def authuser
  @authuser
end

#proxy_hostObject (readonly)

Returns the value of attribute proxy_host.



21
22
23
# File 'lib/openstack/compute/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/compute/connection.rb', line 22

def proxy_port
  @proxy_port
end

#regionObject (readonly)

Returns the value of attribute region.



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

def region
  @region
end

#service_nameObject (readonly)

Returns the value of attribute service_name.



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

def service_name
  @service_name
end

#service_typeObject (readonly)

Returns the value of attribute service_type.



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

def service_type
  @service_type
end

#svrmgmthostObject

Returns the value of attribute svrmgmthost.



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

def svrmgmthost
  @svrmgmthost
end

#svrmgmtpathObject

Returns the value of attribute svrmgmtpath.



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

def svrmgmtpath
  @svrmgmtpath
end

#svrmgmtportObject

Returns the value of attribute svrmgmtport.



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

def svrmgmtport
  @svrmgmtport
end

#svrmgmtschemeObject

Returns the value of attribute svrmgmtscheme.



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

def svrmgmtscheme
  @svrmgmtscheme
end

Instance Method Details

#authok?Boolean

Returns true if the authentication was successful and returns false otherwise.

cs.authok?
=> true

Returns:

  • (Boolean)


75
76
77
# File 'lib/openstack/compute/connection.rb', line 75

def authok?
  @authok
end

#create_server(options) ⇒ Object

Creates a new server instance on OpenStack Compute

The argument is a hash of options. The keys :name, :flavorRef, and :imageRef are required; :metadata and :personality are optional.

:flavorRef and :imageRef are href strings identifying a particular server flavor and image to use when building the server. The :imageRef can either be a stock image, or one of your own created with the server.create_image method.

The :metadata argument should be a hash of key/value pairs. This metadata will be applied to the server at the OpenStack Compute API level.

The “Personality” option allows you to include up to five files, # of 10Kb or less in size, that will be placed on the created server. For :personality, pass a hash of the form => ‘server_path’. The file located at local_path will be base64-encoded and placed at the location identified by server_path on the new server.

Returns a OpenStack::Compute::Server object. The root password is available in the adminPass instance method.

>> server = cs.create_server(
     :name        => 'NewServer',
     :imageRef    => 'http://172.19.0.3/v1.1/images/3',
     :flavorRef   => 'http://172.19.0.3/v1.1/flavors/1',
     :metadata    => {'Racker' => 'Fanatical'},
     :personality => {'/home/bob/wedding.jpg' => '/root/wedding.jpg'})
=> #<OpenStack::Compute::Server:0x101229eb0 ...>
>> server.name
=> "NewServer"
>> server.status
=> "BUILD"
>> server.adminPass
=> "NewServerSHMGpvI"


209
210
211
212
213
214
215
216
217
218
219
# File 'lib/openstack/compute/connection.rb', line 209

def create_server(options)
  raise OpenStack::Compute::Exception::MissingArgument, "Server name, flavorRef, and imageRef, must be supplied" unless (options[:name] && options[:flavorRef] && options[:imageRef])
  options[:personality] = Personalities.get_personality(options[:personality])
  data = JSON.generate(:server => options)
  response = csreq("POST",svrmgmthost,"#{svrmgmtpath}/servers",svrmgmtport,svrmgmtscheme,{'content-type' => 'application/json'},data)
  OpenStack::Compute::Exception.raise_exception(response) unless response.code.match(/^20.$/)
  server_info = JSON.parse(response.body)['server']
  server = OpenStack::Compute::Server.new(self,server_info['id'])
  server.adminPass = server_info['adminPass']
  return server
end

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

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



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

def csreq(method,server,path,port,scheme,headers = {},data = nil,attempts = 0) # :nodoc:
  start = Time.now
  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 = @http[server].request(request)
  if @is_debug
      puts "REQUEST: #{method} => #{path}"
      puts data if data
      puts "RESPONSE: #{response.body}"
      puts '----------------------------------------'
  end
  raise OpenStack::Compute::Exception::ExpiredAuthToken if response.code == "401"
  response
rescue Errno::EPIPE, Timeout::Error, Errno::EINVAL, EOFError
  # Server closed the connection, retry
  raise OpenStack::Compute::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::Compute::Exception::ExpiredAuthToken
  raise OpenStack::Compute::Exception::Connection, "Authentication token expired and you have requested not to retry" if @retry_auth == false
  OpenStack::Compute::Authentication.init(self)
  retry
end

#get_flavor(id) ⇒ Object Also known as: flavor

Returns a OpenStack::Compute::Flavor object for the flavor identified by the provided ID.

>> flavor = cs.flavor(1)
=> #<OpenStack::Compute::Flavor:0x10156dcc0 @name="256 server", @disk=10, @id=1, @ram=256>


275
276
277
# File 'lib/openstack/compute/connection.rb', line 275

def get_flavor(id)
  OpenStack::Compute::Flavor.new(self,id)
end

#get_image(id) ⇒ Object Also known as: image

Returns a OpenStack::Compute::Image object for the image identified by the provided id.

>> image = cs.get_image(8)
=> #<OpenStack::Compute::Image:0x101659698 ...>


246
247
248
# File 'lib/openstack/compute/connection.rb', line 246

def get_image(id)
  OpenStack::Compute::Image.new(self,id)
end

#get_server(id) ⇒ Object Also known as: server

Returns the OpenStack::Compute::Server object identified by the given id.

>> server = cs.get_server(110917)
=> #<OpenStack::Compute::Server:0x101407ae8 ...>
>> server.name
=> "MyServer"


131
132
133
# File 'lib/openstack/compute/connection.rb', line 131

def get_server(id)
  OpenStack::Compute::Server.new(self,id)
end

#limitsObject

Returns the current state of the programatic API limits. Each account has certain limits on the number of resources allowed in the account, and a rate of API operations.

The operation returns a hash. The :absolute hash key reveals the account resource limits, including the maxmimum amount of total RAM that can be allocated (combined among all servers), the maximum members of an IP group, and the maximum number of IP groups that can be created.

The :rate hash key returns an array of hashes indicating the limits on the number of operations that can be performed in a given amount of time. An entry in this array looks like:

{:regex=>"^/servers", :value=>50, :verb=>"POST", :remaining=>50, :unit=>"DAY", :resetTime=>1272399820, :URI=>"/servers*"}

This indicates that you can only run 50 POST operations against URLs in the /servers URI space per day, we have not run any operations today (50 remaining), and gives the Unix time that the limits reset.

Another example is:

{:regex=>".*", :value=>10, :verb=>"PUT", :remaining=>10, :unit=>"MINUTE", :resetTime=>1272399820, :URI=>"*"}

This says that you can run 10 PUT operations on all possible URLs per minute, and also gives the number remaining and the time that the limit resets.

Use this information as you’re building your applications to put in relevant pauses if you approach your API limitations.



303
304
305
306
307
# File 'lib/openstack/compute/connection.rb', line 303

def limits
  response = csreq("GET",svrmgmthost,"#{svrmgmtpath}/limits",svrmgmtport,svrmgmtscheme)
  OpenStack::Compute::Exception.raise_exception(response) unless response.code.match(/^20.$/)
  OpenStack::Compute.symbolize_keys(JSON.parse(response.body)['limits'])
end

#list_flavors(options = {}) ⇒ Object Also known as: flavors

Returns an array of hashes listing all available server flavors. The :id key in the hash can be used when flavorRef is required.

You can also provide :limit and :offset parameters to handle pagination.

>> cs.list_flavors
=> [{:name=>"256 server", :id=>1, :ram=>256, :disk=>10}, 
    {:name=>"512 server", :id=>2, :ram=>512, :disk=>20},...

>> cs.list_flavors(:limit => 3, :offset => 2)
=> [{:ram=>1024, :disk=>40, :name=>"1GB server", :id=>3}, 
    {:ram=>2048, :disk=>80, :name=>"2GB server", :id=>4}, 
    {:ram=>4096, :disk=>160, :name=>"4GB server", :id=>5}]


263
264
265
266
267
268
# File 'lib/openstack/compute/connection.rb', line 263

def list_flavors(options = {})
  path = OpenStack::Compute.paginate(options).empty? ? "#{svrmgmtpath}/flavors/detail" : "#{svrmgmtpath}/flavors/detail?#{OpenStack::Compute.paginate(options)}"
  response = csreq("GET",svrmgmthost,path,svrmgmtport,svrmgmtscheme)
  OpenStack::Compute::Exception.raise_exception(response) unless response.code.match(/^20.$/)
  OpenStack::Compute.symbolize_keys(JSON.parse(response.body)['flavors'])
end

#list_images(options = {}) ⇒ Object Also known as: images

Returns an array of hashes listing available server images that you have access too, including stock OpenStack Compute images and any that you have created. The “id” key in the hash can be used where imageRef is required.

You can also provide :limit and :offset parameters to handle pagination.

>> cs.list_images
=> [{:name=>"CentOS 5.2", :id=>2, :updated=>"2009-07-20T09:16:57-05:00", :status=>"ACTIVE", :created=>"2009-07-20T09:16:57-05:00"}, 
    {:name=>"Gentoo 2008.0", :id=>3, :updated=>"2009-07-20T09:16:57-05:00", :status=>"ACTIVE", :created=>"2009-07-20T09:16:57-05:00"},...

>> cs.list_images(:limit => 3, :offset => 2) 
=> [{:status=>"ACTIVE", :name=>"Fedora 11 (Leonidas)", :updated=>"2009-12-08T13:50:45-06:00", :id=>13}, 
    {:status=>"ACTIVE", :name=>"CentOS 5.3", :updated=>"2009-08-26T14:59:52-05:00", :id=>7}, 
    {:status=>"ACTIVE", :name=>"CentOS 5.4", :updated=>"2009-12-16T01:02:17-06:00", :id=>187811}]


234
235
236
237
238
239
# File 'lib/openstack/compute/connection.rb', line 234

def list_images(options = {})
  path = OpenStack::Compute.paginate(options).empty? ? "#{svrmgmtpath}/images/detail" : "#{svrmgmtpath}/images/detail?#{OpenStack::Compute.paginate(options)}"
  response = csreq("GET",svrmgmthost,path,svrmgmtport,svrmgmtscheme)
  OpenStack::Compute::Exception.raise_exception(response) unless response.code.match(/^20.$/)
  OpenStack::Compute.symbolize_keys(JSON.parse(response.body)['images'])
end

#list_servers(options = {}) ⇒ Object Also known as: servers

Returns an array of hashes, one for each server that exists under this account. The hash keys are :name and :id.

You can also provide :limit and :offset parameters to handle pagination.

>> cs.list_servers
=> [{:name=>"MyServer", :id=>110917}]

>> cs.list_servers(:limit => 2, :offset => 3)
=> [{:name=>"demo-standingcloud-lts", :id=>168867}, 
    {:name=>"demo-aicache1", :id=>187853}]


146
147
148
149
150
151
152
# File 'lib/openstack/compute/connection.rb', line 146

def list_servers(options = {})
  anti_cache_param="cacheid=#{Time.now.to_i}"
  path = OpenStack::Compute.paginate(options).empty? ? "#{svrmgmtpath}/servers?#{anti_cache_param}" : "#{svrmgmtpath}/servers?#{OpenStack::Compute.paginate(options)}&#{anti_cache_param}"
  response = csreq("GET",svrmgmthost,path,svrmgmtport,svrmgmtscheme)
  OpenStack::Compute::Exception.raise_exception(response) unless response.code.match(/^20.$/)
  OpenStack::Compute.symbolize_keys(JSON.parse(response.body)["servers"])
end

#list_servers_detail(options = {}) ⇒ Object Also known as: servers_detail

Returns an array of hashes with more details about each server that exists under this account. Additional information includes public and private IP addresses, status, hostID, and more. All hash keys are symbols except for the metadata hash, which are verbatim strings.

You can also provide :limit and :offset parameters to handle pagination.

>> cs.list_servers_detail
=> [{:name=>"MyServer", :addresses=>{:public=>["67.23.42.37"], :private=>["10.176.241.237"]}, :metadata=>{"MyData" => "Valid"}, :imageRef=>10, :progress=>100, :hostId=>"36143b12e9e48998c2aef79b50e144d2", :flavorRef=>1, :id=>110917, :status=>"ACTIVE"}]

>> cs.list_servers_detail(:limit => 2, :offset => 3)
=> [{:status=>"ACTIVE", :imageRef=>10, :progress=>100, :metadata=>{}, :addresses=>{:public=>["x.x.x.x"], :private=>["x.x.x.x"]}, :name=>"demo-standingcloud-lts", :id=>168867, :flavorRef=>1, :hostId=>"xxxxxx"}, 
    {:status=>"ACTIVE", :imageRef=>8, :progress=>100, :metadata=>{}, :addresses=>{:public=>["x.x.x.x"], :private=>["x.x.x.x"]}, :name=>"demo-aicache1", :id=>187853, :flavorRef=>3, :hostId=>"xxxxxx"}]


166
167
168
169
170
171
# File 'lib/openstack/compute/connection.rb', line 166

def list_servers_detail(options = {})
  path = OpenStack::Compute.paginate(options).empty? ? "#{svrmgmtpath}/servers/detail" : "#{svrmgmtpath}/servers/detail?#{OpenStack::Compute.paginate(options)}"
  response = csreq("GET",svrmgmthost,path,svrmgmtport,svrmgmtscheme)
  OpenStack::Compute::Exception.raise_exception(response) unless response.code.match(/^20.$/)
  OpenStack::Compute.symbolize_keys(JSON.parse(response.body)["servers"])
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”)



110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/openstack/compute/connection.rb', line 110

def req(method, path, options = {})
  server   = options[:server]   || @svrmgmthost
  port     = options[:port]     || @svrmgmtport
  scheme   = options[:scheme]   || @svrmgmtscheme
  headers  = options[:headers]  || {'content-type' => 'application/json'}
  data     = options[:data]
  attempts = options[:attempts] || 0
  path = @svrmgmtpath + path
  res = csreq(method,server,path,port,scheme,headers,data,attempts)
  if not res.code.match(/^20.$/)
    OpenStack::Compute::Exception.raise_exception(res)
  end
  return res
end