deltacloud-core 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (166) hide show
  1. data/Rakefile +63 -7
  2. data/bin/deltacloudd +29 -17
  3. data/config.ru +5 -3
  4. data/config/drivers/ec2.yaml +9 -0
  5. data/config/drivers/google.yaml +3 -0
  6. data/config/drivers/openstack.yaml +3 -0
  7. data/deltacloud-core.gemspec +1 -1
  8. data/lib/cimi/dependencies.rb +62 -0
  9. data/lib/cimi/helpers/cimi_helper.rb +50 -0
  10. data/lib/cimi/model.rb +52 -0
  11. data/lib/cimi/model/action.rb +24 -0
  12. data/lib/cimi/model/base.rb +249 -0
  13. data/lib/cimi/model/cloud_entry_point.rb +48 -0
  14. data/lib/cimi/model/entity_metadata.rb +83 -0
  15. data/lib/cimi/model/entity_metadata_collection.rb +31 -0
  16. data/lib/cimi/model/errors.rb +40 -0
  17. data/lib/cimi/model/machine.rb +227 -0
  18. data/lib/cimi/model/machine_admin.rb +59 -0
  19. data/lib/cimi/model/machine_admin_collection.rb +34 -0
  20. data/lib/cimi/model/machine_collection.rb +34 -0
  21. data/lib/cimi/model/machine_configuration.rb +67 -0
  22. data/lib/cimi/model/machine_configuration_collection.rb +34 -0
  23. data/lib/cimi/model/machine_image.rb +46 -0
  24. data/lib/cimi/model/machine_image_collection.rb +34 -0
  25. data/lib/cimi/model/machine_template.rb +41 -0
  26. data/lib/cimi/model/machine_template_collection.rb +34 -0
  27. data/lib/cimi/model/network.rb +69 -0
  28. data/lib/cimi/model/network_collection.rb +34 -0
  29. data/lib/cimi/model/network_configuration.rb +50 -0
  30. data/lib/cimi/model/network_configuration_collection.rb +34 -0
  31. data/lib/cimi/model/network_template.rb +26 -0
  32. data/lib/cimi/model/schema.rb +277 -0
  33. data/lib/cimi/model/volume.rb +103 -0
  34. data/lib/cimi/model/volume_collection.rb +34 -0
  35. data/lib/cimi/model/volume_configuration.rb +60 -0
  36. data/lib/cimi/model/volume_configuration_collection.rb +34 -0
  37. data/lib/cimi/model/volume_image.rb +49 -0
  38. data/lib/cimi/model/volume_image_collection.rb +34 -0
  39. data/lib/cimi/model/volume_template.rb +23 -0
  40. data/lib/cimi/model/volume_template_collection.rb +34 -0
  41. data/lib/cimi/server.rb +575 -0
  42. data/lib/deltacloud/base_driver/base_driver.rb +11 -1
  43. data/lib/deltacloud/core_ext.rb +2 -0
  44. data/lib/deltacloud/core_ext/array.rb +25 -0
  45. data/lib/deltacloud/core_ext/hash.rb +7 -0
  46. data/lib/deltacloud/core_ext/proc.rb +31 -0
  47. data/lib/deltacloud/core_ext/string.rb +15 -0
  48. data/lib/deltacloud/drivers/condor/condor_driver.rb +2 -1
  49. data/lib/deltacloud/drivers/ec2/ec2_driver.rb +32 -10
  50. data/lib/deltacloud/drivers/eucalyptus/eucalyptus_driver.rb +1 -1
  51. data/lib/deltacloud/drivers/gogrid/gogrid_driver.rb +1 -1
  52. data/lib/deltacloud/drivers/google/google_driver.rb +233 -0
  53. data/lib/deltacloud/drivers/mock/data/instances/inst0.yml +7 -2
  54. data/lib/deltacloud/drivers/mock/data/instances/inst1.yml +7 -2
  55. data/lib/deltacloud/drivers/mock/data/instances/inst2.yml +7 -2
  56. data/lib/deltacloud/drivers/mock/mock_client.rb +17 -0
  57. data/lib/deltacloud/drivers/mock/mock_driver.rb +82 -8
  58. data/lib/deltacloud/drivers/opennebula/opennebula_driver.rb +1 -1
  59. data/lib/deltacloud/drivers/openstack/openstack_driver.rb +47 -0
  60. data/lib/deltacloud/drivers/rackspace/rackspace_driver.rb +8 -8
  61. data/lib/deltacloud/drivers/rhevm/rhevm_client.rb +122 -49
  62. data/lib/deltacloud/drivers/rhevm/rhevm_driver.rb +42 -22
  63. data/lib/deltacloud/drivers/rimuhosting/rimuhosting_driver.rb +1 -1
  64. data/lib/deltacloud/drivers/sbc/sbc_driver.rb +3 -2
  65. data/lib/deltacloud/drivers/terremark/terremark_driver.rb +2 -2
  66. data/lib/deltacloud/drivers/vsphere/vsphere_client.rb +25 -4
  67. data/lib/deltacloud/drivers/vsphere/vsphere_driver.rb +35 -12
  68. data/lib/deltacloud/hardware_profile.rb +34 -10
  69. data/lib/deltacloud/helpers/application_helper.rb +3 -28
  70. data/lib/deltacloud/helpers/blob_stream.rb +2 -1
  71. data/lib/deltacloud/models.rb +2 -0
  72. data/lib/deltacloud/models/bucket.rb +1 -1
  73. data/lib/deltacloud/models/image.rb +1 -1
  74. data/lib/deltacloud/models/instance.rb +2 -1
  75. data/lib/deltacloud/models/instance_address.rb +56 -0
  76. data/lib/deltacloud/models/provider.rb +27 -0
  77. data/{server.rb → lib/deltacloud/server.rb} +72 -14
  78. data/lib/deltacloud/validation.rb +31 -10
  79. data/lib/sinatra/rabbit.rb +34 -26
  80. data/lib/sinatra/rack_accept.rb +5 -5
  81. data/lib/sinatra/rack_matrix_params.rb +6 -2
  82. data/lib/sinatra/rack_syslog.rb +3 -3
  83. data/lib/sinatra/static_assets.rb +1 -1
  84. data/lib/sinatra/url_for.rb +1 -7
  85. data/public/images/bread-bg.png +0 -0
  86. data/public/images/logo-wide.png +0 -0
  87. data/public/images/topbar-bg.png +0 -0
  88. data/public/javascripts/application.js +5 -0
  89. data/public/javascripts/cmwgapp.js +249 -0
  90. data/public/javascripts/jquery-1.4.2.min.js +154 -0
  91. data/public/javascripts/jquery.mobile-1.0rc1.min.js +170 -0
  92. data/public/stylesheets/images/icons-18-black.png +0 -0
  93. data/public/stylesheets/images/icons-18-white.png +0 -0
  94. data/public/stylesheets/images/icons-36-black.png +0 -0
  95. data/public/stylesheets/images/icons-36-white.png +0 -0
  96. data/public/stylesheets/jquery.mobile-1.0rc1.min.css +12 -0
  97. data/public/stylesheets/new.css +4 -0
  98. data/support/fedora/deltacloud-core.init +20 -13
  99. data/tests/cimi/features/step_definitions/common_steps.rb +59 -0
  100. data/tests/cimi/features/step_definitions/machine_images_steps.rb +0 -0
  101. data/tests/cimi/features/step_definitions/machines_steps.rb +99 -0
  102. data/tests/cimi/features/step_definitions/volumes_steps.rb +115 -0
  103. data/tests/cimi/features/support/env.rb +53 -0
  104. data/tests/common.rb +89 -11
  105. data/tests/core_ext/string.rb +31 -0
  106. data/tests/drivers/google/api_test.rb +35 -0
  107. data/tests/drivers/google/buckets_test.rb +116 -0
  108. data/tests/drivers/google/setup.rb +38 -0
  109. data/tests/drivers/mock/instances_test.rb +20 -5
  110. data/tests/drivers/openstack/api_test.rb +41 -0
  111. data/tests/drivers/openstack/hardware_profiles_test.rb +53 -0
  112. data/tests/drivers/openstack/images_test.rb +40 -0
  113. data/tests/drivers/openstack/instances_test.rb +163 -0
  114. data/tests/drivers/openstack/realms_test.rb +36 -0
  115. data/tests/drivers/openstack/setup.rb +20 -0
  116. data/tests/drivers/rackspace/buckets_test.rb +145 -0
  117. data/tests/drivers/rackspace/setup.rb +3 -3
  118. data/tests/drivers/rhevm/api_test.rb +1 -1
  119. data/tests/drivers/rhevm/images_test.rb +2 -2
  120. data/tests/drivers/rhevm/instances_test.rb +10 -12
  121. data/tests/drivers/rhevm/realms_test.rb +4 -4
  122. data/tests/drivers/rhevm/setup.rb +3 -3
  123. data/tests/rabbit_test.rb +1 -1
  124. data/views/api/show.html.haml +13 -0
  125. data/views/cimi/cloudEntryPoint/index.html.haml +5 -0
  126. data/views/cimi/cloudEntryPoint/index.xml.haml +9 -0
  127. data/views/cimi/collection/index.html.haml +45 -0
  128. data/views/cimi/collection/response.xml.haml +3 -0
  129. data/views/cimi/error.html.haml +31 -0
  130. data/views/cimi/errors/400.html.haml +41 -0
  131. data/views/cimi/errors/400.xml.haml +3 -0
  132. data/views/cimi/errors/401.html.haml +41 -0
  133. data/views/cimi/errors/401.xml.haml +2 -0
  134. data/views/cimi/errors/403.html.haml +42 -0
  135. data/views/cimi/errors/403.xml.haml +2 -0
  136. data/views/cimi/errors/404.html.haml +29 -0
  137. data/views/cimi/errors/404.xml.haml +2 -0
  138. data/views/cimi/errors/405.html.haml +29 -0
  139. data/views/cimi/errors/405.xml.haml +5 -0
  140. data/views/cimi/errors/500.html.haml +43 -0
  141. data/views/cimi/errors/500.xml.haml +6 -0
  142. data/views/cimi/errors/502.html.haml +43 -0
  143. data/views/cimi/errors/502.xml.haml +7 -0
  144. data/views/cimi/errors/backend_capability_failure.html.haml +29 -0
  145. data/views/cimi/layout.html.haml +32 -0
  146. data/views/cimi/machine_configurations/show.html.haml +159 -0
  147. data/views/cimi/machine_configurations/show.xml.haml +27 -0
  148. data/views/cimi/machine_images/show.html.haml +79 -0
  149. data/views/cimi/machine_images/show.xml.haml +17 -0
  150. data/views/cimi/machines/show.html.haml +177 -0
  151. data/views/cimi/machines/show.xml.haml +28 -0
  152. data/views/cimi/volumes/show.html.haml +68 -0
  153. data/views/cimi/volumes/show.xml.haml +17 -0
  154. data/views/drivers/show.html.haml +10 -5
  155. data/views/drivers/show.xml.haml +9 -4
  156. data/views/error.html.haml +2 -2
  157. data/views/errors/500.xml.haml +7 -1
  158. data/views/instances/index.html.haml +1 -1
  159. data/views/instances/new.html.haml +19 -16
  160. data/views/instances/show.html.haml +7 -2
  161. data/views/instances/show.xml.haml +8 -7
  162. data/views/layout.html.haml +2 -2
  163. data/views/storage_volumes/show.html.haml +1 -1
  164. metadata +296 -204
  165. data/public/javascripts/jquery.mobile-1.0b1.min.js +0 -146
  166. data/public/stylesheets/jquery.mobile-1.0b1.min.css +0 -8
