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(connection) ⇒ Connection

Returns a new instance of Connection.



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

def initialize(connection)
  @extensions = nil
  @connection = connection
  OpenStack::Authentication.init(@connection)
end

Instance Attribute Details

#connectionObject

Returns the value of attribute connection.



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

def connection
  @connection
end

#extensionsObject

Returns the value of attribute extensions.



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

def extensions
  @extensions
end

Instance Method Details

#add_tenant_to_flavor(flavor_id, tenant_id) ⇒ Object



212
213
214
215
216
# File 'lib/openstack/compute/connection.rb', line 212

def add_tenant_to_flavor(flavor_id, tenant_id)
  data = JSON.generate({'addTenantAccess' => {'tenant' => tenant_id}})
  response = @connection.req('POST', "/flavors/#{flavor_id}/action", {data: data})
  JSON.parse(response.body)
end

#api_extensionsObject

query the openstack provider for any implemented extensions to the compute API returns a hash with openstack service provider’s returned details about the implemented extensions, e.g.:

{ :os-floating_ips => { :links=>[],

                    :updated=>"2011-06-16T00:00:00+00:00",
                    :description=>"Floating IPs support",
                    :namespace=>"http://docs.openstack.org/ext/floating_ips/api/v1.1",
                    :name=>"Floating_ips", :alias=>"os-floating-ips"},
:os-keypairs     =>  { :links=>[],
                    :updated=>"2011-08-08T00:00:00+00:00",
                    :description=>"Keypair Support",
                    :namespace=>"http://docs.openstack.org/ext/keypairs/api/v1.1",
                    :name=>"Keypairs",
                    :alias=>"os-keypairs"}

}



327
328
329
330
331
332
333
334
335
# File 'lib/openstack/compute/connection.rb', line 327

def api_extensions
  if @extensions.nil?
    response = @connection.req("GET", "/extensions")
    OpenStack::Exception.raise_exception(response) unless response.code.match(/^20.$/)
    res = OpenStack.symbolize_keys(JSON.parse(response.body))
    @extensions = res[:extensions].inject({}){|result, c| result[c[:alias].to_sym] = c  ; result}
  end
  @extensions
end

#attach_floating_ip(opts = {:server_id=>"", :ip_id => ""}) ⇒ Object

add or attach a floating IP to a runnin g server



544
545
546
547
548
549
550
551
# File 'lib/openstack/compute/connection.rb', line 544

def attach_floating_ip(opts={:server_id=>"", :ip_id => ""})
  check_extension("os-floating-ips")
  #first get the address:
  addr = get_floating_ip(opts[:ip_id]).ip
  data = JSON.generate({:addFloatingIp=>{:address=>addr}})
  @connection.req("POST", "/servers/#{opts[:server_id]}/action", {:data=>data})
  true
end

#attach_volume(server_id, volume_id, device_id) ⇒ Object

VOLUMES - attach detach



487
488
489
490
491
492
# File 'lib/openstack/compute/connection.rb', line 487

def attach_volume(server_id, volume_id, device_id)
  raise OpenStack::Exception::NotImplemented.new("os-volumes not implemented by #{@connection.http.keys.first}", 501, "NOT IMPLEMENTED") unless api_extensions[:"os-volumes"]
  data = JSON.generate(:volumeAttachment => {"volumeId" => volume_id, "device"=> device_id})
  @connection.req("POST", "/servers/#{server_id}/os-volume_attachments", {:data=>data})
  true
end

#authok?Boolean

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

cs.authok?
=> true

Returns:

  • (Boolean)


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

def authok?
  @connection.authok
end

#create_flavor(options, public = false) ⇒ Object

nova.create_flavor(‘small’, vcpus: 2, ram: 1024, disk: 1, true) :name - must be unique, :ram - MB, :disk - GB

> #<OpenStack::Compute::Flavor:0x007ff95333e268 @id=“0c0c393b-3acd-4569-baae-7a7afbe398f6”, @name=“small”, @ram=1024, @disk=1, @vcpus=2>



199
200
201
202
203
204
205
# File 'lib/openstack/compute/connection.rb', line 199

