fusebox 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,18 +1,30 @@
1
+ # fusebox
2
+
3
+ ## Description
4
+
1
5
  [FuseMail](http://fusemail.com) is a business email hosting provider offering outsourced email hosting to businesses and resellers.
2
6
 
3
7
  **fusebox** is a ruby gem that provides a 1:1 native ruby interface for every command of [FuseMail Platform Programming Interface v2.6](http://www.fusemail.com/support/administration-api), which allows you to manage your accounts, domains, forwards, and aliases via an underlying HTTP interface.
4
8
 
5
9
  ## Installation
6
- gem install fusebox
10
+ $ gem install fusebox
7
11
 
8
12
  ## Configuration
9
- Although the library supports passing a username and password to {Fusebox::Request#initialize}, we recommend storing authentication information in a yaml file within {Fusebox::Request.auth_yaml_paths} as:
13
+ Although the library supports passing a username and password to {Fusebox::Request#initialize}, we recommend storing authentication information in a YAML file within {Fusebox::Request.auth_yaml_paths} as:
10
14
 
11
- # cat ~/.fusemail.yaml
15
+ $ cat ~/.fusemail.yaml
12
16
  username: my_username
13
17
  password: my_password
14
18
 
15
- ## Examples
19
+ ## Command Line Interface (CLI)
20
+ fusebox comes with a command line interface (written on the amazing [thor](http://github.com/wycats/thor/)). CLI usage requires the setup of a ~/.fusemail.yaml authentication file. For a command list type:
21
+ $ fusebox help
22
+ or for command specific flags, e.g. "rm"
23
+ $ fusebox help rm
24
+
25
+ Note: The CLI interface *currently* assumes all group accounts are named postmaster@example.com, and that the username for all accounts is a full email address.
26
+
27
+ ## Library Examples
16
28
  ### Fetch a list of users
17
29
  response = Fusebox::Request.new.report
18
30
  if response.success?
@@ -27,13 +39,13 @@ Although the library supports passing a username and password to {Fusebox::Reque
27
39
  puts "Failure: " + response.detail
28
40
  end
29
41
 
42
+ See the [Fusebox::Request](http://rubydoc.info/github/mudbugmedia/fusebox/master/Fusebox/Request) documentation for more commands.
30
43
 
31
44
  ## Documentation
32
- http://rubydoc.info/github/mudbugmedia/fusebox/master/frames
45
+ * [Project Documentation](http://rubydoc.info/github/mudbugmedia/fusebox/master/frames)
46
+ * [Command Documentation](http://rubydoc.info/github/mudbugmedia/fusebox/master/Fusebox/Request)
33
47
 
34
48
  ## TODO
35
- * Ruby 1.8's OpenSSL does not verify certificates and displays "warning: peer certificate won't be verified in this SSL session"
36
- * CLI tools with Thor
37
49
  * Logging hook
38
50
  * Leverage ActiveModel to create Account, Domain, Alias, etc, classes.
39
51
 
data/bin/fusebox ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require File.expand_path('../../lib/fusebox', __FILE__)
5
+ require 'fusebox/cli'
6
+
7
+ # Unavailable until we can confirm our final behavior
8
+ # config_rc = File.expand_path('~/.fuseboxrc')
9
+ # require config_rc if File.exist?(config_rc)
10
+
11
+ Fusebox::Cli.start
@@ -0,0 +1,131 @@
1
+ require 'thor'
2
+ require 'fusebox/core_ext/array'
3
+
4
+ module Fusebox
5
+
6
+ # These methods are executed via the `bin/fusebox` executable
7
+ # @todo
8
+ # * Allow specification of group admin username-part instead of 'postmaster' (via yaml? fuseboxrc?)
9
+ # * Exit codes
10
+ # * Flags for simple, non-table output for report methods (to allow piping)
11
+ class Cli < Thor
12
+ include Thor::Actions
13
+
14
+ desc "add user@example.com password first_name last_name", "Create user account under a group"
15
+ def add (username, password, first_name, last_name)
16
+ group_parent = username.gsub /.*(@.*)/, 'postmaster\1'
17
+ response = Fusebox::Request.new.order(:account_type => 'group_subaccount', :group_parent => group_parent, :user => username, :password => password, :first_name => first_name, :last_name => last_name)
18
+ say response.detail
19
+ end
20
+
21
+ desc "alias-add user@example.com alias1@example.com [alias2@example.com [...]]", "Add an alias to an account"
22
+ def alias_add(username, *aliases)
23
+ response = Fusebox::Request.new.modify(:user => username, :alias => aliases)
24
+ say response.detail
25
+ end
26
+
27
+ desc "alias-ls user@example.com", "List aliases for a user"
28
+ def alias_ls (username)
29
+ response = Fusebox::Request.new.reportmail(:user => username, :report_type => 'alias')
30
+ if response.success?
31
+ response.records.sort { |x,y| x[:email_name] <=> y[:email_name]}.each { |a| say a[:email_name] }
32
+ else
33
+ warn response.detail
34
+ end
35
+ end
36
+
37
+ desc "alias-rm user@example.com alias1@example.com", "Remove an alias from a maccount"
38
+ def alias_rm (username, alias_address)
39
+ response = Fusebox::Request.new.removealias(:user => username, :alias => alias_address)
40
+ say response.detail
41
+ end
42
+
43
+ desc "domain-add [postmaster@]example.com new.example.com", "Add a domain a group account"
44
+ def domain_add (username, domain)
45
+ username = "postmaster@#{username}" unless username =~ /@/
46
+ response = Fusebox::Request.new.adddomain(:user => username, :domain => domain)
47
+ say response.detail
48
+ end
49
+
50
+ desc "domain-rm secondary.example.com", "Remove a domain"
51
+ method_options [:force, '-f'] => false
52
+ def domain_rm (domain)
53
+ if options[:force] || yes?("Are you sure you want to remove domain: #{domain}? [y/N]")
54
+ response = Fusebox::Request.new.removedomain(:domain => domain, :confirm => true)
55
+ say response.detail
56
+ end
57
+ end
58
+
59
+ desc "enable user@example.com", "Enable a suspended user account"
60
+ def enable (username)
61
+ response = Fusebox::Request.new.enable(:user => username)
62
+ say response.detail
63
+ end
64
+
65
+ desc "get [user@]example.com", "Get aliases, forwarders, and mailing lists for an account"
66
+ # @todo Display account metadata from `report`
67
+ def get (username)
68
+ username = "postmaster@#{username}" unless username =~ /@/
69
+ response = Fusebox::Request.new.reportmail(:user => username)
70
+ if response.success?
71
+ say response.records.sort { |x,y| x[:email_name] <=> y[:email_name]}.to_ascii_table [:username, :internal_account_id, :email_type, :email_name, :email_destination], %w(Username ID Type Name Destination)
72
+ else
73
+ warn response.detail
74
+ end
75
+ end
76
+
77
+ desc "group-add [postmaster@]example.com [password]", "Create a group account"
78
+ def group_add (username, password = nil)
79
+ username = "postmaster@#{username}" unless username =~ /@/
80
+ last, first = username.split /@/
81
+ password ||= ActiveSupport::SecureRandom.hex
82
+ response = Fusebox::Request.new.order(:account_type => 'standard', :user => username, :password => password, :first_name => first, :last_name => last)
83
+ say response.detail
84
+ end
85
+
86
+ desc "ls [[postmaster@]example.com]", "List accounts. This will list all group accounts if argument is blank"
87
+ method_options [:recursive, '-r'] => :boolean
88
+ # @todo add flag for ignoring terminated accounts
89
+ def ls (username = 'all')
90
+ username = "postmaster@#{username}" unless username =~ /@/ || username == 'all'
91
+ recursive = options[:recursive] || (username == 'all' ? false : true)
92
+ response = Fusebox::Request.new.report(:user => username, :group_subaccount => recursive, :report_type => 'extended')
93
+ if response.success?
94
+ say response.records.sort { |x,y| x[:username] <=> y[:username]}.to_ascii_table([:username, :creation_date, :internal_account_id, :status, :disk_usage], %w(Username Created ID Status Disk))
95
+ else
96
+ warn response.detail
97
+ end
98
+ end
99
+
100
+ desc "passwd user@example.com [newpassword]", "Change a user's password (will prompt if password left blank)"
101
+ def passwd (username, password = nil)
102
+ password = ask "New Password:" unless password
103
+ response = Fusebox::Request.new.modify(:user => username, :password => password)
104
+ say response.detail
105
+ end
106
+
107
+ desc "rename old@example.com new@example.com", "Rename an account's username"
108
+ def rename (old_username, new_username)
109
+ response = Fusebox::Request.new.changeusername(:user => old_username, :newuser => new_username)
110
+ say response.detail
111
+ end
112
+
113
+ desc "rm user@example.com", "Terminate a user or group account immediately"
114
+ method_options :purge => false
115
+ method_options [:force, '-f'] => false
116
+ def rm (username)
117
+ if options[:force] || yes?("Are you sure you want to remove user: #{username}? [y/N]")
118
+ response = Fusebox::Request.new.terminate(:user => username, :purge => options[:purge])
119
+ say response.detail
120
+ else
121
+ say "No action taken."
122
+ end
123
+ end
124
+
125
+ desc "suspend user@example.com", "Suspend a user account"
126
+ def suspend (username)
127
+ response = Fusebox::Request.new.suspend(:user => username)
128
+ say response.detail
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,47 @@
1
+ class Array
2
+
3
+ # Return an ASCII table for an array of hashes
4
+ # @example
5
+ # [{:a => "Uno", :b => "Dos"}, {:a => "Ichi", :b => "Ni"}].to_ascii_table([:a, :b], %w(One Two))
6
+ # @param [Array<Symbol>] keys Which keys to display, in order
7
+ # @param [Array<Symbol>] labels Column headings for the keys
8
+ # @return [String]
9
+ def to_ascii_table (keys, labels)
10
+ raise ArgumentError, "`labels` length does not match `keys` length" if keys.length != labels.length
11
+ return '' if self.length == 0
12
+ raise ArgumentError, "expected elements to be Hash instances; instead received: #{first.inspect}" unless first.is_a?(Hash)
13
+
14
+ widths = keys.map do |key|
15
+ ([Hash[keys.zip(labels)]] + self).map { |row| row[key].to_s.length }.max
16
+ end
17
+
18
+ text = ''
19
+
20
+ text += to_ascii_table_hr(widths)
21
+
22
+ labels.each_with_index do |key, i|
23
+ text += "| " + labels[i].ljust(widths[i] + 1)
24
+ end
25
+ text += "|\n"
26
+
27
+ text += to_ascii_table_hr(widths)
28
+
29
+ each do |row|
30
+ keys.each_with_index do |key, i|
31
+ text += "| " + row[key].ljust(widths[i] + 1)
32
+ end
33
+ text += "|\n"
34
+ end
35
+
36
+ text += to_ascii_table_hr(widths)
37
+ text
38
+ end
39
+
40
+ protected
41
+ # Print a horizonal divider calc
42
+ # @param [Array<Fixnum>] widths List of column widths
43
+ def to_ascii_table_hr(widths)
44
+ '+' + '-' * (widths.inject(&:+) + widths.length * 3 - 1 ) + "+\n"
45
+ end
46
+
47
+ end
@@ -203,8 +203,8 @@ module Fusebox
203
203
  # The terminate request is used to permanently remove an account and all of the account data associated with it. This operation cannot be reversed and therefore should be used with caution.
204
204
  # @see http://www.fusemail.com/support/administration-api/requests/terminate terminate API documentation
205
205
  # @param [Array] opts
206
- # @option opts [String] 'user' Username of FuseMail account to terminate
207
- # @option opts [Boolean] 'purge' (false) Will purge all data (such as removing the username) from our system. This process might take a few hours to complete.
206
+ # @option opts [String] :user Username of FuseMail account to terminate
207
+ # @option opts [Boolean] :purge (false) Will purge all data (such as removing the username) from our system. This process might take a few hours to complete.
208
208
  # @return [Response]
209
209
  def terminate (opts)
210
210
  default_options = {
@@ -219,8 +219,8 @@ module Fusebox
219
219
  # This request will remove a single alias from a fusemail account
220
220
  # @see http://www.fusemail.com/support/administration-api/requests/removealias removealias API documentation
221
221
  # @param [Array] opts
222
- # @option opts [String] 'user' FuseMail user to delete alias from
223
- # @option opts [String] 'alias' alias to delete (e.g. user@example.com )
222
+ # @option opts [String] :user FuseMail user to delete alias from
223
+ # @option opts [String] :alias alias to delete (e.g. user@example.com )
224
224
  # @return [Response]
225
225
  def removealias (opts)
226
226
  default_options = {
@@ -235,8 +235,8 @@ module Fusebox
235
235
  # This request will remove a domain name and all its mail aliases, auto-responders, mailing lists & forwarders associated with it. Please see below for the specific requirements for this request.
236
236
  # @see http://www.fusemail.com/support/administration-api/requests/removedomain removedomain API documentation
237
237
  # @param [Array] opts
238
- # @option opts [String] 'domain' The domain to delete
239
- # @option opts [Boolean] 'confirm' (true) This must be set to true to confirm that you understand all aliases, auto-responders, mailing lists & forwarders with this domain will be permanently deleted.
238
+ # @option opts [String] :domain The domain to delete
239
+ # @option opts [Boolean] :confirm (true) This must be set to true to confirm that you understand all aliases, auto-responders, mailing lists & forwarders with this domain will be permanently deleted.
240
240
  # @return [Response]
241
241
  def removedomain (opts)
242
242
  default_options = {
@@ -252,9 +252,9 @@ module Fusebox
252
252
  # This request will remove an existing email forwarder
253
253
  # @see http://www.fusemail.com/support/administration-api/requests/removeforward removeforward API documentation
254
254
  # @param [Array] opts
255
- # @option opts [String] 'user' Username of FuseMail account to remove forwarder to
256
- # @option opts [String] 'forward_what' Email address of forwarder
257
- # @option opts [String] 'forward_to' External email address that forwarder will send to
255
+ # @option opts [String] :user Username of FuseMail account to remove forwarder to
256
+ # @option opts [String] :forward_what Email address of forwarder
257
+ # @option opts [String] :forward_to External email address that forwarder will send to
258
258
  # @return [Response]
259
259
  def removeforward (opts)
260
260
  default_options = {
@@ -270,9 +270,9 @@ module Fusebox
270
270
  # This request will provide information about one or more accounts under your platform in CSV format
271
271
  # @see http://www.fusemail.com/support/administration-api/requests/report report API documentation
272
272
  # @param [Array] opts
273
- # @option opts [String] 'user' ('all') The username you wish to query for information; you may also enter the username "all" to get information about all users under your platform
274
- # @option opts [Boolean] 'group_subaccount' (true) Provide information not only for the Group Administration account but also for the group sub-accounts under the Group Administration account
275
- # @option opts ['basic', 'extended'] report_type ('basic') Level of detailed in returned results
273
+ # @option opts [String] :user ('all') The username you wish to query for information; you may also enter the username "all" to get information about all users under your platform
274
+ # @option opts [Boolean] :group_subaccount (true) Provide information not only for the Group Administration account but also for the group sub-accounts under the Group Administration account
275
+ # @option opts ['basic', 'extended'] :report_type ('basic') Level of detailed in returned results
276
276
  # @return [Response]
277
277
  def report (opts = {})
278
278
  default_options = {
@@ -288,9 +288,9 @@ module Fusebox
288
288
  # This request will provide information about mail aliases, forwarders, autoresponders, or mailing lists on one or more accounts under your platform in CSV format.
289
289
  # @see http://www.fusemail.com/support/administration-api/requests/reportmail reportmail API documentation
290
290
  # @param [Array] opts
291
- # @option opts [String] 'user' ('all') The username you wish to query for information; you may also enter the username "all" to get information about all users under your platform
292
- # @option opts [Boolean] 'group_subaccount' (true) Provide information not only for the Group Administration account but also for the group sub-accounts under the Group Administration account
293
- # @option opts ['all', 'alias', 'forwarder', 'autorespond', 'mailinglist'] report_type ('all')
291
+ # @option opts [String] :user ('all') The username you wish to query for information; you may also enter the username "all" to get information about all users under your platform
292
+ # @option opts [Boolean] :group_subaccount (true) Provide information not only for the Group Administration account but also for the group sub-accounts under the Group Administration account
293
+ # @option opts ['all', 'alias', 'forwarder', 'autorespond', 'mailinglist'] :report_type ('all')
294
294
  # * 'all' = Provide aliases, forwarders, autoresponders, and mailing list info
295
295
  # * 'alias' = Provide only alias information
296
296
  # * 'forwarder' = Provide only fowarder information
@@ -301,7 +301,7 @@ module Fusebox
301
301
  default_options = {
302
302
  :user => 'all',
303
303
  :group_subaccount => true,
304
- :report_type => 'extended'
304
+ :report_type => 'all'
305
305
  }
306
306
 
307
307
  opts.reverse_merge! default_options
@@ -311,7 +311,7 @@ module Fusebox
311
311
  # The suspend request allow you to suspend an account under your platform or temporarily stop access to the account without deleting any of the accounts data. Below are the variables that are specific to this request.
312
312
  # @see http://www.fusemail.com/support/administration-api/requests/suspend suspend API documentation
313
313
  # @param [Array] opts
314
- # @option opts [String] 'user' Username of FuseMail account to suspend
314
+ # @option opts [String] :user Username of FuseMail account to suspend
315
315
  # @return [Response]
316
316
  def suspend (opts)
317
317
  default_options = {
@@ -1,4 +1,4 @@
1
1
  module Fusebox
2
2
  # @return [String] Version number
3
- VERSION = '0.1.1'
3
+ VERSION = '0.2.0'
4
4
  end
data/lib/fusebox.rb CHANGED
@@ -9,4 +9,6 @@ require 'net/https'
9
9
  require 'fusebox/version'
10
10
  require 'fusebox/request'
11
11
  require 'fusebox/response'
12
- require 'fusebox/core_ext/net_http'
12
+ require 'fusebox/core_ext/net_http'
13
+
14
+ # 'fusebox/cli' is intentionally not loaded to reduce overhead; bin/fusebox requires it instead
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fusebox
3
3
  version: !ruby/object:Gem::Version
4
- hash: 25
4
+ hash: 23
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 1
9
- - 1
10
- version: 0.1.1
8
+ - 2
9
+ - 0
10
+ version: 0.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Gabe Martin-Dempesy
@@ -34,9 +34,24 @@ dependencies:
34
34
  type: :runtime
35
35
  version_requirements: *id001
36
36
  - !ruby/object:Gem::Dependency
37
- name: rspec
37
+ name: thor
38
38
  prerelease: false
39
39
  requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ hash: 23
45
+ segments:
46
+ - 0
47
+ - 14
48
+ version: "0.14"
49
+ type: :runtime
50
+ version_requirements: *id002
51
+ - !ruby/object:Gem::Dependency
52
+ name: rspec
53
+ prerelease: false
54
+ requirement: &id003 !ruby/object:Gem::Requirement
40
55
  none: false
41
56
  requirements:
42
57
  - - ">="
@@ -46,17 +61,19 @@ dependencies:
46
61
  - 0
47
62
  version: "0"
48
63
  type: :development
49
- version_requirements: *id002
50
- description: FuseMail API client library
64
+ version_requirements: *id003
65
+ description: FuseMail API client library and CLI
51
66
  email:
52
67
  - gabe@mudbugmedia.com.com
53
- executables: []
54
-
68
+ executables:
69
+ - fusebox
55
70
  extensions: []
56
71
 
57
72
  extra_rdoc_files: []
58
73
 
59
74
  files:
75
+ - lib/fusebox/cli.rb
76
+ - lib/fusebox/core_ext/array.rb
60
77
  - lib/fusebox/core_ext/net_http.rb
61
78
  - lib/fusebox/request.rb
62
79
  - lib/fusebox/response.rb
@@ -69,6 +86,7 @@ files:
69
86
  - spec/spec_helper.rb
70
87
  - LICENSE
71
88
  - README.md
89
+ - bin/fusebox
72
90
  has_rdoc: true
73
91
  homepage: http://github.com/mudbugmedia/fusebox
74
92
  licenses: []
@@ -104,6 +122,6 @@ rubyforge_project:
104
122
  rubygems_version: 1.3.7
105
123
  signing_key:
106
124
  specification_version: 3
107
- summary: FuseMail API client library
125
+ summary: FuseMail API client library and CLI
108
126
  test_files: []
109
127