lumberg 1.0.1 → 1.0.3

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.
Files changed (78) hide show
  1. data/.travis.yml +9 -3
  2. data/LICENSE +1 -1
  3. data/README.md +1 -1
  4. data/Rakefile +3 -1
  5. data/lib/lumberg.rb +32 -7
  6. data/lib/lumberg/config.rb +19 -0
  7. data/lib/lumberg/format_whm.rb +102 -0
  8. data/lib/lumberg/version.rb +1 -1
  9. data/lib/lumberg/whm/server.rb +42 -163
  10. data/lumberg.gemspec +7 -4
  11. data/spec/config_spec.rb +28 -0
  12. data/spec/spec_helper.rb +3 -3
  13. data/spec/vcr_cassettes/whm/account/accountsummary.yml +41 -29
  14. data/spec/vcr_cassettes/whm/account/changepackage.yml +73 -43
  15. data/spec/vcr_cassettes/whm/account/createacct.yml +101 -31
  16. data/spec/vcr_cassettes/whm/account/domainuserdata.yml +43 -29
  17. data/spec/vcr_cassettes/whm/account/editquota.yml +78 -57
  18. data/spec/vcr_cassettes/whm/account/limitbw.yml +79 -57
  19. data/spec/vcr_cassettes/whm/account/listaccts.yml +195 -100
  20. data/spec/vcr_cassettes/whm/account/listsuspended.yml +41 -29
  21. data/spec/vcr_cassettes/whm/account/modifyacct.yml +61 -42
  22. data/spec/vcr_cassettes/whm/account/myprivs.yml +41 -29
  23. data/spec/vcr_cassettes/whm/account/passwd.yml +44 -29
  24. data/spec/vcr_cassettes/whm/account/removeacct.yml +134 -57
  25. data/spec/vcr_cassettes/whm/account/restoreaccount.yml +310 -135
  26. data/spec/vcr_cassettes/whm/account/setsiteip.yml +166 -127
  27. data/spec/vcr_cassettes/whm/account/suspend.yml +75 -43
  28. data/spec/vcr_cassettes/whm/account/unsuspend.yml +46 -29
  29. data/spec/vcr_cassettes/whm/dns/adddns.yml +61 -43
  30. data/spec/vcr_cassettes/whm/dns/addzonerecord.yml +42 -29
  31. data/spec/vcr_cassettes/whm/dns/dumpzone.yml +44 -29
  32. data/spec/vcr_cassettes/whm/dns/editzonerecord.yml +61 -43
  33. data/spec/vcr_cassettes/whm/dns/getzonerecord.yml +60 -43
  34. data/spec/vcr_cassettes/whm/dns/killdns.yml +42 -29
  35. data/spec/vcr_cassettes/whm/dns/listmxs.yml +23 -15
  36. data/spec/vcr_cassettes/whm/dns/listzones.yml +22 -15
  37. data/spec/vcr_cassettes/whm/dns/lookupnsip.yml +40 -29
  38. data/spec/vcr_cassettes/whm/dns/removezonerecord.yml +61 -43
  39. data/spec/vcr_cassettes/whm/dns/resetzone.yml +42 -29
  40. data/spec/vcr_cassettes/whm/dns/resolvedomainname.yml +40 -29
  41. data/spec/vcr_cassettes/whm/dns/savemxs.yml +23 -15
  42. data/spec/vcr_cassettes/whm/reseller/acctcounts.yml +41 -29
  43. data/spec/vcr_cassettes/whm/reseller/listacls.yml +22 -15
  44. data/spec/vcr_cassettes/whm/reseller/listresellers.yml +22 -15
  45. data/spec/vcr_cassettes/whm/reseller/resellerstats.yml +42 -29
  46. data/spec/vcr_cassettes/whm/reseller/saveacllist.yml +76 -57
  47. data/spec/vcr_cassettes/whm/reseller/setacls.yml +40 -29
  48. data/spec/vcr_cassettes/whm/reseller/setresellerips.yml +42 -28
  49. data/spec/vcr_cassettes/whm/reseller/setresellerlimits.yml +41 -29
  50. data/spec/vcr_cassettes/whm/reseller/setresellermainip.yml +59 -43
  51. data/spec/vcr_cassettes/whm/reseller/setresellernameservers.yml +58 -43
  52. data/spec/vcr_cassettes/whm/reseller/setresellerpackagelimit.yml +61 -43
  53. data/spec/vcr_cassettes/whm/reseller/setupreseller.yml +41 -29
  54. data/spec/vcr_cassettes/whm/reseller/suspendreseller.yml +75 -44
  55. data/spec/vcr_cassettes/whm/reseller/terminatereseller.yml +83 -46
  56. data/spec/vcr_cassettes/whm/reseller/unsetupreseller.yml +41 -29
  57. data/spec/vcr_cassettes/whm/reseller/unsuspendreseller.yml +46 -29
  58. data/spec/vcr_cassettes/whm/server/addip.yml +24 -15
  59. data/spec/vcr_cassettes/whm/server/applist.yml +22 -15
  60. data/spec/vcr_cassettes/whm/server/delip.yml +23 -15
  61. data/spec/vcr_cassettes/whm/server/gethostname.yml +22 -15
  62. data/spec/vcr_cassettes/whm/server/getlanglist.yml +22 -15
  63. data/spec/vcr_cassettes/whm/server/listips.yml +22 -15
  64. data/spec/vcr_cassettes/whm/server/loadavg.yml +26 -19
  65. data/spec/vcr_cassettes/whm/server/my_function.yml +59 -43
  66. data/spec/vcr_cassettes/whm/server/nvget.yml +22 -15
  67. data/spec/vcr_cassettes/whm/server/nvset.yml +22 -15
  68. data/spec/vcr_cassettes/whm/server/reboot.yml +22 -15
  69. data/spec/vcr_cassettes/whm/server/sethostname.yml +24 -15
  70. data/spec/vcr_cassettes/whm/server/setresolvers.yml +23 -15
  71. data/spec/vcr_cassettes/whm/server/showbw.yml +22 -15
  72. data/spec/vcr_cassettes/whm/server/systemloadavg.yml +40 -29
  73. data/spec/vcr_cassettes/whm/server/version.yml +22 -15
  74. data/spec/whm/account_spec.rb +0 -1
  75. data/spec/whm/server_spec.rb +2 -106
  76. metadata +98 -26
  77. data/lib/net_http_hacked.rb +0 -42
  78. data/spec/vcr_cassettes/whm/server/response_type.yml +0 -85