def create_flavor(options, public = false)
  raise OpenStack::Exception::MissingArgument, 'Flavor name, vcpus, ram and disk, must be supplied' unless (options[:name] && options[:vcpus] && options[:ram] && options[:disk])
  data = JSON.generate(:flavor => options.merge!({'os-flavor-access:is_public' => public}))
  response = @connection.req('POST', '/flavors', {data: data})
  flavor_info = JSON.parse(response.body)['flavor']
  OpenStack::Compute::Flavor.new(flavor_info)
end

#create_flavor_extra_specs(flavor_id, options) ⇒ Object

Creates extra specs for a flavor, by ID

create_flavor_extra_specs(‘999aca87-5c8a-4862-92fe-deb8bb024b6b’, { ‘quota:disk_total_iops_sec’ => 1000 })

> { ‘quota:disk_total_iops_sec’ => 1000 }



230
231
232
233
234
# File 'lib/openstack/compute/connection.rb', line 230

def create_flavor_extra_specs(flavor_id, options)
  data = JSON.generate(extra_specs: options)
  response = @connection.req('POST', "/flavors/#{flavor_id}/os-extra_specs", data: data)
  JSON.parse(response.body)['extra_specs']
end

#create_floating_ip(opts = {}) ⇒ Object Also known as: allocate_floating_ip

can optionally pass the :pool parameter



527
528
529
530
531
532
533
# File 'lib/openstack/compute/connection.rb', line 527

def create_floating_ip(opts={})
  check_extension("os-floating-ips")
  data = opts[:pool] ? JSON.generate(opts) : JSON.generate({:pool=>nil})
  response = @connection.req("POST", "/os-floating-ips",{:data=>data} )
  res = JSON.parse(response.body)["floating_ip"]
  OpenStack::Compute::FloatingIPAddress.new(res)
end

#create_floating_ips_bulk(opts = {}) ⇒ Object

Raises:

  • (ArgumentError)


581
582
583
584
585
586
587
# File 'lib/openstack/compute/connection.rb', line 581

def create_floating_ips_bulk(opts = {})
  raise ArgumentError, 'Should not be empty' if opts.empty?
  data = JSON.generate({:floating_ips_bulk_create => opts})
  check_extension 'os-floating-ips-bulk'
  response = @connection.req('POST', '/os-floating-ips-bulk', {:data => data})
  JSON.parse(response.body)['floating_ips_bulk_create']
end

#create_keypair(options) ⇒ Object

Create a new keypair for use with launching servers. Raises a OpenStack::Exception::NotImplemented if os-keypairs extension is not implemented (or not advertised) by the OpenStack provider.

The ‘name’ parameter MUST be supplied, otherwise a OpenStack::Exception::MissingArgument will be raised.

Optionally requests can specify a ‘public_key’ parameter, with the full public ssh key (String) to be used to create the keypair (i.e. import a existing key).

Returns a hash with details of the new key; the :private_key attribute must be saved must be saved by caller (not retrievable thereafter). NOTE: when the optional :public_key parameter is given, the response will obviously NOT contain the :private_key attribute.

>> os.create_keypair(:name=>“test_key”)

> { :name => “test_key”,

    :fingerprint  =>  "f1:f3:a2:d3:ca:75:da:f1:06:f4:f7:dc:cc:7d:e1:ca",
    :user_id      =>  "dev_41247879706381",
    :public_key   =>  "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDgGhDH3z9uMAvPV8ziE9BCEjHCPXGufy5bOgY5mY5jOSfdmKspdbl0z/LimHVKRDNX6HoL5qRg5V/tGH/NYP5sX2zF/XRKz16lfBxiUL1EONXA9fsTEBR3FGp8NcA7hW2+YiUxWafms4If3NFqttTQ11XqTU8JCMvms4D81lhbiQ== nova@use03147k5-eth0\n",
    :private_key  =>  "-----BEGIN RSA PRIVATE KEY-----\nMIICXwIBAAKBgQDgGhDH3z9uMAvPV8ziE9BCEjHCPXGufy5bOgY5mY5jOSfdmKsp\ndbl0z/LimHVKRDNX6HoL5qRg5V/tGH/NYP5sX2zF/XRKz16lfBxiUL1EONXA9fsT\nEBR3FGp8NcA7hW2+YiUxWafms4If3NFqttTQ11XqTU8JCMvms4D81lhbiQIDAQAB\nAoGBAJ1akAfXwNEc2V4IV2sy4FtULS4nOKh+0szpjC9rm+gd3Nki9qQQ7lyQGwpy\nZID2LFsAeJnco/UJefaf6jUKcvnS7tlxMuQB8DBlepiDqnnec0EiEAVmmt9GWlYZ\nJgfGWqDzI1WtouDCIsOhx1Vq7Foue6pgOnibktg2kfYnH9IRAkEA9tKzhlr9rFui\nbVDkiRJK3VTIhKyk4davDjqPJFLJ+4+77wRW164sGxwReD7HtW6qVtJd1MFvqLDO\nqJJEsqDvXQJBAOhvGaWiAPSuP+/z6GE6VXB1pADQFTYIp2DXUa5DcStTGe7hGF1b\nDeAxpDNBbLO3YKYqi2L9vJcIsp5PkHlEVh0CQQCVLIkWBb5VQliryv0knuqiVFCQ\nZyuL1s2cQuYqZOLwaFGERtIZrom3pMImM4NN82F98cyF/pb2lE2CckyUzVF9AkEA\nqhwFjS9Pu8N7j8XWoLHsre2rJd0kaPNUbI+pe/xn6ula5XVgO5LUSOyL2+daAv2G\ngpZIhR5m07LN5wccGWRmEQJBALZRenXaSyX2R2C9ag9r2gaU8/h+aU9he5kjXIt8\n+B8wvpvfOkpOAVCQEMxtsDkEixUtI98YKZP60uw+Xzh40YU=\n-----END RSA PRIVATE KEY-----\n"
}

Will raise an OpenStack::Exception::BadRequest if an invalid public_key is provided: >> os.create_keypair(:public_key=>“derp”)

> OpenStack::Exception::BadRequest: Unexpected error while running command.

Stdout: '/tmp/tmp4kI12a/import.pub is not a public key file.\n'


392
393
394
395
396
397
398
399
# File 'lib/openstack/compute/connection.rb', line 392

def create_keypair(options)
  raise OpenStack::Exception::NotImplemented.new("os-keypairs not implemented by #{@connection.http.keys.first}", 501, "NOT IMPLEMENTED") unless api_extensions[:"os-keypairs"]
  raise OpenStack::Exception::MissingArgument, "Keypair name must be supplied" unless (options[:name])
  data = JSON.generate(:keypair => options)
  response = @connection.req("POST", "/os-keypairs", {:data=>data})
  res = OpenStack.symbolize_keys(JSON.parse(response.body))
  res[:keypair]
end

#create_security_group(name, description) ⇒ Object



446
447
448
449
450
451
452
# File 'lib/openstack/compute/connection.rb', line 446

def create_security_group(name, description)
  raise OpenStack::Exception::NotImplemented.new("os-security-groups not implemented by #{@connection.http.keys.first}", 501, "NOT IMPLEMENTED") unless api_extensions[:"os-security-groups"] or api_extensions[:security_groups]
  data = JSON.generate(:security_group => { "name" => name, "description" => description})
  response = @connection.req("POST", "/os-security-groups", {:data => data})
  res = OpenStack.symbolize_keys(JSON.parse(response.body))
  {res[:security_group][:id].to_s => res[:security_group]}
end

#create_security_group_rule(security_group_id, params) ⇒ Object

params: { :ip_protocol=>“tcp”, :from_port=>“123”, :to_port=>“123”, :cidr=>“192.168.0.1/16”, :group_id:=“123” } observed behaviour against Openstack@HP cloud - can specify either cidr OR group_id as source, but not both if both specified, the group is used and the cidr ignored.



471
472
473
474
475
476
477
478
# File 'lib/openstack/compute/connection.rb', line 471

