deltacloud-core 1.1.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. data/Rakefile +10 -12
  2. data/config/drivers/{aruba.yaml → arubacloud.yaml} +2 -2
  3. data/deltacloud-core.gemspec +4 -4
  4. data/lib/cimi/collections/address_templates.rb +1 -1
  5. data/lib/cimi/collections/addresses.rb +2 -2
  6. data/lib/cimi/collections/base.rb +1 -0
  7. data/lib/cimi/collections/credentials.rb +1 -1
  8. data/lib/cimi/collections/forwarding_group_templates.rb +1 -1
  9. data/lib/cimi/collections/forwarding_groups.rb +1 -1
  10. data/lib/cimi/collections/machine_configurations.rb +1 -1
  11. data/lib/cimi/collections/machine_images.rb +1 -1
  12. data/lib/cimi/collections/machine_templates.rb +1 -1
  13. data/lib/cimi/collections/machines.rb +2 -2
  14. data/lib/cimi/collections/network_configurations.rb +1 -1
  15. data/lib/cimi/collections/network_port_configurations.rb +1 -1
  16. data/lib/cimi/collections/network_port_templates.rb +1 -1
  17. data/lib/cimi/collections/network_ports.rb +1 -1
  18. data/lib/cimi/collections/network_templates.rb +1 -1
  19. data/lib/cimi/collections/networks.rb +1 -1
  20. data/lib/cimi/collections/volume_configurations.rb +1 -1
  21. data/lib/cimi/collections/volume_images.rb +1 -1
  22. data/lib/cimi/collections/volume_templates.rb +1 -1
  23. data/lib/cimi/collections/volumes.rb +1 -1
  24. data/lib/cimi/helpers/database_helper.rb +16 -61
  25. data/lib/cimi/helpers/filter_helper.rb +41 -0
  26. data/lib/cimi/helpers/select_helper.rb +62 -0
  27. data/lib/cimi/models.rb +21 -2
  28. data/lib/cimi/models/address.rb +9 -7
  29. data/lib/cimi/models/address_template.rb +4 -4
  30. data/lib/cimi/models/base.rb +62 -197
  31. data/lib/cimi/models/collection.rb +78 -70
  32. data/lib/cimi/models/disk.rb +15 -8
  33. data/lib/cimi/models/machine.rb +27 -29
  34. data/lib/cimi/models/machine_image.rb +10 -13
  35. data/lib/cimi/models/machine_template.rb +3 -3
  36. data/lib/cimi/models/resource.rb +190 -0
  37. data/lib/cimi/models/schema.rb +9 -0
  38. data/lib/cimi/models/volume.rb +10 -13
  39. data/lib/cimi/models/volume_configuration.rb +3 -3
  40. data/lib/cimi/models/volume_template.rb +2 -2
  41. data/lib/cimi/server.rb +1 -0
  42. data/lib/db.rb +15 -0
  43. data/lib/db/address_template.rb +15 -0
  44. data/lib/db/entity.rb +55 -0
  45. data/lib/db/machine_template.rb +15 -0
  46. data/lib/db/provider.rb +40 -0
  47. data/lib/db/volume_configuration.rb +15 -0
  48. data/lib/db/volume_template.rb +15 -0
  49. data/lib/deltacloud/collections/base.rb +1 -0
  50. data/lib/deltacloud/collections/instances.rb +2 -1
  51. data/lib/deltacloud/collections/storage_snapshots.rb +3 -1
  52. data/lib/deltacloud/core_ext/array.rb +5 -0
  53. data/lib/deltacloud/drivers/{aruba/aruba_driver.rb → arubacloud/arubacloud_driver.rb} +3 -6
  54. data/lib/deltacloud/drivers/digitalocean/digitalocean_driver.rb +48 -75
  55. data/lib/deltacloud/drivers/ec2/ec2_driver.rb +18 -3
  56. data/lib/deltacloud/drivers/eucalyptus/eucalyptus_driver.rb +25 -0
  57. data/lib/deltacloud/drivers/fgcp/fgcp_client.rb +1 -1
  58. data/lib/deltacloud/drivers/fgcp/fgcp_driver.rb +34 -14
  59. data/lib/deltacloud/drivers/gogrid/gogrid_driver.rb +2 -0
  60. data/lib/deltacloud/drivers/mock/mock_driver.rb +3 -3
  61. data/lib/deltacloud/drivers/openstack/openstack_driver.rb +93 -33
  62. data/lib/deltacloud/drivers/rackspace/rackspace_driver.rb +2 -0
  63. data/lib/deltacloud/drivers/rhevm/rhevm_driver.rb +2 -2
  64. data/lib/deltacloud/helpers/deltacloud_helper.rb +3 -1
  65. data/lib/deltacloud/helpers/rabbit_helper.rb +1 -2
  66. data/lib/deltacloud/models/address.rb +1 -0
  67. data/lib/deltacloud/models/blob.rb +1 -0
  68. data/lib/deltacloud/models/bucket.rb +1 -0
  69. data/lib/deltacloud/models/firewall.rb +1 -0
  70. data/lib/deltacloud/models/hardware_profile.rb +3 -1
  71. data/lib/deltacloud/models/image.rb +7 -0
  72. data/lib/deltacloud/models/instance.rb +12 -3
  73. data/lib/deltacloud/models/key.rb +1 -0
  74. data/lib/deltacloud/models/load_balancer.rb +1 -0
  75. data/lib/deltacloud/models/metric.rb +1 -0
  76. data/lib/deltacloud/models/realm.rb +10 -1
  77. data/lib/deltacloud/models/storage_snapshot.rb +1 -0
  78. data/lib/deltacloud/models/storage_volume.rb +2 -1
  79. data/lib/deltacloud/runner.rb +2 -1
  80. data/lib/deltacloud/server.rb +1 -0
  81. data/lib/deltacloud/version.rb +1 -1
  82. data/lib/deltacloud_rack.rb +4 -0
  83. data/tests/cimi/collections/machines_test.rb +80 -0
  84. data/tests/cimi/db/database_helper_test.rb +54 -99
  85. data/tests/cimi/db/db_helper.rb +2 -0
  86. data/tests/cimi/db/entity_test.rb +29 -0
  87. data/tests/cimi/model/collection_spec.rb +2 -2
  88. data/tests/cimi/model/credential_spec.rb +2 -2
  89. data/tests/cimi/model/machine_configuration_spec.rb +2 -2
  90. data/tests/cimi/model/machine_image_spec.rb +2 -2
  91. data/tests/cimi/model/machine_spec.rb +4 -4
  92. data/tests/cimi/model/machine_template_spec.rb +2 -2
  93. data/tests/cimi/model/volume_configuration_spec.rb +2 -2
  94. data/tests/cimi/model/volume_image_spec.rb +2 -2
  95. data/tests/cimi/model/volume_spec.rb +2 -2
  96. data/tests/cimi/model/volume_template_spec.rb +2 -2
  97. data/tests/cimi/spec_helper.rb +4 -0
  98. data/tests/deltacloud/collections/instances_collection_test.rb +3 -1
  99. data/tests/deltacloud/launcher_test.rb +3 -5
  100. data/tests/drivers/ec2/images_test.rb +7 -0
  101. data/tests/drivers/gogrid/images_test.rb +7 -0
  102. data/tests/drivers/openstack/instances_test.rb +8 -8
  103. data/tests/drivers/openstack/realms_test.rb +13 -13
  104. data/views/errors/403.xml.haml +2 -1
  105. data/views/images/show.html.haml +4 -1
  106. data/views/images/show.xml.haml +1 -0
  107. data/views/instances/new.html.haml +1 -1
  108. data/views/instances/show.html.haml +3 -0
  109. data/views/realms/index.html.haml +2 -0
  110. data/views/realms/show.html.haml +4 -0
  111. data/views/realms/show.xml.haml +3 -0
  112. metadata +19 -14
