openstack 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|