openstack 1.0.6 → 1.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +51 -2
- data/VERSION +1 -1
- data/lib/openstack.rb +4 -0
- data/lib/openstack/compute/connection.rb +20 -0
- data/lib/openstack/connection.rb +22 -1
- data/lib/openstack/volume/connection.rb +90 -0
- data/lib/openstack/volume/snapshot.rb +0 -0
- data/lib/openstack/volume/volume.rb +31 -0
- metadata +5 -2
data/README.rdoc
CHANGED
@@ -2,13 +2,15 @@
|
|
2
2
|
|
3
3
|
== Description
|
4
4
|
|
5
|
-
Ruby Openstack Compute
|
5
|
+
Ruby Openstack Compute, Object-Store and Block Storage bindings for the OpenStack API.
|
6
|
+
|
7
|
+
http://api.openstack.org/api-reference.html
|
6
8
|
|
7
9
|
Currently supports both v1.0 and v2.0 (keystone) auth.
|
8
10
|
|
9
11
|
Use OpenStack::Connection.create to get a handle to an OpenStack service - set the :service_type parameter to either 'compute' or 'object-store' (defaults to 'compute'). If the requested service is not deployed the gem will throw a OpenStack::Exception::NotImplemented (501) - e.g. :service_type is 'object-store' but swift service isn't deployed.
|
10
12
|
|
11
|
-
The OpenStack::Connection.create class method is a factory constructor which will return the appropriate Connection object, depending on the ':service_type' parameter passed with the options hash: set to either 'compute' or
|
13
|
+
The OpenStack::Connection.create class method is a factory constructor which will return the appropriate Connection object, depending on the ':service_type' parameter passed with the options hash: set to either 'compute', 'volume', or 'object-store' (defaults to 'compute') - see below for examples.
|
12
14
|
|
13
15
|
Other parameters for the create method:
|
14
16
|
|
@@ -179,6 +181,53 @@ See the class definitions for documentation on specific methods and operations.
|
|
179
181
|
>> os.delete_security_group(9571)
|
180
182
|
=> true
|
181
183
|
|
184
|
+
#Attach a volume to a server - params in order are: server_id, volume_id, attachment_point
|
185
|
+
|
186
|
+
>> os.attach_volume(704289, 90805, "/dev/sde")
|
187
|
+
=> true
|
188
|
+
|
189
|
+
#List attachments for a server:
|
190
|
+
|
191
|
+
>> os.list_attachments 704289
|
192
|
+
=> {:volumeAttachments=>[{:device=>"/dev/sde", :serverId=>704289, :id=>90805, :volumeId=>90805}]}
|
193
|
+
|
194
|
+
#Detach volume from server - params in order are server_id and attachment_id
|
195
|
+
>> os.detach_volume(704289, 90805)
|
196
|
+
=> true
|
197
|
+
|
198
|
+
== Examples for Volumes:
|
199
|
+
|
200
|
+
#NOTE - attach/detach operations are implemented for the compute service as the OS API defines these operations as extensions to Openstack Compute.
|
201
|
+
|
202
|
+
vs = OpenStack::Connection.create({:username => "username", :api_key=>"pass", :auth_url => "https://region-a.geo-1.identity.hpcloudsvc.com:35357/v2.0/", :authtenant=>"username-default-tenant", :service_type=>"volume"})
|
203
|
+
|
204
|
+
# Create a volume: - MUST specify display_name and size parameters... optional params are {:display_description, :metadata=>{:key=>val, ...}, :availability_zone, :volume_type }
|
205
|
+
|
206
|
+
>> volume = vs.create_volume({:display_name=>"marios volume", :size=>1, :display_description=>"some new volume bla"})
|
207
|
+
=> #<OpenStack::Volume::Volume:0x8a3c534 @id=90805, @display_name="marios volume", @display_description="some new volume bla", @size=1, @volume_type=nil, @metadata={}, @availability_zone="nova", @snapshot_id="", @attachments=[{}], @created_at="2012-11-15 13:51:23">
|
208
|
+
|
209
|
+
>> volume.size
|
210
|
+
=> 1
|
211
|
+
|
212
|
+
>> volume.attachments
|
213
|
+
=> [{}]
|
214
|
+
|
215
|
+
# List volumes:
|
216
|
+
|
217
|
+
>> vs.list_volumes #aliased as just 'volumes' ... vs.volumes
|
218
|
+
=> [#<OpenStack::Volume::Volume:0x8aad2e8 @id=90625, @display_name="marios volume", @display_description="attach test volume", @size=1, @volume_type=nil, @metadata={}, @availability_zone="nova", @snapshot_id="", @attachments=[{}], @created_at="2012-11-15 09:54:58">, #<OpenStack::Volume::Volume:0x8aad144 @id=90805, @display_name="marios volume", @display_description="some new volume bla", @size=1, @volume_type=nil, @metadata={}, @availability_zone="nova", @snapshot_id="", @attachments=[{}], @created_at="2012-11-15 13:51:23">]
|
219
|
+
|
220
|
+
# Get a particular volume - must specify ID:
|
221
|
+
|
222
|
+
>> vs.get_volume(90625) #aliased as 'volume'
|
223
|
+
=> #<OpenStack::Volume::Volume:0x8abd4a4 @id=90625, @display_name="marios volume", @display_description="attach test volume", @size=1, @volume_type=nil, @metadata={}, @availability_zone="nova", @snapshot_id="", @attachments=[{}], @created_at="2012-11-15 09:54:58">
|
224
|
+
|
225
|
+
# Delete a volume:
|
226
|
+
|
227
|
+
>> vs.delete_volume(90805)
|
228
|
+
=> true
|
229
|
+
|
230
|
+
|
182
231
|
== Examples for Object-Store:
|
183
232
|
|
184
233
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.0.7
|
data/lib/openstack.rb
CHANGED
@@ -42,6 +42,10 @@ module OpenStack
|
|
42
42
|
require 'openstack/swift/connection'
|
43
43
|
require 'openstack/swift/container'
|
44
44
|
require 'openstack/swift/storage_object'
|
45
|
+
require 'openstack/volume/connection'
|
46
|
+
require 'openstack/volume/volume'
|
47
|
+
require 'openstack/volume/snapshot'
|
48
|
+
|
45
49
|
|
46
50
|
# Constants that set limits on server creation
|
47
51
|
MAX_PERSONALITY_ITEMS = 5
|
@@ -387,6 +387,26 @@ module Compute
|
|
387
387
|
response = @connection.req("DELETE", "/os-security-group-rules/#{id}")
|
388
388
|
true
|
389
389
|
end
|
390
|
+
|
391
|
+
#VOLUMES - attach detach
|
392
|
+
def attach_volume(server_id, volume_id, device_id)
|
393
|
+
raise OpenStack::Exception::NotImplemented.new("os-volumes not implemented by #{@connection.http.keys.first}", 501, "NOT IMPLEMENTED") unless api_extensions[:"os-volumes"]
|
394
|
+
data = JSON.generate(:volumeAttachment => {"volumeId" => volume_id, "device"=> device_id})
|
395
|
+
response = @connection.req("POST", "/servers/#{server_id}/os-volume_attachments", {:data=>data})
|
396
|
+
true
|
397
|
+
end
|
398
|
+
|
399
|
+
def list_attachments(server_id)
|
400
|
+
raise OpenStack::Exception::NotImplemented.new("os-volumes not implemented by #{@connection.http.keys.first}", 501, "NOT IMPLEMENTED") unless api_extensions[:"os-volumes"]
|
401
|
+
response = @connection.req("GET", "/servers/#{server_id}/os-volume_attachments")
|
402
|
+
OpenStack.symbolize_keys(JSON.parse(response.body))
|
403
|
+
end
|
404
|
+
|
405
|
+
def detach_volume(server_id, attachment_id)
|
406
|
+
raise OpenStack::Exception::NotImplemented.new("os-volumes not implemented by #{@connection.http.keys.first}", 501, "NOT IMPLEMENTED") unless api_extensions[:"os-volumes"]
|
407
|
+
response = @connection.req("DELETE", "/servers/#{server_id}/os-volume_attachments/#{attachment_id}")
|
408
|
+
true
|
409
|
+
end
|
390
410
|
end
|
391
411
|
end
|
392
412
|
end
|
data/lib/openstack/connection.rb
CHANGED
@@ -63,6 +63,8 @@ class Connection
|
|
63
63
|
OpenStack::Compute::Connection.new(connection)
|
64
64
|
when "object-store"
|
65
65
|
OpenStack::Swift::Connection.new(connection)
|
66
|
+
when "volume"
|
67
|
+
OpenStack::Volume::Connection.new(connection)
|
66
68
|
else
|
67
69
|
raise Exception::InvalidArgument, "Invalid :service_type parameter: #{@service_type}"
|
68
70
|
end
|
@@ -242,9 +244,9 @@ class Authentication
|
|
242
244
|
end
|
243
245
|
|
244
246
|
private
|
245
|
-
|
246
247
|
class AuthV20
|
247
248
|
attr_reader :uri
|
249
|
+
attr_reader :version
|
248
250
|
def initialize(connection)
|
249
251
|
begin
|
250
252
|
server = Net::HTTP::Proxy(connection.proxy_host, connection.proxy_port).new(connection.auth_host, connection.auth_port)
|
@@ -292,6 +294,14 @@ class AuthV20
|
|
292
294
|
if @uri == ""
|
293
295
|
raise OpenStack::Exception::Authentication, "No API endpoint for region #{connection.region}"
|
294
296
|
else
|
297
|
+
if @version #already got one version of endpoints
|
298
|
+
current_version = get_version_from_response(service)
|
299
|
+
if @version.to_f > current_version.to_f
|
300
|
+
next
|
301
|
+
end
|
302
|
+
end
|
303
|
+
#grab version to check next time round for multi-version deployments
|
304
|
+
@version = get_version_from_response(service)
|
295
305
|
connection.service_host = @uri.host
|
296
306
|
connection.service_path = @uri.path
|
297
307
|
connection.service_port = @uri.port
|
@@ -306,6 +316,17 @@ class AuthV20
|
|
306
316
|
end
|
307
317
|
server.finish if server.started?
|
308
318
|
end
|
319
|
+
|
320
|
+
def get_version_from_response(service)
|
321
|
+
service["endpoints"].first["versionId"] || parse_version_from_endpoint(service["endpoints"].first["publicURL"])
|
322
|
+
end
|
323
|
+
|
324
|
+
#IN --> https://az-2.region-a.geo-1.compute.hpcloudsvc.com/v1.1/46871569847393
|
325
|
+
#OUT --> "1.1"
|
326
|
+
def parse_version_from_endpoint(endpoint)
|
327
|
+
endpoint.match(/\/v(\d).(\d)/).to_s.sub("/v", "")
|
328
|
+
end
|
329
|
+
|
309
330
|
end
|
310
331
|
|
311
332
|
class AuthV10
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module OpenStack
|
2
|
+
module Volume
|
3
|
+
|
4
|
+
class Connection
|
5
|
+
|
6
|
+
attr_accessor :connection
|
7
|
+
attr_reader :volumes_native
|
8
|
+
|
9
|
+
def initialize(connection)
|
10
|
+
@connection = connection
|
11
|
+
OpenStack::Authentication.init(@connection)
|
12
|
+
@volumes_native, @volume_path = check_if_native
|
13
|
+
end
|
14
|
+
|
15
|
+
# Returns true if the authentication was successful and returns false otherwise.
|
16
|
+
#
|
17
|
+
# cs.authok?
|
18
|
+
# => true
|
19
|
+
def authok?
|
20
|
+
@connection.authok
|
21
|
+
end
|
22
|
+
|
23
|
+
#require params: {:display_name, :size}
|
24
|
+
#optional params: {:display_description, :metadata=>{:key=>val, ...}, :availability_zone, :volume_type }
|
25
|
+
#returns OpenStack::Volume::Volume object
|
26
|
+
def create_volume(options)
|
27
|
+
raise OpenStack::Exception::MissingArgument, ":display_name and :size must be specified to create a volume" unless (options[:display_name] && options[:size])
|
28
|
+
data = JSON.generate(:volume => options)
|
29
|
+
response = @connection.csreq("POST",@connection.service_host,"#{@connection.service_path}/#{@volume_path}",@connection.service_port,@connection.service_scheme,{'content-type' => 'application/json'},data)
|
30
|
+
volume_info = JSON.parse(response.body)["volume"]
|
31
|
+
volume = OpenStack::Volume::Volume.new(volume_info)
|
32
|
+
end
|
33
|
+
|
34
|
+
#no options documented in API at Nov 2012
|
35
|
+
#(e.g. like limit/marker as used in Nova for servers)
|
36
|
+
def list_volumes
|
37
|
+
response = @connection.req("GET", "/#{@volume_path}")
|
38
|
+
volumes_hash = JSON.parse(response.body)["volumes"]
|
39
|
+
volumes_hash.inject([]){|res, current| res << OpenStack::Volume::Volume.new(current); res}
|
40
|
+
end
|
41
|
+
alias :volumes :list_volumes
|
42
|
+
|
43
|
+
|
44
|
+
def get_volume(vol_id)
|
45
|
+
response = @connection.req("GET", "/#{@volume_path}/#{vol_id}")
|
46
|
+
volume_hash = JSON.parse(response.body)["volume"]
|
47
|
+
OpenStack::Volume::Volume.new(volume_hash)
|
48
|
+
end
|
49
|
+
alias :volume :get_volume
|
50
|
+
|
51
|
+
def delete_volume(vol_id)
|
52
|
+
response = @connection.req("DELETE", "/#{@volume_path}/#{vol_id}")
|
53
|
+
true
|
54
|
+
end
|
55
|
+
|
56
|
+
#TODO SNAPSHOTS
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
#fudge... not clear if volumes support is available as 'native' volume API or
|
61
|
+
#as the os-volumes extension. Need to probe to find out (for now)
|
62
|
+
#see https://lists.launchpad.net/openstack/msg16601.html
|
63
|
+
def check_if_native
|
64
|
+
native = extension = false
|
65
|
+
#check if 'native' volume API present:
|
66
|
+
begin
|
67
|
+
response = @connection.req("GET", "/volumes")
|
68
|
+
native = true if response.code.match(/^20.$/)
|
69
|
+
return true, "volumes"
|
70
|
+
rescue OpenStack::Exception::ItemNotFound => not_found
|
71
|
+
native = false
|
72
|
+
end
|
73
|
+
#check if available as extension:
|
74
|
+
begin
|
75
|
+
response = @connection.req("GET", "/os-volumes")
|
76
|
+
extension = true if response.code.match(/^20.$/)
|
77
|
+
return false, "os-volumes"
|
78
|
+
rescue OpenStack::Exception::ItemNotFound => not_found
|
79
|
+
extension = false
|
80
|
+
end
|
81
|
+
raise OpenStack::Exception::NotImplemented.new("No Volumes support for this provider", 501, "No Volumes Support") unless (native || extension)
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
end
|
File without changes
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module OpenStack
|
2
|
+
module Volume
|
3
|
+
class Volume
|
4
|
+
|
5
|
+
attr_reader :id
|
6
|
+
attr_reader :display_name
|
7
|
+
attr_reader :display_description
|
8
|
+
attr_reader :size
|
9
|
+
attr_reader :volume_type
|
10
|
+
attr_reader :metadata
|
11
|
+
attr_reader :availability_zone
|
12
|
+
attr_reader :snapshot_id
|
13
|
+
attr_reader :attachments
|
14
|
+
attr_reader :created_at
|
15
|
+
|
16
|
+
def initialize(volume_info)
|
17
|
+
@id = volume_info["id"]
|
18
|
+
@display_name = volume_info["display_name"] || volume_info["displayName"]
|
19
|
+
@display_description = volume_info["display_description"] || volume_info["displayDescription"]
|
20
|
+
@size = volume_info["size"]
|
21
|
+
@volume_type = volume_info["volume_type"] || volume_info["volumeType"]
|
22
|
+
@metadata = volume_info["metadata"]
|
23
|
+
@availability_zone = volume_info["availability_zone"] || volume_info["availabilityZone"]
|
24
|
+
@snapshot_id = volume_info["snapshot_id"] || volume_info["snapshotId"]
|
25
|
+
@attachments = volume_info["attachments"]
|
26
|
+
@created_at = volume_info["created_at"] || volume_info["createdAt"]
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: openstack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.7
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-
|
13
|
+
date: 2012-11-19 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: mocha
|
@@ -84,6 +84,9 @@ files:
|
|
84
84
|
- lib/openstack/swift/connection.rb
|
85
85
|
- lib/openstack/swift/container.rb
|
86
86
|
- lib/openstack/swift/storage_object.rb
|
87
|
+
- lib/openstack/volume/connection.rb
|
88
|
+
- lib/openstack/volume/snapshot.rb
|
89
|
+
- lib/openstack/volume/volume.rb
|
87
90
|
- test/authentication_test.rb
|
88
91
|
- test/connection_test.rb
|
89
92
|
- test/exception_test.rb
|