@@ -13,8 +13,26 @@
13
13
  # License for the specific language governing permissions and limitations
14
14
  # under the License.
15
15
  #
16
+
16
17
  module CIMI
17
- module Model; end
18
+ module Model
19
+ def self.register_as_root_entity!(klass, opts = {})
20
+ @root_entities ||= [CIMI::Model::CloudEntryPoint]
21
+ @root_entities << klass
22
+ name = klass.name.split("::").last.pluralize
23
+ unless CIMI::Model::CloudEntryPoint.href_defined?(name)
24
+ params = {}
25
+ if opts[:as]
26
+ params[:xml_name] = params[:json_name] = opts[:as]
27
+ end
28
+ CIMI::Model::CloudEntryPoint.send(:href, name.underscore, params)
29
+ end
30
+ end
31
+
32
+ def self.root_entities
33
+ @root_entities || []
34
+ end
35
+ end
18
36
  end
19
37
 
20
38
  require 'require_relative' if RUBY_VERSION < '1.9'
@@ -31,8 +49,9 @@ unless Deltacloud.test_environment?
31
49
  end
32
50
 
33
51
  require_relative './models/schema'
34
- require_relative './models/base'
52
+ require_relative './models/resource'
35
53
  require_relative './models/collection'
54
+ require_relative './models/base'
36
55
  require_relative './models/errors'
