rxen 0.1.1
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.
- data/README.rdoc +70 -0
- data/Rakefile +37 -0
- data/bin/rxen +0 -0
- data/lib/rxen.rb +244 -0
- data/tests/tc_rxen_session.rb +184 -0
- data/tests/test_helper.rb +4 -0
- data/tests/test_malformed.json +6 -0
- data/tests/test_malformed_user.json +5 -0
- data/tests/test_server.json +6 -0
- data/tests/ts_alltests.rb +4 -0
- metadata +84 -0
data/README.rdoc
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
== rxen
|
2
|
+
|
3
|
+
Ruby wrapper to access the Xen XML-RPC API via simple to use ruby methods, not
|
4
|
+
all methods are implemented, yet. They can be easily added by simply extending the
|
5
|
+
Session class RPC_METHODS Hash to include the correct Regular Expression mathing the
|
6
|
+
call.
|
7
|
+
|
8
|
+
== example
|
9
|
+
|
10
|
+
# Get the rxen gem
|
11
|
+
require 'rxen'
|
12
|
+
|
13
|
+
# create a Session with the Xen Server you want to control
|
14
|
+
xs = Session.new("https://my.xenserver.company.com/")
|
15
|
+
|
16
|
+
# login with username and password
|
17
|
+
xs.login_with_password("root", "password")
|
18
|
+
|
19
|
+
# Some example calls, all possible calls can be found in the XenAPI
|
20
|
+
# Documentation. Calls are build by class_function(parameters), it is not needed
|
21
|
+
# to pass the session id since it is done automatically.
|
22
|
+
# Get IDs for the VMs running on the Server
|
23
|
+
xs.VM_get_all()
|
24
|
+
|
25
|
+
# register for all task events
|
26
|
+
xs.event_register(["task"])
|
27
|
+
|
28
|
+
# get the next event from the queue
|
29
|
+
xs.event_next()
|
30
|
+
|
31
|
+
# unregister from the task events
|
32
|
+
xs.event_unregister(["task"])
|
33
|
+
|
34
|
+
# logout of the XenServer
|
35
|
+
xs.logout()
|
36
|
+
|
37
|
+
Alternativly config based login can be done via
|
38
|
+
|
39
|
+
xs = Session.new_with_config("configfile.json")
|
40
|
+
|
41
|
+
== license
|
42
|
+
|
43
|
+
(the BSD license)
|
44
|
+
|
45
|
+
Copyright 2010 Philipp Fehre. All rights reserved.
|
46
|
+
|
47
|
+
Redistribution and use in source and binary forms, with or without modification, are
|
48
|
+
permitted provided that the following conditions are met:
|
49
|
+
|
50
|
+
1. Redistributions of source code must retain the above copyright notice, this list of
|
51
|
+
conditions and the following disclaimer.
|
52
|
+
|
53
|
+
2. Redistributions in binary form must reproduce the above copyright notice, this list
|
54
|
+
of conditions and the following disclaimer in the documentation and/or other materials
|
55
|
+
provided with the distribution.
|
56
|
+
|
57
|
+
THIS SOFTWARE IS PROVIDED BY PHILIPP FEHRE ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
58
|
+
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
59
|
+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR
|
60
|
+
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
61
|
+
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
62
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
63
|
+
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
64
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
65
|
+
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
66
|
+
|
67
|
+
The views and conclusions contained in the software and documentation are those of the
|
68
|
+
authors and should not be interpreted as representing official policies, either expressed
|
69
|
+
or implied, of Philipp Fehre.
|
70
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems' unless ENV['NO_RUBYGEMS']
|
4
|
+
require 'rake/gempackagetask'
|
5
|
+
require 'rubygems/specification'
|
6
|
+
|
7
|
+
|
8
|
+
spec = Gem::Specification.new do |s|
|
9
|
+
s.name = "rxen"
|
10
|
+
s.version = "0.1.1"
|
11
|
+
s.authors = ['Philipp Fehre']
|
12
|
+
s.email = "philipp.fehre@googlemail.com"
|
13
|
+
s.homepage = "http://sideshowcoder.com/rxen"
|
14
|
+
s.description = "Ruby wrapper to acces the Xen XML-RPC API via simple ruby methods"
|
15
|
+
s.summary = "Handles login, and after that all other Xen API methods exposed via XML-RPC by XenServer"
|
16
|
+
|
17
|
+
s.platform = Gem::Platform::RUBY
|
18
|
+
s.has_rdoc = true
|
19
|
+
s.extra_rdoc_files = ["README.rdoc"]
|
20
|
+
|
21
|
+
s.require_path = 'lib'
|
22
|
+
s.autorequire = 'rxen'
|
23
|
+
s.files = %w(README.rdoc Rakefile) + Dir.glob("{lib,tests,bin}/*")
|
24
|
+
|
25
|
+
s.bindir = 'bin'
|
26
|
+
s.executables = ['rxen']
|
27
|
+
s.test_files = Dir.glob('tests/*.rb')
|
28
|
+
s.add_dependency('json')
|
29
|
+
end
|
30
|
+
|
31
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
32
|
+
pkg.need_tar = true
|
33
|
+
end
|
34
|
+
|
35
|
+
task :default => "pkg/#{spec.name}-#{spec.version}.gem" do
|
36
|
+
puts "generated latest version"
|
37
|
+
end
|
data/bin/rxen
ADDED
File without changes
|
data/lib/rxen.rb
ADDED
@@ -0,0 +1,244 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Access via XML-RPC
|
4
|
+
require "xmlrpc/client"
|
5
|
+
|
6
|
+
# Read Config json file
|
7
|
+
require "rubygems"
|
8
|
+
require "json"
|
9
|
+
|
10
|
+
# Override XMLRPC Client to not throw a waring on self sign Certificate because
|
11
|
+
# XenServer Certificates are always self signed
|
12
|
+
|
13
|
+
require "net/https"
|
14
|
+
require "openssl"
|
15
|
+
require "pp"
|
16
|
+
|
17
|
+
# enable debugger
|
18
|
+
# require "ruby-debug"
|
19
|
+
|
20
|
+
|
21
|
+
# Get rid of message that Cerificate from Server is self signed, since XenServer uses
|
22
|
+
# a self signed Cert in the default case and we know to which Server we connect anyway
|
23
|
+
module SELF_SSL
|
24
|
+
|
25
|
+
class Net_HTTP < Net::HTTP
|
26
|
+
def initialize(*args)
|
27
|
+
super
|
28
|
+
@ssl_context = OpenSSL::SSL::SSLContext.new
|
29
|
+
# Set verify mode to VERIFY_NONE to not display a warning on
|
30
|
+
# self signed certificates
|
31
|
+
@ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class XMLRPC_Client < XMLRPC::Client
|
36
|
+
def initialize(*args)
|
37
|
+
super
|
38
|
+
# Use patched NET::HTTP module for XMLRPC
|
39
|
+
@http = SELF_SSL::Net_HTTP.new( @host, @port,
|
40
|
+
@proxy_host,@proxy_port )
|
41
|
+
@http.use_ssl = @use_ssl if @use_ssl
|
42
|
+
@http.read_timeout = @timeout
|
43
|
+
@http.open_timeout = @timeout
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
# XenAPI
|
51
|
+
|
52
|
+
# Define Xen Api Error to make clearer it clearer Exception belongs to XenApi
|
53
|
+
class XenApiError < RuntimeError; end
|
54
|
+
# Define Config Error
|
55
|
+
class XenApiConfigError < RuntimeError; end
|
56
|
+
|
57
|
+
# Handle a session with a given XenServer
|
58
|
+
class Session
|
59
|
+
|
60
|
+
# Methods to respond to
|
61
|
+
RPC_METHODS = {
|
62
|
+
# Login / Logout
|
63
|
+
:login => /^login/,
|
64
|
+
:logout => /^logout/,
|
65
|
+
|
66
|
+
# Session
|
67
|
+
:session_change_password => /^session_change_password/,
|
68
|
+
:session_get_all_subject_identifiers => /^session_get_all_subject_identifiers/,
|
69
|
+
:session_logout_subject_identifier => /^session_logout_subject_identifier/,
|
70
|
+
:session_get_uuid => /^session_get_uuid/,
|
71
|
+
:session_get_this_user => /^session_get_this_user/,
|
72
|
+
:session_get_this_host => /^session_get_this_host/,
|
73
|
+
:session_get_last_active => /^session_get_last_active/,
|
74
|
+
:session_get_pool => /^session_get_pool/,
|
75
|
+
:session_get_other_config => /^session_get_other_config/,
|
76
|
+
:session_set_other_config => /^session_set_other_config/,
|
77
|
+
|
78
|
+
# Task
|
79
|
+
:task_create => /^task_create/,
|
80
|
+
:task_destroy => /^task_destroy/,
|
81
|
+
:task_get_all => /^task_get_all/,
|
82
|
+
|
83
|
+
# Event
|
84
|
+
:event_register => /^event_register/,
|
85
|
+
:event_unregister => /^event_unregister/,
|
86
|
+
:event_next => /^event_next/,
|
87
|
+
:event_get_current_id => /^event_get_current_id/,
|
88
|
+
|
89
|
+
# VM
|
90
|
+
:vm_snapshot => /^VM_snapshot/,
|
91
|
+
:vm_clone => /^VM_clone/,
|
92
|
+
:vm_copy => /^VM_copy/,
|
93
|
+
:vm_start => /^VM_start/,
|
94
|
+
:vm_start_on => /^VM_start_on/,
|
95
|
+
:vm_pause => /^VM_pause/,
|
96
|
+
:vm_unpause => /^VM_unpause/,
|
97
|
+
:vm_suspend => /^VM_suspend/,
|
98
|
+
:vm_resume => /^VM_resume/,
|
99
|
+
:vm_clean_shutdown => /^VM_clean_shutdown/,
|
100
|
+
:vm_clean_reboot => /^VM_clean_reboot/,
|
101
|
+
:vm_hard_showdown => /^VM_hard_shutdown/,
|
102
|
+
:vm_pool_migrate => /^VM_pool_migrate/,
|
103
|
+
:vm_get_possible_hosts => /^VM_get_possible_hosts/,
|
104
|
+
:vm_assert_agile => /^VM_assert_agile/,
|
105
|
+
:vm_get_uuid => /^VM_get_uuid/,
|
106
|
+
:vm_get_powerstate => /^VM_get_powerstate/,
|
107
|
+
:vm_get_name_label => /^VM_name_label/,
|
108
|
+
:vm_get_resident_on => /^VM_get_resident_on/,
|
109
|
+
:vm_get_all => /^VM_get_all/
|
110
|
+
}
|
111
|
+
|
112
|
+
# Access the Session ID
|
113
|
+
attr_reader :session, :xenserver
|
114
|
+
|
115
|
+
# Access and set session attributes
|
116
|
+
attr_accessor :uri, :user, :password
|
117
|
+
|
118
|
+
# Initialize with Server URI
|
119
|
+
def initialize(uri)
|
120
|
+
@uri = uri
|
121
|
+
@xenserver = SELF_SSL::XMLRPC_Client.new2(@uri)
|
122
|
+
end
|
123
|
+
|
124
|
+
# Initialize with JSON config
|
125
|
+
class << self
|
126
|
+
def new_with_config(config)
|
127
|
+
config = JSON.parse(File.read(config))["xenserver"]
|
128
|
+
if config.nil?
|
129
|
+
raise XenApiConfigError, "malformed config"
|
130
|
+
end
|
131
|
+
|
132
|
+
@password = config["password"]
|
133
|
+
@user = config["user"]
|
134
|
+
@uri = config["uri"]
|
135
|
+
if @password.nil? || @user.nil? || @uri.nil?
|
136
|
+
raise XenApiConfigError, "missing uri, user, or password"
|
137
|
+
end
|
138
|
+
|
139
|
+
s = self.new(@uri)
|
140
|
+
s.login_with_password(@user, @password)
|
141
|
+
return s
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
# Since methods are just forwarded to the Server with params they don't have to be implemented itself
|
146
|
+
# but via responding to method_missing in the correct form
|
147
|
+
def method_missing(method, *args, &block)
|
148
|
+
RPC_METHODS.each do |m|
|
149
|
+
if method.to_s =~ m.last
|
150
|
+
return xenapi_request(method, *args)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
# Call super class method missing
|
154
|
+
super
|
155
|
+
end
|
156
|
+
|
157
|
+
# If methods are only implemented via method_missing the responds to is not working correctly anymore
|
158
|
+
# therefor it needs to be updated with the correct methods to be called
|
159
|
+
|
160
|
+
def respond_to?(method)
|
161
|
+
# Check if any RPC methods match the call
|
162
|
+
RPC_METHODS.each do |m|
|
163
|
+
return true if method.to_s =~ m.last
|
164
|
+
end
|
165
|
+
# Call super class responds_to?
|
166
|
+
super
|
167
|
+
end
|
168
|
+
|
169
|
+
# Declare a XenAPI request to be only called by object itself
|
170
|
+
private
|
171
|
+
|
172
|
+
def xenapi_request(method, *params)
|
173
|
+
# Catch login method
|
174
|
+
if method.to_s =~ RPC_METHODS[:login]
|
175
|
+
return login(method, *params)
|
176
|
+
end
|
177
|
+
|
178
|
+
if method.to_s =~ RPC_METHODS[:logout]
|
179
|
+
return logout(method)
|
180
|
+
end
|
181
|
+
|
182
|
+
# Pass method to server
|
183
|
+
# First part of method name is the class, so _ got to be replace by a .
|
184
|
+
method = method.to_s
|
185
|
+
method.sub!(/_/, ".")
|
186
|
+
|
187
|
+
# Check if we are logged in
|
188
|
+
raise XenApiError, "not logged in" unless @session
|
189
|
+
|
190
|
+
# Call Server with method passed
|
191
|
+
res = @xenserver.call(method, @session, *params)
|
192
|
+
if res["Status"] == "Success"
|
193
|
+
# return the result value passed back via XMLRPC
|
194
|
+
return res["Value"]
|
195
|
+
else
|
196
|
+
# get the error if one occurs
|
197
|
+
raise XenApiError, res["ErrorDescription"][0]
|
198
|
+
end
|
199
|
+
|
200
|
+
end
|
201
|
+
|
202
|
+
# Login Method needs to save the session cookie for further requests so it
|
203
|
+
# does not have to be passed every single call
|
204
|
+
def login(method, *params)
|
205
|
+
# Use saved passwords if nothing is passed
|
206
|
+
if params.empty?
|
207
|
+
params << @user
|
208
|
+
params << @password
|
209
|
+
else
|
210
|
+
# save password and user for quicker reloggon
|
211
|
+
@user = params[0]
|
212
|
+
@password = params[1]
|
213
|
+
end
|
214
|
+
|
215
|
+
res = @xenserver.call("session.#{method}", *params)
|
216
|
+
|
217
|
+
if res["Status"] == "Success"
|
218
|
+
@session = res["Value"]
|
219
|
+
return @session
|
220
|
+
else
|
221
|
+
raise XenApiError, res["ErrorDescription"][0]
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
# Logout needs to clear the session cookie saved by login
|
226
|
+
def logout(method)
|
227
|
+
# Check if logged on, else session should be nil
|
228
|
+
unless @session.nil?
|
229
|
+
res = @xenserver.call("session.#{method}", @session)
|
230
|
+
else
|
231
|
+
# If not logged in logout will always be successful (common sense)
|
232
|
+
return true
|
233
|
+
end
|
234
|
+
|
235
|
+
# Check if logout was Successful and clear session if so
|
236
|
+
if res["Status"] == "Success"
|
237
|
+
@session = nil
|
238
|
+
return true
|
239
|
+
else
|
240
|
+
raise XenApiError, res["ErrorDescription"][0]
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
end
|
@@ -0,0 +1,184 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "test_helper"
|
4
|
+
require "test/unit"
|
5
|
+
require "rxen"
|
6
|
+
require "net/http"
|
7
|
+
require "net/https"
|
8
|
+
require "json"
|
9
|
+
|
10
|
+
class SessionTest < Test::Unit::TestCase
|
11
|
+
|
12
|
+
# define Server config file
|
13
|
+
SERVER_CONFIG = "test_server.json"
|
14
|
+
MALFORMED_CONFIG = "test_malformed.json"
|
15
|
+
MALFORMED_CONFIG_USER = "test_malformed_user.json"
|
16
|
+
|
17
|
+
# Methods that can be called on the xensession at the moment
|
18
|
+
METHODS = [
|
19
|
+
:session_change_password,
|
20
|
+
:session_get_all_subject_identifiers,
|
21
|
+
:session_logout_subject_identifier,
|
22
|
+
:session_get_uuid,
|
23
|
+
:session_get_this_user,
|
24
|
+
:session_get_this_host,
|
25
|
+
:session_get_last_active,
|
26
|
+
:session_get_pool,
|
27
|
+
:session_get_other_config,
|
28
|
+
:session_set_other_config,
|
29
|
+
:task_create,
|
30
|
+
:task_destroy,
|
31
|
+
:task_get_all,
|
32
|
+
:event_register,
|
33
|
+
:event_unregister,
|
34
|
+
:event_next,
|
35
|
+
:event_get_current_id,
|
36
|
+
:VM_snapshot,
|
37
|
+
:VM_clone,
|
38
|
+
:VM_copy,
|
39
|
+
:VM_start,
|
40
|
+
:VM_start_on,
|
41
|
+
:VM_pause,
|
42
|
+
:VM_unpause,
|
43
|
+
:VM_suspend,
|
44
|
+
:VM_resume,
|
45
|
+
:VM_clean_shutdown,
|
46
|
+
:VM_clean_reboot,
|
47
|
+
:VM_hard_shutdown,
|
48
|
+
:VM_pool_migrate,
|
49
|
+
:VM_get_possible_hosts,
|
50
|
+
:VM_assert_agile,
|
51
|
+
:VM_get_uuid,
|
52
|
+
:VM_get_powerstate,
|
53
|
+
:VM_name_label,
|
54
|
+
:VM_get_resident_on,
|
55
|
+
:VM_get_all
|
56
|
+
]
|
57
|
+
|
58
|
+
# Methods used for testing do to them being non blocking and do not require specific order
|
59
|
+
# of execution
|
60
|
+
METHODS_TEST_SAVE = {
|
61
|
+
:session_get_all_subject_identifiers => [],
|
62
|
+
:task_get_all => [],
|
63
|
+
:event_register => ["task"],
|
64
|
+
:event_unregister => ["task"],
|
65
|
+
:event_get_current_id => [],
|
66
|
+
:VM_get_all => []
|
67
|
+
}
|
68
|
+
|
69
|
+
# Setup
|
70
|
+
def setup
|
71
|
+
config = JSON.parse(File.read(SERVER_CONFIG))["xenserver"]
|
72
|
+
@serveruri = config["uri"]
|
73
|
+
@user = config["user"]
|
74
|
+
@password = config["password"]
|
75
|
+
@xensession = Session.new(@serveruri)
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_login
|
79
|
+
# Check if Session responds to login
|
80
|
+
assert_respond_to(@xensession, :login_with_password)
|
81
|
+
|
82
|
+
# Check if login works
|
83
|
+
assert_nothing_raised(XenApiError) do
|
84
|
+
@xensession.login_with_password(@user, @password)
|
85
|
+
end
|
86
|
+
assert_not_nil( @xensession.session )
|
87
|
+
assert_not_nil( @xensession.user )
|
88
|
+
assert_not_nil( @xensession.password )
|
89
|
+
|
90
|
+
# Login credentials should be saved, and not be required again
|
91
|
+
assert_nothing_raised(XenApiError) do
|
92
|
+
@xensession.login_with_password()
|
93
|
+
end
|
94
|
+
|
95
|
+
# Check if login fails with wrong password and username, overwriting
|
96
|
+
# saved ones
|
97
|
+
assert_raise(XenApiError) do
|
98
|
+
@xensession.login_with_password("toor", "12345")
|
99
|
+
end
|
100
|
+
assert_equal( @xensession.user, "toor" )
|
101
|
+
assert_equal( @xensession.password, "12345" )
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_new_with_config
|
106
|
+
test_session = nil
|
107
|
+
assert_nothing_raised(XenApiConfigError) do
|
108
|
+
test_session = Session.new_with_config(SERVER_CONFIG)
|
109
|
+
end
|
110
|
+
|
111
|
+
assert_not_nil( test_session.session )
|
112
|
+
|
113
|
+
assert_raises(XenApiConfigError) do
|
114
|
+
Session.new_with_config(MALFORMED_CONFIG)
|
115
|
+
end
|
116
|
+
|
117
|
+
assert_raises(XenApiConfigError) do
|
118
|
+
Session.new_with_config(MALFORMED_CONFIG_USER)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_logout
|
123
|
+
# Check if Session responds to logout
|
124
|
+
assert_respond_to(@xensession, :logout)
|
125
|
+
|
126
|
+
# Logout should always be successful if not logged in
|
127
|
+
assert_equal(true, @xensession.logout())
|
128
|
+
|
129
|
+
# Login first
|
130
|
+
@xensession.login_with_password(@user, @password)
|
131
|
+
|
132
|
+
# Check if we are logged in
|
133
|
+
assert_not_nil( @xensession.session )
|
134
|
+
|
135
|
+
# Logout
|
136
|
+
assert_nothing_raised(XenApiError) do
|
137
|
+
@xensession.logout()
|
138
|
+
end
|
139
|
+
assert_nil( @xensession.session )
|
140
|
+
end
|
141
|
+
|
142
|
+
def test_respond_to_method
|
143
|
+
# Check to see if we are responding to correct methods
|
144
|
+
METHODS.each do |m|
|
145
|
+
assert_respond_to( @xensession, m )
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def test_method_basic_function
|
150
|
+
# Check if no methods defined throw an error
|
151
|
+
# Start by loggin in
|
152
|
+
assert_nothing_raised(XenApiError) {@xensession.login_with_password(@user, @password)}
|
153
|
+
|
154
|
+
# Methods able to call
|
155
|
+
METHODS_TEST_SAVE.each do |m|
|
156
|
+
assert_nothing_raised(XenApiError) do
|
157
|
+
if m[1].empty?
|
158
|
+
@xensession.send(m[0])
|
159
|
+
else
|
160
|
+
@xensession.send(m[0], m[1])
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
# End by loggin out
|
166
|
+
assert_nothing_raised(XenApiError) {@xensession.logout()}
|
167
|
+
end
|
168
|
+
|
169
|
+
def test_method_call_deep
|
170
|
+
# We should not be able to call a method unless we are logged in
|
171
|
+
assert_raise(XenApiError) do
|
172
|
+
@xensession.VM_get_all()
|
173
|
+
end
|
174
|
+
|
175
|
+
# Login now
|
176
|
+
@xensession.login_with_password(@user, @password)
|
177
|
+
|
178
|
+
# Method should run fine now
|
179
|
+
assert_nothing_raised(XenApiError) do
|
180
|
+
@xensession.VM_get_all()
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
end
|
metadata
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rxen
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 1
|
9
|
+
version: 0.1.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Philipp Fehre
|
13
|
+
autorequire: rxen
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-04-26 00:00:00 +02:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: json
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
version: "0"
|
30
|
+
type: :runtime
|
31
|
+
version_requirements: *id001
|
32
|
+
description: Ruby wrapper to acces the Xen XML-RPC API via simple ruby methods
|
33
|
+
email: philipp.fehre@googlemail.com
|
34
|
+
executables:
|
35
|
+
- rxen
|
36
|
+
extensions: []
|
37
|
+
|
38
|
+
extra_rdoc_files:
|
39
|
+
- README.rdoc
|
40
|
+
files:
|
41
|
+
- README.rdoc
|
42
|
+
- Rakefile
|
43
|
+
- lib/rxen.rb
|
44
|
+
- tests/tc_rxen_session.rb
|
45
|
+
- tests/test_helper.rb
|
46
|
+
- tests/test_malformed.json
|
47
|
+
- tests/test_malformed_user.json
|
48
|
+
- tests/test_server.json
|
49
|
+
- tests/ts_alltests.rb
|
50
|
+
- bin/rxen
|
51
|
+
has_rdoc: true
|
52
|
+
homepage: http://sideshowcoder.com/rxen
|
53
|
+
licenses: []
|
54
|
+
|
55
|
+
post_install_message:
|
56
|
+
rdoc_options: []
|
57
|
+
|
58
|
+
require_paths:
|
59
|
+
- lib
|
60
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
segments:
|
65
|
+
- 0
|
66
|
+
version: "0"
|
67
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
segments:
|
72
|
+
- 0
|
73
|
+
version: "0"
|
74
|
+
requirements: []
|
75
|
+
|
76
|
+
rubyforge_project:
|
77
|
+
rubygems_version: 1.3.6
|
78
|
+
signing_key:
|
79
|
+
specification_version: 3
|
80
|
+
summary: Handles login, and after that all other Xen API methods exposed via XML-RPC by XenServer
|
81
|
+
test_files:
|
82
|
+
- tests/tc_rxen_session.rb
|
83
|
+
- tests/test_helper.rb
|
84
|
+
- tests/ts_alltests.rb
|