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 +19 -7
- data/bin/fusebox +11 -0
- data/lib/fusebox/cli.rb +131 -0
- data/lib/fusebox/core_ext/array.rb +47 -0
- data/lib/fusebox/request.rb +17 -17
- data/lib/fusebox/version.rb +1 -1
- data/lib/fusebox.rb +3 -1
- metadata +28 -10
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
|
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
|
-
|
15
|
+
$ cat ~/.fusemail.yaml
|
12
16
|
username: my_username
|
13
17
|
password: my_password
|
14
18
|
|
15
|
-
##
|
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
|
data/lib/fusebox/cli.rb
ADDED
@@ -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
|
data/lib/fusebox/request.rb
CHANGED
@@ -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]
|
207
|
-
# @option opts [Boolean]
|
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]
|
223
|
-
# @option opts [String]
|
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]
|
239
|
-
# @option opts [Boolean]
|
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]
|
256
|
-
# @option opts [String]
|
257
|
-
# @option opts [String]
|
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]
|
274
|
-
# @option opts [Boolean]
|
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]
|
292
|
-
# @option opts [Boolean]
|
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 => '
|
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]
|
314
|
+
# @option opts [String] :user Username of FuseMail account to suspend
|
315
315
|
# @return [Response]
|
316
316
|
def suspend (opts)
|
317
317
|
default_options = {
|
data/lib/fusebox/version.rb
CHANGED
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:
|
4
|
+
hash: 23
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
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:
|
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: *
|
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
|
|