def create_security_group_rule(security_group_id, params)
  raise OpenStack::Exception::NotImplemented.new("os-security-groups not implemented by #{@connection.http.keys.first}", 501, "NOT IMPLEMENTED") unless api_extensions[:"os-security-groups"] or api_extensions[:security_groups]
  params.merge!({:parent_group_id=>security_group_id.to_s})
  data = JSON.generate(:security_group_rule => params)
  response = @connection.req("POST", "/os-security-group-rules", {:data => data})
  res = OpenStack.symbolize_keys(JSON.parse(response.body))
  {res[:security_group_rule][:id].to_s => res[:security_group_rule]}
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, :security_groups, :key_name 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    => '3',
     :flavorRef   => '1',
     :metadata    => {'Racker' => 'Fanatical'},
     :personality => {'/home/bob/wedding.jpg' => '/root/wedding.jpg'},
     :key_name    => "mykey",
     :security_groups => [ "devel", "test"])
=> #<OpenStack::Compute::Server:0x101229eb0 ...>
>> server.name
=> "NewServer"
>> server.status
=> "BUILD"
>> server.adminPass
=> "NewServerSHMGpvI"


118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/openstack/compute/connection.rb', line 118

def create_server(options)
  raise OpenStack::Exception::MissingArgument, "Server name, flavorRef, and imageRef, must be supplied" unless (options[:name] && options[:flavorRef] && options[:imageRef])
  if options[:personality]
    options[:personality] = Personalities.get_personality(options[:personality])
  end
  options[:security_groups] = (options[:security_groups] || []).inject([]){|res, c| res << {"name"=>c} ;res}
  data = JSON.generate(:server => options)
  response = @connection.csreq("POST",@connection.service_host,"#{@connection.service_path}/servers",@connection.service_port,@connection.service_scheme,{'content-type' => 'application/json'},data)
  OpenStack::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'] if server_info['adminPass']
  server
end

#delete_flavor(id) ⇒ Object



207
208
209
210
# File 'lib/openstack/compute/connection.rb', line 207

def delete_flavor(id)
  @connection.req('DELETE', "/flavors/#{id}")
  true
end

#delete_flavor_extra_spec(flavor_id, flavor_extra_spec_key) ⇒ Object

Deletes an extra spec, by key, for a flavor, by ID.

delete_flavor_extra_spec(‘999aca87-5c8a-4862-92fe-deb8bb024b6b’, ‘quota:disk_total_iops_sec’)

> true



268
269
270
271
# File 'lib/openstack/compute/connection.rb', line 268

def delete_flavor_extra_spec(flavor_id, flavor_extra_spec_key)
  @connection.req('DELETE', "/flavors/#{flavor_id}/os-extra_specs/#{flavor_extra_spec_key}")
  true
end

#delete_floating_ip(id) ⇒ Object

delete or deallocate a floating IP using its id



537
538
539
540
541
# File 'lib/openstack/compute/connection.rb', line 537

def delete_floating_ip(id)
  check_extension("os-floating-ips")
  @connection.req("DELETE", "/os-floating-ips/#{id}")
  true
end

#delete_floating_ips_bulk(opts = {}) ⇒ Object

Not working Nova does not supported deletion via API

Raises:

  • (ArgumentError)


591
592
593
594
595
596
597
# File 'lib/openstack/compute/connection.rb', line 591

def delete_floating_ips_bulk(opts = {})
  raise ArgumentError, 'Should not be empty' if opts.empty?
  data = JSON.generate(opts)
  check_extension 'os-floating-ips-bulk'
  response = @connection.req('POST', '/os-floating-ips-bulk/delete', {:data => data})
  JSON.generate(response)
end

#delete_keypair(keypair_name) ⇒ Object

Delete an existing keypair. Raises OpenStack::Exception::NotImplemented if os-keypairs extension is not implemented (or not advertised) by the OpenStack provider.

Returns true if succesful. >> os.delete_keypair(“marios_keypair”)

> true

Will raise OpenStack::Exception::ItemNotFound if specified keypair doesn’t exist



410
411
412
413
414
# File 'lib/openstack/compute/connection.rb', line 410

def delete_keypair(keypair_name)
  raise OpenStack::Exception::NotImplemented.new("os-keypairs not implemented by #{@connection.http.keys.first}", 501, "NOT IMPLEMENTED") unless api_extensions[:"os-keypairs"]
  @connection.req("DELETE", "/os-keypairs/#{keypair_name}")
  true
