openstack-compute 1.1.0.pre0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +5 -3
- data/VERSION +1 -1
- data/lib/openstack/compute.rb +1 -1
- data/lib/openstack/compute/authentication.rb +70 -15
- data/lib/openstack/compute/connection.rb +28 -23
- data/lib/openstack/compute/image.rb +6 -2
- data/lib/openstack/compute/server.rb +8 -28
- metadata +8 -11
data/README.rdoc
CHANGED
@@ -2,7 +2,9 @@
|
|
2
2
|
|
3
3
|
== Description
|
4
4
|
|
5
|
-
Ruby Openstack Compute binding.
|
5
|
+
Ruby Openstack Compute binding for the v1.0 OSAPI.
|
6
|
+
|
7
|
+
Currently supports both v1.0 and v2.0 (keystone) auth.
|
6
8
|
|
7
9
|
== Examples
|
8
10
|
|
@@ -10,7 +12,7 @@ See the class definitions for documentation on specific methods and operations.
|
|
10
12
|
|
11
13
|
require 'openstack/compute'
|
12
14
|
|
13
|
-
cs = OpenStack::Compute::Connection.new(:username => USERNAME, :api_key => API_KEY, :
|
15
|
+
cs = OpenStack::Compute::Connection.new(:username => USERNAME, :api_key => API_KEY, :auth_url => API_URL)
|
14
16
|
|
15
17
|
# Get a listing of all current servers
|
16
18
|
>> cs.servers
|
@@ -44,7 +46,7 @@ See the class definitions for documentation on specific methods and operations.
|
|
44
46
|
=> #<OpenStack::Compute::Flavor:0x101469130 @disk=20, @name="512 server", @id=2, @ram=512>
|
45
47
|
>> flavor.name
|
46
48
|
=> "512 server"
|
47
|
-
>> newserver = cs.create_server(:name => "New Server", :
|
49
|
+
>> newserver = cs.create_server(:name => "New Server", :imageRef => image.id, :flavorRef => flavor.id)
|
48
50
|
=> #<OpenStack::Compute::Server:0x101433f08 ....
|
49
51
|
>> newserver.status
|
50
52
|
=> "BUILD"
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.1.0
|
1
|
+
1.1.0
|
data/lib/openstack/compute.rb
CHANGED
@@ -9,7 +9,7 @@
|
|
9
9
|
# To begin reviewing the available methods and examples, view the README.rdoc file, or begin by looking at documentation for the OpenStack::Compute::Connection class.
|
10
10
|
#
|
11
11
|
# Example:
|
12
|
-
# OpenStack::Compute::Connection.new(:username => USERNAME, :api_key => API_KEY, :
|
12
|
+
# OpenStack::Compute::Connection.new(:username => USERNAME, :api_key => API_KEY, :auth_url => API_URL) method.
|
13
13
|
module OpenStack
|
14
14
|
module Compute
|
15
15
|
|
@@ -1,19 +1,70 @@
|
|
1
1
|
module OpenStack
|
2
2
|
module Compute
|
3
|
+
|
3
4
|
class Authentication
|
5
|
+
|
6
|
+
# Performs an authentication to the OpenStack auth server.
|
7
|
+
# If it succeeds, it sets the svrmgmthost, svrmgtpath, svrmgmtport,
|
8
|
+
# svrmgmtscheme, authtoken, and authok variables on the connection.
|
9
|
+
# If it fails, it raises an exception.
|
10
|
+
def self.init(conn)
|
11
|
+
if conn.auth_path =~ /.*v2.0\/?$/
|
12
|
+
AuthV20.new(conn)
|
13
|
+
else
|
14
|
+
AuthV10.new(conn)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
class AuthV20
|
22
|
+
|
23
|
+
def initialize(connection)
|
24
|
+
begin
|
25
|
+
server = Net::HTTP::Proxy(connection.proxy_host, connection.proxy_port).new(connection.auth_host, connection.auth_port)
|
26
|
+
if connection.auth_scheme == "https"
|
27
|
+
server.use_ssl = true
|
28
|
+
server.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
29
|
+
end
|
30
|
+
server.start
|
31
|
+
rescue
|
32
|
+
raise OpenStack::Compute::Exception::Connection, "Unable to connect to #{server}"
|
33
|
+
end
|
34
|
+
|
35
|
+
auth_data = JSON.generate({ "passwordCredentials" => { "username" => connection.authuser, "password" => connection.authkey }})
|
36
|
+
response = server.post(connection.auth_path.chomp("/")+"/tokens", auth_data, {'Content-Type' => 'application/json'})
|
37
|
+
if (response.code =~ /^20./)
|
38
|
+
resp_data=JSON.parse(response.body)
|
39
|
+
connection.authtoken = resp_data['auth']['token']['id']
|
40
|
+
if resp_data['auth']['serviceCatalog'] and resp_data['auth']['serviceCatalog'][connection.service_name] and resp_data['auth']['serviceCatalog'][connection.service_name][0] then
|
41
|
+
uri = URI.parse(resp_data['auth']['serviceCatalog'][connection.service_name][0]['publicURL'])
|
42
|
+
connection.svrmgmthost = uri.host
|
43
|
+
connection.svrmgmtpath = uri.path
|
44
|
+
# Force the path into the v1.1 URL space
|
45
|
+
connection.svrmgmtpath.sub!(/\/.*\/?/, '/v1.1/')
|
46
|
+
connection.svrmgmtpath += connection.authtenant
|
47
|
+
connection.svrmgmtport = uri.port
|
48
|
+
connection.svrmgmtscheme = uri.scheme
|
49
|
+
connection.authok = true
|
50
|
+
else
|
51
|
+
connection.authok = false
|
52
|
+
end
|
53
|
+
else
|
54
|
+
connection.authtoken = false
|
55
|
+
raise OpenStack::Compute::Exception::Authentication, "Authentication failed with response code #{response.code}"
|
56
|
+
end
|
57
|
+
server.finish
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class AuthV10
|
4
62
|
|
5
|
-
# Performs an authentication to the OpenStack authorization servers. Opens a new HTTP connection to the API server,
|
6
|
-
# sends the credentials, and looks for a successful authentication. If it succeeds, it sets the svrmgmthost,
|
7
|
-
# svrmgtpath, svrmgmtport, svrmgmtscheme, authtoken, and authok variables on the connection. If it fails, it raises
|
8
|
-
# an exception.
|
9
|
-
#
|
10
|
-
# Should probably never be called directly.
|
11
63
|
def initialize(connection)
|
12
|
-
path = connection.api_path
|
13
64
|
hdrhash = { "X-Auth-User" => connection.authuser, "X-Auth-Key" => connection.authkey }
|
14
65
|
begin
|
15
|
-
server = Net::HTTP::Proxy(connection.proxy_host, connection.proxy_port).new(connection.
|
16
|
-
if connection.
|
66
|
+
server = Net::HTTP::Proxy(connection.proxy_host, connection.proxy_port).new(connection.auth_host, connection.auth_port)
|
67
|
+
if connection.auth_scheme == "https"
|
17
68
|
server.use_ssl = true
|
18
69
|
server.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
19
70
|
end
|
@@ -21,14 +72,17 @@ module Compute
|
|
21
72
|
rescue
|
22
73
|
raise OpenStack::Compute::Exception::Connection, "Unable to connect to #{server}"
|
23
74
|
end
|
24
|
-
response = server.get(
|
75
|
+
response = server.get(connection.auth_path, hdrhash)
|
25
76
|
if (response.code =~ /^20./)
|
26
77
|
connection.authtoken = response["x-auth-token"]
|
27
|
-
|
28
|
-
connection.
|
29
|
-
|
30
|
-
|
31
|
-
connection.
|
78
|
+
uri = URI.parse(response["x-server-management-url"])
|
79
|
+
connection.svrmgmthost = uri.host
|
80
|
+
connection.svrmgmtpath = uri.path
|
81
|
+
# Force the path into the v1.1 URL space
|
82
|
+
connection.svrmgmtpath.sub!(/\/.*\/?/, '/v1.1/')
|
83
|
+
connection.svrmgmtpath += connection.authtenant
|
84
|
+
connection.svrmgmtport = uri.port
|
85
|
+
connection.svrmgmtscheme = uri.scheme
|
32
86
|
connection.authok = true
|
33
87
|
else
|
34
88
|
connection.authtoken = false
|
@@ -37,5 +91,6 @@ module Compute
|
|
37
91
|
server.finish
|
38
92
|
end
|
39
93
|
end
|
94
|
+
|
40
95
|
end
|
41
96
|
end
|
@@ -3,6 +3,7 @@ module Compute
|
|
3
3
|
class Connection
|
4
4
|
|
5
5
|
attr_reader :authuser
|
6
|
+
attr_reader :authtenant
|
6
7
|
attr_reader :authkey
|
7
8
|
attr_accessor :authtoken
|
8
9
|
attr_accessor :authok
|
@@ -10,10 +11,11 @@ module Compute
|
|
10
11
|
attr_accessor :svrmgmtpath
|
11
12
|
attr_accessor :svrmgmtport
|
12
13
|
attr_accessor :svrmgmtscheme
|
13
|
-
attr_reader :
|
14
|
-
attr_reader :
|
15
|
-
attr_reader :
|
16
|
-
attr_reader :
|
14
|
+
attr_reader :auth_host
|
15
|
+
attr_reader :auth_port
|
16
|
+
attr_reader :auth_scheme
|
17
|
+
attr_reader :auth_path
|
18
|
+
attr_accessor :service_name
|
17
19
|
attr_reader :proxy_host
|
18
20
|
attr_reader :proxy_port
|
19
21
|
|
@@ -22,37 +24,40 @@ module Compute
|
|
22
24
|
# The constructor takes a hash of options, including:
|
23
25
|
#
|
24
26
|
# :username - Your Openstack username *required*
|
27
|
+
# :tenant - Your Openstack tenant *required*. Defaults to username.
|
25
28
|
# :api_key - Your Openstack API key *required*
|
26
|
-
# :
|
29
|
+
# :auth_url - Configurable auth_url endpoint.
|
30
|
+
# :service_name - (Optional for v2.0 auth only). The name of the compute service to use. Defaults to 'nova'.
|
27
31
|
# :retry_auth - Whether to retry if your auth token expires (defaults to true)
|
28
32
|
# :proxy_host - If you need to connect through a proxy, supply the hostname here
|
29
33
|
# :proxy_port - If you need to connect through a proxy, supply the port here
|
30
34
|
#
|
31
|
-
#
|
35
|
+
# cs = OpenStack::Compute::Connection.new(:username => 'USERNAME', :api_key => 'API_KEY', :auth_url => 'AUTH_URL')
|
32
36
|
def initialize(options = {:retry_auth => true})
|
33
37
|
@authuser = options[:username] || (raise Exception::MissingArgument, "Must supply a :username")
|
34
38
|
@authkey = options[:api_key] || (raise Exception::MissingArgument, "Must supply an :api_key")
|
35
|
-
@
|
39
|
+
@auth_url = options[:auth_url] || (raise Exception::MissingArgument, "Must supply an :auth_url")
|
40
|
+
@authtenant = options[:authtenant] || @authuser
|
41
|
+
@service_name = options[:service_name] || "nova"
|
36
42
|
@is_debug = options[:is_debug]
|
37
43
|
|
38
|
-
|
44
|
+
auth_uri=nil
|
39
45
|
begin
|
40
|
-
|
46
|
+
auth_uri=URI.parse(@auth_url)
|
41
47
|
rescue Exception => e
|
42
|
-
raise Exception::InvalidArgument, "Invalid :
|
48
|
+
raise Exception::InvalidArgument, "Invalid :auth_url parameter: #{e.message}"
|
43
49
|
end
|
44
|
-
raise Exception::InvalidArgument, "Invalid :
|
45
|
-
@
|
46
|
-
@
|
47
|
-
@
|
48
|
-
@
|
49
|
-
|
50
|
+
raise Exception::InvalidArgument, "Invalid :auth_url parameter." if auth_uri.nil? or auth_uri.host.nil?
|
51
|
+
@auth_host = auth_uri.host
|
52
|
+
@auth_port = auth_uri.port
|
53
|
+
@auth_scheme = auth_uri.scheme
|
54
|
+
@auth_path = auth_uri.path
|
50
55
|
@retry_auth = options[:retry_auth]
|
51
56
|
@proxy_host = options[:proxy_host]
|
52
57
|
@proxy_port = options[:proxy_port]
|
53
58
|
@authok = false
|
54
59
|
@http = {}
|
55
|
-
OpenStack::Compute::Authentication.
|
60
|
+
OpenStack::Compute::Authentication.init(self)
|
56
61
|
end
|
57
62
|
|
58
63
|
# Returns true if the authentication was successful and returns false otherwise.
|
@@ -88,7 +93,7 @@ module Compute
|
|
88
93
|
retry
|
89
94
|
rescue OpenStack::Compute::Exception::ExpiredAuthToken
|
90
95
|
raise OpenStack::Compute::Exception::Connection, "Authentication token expired and you have requested not to retry" if @retry_auth == false
|
91
|
-
OpenStack::Compute::Authentication.
|
96
|
+
OpenStack::Compute::Authentication.init(self)
|
92
97
|
retry
|
93
98
|
end
|
94
99
|
|
@@ -145,11 +150,11 @@ module Compute
|
|
145
150
|
#
|
146
151
|
# You can also provide :limit and :offset parameters to handle pagination.
|
147
152
|
# >> cs.list_servers_detail
|
148
|
-
# => [{:name=>"MyServer", :addresses=>{:public=>["67.23.42.37"], :private=>["10.176.241.237"]}, :metadata=>{"MyData" => "Valid"}, :
|
153
|
+
# => [{: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"}]
|
149
154
|
#
|
150
155
|
# >> cs.list_servers_detail(:limit => 2, :offset => 3)
|
151
|
-
# => [{:status=>"ACTIVE", :
|
152
|
-
# {:status=>"ACTIVE", :
|
156
|
+
# => [{: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"},
|
157
|
+
# {: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"}]
|
153
158
|
def list_servers_detail(options = {})
|
154
159
|
path = OpenStack::Compute.paginate(options).empty? ? "#{svrmgmtpath}/servers/detail" : "#{svrmgmtpath}/servers/detail?#{OpenStack::Compute.paginate(options)}"
|
155
160
|
response = csreq("GET",svrmgmthost,path,svrmgmtport,svrmgmtscheme)
|
@@ -206,7 +211,7 @@ module Compute
|
|
206
211
|
end
|
207
212
|
|
208
213
|
# Returns an array of hashes listing available server images that you have access too, including stock OpenStack Compute images and
|
209
|
-
# any that you have created. The "id" key in the hash can be used where
|
214
|
+
# any that you have created. The "id" key in the hash can be used where imageRef is required.
|
210
215
|
#
|
211
216
|
# You can also provide :limit and :offset parameters to handle pagination.
|
212
217
|
#
|
@@ -235,7 +240,7 @@ module Compute
|
|
235
240
|
end
|
236
241
|
alias :image :get_image
|
237
242
|
|
238
|
-
# Returns an array of hashes listing all available server flavors. The :id key in the hash can be used when
|
243
|
+
# Returns an array of hashes listing all available server flavors. The :id key in the hash can be used when flavorRef is required.
|
239
244
|
#
|
240
245
|
# You can also provide :limit and :offset parameters to handle pagination.
|
241
246
|
#
|
@@ -6,10 +6,12 @@ module Compute
|
|
6
6
|
|
7
7
|
attr_reader :id
|
8
8
|
attr_reader :name
|
9
|
-
attr_reader :
|
9
|
+
attr_reader :server
|
10
10
|
attr_reader :updated
|
11
11
|
attr_reader :created
|
12
12
|
attr_reader :status
|
13
|
+
attr_reader :minDisk
|
14
|
+
attr_reader :minRam
|
13
15
|
attr_reader :progress
|
14
16
|
attr_reader :metadata
|
15
17
|
|
@@ -41,12 +43,14 @@ module Compute
|
|
41
43
|
data = JSON.parse(response.body)['image']
|
42
44
|
@id = data['id']
|
43
45
|
@name = data['name']
|
44
|
-
@
|
46
|
+
@server = data['server']
|
45
47
|
if data['updated'] then
|
46
48
|
@updated = DateTime.parse(data['updated'])
|
47
49
|
end
|
48
50
|
@created = DateTime.parse(data['created'])
|
49
51
|
@status = data['status']
|
52
|
+
@minDisk = data['minDisk']
|
53
|
+
@minRam = data['minRam']
|
50
54
|
@progress = data['progress']
|
51
55
|
return true
|
52
56
|
end
|
@@ -10,8 +10,8 @@ module Compute
|
|
10
10
|
attr_reader :progress
|
11
11
|
attr_reader :addresses
|
12
12
|
attr_reader :hostId
|
13
|
-
attr_reader :
|
14
|
-
attr_reader :
|
13
|
+
attr_reader :image
|
14
|
+
attr_reader :flavor
|
15
15
|
attr_reader :metadata
|
16
16
|
attr_accessor :adminPass
|
17
17
|
|
@@ -54,32 +54,12 @@ module Compute
|
|
54
54
|
@addresses = OpenStack::Compute.symbolize_keys(data["addresses"])
|
55
55
|
@metadata = OpenStack::Compute::ServerMetadata.new(@connection, @id)
|
56
56
|
@hostId = data["hostId"]
|
57
|
-
@
|
58
|
-
@
|
57
|
+
@image = data["image"]
|
58
|
+
@flavor = data["flavor"]
|
59
59
|
true
|
60
60
|
end
|
61
61
|
alias :refresh :populate
|
62
62
|
|
63
|
-
# Returns a new OpenStack::Compute::Flavor object for the flavor assigned to this server.
|
64
|
-
#
|
65
|
-
# >> flavor = server.flavor
|
66
|
-
# => #<OpenStack::Compute::Flavor:0x1014aac20 @name="256 server", @disk=10, @id=1, @ram=256>
|
67
|
-
# >> flavor.name
|
68
|
-
# => "256 server"
|
69
|
-
def flavor
|
70
|
-
OpenStack::Compute::Flavor.new(@connection, self.flavorId)
|
71
|
-
end
|
72
|
-
|
73
|
-
# Returns a new OpenStack::Compute::Image object for the image assigned to this server.
|
74
|
-
#
|
75
|
-
# >> image = server.image
|
76
|
-
# => #<OpenStack::Compute::Image:0x10149a960 ...>
|
77
|
-
# >> image.name
|
78
|
-
# => "Ubuntu 8.04.2 LTS (hardy)"
|
79
|
-
def image
|
80
|
-
OpenStack::Compute::Image.new(@connection, self.imageId)
|
81
|
-
end
|
82
|
-
|
83
63
|
# Sends an API request to reboot this server. Takes an optional argument for the type of reboot, which can be "SOFT" (graceful shutdown)
|
84
64
|
# or "HARD" (power cycle). The hard reboot is also triggered by server.reboot!, so that may be a better way to call it.
|
85
65
|
#
|
@@ -144,7 +124,7 @@ module Compute
|
|
144
124
|
#
|
145
125
|
# This method expects a hash of the form:
|
146
126
|
# {
|
147
|
-
# :
|
127
|
+
# :imageRef => "https://foo.com/v1.1/images/2",
|
148
128
|
# :name => "newName",
|
149
129
|
# :metadata => { :values => { :foo : "bar" } },
|
150
130
|
# :personality => [
|
@@ -187,15 +167,15 @@ module Compute
|
|
187
167
|
OpenStack::Compute::Image.new(@connection,JSON.parse(response.body)['image']['id'])
|
188
168
|
end
|
189
169
|
|
190
|
-
# Resizes the server to the size contained in the server flavor found at ID
|
170
|
+
# Resizes the server to the size contained in the server flavor found at ID flavorRef. The server name, ID number, and IP addresses
|
191
171
|
# will remain the same. After the resize is done, the server.status will be set to "VERIFY_RESIZE" until the resize is confirmed or reverted.
|
192
172
|
#
|
193
173
|
# Refreshes the OpenStack::Compute::Server object, and returns true if the API call succeeds.
|
194
174
|
#
|
195
175
|
# >> server.resize!(1)
|
196
176
|
# => true
|
197
|
-
def resize!(
|
198
|
-
data = JSON.generate(:resize => {:
|
177
|
+
def resize!(flavorRef)
|
178
|
+
data = JSON.generate(:resize => {:flavorRef => flavorRef})
|
199
179
|
response = @connection.csreq("POST",@svrmgmthost,"#{@svrmgmtpath}/servers/#{URI.encode(self.id.to_s)}/action",@svrmgmtport,@svrmgmtscheme,{'content-type' => 'application/json'},data)
|
200
180
|
OpenStack::Compute::Exception.raise_exception(response) unless response.code.match(/^20.$/)
|
201
181
|
self.populate
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: openstack-compute
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 19
|
5
|
+
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 1
|
9
9
|
- 0
|
10
|
-
|
11
|
-
version: 1.1.0.pre0
|
10
|
+
version: 1.1.0
|
12
11
|
platform: ruby
|
13
12
|
authors:
|
14
13
|
- Dan Prince
|
@@ -16,7 +15,7 @@ autorequire:
|
|
16
15
|
bindir: bin
|
17
16
|
cert_chain: []
|
18
17
|
|
19
|
-
date: 2011-10-
|
18
|
+
date: 2011-10-14 00:00:00 -04:00
|
20
19
|
default_executable:
|
21
20
|
dependencies:
|
22
21
|
- !ruby/object:Gem::Dependency
|
@@ -74,14 +73,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
74
73
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
74
|
none: false
|
76
75
|
requirements:
|
77
|
-
- - "
|
76
|
+
- - ">="
|
78
77
|
- !ruby/object:Gem::Version
|
79
|
-
hash:
|
78
|
+
hash: 3
|
80
79
|
segments:
|
81
|
-
-
|
82
|
-
|
83
|
-
- 1
|
84
|
-
version: 1.3.1
|
80
|
+
- 0
|
81
|
+
version: "0"
|
85
82
|
requirements: []
|
86
83
|
|
87
84
|
rubyforge_project:
|