ivanoats-whm_xml 0.3.0

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 ADDED
@@ -0,0 +1,87 @@
1
+ = WHM XML-API Ruby Wrapper
2
+
3
+ This is a Ruby wrapper for the cPanel WHM XML-API interface. It will allow you to perform multiple functions available on your cPanel WHM server. For more information on the XML-API, see the cPanel website at http://twiki.cpanel.net/twiki/bin/view/AllDocumentation/AutomationIntegration/XmlApi.
4
+
5
+ == Requirements
6
+
7
+ The following Ruby gems are required to be installed in order to make use this gem:
8
+
9
+ xml-simple (>= 1.0.12):: http://xml-simple.rubyforge.org
10
+ activesupport (>= 2.3.2):: http://as.rubyonrails.org
11
+ curb (>= 0.3.2):: http://curb.rubyforge.org
12
+ validatable (>= 1.6.7):: http://validatable.rubyforge.org
13
+
14
+ == Usage
15
+
16
+ First off, you must have root access to a cPanel WHM server. With this gem, you can either use <b>password</b> or <b>remote access key</b> authentication. To get to the remote access key in WHM (which is likely the more secure method of connecting), go under "Cluster/Remote Access", and click on "Setup Remote Access Key". You can either copy the pre-generated one, or re-generate it.
17
+
18
+ ==== Installation
19
+
20
+ You can install this gem simply by doing the following:
21
+
22
+ $ gem sources -a http://gems.github.com
23
+ $ gem install ivanoats-whm_xml_api_ruby
24
+
25
+ You can also include it in a Rails project:
26
+
27
+ $ script/plugin install git://github.com/ivanoats/whm_xml_api_ruby.git
28
+
29
+ ==== Connecting
30
+
31
+ To access the functions of the server, all you need to do is initialize a new Server class:
32
+
33
+ server = Whm::Server.new(
34
+ :username => "root",
35
+ :remote_access_key => "sd00fsd2i3rj...",
36
+ :host => "dedicated.server.com"
37
+ )
38
+
39
+ server.version
40
+ => "11.24.2"
41
+
42
+ == Currently Available Methods
43
+
44
+ As of WHM version 11.24.2, these are the methods that are available via this gem:
45
+
46
+ * <tt>account_summary</tt>
47
+ * <tt>change_account_password</tt>
48
+ * <tt>change_package</tt>
49
+ * <tt>create_account</tt>
50
+ * <tt>generate_ssl_certificate</tt>
51
+ * <tt>hostname</tt>
52
+ * <tt>limit_bandwidth_usage</tt>
53
+ * <tt>list_accounts</tt>
54
+ * <tt>list_packages</tt>
55
+ * <tt>modify_account</tt>
56
+ * <tt>suspend_account</tt>
57
+ * <tt>terminate_account</tt>
58
+ * <tt>unsuspend_account</tt>
59
+ * <tt>version</tt>
60
+
61
+ == Authors and credits
62
+
63
+ Authors:: Ivan Storck, Josh Delsman, Padraic McGee
64
+ Home page:: http://github.com/ivanoats/whm_xml_api_ruby
65
+
66
+ == License
67
+
68
+ Copyright (c) 2008-2009 Ivan Storck
69
+
70
+ Permission is hereby granted, free of charge, to any person obtaining
71
+ a copy of this software and associated documentation files (the
72
+ 'Software'), to deal in the Software without restriction, including
73
+ without limitation the rights to use, copy, modify, merge, publish,
74
+ distribute, sublicense, and/or sell copies of the Software, and to
75
+ permit persons to whom the Software is furnished to do so, subject to
76
+ the following conditions:
77
+
78
+ The above copyright notice and this permission notice shall be
79
+ included in all copies or substantial portions of the Software.
80
+
81
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
82
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
83
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
84
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
85
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
86
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
87
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require 'rubygems'
2
+ require 'rake/rdoctask'
3
+
4
+ desc 'Generate documentation for whm_xml_api_ruby'
5
+ Rake::RDocTask.new do |rd|
6
+ rd.rdoc_dir = 'html'
7
+ rd.rdoc_files.include("README.rdoc", "lib/**/*.rb")
8
+ rd.main = "README.rdoc"
9
+ rd.title = "whm_xml_api_ruby -- A Ruby wrapper for cPanel's WHM"
10
+ rd.options << "--all"
11
+ end
data/lib/parameters.rb ADDED
@@ -0,0 +1,67 @@
1
+ module Whm #:nodoc:
2
+ # Allows for parameter requirements and validations for methods
3
+ module Parameters
4
+ # Check the included hash for the included parameters, and ensure they aren't blank.
5
+ #
6
+ # ==== Example
7
+ #
8
+ # class User
9
+ # def initialize
10
+ # requires!(options, :username, :password)
11
+ # end
12
+ # end
13
+ #
14
+ # >> User.new
15
+ # ArgumentError: Missing required parameter: username
16
+ #
17
+ # >> User.new(:username => "john")
18
+ # ArgumentError: Missing required parameter: password
19
+ def requires!(hash, *params)
20
+ params.each do |param|
21
+ if param.is_a?(Array)
22
+ raise ArgumentError.new("Missing required parameter: #{param.first}") unless hash.has_key?(param.first)
23
+ raise ArgumentError.new("Required parameter cannot be blank: #{param.first}") if hash[param.first].blank?
24
+ else
25
+ raise ArgumentError.new("Missing required parameter: #{param}") unless hash.has_key?(param)
26
+ raise ArgumentError.new("Required parameter cannot be blank: #{param}") if hash[param].blank?
27
+ end
28
+ end
29
+ end
30
+
31
+ # Checks to see if supplied params (which are booleans) contain
32
+ # either a 1 ("Yes") or 0 ("No") value.
33
+ def booleans!(hash, *params)
34
+ params.each do |param|
35
+ if param.is_a?(Array)
36
+ raise ArgumentError.new("Boolean parameter must be \"1\" or \"0\": #{param.first}") unless hash[param.first].to_s.match(/(1|0)/)
37
+ else
38
+ raise ArgumentError.new("Boolean parameter must be \"1\" or \"0\": #{param}") unless hash[param].to_s.match(/(1|0)/)
39
+ end
40
+ end
41
+ end
42
+
43
+ # Checks the hash to see if the hash includes any parameter
44
+ # which is not included in the list of valid parameters.
45
+ #
46
+ # ==== Example
47
+ #
48
+ # class User
49
+ # def initialize
50
+ # valid_options!(options, :username)
51
+ # end
52
+ # end
53
+ #
54
+ # >> User.new(:username => "josh")
55
+ # => #<User:0x18a1190 @username="josh">
56
+ #
57
+ # >> User.new(:username => "josh", :credit_card => "5105105105105100")
58
+ # ArgumentError: Not a valid parameter: credit_card
59
+ def valid_options!(hash, *params)
60
+ keys = hash.keys
61
+
62
+ keys.each do |key|
63
+ raise ArgumentError.new("Not a valid parameter: #{key}") unless params.include?(key)
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,4 @@
1
+ module Whm #:nodoc:
2
+ class CommandFailedError < StandardError #:nodoc:
3
+ end
4
+ end
data/lib/whm/server.rb ADDED
@@ -0,0 +1,355 @@
1
+ module Whm #:nodoc:
2
+ # The Server class initializes a new connection with the cPanel WHM server, and
3
+ # contains all functions that can be run on a cPanel WHM server as of version 11.24.2.
4
+ class Server
5
+ include Parameters
6
+
7
+ # Hostname of the WHM server (e.g., <tt>dedicated.server.com</tt>)
8
+ attr_reader :host
9
+
10
+ # WHM XML-API username
11
+ attr_reader :username
12
+
13
+ # WHM XML-API password. Use this, or the remote key, to authenticate with the server
14
+ attr_reader :password
15
+
16
+ # WHM XML-API remote key. Use this, or the password, to authenticate with the server
17
+ attr_reader :remote_key
18
+
19
+ # If you'd like increased verbosity of commands, set this to <tt>true</tt>. Defaults to <tt>false</tt>
20
+ attr_accessor :debug
21
+
22
+ # By default, SSL is enable. Set to <tt>false</tt> to disable it.
23
+ attr_accessor :ssl
24
+
25
+ # By default, we connect on port 2087. Set this to another integer to change it.
26
+ attr_accessor :port
27
+
28
+ attr_accessor :attributes
29
+
30
+ # Initialize the connection with WHM using the hostname,
31
+ # user and password/remote key. Will default to asking for
32
+ # a password, but remote_key is required if a password
33
+ # is not used.
34
+ #
35
+ # ==== Example
36
+ #
37
+ # Password authentication with debugging enabled:
38
+ #
39
+ # Whm::Server.new(
40
+ # :host => "dedicated.server.com",
41
+ # :username => "root",
42
+ # :password => "s3cUr3!p@5sw0rD",
43
+ # :debug => true
44
+ # )
45
+ #
46
+ # Remote key authentication with port 8000, and SSL to off (defaults to port 2087, and SSL on):
47
+ #
48
+ # Whm::Server.new(
49
+ # :host => "dedicated.server.com",
50
+ # :username => "root",
51
+ # :remote_key => "cf975b8930b0d0da69764c5d8dc8cf82 ...",
52
+ # :port => 8000,
53
+ # :ssl => false
54
+ # )
55
+ def initialize(options = {})
56
+ requires!(options, :host, :username)
57
+ requires!(options, :password) unless options[:remote_key]
58
+
59
+ @host = options[:host]
60
+ @username = options[:username] || "root"
61
+ @remote_key = options[:remote_key].gsub(/(\r|\n)/, "") unless options[:password]
62
+ @password = options[:password] unless options[:remote_key]
63
+ @debug = options[:debug] || false
64
+ @port = options[:port] || 2087
65
+ @ssl = options[:ssl] || true
66
+ end
67
+
68
+ # Finds all accounts
69
+ #
70
+ # ==== Options
71
+ # * <tt>:user</tt> - Username associated with the acount to display (string)
72
+ def accounts(options = {})
73
+ summary = self.list_accounts(options)
74
+ summary = [summary] unless summary.is_a? Array
75
+ summary.collect { |attributes| Account.new(attributes) }
76
+ end
77
+
78
+ # Find an account
79
+ #
80
+ # ==== Options
81
+ # * <tt>:user</tt> - Username associated with the acount to display (string)
82
+ def account(name)
83
+ summary = self.account_summary(:user => name)
84
+ build_account(summary)
85
+ end
86
+
87
+ # Displays pertient account information for a specific account.
88
+ #
89
+ # ==== Options
90
+ # * <tt>:user</tt> - Username associated with the acount to display (string)
91
+ def account_summary(options = {})
92
+ requires!(options, :user)
93
+
94
+ data = get_xml(:url => "accountsummary", :params => options)
95
+ check_for_cpanel_errors_on(data)["acct"]
96
+ end
97
+
98
+ # Changes the password of a domain owner (cPanel) or reseller (WHM) account.
99
+ #
100
+ # ==== Options
101
+ # * <tt>:user</tt> - Username of the user whose password should be changed (string)
102
+ # * <tt>:pass</tt> - New password for that user (string)
103
+ def change_account_password(options = {})
104
+ requires!(options, :user, :pass)
105
+
106
+ data = get_xml(:url => "passwd", :params => options)
107
+ check_for_cpanel_errors_on(data)["passwd"]
108
+ end
109
+
110
+ # Changes the hosting package associated with an account.
111
+ # Returns <tt>true</tt> if it is successful, or
112
+ # <tt>false</tt> if it is not.
113
+ #
114
+ # ==== Options
115
+ # * <tt>:user</tt> - Username of the account to change the package for (string)
116
+ # * <tt>:pkg</tt> - Name of the package that the account should use (string)
117
+ def change_package(options = {})
118
+ requires!(options, :user, :pkg)
119
+
120
+ data = get_xml(:url => "changepackage", :params => options)
121
+ check_for_cpanel_errors_on(data)
122
+
123
+ data["status"] == "1" ? true : false
124
+ end
125
+
126
+ # Creates a hosting account and sets up it's associated domain information.
127
+ #
128
+ # ==== Options
129
+ # * <tt>:username</tt> - Username of the account (string)
130
+ # * <tt>:domain</tt> - Domain name (string)
131
+ # * <tt>:pkgname</tt> - Name of a new package to be created based on the settings used (string)
132
+ # * <tt>:savepkg</tt> - Save the settings used as a new package (boolean)
133
+ # * <tt>:featurelist</tt> - Name of the feature list to be used when creating a new package (string)
134
+ # * <tt>:quota</tt> - Disk space quota in MB. Must be between 0-999999, with 0 being unlimited (integer)
135
+ # * <tt>:password</tt> - User's password to access cPanel (string)
136
+ # * <tt>:ip</tt> - Whether or not the domain has a dedicated IP address, either <tt>"y"</tt> (Yes) or <tt>"n"</tt> (No) (string)
137
+ # * <tt>:cgi</tt> - Whether or not the domain has CGI access (boolean)
138
+ # * <tt>:frontpage</tt> - Whether or not the domain has FrontPage extensions installed (boolean)
139
+ # * <tt>:hasshell</tt> - Whether or not the domain has shell/SSH access (boolean)
140
+ # * <tt>:contactemail</tt> - Contact email address for the account (string)
141
+ # * <tt>:cpmod</tt> - cPanel theme name (string)
142
+ # * <tt>:maxftp</tt> - Maximum number of FTP accounts the user can create. Must be between 0-999999, with 0 being unlimited (integer)
143
+ # * <tt>:maxsql</tt> - Maximum number of SQL databases the user can create. Must be between 0-999999, with 0 being unlimited (integer)
144
+ # * <tt>:maxpop</tt> - Maximum number of email accounts the user can create. Must be between 0-999999, with 0 being unlimited (integer)
145
+ # * <tt>:maxlst</tt> - Maximum number of mailing lists the user can create. Must be between 0-999999, with 0 being unlimited (integer)
146
+ # * <tt>:maxsub</tt> - Maximum number of subdomains the user can create. Must be between 0-999999, with 0 being unlimited (integer)
147
+ # * <tt>:maxpark</tt> - Maximum number of parked domains the user can create. Must be between 0-999999, with 0 being unlimited (integer)
148
+ # * <tt>:maxaddon</tt> - Maximum number of addon domains the user can create. Must be between 0-999999, with 0 being unlimited (integer)
149
+ # * <tt>:bwlimit</tt> - Bandwidth limit in MB. Must be between 0-999999, with 0 being unlimited (integer)
150
+ # * <tt>:customip</tt> - Specific IP for the site (string)
151
+ # * <tt>:language</tt> - Language to use in the account's cPanel interface (string)
152
+ # * <tt>:useregns</tt> - Use the registered nameservers for the domain instead of the ones configured on the server (boolean)
153
+ # * <tt>:hasuseregns</tt> - Must be set to <tt>1</tt> if the above <tt>:useregns</tt> is set to <tt>1</tt> (boolean)
154
+ # * <tt>:reseller</tt> - Give reseller privileges to the account (boolean)
155
+ def create_account(options = {})
156
+ requires!(options, :domain, :username)
157
+
158
+ data = get_xml(:url => "createacct", :params => options)
159
+ check_for_cpanel_errors_on(data)
160
+ end
161
+
162
+ # Generates an SSL certificate
163
+ #
164
+ # ==== Options
165
+ # * <tt>:xemail</tt> - Email address of the domain owner (string)
166
+ # * <tt>:host</tt> - Domain the SSL certificate is for, or the SSL host (string)
167
+ # * <tt>:country</tt> - Country the organization is located in (string)
168
+ # * <tt>:state</tt> - State the organization is located in (string)
169
+ # * <tt>:city</tt> - City the organization is located in (string)
170
+ # * <tt>:co</tt> - Name of the organization/company (string)
171
+ # * <tt>:cod</tt> - Name of the department (string)
172
+ # * <tt>:email</tt> - Email to send the certificate to (string)
173
+ # * <tt>:pass</tt> - Certificate password (string)
174
+ def generate_ssl_certificate(options = {})
175
+ requires!(options, :city, :co, :cod, :country, :email, :host, :pass, :state, :xemail)
176
+ data = get_xml(:url => "generatessl", :params => options)
177
+ check_for_cpanel_errors_on(data)
178
+ end
179
+
180
+ # Displays the server's hostname.
181
+ def hostname
182
+ data = get_xml(:url => "gethostname")
183
+ check_for_cpanel_errors_on(data)["hostname"]
184
+ end
185
+
186
+ # Modifies the bandwidth usage (transfer) limit for a specific account.
187
+ #
188
+ # ==== Options
189
+ # * <tt>:user</tt> - Name of user to modify the bandwidth usage (transfer) limit for (string)
190
+ # * <tt>:bwlimit</tt> - Bandwidth usage (transfer) limit in MB (string)
191
+ def limit_bandwidth_usage(options = {})
192
+ requires!(options, :user, :bwlimit)
193
+
194
+ data = get_xml(:url => "limitbw", :params => options)
195
+ check_for_cpanel_errors_on(data)["bwlimit"]
196
+ end
197
+
198
+ # Lists all accounts on the server, or allows you to search for
199
+ # a specific account or set of accounts.
200
+ #
201
+ # ==== Options
202
+ # * <tt>:searchtype</tt> - Type of account search (<tt>"domain"</tt>, <tt>"owner"</tt>, <tt>"user"</tt>, <tt>"ip"</tt> or <tt>"package"</tt>)
203
+ # * <tt>:search</tt> - Search criteria, in Perl regular expression format (string)
204
+ def list_accounts(options = {})
205
+ data = get_xml(:url => "listaccts", :params => options)
206
+ check_for_cpanel_errors_on(data)["acct"]
207
+ end
208
+
209
+ # Lists all hosting packages that are available for use by
210
+ # the current WHM user. If the current user is a reseller,
211
+ # they may not see some packages that exist if those packages
212
+ # are not available to be used for account creation at this time.
213
+ def list_packages
214
+ data = get_xml(:url => "listpkgs")
215
+ check_for_cpanel_errors_on(data)["package"]
216
+ end
217
+
218
+ # Modifies account specific settings. We recommend changing the
219
+ # account's package instead with change_package. If the account
220
+ # is associated with a package, the account's settings will be
221
+ # changed whenever the package is changed. That may overwrite
222
+ # any changes you make with this function.
223
+ #
224
+ # ==== Options
225
+ # * <tt>:CPTHEME</tt> - cPanel theme name (string)
226
+ # * <tt>:domain</tt> - Domain name (string)
227
+ # * <tt>:HASCGI</tt> - Whether or not the domain has CGI access (boolean)
228
+ # * <tt>:LANG</tt> - Language to use in the account's cPanel interface (boolean)
229
+ # * <tt>:MAXFTP</tt> - Maximum number of FTP accounts the user can create. Must be between 0-999999, with 0 being unlimited (integer)
230
+ # * <tt>:MAXSQL</tt> - Maximum number of SQL databases the user can create. Must be between 0-999999, with 0 being unlimited (integer)
231
+ # * <tt>:MAXPOP</tt> - Maximum number of email accounts the user can create. Must be between 0-999999, with 0 being unlimited (integer)
232
+ # * <tt>:MAXLST</tt> - Maximum number of mailing lists the user can create. Must be between 0-999999, with 0 being unlimited (integer)
233
+ # * <tt>:MAXSUB</tt> - Maximum number of subdomains the user can create. Must be between 0-999999, with 0 being unlimited (integer)
234
+ # * <tt>:MAXPARK</tt> - Maximum number of parked domains the user can create. Must be between 0-999999, with 0 being unlimited (integer)
235
+ # * <tt>:MAXADDON</tt> - Maximum number of addon domains the user can create. Must be between 0-999999, with 0 being unlimited (integer)
236
+ # * <tt>:shell</tt> - Whether or not the domain has shell/SSH access (boolean)
237
+ # * <tt>:user</tt> - User name of the account (string)
238
+ def modify_account(options = {})
239
+ booleans!(options, :HASCGI, :LANG, :shell)
240
+ requires!(options, :user, :domain, :HASCGI, :CPTHEME, :LANG, :MAXPOP, :MAXFTP, :MAXLST, :MAXSUB,
241
+ :MAXPARK, :MAXADDON, :MAXSQL, :shell)
242
+
243
+ data = get_xml(:url => "modifyacct", :params => options)
244
+
245
+ check_for_cpanel_errors_on(data)
246
+ end
247
+
248
+ # Suspend an account. Returns <tt>true</tt> if it is successful,
249
+ # or <tt>false</tt> if it is not.
250
+ #
251
+ # ==== Options
252
+ # * <tt>:user</tt> - Username to suspend (string)
253
+ # * <tt>:reason</tt> - Reason for suspension (string)
254
+ def suspend_account(options = {})
255
+ requires!(options, :user, :reason)
256
+
257
+ data = get_xml(:url => "suspendacct", :params => options)
258
+ check_for_cpanel_errors_on(data)
259
+
260
+ data["status"] == "1" ? true : false
261
+ end
262
+
263
+ # Terminates a hosting account. <b>Please note that this action is irreversible!</b>
264
+ #
265
+ # ==== Options
266
+ # * <tt>:user</tt> - Username to terminate (string)
267
+ # * <tt>:keepdns</tt> - Keep DNS entries for the domain ("y" or "n")
268
+ def terminate_account(options = {})
269
+ requires!(options, :user)
270
+
271
+ data = get_xml(:url => "removeacct", :params => {
272
+ :user => options[:user],
273
+ :keepdns => options[:keepdns] || "n"
274
+ })
275
+
276
+ check_for_cpanel_errors_on(data)
277
+ end
278
+
279
+ # Unsuspend a suspended account. Returns <tt>true</tt> if it
280
+ # is successful, or <tt>false</tt> if it is not.
281
+ #
282
+ # ==== Options
283
+ # * <tt>:user</tt> - Username to unsuspend (string)
284
+ def unsuspend_account(options = {})
285
+ requires!(options, :user)
286
+
287
+ data = get_xml(:url => "unsuspendacct", :params => options)
288
+ check_for_cpanel_errors_on(data)
289
+
290
+ data["status"] == "1" ? true : false
291
+ end
292
+
293
+ # Returns the cPanel WHM version.
294
+ def version
295
+ data = get_xml(:url => 'version')
296
+ check_for_cpanel_errors_on(data)["version"]
297
+ end
298
+
299
+ private
300
+
301
+ # Grabs the XML response for a command to the server, and parses it.
302
+ #
303
+ # ==== Options
304
+ # * <tt>:url</tt> - URL of the XML API function (string)
305
+ # * <tt>:params</tt> - Passed in parameter hash (hash)
306
+ def get_xml(options = {})
307
+ requires!(options, :url)
308
+
309
+ prefix = @ssl ? "https" : "http"
310
+ params = []
311
+
312
+ unless options[:params].nil?
313
+ for key, value in options[:params]
314
+ params << Curl::PostField.content(key.to_s, value)
315
+ end
316
+ end
317
+
318
+ request = Curl::Easy.new("#{prefix}://#{@host}:#{@port}/xml-api/#{options[:url]}") do |connection|
319
+ puts "WHM: Requesting #{options[:url]}..." if @debug
320
+
321
+ connection.userpwd = "#{@username}:#{@password}" if @password
322
+ connection.headers["Authorization"] = "WHM #{@username}:#{@remote_key}" if @remote_key
323
+ connection.verbose = true if @debug
324
+ connection.timeout = 60
325
+ end
326
+
327
+ if request.http_post(params)
328
+ puts "Response: #{request.body_str}" if @debug
329
+ xml = XmlSimple.xml_in(request.body_str, { 'ForceArray' => false })
330
+ xml["result"].nil? ? xml : xml["result"]
331
+ end
332
+ end
333
+
334
+ # Returns the data, unless a <tt>status</tt> is equal to <tt>0</tt>,
335
+ # in which case a CommandFailedError exception is
336
+ # thrown with the <tt>statusmsg</tt> from the fetched XML.
337
+ #
338
+ # If the command does not support status messaging,
339
+ # then just return the raw data.
340
+ def check_for_cpanel_errors_on(data)
341
+ result = data["result"].nil? ? data : data["result"]
342
+ if result["status"] == "0"
343
+ raise CommandFailedError, result["statusmsg"]
344
+ else
345
+ result
346
+ end
347
+ end
348
+
349
+ def build_account(attributes) #:nodoc:
350
+ account = Account.new(attributes)
351
+ account.server = self
352
+ account
353
+ end
354
+ end
355
+ end
data/lib/whm.rb ADDED
@@ -0,0 +1,16 @@
1
+ $:.unshift(File.dirname(__FILE__))
2
+
3
+ require 'rubygems'
4
+ require 'curb' # As opposed to Net::HTTP (for faster requests)
5
+ require 'xmlsimple' # For simple XML parsing
6
+ require 'active_support' # For stringifying keys, etc.
7
+ require 'parameters' # For parameter requirements in methods
8
+ require 'validatable' # For object validation
9
+
10
+ require 'whm/exceptions'
11
+ require 'whm/server'
12
+ require 'whm/account'
13
+
14
+ module Whm
15
+ VERSION = '0.3.0'
16
+ end
@@ -0,0 +1,195 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require 'lib/whm'
3
+
4
+ describe Whm::Server do
5
+ before do
6
+ @server = Whm::Server.new(
7
+ :username => "username",
8
+ :password => "password",
9
+ :host => "dedicated.server.com"
10
+ )
11
+ end
12
+
13
+ it "should build a server object" do
14
+ @server.should_not be_nil
15
+
16
+ @server.host.should eql("dedicated.server.com")
17
+ @server.username.should eql("username")
18
+ @server.password.should eql("password")
19
+ end
20
+
21
+ it "should have default options" do
22
+ @server.debug.should eql(false)
23
+ @server.ssl.should eql(true)
24
+ @server.port.should eql(2087)
25
+ end
26
+
27
+ it "should handle successful commands from cPanel" do
28
+ end
29
+
30
+ it "should handle unsuccessful commands from cPanel" do
31
+ end
32
+
33
+ it "should list accounts" do
34
+ data = open(File.expand_path('spec/fixtures/listaccts.xml')).read
35
+
36
+ @server.expects(:list_accounts).returns(XmlSimple.xml_in(data))
37
+ @server.list_accounts.eql?(XmlSimple.xml_in(data))
38
+ end
39
+
40
+ it "should list packages" do
41
+ data = open('spec/fixtures/listpkgs.xml').read
42
+
43
+ @server.expects(:list_packages).returns(XmlSimple.xml_in(data))
44
+ @server.list_packages.eql?(XmlSimple.xml_in(data))
45
+ end
46
+
47
+ it "should display the actual server hostname" do
48
+ data = open('spec/fixtures/gethostname.xml').read
49
+
50
+ @server.expects(:hostname).returns(XmlSimple.xml_in(data)["hostname"])
51
+ @server.hostname.eql?("ns100.example.com")
52
+ end
53
+
54
+ it "should display the actual server version" do
55
+ data = open('spec/fixtures/version.xml').read
56
+
57
+ @server.expects(:version).returns(XmlSimple.xml_in(data)["version"])
58
+ @server.version.eql?("11.24.2")
59
+ end
60
+
61
+ it "should generate ssl certificates" do
62
+ data = open('spec/fixtures/generatessl.xml').read
63
+
64
+ params = {
65
+ :city => "Houston",
66
+ :co => "Domain LLC",
67
+ :cod => "Web",
68
+ :country => "US",
69
+ :email => "test@domain.com",
70
+ :host => "domain.com",
71
+ :pass => "password",
72
+ :state => "TX",
73
+ :xemail => "test@domain.com"
74
+ }
75
+
76
+ @server.expects(:generate_ssl_certificate).with(params).returns(XmlSimple.xml_in(data))
77
+ @server.generate_ssl_certificate(params).eql?(XmlSimple.xml_in(data))
78
+ end
79
+
80
+ it "should display account summaries" do
81
+ data = open('spec/fixtures/accountsummary.xml').read
82
+
83
+ params = {
84
+ :user => "magic"
85
+ }
86
+
87
+ @server.expects(:account_summary).with(params).returns(XmlSimple.xml_in(data))
88
+ @server.account_summary(params).eql?(XmlSimple.xml_in(data))
89
+ end
90
+
91
+ it "should change packages" do
92
+ data = open('spec/fixtures/accountsummary.xml').read
93
+
94
+ params = {
95
+ :user => "user",
96
+ :pkg => "new_plan"
97
+ }
98
+
99
+ @server.expects(:change_package).with(params).returns(XmlSimple.xml_in(data))
100
+ @server.change_package(params).eql?(XmlSimple.xml_in(data))
101
+ end
102
+
103
+ it "should create accounts" do
104
+ data = open('spec/fixtures/createacct.xml').read
105
+
106
+ params = {
107
+ :user => "user",
108
+ :domain => "domain.com"
109
+ }
110
+
111
+ @server.expects(:create_account).with(params).returns(XmlSimple.xml_in(data))
112
+ @server.create_account(params).eql?(XmlSimple.xml_in(data))
113
+ end
114
+
115
+ it "should suspend accounts" do
116
+ data = open('spec/fixtures/suspendacct.xml').read
117
+
118
+ params = {
119
+ :user => "user",
120
+ :reason => "N/A"
121
+ }
122
+
123
+ @server.expects(:suspend_account).with(params).returns(XmlSimple.xml_in(data))
124
+ @server.suspend_account(params).eql?(XmlSimple.xml_in(data))
125
+ end
126
+
127
+ it "should unsuspend accounts" do
128
+ data = open('spec/fixtures/unsuspendacct.xml').read
129
+
130
+ params = {
131
+ :user => "user"
132
+ }
133
+
134
+ @server.expects(:unsuspend_account).with(params).returns(XmlSimple.xml_in(data))
135
+ @server.unsuspend_account(params).eql?(XmlSimple.xml_in(data))
136
+ end
137
+
138
+ it "should terminate accounts" do
139
+ data = open('spec/fixtures/removeacct.xml').read
140
+
141
+ params = {
142
+ :user => "user"
143
+ }
144
+
145
+ @server.expects(:terminate_account).with(params).returns(XmlSimple.xml_in(data))
146
+ @server.terminate_account(params).eql?(XmlSimple.xml_in(data))
147
+ end
148
+
149
+ it "should limit an account's bandwidth usage limit" do
150
+ data = open('spec/fixtures/limitbw.xml').read
151
+
152
+ params = {
153
+ :user => "username",
154
+ :bwlimit => "1"
155
+ }
156
+
157
+ @server.expects(:limit_bandwidth_usage).with(params).returns(XmlSimple.xml_in(data))
158
+ @server.limit_bandwidth_usage(params).eql?(XmlSimple.xml_in(data))
159
+ end
160
+
161
+ it "should change account passwords" do
162
+ data = open('spec/fixtures/passwd.xml').read
163
+
164
+ params = {
165
+ :user => "username",
166
+ :pass => "password"
167
+ }
168
+
169
+ @server.expects(:change_account_password).with(params).returns(XmlSimple.xml_in(data))
170
+ @server.change_account_password(params).eql?(XmlSimple.xml_in(data))
171
+ end
172
+
173
+ it "should modify accounts" do
174
+ data = open('spec/fixtures/modifyacct.xml').read
175
+
176
+ params = {
177
+ :user => "user",
178
+ :domain => "domain.com",
179
+ :HASCGI => 0,
180
+ :CPTHEME => "x3",
181
+ :LANG => "english",
182
+ :MAXPOP => 3,
183
+ :MAXFTP => 0,
184
+ :MAXLST => 1,
185
+ :MAXSUB => 3,
186
+ :MAXPARK => 4,
187
+ :MAXADDON => 5,
188
+ :MAXSQL => 6,
189
+ :shell => 1
190
+ }
191
+
192
+ @server.expects(:modify_account).with(params).returns(XmlSimple.xml_in(data))
193
+ @server.modify_account(params).eql?(XmlSimple.xml_in(data))
194
+ end
195
+ end
@@ -0,0 +1,26 @@
1
+ begin
2
+ require 'spec'
3
+ rescue LoadError
4
+ require 'rubygems'
5
+ gem 'rspec'
6
+ require 'spec'
7
+ end
8
+
9
+ dir = File.dirname(__FILE__)
10
+
11
+ $:.unshift(File.join(dir, '/lib/'))
12
+
13
+ # Enable mocha mocking/stubbing
14
+ Spec::Runner.configure do |config|
15
+ config.mock_with :mocha
16
+ end
17
+
18
+ def stdout_for(&block)
19
+ # Inspired by http://www.ruby-forum.com/topic/58647
20
+ old_stdout = $stdout
21
+ $stdout = StringIO.new
22
+ yield
23
+ output = $stdout.string
24
+ $stdout = old_stdout
25
+ output
26
+ end
metadata ADDED
@@ -0,0 +1,104 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ivanoats-whm_xml
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ platform: ruby
6
+ authors:
7
+ - Ivan Storck
8
+ - Padraic McGee
9
+ - Josh Delsman
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+
14
+ date: 2009-04-17 00:00:00 -07:00
15
+ default_executable:
16
+ dependencies:
17
+ - !ruby/object:Gem::Dependency
18
+ name: xml-simple
19
+ type: :runtime
20
+ version_requirement:
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: 1.0.12
26
+ version:
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ type: :runtime
30
+ version_requirement:
31
+ version_requirements: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: 2.3.2
36
+ version:
37
+ - !ruby/object:Gem::Dependency
38
+ name: curb
39
+ type: :runtime
40
+ version_requirement:
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: 0.3.2
46
+ version:
47
+ - !ruby/object:Gem::Dependency
48
+ name: validatable
49
+ type: :runtime
50
+ version_requirement:
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: 1.6.7
56
+ version:
57
+ description: The whm_xml library provides a Ruby wrapper for the cPanel Web Host Manager (WHM) XML-API
58
+ email: ivanoats+whm_xml@gmail.com
59
+ executables: []
60
+
61
+ extensions: []
62
+
63
+ extra_rdoc_files:
64
+ - README.rdoc
65
+ files:
66
+ - Rakefile
67
+ - README.rdoc
68
+ - lib/parameters.rb
69
+ - lib/whm/exceptions.rb
70
+ - lib/whm/server.rb
71
+ - lib/whm.rb
72
+ - spec/server_spec.rb
73
+ - spec/spec_helper.rb
74
+ has_rdoc: true
75
+ homepage: http://github.com/ivanoats/whm_xml_api_ruby
76
+ post_install_message:
77
+ rdoc_options:
78
+ - --main
79
+ - README.rdoc
80
+ - --inline-source
81
+ - --charset=UTF-8
82
+ require_paths:
83
+ - lib
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: "0"
89
+ version:
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: "0"
95
+ version:
96
+ requirements: []
97
+
98
+ rubyforge_project:
99
+ rubygems_version: 1.2.0
100
+ signing_key:
101
+ specification_version: 2
102
+ summary: Web Host Manager (WHM) XML-API Ruby library
103
+ test_files:
104
+ - spec/server_spec.rb