end

#delete_security_group(id) ⇒ Object



462
463
464
465
466
# File 'lib/openstack/compute/connection.rb', line 462

def delete_security_group(id)
  raise OpenStack::Exception::NotImplemented.new("os-security-groups not implemented by #{@connection.http.keys.first}", 501, "NOT IMPLEMENTED") unless api_extensions[:"os-security-groups"] or api_extensions[:security_groups]
  @connection.req("DELETE", "/os-security-groups/#{id}")
  true
end

#delete_security_group_rule(id) ⇒ Object



480
481
482
483
484
# File 'lib/openstack/compute/connection.rb', line 480

def delete_security_group_rule(id)
  raise OpenStack::Exception::NotImplemented.new("os-security-groups not implemented by #{@connection.http.keys.first}", 501, "NOT IMPLEMENTED") unless api_extensions[:"os-security-groups"] or api_extensions[:security_groups]
  @connection.req("DELETE", "/os-security-group-rules/#{id}")
  true
end

#delete_tenant_from_flavor(flavor_id, tenant_id) ⇒ Object



218
219
220
221
222
# File 'lib/openstack/compute/connection.rb', line 218

def delete_tenant_from_flavor(flavor_id, tenant_id)
  data = JSON.generate({'removeTenantAccess' => {'tenant' => tenant_id}})
  response = @connection.req('POST', "/flavors/#{flavor_id}/action", {data: data})
  JSON.parse(response.body)
end

#detach_floating_ip(opts = {:server_id=>"", :ip_id => ""}) ⇒ Object



553
554
555
556
557
558
559
560
# File 'lib/openstack/compute/connection.rb', line 553

def detach_floating_ip(opts={:server_id=>"", :ip_id => ""})
  check_extension("os-floating-ips")
  #first get the address:
  addr = get_floating_ip(opts[:ip_id]).ip
  data = JSON.generate({:removeFloatingIp=>{:address=>addr}})
  @connection.req("POST", "/servers/#{opts[:server_id]}/action", {:data=>data})
  true
end

#detach_volume(server_id, attachment_id) ⇒ Object



500
501
502
503
504
# File 'lib/openstack/compute/connection.rb', line 500

def detach_volume(server_id, attachment_id)
  raise OpenStack::Exception::NotImplemented.new("os-volumes not implemented by #{@connection.http.keys.first}", 501, "NOT IMPLEMENTED") unless api_extensions[:"os-volumes"]
  @connection.req("DELETE", "/servers/#{server_id}/os-volume_attachments/#{attachment_id}")
  true
end

#flavor_extra_spec(flavor_id, flavor_extra_spec_key) ⇒ Object

Shows an extra spec, by key, for a flavor, by ID.

flavor_extra_spec(‘999aca87-5c8a-4862-92fe-deb8bb024b6b’, ‘quota:disk_total_iops_sec’)

> { ‘quota:disk_total_iops_sec’ => 1000 }



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

def flavor_extra_spec(flavor_id, flavor_extra_spec_key)
  response = @connection.req('GET', "/flavors/#{flavor_id}/os-extra_specs/#{flavor_extra_spec_key}")
  JSON.parse(response.body)
end

#flavor_extra_specs(flavor_id) ⇒ Object

Lists all extra specs for a flavor, by ID.

flavor_extra_specs(‘999aca87-5c8a-4862-92fe-deb8bb024b6b’)

> { ‘quota:disk_total_iops_sec’ => 1000 }



240
241
242
243
# File 'lib/openstack/compute/connection.rb', line 240

def flavor_extra_specs(flavor_id)
  response = @connection.req('GET', "/flavors/#{flavor_id}/os-extra_specs")
  JSON.parse(response.body)['extra_specs']
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>


189
190
191
192
193
# File 'lib/openstack/compute/connection.rb', line 189

def get_flavor(id)
  response = @connection.req('GET', "/flavors/#{id}")
  flavor_info = JSON.parse(response.body)['flavor']
  OpenStack::Compute::Flavor.new(flavor_info)
end

