openstack 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +80 -0
- data/VERSION +1 -1
- data/lib/openstack/compute/connection.rb +111 -0
- data/lib/openstack/compute/server.rb +2 -0
- data/lib/openstack/connection.rb +16 -11
- data/lib/openstack/swift/storage_object.rb +1 -1
- metadata +5 -5
data/README.rdoc
CHANGED
@@ -8,6 +8,40 @@ Currently supports both v1.0 and v2.0 (keystone) auth.
|
|
8
8
|
|
9
9
|
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')
|
10
10
|
|
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 'object-store' (defaults to 'compute') - see below for examples.
|
12
|
+
|
13
|
+
Other parameters for the create method:
|
14
|
+
|
15
|
+
* :auth_url - the OpenStack service provider specific authentication url endpoint.
|
16
|
+
* :auth_method - the type of authentication to be used with the above auth_url - either 'password' (username/password, 'key' (ec2 style key/private key) or 'rax-kskey'.
|
17
|
+
* :authtenant_name OR :authtenant_id - one of these MUST be specified when talking to a v2 authentication endpoint (keystone) - depending on whether you use tenant name (or tenant ID). Passing only :authtenant will result in that parameter being used as tenant name.
|
18
|
+
* :username - the username or public key (depending on auth_method)
|
19
|
+
* :api_key - the password or private key (denending on auth_method).
|
20
|
+
|
21
|
+
=== Try it out:
|
22
|
+
|
23
|
+
sudo gem install openstack
|
24
|
+
[sudo] password for herp:
|
25
|
+
Successfully installed openstack-1.0.0
|
26
|
+
|
27
|
+
[herp@name lib]$ irb -rubygems
|
28
|
+
irb(main):001:0> require 'openstack'
|
29
|
+
=> true
|
30
|
+
|
31
|
+
irb(main):002:0> os = OpenStack::Connection.create({:username => "herp@derp.net", :api_key=>"1234abcd", :auth_method=>"password", :auth_url => "https://regionerer-g.go-bar.identity.dacloudfoo.herpy:13327/v2.0/", :authtenant_name =>"herp@derp.net-default-tenant", :service_type=>"compute"})
|
32
|
+
|
33
|
+
=> #<OpenStack::Compute::Connection:0xb7339070 @connection=#<OpenStack::Connection:0xb73392dc @service_scheme="https", @auth_host="regionerer-g.go-bar.identity.dacloudfoo.herpy", @http={}, @service_name=nil, @authuser="herp@derp.net", @proxy_port=nil, @auth_path="/v2.0/", @authtenant={:type=>"tenantName", :value=>"herp@derp.net-default-tenant"}, @service_port=443, @authkey="1235abcd", @authok=true, @service_type="compute", @auth_method="password", @auth_scheme="https", @service_host="az-2.region-a.geo-1.dacloudfoo.herpy", @is_debug=nil, @proxy_host=nil, @service_path="/v1.1/482195756462871", @auth_port=35357, @auth_url="https://regionerer-g.go-bar.identity.dacloudfoo.herpy:13327/v2.0/", @region=nil, @authtoken="Auth_543254fdsasabd546543a3", @retry_auth=nil>>
|
34
|
+
|
35
|
+
irb(main):003:0> os.servers
|
36
|
+
=> []
|
37
|
+
|
38
|
+
irb(main):004:0> os = OpenStack::Connection.create({:username => "AWHFDADHJ32EL6V23GFK", :api_key=>"jd823jFDJEY2/82jfhYteG52AKJAUEY184JHRfeR", :auth_method=> "key", :auth_url => "https://regionerer-g.go-bar.identity.dacloudfoo.herpy:13327/v2.0/", :authtenant_id =>"482195756462871", :service_type=>"object-store"})
|
39
|
+
|
40
|
+
=> #<OpenStack::Swift::Connection:0xb72ff2a8 @connection=#<OpenStack::Connection:0xb72ff460 @service_scheme="https", @auth_host="regionerer-g.go-bar.identity.dacloudfoo.herpy", @http={}, @service_name=nil, @authuser="AWHFDADHJ32EL6V23GFK", @proxy_port=nil, @auth_path="/v2.0/", @authtenant={:type=>"tenantId", :value=>"482195756462871"}, @service_port=443, @authkey="jd823jFDJEY2/82jfhYteG52AKJAUEY184JHRfeR", @authok=true, @service_type="object-store", @auth_method="key", @auth_scheme="https", @service_host="region-a.geo-1.objects.dacloudfoo.herpy", @is_debug=nil, @proxy_host=nil, @service_path="/v1.0/482195756462871", @auth_port=35357, @auth_url="https://regionerer-g.go-bar.identity.dacloudfoo.herpy:13327/v2.0/", @region=nil, @authtoken="Auth_543254fdsasabd546543a3", @retry_auth=nil>>
|
41
|
+
|
42
|
+
irb(main):006:0> os.containers
|
43
|
+
=> ["herpy_Foo_container", "derpy_bar_bucket"]
|
44
|
+
|
11
45
|
== Examples
|
12
46
|
|
13
47
|
== For Compute:
|
@@ -59,10 +93,56 @@ See the class definitions for documentation on specific methods and operations.
|
|
59
93
|
>> newserver.progress
|
60
94
|
=> 12
|
61
95
|
|
96
|
+
# Create a new server and specify the keyname to be used (some provider support the Keys extension):
|
97
|
+
>> server = os.create_server({:imageRef=>14075, :flavorRef=>100, :key_name=>"my_default_key", :name=>"marios_server"})
|
98
|
+
=> #<OpenStack::Compute::Server:0x101433f08 ....
|
99
|
+
>> server.key_name
|
100
|
+
=> "my_default_key"
|
101
|
+
|
62
102
|
# Delete the new server
|
63
103
|
>> newserver.delete!
|
64
104
|
=> true
|
65
105
|
|
106
|
+
=== Compute API extensions.
|
107
|
+
|
108
|
+
# Get info on extensions offered by the given OpenStack provider:
|
109
|
+
>> os.api_extensions
|
110
|
+
=> { :os-keypairs => { :links=>[], :updated=>"2011-08-08T00:00:00+00:00", :description=>"Keypair Support",
|
111
|
+
:namespace=>"http://docs.openstack.org/ext/keypairs/api/v1.1", :name=>"Keypairs",
|
112
|
+
:alias=>"os-keypairs" },
|
113
|
+
:os-floating_ips => { :links=>[], :updated=>"2011-06-16T00:00:00+00:00", :description=>"Floating IPs support",
|
114
|
+
:namespace=>"http://docs.openstack.org/ext/floating_ips/api/v1.1", :name=>"Floating_ips", :alias=>"os-floating-ips"},
|
115
|
+
... }
|
116
|
+
|
117
|
+
# Get list of keypairs for current tenant/account:
|
118
|
+
>> os.keypairs
|
119
|
+
=> { :key_one => { :fingerprint => "3f:12:4d:d1:54:f1:f4:3f:fe:a8:12:ec:1a:fb:35:b2",
|
120
|
+
:public_key => "ssh-rsa AAAAB3Nza923kJ ...
|
121
|
+
:name => "key_one"},
|
122
|
+
:key_two => { ... },
|
123
|
+
... }
|
124
|
+
|
125
|
+
# Create new keypair:
|
126
|
+
>> os.create_keypair({:name=>"test_key"})
|
127
|
+
=> { :name => "test_key",
|
128
|
+
:fingerprint => "f1:f3:a2:d3:ca:75:da:f1:06:f4:f7:dc:cc:7d:e1:ca",
|
129
|
+
:user_id => "dev_41247879706381",$
|
130
|
+
:public_key => "ssh-rsa AAAAB3NzaC1y ...
|
131
|
+
:private_key => "-----BEGIN RSA PRIVATE KEY-----\nMIICXwIBA ... -----END RSA PRIVATE KEY-----\n"
|
132
|
+
}
|
133
|
+
|
134
|
+
# Import keypair:
|
135
|
+
>> os.create_keypair({:name=>"test_key_imported", :public_key=>"sh-rsa AAAAB3Nza923kJ ..."})
|
136
|
+
=> { :name => "test_key_imported",
|
137
|
+
:fingerprint => "f1:f3:a2:d3:ca:75:da:f1:06:f4:f7:dc:cc:7d:e1:ca",
|
138
|
+
:user_id => "dev_41247879706381",$
|
139
|
+
:public_key => "ssh-rsa AAAAB3Nza ...
|
140
|
+
}
|
141
|
+
|
142
|
+
# Delete Keypair:
|
143
|
+
>> os.delete_keypair("test_key_imported")
|
144
|
+
=> true
|
145
|
+
|
66
146
|
== Examples for Object-Store:
|
67
147
|
|
68
148
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.0.1
|
@@ -202,6 +202,117 @@ module Compute
|
|
202
202
|
OpenStack.symbolize_keys(JSON.parse(response.body)['limits'])
|
203
203
|
end
|
204
204
|
|
205
|
+
# ==============================
|
206
|
+
# API EXTENSIONS
|
207
|
+
#
|
208
|
+
# http://nova.openstack.org/api_ext/index.html
|
209
|
+
# http://api.openstack.org/ (grep 'Compute API Extensions')
|
210
|
+
#
|
211
|
+
|
212
|
+
|
213
|
+
#query the openstack provider for any implemented extensions to the compute API
|
214
|
+
#returns a hash with openstack service provider's returned details
|
215
|
+
#about the implemented extensions, e.g.:
|
216
|
+
#
|
217
|
+
# { :os-floating_ips => { :links=>[],
|
218
|
+
# :updated=>"2011-06-16T00:00:00+00:00",
|
219
|
+
# :description=>"Floating IPs support",
|
220
|
+
# :namespace=>"http://docs.openstack.org/ext/floating_ips/api/v1.1",
|
221
|
+
# :name=>"Floating_ips", :alias=>"os-floating-ips"},
|
222
|
+
# :os-keypairs => { :links=>[],
|
223
|
+
# :updated=>"2011-08-08T00:00:00+00:00",
|
224
|
+
# :description=>"Keypair Support",
|
225
|
+
# :namespace=>"http://docs.openstack.org/ext/keypairs/api/v1.1",
|
226
|
+
# :name=>"Keypairs",
|
227
|
+
# :alias=>"os-keypairs"}
|
228
|
+
# }
|
229
|
+
#
|
230
|
+
def api_extensions
|
231
|
+
response = @connection.req("GET", "/extensions")
|
232
|
+
OpenStack::Exception.raise_exception(response) unless response.code.match(/^20.$/)
|
233
|
+
res = OpenStack.symbolize_keys(JSON.parse(response.body))
|
234
|
+
res[:extensions].inject({}){|result, c| result[c[:alias].to_sym] = c ; result}
|
235
|
+
end
|
236
|
+
|
237
|
+
# Retrieve a list of key pairs associated with the current authenticated account
|
238
|
+
# Will return a hash:
|
239
|
+
# { :key_one => { :fingerprint => "3f:12:4d:d1:54:f1:f4:3f:fe:a8:12:ec:1a:fb:35:b2",
|
240
|
+
# :public_key => "ssh-rsa AAAAB3Nza923kJU123AADAQABAAAAg928JUwydszi029kIJudfOzQ7o160Ll1ItybDzYYcCAJ/N02loIKJU17264520bmXZFSsaZf2ErX3nSBNI3K+2zQzu832jkhkfdsa7GHH5hvNOxO7u800894312JKLJLHP/R91fdsajHKKJADSAgQ== nova@nv-zz2232-api0002\n",
|
241
|
+
# :name => "key_one"},
|
242
|
+
#
|
243
|
+
# :key_two => { :fingerprint => "6b:32:dd:d2:51:c1:f2:3a:fb:a2:52:3a:1a:bb:25:1b",
|
244
|
+
# :public_key => "ssh-rsa AKIJUuw71645kJU123AADAQABAAAAg928019oiUJY12765IJudfOzQ7o160Ll1ItybDzYYcCAJ/N80438012480321jhkhKJlfdsazu832jkhkfdsa7GHH5fdasfdsajlj2999789799987989894312JKLJLHP/R91fdsajHKKJADSAgQ== nova@bv-fdsa32-api0002\n",
|
245
|
+
# :name => "key_two"}
|
246
|
+
# }
|
247
|
+
#
|
248
|
+
# Raises OpenStack::Exception::NotImplemented if the current provider doesn't
|
249
|
+
# offer the os-keypairs extension
|
250
|
+
#
|
251
|
+
def keypairs
|
252
|
+
begin
|
253
|
+
response = @connection.req("GET", "/os-keypairs")
|
254
|
+
res = OpenStack.symbolize_keys(JSON.parse(response.body))
|
255
|
+
res[:keypairs].inject({}){|result, c| result[c[:keypair][:name].to_sym] = c[:keypair] ; result }
|
256
|
+
rescue OpenStack::Exception::ItemNotFound => not_found
|
257
|
+
msg = "The os-keypairs extension is not implemented for the provider you are talking to "+
|
258
|
+
"- #{@connection.http.keys.first}"
|
259
|
+
raise OpenStack::Exception::NotImplemented.new(msg, 501, "#{not_found.message}")
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
# Create a new keypair for use with launching servers. Raises
|
264
|
+
# a OpenStack::Exception::NotImplemented if os-keypairs extension
|
265
|
+
# is not implemented (or not advertised) by the OpenStack provider.
|
266
|
+
#
|
267
|
+
# The 'name' parameter MUST be supplied, otherwise a
|
268
|
+
# OpenStack::Exception::MissingArgument will be raised.
|
269
|
+
#
|
270
|
+
# Optionally requests can specify a 'public_key' parameter,
|
271
|
+
# with the full public ssh key (String) to be used to create the keypair
|
272
|
+
# (i.e. import a existing key).
|
273
|
+
#
|
274
|
+
# Returns a hash with details of the new key; the :private_key attribute
|
275
|
+
# must be saved must be saved by caller (not retrievable thereafter).
|
276
|
+
# NOTE: when the optional :public_key parameter is given, the response
|
277
|
+
# will obviously NOT contain the :private_key attribute.
|
278
|
+
#
|
279
|
+
# >> os.create_keypair({:name=>"test_key"})
|
280
|
+
# => { :name => "test_key",
|
281
|
+
# :fingerprint => "f1:f3:a2:d3:ca:75:da:f1:06:f4:f7:dc:cc:7d:e1:ca",
|
282
|
+
# :user_id => "dev_41247879706381",
|
283
|
+
# :public_key => "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDgGhDH3z9uMAvPV8ziE9BCEjHCPXGufy5bOgY5mY5jOSfdmKspdbl0z/LimHVKRDNX6HoL5qRg5V/tGH/NYP5sX2zF/XRKz16lfBxiUL1EONXA9fsTEBR3FGp8NcA7hW2+YiUxWafms4If3NFqttTQ11XqTU8JCMvms4D81lhbiQ== nova@use03147k5-eth0\n",
|
284
|
+
# :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"
|
285
|
+
# }
|
286
|
+
#
|
287
|
+
# Will raise an OpenStack::Exception::BadRequest if an invalid public_key is provided:
|
288
|
+
# >> os.create_keypair({:name=>"marios_keypair_test_invalid", :public_key=>"derp"})
|
289
|
+
# => OpenStack::Exception::BadRequest: Unexpected error while running command.
|
290
|
+
# Stdout: '/tmp/tmp4kI12a/import.pub is not a public key file.\n'
|
291
|
+
#
|
292
|
+
def create_keypair(options)
|
293
|
+
raise OpenStack::Exception::NotImplemented.new("os-keypairs not implemented by #{@connection.http.keys.first}", 501, "NOT IMPLEMENTED") unless api_extensions[:"os-keypairs"]
|
294
|
+
raise OpenStack::Exception::MissingArgument, "Keypair name must be supplied" unless (options[:name])
|
295
|
+
data = JSON.generate(:keypair => options)
|
296
|
+
response = @connection.req("POST", "/os-keypairs", {:data=>data})
|
297
|
+
res = OpenStack.symbolize_keys(JSON.parse(response.body))
|
298
|
+
res[:keypair]
|
299
|
+
end
|
300
|
+
|
301
|
+
# Delete an existing keypair. Raises OpenStack::Exception::NotImplemented
|
302
|
+
# if os-keypairs extension is not implemented (or not advertised) by the OpenStack provider.
|
303
|
+
#
|
304
|
+
# Returns true if succesful.
|
305
|
+
# >> os.delete_keypair("marios_keypair")
|
306
|
+
# => true
|
307
|
+
#
|
308
|
+
# Will raise OpenStack::Exception::ItemNotFound if specified keypair doesn't exist
|
309
|
+
#
|
310
|
+
def delete_keypair(keypair_name)
|
311
|
+
raise OpenStack::Exception::NotImplemented.new("os-keypairs not implemented by #{@connection.http.keys.first}", 501, "NOT IMPLEMENTED") unless api_extensions[:"os-keypairs"]
|
312
|
+
@connection.req("DELETE", "/os-keypairs/#{keypair_name}")
|
313
|
+
true
|
314
|
+
end
|
315
|
+
|
205
316
|
end
|
206
317
|
end
|
207
318
|
end
|
@@ -16,6 +16,7 @@ module Compute
|
|
16
16
|
attr_reader :flavor
|
17
17
|
attr_reader :metadata
|
18
18
|
attr_accessor :adminPass
|
19
|
+
attr_reader :key_name
|
19
20
|
|
20
21
|
# This class is the representation of a single Server object. The constructor finds the server identified by the specified
|
21
22
|
# ID number, accesses the API via the populate method to get information about that server, and returns the object.
|
@@ -61,6 +62,7 @@ module Compute
|
|
61
62
|
@hostId = data["hostId"]
|
62
63
|
@image = data["image"]
|
63
64
|
@flavor = data["flavor"]
|
65
|
+
@key_name = data["key_name"] # if provider uses the keys API extension for accessing servers
|
64
66
|
true
|
65
67
|
end
|
66
68
|
alias :refresh :populate
|
data/lib/openstack/connection.rb
CHANGED
@@ -37,9 +37,11 @@ class Connection
|
|
37
37
|
#
|
38
38
|
# options hash:
|
39
39
|
#
|
40
|
-
# :
|
41
|
-
# :
|
42
|
-
# :
|
40
|
+
# :auth_method - Type of authentication - 'password', 'key', 'rax-kskey' - defaults to 'password'
|
41
|
+
# :username - Your OpenStack username or public key, depending on auth_method. *required*
|
42
|
+
# :authtenant_name OR :authtenant_id - Your OpenStack tenant name or id *required*. Defaults to username.
|
43
|
+
# passing :authtenant will default to using that parameter as tenant name.
|
44
|
+
# :api_key - Your OpenStack API key *required* (either private key or password, depending on auth_method)
|
43
45
|
# :auth_url - Configurable auth_url endpoint.
|
44
46
|
# :service_name - (Optional for v2.0 auth only). The optional name of the compute service to use.
|
45
47
|
# :service_type - (Optional for v2.0 auth only). Defaults to "compute"
|
@@ -72,7 +74,7 @@ class Connection
|
|
72
74
|
@authuser = options[:username] || (raise Exception::MissingArgument, "Must supply a :username")
|
73
75
|
@authkey = options[:api_key] || (raise Exception::MissingArgument, "Must supply an :api_key")
|
74
76
|
@auth_url = options[:auth_url] || (raise Exception::MissingArgument, "Must supply an :auth_url")
|
75
|
-
@authtenant = options[:authtenant] || @authuser
|
77
|
+
@authtenant = (options[:authtenant_id])? {:type => "tenantId", :value=>options[:authtenant_id]} : {:type=>"tenantName", :value=>(options[:authtenant_name] || options[:authtenant] || @authuser)}
|
76
78
|
@auth_method = options[:auth_method] || "password"
|
77
79
|
@service_name = options[:service_name] || nil
|
78
80
|
@service_type = options[:service_type] || "compute"
|
@@ -106,7 +108,7 @@ class Connection
|
|
106
108
|
chunked = OpenStack::Swift::ChunkedConnectionWrapper.new(data, 65535)
|
107
109
|
request.body_stream = chunked
|
108
110
|
else
|
109
|
-
headers['Content-Length'] = (
|
111
|
+
headers['Content-Length'] = (data.respond_to?(:lstat))? data.lstat.size.to_s : ((data.respond_to?(:size))? data.size.to_s : "0")
|
110
112
|
hdrhash = headerprep(headers)
|
111
113
|
request = Net::HTTP::Put.new(path,hdrhash)
|
112
114
|
request.body = data
|
@@ -260,12 +262,15 @@ class AuthV20
|
|
260
262
|
|
261
263
|
@uri = String.new
|
262
264
|
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
265
|
+
case connection.auth_method
|
266
|
+
when "password"
|
267
|
+
auth_data = JSON.generate({ "auth" => { "passwordCredentials" => { "username" => connection.authuser, "password" => connection.authkey }, connection.authtenant[:type] => connection.authtenant[:value]}})
|
268
|
+
when "rax-kskey"
|
269
|
+
auth_data = JSON.generate({"auth" => {"RAX-KSKEY:apiKeyCredentials" => {"username" => connection.authuser, "apiKey" => connection.authkey}}})
|
270
|
+
when "key"
|
271
|
+
auth_data = JSON.generate({"auth" => { "apiAccessKeyCredentials" => {"accessKey" => connection.authuser, "secretKey" => connection.authkey}, connection.authtenant[:type] => connection.authtenant[:value]}})
|
272
|
+
else
|
273
|
+
raise Exception::InvalidArgument, "Unrecognized auth method #{connection.auth_method}"
|
269
274
|
end
|
270
275
|
|
271
276
|
response = server.post(connection.auth_path.chomp("/")+"/tokens", auth_data, {'Content-Type' => 'application/json'})
|
@@ -46,7 +46,7 @@ module Swift
|
|
46
46
|
# cont.create_object("my_new_object", {}, "object data")
|
47
47
|
#
|
48
48
|
def self.create(container, objectname, headers={}, data=nil)
|
49
|
-
provided_headers = (headers[:metadata] || {}).inject({}){|res, (k,v)| ((k.match /^X-Object-Meta-/i) ? res[k]=v : res["X-Object-Meta-#{k}"]=v) ;res}
|
49
|
+
provided_headers = (headers[:metadata] || {}).inject({}){|res, (k,v)| ((k.to_s.match /^X-Object-Meta-/i) ? res[k.to_s]=v : res["X-Object-Meta-#{k.to_s}"]=v) ;res}
|
50
50
|
provided_headers["content-type"] = headers[:content_type] unless headers[:content_type].nil?
|
51
51
|
provided_headers["ETag"] = headers[:etag] unless headers[:etag].nil?
|
52
52
|
provided_headers["X-Object-Manifest"] = headers[:manifest] unless headers[:manifest].nil?
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: openstack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 21
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 1.0.
|
9
|
+
- 1
|
10
|
+
version: 1.0.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Dan Prince
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2012-
|
19
|
+
date: 2012-06-22 00:00:00 Z
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
22
22
|
name: json
|
@@ -58,7 +58,7 @@ files:
|
|
58
58
|
- lib/openstack/swift/connection.rb
|
59
59
|
- lib/openstack/swift/container.rb
|
60
60
|
- lib/openstack/swift/storage_object.rb
|
61
|
-
homepage: https://
|
61
|
+
homepage: https://github.com/ruby-openstack/ruby-openstack
|
62
62
|
licenses: []
|
63
63
|
|
64
64
|
post_install_message:
|