openstack 1.0.1 → 1.0.2
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 +38 -2
- data/VERSION +1 -1
- data/lib/openstack/compute/address.rb +29 -0
- data/lib/openstack/compute/connection.rb +81 -7
- data/lib/openstack/compute/server.rb +4 -1
- metadata +35 -51
data/README.rdoc
CHANGED
@@ -93,11 +93,12 @@ See the class definitions for documentation on specific methods and operations.
|
|
93
93
|
>> newserver.progress
|
94
94
|
=> 12
|
95
95
|
|
96
|
-
# Create a new server and specify the keyname to be used (
|
97
|
-
>> server = os.create_server({:imageRef=>14075, :flavorRef=>100, :key_name=>"my_default_key", :name=>"marios_server"})
|
96
|
+
# Create a new server and specify the keyname and security_groups to be used (dependent on provider support for these API extensions):
|
97
|
+
>> server = os.create_server({:imageRef=>14075, :flavorRef=>100, :key_name=>"my_default_key", :security_groups=>["test", "default"], :name=>"marios_server"})
|
98
98
|
=> #<OpenStack::Compute::Server:0x101433f08 ....
|
99
99
|
>> server.key_name
|
100
100
|
=> "my_default_key"
|
101
|
+
>> server.security_groups
|
101
102
|
|
102
103
|
# Delete the new server
|
103
104
|
>> newserver.delete!
|
@@ -143,6 +144,41 @@ See the class definitions for documentation on specific methods and operations.
|
|
143
144
|
>> os.delete_keypair("test_key_imported")
|
144
145
|
=> true
|
145
146
|
|
147
|
+
# List all security groups:
|
148
|
+
>> os.security_groups
|
149
|
+
=> { "1381" => { :tenant_id=>"12345678909876", :id=>1381, :name=>"default", :description=>"default",
|
150
|
+
:rules=> [
|
151
|
+
{:from_port=>22, :group=>{}, :ip_protocol=>"tcp", :to_port=>22,
|
152
|
+
:parent_group_id=>1381, :ip_range=>{:cidr=>"0.0.0.0/0"}, :id=>4902},
|
153
|
+
]
|
154
|
+
},
|
155
|
+
"1234" => { ... } }
|
156
|
+
|
157
|
+
# Get a specific security group:
|
158
|
+
>> os.security_group(1381)
|
159
|
+
=> { "1381" => { :tenant_id=>"12345678909876", :id=>1381, :name=>"default", :description=>"default",
|
160
|
+
:rules=> [
|
161
|
+
{:from_port=>22, :group=>{}, :ip_protocol=>"tcp", :to_port=>22,
|
162
|
+
:parent_group_id=>1381, :ip_range=>{:cidr=>"0.0.0.0/0"}, :id=>4902},
|
163
|
+
]
|
164
|
+
}}
|
165
|
+
|
166
|
+
#Create a new security group:
|
167
|
+
>> os.create_security_group("devel_group", "all development machines")
|
168
|
+
=> {"9573"=>{:rules=>[], :tenant_id=>"46871569847393", :id=>9573, :name=>"devel_group", :description=>"all development machines"}}
|
169
|
+
|
170
|
+
#Create a new security group rule - first param is id of the security group for this rule. Instead of :cidr you may specify :group_id to use another group as source:
|
171
|
+
>> os.create_security_group_rule(9567, {:ip_protocol=>"tcp", :from_port=>"123", :to_port=>"123", :cidr=>"192.168.0.1/16" })
|
172
|
+
=> => {"27375"=>{:from_port=>123, :group=>{}, :ip_protocol=>"tcp", :to_port=>123, :parent_group_id=>9573, :ip_range=>{:cidr=>"192.168.0.1/16"}, :id=>27375}}
|
173
|
+
|
174
|
+
#Delete a security group rule:
|
175
|
+
>> os.delete_security_group_rule(27375)
|
176
|
+
=> true
|
177
|
+
|
178
|
+
#Delete a security group:
|
179
|
+
>> os.delete_security_group(9571)
|
180
|
+
=> true
|
181
|
+
|
146
182
|
== Examples for Object-Store:
|
147
183
|
|
148
184
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.0.2
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'ipaddr'
|
1
2
|
module OpenStack
|
2
3
|
module Compute
|
3
4
|
|
@@ -33,6 +34,34 @@ module Compute
|
|
33
34
|
@version = version
|
34
35
|
end
|
35
36
|
end
|
37
|
+
|
38
|
+
NON_ROUTABLE_ADDRESSES = [IPAddr.new("10.0.0.0/8"), IPAddr.new("192.168.0.0/16"), IPAddr.new("172.16.0.0/12")]
|
39
|
+
|
40
|
+
def self.is_private?(address_string)
|
41
|
+
NON_ROUTABLE_ADDRESSES.each do |no_route|
|
42
|
+
return true if no_route.include?(address_string)
|
43
|
+
end
|
44
|
+
false
|
45
|
+
end
|
46
|
+
|
47
|
+
#IN: { "private"=> [{"addr"=>"10.7.206.171", "version"=>4}, {"addr"=>"15.185.160.208", "version"=>4}]}
|
48
|
+
#OUT: { "private"=> [{"addr"=>"10.7.206.171", "version"=>4}],
|
49
|
+
# "public"=> [{"addr"=>"15.185.160.208", "version"=>4}] }
|
50
|
+
def self.fix_labels(addresses_info)
|
51
|
+
addresses_info.inject({"public"=>[], "private"=>[]}) do |res, (label,address_struct_list)|
|
52
|
+
address_struct_list.each do |address_struct|
|
53
|
+
if(address_struct["version"==6])#v6 addresses are all routable...
|
54
|
+
res["public"] << address_struct
|
55
|
+
else
|
56
|
+
is_private?(address_struct["addr"])? res["private"] << address_struct : res["public"] << address_struct
|
57
|
+
end
|
58
|
+
end
|
59
|
+
res
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
|
36
65
|
end
|
37
66
|
|
38
67
|
end
|
@@ -4,8 +4,10 @@ module Compute
|
|
4
4
|
class Connection
|
5
5
|
|
6
6
|
attr_accessor :connection
|
7
|
+
attr_accessor :extensions
|
7
8
|
|
8
9
|
def initialize(connection)
|
10
|
+
@extensions = nil
|
9
11
|
@connection = connection
|
10
12
|
OpenStack::Authentication.init(@connection)
|
11
13
|
end
|
@@ -63,14 +65,19 @@ module Compute
|
|
63
65
|
path = OpenStack.paginate(options).empty? ? "#{@connection.service_path}/servers/detail" : "#{@connection.service_path}/servers/detail?#{OpenStack.paginate(options)}"
|
64
66
|
response = @connection.csreq("GET",@connection.service_host,path,@connection.service_port,@connection.service_scheme)
|
65
67
|
OpenStack::Exception.raise_exception(response) unless response.code.match(/^20.$/)
|
66
|
-
|
68
|
+
json_server_list = JSON.parse(response.body)["servers"]
|
69
|
+
json_server_list.each do |server|
|
70
|
+
server["addresses"] = OpenStack::Compute::Address.fix_labels(server["addresses"])
|
71
|
+
end
|
72
|
+
OpenStack.symbolize_keys(json_server_list)
|
67
73
|
end
|
68
74
|
alias :servers_detail :list_servers_detail
|
69
75
|
|
70
76
|
# Creates a new server instance on OpenStack Compute
|
71
77
|
#
|
72
78
|
# The argument is a hash of options. The keys :name, :flavorRef,
|
73
|
-
# and :imageRef are required; :metadata
|
79
|
+
# and :imageRef are required; :metadata, :security_groups,
|
80
|
+
# :key_name and :personality are optional.
|
74
81
|
#
|
75
82
|
# :flavorRef and :imageRef are href strings identifying a particular
|
76
83
|
# server flavor and image to use when building the server. The :imageRef
|
@@ -94,7 +101,9 @@ module Compute
|
|
94
101
|
# :imageRef => '3',
|
95
102
|
# :flavorRef => '1',
|
96
103
|
# :metadata => {'Racker' => 'Fanatical'},
|
97
|
-
# :personality => {'/home/bob/wedding.jpg' => '/root/wedding.jpg'}
|
104
|
+
# :personality => {'/home/bob/wedding.jpg' => '/root/wedding.jpg'},
|
105
|
+
# :key_name => "mykey",
|
106
|
+
# :security_groups => [ "devel", "test"])
|
98
107
|
# => #<OpenStack::Compute::Server:0x101229eb0 ...>
|
99
108
|
# >> server.name
|
100
109
|
# => "NewServer"
|
@@ -105,6 +114,7 @@ module Compute
|
|
105
114
|
def create_server(options)
|
106
115
|
raise OpenStack::Exception::MissingArgument, "Server name, flavorRef, and imageRef, must be supplied" unless (options[:name] && options[:flavorRef] && options[:imageRef])
|
107
116
|
options[:personality] = Personalities.get_personality(options[:personality])
|
117
|
+
options[:security_groups] = (options[:security_groups] || []).inject([]){|res, c| res << {"name"=>c} ;res}
|
108
118
|
data = JSON.generate(:server => options)
|
109
119
|
response = @connection.csreq("POST",@connection.service_host,"#{@connection.service_path}/servers",@connection.service_port,@connection.service_scheme,{'content-type' => 'application/json'},data)
|
110
120
|
OpenStack::Exception.raise_exception(response) unless response.code.match(/^20.$/)
|
@@ -228,10 +238,13 @@ module Compute
|
|
228
238
|
# }
|
229
239
|
#
|
230
240
|
def api_extensions
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
241
|
+
if @extensions.nil?
|
242
|
+
response = @connection.req("GET", "/extensions")
|
243
|
+
OpenStack::Exception.raise_exception(response) unless response.code.match(/^20.$/)
|
244
|
+
res = OpenStack.symbolize_keys(JSON.parse(response.body))
|
245
|
+
@extensions = res[:extensions].inject({}){|result, c| result[c[:alias].to_sym] = c ; result}
|
246
|
+
end
|
247
|
+
@extensions
|
235
248
|
end
|
236
249
|
|
237
250
|
# Retrieve a list of key pairs associated with the current authenticated account
|
@@ -313,6 +326,67 @@ module Compute
|
|
313
326
|
true
|
314
327
|
end
|
315
328
|
|
329
|
+
#Security Groups:
|
330
|
+
#Returns a hash with the security group IDs as keys:
|
331
|
+
#=> { "1381" => { :tenant_id=>"12345678909876", :id=>1381, :name=>"default", :description=>"default",
|
332
|
+
# :rules=> [
|
333
|
+
# {:from_port=>22, :group=>{}, :ip_protocol=>"tcp", :to_port=>22,
|
334
|
+
# :parent_group_id=>1381, :ip_range=>{:cidr=>"0.0.0.0/0"}, :id=>4902},
|
335
|
+
# {:from_port=>80, :group=>{}, :ip_protocol=>"tcp", :to_port=>80,
|
336
|
+
# :parent_group_id=>1381, :ip_range=>{:cidr=>"0.0.0.0/0"}, :id=>4903},
|
337
|
+
# {:from_port=>443, :group=>{}, :ip_protocol=>"tcp", :to_port=>443,
|
338
|
+
# :parent_group_id=>1381, :ip_range=>{:cidr=>"0.0.0.0/0"}, :id=>4904},
|
339
|
+
# {:from_port=>-1, :group=>{}, :ip_protocol=>"icmp", :to_port=>-1,
|
340
|
+
# :parent_group_id=>1381, :ip_range=>{:cidr=>"0.0.0.0/0"}, :id=>4905}],
|
341
|
+
# ]
|
342
|
+
# },
|
343
|
+
# "1234" => { ... } }
|
344
|
+
#
|
345
|
+
def security_groups
|
346
|
+
raise OpenStack::Exception::NotImplemented.new("os-security-groups not implemented by #{@connection.http.keys.first}", 501, "NOT IMPLEMENTED") unless api_extensions[:"os-security-groups"] or api_extensions[:security_groups]
|
347
|
+
response = @connection.req("GET", "/os-security-groups")
|
348
|
+
res = OpenStack.symbolize_keys(JSON.parse(response.body))
|
349
|
+
res[:security_groups].inject({}){|result, c| result[c[:id].to_s] = c ; result }
|
350
|
+
end
|
351
|
+
|
352
|
+
def security_group(id)
|
353
|
+
raise OpenStack::Exception::NotImplemented.new("os-security-groups not implemented by #{@connection.http.keys.first}", 501, "NOT IMPLEMENTED") unless api_extensions[:"os-security-groups"] or api_extensions[:security_groups]
|
354
|
+
response = @connection.req("GET", "/os-security-groups/#{id}")
|
355
|
+
res = OpenStack.symbolize_keys(JSON.parse(response.body))
|
356
|
+
{res[:security_group][:id].to_s => res[:security_group]}
|
357
|
+
end
|
358
|
+
|
359
|
+
def create_security_group(name, description)
|
360
|
+
raise OpenStack::Exception::NotImplemented.new("os-security-groups not implemented by #{@connection.http.keys.first}", 501, "NOT IMPLEMENTED") unless api_extensions[:"os-security-groups"] or api_extensions[:security_groups]
|
361
|
+
data = JSON.generate(:security_group => { "name" => name, "description" => description})
|
362
|
+
response = @connection.req("POST", "/os-security-groups", {:data => data})
|
363
|
+
res = OpenStack.symbolize_keys(JSON.parse(response.body))
|
364
|
+
{res[:security_group][:id].to_s => res[:security_group]}
|
365
|
+
end
|
366
|
+
|
367
|
+
def delete_security_group(id)
|
368
|
+
raise OpenStack::Exception::NotImplemented.new("os-security-groups not implemented by #{@connection.http.keys.first}", 501, "NOT IMPLEMENTED") unless api_extensions[:"os-security-groups"] or api_extensions[:security_groups]
|
369
|
+
response = @connection.req("DELETE", "/os-security-groups/#{id}")
|
370
|
+
true
|
371
|
+
end
|
372
|
+
|
373
|
+
#params: { :ip_protocol=>"tcp", :from_port=>"123", :to_port=>"123", :cidr=>"192.168.0.1/16", :group_id:="123" }
|
374
|
+
#observed behaviour against Openstack@HP cloud - can specify either cidr OR group_id as source, but not both
|
375
|
+
#if both specified, the group is used and the cidr ignored.
|
376
|
+
def create_security_group_rule(security_group_id, params)
|
377
|
+
raise OpenStack::Exception::NotImplemented.new("os-security-groups not implemented by #{@connection.http.keys.first}", 501, "NOT IMPLEMENTED") unless api_extensions[:"os-security-groups"] or api_extensions[:security_groups]
|
378
|
+
params.merge!({:parent_group_id=>security_group_id.to_s})
|
379
|
+
data = JSON.generate(:security_group_rule => params)
|
380
|
+
response = @connection.req("POST", "/os-security-group-rules", {:data => data})
|
381
|
+
res = OpenStack.symbolize_keys(JSON.parse(response.body))
|
382
|
+
{res[:security_group_rule][:id].to_s => res[:security_group_rule]}
|
383
|
+
end
|
384
|
+
|
385
|
+
def delete_security_group_rule(id)
|
386
|
+
raise OpenStack::Exception::NotImplemented.new("os-security-groups not implemented by #{@connection.http.keys.first}", 501, "NOT IMPLEMENTED") unless api_extensions[:"os-security-groups"] or api_extensions[:security_groups]
|
387
|
+
response = @connection.req("DELETE", "/os-security-group-rules/#{id}")
|
388
|
+
true
|
389
|
+
end
|
316
390
|
end
|
317
391
|
end
|
318
392
|
end
|
@@ -17,6 +17,7 @@ module Compute
|
|
17
17
|
attr_reader :metadata
|
18
18
|
attr_accessor :adminPass
|
19
19
|
attr_reader :key_name
|
20
|
+
attr_reader :security_groups
|
20
21
|
|
21
22
|
# This class is the representation of a single Server object. The constructor finds the server identified by the specified
|
22
23
|
# ID number, accesses the API via the populate method to get information about that server, and returns the object.
|
@@ -53,7 +54,7 @@ module Compute
|
|
53
54
|
OpenStack::Exception.raise_exception(response) unless response.code.match(/^20.$/)
|
54
55
|
data = JSON.parse(response.body)["server"]
|
55
56
|
end
|
56
|
-
@id = data["
|
57
|
+
@id = data["uuid"]
|
57
58
|
@name = data["name"]
|
58
59
|
@status = data["status"]
|
59
60
|
@progress = data["progress"]
|
@@ -63,6 +64,7 @@ module Compute
|
|
63
64
|
@image = data["image"]
|
64
65
|
@flavor = data["flavor"]
|
65
66
|
@key_name = data["key_name"] # if provider uses the keys API extension for accessing servers
|
67
|
+
@security_groups = data["security_groups"].inject([]){|res, c| res << c["id"] ; res}
|
66
68
|
true
|
67
69
|
end
|
68
70
|
alias :refresh :populate
|
@@ -234,6 +236,7 @@ module Compute
|
|
234
236
|
end
|
235
237
|
|
236
238
|
def get_addresses(address_info)
|
239
|
+
address_info = OpenStack::Compute::Address.fix_labels(address_info)
|
237
240
|
address_list = OpenStack::Compute::AddressList.new
|
238
241
|
address_info.each do |label, addr|
|
239
242
|
addr.each do |address|
|
metadata
CHANGED
@@ -1,48 +1,42 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: openstack
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.2
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 1
|
8
|
-
- 0
|
9
|
-
- 1
|
10
|
-
version: 1.0.1
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Dan Prince
|
14
9
|
- Marios Andreou
|
15
10
|
autorequire:
|
16
11
|
bindir: bin
|
17
12
|
cert_chain: []
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
- !ruby/object:Gem::Dependency
|
13
|
+
date: 2012-08-24 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
22
16
|
name: json
|
23
|
-
|
24
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
25
18
|
none: false
|
26
|
-
requirements:
|
27
|
-
- -
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
|
30
|
-
segments:
|
31
|
-
- 0
|
32
|
-
version: "0"
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0'
|
33
23
|
type: :runtime
|
34
|
-
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ! '>='
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: '0'
|
35
31
|
description: API Binding for OpenStack
|
36
|
-
email:
|
32
|
+
email:
|
37
33
|
- dprince@redhat.com
|
38
34
|
- marios@redhat.com
|
39
35
|
executables: []
|
40
|
-
|
41
36
|
extensions: []
|
42
|
-
|
43
|
-
extra_rdoc_files:
|
37
|
+
extra_rdoc_files:
|
44
38
|
- README.rdoc
|
45
|
-
files:
|
39
|
+
files:
|
46
40
|
- COPYING
|
47
41
|
- README.rdoc
|
48
42
|
- VERSION
|
@@ -60,37 +54,27 @@ files:
|
|
60
54
|
- lib/openstack/swift/storage_object.rb
|
61
55
|
homepage: https://github.com/ruby-openstack/ruby-openstack
|
62
56
|
licenses: []
|
63
|
-
|
64
57
|
post_install_message:
|
65
58
|
rdoc_options: []
|
66
|
-
|
67
|
-
require_paths:
|
59
|
+
require_paths:
|
68
60
|
- lib
|
69
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
61
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
70
62
|
none: false
|
71
|
-
requirements:
|
72
|
-
- -
|
73
|
-
- !ruby/object:Gem::Version
|
74
|
-
|
75
|
-
|
76
|
-
- 0
|
77
|
-
version: "0"
|
78
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ! '>='
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
79
68
|
none: false
|
80
|
-
requirements:
|
81
|
-
- -
|
82
|
-
- !ruby/object:Gem::Version
|
83
|
-
|
84
|
-
segments:
|
85
|
-
- 0
|
86
|
-
version: "0"
|
69
|
+
requirements:
|
70
|
+
- - ! '>='
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '0'
|
87
73
|
requirements: []
|
88
|
-
|
89
74
|
rubyforge_project:
|
90
|
-
rubygems_version: 1.
|
75
|
+
rubygems_version: 1.8.24
|
91
76
|
signing_key:
|
92
77
|
specification_version: 3
|
93
78
|
summary: OpenStack Ruby API
|
94
79
|
test_files: []
|
95
|
-
|
96
|
-
has_rdoc: false
|
80
|
+
has_rdoc:
|