37
56
  require_relative './models/action'
38
57
  require_relative './models/machine_volume'
@@ -65,23 +65,26 @@ class CIMI::Model::Address < CIMI::Model::Base
65
65
  params = {:name=>input["name"], :description=>input["description"], :address_template=>address_template, :env=>context }
66
66
  raise CIMI::Model::BadRequest.new("Bad request - missing required parameters. Client sent: #{request_body} which produced #{params.inspect}") if params.has_value?(nil)
67
67
  address = context.driver.create_address(context.credentials, params)
68
- store_attributes_for(address, input)
69
- from_address(address, context)
68
+ result = from_address(address, context)
69
+ result.name = input['name'] if input['name']
70
+ result.description = input['description'] if input['description']
71
+ result.extract_properties!(input)
72
+ result.save
73
+ result
70
74
  end
71
75
 
72
76
  def self.delete!(id, context)
73
77
  context.driver.delete_address(context.credentials, id)
74
- delete_attributes_for(::Address.new(:id => id))
78
+ new(:id => id).destroy
75
79
  end
76
80
 
77
81
  private
78
82
 
79
83
  def self.from_address(address, context)
80
- stored_attributes = load_attributes_for(address)
81
84
  self.new(
82
- :name => stored_attributes[:name] || address.id,
85
+ :name => address.id,
83
86
  :id => context.address_url(address.id),
84
- :description => stored_attributes[:description] || "Address #{address.id}",
87
+ :description => "Address #{address.id}",
85
88
  :ip => address.id,
86
89
  :allocation => "dynamic", #or "static"
87
90
  :default_gateway => "unknown", #wtf
@@ -89,7 +92,6 @@ class CIMI::Model::Address < CIMI::Model::Base
89
92
  :protocol => protocol_from_address(address.id),
90
93
  :mask => "unknown",
91
94
  :resource => (address.instance_id) ? {:href=> context.machine_url(address.instance_id)} : nil,
92
- :property => stored_attributes[:property],
93
95
  :network => nil #unknown
94
96
  #optional:
95
97
  #:hostname =>
@@ -42,7 +42,7 @@ class CIMI::Model::AddressTemplate < CIMI::Model::Base
42
42
  if context.driver.respond_to? :address_templates
43
43
  context.driver.address_templates(context.credentials, {:env=>context})
44
44
  else
45
- current_db.address_teplates.map { |t| from_db(t, context) }
45
+ current_db.address_templates.map { |t| from_db(t, context) }
46
46
  end
47
47
  else
48
48
  if context.driver.respond_to? :address_template
@@ -67,7 +67,7 @@ class CIMI::Model::AddressTemplate < CIMI::Model::Base
67
67
  :dns => json['dns'],
68
68
  :protocol => json['protocol'],
69
69
  :mask => json['mask'],
70
- :ent_properties => json['properties'].to_json
70
+ :ent_properties => json['properties'] ? json['properties'].to_json : {}
71
71
  )
72
72
  from_db(new_template, context)
73
73
  end
@@ -85,7 +85,7 @@ class CIMI::Model::AddressTemplate < CIMI::Model::Base
85
85
  :dns => xml['dns'].first,
86
86
  :protocol => xml['protocol'].nil? ? nil : xml['protocol'].first,
87
87
  :mask => xml['mask'].first,
88
- :ent_properties => JSON::dump(xml['property'].inject({}) { |r, p| r[p['key']]=p['content']; r })
88
+ :ent_properties => xml['property'] ? JSON::dump(xml['property'].inject({}) { |r, p| r[p['key']]=p['content']; r }) : {}
89
89
  )
90
90
  from_db(new_template, context)
91
91
  end
@@ -108,7 +108,7 @@ class CIMI::Model::AddressTemplate < CIMI::Model::Base
108
108
  :dns => model.dns,
