openstack_activeresource 0.4.0 → 0.5.0

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.
Files changed (41) hide show
  1. data/Gemfile +11 -10
  2. data/Gemfile.lock +14 -13
  3. data/LICENSE.txt +1 -0
  4. data/README.rdoc +1 -1
  5. data/VERSION +1 -1
  6. data/lib/hot_fixes.rb +3 -1
  7. data/lib/open_stack/base.rb +2 -2
  8. data/lib/open_stack/keystone/admin.rb +0 -1
  9. data/lib/open_stack/keystone/admin/role.rb +5 -0
  10. data/lib/open_stack/keystone/admin/tenant.rb +3 -4
  11. data/lib/open_stack/keystone/admin/user.rb +26 -6
  12. data/lib/open_stack/keystone/public/auth.rb +4 -4
  13. data/lib/open_stack/keystone/public/tenant.rb +1 -2
  14. data/lib/open_stack/nova/compute/base.rb +2 -0
  15. data/lib/open_stack/nova/compute/base_detail.rb +1 -1
  16. data/lib/open_stack/nova/compute/flavor.rb +53 -8
  17. data/lib/open_stack/nova/compute/floating_ip.rb +1 -1
  18. data/lib/open_stack/nova/compute/key_pair.rb +1 -1
  19. data/lib/open_stack/nova/compute/security_group.rb +3 -3
  20. data/lib/open_stack/nova/compute/server.rb +1 -2
  21. data/lib/open_stack/nova/compute/simple_tenant_usage.rb +1 -1
  22. data/lib/open_stack/nova/compute/volume_attachment.rb +3 -4
  23. data/lib/open_stack/nova/volume/volume.rb +1 -1
  24. data/openstack_activeresource.gemspec +18 -19
  25. data/test/helper.rb +3 -1
  26. data/test/test_configuration-sample.yml +1 -0
  27. data/test/test_keystone_authentications.rb +1 -6
  28. data/test/test_keystone_tenants.rb +58 -7
  29. data/test/test_keystone_users_and_roles.rb +168 -0
  30. data/test/test_nova_flavors.rb +64 -6
  31. data/test/test_nova_floating_ips.rb +1 -6
  32. data/test/test_nova_images.rb +0 -5
  33. data/test/test_nova_keypairs.rb +0 -5
  34. data/test/test_nova_quota_sets.rb +0 -5
  35. data/test/test_nova_security_groups.rb +16 -5
  36. data/test/test_nova_servers.rb +0 -5
  37. data/test/test_simple_tenant_usages.rb +0 -5
  38. data/test/utils.rb +8 -0
  39. metadata +21 -22
  40. data/lib/open_stack/keystone/admin/user_role.rb +0 -45
  41. data/test/test_keystone_users.rb +0 -29
data/Gemfile CHANGED
@@ -1,16 +1,17 @@
1
- source :rubygems
1
+ source 'https://rubygems.org'
2
2
 
3
- gem "activemodel", "~> 3.2.6", :require => 'active_model'
4
- gem "activeresource", "~> 3.2.6", :require => 'active_resource'
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
- gem "bundler", "~> 1.2.0"
9
-
10
- gem "shoulda", ">= 0"
11
- gem "rdoc", "~> 3.12"
12
- gem "jeweler", "~> 1.8.4"
13
- gem "simplecov", ">= 0"
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: http://rubygems.org/
2
+ remote: https://rubygems.org/
3
3
  specs:
4
- activemodel (3.2.9)
5
- activesupport (= 3.2.9)
4
+ activemodel (3.2.12)
5
+ activesupport (= 3.2.12)
6
6
  builder (~> 3.0.0)
7
- activeresource (3.2.9)
8
- activemodel (= 3.2.9)
9
- activesupport (= 3.2.9)
10
- activesupport (3.2.9)
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.1)
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.5.0)
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.6)
49
- activeresource (~> 3.2.6)
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
@@ -1,4 +1,5 @@
1
1
  OpenStack-ActiveResource
2
+ Copyright (c) 2013 Davide Guerri (@dguerri davide.guerri@gmail.com)
2
3
 
3
4
  This program is free software: you can redistribute it and/or modify
4
5
  it under the terms of the GNU General Public License as published by
data/README.rdoc CHANGED
@@ -17,7 +17,7 @@ Command line:
17
17
 
18
18
  Or in bundler Gemfile:
19
19
 
20
- gem "openstack_activeresource", "~> 0.3.2"
20
+ gem "openstack_activeresource", "~> 0.5.0"
21
21
 
22
22
  == Sample usages
23
23
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.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
- module ActiveResource #:nodoc:
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)
@@ -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? ? old_message : decoded_error
71
+ decoded_error.nil? ? @message : decoded_error
72
72
  rescue Exception => e
73
73
  # Fallback to the original method
74
- old_message
74
+ @message
75
75
  end
76
76
 
77
77
  def to_s
@@ -25,7 +25,6 @@ module OpenStack
25
25
  autoload :Role
26
26
  autoload :Tenant
27
27
  autoload :User
28
- autoload :UserRole
29
28
  end
30
29
 
31
30
  end
@@ -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
- :presence => true,
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) #:notnew:
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) #:nodoc:
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
- :presence => true,
53
- :inclusion => {:in => [true, false], :allow_blank => true}
52
+ :inclusion => {:in => [true, false]}
54
53
 
55
- def initialize(attributes = {}, persisted = false) #:notnew:
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={}) #:nodoc: Custom encoding to deal with openstack API
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
- OpenStack::Keystone::Admin::UserRole.find(scope, :params => {:tenant_id => tenant_id, :user_id => self.id})
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) #:notnew:
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={}) #:nodoc: Custom encoding to deal with openstack API
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 #:nodoc: Catch some exceptions to perform "remote validation" of this resource
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) #:notnew:
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) #:nodoc:
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
@@ -19,7 +19,7 @@ module OpenStack
19
19
  module Nova
20
20
  module Compute
21
21
 
22
- class BaseDetail < Base #:nodoc:
22
+ class BaseDetail < Base # :nodoc:
23
23
 
24
24
  # Overrides ActiveResource::Base::collection_path to add /details to resource path for servers and
25
25
  # to remove .<extension>
@@ -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 => false,
57
- :numericality => {:greater_than_or_equal_to => 10, :only_integer => true}
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={}) #:nodoc: Custom encoding to deal with openstack API
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?
@@ -37,7 +37,7 @@ module OpenStack
37
37
  attribute :fingerprint, :string
38
38
  end
39
39
 
40
- def id #:nodoc:
40
+ def id # :nodoc:
41
41
  name
42
42
  end
43
43
 
@@ -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 SecurityGroup::Rule < Base
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) #:notnew:
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={}) #:nodoc: Custom encoding to deal with openstack API
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,