#get_floating_ip(id) ⇒ Object Also known as: floating_ip

get details of a specific floating_ip by its id



518
519
520
521
522
523
# File 'lib/openstack/compute/connection.rb', line 518

def get_floating_ip(id)
  check_extension("os-floating-ips")
  response = @connection.req("GET", "/os-floating-ips/#{id}")
  res = JSON.parse(response.body)["floating_ip"]
  OpenStack::Compute::FloatingIPAddress.new(res)
end

#get_floating_ip_pollsObject

deprecated - please do not use this typo method :)



569
570
571
572
# File 'lib/openstack/compute/connection.rb', line 569

def get_floating_ip_polls
  puts "get_floating_ip_polls() is DEPRECATED: Please use get_floating_ip_pools() without typo!"
  self.get_floating_ip_pools
end

#get_floating_ip_poolsObject



562
563
564
565
566
# File 'lib/openstack/compute/connection.rb', line 562

def get_floating_ip_pools
  check_extension 'os-floating-ip-pools'
  response = @connection.req('GET', '/os-floating-ip-pools')
  JSON.parse(response.body)['floating_ip_pools']
end

#get_floating_ipsObject Also known as: floating_ips

FLOATING IPs: list all float ips associated with tennant or account



509
510
511
512
513
514
# File 'lib/openstack/compute/connection.rb', line 509

def get_floating_ips
  check_extension("os-floating-ips")
  response = @connection.req("GET", "/os-floating-ips")
  res = JSON.parse(response.body)["floating_ips"]
  res.inject([]){|result, c| result<< OpenStack::Compute::FloatingIPAddress.new(c) ; result }
end

#get_floating_ips_bulkObject



574
575
576
577
578
579
# File 'lib/openstack/compute/connection.rb', line 574

def get_floating_ips_bulk
  check_extension 'os-floating-ips-bulk'
  response = @connection.req('GET', '/os-floating-ips-bulk')
  res = JSON.parse(response.body)['floating_ip_info']
  res.inject([]){|result, c| result << OpenStack::Compute::FloatingIPInfo.new(c); result}
end

#get_hypervisor_statsObject

Shows summary statistics for all hypervisors over all compute nodes



600
601
602
603
604
# File 'lib/openstack/compute/connection.rb', line 600

def get_hypervisor_stats
  response = @connection.req('GET', '/os-hypervisors/statistics')
  OpenStack::Exception.raise_exception(response) unless response.code.match(/^20.$/)
  JSON.parse(response.body)['hypervisor_statistics']
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 ...>


159
160
161
# File 'lib/openstack/compute/connection.rb', line 159

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"


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

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

#keypairsObject

Retrieve a list of key pairs associated with the current authenticated account Will return a hash:

{ :key_one => {  :fingerprint  =>  "3f:12:4d:d1:54:f1:f4:3f:fe:a8:12:ec:1a:fb:35:b2",
                 :public_key   =>  "ssh-rsa AAAAB3Nza923kJU123AADAQABAAAAg928JUwydszi029kIJudfOzQ7o160Ll1ItybDzYYcCAJ/N02loIKJU17264520bmXZFSsaZf2ErX3nSBNI3K+2zQzu832jkhkfdsa7GHH5hvNOxO7u800894312JKLJLHP/R91fdsajHKKJADSAgQ== nova@nv-zz2232-api0002\n",
                 :name         =>  "key_one"},

  :key_two =>  { :fingerprint  =>  "6b:32:dd:d2:51:c1:f2:3a:fb:a2:52:3a:1a:bb:25:1b",
                 :public_key   =>  "ssh-rsa AKIJUuw71645kJU123AADAQABAAAAg928019oiUJY12765IJudfOzQ7o160Ll1ItybDzYYcCAJ/N80438012480321jhkhKJlfdsazu832jkhkfdsa7GHH5fdasfdsajlj2999789799987989894312JKLJLHP/R91fdsajHKKJADSAgQ== nova@bv-fdsa32-api0002\n",
                 :name         =>  "key_two"}
}

Raises OpenStack::Exception::NotImplemented if the current provider doesn’t offer the os-keypairs extension