109
109
  :protocol => model.protocol,
110
110
  :mask => model.mask,
111
- :property => JSON::parse(model.ent_properties),
111
+ :property => (model.ent_properties ? JSON::parse(model.ent_properties) : nil),
112
112
  :operations => [
113
113
  { :href => context.destroy_address_template_url(model.id), :rel => 'http://schemas.dmtf.org/cimi/1/action/delete' }
114
114
  ]
@@ -15,6 +15,8 @@
15
15
 
16
16
  require 'xmlsimple'
17
17
 
18
+ require_relative '../helpers/database_helper'
19
+
18
20
  # The base class for any CIMI object that we either read from a request or
19
21
  # write as a response. This class handles serializing/deserializing XML and
20
22
  # JSON into a common form.
@@ -61,7 +63,7 @@ require 'xmlsimple'
61
63
  # [struct(name, opts, &block)]
62
64
  # A structured subobject; the block defines the schema of the
63
65
  # subobject. The +:content+ option can be used to specify the attribute
64
- # that should receive the content of hte corresponding XML element
66
+ # that should receive the content of the corresponding XML element
65
67
  # [array(name, opts, &block)]
66
68
  # An array of structured subobjects; the block defines the schema of
67
69
  # the subobjects.
@@ -71,221 +73,84 @@ require 'xmlsimple'
71
73
 
72
74
  module CIMI::Model
73
75
 
74
- def self.register_as_root_entity!(klass, opts = {})
75
- @root_entities ||= [CIMI::Model::CloudEntryPoint]
76
- @root_entities << klass
77
- name = klass.name.split("::").last.pluralize
78
- unless CIMI::Model::CloudEntryPoint.href_defined?(name)
79
- params = {}
80
- if opts[:as]
81
- params[:xml_name] = params[:json_name] = opts[:as]
82
- end
83
- CIMI::Model::CloudEntryPoint.send(:href, name.underscore, params)
84
- end
85
- end
86
-
87
- def self.root_entities
88
- @root_entities || []
89
- end
90
-
91
- end
92
-
93
- class CIMI::Model::Resource
76
+ class Base < Resource
94
77
 
95
- #
96
- # We keep the values of the attributes in a hash
97
- #
98
- attr_reader :attribute_values
78
+ # Extend the base model with database methods
79
+ extend Deltacloud::Helpers::Database
99
80
 
100
- CMWG_NAMESPACE = "http://schemas.dmtf.org/cimi/1"
81
+ # Extend the base model with the collection handling methods
82
+ extend CIMI::Model::CollectionMethods
101
83
 
102
- # Keep the list of all attributes in an array +attributes+; for each
103
- # attribute, we also define a getter and a setter to access/change the
104
- # value for that attribute
105
- class << self
84
+ # Include methods needed to handle the $select query parameter
85
+ include CIMI::Helpers::SelectBaseMethods
86
+ #
87
+ # Common attributes for all resources
88
+ #
89
+ text :id, :name, :description, :created, :updated
90
+ hash :property
106
91
 
107
- def <<(model)
108
- clone_base_schema unless base_schema_cloned?
109
- member_name = model.name.split("::").last
110
- if ::Struct.const_defined?("CIMI_#{member_name}")
111
- ::Struct.send(:remove_const, "CIMI_#{member_name}")
112
- end
113
- member_symbol = member_name.underscore.pluralize.to_sym
114
- members = CIMI::Model::Schema::Array.new(member_symbol)
115
- members.struct.schema.attributes = model.schema.attributes
116
- base_schema.attributes << members
92
+ def initialize(values = {})
93
+ super(values)
94
+ retrieve_entity
117
95
  end
118
96
 
119
- def base_schema
120
- @schema ||= CIMI::Model::Schema.new
97
+ def []=(a, v)
98
+ v = super
99
+ retrieve_entity if a == :id
100
+ v
121
101
  end
122
102
 
123
- def clone_base_schema
124
- @schema_duped = true
125
- @schema = Marshal::load(Marshal.dump(superclass.base_schema))
103
+ # Save the common attributes name, description, and properties to the
104
+ # database
105
+ def save
106
+ if @entity
107
+ @entity.name = name
108
+ @entity.description = description
109
+ @entity.properties = property
110
+ @entity.save
111
+ end
112
+ self
126
113
  end