@@ -0,0 +1,24 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one or more
2
+ # contributor license agreements. See the NOTICE file distributed with
3
+ # this work for additional information regarding copyright ownership. The
4
+ # ASF licenses this file to you under the Apache License, Version 2.0 (the
5
+ # "License"); you may not use this file except in compliance with the
6
+ # License. You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations
14
+ # under the License.
15
+
16
+ class CIMI::Model::Action < CIMI::Model::Base
17
+
18
+ text :action
19
+
20
+ def name
21
+ action.split('/').last.intern
22
+ end
23
+
24
+ end
@@ -0,0 +1,249 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one or more
2
+ # contributor license agreements. See the NOTICE file distributed with
3
+ # this work for additional information regarding copyright ownership. The
4
+ # ASF licenses this file to you under the Apache License, Version 2.0 (the
5
+ # "License"); you may not use this file except in compliance with the
6
+ # License. You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations
14
+ # under the License.
15
+
16
+ require 'xmlsimple'
17
+ require 'json'
18
+
19
+ # The base class for any CIMI object that we either read from a request or
20
+ # write as a response. This class handles serializing/deserializing XML and
21
+ # JSON into a common form.
22
+ #
23
+ # == Defining the schema
24
+ #
25
+ # The conversion of XML and JSON into internal objects is based on a schema
26
+ # that is defined through a DSL:
27
+ #
28
+ # class Machine < CIMI::Model::Base
29
+ # text :status
30
+ # href :meter
31
+ # array :volumes do
32
+ # scalar :href, :attachment_point, :protocol
33
+ # end
34
+ # end
35
+ #
36
+ # The DSL automatically takes care of converting identifiers from their
37
+ # underscored form to the camel-cased form used by CIMI. The above class
38
+ # can be used in the following way:
39
+ #
40
+ # machine = Machine.from_xml(some_xml)
41
+ # if machine.status == "UP"
42
+ # ...
43
+ # end
44
+ # sda = machine.volumes.find { |v| v.attachment_point == "/dev/sda" }
45
+ # handle_meter(machine.meter.href)
46
+ #
47
+ # The keywords for the DSL are
48
+ # [scalar(names, ...)]
49
+ # Define a scalar attribute; in JSON, this is represented as a string
50
+ # property. In XML, this can be represented in a number of ways,
51
+ # depending on whether the option :text is set:
52
+ # * :text not set: attribute on the enclosing element
53
+ # * :text == :direct: the text content of the enclosing element
54
+ # * :text == :nested: the text content of an element +<name>...</name>+
55
+ # [text(names)]
56
+ # A shorthand for +scalar(names, :text => :nested)+, i.e., for
57
+ # attributes that in XML are represented by their own tags
58
+ # [href(name)]
59
+ # A shorthand for +struct name { scalar :href }+; in JSON, this is
60
+ # represented as +{ name: { "href": string } }+, and in XML as +<name
61
+ # href="..."/>+
62
+ # [struct(name, opts, &block)]
63
+ # A structured subobject; the block defines the schema of the
64
+ # subobject. The +:content+ option can be used to specify the attribute
65
+ # that should receive the content of hte corresponding XML element
66
+ # [array(name, opts, &block)]
67
+ # An array of structured subobjects; the block defines the schema of
68
+ # the subobjects.
69
+
70
+ module CIMI::Model
71
+
72
+ def self.register_as_root_entity!(name)
73
+ @root_entities ||= []
74
+ @root_entities << name
75
+ unless CIMI::Model::CloudEntryPoint.href_defined?(name)
76
+ CIMI::Model::CloudEntryPoint.send(:href, name.underscore)
77
+ end
78
+ end
79
+
80
+ def self.root_entities
81
+ @root_entities || []
82
+ end
83
+
84
+ end
85
+
86
+ class CIMI::Model::Base
87
+
88
+ #
89
+ # We keep the values of the attributes in a hash
90
+ #
91
+ attr_reader :attribute_values
92
+
93
+ # Keep the list of all attributes in an array +attributes+; for each
94
+ # attribute, we also define a getter and a setter to access/change the
95
+ # value for that attribute
96
+ class << self
97
+ def base_schema
98
+ @schema ||= CIMI::Model::Schema.new
99
+ end
100
+
101
+ def clone_base_schema
102
+ @schema_duped = true
103
+ @schema = Marshal::load(Marshal.dump(superclass.base_schema))
104
+ end
105
+
106
+ def base_schema_cloned?
107
+ @schema_duped
108
+ end
109
+
110
+ private :'clone_base_schema', :'base_schema_cloned?'
111
+
112
+ def inherited(child)
113
+ child.instance_eval do
114
+ def schema
115
+ base_schema_cloned? ? @schema : clone_base_schema
116
+ end
117
+ end
118
+ end
119
+
120
+ def add_attributes!(names, attr_klass, &block)
121
+ if self.respond_to? :schema
122
+ schema.add_attributes!(names, attr_klass, &block)
123
+ else
124
+ base_schema.add_attributes!(names, attr_klass, &block)
125
+ end
126
+ names.each do |name|
127
+ define_method(name) { @attribute_values[name] }
128
+ define_method(:"#{name}=") { |newval| @attribute_values[name] = newval }
129
+ end
130
+ end
131
+
132
+ # Return Array of links to current CIMI object
133
+ def all_uri(context)
134
+ self.all(context).map { |e| { :href => e.uri } }
135
+ end
136
+ end
137
+
138
+ extend CIMI::Model::Schema::DSL
139
+
140
+ def [](a)
141
+ @attribute_values[a]
142
+ end
143
+
144
+ def []=(a, v)
145
+ @attribute_values[a] = v
146
+ end
147
+
148
+ #
149
+ # Factory methods
150
+ #
151
+ def initialize(values = {})
152
+ @attribute_values = values
153
+ end
154
+
155
+ # Construct a new object from the XML representation +xml+
156
+ def self.from_xml(text)
157
+ xml = XmlSimple.xml_in(text, :force_content => true)
158
+ model = self.new
159
+ @schema.from_xml(xml, model)
160
+ model
161
+ end
162
+
163
+ # Construct a new object
164
+ def self.from_json(text)
165
+ json = JSON::parse(text)
166
+ model = self.new
167
+ @schema.from_json(json, model)
168
+ model
169
+ end
170
+
171
+ #
172
+ # Serialize
173
+ #
174
+
175
+ def self.xml_tag_name
176
+ self.name.split("::").last
177
+ end
178
+
179
+ def self.to_json(model)
180
+ JSON::unparse(@schema.to_json(model))
181
+ end
182
+
183
+ def self.to_xml(model)
184
+ xml = @schema.to_xml(model)
185
+ xml["xmlns"] = "http://www.dmtf.org/cimi"
186
+ XmlSimple.xml_out(xml, :root_name => xml_tag_name)
187
+ end
188
+
189
+ def to_json
190
+ self.class.to_json(self)
191
+ end
192
+
193
+ def to_xml
194
+ self.class.to_xml(self)
195
+ end
196
+
197
+ #
198
+ # Common attributes for all resources
199
+ #
200
+ text :uri, :name, :description, :created
201
+
202
+ # FIXME: this doesn't match with JSON
203
+ hash :property, :content => :value do
204
+ scalar :name
205
+ end
206
+
207
+ def self.act_as_root_entity(name=nil)
208
+ if name
209
+ name = name.to_s.camelize.pluralize
210
+ else
211
+ name = xml_tag_name.pluralize.uncapitalize
212
+ end
213
+ CIMI::Model.register_as_root_entity! name
214
+ end
215
+
216
+ def self.all(_self); find(:all, _self); end
217
+
218
+ def filter_by(filter_opts)
219
+ return self if filter_opts.nil?
220
+ return filter_attributes(filter_opts.split(',').map{ |a| a.intern }) if filter_opts.include? ','
221
+ case filter_opts
222
+ when /^([\w\_]+)$/ then filter_attributes([$1.intern])
223
+ when /^([\w\_]+)\[(\d+\-\d+)\]$/ then filter_by_arr_range($1.intern, $2)
224
+ when /^([\w\_]+)\[(\d+)\]$/ then filter_by_arr_index($1.intern, $2)
225
+ else self
226
+ end
227
+ end
228
+
229
+ private
230
+
231
+ def filter_attributes(attr_list)
232
+ attrs = attr_list.inject({}) do |result, attr|
233
+ result[attr] = self.send(attr) if self.respond_to?(attr)
234
+ result
235
+ end
236
+ self.class.new(attrs)
237
+ end
238
+
239
+ def filter_by_arr_index(attr, filter)
240
+ return self unless self.respond_to?(attr)
241
+ self.class.new(attr => [self.send(attr)[filter.to_i]])
242
+ end
243
+
244
+ def filter_by_arr_range(attr, filter)
245
+ return self unless self.respond_to?(attr)
246
+ filter = filter.split('-').inject { |s,e| s.to_i..e.to_i }
247
+ self.class.new(attr => self.send(attr)[filter])
248
+ end
249
+ end
@@ -0,0 +1,48 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one or more
2
+ # contributor license agreements. See the NOTICE file distributed with
3
+ # this work for additional information regarding copyright ownership. The
4
+ # ASF licenses this file to you under the Apache License, Version 2.0 (the
5
+ # "License"); you may not use this file except in compliance with the
6
+ # License. You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations
14
+ # under the License.
15
+
16
+ class CIMI::Model::CloudEntryPoint < CIMI::Model::Base
17
+
18
+ array :entity_metadata do
19
+ scalar :href
20
+ end
21
+
22
+ def self.create(context)
23
+ self.new(entities(context).merge({
24
+ :name => context.driver.name,
25
+ :description => "Cloud Entry Point for the Deltacloud #{context.driver.name} driver",
26
+ :uri => context.cloudEntryPoint_url,
27
+ :created => Time.now,
28
+ :entity_metadata => EntityMetadata.all_uri(context)
29
+ }))
30
+ end
31
+
32
+ # Return an Hash of the CIMI root entities used in CloudEntryPoint
33
+ def self.entities(context)
34
+ CIMI::Model.root_entities.inject({}) do |result, entity|
35
+ if context.respond_to? :"#{entity.underscore}_url"
36
+ result[entity.underscore] = { :href => context.send(:"#{entity.underscore}_url") }
37
+ end
38
+ result
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def self.href_defined?(entity)
45
+ true if schema.attribute_names.include? entity.underscore
46
+ end
47
+
48
+ end
@@ -0,0 +1,83 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one or more
2
+ # contributor license agreements. See the NOTICE file distributed with
3
+ # this work for additional information regarding copyright ownership. The
4
+ # ASF licenses this file to you under the Apache License, Version 2.0 (the
5
+ # "License"); you may not use this file except in compliance with the
6
+ # License. You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations
14
+ # under the License.
15
+
16
+
17
+ class CIMI::Model::EntityMetadata < CIMI::Model::Base
18
+
19
+ text :type_uri
20
+
21
+ array :attributes do
22
+ scalar :name
23
+ scalar :namespace
24
+ scalar :type
25
+ scalar :required
26
+ scalar :constraints
27
+ end
28
+
29
+ array :operations do
30
+ scalar :name
31
+ scalar :uri
32
+ scalar :description
33
+ scalar :method
34
+ scalar :input_message
35
+ scalar :output_message
36
+ end
37
+
38
+ def self.find(id, context)
39
+ entity_metadata = []
40
+ if id == :all
41
+ CIMI::Model.root_entities.each do |entity|
42
+ entity_class = CIMI::Model.const_get("#{entity.singularize}")
43
+ entity_metadata << entity_class.create_entity_metadata(context) if entity_class.respond_to?(:create_entity_metadata)
44
+ end
45
+ return entity_metadata
46
+ else
47
+ entity_class = CIMI::Model.const_get("#{id.camelize}")
48
+ if entity_class.respond_to?(:create_entity_metadata)
49
+ entity_class.create_entity_metadata(context)
50
+ end
51
+ end
52
+ end
53
+
54
+ def self.metadata_from_deltacloud_features(cimi_entity, dcloud_entity, context)
55
+ deltacloud_features = context.driver.features(dcloud_entity)
56
+ metadata_attributes = deltacloud_features.map{|f| attributes_from_feature(f)}
57
+ from_feature(cimi_entity, context, metadata_attributes.flatten!)
58
+ end
59
+
60
+ def includes_attribute?(attribute)
61
+ self.attributes.any?{|attr| attr[:name] == attribute}
62
+ end
63
+
64
+ private
65
+
66
+ def self.attributes_from_feature(feature)
67
+ feature.operations.first.params.inject([]) do |result, param|
68
+ result << {
69
+ :name=>(feature.name == :user_name ? :name : param[0]),
70
+ :type=> "xs:string",
71
+ :required=> (param[1] and param[1].optional?) ? "false" : "true",
72
+ :constraints=> (feature.constraints.empty? ? (feature.description.nil? ? "" : feature.description): feature.constraints)
73
+ }
74
+ end
75
+ end
76
+
77
+ def self.from_feature(cimi_entity, context, metadata_attributes)
78
+ self.new(:name => cimi_entity, :uri=>"#{context.entity_metadata_url}/#{cimi_entity.underscore}",
79
+ :type_uri=> context.send("#{cimi_entity.pluralize.underscore}_url"),
80
+ :attributes => metadata_attributes)
81
+ end
82
+
83
+ end
@@ -0,0 +1,31 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one or more
2
+ # contributor license agreements. See the NOTICE file distributed with
3
+ # this work for additional information regarding copyright ownership. The
4
+ # ASF licenses this file to you under the Apache License, Version 2.0 (the
5
+ # "License"); you may not use this file except in compliance with the
6
+ # License. You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations
14
+ # under the License.
15
+
16
+ class CIMI::Model::EntityMetadataCollection < CIMI::Model::Base
17
+
18
+ array :entity_metadata do
19
+ scalar :href
20
+ end
21
+
22
+ def self.default(context)
23
+ self.new(
24
+ :uri => context.entity_metadata_url,
25
+ :name => 'default',
26
+ :created => Time.now,
27
+ :entity_metadata => EntityMetadata.all_uri(context)
28
+ )
29
+ end
30
+
31
+ end
@@ -0,0 +1,40 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one or more
2
+ # contributor license agreements. See the NOTICE file distributed with
3
+ # this work for additional information regarding copyright ownership. The
4
+ # ASF licenses this file to you under the Apache License, Version 2.0 (the
5
+ # "License"); you may not use this file except in compliance with the
6
+ # License. You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations
14
+ # under the License.
15
+
16
+ module CIMI::Model
17
+
18
+ class NotFound < StandardError
19
+ attr_accessor :code
20
+
21
+ def initialize
22
+ super("Requested Entity Not Found")
23
+ self.code = 404
24
+ end
25
+
26
+ end
27
+
28
+ class NotImplemented < StandardError
29
+ attr_accessor :code
30
+
31
+ def initialize
32
+ super("Requested operation is not implemented by backend provider")
33
+ self.code = 501
34
+ end
35
+
36
+ end
37
+
38
+ end
39
+
40
+