openstack 1.1.1 → 1.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/openstack.rb +2 -1
- data/lib/openstack/compute/address.rb +15 -0
- data/lib/openstack/compute/connection.rb +31 -1
- data/lib/openstack/connection.rb +49 -16
- data/lib/openstack/network/connection.rb +59 -2
- data/lib/openstack/network/port.rb +1 -1
- data/lib/openstack/network/router.rb +27 -0
- data/lib/openstack/network/subnet.rb +1 -1
- data/lib/openstack/version.rb +3 -0
- metadata +19 -2
- data/VERSION +0 -1
data/lib/openstack.rb
CHANGED
@@ -18,7 +18,6 @@
|
|
18
18
|
|
19
19
|
module OpenStack
|
20
20
|
|
21
|
-
VERSION = IO.read(File.dirname(__FILE__) + '/../VERSION')
|
22
21
|
require 'net/http'
|
23
22
|
require 'net/https'
|
24
23
|
require 'uri'
|
@@ -49,7 +48,9 @@ module OpenStack
|
|
49
48
|
require 'openstack/network/connection'
|
50
49
|
require 'openstack/network/network'
|
51
50
|
require 'openstack/network/subnet'
|
51
|
+
require 'openstack/network/router'
|
52
52
|
require 'openstack/network/port'
|
53
|
+
require 'openstack/version'
|
53
54
|
# Constants that set limits on server creation
|
54
55
|
MAX_PERSONALITY_ITEMS = 5
|
55
56
|
MAX_PERSONALITY_FILE_SIZE = 10240
|
@@ -78,7 +78,22 @@ module Compute
|
|
78
78
|
@pool = addr_hash["pool"]
|
79
79
|
end
|
80
80
|
|
81
|
+
end
|
81
82
|
|
83
|
+
class FloatingIPInfo
|
84
|
+
attr_reader :address
|
85
|
+
attr_reader :instance_uuid
|
86
|
+
attr_reader :interface
|
87
|
+
attr_reader :pool
|
88
|
+
attr_reader :project_id
|
89
|
+
|
90
|
+
def initialize(info_hash)
|
91
|
+
@address = info_hash['address']
|
92
|
+
@instance_uuid = info_hash['instance_uuid']
|
93
|
+
@interface = info_hash['interface']
|
94
|
+
@pool = info_hash['pool']
|
95
|
+
@project_id = info_hash['project_id']
|
96
|
+
end
|
82
97
|
end
|
83
98
|
|
84
99
|
end
|
@@ -465,6 +465,37 @@ module Compute
|
|
465
465
|
true
|
466
466
|
end
|
467
467
|
|
468
|
+
def get_floating_ip_polls
|
469
|
+
check_extension 'os-floating-ip-pools'
|
470
|
+
response = @connection.req('GET', '/os-floating-ip-pools')
|
471
|
+
res = JSON.parse(response.body)['floating_ip_pools']
|
472
|
+
end
|
473
|
+
|
474
|
+
def get_floating_ips_bulk
|
475
|
+
check_extension 'os-floating-ips-bulk'
|
476
|
+
response = @connection.req('GET', '/os-floating-ips-bulk')
|
477
|
+
res = JSON.parse(response.body)['floating_ip_info']
|
478
|
+
res.inject([]){|result, c| result << OpenStack::Compute::FloatingIPInfo.new(c); result}
|
479
|
+
end
|
480
|
+
|
481
|
+
def create_floating_ips_bulk(opts = {})
|
482
|
+
raise ArgumentError, 'Should not be empty' if opts.empty?
|
483
|
+
data = JSON.generate({:floating_ips_bulk_create => opts})
|
484
|
+
check_extension 'os-floating-ips-bulk'
|
485
|
+
response = @connection.req('POST', '/os-floating-ips-bulk', {:data => data})
|
486
|
+
JSON.parse(response.body)['floating_ips_bulk_create']
|
487
|
+
end
|
488
|
+
|
489
|
+
# Not working
|
490
|
+
# Nova does not supported deletion via API
|
491
|
+
def delete_floating_ips_bulk(opts = {})
|
492
|
+
raise ArgumentError, 'Should not be empty' if opts.empty?
|
493
|
+
data = JSON.generate(opts)
|
494
|
+
check_extension 'os-floating-ips-bulk'
|
495
|
+
response = @connection.req('POST', '/os-floating-ips-bulk/delete', {:data => data})
|
496
|
+
res = JSON.generate(response)
|
497
|
+
end
|
498
|
+
|
468
499
|
private
|
469
500
|
|
470
501
|
def check_extension(name)
|
@@ -472,7 +503,6 @@ module Compute
|
|
472
503
|
true
|
473
504
|
end
|
474
505
|
|
475
|
-
|
476
506
|
end
|
477
507
|
|
478
508
|
end
|
data/lib/openstack/connection.rb
CHANGED
@@ -12,6 +12,8 @@ class Connection
|
|
12
12
|
attr_accessor :service_path
|
13
13
|
attr_accessor :service_port
|
14
14
|
attr_accessor :service_scheme
|
15
|
+
attr_accessor :quantum_version
|
16
|
+
attr_reader :retries
|
15
17
|
attr_reader :auth_host
|
16
18
|
attr_reader :auth_port
|
17
19
|
attr_reader :auth_scheme
|
@@ -78,6 +80,7 @@ class Connection
|
|
78
80
|
private_class_method :new
|
79
81
|
|
80
82
|
def initialize(options = {:retry_auth => true})
|
83
|
+
@retries = options[:retries] || 3
|
81
84
|
@authuser = options[:username] || (raise Exception::MissingArgument, "Must supply a :username")
|
82
85
|
@authkey = options[:api_key] || (raise Exception::MissingArgument, "Must supply an :api_key")
|
83
86
|
@auth_url = options[:auth_url] || (raise Exception::MissingArgument, "Must supply an :auth_url")
|
@@ -104,10 +107,15 @@ class Connection
|
|
104
107
|
@proxy_port = options[:proxy_port]
|
105
108
|
@authok = false
|
106
109
|
@http = {}
|
110
|
+
@quantum_version = 'v2.0' if @service_type == 'network'
|
107
111
|
end
|
108
112
|
|
109
113
|
#specialised from of csreq for PUT object... uses body_stream if possible
|
110
114
|
def put_object(server,path,port,scheme,headers = {},data = nil,attempts = 0) # :nodoc:
|
115
|
+
|
116
|
+
tries = @retries
|
117
|
+
time = 3
|
118
|
+
|
111
119
|
if data.respond_to? :read
|
112
120
|
headers['Transfer-Encoding'] = 'chunked'
|
113
121
|
hdrhash = headerprep(headers)
|
@@ -132,11 +140,12 @@ class Connection
|
|
132
140
|
response
|
133
141
|
rescue Errno::EPIPE, Timeout::Error, Errno::EINVAL, EOFError
|
134
142
|
# Server closed the connection, retry
|
135
|
-
|
136
|
-
|
143
|
+
puts "Can't connect to the server: #{tries} tries to reconnect" if @is_debug
|
144
|
+
sleep time += 1
|
137
145
|
@http[server].finish if @http[server].started?
|
138
|
-
|
139
|
-
|
146
|
+
retry unless (tries -= 1) <= 0
|
147
|
+
raise OpenStack::Exception::Connection, "Unable to connect to #{server} after #{@retries} retries"
|
148
|
+
|
140
149
|
rescue OpenStack::Exception::ExpiredAuthToken
|
141
150
|
raise OpenStack::Exception::Connection, "Authentication token expired and you have requested not to retry" if @retry_auth == false
|
142
151
|
OpenStack::Authentication.init(self)
|
@@ -146,6 +155,10 @@ class Connection
|
|
146
155
|
|
147
156
|
# This method actually makes the HTTP REST calls out to the server
|
148
157
|
def csreq(method,server,path,port,scheme,headers = {},data = nil,attempts = 0, &block) # :nodoc:
|
158
|
+
|
159
|
+
tries = @retries
|
160
|
+
time = 3
|
161
|
+
|
149
162
|
hdrhash = headerprep(headers)
|
150
163
|
start_http(server,path,port,scheme,hdrhash)
|
151
164
|
request = Net::HTTP.const_get(method.to_s.capitalize).new(path,hdrhash)
|
@@ -169,11 +182,11 @@ class Connection
|
|
169
182
|
response
|
170
183
|
rescue Errno::EPIPE, Timeout::Error, Errno::EINVAL, EOFError
|
171
184
|
# Server closed the connection, retry
|
172
|
-
|
173
|
-
|
185
|
+
puts "Can't connect to the server: #{tries} tries to reconnect" if @is_debug
|
186
|
+
sleep time += 1
|
174
187
|
@http[server].finish if @http[server].started?
|
175
|
-
|
176
|
-
|
188
|
+
retry unless (tries -= 1) <= 0
|
189
|
+
raise OpenStack::Exception::Connection, "Unable to connect to #{server} after #{@retries} retries"
|
177
190
|
rescue OpenStack::Exception::ExpiredAuthToken
|
178
191
|
raise OpenStack::Exception::Connection, "Authentication token expired and you have requested not to retry" if @retry_auth == false
|
179
192
|
OpenStack::Authentication.init(self)
|
@@ -189,13 +202,10 @@ class Connection
|
|
189
202
|
headers = options[:headers] || {'content-type' => 'application/json'}
|
190
203
|
data = options[:data]
|
191
204
|
attempts = options[:attempts] || 0
|
192
|
-
path = @service_path + path
|
205
|
+
path = @service_path + @quantum_version.to_s + path
|
193
206
|
res = csreq(method,server,path,port,scheme,headers,data,attempts)
|
194
|
-
|
195
|
-
|
196
|
-
end
|
197
|
-
return res
|
198
|
-
end;
|
207
|
+
res.code.match(/^20.$/) ? (return res) : OpenStack::Exception.raise_exception(res)
|
208
|
+
end
|
199
209
|
|
200
210
|
private
|
201
211
|
|
@@ -205,13 +215,17 @@ class Connection
|
|
205
215
|
default_headers["X-Auth-Token"] = @authtoken if authok
|
206
216
|
default_headers["X-Storage-Token"] = @authtoken if authok
|
207
217
|
default_headers["Connection"] = "Keep-Alive"
|
208
|
-
default_headers["User-Agent"] = "OpenStack Ruby API #{VERSION}"
|
218
|
+
default_headers["User-Agent"] = "OpenStack Ruby API #{OpenStack::VERSION}"
|
209
219
|
default_headers["Accept"] = "application/json"
|
210
220
|
default_headers.merge(headers)
|
211
221
|
end
|
212
222
|
|
213
223
|
# Starts (or restarts) the HTTP connection
|
214
224
|
def start_http(server,path,port,scheme,headers) # :nodoc:
|
225
|
+
|
226
|
+
tries = @retries
|
227
|
+
time = 3
|
228
|
+
|
215
229
|
if (@http[server].nil?)
|
216
230
|
begin
|
217
231
|
@http[server] = Net::HTTP::Proxy(@proxy_host, @proxy_port).new(server,port)
|
@@ -221,6 +235,9 @@ class Connection
|
|
221
235
|
end
|
222
236
|
@http[server].start
|
223
237
|
rescue
|
238
|
+
puts "Can't connect to the server: #{tries} tries to reconnect" if @is_debug
|
239
|
+
sleep time += 1
|
240
|
+
retry unless (tries -= 1) <= 0
|
224
241
|
raise OpenStack::Exception::Connection, "Unable to connect to #{server}"
|
225
242
|
end
|
226
243
|
end
|
@@ -254,6 +271,10 @@ class AuthV20
|
|
254
271
|
attr_reader :uri
|
255
272
|
attr_reader :version
|
256
273
|
def initialize(connection)
|
274
|
+
|
275
|
+
tries = connection.retries
|
276
|
+
time = 3
|
277
|
+
|
257
278
|
begin
|
258
279
|
server = Net::HTTP::Proxy(connection.proxy_host, connection.proxy_port).new(connection.auth_host, connection.auth_port)
|
259
280
|
if connection.auth_scheme == "https"
|
@@ -262,7 +283,10 @@ class AuthV20
|
|
262
283
|
end
|
263
284
|
server.start
|
264
285
|
rescue
|
265
|
-
|
286
|
+
puts "Can't connect to the server: #{tries} tries to reconnect" if connection.is_debug
|
287
|
+
sleep time += 1
|
288
|
+
retry unless (tries -= 1) <= 0
|
289
|
+
raise OpenStack::Exception::Connection, "Unable to connect to #{server}"
|
266
290
|
end
|
267
291
|
|
268
292
|
@uri = String.new
|
@@ -347,6 +371,10 @@ end
|
|
347
371
|
class AuthV10
|
348
372
|
|
349
373
|
def initialize(connection)
|
374
|
+
|
375
|
+
tries = connection.retries
|
376
|
+
time = 3
|
377
|
+
|
350
378
|
hdrhash = { "X-Auth-User" => connection.authuser, "X-Auth-Key" => connection.authkey }
|
351
379
|
begin
|
352
380
|
server = Net::HTTP::Proxy(connection.proxy_host, connection.proxy_port).new(connection.auth_host, connection.auth_port)
|
@@ -356,9 +384,14 @@ class AuthV10
|
|
356
384
|
end
|
357
385
|
server.start
|
358
386
|
rescue
|
387
|
+
puts "Can't connect to the server: #{tries} tries to reconnect" if connection.is_debug
|
388
|
+
sleep time += 1
|
389
|
+
retry unless (tries -= 1) <= 0
|
359
390
|
raise OpenStack::Exception::Connection, "Unable to connect to #{server}"
|
360
391
|
end
|
392
|
+
|
361
393
|
response = server.get(connection.auth_path, hdrhash)
|
394
|
+
|
362
395
|
if (response.code =~ /^20./)
|
363
396
|
connection.authtoken = response["x-auth-token"]
|
364
397
|
case connection.service_type
|
@@ -31,8 +31,10 @@ module Network
|
|
31
31
|
end
|
32
32
|
alias :network :get_network
|
33
33
|
|
34
|
-
def create_network(name)
|
35
|
-
|
34
|
+
def create_network(name, parameter={})
|
35
|
+
body_hash = {"network" => {"name"=>name}}
|
36
|
+
body_hash['network'].merge! parameter
|
37
|
+
req_body = JSON.generate(body_hash)
|
36
38
|
response = @connection.req("POST", "/networks", {:data=>req_body})
|
37
39
|
OpenStack::Network::Network.new(JSON.parse(response.body)["network"])
|
38
40
|
end
|
@@ -94,6 +96,61 @@ module Network
|
|
94
96
|
true
|
95
97
|
end
|
96
98
|
|
99
|
+
def list_routers
|
100
|
+
response = @connection.req('GET', '/routers')
|
101
|
+
nets_hash = JSON.parse(response.body)['routers']
|
102
|
+
nets_hash.inject([]){|res, current| res << OpenStack::Network::Router.new(current); res}
|
103
|
+
end
|
104
|
+
alias :routers :list_routers
|
105
|
+
|
106
|
+
def create_router(name, admin_state_up, opts={})
|
107
|
+
body_hash = {'router'=> {'name' => name, 'admin_state_up' => admin_state_up}}
|
108
|
+
body_hash['router'].merge! opts
|
109
|
+
req_body = JSON.generate body_hash
|
110
|
+
response = @connection.req('POST', '/routers', {:data => req_body })
|
111
|
+
OpenStack::Network::Router.new(JSON.parse(response.body)['router'])
|
112
|
+
end
|
113
|
+
|
114
|
+
def delete_router_by_name(name)
|
115
|
+
@connection.req('DELETE', "/routers/#{get_router_id(name)}")
|
116
|
+
end
|
117
|
+
|
118
|
+
def delete_router(id)
|
119
|
+
@connection.req('DELETE', "/routers/#{id}")
|
120
|
+
end
|
121
|
+
|
122
|
+
def add_router_interface_by_name(name, interface)
|
123
|
+
@connection.req('PUT', "/routers/#{get_router_id(name)}/#{interface}")
|
124
|
+
end
|
125
|
+
|
126
|
+
def add_router_interface(id, subnet_id)
|
127
|
+
req_body = JSON.generate({'subnet_id' => subnet_id})
|
128
|
+
@connection.req('PUT', "/routers/#{id}/add_router_interface", {:data => req_body})
|
129
|
+
end
|
130
|
+
|
131
|
+
def remove_router_interface(id, subnet_id)
|
132
|
+
req_body = JSON.generate({'subnet_id' => subnet_id})
|
133
|
+
@connection.req('PUT', "/routers/#{id}/remove_router_interface", {:data => req_body})
|
134
|
+
end
|
135
|
+
|
136
|
+
def update_router_by_name(name,opts={})
|
137
|
+
req_body = JSON.generate opts
|
138
|
+
response = @connection.req('PUT',"/routers/#{get_router_id(name)}",{:data => req_body})
|
139
|
+
OpenStack::Network::Router.new(JSON.parse(response.body)['router'])
|
140
|
+
end
|
141
|
+
|
142
|
+
def update_router(id,opts={})
|
143
|
+
req_body = JSON.generate({'router' => opts})
|
144
|
+
response = @connection.req('PUT',"/routers/#{id}",{:data => req_body})
|
145
|
+
OpenStack::Network::Router.new(JSON.parse(response.body)['router'])
|
146
|
+
end
|
147
|
+
|
148
|
+
def get_router_id(name)
|
149
|
+
routers.detect do |value|
|
150
|
+
return value.id if value.name == name
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
97
154
|
end
|
98
155
|
|
99
156
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module OpenStack
|
2
|
+
module Network
|
3
|
+
class Router
|
4
|
+
|
5
|
+
attr_reader :id
|
6
|
+
attr_reader :name
|
7
|
+
attr_reader :admin_state_up
|
8
|
+
attr_reader :status
|
9
|
+
attr_reader :external_gateway_info
|
10
|
+
attr_reader :tenant_ip
|
11
|
+
attr_reader :enable_snat
|
12
|
+
attr_reader :admin_state_up
|
13
|
+
|
14
|
+
def initialize(router_info={})
|
15
|
+
@name = router_info['name']
|
16
|
+
@status = router_info['status']
|
17
|
+
@external_geteway_info = router_info['external_gateway_info']
|
18
|
+
@admin_state_up = router_info['admin_state_up']
|
19
|
+
@tenant_ip = router_info['tenant_ip']
|
20
|
+
@id = router_info['id']
|
21
|
+
@enable_snat = router_info['enable_snat']
|
22
|
+
# @admin_state_up = router_info['external_gateway_info']['admin_state_up']
|
23
|
+
# @network_id = router_info['external_gateway_info']['network_id']
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
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.1.
|
4
|
+
version: 1.1.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -28,6 +28,22 @@ dependencies:
|
|
28
28
|
- - ! '>='
|
29
29
|
- !ruby/object:Gem::Version
|
30
30
|
version: '0'
|
31
|
+
- !ruby/object:Gem::Dependency
|
32
|
+
name: rake
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
34
|
+
none: false
|
35
|
+
requirements:
|
36
|
+
- - ! '>='
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
39
|
+
type: :development
|
40
|
+
prerelease: false
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ! '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
31
47
|
- !ruby/object:Gem::Dependency
|
32
48
|
name: test-unit
|
33
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -71,7 +87,7 @@ extra_rdoc_files:
|
|
71
87
|
files:
|
72
88
|
- COPYING
|
73
89
|
- README.rdoc
|
74
|
-
-
|
90
|
+
- lib/openstack/version.rb
|
75
91
|
- lib/openstack.rb
|
76
92
|
- lib/openstack/compute/address.rb
|
77
93
|
- lib/openstack/compute/connection.rb
|
@@ -86,6 +102,7 @@ files:
|
|
86
102
|
- lib/openstack/network/network.rb
|
87
103
|
- lib/openstack/network/port.rb
|
88
104
|
- lib/openstack/network/subnet.rb
|
105
|
+
- lib/openstack/network/router.rb
|
89
106
|
- lib/openstack/swift/connection.rb
|
90
107
|
- lib/openstack/swift/container.rb
|
91
108
|
- lib/openstack/swift/storage_object.rb
|
data/VERSION
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
1.1.1
|