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*
:api_key - Your Openstack API key *required*
:api_url - The url of the Openstack Compute API server.
: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

cf = OpenStack::Compute::Connection.new(:username => 'USERNAME', :api_key => 'API_KEY', :api_url => 'API_URL')


31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/openstack/compute/connection.rb', line 31

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")
  @api_url = options[:api_url] || (raise Exception::MissingArgument, "Must supply an :api_url")

  api_uri=nil
  begin
    api_uri=URI.parse(@api_url)
  rescue Exception => e
    raise Exception::InvalidArgument, "Invalid :api_url parameter: #{e.message}"
  end
  raise Exception::InvalidArgument, "Invalid :api_url parameter." if api_uri.nil? or api_uri.host.nil?
  @api_host = api_uri.host
  @api_port = api_uri.port
  @api_scheme = api_uri.scheme

  @retry_auth = options[:retry_auth]
  @proxy_host = options[:proxy_host]
  @proxy_port = options[:proxy_port]
  @authok = false
  @http = {}
  OpenStack::Compute::Authentication.new(self)
end

Instance Attribute Details

#api_hostObject (readonly)

Returns the value of attribute api_host.



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

def api_host
  @api_host
end

#api_portObject (readonly)

Returns the value of attribute api_port.



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

def api_port
  @api_port
end

#api_schemeObject (readonly)

Returns the value of attribute api_scheme.



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

def api_scheme
  @api_scheme
end

#authkeyObject (readonly)

Returns the value of attribute authkey.



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

def authkey
  @authkey
end

#authokObject

Returns the value of attribute authok.



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

def authok
  @authok
end

#authtokenObject

Returns the value of attribute authtoken.



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

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.



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

def proxy_host
  @proxy_host
end

#proxy_portObject (readonly)

Returns the value of attribute proxy_port.



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

def proxy_port
  @proxy_port
end

#svrmgmthostObject

Returns the value of attribute svrmgmthost.



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

def svrmgmthost
  @svrmgmthost
end

#svrmgmtpathObject

Returns the value of attribute svrmgmtpath.



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

def svrmgmtpath
  @svrmgmtpath
end

#svrmgmtportObject

Returns the value of attribute svrmgmtport.



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

def svrmgmtport
  @svrmgmtport
end

#svrmgmtschemeObject

Returns the value of attribute svrmgmtscheme.



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

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)


59
60
61
# File 'lib/openstack/compute/connection.rb', line 59

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, :flavorId, and :imageId are required, :metadata and :personality are optional.

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

The :metadata argument will take a hash of up to five 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 => "New Server", :imageId => 2, :flavorId => 2, :metadata => {'Racker' => 'Fanatical'}, :personality => {'/Users/me/Pictures/wedding.jpg' => '/root/me.jpg'})
=> #<OpenStack::Compute::Server:0x101229eb0 ...>
>> server.name
=> "NewServer"
>> server.status
=> "BUILD"
>> server.adminPass
=> "NewServerSHMGpvI"


159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/openstack/compute/connection.rb', line 159

def create_server(options)
  raise OpenStack::Compute::Exception::MissingArgument, "Server name, flavor ID, and image ID must be supplied" unless (options[:name] && options[:flavorId] && options[:imageId])
  options[:personality] = get_personality(options[:personality])
  raise TooManyMetadataItems, "Metadata is limited to a total of #{MAX_PERSONALITY_METADATA_ITEMS} key/value pairs" if options[:metadata].is_a?(Hash) && options[:metadata].keys.size > MAX_PERSONALITY_METADATA_ITEMS
  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

#create_shared_ip_group(options) ⇒ Object

Creates a new Shared IP group. Takes a hash as an argument.

Valid hash keys are :name (required) and :server (optional), which indicates the one server to place into this group by default.

>> sig = cs.create_shared_ip_group(:name => "Production Web", :server => 110917) 
=> #<OpenStack::Compute::SharedIPGroup:0x101501d18 ...>
>> sig.name
=> "Production Web"
>> sig.servers
=> [110917]


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

def create_shared_ip_group(options)
  data = JSON.generate(:sharedIpGroup => options)
  response = csreq("POST",svrmgmthost,"#{svrmgmtpath}/shared_ip_groups",svrmgmtport,svrmgmtscheme,{'content-type' => 'application/json'},data)
  OpenStack::Compute::Exception.raise_exception(response) unless response.code.match(/^20.$/)
  ip_group = JSON.parse(response.body)['sharedIpGroup']
  OpenStack::Compute::SharedIPGroup.new(self,ip_group['id'])
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



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/openstack/compute/connection.rb', line 64

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)
  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
  CloudFiles::Authentication.new(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>


226
227
228
# File 'lib/openstack/compute/connection.rb', line 226

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


197
198
199
# File 'lib/openstack/compute/connection.rb', line 197

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"


92
93
94
# File 'lib/openstack/compute/connection.rb', line 92

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

#get_shared_ip_group(id) ⇒ Object Also known as: shared_ip_group

Returns a OpenStack::Compute::SharedIPGroup object for the IP group identified by the provided ID.

>> sig = cs.get_shared_ip_group(127)
=> #<OpenStack::Compute::SharedIPGroup:0x10153ca30  ...>


249
250
251
# File 'lib/openstack/compute/connection.rb', line 249

def get_shared_ip_group(id)
  OpenStack::Compute::SharedIPGroup.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.



295
296
297
298
299
# File 'lib/openstack/compute/connection.rb', line 295

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


214
215
216
217
218
219
# File 'lib/openstack/compute/connection.rb', line 214

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


185
186
187
188
189
190
# File 'lib/openstack/compute/connection.rb', line 185

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


107
108
109
110
111
112
113
# File 'lib/openstack/compute/connection.rb', line 107

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"}, :imageId=>10, :progress=>100, :hostId=>"36143b12e9e48998c2aef79b50e144d2", :flavorId=>1, :id=>110917, :status=>"ACTIVE"}]

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


127
128
129
130
131
132
# File 'lib/openstack/compute/connection.rb', line 127

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

#list_shared_ip_groups(options = {}) ⇒ Object Also known as: shared_ip_groups

Returns an array of hashes for all Shared IP Groups that are available. The :id key can be used to find that specific object.

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

>> cs.list_shared_ip_groups
=> [{:name=>"New Group", :id=>127}]


237
238
239
240
241
242
# File 'lib/openstack/compute/connection.rb', line 237

def list_shared_ip_groups(options = {})
  path = OpenStack::Compute.paginate(options).empty? ? "#{svrmgmtpath}/shared_ip_groups/detail" : "#{svrmgmtpath}/shared_ip_groups/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)['sharedIpGroups'])
end