127
114
 
128
- def base_schema_cloned?
129
- @schema_duped
115
+ # Destroy the database attributes for this model
116
+ def destroy
117
+ @entity.destroy
118
+ self
130
119
  end
131
120
 
132
- private :clone_base_schema, :base_schema_cloned?
133
-
134
- def inherited(child)
135
- child.instance_eval do
136
- def schema
137
- base_schema_cloned? ? @schema : clone_base_schema
121
+ # FIXME: Kludge around the fact that we do not have proper *Create
122
+ # objects that deserialize properties by themselves
123
+ def extract_properties!(data)
124
+ h = {}
125
+ if data['property']
126
+ # Data came from XML
127
+ h = data['property'].inject({}) do |r,v|
128
+ r[v['key']] = v['content']
129
+ r
138
130
  end
131
+ elsif data['properties']
132
+ h = data['properties']
139
133
  end
134
+ property ||= {}
135
+ property.merge!(h)
140
136
  end
141
137
 
142
- def add_attributes!(names, attr_klass, &block)
143
- if self.respond_to? :schema
144
- schema.add_attributes!(names, attr_klass, &block)
138
+ private
139
+
140
+ # Load an existing database entity for this object, or create a new one
141
+ def retrieve_entity
142
+ if self.id
143
+ @entity = Deltacloud::Database::Entity::retrieve(self)
144
+ if @entity.exists?
145
+ self.name = @entity.name
146
+ self.description = @entity.description
147
+ self.property ||= {}
148
+ self.property.merge!(@entity.properties)
149
+ end
145
150
  else
146
- base_schema.add_attributes!(names, attr_klass, &block)
151
+ @entity = nil
147
152
  end
148
- names.each do |name|
149
- define_method(name) { self[name] }
150
- define_method(:"#{name}=") { |newval| self[name] = newval }
151
- end
152
- end
153
-
154
- # Return Array of links to current CIMI object
155
- def all_uri(context)
156
- self.all(context).map { |e| { :href => e.id } }
157
- end
158
- end
159
-
160
- extend CIMI::Model::Schema::DSL
161
-
162
- def [](a)
163
- @attribute_values[a]
164
- end
165
-
166
- def []=(a, v)
167
- @attribute_values[a] = self.class.schema.convert(a, v)
168
- end
169
-
170
- # Prepare to serialize
171
- def prepare
172
- self.class.schema.collections.map { |coll| coll.name }.each do |n|
173
- self[n].href = "#{self.id}/#{n}" unless self[n].href
174
- self[n].id = "#{self.id}/#{n}" if !self[n].entries.empty?
175
- end
176
- end
177
-
178
- #
179
- # Factory methods
180
- #
181
- def initialize(values = {})
182
- names = self.class.schema.attribute_names
183
- @attribute_values = names.inject(OrderedHash.new) do |hash, name|
184
- hash[name] = self.class.schema.convert(name, values[name])
185
- hash
186
153
  end
187
- end
188
-
189
- # Construct a new object from the XML representation +xml+
190
- def self.from_xml(text)
191
- xml = XmlSimple.xml_in(text, :force_content => true)
192
- model = self.new
193
- @schema.from_xml(xml, model)
194
- model
195
- end
196
154
 
197
- # Construct a new object
198
- def self.from_json(text)
199
- json = JSON::parse(text)
200
- model = self.new
201
- @schema.from_json(json, model)
202
- model
203
155
  end