351
352
353
354
355
356
357
358
359
360
361
# File 'lib/openstack/compute/connection.rb', line 351

def keypairs
  begin
    response = @connection.req("GET", "/os-keypairs")
    res = OpenStack.symbolize_keys(JSON.parse(response.body))
    res[:keypairs].inject({}){|result, c| result[c[:keypair][:name].to_sym] = c[:keypair] ; result }
  rescue OpenStack::Exception::ItemNotFound => not_found
    msg = "The os-keypairs extension is not implemented for the provider you are talking to "+
          "- #{@connection.http.keys.first}"
    raise OpenStack::Exception::NotImplemented.new(msg, 501, "#{not_found.message}")
  end
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.



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

def limits
  response = @connection.csreq("GET",@connection.service_host,"#{@connection.service_path}/limits",@connection.service_port,@connection.service_scheme)
  OpenStack::Exception.raise_exception(response) unless response.code.match(/^20.$/)
  OpenStack.symbolize_keys(JSON.parse(response.body)['limits'])
end

#list_attachments(server_id) ⇒ Object



494
495
496
497
498
# File 'lib/openstack/compute/connection.rb', line 494

def list_attachments(server_id)
  raise OpenStack::Exception::NotImplemented.new("os-volumes not implemented by #{@connection.http.keys.first}", 501, "NOT IMPLEMENTED") unless api_extensions[:"os-volumes"]
  response = @connection.req("GET", "/servers/#{server_id}/os-volume_attachments")
  OpenStack.symbolize_keys(JSON.parse(response.body))
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. developer.openstack.org/api-ref-compute-v2.1.html

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


177
178
179
180
181
182
# File 'lib/openstack/compute/connection.rb', line 177

def list_flavors(options = {})
  path = options.empty? ? "#{@connection.service_path}/flavors/detail" : "#{@connection.service_path}/flavors/detail?#{options.to_query}"
  response = @connection.csreq("GET",@connection.service_host,path,@connection.service_port,@connection.service_scheme)
  OpenStack::Exception.raise_exception(response) unless response.code.match(/^20.$/)
  OpenStack.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 and :“changes-since” and :server and :name and :status :minDisk and :minRam and :type and :limit and :marker 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")
=> [{: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}]


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

def list_images(options = {})
  path = options.empty? ? "#{@connection.service_path}/images/detail" : "#{@connection.service_path}/images/detail?#{options.to_query}"
  response = @connection.csreq("GET",@connection.service_host,path,@connection.service_port,@connection.service_scheme)
  OpenStack::Exception.raise_exception(response) unless response.code.match(/^20.$/)
  OpenStack.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 and :“changes-since” and :image and :flavor and :name and :status and :host and :limit and :marker parameters to handle pagination. developer.openstack.org/api-ref-compute-v2.1.html

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

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


46
47
48
49
50
51
52
# File 'lib/openstack/compute/connection.rb', line 46

def list_servers(options = {})
  anti_cache_param="cacheid=#{Time.now.to_i}"
  path = options.empty? ? "#{@connection.service_path}/servers?#{anti_cache_param}" : "#{@connection.service_path}/servers?#{options.to_query}&#{anti_cache_param}"
  response = @connection.csreq("GET",@connection.service_host,path,@connection.service_port,@connection.service_scheme)
  OpenStack::Exception.raise_exception(response) unless response.code.match(/^20.$/)
  OpenStack.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 and :“changes-since” and :image and :flavor and :name and :status and :host and :limit and :marker parameters to handle pagination. developer.openstack.org/api-ref-compute-v2.1.html