data/.travis.yml CHANGED
@@ -1,11 +1,17 @@
1
+ language: ruby
1
2
  script: "bundle exec rake spec"
2
3
  notifications:
3
- disabled: true
4
+ email:
5
+ recipients:
6
+ - engineering@internal.site5.com
7
+ on_success: never
8
+ on_failure: always
4
9
  rvm:
5
10
  - 1.8.7
6
11
  - 1.9.2
7
12
  - 1.9.3
8
13
  - ree
9
- - rbx
10
14
  - rbx-head
11
- - jruby
15
+ - rbx-18mode
16
+ - jruby-18mode
17
+ - jruby-19mode
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2011 Site5 LLC
1
+ Copyright (c) 2012 Site5.com <http://www.site5.com>
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -243,4 +243,4 @@ remove any sensitive information from your cassettes.
243
243
  Copyright
244
244
  =========
245
245
 
246
- Copyright (c) 2011 Site5. See LICENSE for details.
246
+ Copyright (c) 2012 Site5.com. See LICENSE for details.
data/Rakefile CHANGED
@@ -14,6 +14,8 @@ begin
14
14
  rescue LoadError
15
15
  end
16
16
 
17
+ load 'vcr/tasks/vcr.rake'
18
+
17
19
  RSpec::Core::RakeTask.new :spec
