openstack_activeresource 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +11 -10
- data/Gemfile.lock +14 -13
- data/LICENSE.txt +1 -0
- data/README.rdoc +1 -1
- data/VERSION +1 -1
- data/lib/hot_fixes.rb +3 -1
- data/lib/open_stack/base.rb +2 -2
- data/lib/open_stack/keystone/admin.rb +0 -1
- data/lib/open_stack/keystone/admin/role.rb +5 -0
- data/lib/open_stack/keystone/admin/tenant.rb +3 -4
- data/lib/open_stack/keystone/admin/user.rb +26 -6
- data/lib/open_stack/keystone/public/auth.rb +4 -4
- data/lib/open_stack/keystone/public/tenant.rb +1 -2
- data/lib/open_stack/nova/compute/base.rb +2 -0
- data/lib/open_stack/nova/compute/base_detail.rb +1 -1
- data/lib/open_stack/nova/compute/flavor.rb +53 -8
- data/lib/open_stack/nova/compute/floating_ip.rb +1 -1
- data/lib/open_stack/nova/compute/key_pair.rb +1 -1
- data/lib/open_stack/nova/compute/security_group.rb +3 -3
- data/lib/open_stack/nova/compute/server.rb +1 -2
- data/lib/open_stack/nova/compute/simple_tenant_usage.rb +1 -1
- data/lib/open_stack/nova/compute/volume_attachment.rb +3 -4
- data/lib/open_stack/nova/volume/volume.rb +1 -1
- data/openstack_activeresource.gemspec +18 -19
- data/test/helper.rb +3 -1
- data/test/test_configuration-sample.yml +1 -0
- data/test/test_keystone_authentications.rb +1 -6
- data/test/test_keystone_tenants.rb +58 -7
- data/test/test_keystone_users_and_roles.rb +168 -0
- data/test/test_nova_flavors.rb +64 -6
- data/test/test_nova_floating_ips.rb +1 -6
- data/test/test_nova_images.rb +0 -5
- data/test/test_nova_keypairs.rb +0 -5
- data/test/test_nova_quota_sets.rb +0 -5
- data/test/test_nova_security_groups.rb +16 -5
- data/test/test_nova_servers.rb +0 -5
- data/test/test_simple_tenant_usages.rb +0 -5
- data/test/utils.rb +8 -0
- metadata +21 -22
- data/lib/open_stack/keystone/admin/user_role.rb +0 -45
- data/test/test_keystone_users.rb +0 -29
data/Gemfile
CHANGED
@@ -1,16 +1,17 @@
|
|
1
|
-
source
|
1
|
+
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
gem "activemodel", "~> 3.2.
|
4
|
-
gem "activeresource", "~> 3.2.
|
3
|
+
gem "activemodel", "~> 3.2.12", :require => 'active_model'
|
4
|
+
gem "activeresource", "~> 3.2.12", :require => 'active_resource'
|
5
5
|
|
6
6
|
gem "oj", "~> 1.2.9"
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
gem "
|
11
|
-
gem "
|
12
|
-
gem "
|
13
|
-
gem
|
8
|
+
group :development, :test do
|
9
|
+
gem "shoulda", ">= 0"
|
10
|
+
gem "rdoc", "~> 3.12"
|
11
|
+
gem "jeweler", "~> 1.8.4"
|
12
|
+
gem "simplecov", ">= 0"
|
13
|
+
gem 'test-unit'
|
14
|
+
end
|
14
15
|
|
15
16
|
# Security fixes
|
16
|
-
gem "json", "~> 1.7.7"
|
17
|
+
gem "json", "~> 1.7.7"
|
data/Gemfile.lock
CHANGED
@@ -1,20 +1,20 @@
|
|
1
1
|
GEM
|
2
|
-
remote:
|
2
|
+
remote: https://rubygems.org/
|
3
3
|
specs:
|
4
|
-
activemodel (3.2.
|
5
|
-
activesupport (= 3.2.
|
4
|
+
activemodel (3.2.12)
|
5
|
+
activesupport (= 3.2.12)
|
6
6
|
builder (~> 3.0.0)
|
7
|
-
activeresource (3.2.
|
8
|
-
activemodel (= 3.2.
|
9
|
-
activesupport (= 3.2.
|
10
|
-
activesupport (3.2.
|
7
|
+
activeresource (3.2.12)
|
8
|
+
activemodel (= 3.2.12)
|
9
|
+
activesupport (= 3.2.12)
|
10
|
+
activesupport (3.2.12)
|
11
11
|
i18n (~> 0.6)
|
12
12
|
multi_json (~> 1.0)
|
13
13
|
bourne (1.1.2)
|
14
14
|
mocha (= 0.10.5)
|
15
15
|
builder (3.0.4)
|
16
16
|
git (1.2.5)
|
17
|
-
i18n (0.6.
|
17
|
+
i18n (0.6.4)
|
18
18
|
jeweler (1.8.4)
|
19
19
|
bundler (~> 1.0)
|
20
20
|
git (>= 1.2.5)
|
@@ -24,10 +24,10 @@ GEM
|
|
24
24
|
metaclass (0.0.1)
|
25
25
|
mocha (0.10.5)
|
26
26
|
metaclass (~> 0.0.1)
|
27
|
-
multi_json (1.
|
27
|
+
multi_json (1.6.1)
|
28
28
|
oj (1.2.13)
|
29
29
|
rake (10.0.3)
|
30
|
-
rdoc (3.12)
|
30
|
+
rdoc (3.12.2)
|
31
31
|
json (~> 1.4)
|
32
32
|
shoulda (3.3.2)
|
33
33
|
shoulda-context (~> 1.0.1)
|
@@ -40,17 +40,18 @@ GEM
|
|
40
40
|
multi_json (~> 1.0)
|
41
41
|
simplecov-html (~> 0.7.1)
|
42
42
|
simplecov-html (0.7.1)
|
43
|
+
test-unit (2.5.4)
|
43
44
|
|
44
45
|
PLATFORMS
|
45
46
|
ruby
|
46
47
|
|
47
48
|
DEPENDENCIES
|
48
|
-
activemodel (~> 3.2.
|
49
|
-
activeresource (~> 3.2.
|
50
|
-
bundler (~> 1.2.0)
|
49
|
+
activemodel (~> 3.2.12)
|
50
|
+
activeresource (~> 3.2.12)
|
51
51
|
jeweler (~> 1.8.4)
|
52
52
|
json (~> 1.7.7)
|
53
53
|
oj (~> 1.2.9)
|
54
54
|
rdoc (~> 3.12)
|
55
55
|
shoulda
|
56
56
|
simplecov
|
57
|
+
test-unit
|
data/LICENSE.txt
CHANGED
data/README.rdoc
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.5.0
|
data/lib/hot_fixes.rb
CHANGED
@@ -17,7 +17,9 @@
|
|
17
17
|
|
18
18
|
# Reopens ActiveResource::Base to fix "ActiveResource nested resources not being persisted"
|
19
19
|
# See https://github.com/rails/rails/pull/3107
|
20
|
-
|
20
|
+
# and https://github.com/rails/activeresource/pull/30
|
21
|
+
# Fixes non yet included in any ActiveResource releases (as of 2013-02-28)
|
22
|
+
module ActiveResource # :nodoc:
|
21
23
|
class Base
|
22
24
|
|
23
25
|
def load(attributes, remove_root = false)
|
data/lib/open_stack/base.rb
CHANGED
@@ -68,10 +68,10 @@ class ActiveResource::ClientError < ActiveResource::ConnectionError
|
|
68
68
|
|
69
69
|
def message
|
70
70
|
decoded_error = decode_openstack_error
|
71
|
-
decoded_error.nil? ?
|
71
|
+
decoded_error.nil? ? @message : decoded_error
|
72
72
|
rescue Exception => e
|
73
73
|
# Fallback to the original method
|
74
|
-
|
74
|
+
@message
|
75
75
|
end
|
76
76
|
|
77
77
|
def to_s
|
@@ -30,6 +30,11 @@ module OpenStack
|
|
30
30
|
attribute :name, :string
|
31
31
|
end
|
32
32
|
|
33
|
+
validates :name,
|
34
|
+
:presence => true,
|
35
|
+
:length => {:minimum => 4, :allow_blank => true},
|
36
|
+
:format => {:with => /\A[0-9a-z_]+\Z/i, :allow_blank => true}
|
37
|
+
|
33
38
|
# List Roles with a given name
|
34
39
|
def self.find_by_name(name)
|
35
40
|
all.detect { |role| role.name == name }
|
@@ -34,21 +34,20 @@ module OpenStack
|
|
34
34
|
end
|
35
35
|
|
36
36
|
validates :enabled,
|
37
|
-
:
|
38
|
-
:inclusion => {:in => [true, false], :allow_blank => true}
|
37
|
+
:inclusion => {:in => [true, false]}
|
39
38
|
validates :name,
|
40
39
|
:presence => true,
|
41
40
|
:format => {:with => /\A\w[\w\s]+\w\Z/, :allow_blank => true}
|
42
41
|
validates :description,
|
43
42
|
:format => {:with => /\A[\w\s\.\-:@+,'"]+\Z/, :allow_blank => true}
|
44
43
|
|
45
|
-
def initialize(params = {}, persisted = false)
|
44
|
+
def initialize(params = {}, persisted = false) # :notnew:
|
46
45
|
super(params, persisted)
|
47
46
|
|
48
47
|
self.description = description
|
49
48
|
end
|
50
49
|
|
51
|
-
def self.find_every(options)
|
50
|
+
def self.find_every(options) # :nodoc:
|
52
51
|
class_name = self.name.split('::').last.downcase
|
53
52
|
begin
|
54
53
|
case from = options[:from]
|
@@ -42,17 +42,16 @@ module OpenStack
|
|
42
42
|
:length => {:minimum => 4, :allow_blank => true},
|
43
43
|
:format => {:with => /\A[0-9a-z_]+\Z/i, :allow_blank => true}
|
44
44
|
validates :password,
|
45
|
-
:presence => true,
|
45
|
+
:presence => { :with =>true, :on => :create },
|
46
46
|
:format => {:with => /(?=.*[\d\W])/, :message => :must_contain_at_least_one_digit_or_one_special_character, :allow_blank => true},
|
47
47
|
:length => {:minimum => 8, :allow_blank => true}
|
48
48
|
validates :email,
|
49
49
|
:presence => true,
|
50
50
|
:format => {:with => /\A[-a-z0-9_+\.]+\@([-a-z0-9]+\.)+[a-z0-9]{2,4}\Z/i, :allow_blank => true}
|
51
51
|
validates :enabled,
|
52
|
-
:
|
53
|
-
:inclusion => {:in => [true, false], :allow_blank => true}
|
52
|
+
:inclusion => {:in => [true, false]}
|
54
53
|
|
55
|
-
def initialize(attributes = {}, persisted = false)
|
54
|
+
def initialize(attributes = {}, persisted = false) # :notnew:
|
56
55
|
attributes = attributes.with_indifferent_access
|
57
56
|
|
58
57
|
if attributes[:tenant].present?
|
@@ -67,7 +66,7 @@ module OpenStack
|
|
67
66
|
end
|
68
67
|
|
69
68
|
# Overloads ActiveRecord::encode method
|
70
|
-
def encode(options={})
|
69
|
+
def encode(options={}) # :nodoc: Custom encoding to deal with openstack API
|
71
70
|
to_encode = {
|
72
71
|
:user => {
|
73
72
|
:name => name,
|
@@ -133,7 +132,28 @@ module OpenStack
|
|
133
132
|
def roles(scope = :all, tenant = nil)
|
134
133
|
tenant_id = tenant.is_a?(OpenStack::Keystone::Admin::Tenant) ? tenant.id : (tenant || self.tenant_id)
|
135
134
|
|
136
|
-
|
135
|
+
UserRole.find(scope, :params => {:tenant_id => tenant_id, :user_id => self.id})
|
136
|
+
end
|
137
|
+
|
138
|
+
# User Role ("admin view") (\*Warning:* incomplete)
|
139
|
+
#
|
140
|
+
# ==== Attributes
|
141
|
+
# * +name+ - The name of the Role
|
142
|
+
# * +description+ - A description of the role
|
143
|
+
class UserRole < Base
|
144
|
+
self.element_name = "role"
|
145
|
+
self.site = "#{superclass.site}/tenants/:tenant_id/users/:user_id"
|
146
|
+
|
147
|
+
schema do
|
148
|
+
attribute :name, :string
|
149
|
+
attribute :description, :string
|
150
|
+
end
|
151
|
+
|
152
|
+
# Return the associated instance of OpenStack::Keystone::Admin::Role
|
153
|
+
def role
|
154
|
+
OpenStack::Keystone::Admin::Role.find(self.id) if persisted?
|
155
|
+
end
|
156
|
+
|
137
157
|
end
|
138
158
|
|
139
159
|
end
|
@@ -36,7 +36,7 @@ module OpenStack
|
|
36
36
|
:presence => true,
|
37
37
|
:unless => Proc.new { token.present? }
|
38
38
|
|
39
|
-
def initialize(attributes = {}, persisted = false)
|
39
|
+
def initialize(attributes = {}, persisted = false) # :notnew:
|
40
40
|
attributes[:username] ||= ""
|
41
41
|
attributes[:password] ||= ""
|
42
42
|
|
@@ -50,7 +50,7 @@ module OpenStack
|
|
50
50
|
end
|
51
51
|
|
52
52
|
# Overloads ActiveRecord::encode method
|
53
|
-
def encode(options={})
|
53
|
+
def encode(options={}) # :nodoc: Custom encoding to deal with openstack API
|
54
54
|
to_encode = {}
|
55
55
|
if token.present?
|
56
56
|
to_encode[:auth] = {
|
@@ -72,7 +72,7 @@ module OpenStack
|
|
72
72
|
to_encode.send("to_#{self.class.format.extension}", options)
|
73
73
|
end
|
74
74
|
|
75
|
-
def save
|
75
|
+
def save # :nodoc: Catch some exceptions to perform "remote validation" of this resource
|
76
76
|
super
|
77
77
|
rescue ActiveResource::UnauthorizedAccess
|
78
78
|
errors.add :password, I18n.t(:is_invalid)
|
@@ -133,7 +133,7 @@ module OpenStack
|
|
133
133
|
attribute :expires, :string
|
134
134
|
end
|
135
135
|
|
136
|
-
def initialize(attributes = {}, persisted = false)
|
136
|
+
def initialize(attributes = {}, persisted = false) # :notnew:
|
137
137
|
attributes = attributes.with_indifferent_access
|
138
138
|
new_attributes = {
|
139
139
|
:id => attributes[:id],
|
@@ -31,10 +31,9 @@ module OpenStack
|
|
31
31
|
attribute :name, :string
|
32
32
|
attribute :description, :string
|
33
33
|
attribute :enabled, :boolean
|
34
|
-
|
35
34
|
end
|
36
35
|
|
37
|
-
def self.find_every(options)
|
36
|
+
def self.find_every(options) # :nodoc:
|
38
37
|
class_name = self.name.split('::').last.downcase
|
39
38
|
begin
|
40
39
|
case from = options[:from]
|
@@ -21,6 +21,8 @@ module OpenStack
|
|
21
21
|
|
22
22
|
class Base < OpenStack::Common
|
23
23
|
|
24
|
+
# The following 2 methods overloading are required for Rails applications
|
25
|
+
|
24
26
|
# Get the Nova Compute endpoint assigned to OpenStack::Nova::Compute classes
|
25
27
|
def self.site
|
26
28
|
if self == OpenStack::Nova::Compute::Base
|
@@ -25,18 +25,22 @@ module OpenStack
|
|
25
25
|
# * +name+ - The name of the flavor
|
26
26
|
# * +ram+ - Amount of RAM (MBytes)
|
27
27
|
# * +disk+ - Amount of storage (GBytes)
|
28
|
+
# * +swap+ - Amount of swap storage (MBytes)
|
28
29
|
# * +vcpus+ - Virtual CPUs
|
29
30
|
# * +rxtx_factor+ - Traffic shaping (?)
|
30
31
|
# * +ephemeral_disk+ - Ephemeral storage amount (GByte)
|
32
|
+
# * +is_public+ - True if the flavor is public
|
31
33
|
class Flavor < BaseDetail
|
32
34
|
|
33
35
|
schema do
|
34
36
|
attribute :name, :string
|
35
37
|
attribute :ram, :integer
|
36
38
|
attribute :disk, :integer
|
39
|
+
attribute :swap, :integer
|
37
40
|
attribute :vcpus, :integer
|
38
41
|
attribute :rxtx_factor, :float
|
39
42
|
attribute :ephemeral_disk, :integer
|
43
|
+
attribute :is_public, :boolean
|
40
44
|
end
|
41
45
|
|
42
46
|
validates :name,
|
@@ -52,9 +56,55 @@ module OpenStack
|
|
52
56
|
validates :disk,
|
53
57
|
:presence => true,
|
54
58
|
:numericality => {:greater_than_or_equal_to => 10, :only_integer => true, :allow_blank => true}
|
59
|
+
validates :swap,
|
60
|
+
:presence => true,
|
61
|
+
:numericality => {:greater_than_or_equal_to => 1, :only_integer => true, :allow_blank => true}
|
55
62
|
validates :ephemeral_disk,
|
56
|
-
:presence =>
|
57
|
-
:numericality => {:greater_than_or_equal_to =>
|
63
|
+
:presence => true,
|
64
|
+
:numericality => {:greater_than_or_equal_to => 0, :only_integer => true, :allow_blank => true}
|
65
|
+
validates :rxtx_factor,
|
66
|
+
:presence => true,
|
67
|
+
:numericality => {:only_integer => false, :allow_blank => true}
|
68
|
+
validates :is_public,
|
69
|
+
:inclusion => {:in => [true, false], :allow_blank => true}
|
70
|
+
|
71
|
+
def initialize(attributes = {}, persisted = false) # :notnew:
|
72
|
+
attributes = attributes.with_indifferent_access
|
73
|
+
new_attributes = {
|
74
|
+
:id => attributes[:id],
|
75
|
+
:name => attributes[:name],
|
76
|
+
:ram => attributes[:ram],
|
77
|
+
:disk => attributes[:disk],
|
78
|
+
:swap => attributes[:swap],
|
79
|
+
:vcpus => attributes[:vcpus],
|
80
|
+
:rxtx_factor => attributes[:rxtx_factor],
|
81
|
+
:ephemeral_disk => attributes[:'OS-FLV-EXT-DATA:ephemeral'] || attributes[:ephemeral_disk],
|
82
|
+
:is_public => attributes[:'os-flavor-access:is_public'] || attributes[:is_public]
|
83
|
+
}
|
84
|
+
super(new_attributes, persisted)
|
85
|
+
|
86
|
+
self
|
87
|
+
end
|
88
|
+
|
89
|
+
# Overloads ActiveRecord::encode method
|
90
|
+
def encode(options={}) # :nodoc: Custom encoding to deal with openstack API
|
91
|
+
to_encode = {
|
92
|
+
:flavor => {
|
93
|
+
:name => name,
|
94
|
+
:ram => ram,
|
95
|
+
:disk => disk,
|
96
|
+
:swap => swap,
|
97
|
+
:vcpus => vcpus
|
98
|
+
}
|
99
|
+
}
|
100
|
+
|
101
|
+
# Optional attributes (openstack will not accept empty attribute for update/create)
|
102
|
+
to_encode[:flavor][:'OS-FLV-EXT-DATA:ephemeral'] = ephemeral_disk if ephemeral_disk.present?
|
103
|
+
to_encode[:flavor][:'os-flavor-access:is_public'] = is_public if is_public.present?
|
104
|
+
to_encode[:flavor][:rxtx_factor] = rxtx_factor if rxtx_factor.present?
|
105
|
+
|
106
|
+
to_encode.send("to_#{self.class.format.extension}", options)
|
107
|
+
end
|
58
108
|
|
59
109
|
# Returns a list of Flavor for a given name
|
60
110
|
#
|
@@ -82,7 +132,7 @@ module OpenStack
|
|
82
132
|
constraints[:vcpus] ||= -1.0/0.0
|
83
133
|
constraints[:disk] ||= -1.0/0.0
|
84
134
|
|
85
|
-
all.select { |flavor| flavor.ram >= constraints[:ram] and flavor.vcpus >= constraints[:vcpus] and flavor.disk >= constraints[:disk] }
|
135
|
+
self.all.select { |flavor| flavor.ram >= constraints[:ram] and flavor.vcpus >= constraints[:vcpus] and flavor.disk >= constraints[:disk] }
|
86
136
|
end
|
87
137
|
|
88
138
|
# Returns a list of Flavor that can be used with the given Image
|
@@ -99,11 +149,6 @@ module OpenStack
|
|
99
149
|
find_by_constraints constraints
|
100
150
|
end
|
101
151
|
|
102
|
-
# Returns the amount of ephemeral disk
|
103
|
-
def ephemeral_disk
|
104
|
-
@attributes[:'OS-FLV-EXT-DATA:ephemeral'] || nil
|
105
|
-
end
|
106
|
-
|
107
152
|
# Returns a human-friendly description for this Flavor
|
108
153
|
def description
|
109
154
|
"#{vcpus} vCPU - #{ram} MB RAM - #{disk} GB Disk"
|
@@ -38,7 +38,7 @@ module OpenStack
|
|
38
38
|
end
|
39
39
|
|
40
40
|
# Overloads ActiveRecord::encode method
|
41
|
-
def encode(options={})
|
41
|
+
def encode(options={}) # :nodoc: Custom encoding to deal with openstack API
|
42
42
|
to_encode = {}
|
43
43
|
# Optional attributes (openstack will not accept empty attribute for update/create)
|
44
44
|
to_encode[:pool] = pool if pool.present?
|
@@ -50,7 +50,7 @@ module OpenStack
|
|
50
50
|
# * +to_port+ - Final port
|
51
51
|
# * +parent_group_id+ - The security group this rule belongs to
|
52
52
|
# * +cidr+ - A cidr
|
53
|
-
class
|
53
|
+
class Rule < Base
|
54
54
|
self.element_name = "security_group_rule"
|
55
55
|
self.collection_name = "os-security-group-rules"
|
56
56
|
|
@@ -76,7 +76,7 @@ module OpenStack
|
|
76
76
|
validates_numericality_of :to_port, :greater_than_or_equal_to => :from_port, :if => Proc.new { |rule| rule.udp? or rule.tcp? }
|
77
77
|
|
78
78
|
|
79
|
-
def initialize(attributes = {}, persisted = false)
|
79
|
+
def initialize(attributes = {}, persisted = false) # :notnew:
|
80
80
|
attributes = attributes.with_indifferent_access
|
81
81
|
new_attributes = {
|
82
82
|
:id => attributes[:id],
|
@@ -90,7 +90,7 @@ module OpenStack
|
|
90
90
|
end
|
91
91
|
|
92
92
|
# Override ActiveRecord::encode method
|
93
|
-
def encode(options={})
|
93
|
+
def encode(options={}) # :nodoc: Custom encoding to deal with openstack API
|
94
94
|
to_encode = {
|
95
95
|
:security_group_rule => {
|
96
96
|
:ip_protocol => ip_protocol,
|