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.
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,