204
-
205
- def self.parse(text, content_type)
206
- if content_type == "application/xml"
207
- from_xml(text)
208
- elsif content_type == "application/json"
209
- from_json(text)
210
- else
211
- raise "Can not parse content type #{content_type}"
212
- end
213
- end
214
-
215
- #
216
- # Serialize
217
- #
218
-
219
- def self.xml_tag_name
220
- self.name.split("::").last
221
- end
222
-
223
- def self.resource_uri
224
- CMWG_NAMESPACE + "/" + self.name.split("::").last
225
- end
226
-
227
- def self.to_json(model)
228
- json = @schema.to_json(model)
229
- json[:resourceURI] = resource_uri
230
- JSON::unparse(json)
231
- end
232
-
233
- def self.to_xml(model)
234
- xml = @schema.to_xml(model)
235
- xml["xmlns"] = CMWG_NAMESPACE
236
- xml["resourceURI"] = resource_uri
237
- XmlSimple.xml_out(xml, :root_name => xml_tag_name)
238
- end
239
-
240
- def to_json
241
- self.class.to_json(self)
242
- end
243
-
244
- def to_xml
245
- self.class.to_xml(self)
246
- end
247
-
248
- def filter_by(filter_opts)
249
- return self if filter_opts.nil?
250
- return filter_attributes(filter_opts.split(',').map{ |a| a.intern }) if filter_opts.include? ','
251
- case filter_opts
252
- when /^([\w\_]+)$/ then filter_attributes([$1.intern])
253
- when /^([\w\_]+)\[(\d+\-\d+)\]$/ then filter_by_arr_range($1.intern, $2)
254
- when /^([\w\_]+)\[(\d+)\]$/ then filter_by_arr_index($1.intern, $2)
255
- else self
256
- end
257
- end
258
-
259
- def filter_by_arr_index(attr, filter)
260
- return self unless self.respond_to?(attr)
261
- self.class.new(attr => [self.send(attr)[filter.to_i]])
262
- end
263
-
264
- def filter_by_arr_range(attr, filter)
265
- return self unless self.respond_to?(attr)
266
- filter = filter.split('-').inject { |s,e| s.to_i..e.to_i }
267
- self.class.new(attr => self.send(attr)[filter])
268
- end
269
- end
270
-
271
- require_relative '../helpers/database_helper'
272
-
273
- class CIMI::Model::Base < CIMI::Model::Resource
274
- extend Deltacloud::Helpers::Database
275
- #
276
- # Common attributes for all resources
277
- #
278
- text :id, :name, :description, :created
279
-
280
- hash :property
281
-
282
- def filter_attributes(attr_list)
283
- attrs = attr_list.inject({}) do |result, attr|
284
- attr = attr.to_s.underscore
285
- result[attr.to_sym] = self.send(attr) if self.respond_to?(attr)
286
- result
287
- end
288
- self.class.new(attrs)
289
- end
290
-
291
156
  end
@@ -13,22 +13,56 @@
13
13
  # License for the specific language governing permissions and limitations
14
14
  # under the License.
15
15
 
16
+
16
17
  module CIMI::Model
17
18
  class Collection < Resource
18
19
 
19
20
  class << self
20
21
  attr_accessor :entry_name, :embedded
22
+
23
+ def xml_tag_name
24
+ 'Collection'
25
+ end
26
+
27
+ def generate(model_class, opts = {})
28
+ model_name = model_class.name.split("::").last
29
+ scope = opts[:scope] || CIMI::Model
30
+ coll_class = Class.new(CIMI::Model::Collection)
31
+ scope.const_set(:"#{model_name}Collection", coll_class)
32
+ coll_class.entry_name = model_name.underscore.pluralize.to_sym
33
+ coll_class.embedded = opts[:embedded]
34
+ entry_schema = model_class.schema
35
+ coll_class.instance_eval do
36
+ text :id
37
+ scalar :href
38
+ text :count
39
+ scalar :href if opts[:embedded]
40
+ array self.entry_name, :schema => entry_schema, :xml_name => model_name
41
+ array :operations do
42
+ scalar :rel, :href
43
+ end
44
+ end
45
+ coll_class
46
+ end
47
+
21
48
  end
22
49
 
23
50
  # Make sure the base schema gets cloned
24
- self.schema
51
+ schema
25
52
 
53
+ # You can initialize collection by passing the Hash representation of the
54
+ # collection or passing another Collection object.
55
+ #
26
56
  def initialize(values = {})
27
- if values[:entries]
28
- values[self.class.entry_name] = values.delete(:entries)
57
+ if values.kind_of?(Hash)
58
+ if values[:entries]
59
+ values[self.class.entry_name] = values.delete(:entries)
60
+ end
61
+ values[self.class.entry_name] ||= []
62
+ super(values)
63
+ else
64
+ super
29
65
  end
30
- values[self.class.entry_name] ||= []
31
- super(values)
32
66
  end
33
67
 
34
68
  def entries
@@ -53,91 +87,65 @@ module CIMI::Model
53
87
  end
54
88
 
55
89
  def [](a)
56
- a = entry_name if a == :entries
90
+ a = self.class.entry_name if a == :entries
57
91
  super(a)
58
92
  end
59
93
 
60
94
  def []=(a, v)
61
- a = entry_name if a == :entries
95
+ a = self.class.entry_name if a == :entries
62
96
  super(a, v)
63
97
  end
64
98
 
65
- def filter_attributes(attr_list)
99
+ def select_attributes(attr_list)
66
100
  self[self.class.entry_name] = entries.map do |e|
67
- e.filter_attributes(attr_list)
101
+ e.select_attributes(attr_list)
68
102
  end
69
103
  self
70
104
  end
71
-
72
- def self.xml_tag_name
73
- "Collection"
74
- end
75
-
76
- def self.generate(model_class, opts = {})
77
- model_name = model_class.name.split("::").last
78
- scope = opts[:scope] || CIMI::Model
79
- coll_class = Class.new(CIMI::Model::Collection)
80
- scope.const_set(:"#{model_name}Collection", coll_class)
81
- coll_class.entry_name = model_name.underscore.pluralize.to_sym
82
- coll_class.embedded = opts[:embedded]
83
- entry_schema = model_class.schema
84
- coll_class.instance_eval do
85
- text :id
86
- scalar :href
87
- text :count
88
- scalar :href if opts[:embedded]
89
- array self.entry_name, :schema => entry_schema, :xml_name => model_name
90
- array :operations do
91
- scalar :rel, :href
92
- end
93
- end
94
- coll_class
95
- end
96
105
  end
97
106
 
98
- #
99
- # We need to reopen Base and add some stuff to avoid circular dependencies
100
- #
101
- class Base
102
- #
103
- # Toplevel collections
104
- #
107
+ module CollectionMethods
105
108
 
106
- class << self
109
+ def collection_class=(klass)
110
+ @collection_class = klass
111
+ end
107
112
 
108
- attr_accessor :collection_class
113
+ def collection_class
114
+ @collection_class
115
+ end
109
116
 
110
- def acts_as_root_entity(opts = {})
111
- self.collection_class = Collection.generate(self)
112
- CIMI::Model.register_as_root_entity! self, opts
113
- end
117
+ def acts_as_root_entity(opts = {})
118
+ self.collection_class = Collection.generate(self)
119
+ CIMI::Model.register_as_root_entity! self, opts
120
+ end
114
121
 
115
- # Return a collection of entities
116
- def list(context)
117
- entries = find(:all, context)
118
- desc = "#{self.name.split("::").last} Collection for the #{context.driver.name.capitalize} driver"
119
- acts_as_root_entity unless collection_class
120
- id = context.send("#{collection_class.entry_name}_url")
121
- ops = []
122
- cimi_entity = collection_class.entry_name.to_s.singularize
123
- cimi_create = "create_#{cimi_entity}_url"
124
- dcloud_create = context.deltacloud_create_method_for(cimi_entity)
125
- if(context.respond_to?(cimi_create) &&
126
- context.driver.respond_to?(dcloud_create)) ||
127
- provides?(cimi_entity)
128
- url = context.send(cimi_create)
129
- ops << { :rel => "add", :href => url }
130
- end
131
- collection_class.new(:id => id,
132
- :count => entries.size,
133
- :entries => entries,
134
- :operations => ops,
135
- :description => desc)
122
+ # Return a collection of entities
123
+ def list(context)
124
+ entries = find(:all, context)
125
+ desc = "#{self.name.split("::").last} Collection for the #{context.driver.name.capitalize} driver"
126
+ acts_as_root_entity unless collection_class
127
+ id = context.send("#{collection_class.entry_name}_url")
128
+ ops = []
129
+ cimi_entity = collection_class.entry_name.to_s.singularize
130
+ cimi_create = "create_#{cimi_entity}_url"
131
+ dcloud_create = context.deltacloud_create_method_for(cimi_entity)
132
+ if(context.respond_to?(cimi_create) &&
133
+ context.driver.respond_to?(dcloud_create)) ||
134
+ provides?(cimi_entity)
135
+ url = context.send(cimi_create)
136
+ ops << { :rel => "add", :href => url }
136
137
  end
138
+ collection_class.new(:id => id,
139
+ :count => entries.size,
140
+ :entries => entries,
141
+ :operations => ops,
142
+ :description => desc)
137
143
  end
138
144
 
139
- def self.all(context)
140
- find(:all, context)
145
+ def all(context)
146
+ find :all, context
141
147
  end
148
+
142
149
  end
150
+
143
151
  end