>> 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, :name => "MyServer", :flavor => 1, :status => "ACTIVE")
=> [{: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"}]


68
69
70
71
72
73
74
75
76
77
# File 'lib/openstack/compute/connection.rb', line 68

def list_servers_detail(options = {})
  path = options.empty? ? "#{@connection.service_path}/servers/detail" : "#{@connection.service_path}/servers/detail?#{options.to_query}"
  response = @connection.csreq("GET",@connection.service_host,path,@connection.service_port,@connection.service_scheme)
  OpenStack::Exception.raise_exception(response) unless response.code.match(/^20.$/)
  json_server_list = JSON.parse(response.body)["servers"]
  json_server_list.each do |server|
    server["addresses"] = OpenStack::Compute::Address.fix_labels(server["addresses"])
  end
  OpenStack.symbolize_keys(json_server_list)
end

#security_group(id) ⇒ Object



439
440
441
442
443
444
# File 'lib/openstack/compute/connection.rb', line 439

def security_group(id)
  raise OpenStack::Exception::NotImplemented.new("os-security-groups not implemented by #{@connection.http.keys.first}", 501, "NOT IMPLEMENTED") unless api_extensions[:"os-security-groups"] or api_extensions[:security_groups]
  response = @connection.req("GET", "/os-security-groups/#{id}")
  res = OpenStack.symbolize_keys(JSON.parse(response.body))
  {res[:security_group][:id].to_s => res[:security_group]}
end

#security_groupsObject

Security Groups: Returns a hash with the security group IDs as keys:

> { “1381” => { :tenant_id=>“12345678909876”, :id=>1381, :name=>“default”, :description=>“default”,

            :rules=> [
                      {:from_port=>22, :group=>{}, :ip_protocol=>"tcp", :to_port=>22,
                       :parent_group_id=>1381, :ip_range=>{:cidr=>"0.0.0.0/0"}, :id=>4902},
                      {:from_port=>80, :group=>{}, :ip_protocol=>"tcp", :to_port=>80,
                       :parent_group_id=>1381, :ip_range=>{:cidr=>"0.0.0.0/0"}, :id=>4903},
                      {:from_port=>443, :group=>{}, :ip_protocol=>"tcp", :to_port=>443,
                       :parent_group_id=>1381, :ip_range=>{:cidr=>"0.0.0.0/0"}, :id=>4904},
                      {:from_port=>-1, :group=>{}, :ip_protocol=>"icmp", :to_port=>-1,
                       :parent_group_id=>1381, :ip_range=>{:cidr=>"0.0.0.0/0"}, :id=>4905}],
                     ]
          },
"1234" => { ... } }


432
433
434
435
436
437
# File 'lib/openstack/compute/connection.rb', line 432

def security_groups
  raise OpenStack::Exception::NotImplemented.new("os-security-groups not implemented by #{@connection.http.keys.first}", 501, "NOT IMPLEMENTED") unless api_extensions[:"os-security-groups"] or api_extensions[:security_groups]
  response = @connection.req("GET", "/os-security-groups")
  res = OpenStack.symbolize_keys(JSON.parse(response.body))
  res[:security_groups].inject({}){|result, c| result[c[:id].to_s] = c ; result }
end

#update_flavor_extra_spec(flavor_id, flavor_extra_spec_key, new_value) ⇒ Object

Updates an extra spec, by key, for a flavor, by ID.

update_flavor_extra_spec(‘999aca87-5c8a-4862-92fe-deb8bb024b6b’, ‘quota:disk_total_iops_sec’, 2000)

> { ‘quota:disk_total_iops_sec’ => 2000 }



258
259
260
261
262
# File 'lib/openstack/compute/connection.rb', line 258

def update_flavor_extra_spec(flavor_id, flavor_extra_spec_key, new_value)
  data = JSON.generate(flavor_extra_spec_key => new_value)
  response = @connection.req('PUT', "/flavors/#{flavor_id}/os-extra_specs/#{flavor_extra_spec_key}", data: data)
  JSON.parse(response.body)
end

#update_security_group(id, name, description) ⇒ Object



454
455
456
457
458
459
460
# File 'lib/openstack/compute/connection.rb', line 454

def update_security_group(id, name, description)
  raise OpenStack::Exception::NotImplemented.new("os-security-groups not implemented by #{@connection.http.keys.first}", 501, "NOT IMPLEMENTED") unless api_extensions[:"os-security-groups"] or api_extensions[:security_groups]
  data = JSON.generate(:security_group => { "name" => name, "description" => description})
  response = @connection.req("PUT", "/os-security-groups/#{id}", {:data => data})
  res = OpenStack.symbolize_keys(JSON.parse(response.body))
  {res[:security_group][:id].to_s => res[:security_group]}
end