18
20
  Bundler::GemHelper.install_tasks
19
21
 
@@ -26,7 +28,7 @@ task :sanitize_cassettes do
26
28
  files.each do |file|
27
29
  old = File.read(file)
28
30
  if old.match(/#{ENV['WHM_HASH']}|#{ENV['WHM_HOST']}/)
29
- puts "Sanitizing #{file}"
31
+ puts "Sanitizing #{file}"
30
32
  old.gsub!(ENV['WHM_HASH'], 'iscool')
31
33
  old.gsub!(ENV['WHM_HOST'], 'myhost.com')
32
34
  File.open(file, 'w') do |f|
data/lib/lumberg.rb CHANGED
@@ -3,21 +3,46 @@ $:.unshift(File.dirname(__FILE__))
3
3
  # External Libs
4
4
  require 'json'
5
5
  require 'uri'
6
- require 'net/http'
7
- require 'net/https'
6
+ require 'excon'
7
+ require 'faraday'
8
+ require 'faraday_middleware'
9
+ require 'logger'
8
10
 
9
11
  # Internal Libs
10
- require 'net_http_hacked'
12
+ require 'lumberg/format_whm'
11
13
  require 'lumberg/version'
12
14
  require 'lumberg/exceptions'
15
+ require 'lumberg/config'
13
16
  require 'lumberg/whm/args'
14
17
  require 'lumberg/whm'
15
18
 
16
19
  module Lumberg
17
- class << self
18
- def base_path
19
- File.dirname(__FILE__)
20
- end
20
+
21
+ extend self
22
+
23
+ attr_accessor :configuration
24
+
25
+ def base_path
26
+ File.dirname(__FILE__)
21
27
  end
28
+
29
+ self.configuration ||= Lumberg::Config.new
30
+
31
+ # Specificy the config via block
32
+ #
33
+ # ==== Attributes
34
+ #
35
+ # * +debug+ - Set to true to log debug info to $stderr, or a file path
36
+ #
37
+ # ==== Example
38
+ #
39
+ # Lumberg.config do |c|
40
+ # c.dubug "path/to/file.log"
41
+ # end
42
+ def config
43
+ yield self.configuration if block_given?
44
+ self.configuration.options
45
+ end
46
+
22
47
  end
23
48
 
@@ -0,0 +1,19 @@
1
+ module Lumberg
2
+ # Holds the configuration for Lumberg
3
+ class Config
4
+ attr_accessor :options
5
+
6
+ def initialize
7
+ @options = {}
8
+ end
9
+
10
+ def [](v)
11
+ @options[v]
12
+ end
13
+
14
+ # Debug output. value can be either true to output to $stderr or a path to a file
15
+ def debug(output)
16
+ @options[:debug] = output
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,102 @@
1
+ module Lumberg
2
+ class FormatWhm < Faraday::Response::Middleware
3
+
4
+ def initialize(env, *args, &block)
5
+ @type = args[0]
6
+ @key = args[1]
7
+ @boolean_params = args[2]
8
+ super(env)
9
+ end
10
+
11
+ def on_complete(env)
12
+ env[:body] = format_response(env[:body])
13
+ end
14
+
15
+ def response_values(env)
16
+ {:status => env[:status], :headers => env[:response_headers], :body => env[:body]}
17
+ end
18
+
19
+ private
20
+
21
+ def format_response(response)
22
+ success, message, params = false, nil, {}
23
+
24
+ case @type || response_type(response)
25
+ when :action
26
+ success, message, params = format_action_response(response)
27
+ when :query
28
+ success, message, params = format_query_response(response)
29
+ when :error
30
+ message = response['error']
31
+ when :unknown
32
+ message = "Unknown error occurred #{response.inspect}"
33
+ end
34
+
35
+ params = Whm::symbolize_keys(params)
36
+ params = Whm::to_bool(params, @boolean_params)
37
+
38
+ {:success => success, :message => message, :params => params}
39
+ end
40
+
41
+ def response_type(response)
42
+ if !response.respond_to?(:has_key?)
43
+ :unknown
44
+ elsif response.has_key?('error')
45
+ :error
46
+ elsif response.has_key?(@key)
47
+ :action
48
+ elsif response.has_key?('status') && response.has_key?('statusmsg')
49
+ :query
50
+ else
51
+ :unknown
52
+ end
53
+ end
54
+
55
+ def format_action_response(response)
56
+ # Some API methods ALSO return a 'status' as
57
+ # part of a result. We only use this value if it's
58
+ # part of the results hash
59
+ item = response[@key]
60
+ unless item.is_a?(Array) || item.is_a?(Hash)
61
+ res = {@key => item}
62
+ success, message = true, ""
63
+ else
64
+ result = nil
65
+ if item.first.is_a?(Hash)
66
+ result = item.first
67
+ res = (item.size > 1 ? item.dup : item.first.dup)
68
+ else
69
+ res = item.dup
70
+
71
+ # more hacks for WHM silly API
72
+ if response.has_key?('result')
73
+ result_node = response['result']
74
+ node_with_key_status = result_node.is_a?(Hash) && result_node.has_key?('status')
75
+ result = (node_with_key_status ? result_node : result_node.first)
76
+ else
77
+ res.delete('status')
78
+ res.delete('statusmsg')
79
+ end
80
+ end
81
+ unless result.nil?
82
+ success = result['status'].to_i == 1
83
+ message = result['statusmsg']
84
+ end
85
+ end
86
+ return success, message, res
87
+ end
88
+
89
+ def format_query_response(response)
90
+ success = response['status'].to_i == 1
91
+ message = response['statusmsg']
92
+
93
+ # returns the rest as a params arg
94
+ res = response.dup
95
+ res.delete('status')
96
+ res.delete('statusmsg')
97
+
98
+ return success, message, res
99
+ end
100
+
101
+ end
102
+ end
@@ -1,3 +1,3 @@
1
1
  module Lumberg
2
- VERSION = '1.0.1'
2
+ VERSION = '1.0.3'
3
3
  end
@@ -1,5 +1,4 @@
1
- require 'cgi'
2
- require 'base64'
1
+ Faraday.register_middleware :response, :format_whm => Lumberg::FormatWhm
3
2
 
4
3
  module Lumberg
5
4
  module Whm
@@ -19,9 +18,6 @@ module Lumberg
19
18
  # API username - :default => root
20
19
  attr_accessor :user
21
20
 
22
- # Raw HTTP response from WHM
23
- attr_accessor :raw_response
24
-
25
21
  # WHM parsed response
26
22
  attr_reader :response
27
23
 
@@ -44,11 +40,11 @@ module Lumberg
44
40
  attr_accessor :force_response_type
45
41
 
46
42
  #
47
- # ==== Required
43
+ # ==== Required
48
44
  # * <tt>:host</tt> - PENDING
49
45
  # * <tt>:hash</tt> - PENDING
50
46
  #
51
- # ==== Optional
47
+ # ==== Optional
52
48
  # * <tt>:user</tt> - PENDING
53
49
  # * <tt>:ssl</tt> - PENDING
54
50
  # * <tt>:basic_auth</tt>
@@ -63,30 +59,19 @@ module Lumberg
63
59
  @host = options.delete(:host)
64
60
  @hash = format_hash(options.delete(:hash))
65
61
  @user = (options.has_key?(:user) ? options.delete(:user) : 'root')
66
- @basic_auth = options.has_key?(:basic_auth) && options.delete(:basic_auth)
67
-
62
+ @basic_auth = options.delete(:basic_auth)
68
63
  @base_url = format_url(options)
69
64
  end
70
65
 
71
66
  def perform_request(function, options = {})
72
- @function = function
73
-
74
67
  # WHM sometime uses different keys for the result hash
75
- @key = options.delete(:key) || 'result'
76
-
68
+ @key = options.delete(:key) || 'result'
69
+ @function = function
77
70
  @params = format_query(options)
78
- uri = URI.parse("#{@base_url}#{function}?#{@params}")
79
71
 
80
72
  yield self if block_given?
81
73
 
82
- req = prepare_request(uri)
83
-
84
- # Do the request
85
- res = do_request(uri, req)
86
-
87
- @raw_response = res
88
- @response = JSON.parse(@raw_response.body)
89
- format_response
74
+ do_request(@base_url, function, @params)
90
75
  end
91
76
 
92
77
  def get_hostname
@@ -185,136 +170,59 @@ module Lumberg
185
170
  perform_request('reboot', {:key => "reboot"})
186
171
  end
187
172
 
188
- protected
189
- def response_type
190
- if !@force_response_type.nil?
191
- @force_response_type
192
- elsif !@response.respond_to?(:has_key?)
193
- :unknown
194
- elsif @response.has_key?('error')
195
- :error
196
- elsif @response.has_key?(@key)
197
- :action
198
- elsif @response.has_key?('status') && @response.has_key?('statusmsg')
199
- :query
200
- else
201
- :unknown
202
- end
203
- end
173
+ private
204
174
 
205
- def format_response
206
- success, message, params = false, nil, {}
207
-
208
- case response_type
209
- when :action
210
- success, message, params = format_action_response
211
- when :query
212
- success, message, params = format_query_response
213
- when :error
214
- message = @response['error']
215
- when :unknown
216
- message = "Unknown error occurred #{@response.inspect}"
217
- end
218
-
219
- params = Whm::to_bool(params, @boolean_params) unless @boolean_params.nil?
220
-
221
- # Reset this for subsequent requests
175
+ def do_request(uri, function, params)
176
+ @response = Faraday.new(:url => uri, :ssl => ssl_options) do |c|
177
+ c.basic_auth @user, @hash
178
+ c.params = params
179
+ c.request :url_encoded
180
+ c.response :format_whm, @force_response_type, @key, @boolean_params
181
+ c.response :logger, create_logger_instance
182
+ c.response :json
183
+ c.adapter :excon
184
+ end.get(function).body
222
185
  @force_response_type = nil
223
- {:success => success, :message => message, :params => Whm::symbolize_keys(params)}
224
- end
225
-
226
- def format_url(options = {})
227
- @ssl = true if @ssl.nil?
228
- port = (@ssl ? 2087 : 2086)
229
- proto = (@ssl ? 'https' : 'http')
230
-
231
- "#{proto}://#{@host}:#{port}/json-api/"
232
- end
233
-
234
- def format_hash(hash)
235
- raise Lumberg::WhmArgumentError.new("Missing WHM hash") unless hash.is_a?(String)
236
- hash.gsub(/\n|\s/, '')
186
+ @response
237
187
  end
238
188
 
239
189
  def format_query(hash)
240
- elements = []
241
- hash.each do |key, value|
190
+ hash.inject({}) do |params, (key, value)|
242
191
  value = 1 if value === true
243
192
  value = 0 if value === false
244
- elements << "#{CGI::escape(key.to_s)}=#{CGI::escape(value.to_s)}"
193
+ params[key] = value
194
+ params
245
195
  end
246
- elements.sort.join('&')
247
196
  end
248
197
 
249
- private
250
-
251
- def do_request(uri, req)
252
- begin
253
- Net::HTTP.skip_bad_headers = true
254
- http = Net::HTTP.new(uri.host, uri.port)
255
- http.set_debug_output($stderr) if ENV['LUMBERG_DEBUG']
256
-
257
- enable_ssl(http) if uri.port == 2087
258
-
259
- http.start do |h|
260
- h.request(req)
261
- end
262
- rescue Exception => e
263
- puts "Error when sending the request.
264
- Enable debug output by setting the environment variable LUMBERG_DEBUG and try again."
265
- raise e
266
- ensure
267
- Net::HTTP.skip_bad_headers = false
268
- end
198
+ def create_logger_instance
199
+ Logger.new(Lumberg.configuration[:debug].is_a?(TrueClass) ? $stderr : Lumberg.configuration[:debug])
269
200
  end
270
201
 
271
- def format_action_response
272
- # Some API methods ALSO return a 'status' as
273
- # part of a result. We only use this value if it's
274
- # part of the results hash
275
- item = @response[@key]
276
-
277
- unless item.is_a?(Array) || item.is_a?(Hash)
278
- res = {@key => item}
279
- success, message = true, ""
202
+ def ssl_options
203
+ if @ssl_verify
204
+ {
205
+ :verify_mode => OpenSSL::SSL::VERIFY_PEER,
206
+ :ca_file => File.join(Lumberg::base_path, "cacert.pem")
207
+ }
280
208
  else
281
- result = nil
282
- if item.first.is_a?(Hash)
283
- result = item.first
284
- res = (item.size > 1 ? item.dup : item.first.dup)
285
- else
286
- res = item.dup
287
-
288
- # more hacks for WHM silly API
289
- if @response.has_key?('result')
290
- result_node = @response['result']
291
- node_with_key_status = result_node.is_a?(Hash) && result_node.has_key?('status')
292
- result = (node_with_key_status ? result_node : result_node.first)
293
- else
294
- res.delete('status')
295
- res.delete('statusmsg')
296
- end
297
- end
298
-
299
- unless result.nil?
300
- success = result['status'].to_i == 1
301
- message = result['statusmsg']
302
- end
209
+ {
210
+ :verify_mode => OpenSSL::SSL::VERIFY_NONE
211
+ }
303
212
  end
304
-
305
- return success, message, res
306
213
  end
307
214
 
308
- def format_query_response
309
- success = @response['status'].to_i == 1
310
- message = @response['statusmsg']
215
+ def format_url(options = {})
216
+ @ssl = true if @ssl.nil?
217
+ port = (@ssl ? 2087 : 2086)
218
+ proto = (@ssl ? 'https' : 'http')
311
219
 
312
- # returns the rest as a params arg
313
- res = @response.dup
314
- res.delete('status')
315
- res.delete('statusmsg')
220
+ "#{proto}://#{@host}:#{port}/json-api/"
221
+ end
316
222
 
317
- return success, message, res
223
+ def format_hash(hash)
224
+ raise Lumberg::WhmArgumentError.new("Missing WHM hash") unless hash.is_a?(String)
225
+ hash.gsub(/\n|\s/, '')
318
226
  end
319
227
 
320
228
  # Creates WHM::Whatever.new(:server => @server)
@@ -337,35 +245,6 @@ module Lumberg
337
245
  end
338
246
  end
339
247
 
340
- def prepare_request(uri)
341
- # Setup request URL
342
- url = uri.path
343
- query = uri.query
344
- url << "?" + query unless query.nil? || query.empty?
345
-
346
- req = Net::HTTP::Get.new(url)
347
-
348
- # Add Auth Header
349
- if basic_auth
350
- encoded = Base64.encode64("#{@user}:#{@hash}")
351
- auth = "Basic #{encoded}"
352
- else
353
- auth = "WHM #{@user}:#{@hash}"
354
- end
355
- req.add_field("Authorization", auth)
356
- req
357
- end
358
-
359
- def enable_ssl(http)
360
- if @ssl_verify
361
- http.verify_mode = OpenSSL::SSL::VERIFY_PEER
362
- http.ca_file = File.join(Lumberg::base_path, "cacert.pem")
363
- else
364
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
365
- end
366
- http.use_ssl = true
367
- end
368
-
369
248
  end
370
249
  end
371
250
  end