opennebula-oca 3.8.0.beta1

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.
@@ -0,0 +1,436 @@
1
+ # -------------------------------------------------------------------------- #
2
+ # Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) #
3
+ # #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may #
5
+ # not use this file except in compliance with the License. You may obtain #
6
+ # 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, #
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
13
+ # See the License for the specific language governing permissions and #
14
+ # limitations under the License. #
15
+ #--------------------------------------------------------------------------- #
16
+
17
+
18
+ module OpenNebula
19
+
20
+ begin
21
+ require 'nokogiri'
22
+ NOKOGIRI=true
23
+ rescue LoadError
24
+ NOKOGIRI=false
25
+ end
26
+
27
+ begin
28
+ require 'rexml/formatters/pretty'
29
+ REXML_FORMATTERS=true
30
+ rescue LoadError
31
+ REXML_FORMATTERS=false
32
+ end
33
+
34
+ # The XMLElement class provides an abstraction of the underlying
35
+ # XML parser engine. It provides XML-related methods for the Pool and
36
+ # PoolElement classes
37
+ class XMLElement
38
+
39
+ # xml:: _opaque xml object_ an xml object as returned by build_xml
40
+ def initialize(xml=nil)
41
+ @xml = xml
42
+ end
43
+
44
+ # Initialize a XML document for the element
45
+ # xml:: _String_ the XML document of the object
46
+ # root_element:: _String_ Base xml element
47
+ def initialize_xml(xml, root_element)
48
+ @xml = XMLElement.build_xml(xml, root_element)
49
+
50
+ if OpenNebula.is_error?(@xml)
51
+ @xml = nil
52
+ else
53
+ if NOKOGIRI
54
+ if @xml.size == 0
55
+ @xml = nil
56
+ end
57
+ else
58
+ if @xml.name != root_element
59
+ @xml = nil
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ # Builds a XML document
66
+ # xml:: _String_ the XML document of the object
67
+ # root_element:: _String_ Base xml element
68
+ # [return] _XML_ object for the underlying XML engine
69
+ def self.build_xml(xml, root_element)
70
+ begin
71
+ if NOKOGIRI
72
+ doc = Nokogiri::XML(xml).xpath("/#{root_element}")
73
+ else
74
+ doc = REXML::Document.new(xml).root
75
+ end
76
+ rescue Exception => e
77
+ return OpenNebula::Error.new(e.message)
78
+ end
79
+
80
+ return doc
81
+ end
82
+ # Extract an element from the XML description of the PoolElement.
83
+ # key::_String_ The name of the element
84
+ # [return] _String_ the value of the element
85
+ # Examples:
86
+ # ['VID'] # gets VM id
87
+ # ['HISTORY/HOSTNAME'] # get the hostname from the history
88
+ def [](key)
89
+ if NOKOGIRI
90
+ element=@xml.xpath(key.to_s)
91
+
92
+ return nil if element.size == 0
93
+ else
94
+ element=@xml.elements[key.to_s]
95
+
96
+ return "" if element && !element.has_text?
97
+ end
98
+
99
+ element.text if element
100
+ end
101
+
102
+ # Delete an element from the xml
103
+ # xpath::_String_ xpath expression that selects the elemnts to be deleted
104
+ def delete_element(xpath)
105
+ if NOKOGIRI
106
+ @xml.xpath(xpath.to_s).remove
107
+ else
108
+ @xml.delete_element(xpath.to_s)
109
+ end
110
+ end
111
+
112
+ # Add a new element to the xml
113
+ # xpath::_String_ xpath xpression where the elemente will be added
114
+ # elems::_Hash_ Hash containing the pairs key-value to be included
115
+ # Examples:
116
+ # add_element('VM', 'NEW_ITEM' => 'NEW_VALUE')
117
+ # <VM><NEW_ITEM>NEW_VALUE</NEW_ITEM>...</VM>
118
+ #
119
+ # add_element('VM/TEMPLATE', 'V1' => {'X1' => 'A1', 'Y2' => 'A2'})
120
+ # <VM><TEMPLATE><V1><X1>A1</X1><Y2>A2</Y2>...</TEMPLATE></VM>
121
+ def add_element(xpath, elems)
122
+ elems.each { |key, value|
123
+ if value.instance_of?(Hash)
124
+ if NOKOGIRI
125
+ elem = Nokogiri::XML::Node.new key, @xml.document
126
+ value.each { |k2, v2|
127
+ child = Nokogiri::XML::Node.new k2, elem
128
+ child.content = v2
129
+ elem.add_child(child)
130
+ }
131
+ @xml.xpath(xpath.to_s).first.add_child(elem)
132
+ else
133
+ elem = REXML::Element.new(key)
134
+ value.each { |k2, v2|
135
+ elem.add_element(k2).text = v2
136
+ }
137
+ @xml.elements[xpath].add_element(elem)
138
+ end
139
+ else
140
+ if NOKOGIRI
141
+ elem = Nokogiri::XML::Node.new key, @xml.document
142
+ elem.content = value
143
+ @xml.xpath(xpath.to_s).first.add_child(elem)
144
+ else
145
+ @xml.elements[xpath].add_element(key).text = value
146
+ end
147
+ end
148
+ }
149
+ end
150
+
151
+ # Gets an array of text from elemenets extracted
152
+ # using the XPATH expression passed as filter
153
+ def retrieve_elements(filter)
154
+ elements_array = Array.new
155
+
156
+ if NOKOGIRI
157
+ @xml.xpath(filter.to_s).each { |pelem|
158
+ elements_array << pelem.text if pelem.text
159
+ }
160
+ else
161
+ @xml.elements.each(filter.to_s) { |pelem|
162
+ elements_array << pelem.text if pelem.text
163
+ }
164
+ end
165
+
166
+ if elements_array.size == 0
167
+ return nil
168
+ else
169
+ return elements_array
170
+ end
171
+
172
+ end
173
+
174
+ # Gets an attribute from an elemenT
175
+ # key:: _String_ xpath for the element
176
+ # name:: _String_ name of the attribute
177
+ def attr(key,name)
178
+ value = nil
179
+
180
+ if NOKOGIRI
181
+ element=@xml.xpath(key.to_s.upcase)
182
+ if element.size == 0
183
+ return nil
184
+ end
185
+
186
+ attribute = element.attr(name)
187
+
188
+ value = attribute.text if attribute != nil
189
+ else
190
+ element=@xml.elements[key.to_s.upcase]
191
+
192
+ value = element.attributes[name] if element != nil
193
+ end
194
+
195
+ return value
196
+ end
197
+
198
+ # Iterates over every Element in the XPath and calls the block with a
199
+ # a XMLElement
200
+ # block:: _Block_
201
+ def each(xpath_str,&block)
202
+ if NOKOGIRI
203
+ @xml.xpath(xpath_str).each { |pelem|
204
+ block.call XMLElement.new(pelem)
205
+ }
206
+ else
207
+ @xml.elements.each(xpath_str) { |pelem|
208
+ block.call XMLElement.new(pelem)
209
+ }
210
+ end
211
+ end
212
+
213
+ def each_xpath(xpath_str,&block)
214
+ if NOKOGIRI
215
+ @xml.xpath(xpath_str).each { |pelem|
216
+ block.call pelem.text
217
+ }
218
+ else
219
+ @xml.elements.each(xpath_str) { |pelem|
220
+ block.call pelem.text
221
+ }
222
+ end
223
+ end
224
+
225
+ def name
226
+ @xml.name
227
+ end
228
+
229
+ def text
230
+ if NOKOGIRI
231
+ @xml.content
232
+ else
233
+ @xml.text
234
+ end
235
+ end
236
+
237
+ # Returns wheter there are elements for a given XPath
238
+ # xpath_str:: _String_ XPath expression to locate the element
239
+ def has_elements?(xpath_str)
240
+ if NOKOGIRI
241
+ element = @xml.xpath(xpath_str.to_s.upcase)
242
+ return element != nil && element.children.size > 0
243
+ else
244
+ element = @xml.elements[xpath_str.to_s]
245
+ return element != nil && element.has_elements?
246
+ end
247
+ end
248
+
249
+ # Returns the <TEMPLATE> element in text form
250
+ # indent:: _Boolean_ indents the resulting string, default true
251
+ def template_str(indent=true)
252
+ template_like_str('TEMPLATE', indent)
253
+ end
254
+
255
+ # Returns the <TEMPLATE> element in XML form
256
+ def template_xml
257
+ if NOKOGIRI
258
+ @xml.xpath('TEMPLATE').to_s
259
+ else
260
+ @xml.elements['TEMPLATE'].to_s
261
+ end
262
+ end
263
+
264
+ # Returns the xml of an element
265
+ def element_xml(xpath)
266
+ if NOKOGIRI
267
+ @xml.xpath(xpath).to_s
268
+ else
269
+ @xml.elements[xpath].to_s
270
+ end
271
+ end
272
+
273
+ # Returns elements in text form
274
+ # root_element:: _String_ base element
275
+ # indent:: _Boolean_ indents the resulting string, default true
276
+ # xpath_exp:: _String_ filter elements with a XPath
277
+ def template_like_str(root_element, indent=true, xpath_exp=nil)
278
+ if NOKOGIRI
279
+ xml_template = @xml.xpath(root_element).to_s
280
+ rexml = REXML::Document.new(xml_template).root
281
+ else
282
+ rexml = @xml.elements[root_element]
283
+ end
284
+
285
+ if indent
286
+ ind_enter = "\n"
287
+ ind_tab = ' '
288
+ else
289
+ ind_enter = ''
290
+ ind_tab = ' '
291
+ end
292
+
293
+ str = rexml.elements.collect(xpath_exp) {|n|
294
+ next if n.class != REXML::Element
295
+
296
+ str_line = ""
297
+
298
+ if n.has_elements?
299
+ str_line << "#{n.name}=[#{ind_enter}" << n.collect { |n2|
300
+
301
+ next if n2.class != REXML::Element or !n2.has_text?
302
+
303
+ str = "#{ind_tab}#{n2.name}=#{attr_to_str(n2.text)}"
304
+
305
+ }.compact.join(",#{ind_enter}") << " ]"
306
+ else
307
+ next if !n.has_text?
308
+
309
+ str_line << "#{n.name}=#{attr_to_str(n.text)}"
310
+ end
311
+
312
+ str_line
313
+ }.compact.join("\n")
314
+
315
+ return str
316
+ end
317
+
318
+ #
319
+ #
320
+ #
321
+ def to_xml(pretty=false)
322
+ if NOKOGIRI && pretty
323
+ str = @xml.to_xml
324
+ elsif REXML_FORMATTERS && pretty
325
+ str = String.new
326
+
327
+ formatter = REXML::Formatters::Pretty.new
328
+ formatter.compact = true
329
+
330
+ formatter.write(@xml,str)
331
+ else
332
+ str = @xml.to_s
333
+ end
334
+
335
+ return str
336
+ end
337
+
338
+ # @return [Hash] a hash representing the resource
339
+ def to_hash
340
+ hash = {}
341
+
342
+ if NOKOGIRI
343
+ if @xml.instance_of?(Nokogiri::XML::NodeSet)
344
+ @xml.each { |c|
345
+ if c.element?
346
+ build_hash(hash, c)
347
+ end
348
+ }
349
+ else
350
+ build_hash(hash, @xml)
351
+ end
352
+ else
353
+ build_hash(hash, @xml)
354
+ end
355
+
356
+ hash
357
+ end
358
+
359
+ private
360
+
361
+ #
362
+ #
363
+ #
364
+ def build_hash(hash, element)
365
+ if NOKOGIRI
366
+ array = element.children
367
+ if array.length==1 and (array.first.text? or array.first.cdata?)
368
+ r = array.first.text
369
+ else
370
+ r = {}
371
+ array.each { |c|
372
+ if c.element?
373
+ build_hash(r, c)
374
+ end
375
+ }
376
+ end
377
+ else
378
+ r = {}
379
+ if element.has_elements?
380
+ element.each_element { |c| build_hash(r, c) }
381
+ elsif element.has_text?
382
+ r = element.text
383
+ end
384
+ end
385
+
386
+ key = element.name
387
+ if hash.has_key?(key)
388
+ if hash[key].instance_of?(Array)
389
+ hash[key] << r
390
+ else
391
+ hash[key] = [hash[key], r]
392
+ end
393
+ else
394
+ hash[key] = r
395
+ end
396
+
397
+ hash
398
+ end
399
+
400
+ #
401
+ #
402
+ #
403
+ def attr_to_str(attr)
404
+ attr.gsub!('"',"\\\"")
405
+ attr = "\"#{attr}\""
406
+
407
+ return attr
408
+ end
409
+ end
410
+
411
+ # The XMLUtilsPool module provides an abstraction of the underlying
412
+ # XML parser engine. It provides XML-related methods for the Pools
413
+ class XMLPool < XMLElement
414
+
415
+ def initialize(xml=nil)
416
+ super(xml)
417
+ end
418
+
419
+ #Executes the given block for each element of the Pool
420
+ #block:: _Block_
421
+ def each_element(block)
422
+ if NOKOGIRI
423
+ @xml.xpath(
424
+ "#{@element_name}").each {|pelem|
425
+ block.call self.factory(pelem)
426
+ }
427
+ else
428
+ @xml.elements.each(
429
+ "#{@element_name}") {|pelem|
430
+ block.call self.factory(pelem)
431
+ }
432
+ end
433
+ end
434
+ end
435
+
436
+ end
data/lib/OpenNebula.rb ADDED
@@ -0,0 +1,175 @@
1
+ # -------------------------------------------------------------------------- #
2
+ # Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) #
3
+ # #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may #
5
+ # not use this file except in compliance with the License. You may obtain #
6
+ # 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, #
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
13
+ # See the License for the specific language governing permissions and #
14
+ # limitations under the License. #
15
+ #--------------------------------------------------------------------------- #
16
+
17
+
18
+ begin # require 'rubygems'
19
+ require 'rubygems'
20
+ rescue Exception
21
+ end
22
+
23
+ require 'xmlrpc/client'
24
+ require 'digest/sha1'
25
+ require 'rexml/document'
26
+ require 'pp'
27
+
28
+ require 'OpenNebula/XMLUtils'
29
+ require 'OpenNebula/VirtualMachine'
30
+ require 'OpenNebula/VirtualMachinePool'
31
+ require 'OpenNebula/VirtualNetwork'
32
+ require 'OpenNebula/VirtualNetworkPool'
33
+ require 'OpenNebula/Image'
34
+ require 'OpenNebula/ImagePool'
35
+ require 'OpenNebula/User'
36
+ require 'OpenNebula/UserPool'
37
+ require 'OpenNebula/Host'
38
+ require 'OpenNebula/HostPool'
39
+ require 'OpenNebula/Template'
40
+ require 'OpenNebula/TemplatePool'
41
+ require 'OpenNebula/Group'
42
+ require 'OpenNebula/GroupPool'
43
+ require 'OpenNebula/Acl'
44
+ require 'OpenNebula/AclPool'
45
+ require 'OpenNebula/Datastore'
46
+ require 'OpenNebula/DatastorePool'
47
+ require 'OpenNebula/Cluster'
48
+ require 'OpenNebula/ClusterPool'
49
+ require 'OpenNebula/Document'
50
+ require 'OpenNebula/DocumentPool'
51
+
52
+ module OpenNebula
53
+
54
+ # OpenNebula version
55
+ VERSION = '3.8.0'
56
+
57
+ # The Error Class represents a generic error in the OpenNebula
58
+ # library. It contains a readable representation of the error.
59
+ # Any function in the OpenNebula module will return an Error
60
+ # object in case of error.
61
+ class Error
62
+ ESUCCESS = 0x0000
63
+ EAUTHENTICATION = 0x0100
64
+ EAUTHORIZATION = 0x0200
65
+ ENO_EXISTS = 0x0400
66
+ EACTION = 0x0800
67
+ EXML_RPC_API = 0x1000
68
+ EINTERNAL = 0x2000
69
+ ENOTDEFINED = 0x1111
70
+
71
+ attr_reader :message, :errno
72
+
73
+ # +message+ Description of the error
74
+ # +errno+ OpenNebula code error
75
+ def initialize(message=nil, errno=0x1111)
76
+ @message = message
77
+ @errno = errno
78
+ end
79
+
80
+ def to_str()
81
+ @message
82
+ end
83
+ end
84
+
85
+ # Returns true if the object returned by a method of the OpenNebula
86
+ # library is an Error
87
+ def self.is_error?(value)
88
+ value.class==OpenNebula::Error
89
+ end
90
+
91
+
92
+ if OpenNebula::NOKOGIRI
93
+ class NokogiriStreamParser < XMLRPC::XMLParser::AbstractStreamParser
94
+ def initialize
95
+ @parser_class = NokogiriParser
96
+ end
97
+
98
+ class NokogiriParser < Nokogiri::XML::SAX::Document
99
+ include XMLRPC::XMLParser::StreamParserMixin
100
+
101
+ alias :cdata_block :character
102
+ alias :characters :character
103
+ alias :end_element :endElement
104
+ alias :start_element :startElement
105
+
106
+ def parse(str)
107
+ parser = Nokogiri::XML::SAX::Parser.new(self)
108
+ parser.parse(str)
109
+ end
110
+ end
111
+ end
112
+ end
113
+
114
+
115
+ # The client class, represents the connection with the core and handles the
116
+ # xml-rpc calls.
117
+ class Client
118
+ attr_accessor :one_auth
119
+
120
+ begin
121
+ require 'xmlparser'
122
+ XMLPARSER=true
123
+ rescue LoadError
124
+ XMLPARSER=false
125
+ end
126
+
127
+ def initialize(secret=nil, endpoint=nil)
128
+ if secret
129
+ @one_auth = secret
130
+ elsif ENV["ONE_AUTH"] and !ENV["ONE_AUTH"].empty? and File.file?(ENV["ONE_AUTH"])
131
+ @one_auth = File.read(ENV["ONE_AUTH"])
132
+ elsif File.file?(ENV["HOME"]+"/.one/one_auth")
133
+ @one_auth = File.read(ENV["HOME"]+"/.one/one_auth")
134
+ else
135
+ raise "ONE_AUTH file not present"
136
+ end
137
+
138
+ @one_auth.rstrip!
139
+
140
+ if endpoint
141
+ @one_endpoint = endpoint
142
+ elsif ENV["ONE_XMLRPC"]
143
+ @one_endpoint = ENV["ONE_XMLRPC"]
144
+ else
145
+ @one_endpoint = "http://localhost:2633/RPC2"
146
+ end
147
+
148
+ @server = XMLRPC::Client.new2(@one_endpoint)
149
+
150
+ if OpenNebula::NOKOGIRI
151
+ @server.set_parser(NokogiriStreamParser.new)
152
+ elsif XMLPARSER
153
+ @server.set_parser(XMLRPC::XMLParser::XMLStreamParser.new)
154
+ end
155
+ end
156
+
157
+ def call(action, *args)
158
+ begin
159
+ response = @server.call_async("one."+action, @one_auth, *args)
160
+
161
+ if response[0] == false
162
+ Error.new(response[1], response[2])
163
+ else
164
+ response[1] #response[1..-1]
165
+ end
166
+ rescue Exception => e
167
+ Error.new(e.message)
168
+ end
169
+ end
170
+
171
+ def get_version()
172
+ call("system.version")
173
+ end
174
+ end
175
+ end
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: opennebula-oca
3
+ version: !ruby/object:Gem::Version
4
+ version: 3.8.0.beta1
5
+ prerelease: 6
6
+ platform: ruby
7
+ authors:
8
+ - OpenNebula
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-10-30 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: nokogiri
16
+ requirement: &2152558860 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *2152558860
25
+ - !ruby/object:Gem::Dependency
26
+ name: json
27
+ requirement: &2152557640 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *2152557640
36
+ description: Libraries needed to talk to OpenNebula
37
+ email: contact@opennebula.org
38
+ executables: []
39
+ extensions: []
40
+ extra_rdoc_files: []
41
+ files:
42
+ - lib/OpenNebula.rb
43
+ - lib/OpenNebula/Acl.rb
44
+ - lib/OpenNebula/AclPool.rb
45
+ - lib/OpenNebula/Cluster.rb
46
+ - lib/OpenNebula/ClusterPool.rb
47
+ - lib/OpenNebula/Datastore.rb
48
+ - lib/OpenNebula/DatastorePool.rb
49
+ - lib/OpenNebula/Document.rb
50
+ - lib/OpenNebula/DocumentJSON.rb
51
+ - lib/OpenNebula/DocumentPool.rb
52
+ - lib/OpenNebula/DocumentPoolJSON.rb
53
+ - lib/OpenNebula/Group.rb
54
+ - lib/OpenNebula/GroupPool.rb
55
+ - lib/OpenNebula/Host.rb
56
+ - lib/OpenNebula/HostPool.rb
57
+ - lib/OpenNebula/Image.rb
58
+ - lib/OpenNebula/ImagePool.rb
59
+ - lib/OpenNebula/Pool.rb
60
+ - lib/OpenNebula/Template.rb
61
+ - lib/OpenNebula/TemplatePool.rb
62
+ - lib/OpenNebula/User.rb
63
+ - lib/OpenNebula/UserPool.rb
64
+ - lib/OpenNebula/VirtualMachine.rb
65
+ - lib/OpenNebula/VirtualMachinePool.rb
66
+ - lib/OpenNebula/VirtualNetwork.rb
67
+ - lib/OpenNebula/VirtualNetworkPool.rb
68
+ - lib/OpenNebula/XMLUtils.rb
69
+ homepage: http://opennebula.org
70
+ licenses: []
71
+ post_install_message:
72
+ rdoc_options: []
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ! '>='
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ! '>'
85
+ - !ruby/object:Gem::Version
86
+ version: 1.3.1
87
+ requirements: []
88
+ rubyforge_project:
89
+ rubygems_version: 1.8.15
90
+ signing_key:
91
+ specification_version: 3
92
+ summary: OpenNebula Client API
93
+ test_files: []
94
+ has_rdoc: