esgob 0.0.2 → 0.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.
- checksums.yaml +4 -4
- data/README.md +58 -7
- data/lib/esgob.rb +6 -0
- data/lib/esgob/cli.rb +19 -3
- data/lib/esgob/client.rb +76 -24
- data/lib/esgob/config.rb +104 -0
- data/lib/esgob/version.rb +1 -1
- data/test/esgob_cli_test.rb +31 -7
- data/test/esgob_client_test.rb +45 -18
- data/test/esgob_config_test.rb +151 -0
- data/test/fixtures/config.txt +5 -0
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3f360864b7199c78e7842d5792c7557cbbead80e
|
4
|
+
data.tar.gz: ff27595eaf87037c471f87193e9cf4e71075dc94
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a731e04c8c2d50199ad8222f36773ecb5c223455a4dc0c039c5bd50a41ba709a6cae4c744d663430447cee26c5d09257c5e56a3ac1d8cb4b01784593b165af06
|
7
|
+
data.tar.gz: 6203a00e25e0b844c92814de5f093e569ac6bd2fb0f21cd2c75fe3bf7132729c96c4674dd22623b8efe37e5c6813ae039c088808fe533b971433cda05927e43b
|
data/README.md
CHANGED
@@ -5,12 +5,17 @@ Esgob Ruby Client
|
|
5
5
|
|
6
6
|
[Esgob Ltd] operate an [international network] of anycast servers.
|
7
7
|
Their [Secondary DNS] service is available for free.
|
8
|
-
This Ruby Gem provides convenient access to the [Esgob API]
|
8
|
+
This Ruby Gem provides convenient access to the [Esgob API] via a command line tool
|
9
|
+
and Ruby library.
|
9
10
|
|
10
11
|
|
11
12
|
## Installation
|
12
13
|
|
13
|
-
|
14
|
+
Install it as a gem using:
|
15
|
+
|
16
|
+
$ gem install esgob
|
17
|
+
|
18
|
+
Or add this line to your application's Gemfile:
|
14
19
|
|
15
20
|
```ruby
|
16
21
|
gem 'esgob'
|
@@ -20,20 +25,66 @@ And then execute:
|
|
20
25
|
|
21
26
|
$ bundle
|
22
27
|
|
23
|
-
Or install it yourself as:
|
24
28
|
|
25
|
-
|
29
|
+
## Command Line Usage
|
30
|
+
|
31
|
+
Without any arguments, the ```esgob``` tool will display a list of commands:
|
32
|
+
|
33
|
+
```
|
34
|
+
Commands:
|
35
|
+
esgob account # Display account info
|
36
|
+
esgob config # Save the Esgob account and key
|
37
|
+
esgob domains # List all domains
|
38
|
+
esgob help [COMMAND] # Describe available commands or one specific command
|
39
|
+
esgob slaves # List slave domains
|
40
|
+
esgob slaves-add DOMAIN MASTERIP # Add new slave domain
|
41
|
+
esgob slaves-delete DOMAIN # Delete a slave domain
|
42
|
+
esgob slaves-sync FILE MASTERIP # Synronises list of slave domains in a file
|
43
|
+
esgob slaves-transfer DOMAIN # Force transfer from master of a slave domain
|
44
|
+
esgob slaves-update DOMAIN MASTERIP # Updates the master IP of a slave domain
|
45
|
+
esgob soacheck DOMAIN # Fetch domain SOA serial number for all nodes
|
46
|
+
esgob version # Show Esgob Ruby Client version
|
47
|
+
|
48
|
+
Options:
|
49
|
+
-a, [--account=Account Name]
|
50
|
+
-k, [--key=API Key]
|
51
|
+
-v, [--verbose], [--no-verbose]
|
52
|
+
```
|
53
|
+
|
54
|
+
To configure the client with some credentials use the ```esgob config``` command:
|
26
55
|
|
27
|
-
|
56
|
+
```
|
57
|
+
$ esgob config
|
58
|
+
What is your Esgob account name? accountname
|
59
|
+
What is your Esgob key? 4472ed80e0f511e4aee13c0754043581
|
60
|
+
Configuration written to /home/username/.esgob
|
61
|
+
```
|
62
|
+
|
63
|
+
|
64
|
+
|
65
|
+
## Library Usage
|
28
66
|
|
29
67
|
First create a new client instance, by passing in your account name and API key:
|
30
68
|
|
31
69
|
esgob = Esgob::Client.new('account', 'key')
|
32
70
|
|
33
|
-
Alternatively, as it is often desirable to keep secrets outside of the source code,
|
71
|
+
Alternatively, as it is often desirable to keep secrets outside of the source code,
|
72
|
+
it is also possible to pass in the account name and API key using a configuration file.
|
73
|
+
The following paths are searched in the following order:
|
74
|
+
|
75
|
+
~/.esgob
|
76
|
+
/usr/local/etc/esgob.conf
|
77
|
+
/etc/esgob.conf
|
78
|
+
|
79
|
+
The configuration file should be in the format:
|
80
|
+
|
81
|
+
account some_account_name
|
82
|
+
key kskjhdkjdhkjhdkjdhdkjhdkjhd
|
83
|
+
|
84
|
+
Or set using environment variables:
|
34
85
|
|
35
86
|
export ESGOB_ACCOUNT=accountname
|
36
|
-
export
|
87
|
+
export ESGOB_KEY=4472ed80e0f511e4aee13c0754043581
|
37
88
|
|
38
89
|
The client instance can then be initialised without passing any arguments:
|
39
90
|
|
data/lib/esgob.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
module Esgob
|
2
2
|
autoload :Client, 'esgob/client'
|
3
|
+
autoload :Config, 'esgob/config'
|
3
4
|
autoload :CLI, 'esgob/cli'
|
4
5
|
autoload :VERSION, 'esgob/version'
|
5
6
|
|
7
|
+
# Exception raised when the Esgob API returns an error
|
6
8
|
class ServerError < StandardError
|
9
|
+
# Get the error code number returned by Esgob
|
7
10
|
attr_reader :code
|
8
11
|
|
9
12
|
def initialize(message, code = nil)
|
@@ -11,4 +14,7 @@ module Esgob
|
|
11
14
|
@code = code
|
12
15
|
end
|
13
16
|
end
|
17
|
+
|
18
|
+
# Exception raised if client is configured
|
19
|
+
class UnconfiguredError < StandardError; end
|
14
20
|
end
|
data/lib/esgob/cli.rb
CHANGED
@@ -22,16 +22,28 @@ class Esgob::CLI < Thor
|
|
22
22
|
super(args, config)
|
23
23
|
rescue Esgob::ServerError => err
|
24
24
|
$stderr.puts config[:shell].set_color("=> Error: #{err.message} [#{err.code}]", :red, :bold)
|
25
|
+
rescue Esgob::UnconfiguredError => err
|
26
|
+
$stderr.puts config[:shell].set_color("=> Error: #{err.message}", :red, :bold)
|
27
|
+
$stderr.puts "Use the 'esgob config' command to create a configuration file."
|
25
28
|
end
|
26
29
|
end
|
27
30
|
|
31
|
+
desc "config", "Save the Esgob account and key"
|
32
|
+
def config
|
33
|
+
config = Esgob::Config.new
|
34
|
+
config.account = ask("What is your Esgob account name?")
|
35
|
+
config.key = ask("What is your Esgob key?")
|
36
|
+
config.save
|
37
|
+
say "Configuration written to #{config.filepath}"
|
38
|
+
end
|
39
|
+
|
28
40
|
desc "account", "Display account info"
|
29
41
|
def account
|
30
42
|
client.accounts_get.each_pair do |k, v|
|
31
43
|
say sprintf("%8s: %s\n", k, v)
|
32
44
|
end
|
33
45
|
end
|
34
|
-
|
46
|
+
|
35
47
|
desc "domains", "List all domains"
|
36
48
|
def domains
|
37
49
|
print_table(
|
@@ -118,7 +130,11 @@ class Esgob::CLI < Thor
|
|
118
130
|
private ######################################################################
|
119
131
|
|
120
132
|
def client
|
121
|
-
@client ||=
|
133
|
+
@client ||= if options[:account] and options[:key]
|
134
|
+
Esgob::Client.new(options[:account], options[:key])
|
135
|
+
else
|
136
|
+
Esgob::Client.new
|
137
|
+
end
|
122
138
|
end
|
123
139
|
|
124
140
|
def check_action
|
@@ -130,5 +146,5 @@ class Esgob::CLI < Thor
|
|
130
146
|
end
|
131
147
|
end
|
132
148
|
end
|
133
|
-
|
149
|
+
|
134
150
|
end
|
data/lib/esgob/client.rb
CHANGED
@@ -3,36 +3,64 @@ require "uri"
|
|
3
3
|
require "json"
|
4
4
|
|
5
5
|
class Esgob::Client
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
DEFAULT_API_ENDPOINT = "https://api.esgob.com/1.0/".freeze
|
6
|
+
# Esgob configuration, used to store account name and key
|
7
|
+
# @return [Esgob::Config]
|
8
|
+
attr_reader :config
|
11
9
|
|
10
|
+
# Create a new Esgob Client instance.
|
11
|
+
#
|
12
|
+
# @overload initialize
|
13
|
+
# Create a new client, using one of the default configuration files.
|
14
|
+
# Or the ESGOB_ACCOUNT and ESGOB_KEY environment variables.
|
15
|
+
# @overload initialize(account, key)
|
16
|
+
# @param [String] account
|
17
|
+
# @param [String] key
|
18
|
+
# @overload initialize(args)
|
19
|
+
# @param [Hash] options
|
20
|
+
# @option options [String] :endpoint The URI of the API endpoint
|
21
|
+
# @option options [String] :account The account name
|
22
|
+
# @option options [String] :key The API key
|
23
|
+
# @overload initialize(config)
|
24
|
+
# @param [Esgob::Config] config
|
25
|
+
# @return [Esgob::Client] A new client instance.
|
26
|
+
# @example
|
27
|
+
# client = Esgob::Client.new('account', 'key')
|
12
28
|
def initialize(*args)
|
13
|
-
if args.
|
14
|
-
|
29
|
+
if args.empty?
|
30
|
+
# Load configuration from file if no arguments were given
|
31
|
+
@config = Esgob::Config.load
|
32
|
+
elsif args.first.is_a?(Esgob::Config)
|
33
|
+
@config = args.first
|
34
|
+
elsif args.first.is_a?(Hash)
|
35
|
+
@config = Esgob::Config.new(args.first)
|
36
|
+
elsif args.length == 2
|
37
|
+
@config = Esgob::Config.new(:account => args[0], :key => args[1])
|
15
38
|
else
|
16
|
-
|
17
|
-
self.api_key = args[1]
|
39
|
+
raise(ArgumentError, "Unsupported arguments for creating Esgob::Client")
|
18
40
|
end
|
19
41
|
|
20
|
-
|
21
|
-
|
22
|
-
|
42
|
+
if config.nil?
|
43
|
+
raise(Esgob::UnconfiguredError, "Unable to load Esgob configuration")
|
44
|
+
end
|
23
45
|
|
24
|
-
if account.nil? or account.empty?
|
46
|
+
if config.account.nil? or config.account.empty?
|
25
47
|
raise(ArgumentError, "No account name configured for Esgob")
|
26
48
|
end
|
27
49
|
|
28
|
-
if
|
50
|
+
if config.key.nil? or config.key.empty?
|
29
51
|
raise(ArgumentError, "No API key configured for Esgob")
|
30
52
|
end
|
31
53
|
end
|
32
54
|
|
33
|
-
|
34
|
-
|
35
|
-
|
55
|
+
# Call a named Esgob API function.
|
56
|
+
#
|
57
|
+
# @param [String] function_name The name of API function.
|
58
|
+
# @param [Hash] args Pairs of argument keys and values.
|
59
|
+
# @return [Hash] The response from the Esgob service, with symbols as keys.
|
60
|
+
# @example client.call('domains.slaves.add', :domain => 'example.com', :masterip => '192.168.0.1')
|
61
|
+
def call(function_name, args = {})
|
62
|
+
uri = URI(config.endpoint + function_name)
|
63
|
+
uri.query = build_query(default_arguments.merge(args))
|
36
64
|
|
37
65
|
res = Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
|
38
66
|
req = Net::HTTP::Get.new(uri.request_uri)
|
@@ -57,7 +85,8 @@ class Esgob::Client
|
|
57
85
|
end
|
58
86
|
end
|
59
87
|
|
60
|
-
# Return account status; credit balance, etc
|
88
|
+
# Return account status; credit balance, etc.
|
89
|
+
# @return [Hash] Key, value pairs, containing account information.
|
61
90
|
def accounts_get
|
62
91
|
account = call('accounts.get')
|
63
92
|
account[:added] = Time.at(account[:added]) if account[:added].is_a?(Fixnum)
|
@@ -65,12 +94,13 @@ class Esgob::Client
|
|
65
94
|
end
|
66
95
|
|
67
96
|
# Returns all hosted domains
|
97
|
+
# @return [Array<Hash>] Array of hashes, one per domain.
|
68
98
|
def domains_list
|
69
99
|
call('domains.list')[:domains]
|
70
100
|
end
|
71
101
|
|
72
102
|
# Returns all hosted slave domains as a hash
|
73
|
-
#
|
103
|
+
# @return [Hash] Domain name as key, master ip as value
|
74
104
|
def domains_slaves_list
|
75
105
|
Hash[
|
76
106
|
call('domains.slaves.list')[:domains].map do |item|
|
@@ -79,14 +109,19 @@ class Esgob::Client
|
|
79
109
|
]
|
80
110
|
end
|
81
111
|
|
82
|
-
# Adds a new slave domain
|
112
|
+
# Adds a new slave domain.
|
113
|
+
# @param [String] domain The name of the domain to add
|
114
|
+
# @param [String] masterip The IP of the master to transfer the zone from.
|
115
|
+
# @return [Hash] The response from the Esgob service, with symbols as keys.
|
83
116
|
def domains_slaves_add(domain, masterip)
|
84
117
|
result = call('domains.slaves.add', :domain => domain, :masterip => masterip)
|
85
118
|
result[:domain] ||= domain
|
86
119
|
result
|
87
120
|
end
|
88
121
|
|
89
|
-
# Deletes a slave domain
|
122
|
+
# Deletes a slave domain.
|
123
|
+
# @param [String] domain The name of the domain to delete.
|
124
|
+
# @return [Hash] The response from the Esgob service, with symbols as keys.
|
90
125
|
def domains_slaves_delete(domain)
|
91
126
|
result = call('domains.slaves.delete', :domain => domain)
|
92
127
|
result[:domain] ||= domain
|
@@ -94,6 +129,8 @@ class Esgob::Client
|
|
94
129
|
end
|
95
130
|
|
96
131
|
# Force AXFR / transfer from master of a slave domain
|
132
|
+
# @param [String] domain The name of the domain to transfer.
|
133
|
+
# @return [Hash] The response from the Esgob service, with symbols as keys.
|
97
134
|
def domains_slaves_forcetransfer(domain)
|
98
135
|
result = call('domains.slaves.forcetransfer', :domain => domain)
|
99
136
|
result[:domain] ||= domain
|
@@ -101,6 +138,9 @@ class Esgob::Client
|
|
101
138
|
end
|
102
139
|
|
103
140
|
# Updates the master IP of a slave domain
|
141
|
+
# @param [String] domain The name of the domain to update
|
142
|
+
# @param [String] masterip The new IP of the master to transfer the zone from.
|
143
|
+
# @return [Hash] The response from the Esgob service, with symbols as keys.
|
104
144
|
def domains_slaves_updatemasterip(domain, masterip)
|
105
145
|
result = call('domains.slaves.updatemasterip', :domain => domain, :masterip => masterip)
|
106
146
|
result[:domain] ||= domain
|
@@ -108,6 +148,9 @@ class Esgob::Client
|
|
108
148
|
end
|
109
149
|
|
110
150
|
# Add a host allowed to AXFR out
|
151
|
+
# @param [String] domain The name of the domain to update
|
152
|
+
# @param [String] axfrip The new IP of the host to allow transfers to.
|
153
|
+
# @return [Hash] The response from the Esgob service, with symbols as keys.
|
111
154
|
def domains_slaves_axfrout_add(domain, axfrip)
|
112
155
|
result = call('domains.slaves.axfrout.add', :domain => domain, :axfrip => axfrip)
|
113
156
|
result[:domain] ||= domain
|
@@ -115,6 +158,9 @@ class Esgob::Client
|
|
115
158
|
end
|
116
159
|
|
117
160
|
# Account Delete a host allowed to AXFR out
|
161
|
+
# @param [String] domain The name of the domain to update
|
162
|
+
# @param [String] axfrip The IP of the host to stop allowing transfers to.
|
163
|
+
# @return [Hash] The response from the Esgob service, with symbols as keys.
|
118
164
|
def domains_slaves_axfrout_delete(domain, axfrip)
|
119
165
|
result = call('domains.slaves.axfrout.delete', :domain => domain, :axfrip => axfrip)
|
120
166
|
result[:domain] ||= domain
|
@@ -122,12 +168,17 @@ class Esgob::Client
|
|
122
168
|
end
|
123
169
|
|
124
170
|
# Retrieve the domain SOA serial number from the master and each anycast node
|
171
|
+
# @param [String] domain The name of the domain to look up
|
172
|
+
# @return [Hash] The response from the Esgob service, with symbols as keys.
|
125
173
|
def domains_tools_soacheck(domain)
|
126
174
|
call('domains.tools.soacheck', :domain => domain)
|
127
175
|
end
|
128
176
|
|
129
177
|
# Given a list of domains and a master IP, add and delete domains
|
130
178
|
# so that the Esgob account matches the local list
|
179
|
+
# @param [Array<String>] domains The an array of domains to add to Esgob
|
180
|
+
# @param [String] masterip The master IP address to use for all the domains
|
181
|
+
# @return [Array<Hash>] A list of responses from the Esgob service
|
131
182
|
def domains_slaves_sync(domains, masterip)
|
132
183
|
existing_domains = domains_slaves_list
|
133
184
|
|
@@ -161,8 +212,9 @@ class Esgob::Client
|
|
161
212
|
responses
|
162
213
|
end
|
163
214
|
|
215
|
+
# @return [String]
|
164
216
|
def inspect
|
165
|
-
"\#<#{self.class} account=#{
|
217
|
+
"\#<#{self.class} account=#{config.account}>"
|
166
218
|
end
|
167
219
|
|
168
220
|
protected
|
@@ -183,8 +235,8 @@ class Esgob::Client
|
|
183
235
|
|
184
236
|
def default_arguments
|
185
237
|
{
|
186
|
-
:account => account,
|
187
|
-
:key =>
|
238
|
+
:account => config.account,
|
239
|
+
:key => config.key,
|
188
240
|
:f => 'json'
|
189
241
|
}
|
190
242
|
end
|
data/lib/esgob/config.rb
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
class Esgob::Config
|
2
|
+
# Path to the configuration file
|
3
|
+
# @return [String]
|
4
|
+
attr_accessor :filepath
|
5
|
+
# @return [String]
|
6
|
+
attr_accessor :endpoint
|
7
|
+
# @return [String]
|
8
|
+
attr_accessor :account
|
9
|
+
# @return [String]
|
10
|
+
attr_accessor :key
|
11
|
+
|
12
|
+
DEFAULT_API_ENDPOINT = "https://api.esgob.com/1.0/".freeze
|
13
|
+
|
14
|
+
# @param [Hash] args
|
15
|
+
# @option args [String] :account The account name
|
16
|
+
# @option args [String] :key The API key
|
17
|
+
def initialize(args={})
|
18
|
+
args.each_pair { |k, v| send("#{k}=", v) }
|
19
|
+
end
|
20
|
+
|
21
|
+
def endpoint
|
22
|
+
# Use default endpoint if none configured
|
23
|
+
@endpoint || DEFAULT_API_ENDPOINT
|
24
|
+
end
|
25
|
+
|
26
|
+
# Get an ordered list of paths to possible Esgob configuration files
|
27
|
+
# @return [Array<String>] Array of file paths
|
28
|
+
def self.default_filepaths
|
29
|
+
[
|
30
|
+
File.join(ENV['HOME'], '.esgob'),
|
31
|
+
'/usr/local/etc/esgob.conf',
|
32
|
+
'/etc/esgob.conf'
|
33
|
+
]
|
34
|
+
end
|
35
|
+
|
36
|
+
# Try and read Esgob configuration either from
|
37
|
+
# Environment variables or one of the config files
|
38
|
+
# @param [String] path Optional path to a configuration file
|
39
|
+
# @return Esgob::Config
|
40
|
+
def self.load(path=nil)
|
41
|
+
if !path.nil?
|
42
|
+
load_file(path)
|
43
|
+
elsif ENV['ESGOB_ACCOUNT'] and ENV['ESGOB_KEY']
|
44
|
+
self.new(
|
45
|
+
:account => ENV['ESGOB_ACCOUNT'],
|
46
|
+
:key => ENV['ESGOB_KEY']
|
47
|
+
)
|
48
|
+
else
|
49
|
+
default_filepaths.each do |path|
|
50
|
+
if File.exist?(path)
|
51
|
+
return load_file(path)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# No config file found, return nil
|
56
|
+
nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Save Esgob configuration to file
|
61
|
+
# If no filepath is given, save to the default filepath
|
62
|
+
# @param [String] path Optional path to a configuration file
|
63
|
+
def save(path=nil)
|
64
|
+
if !path.nil?
|
65
|
+
self.filepath = path
|
66
|
+
elsif filepath.nil?
|
67
|
+
self.filepath = self.class.default_filepaths.first
|
68
|
+
end
|
69
|
+
|
70
|
+
File.open(filepath, 'wb') do |file|
|
71
|
+
each_pair do |key,value|
|
72
|
+
file.puts "#{key} #{value}"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Calls block once for each configuration key value pair,
|
78
|
+
# passing the key and value as parameters.
|
79
|
+
def each_pair
|
80
|
+
instance_variables.sort.each do |var|
|
81
|
+
next if var.to_s == '@filepath'
|
82
|
+
yield(var.to_s.sub(/^@/,''), instance_variable_get(var))
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
protected
|
88
|
+
|
89
|
+
def self.load_file(path)
|
90
|
+
config = self.new(:filepath => path)
|
91
|
+
|
92
|
+
File.foreach(path) do |line|
|
93
|
+
if line =~ /^(\w+)\s+(.+)$/
|
94
|
+
method, value = ["#{$1}=", $2]
|
95
|
+
if config.respond_to?(method)
|
96
|
+
config.send(method, value)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
config
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
data/lib/esgob/version.rb
CHANGED
data/test/esgob_cli_test.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
$:.unshift(File.dirname(__FILE__))
|
2
2
|
|
3
3
|
require 'test_helper'
|
4
|
+
require 'thor'
|
4
5
|
require 'esgob'
|
5
6
|
|
6
7
|
class TestCLI < MiniTest::Unit::TestCase
|
@@ -8,16 +9,29 @@ class TestCLI < MiniTest::Unit::TestCase
|
|
8
9
|
# Run before each test
|
9
10
|
FakeWeb.clean_registry
|
10
11
|
|
11
|
-
@client = Esgob::Client.new('acct', 'xxxx')
|
12
|
-
Esgob::Client.stubs(:new).returns(@client)
|
13
|
-
|
14
12
|
ENV['THOR_SHELL'] = 'Basic'
|
13
|
+
ENV['ESGOB_ACCOUNT'] = 'acct'
|
14
|
+
ENV['ESGOB_KEY'] = 'xxxx'
|
15
15
|
end
|
16
16
|
|
17
17
|
def teardown
|
18
18
|
# Reset environment variables after each test
|
19
19
|
ENV.delete('ESGOB_ACCOUNT')
|
20
|
-
ENV.delete('
|
20
|
+
ENV.delete('ESGOB_KEY')
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_config
|
24
|
+
shell = Thor::Base.shell.new
|
25
|
+
shell.expects(:ask).with("What is your Esgob account name?").returns('ask_acct')
|
26
|
+
shell.expects(:ask).with("What is your Esgob key?").returns('ask_key')
|
27
|
+
|
28
|
+
config = Esgob::Config.new
|
29
|
+
Esgob::Config.expects(:new).with().returns(config)
|
30
|
+
config.filepath = '/etc/esgob.conf'
|
31
|
+
config.expects(:save)
|
32
|
+
|
33
|
+
output = capture(:stdout) { Esgob::CLI.start(%w(config), :shell => shell) }
|
34
|
+
assert_equal "Configuration written to /etc/esgob.conf\n", output
|
21
35
|
end
|
22
36
|
|
23
37
|
def test_account
|
@@ -29,6 +43,14 @@ class TestCLI < MiniTest::Unit::TestCase
|
|
29
43
|
assert_match " credits: 48\n", output
|
30
44
|
end
|
31
45
|
|
46
|
+
def test_account_unconfigured
|
47
|
+
Esgob::Config.expects(:load).with().returns(nil)
|
48
|
+
|
49
|
+
output = capture(:stderr) { Esgob::CLI.start(%w(account)) }
|
50
|
+
assert_match "=> Error: Unable to load Esgob configuration\n", output
|
51
|
+
assert_match "Use the 'esgob config' command to create a configuration file.\n", output
|
52
|
+
end
|
53
|
+
|
32
54
|
def test_account_error
|
33
55
|
FakeWeb.register_uri(
|
34
56
|
:get, %r{^https?://api\.esgob\.com(:443)?/},
|
@@ -102,9 +124,11 @@ class TestCLI < MiniTest::Unit::TestCase
|
|
102
124
|
end
|
103
125
|
|
104
126
|
def test_slaves_sync
|
105
|
-
|
106
|
-
|
107
|
-
|
127
|
+
client = Esgob::Client.new
|
128
|
+
client.expects(:domains_slaves_list).with().returns('a.com' => '195.177.253.169', 'b.com' => '195.177.253.169')
|
129
|
+
client.expects(:domains_slaves_delete).with('a.com').returns(:action => 'domain deleted')
|
130
|
+
client.expects(:domains_slaves_add).with('c.com', '195.177.253.169').returns(:action => 'domain added')
|
131
|
+
Esgob::Client.stubs(:new).returns(client)
|
108
132
|
|
109
133
|
output = capture(:stdout) { Esgob::CLI.start(['slaves-sync', fixture_path('sync-domain-list.txt'), '195.177.253.169']) }
|
110
134
|
assert_match "a.com => domain deleted\n", output
|
data/test/esgob_client_test.rb
CHANGED
@@ -5,7 +5,9 @@ require 'esgob'
|
|
5
5
|
|
6
6
|
class TestClient < MiniTest::Unit::TestCase
|
7
7
|
def setup
|
8
|
-
#
|
8
|
+
# Clear environment variables before each test
|
9
|
+
ENV.delete('ESGOB_ACCOUNT')
|
10
|
+
ENV.delete('ESGOB_KEY')
|
9
11
|
FakeWeb.clean_registry
|
10
12
|
@client = Esgob::Client.new('acct', 'xxxx')
|
11
13
|
end
|
@@ -13,49 +15,74 @@ class TestClient < MiniTest::Unit::TestCase
|
|
13
15
|
def teardown
|
14
16
|
# Reset environment variables after each test
|
15
17
|
ENV.delete('ESGOB_ACCOUNT')
|
16
|
-
ENV.delete('
|
18
|
+
ENV.delete('ESGOB_KEY')
|
17
19
|
end
|
18
20
|
|
19
21
|
def test_new_client_using_environment
|
20
22
|
ENV['ESGOB_ACCOUNT'] = 'envacct'
|
21
|
-
ENV['
|
23
|
+
ENV['ESGOB_KEY'] = 'envkey'
|
22
24
|
|
23
25
|
client = Esgob::Client.new
|
24
|
-
assert_equal 'envacct', client.account
|
25
|
-
assert_equal 'envkey', client.
|
26
|
-
assert_equal 'https://api.esgob.com/1.0/', client.endpoint
|
26
|
+
assert_equal 'envacct', client.config.account
|
27
|
+
assert_equal 'envkey', client.config.key
|
28
|
+
assert_equal 'https://api.esgob.com/1.0/', client.config.endpoint
|
27
29
|
end
|
28
30
|
|
29
31
|
def test_new_client_using_arguments
|
30
32
|
client = Esgob::Client.new('foobar', 'mykey')
|
31
|
-
assert_equal 'foobar', client.account
|
32
|
-
assert_equal 'mykey', client.
|
33
|
-
assert_equal 'https://api.esgob.com/1.0/', client.endpoint
|
33
|
+
assert_equal 'foobar', client.config.account
|
34
|
+
assert_equal 'mykey', client.config.key
|
35
|
+
assert_equal 'https://api.esgob.com/1.0/', client.config.endpoint
|
34
36
|
end
|
35
37
|
|
36
38
|
def test_new_client_using_hash
|
37
39
|
client = Esgob::Client.new(
|
38
40
|
:account => 'hashacct',
|
39
|
-
:
|
41
|
+
:key => 'hashkey',
|
40
42
|
:endpoint => 'http://api.example.com/'
|
41
43
|
)
|
42
|
-
assert_equal 'hashacct', client.account
|
43
|
-
assert_equal 'hashkey', client.
|
44
|
-
assert_equal 'http://api.example.com/', client.endpoint
|
44
|
+
assert_equal 'hashacct', client.config.account
|
45
|
+
assert_equal 'hashkey', client.config.key
|
46
|
+
assert_equal 'http://api.example.com/', client.config.endpoint
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_new_client_using_config
|
50
|
+
config = Esgob::Config.new(
|
51
|
+
:account => 'confacct',
|
52
|
+
:key => 'confkey'
|
53
|
+
)
|
54
|
+
client = Esgob::Client.new(config)
|
55
|
+
assert_equal 'confacct', client.config.account
|
56
|
+
assert_equal 'confkey', client.config.key
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_new_client_with_no_config_files
|
60
|
+
Esgob::Config.expects(:default_filepaths).with().returns([])
|
61
|
+
err = assert_raises(Esgob::UnconfiguredError) { Esgob::Client.new }
|
62
|
+
assert_equal 'Unable to load Esgob configuration', err.message
|
45
63
|
end
|
46
64
|
|
47
65
|
def test_new_client_with_no_account
|
48
66
|
ENV.delete('ESGOB_ACCOUNT')
|
49
|
-
assert_raises(ArgumentError) do
|
67
|
+
err = assert_raises(ArgumentError) do
|
50
68
|
Esgob::Client.new(nil, 'mykey')
|
51
69
|
end
|
70
|
+
assert_equal 'No account name configured for Esgob', err.message
|
52
71
|
end
|
53
72
|
|
54
|
-
def
|
55
|
-
ENV.delete('
|
56
|
-
assert_raises(ArgumentError) do
|
73
|
+
def test_new_client_with_no_key
|
74
|
+
ENV.delete('ESGOB_KEY')
|
75
|
+
err = assert_raises(ArgumentError) do
|
57
76
|
Esgob::Client.new('acct', nil)
|
58
77
|
end
|
78
|
+
assert_equal 'No API key configured for Esgob', err.message
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_new_client_unsupported_arguments
|
82
|
+
err = assert_raises(ArgumentError) do
|
83
|
+
Esgob::Client.new(1, 2, 3, 4)
|
84
|
+
end
|
85
|
+
assert_equal 'Unsupported arguments for creating Esgob::Client', err.message
|
59
86
|
end
|
60
87
|
|
61
88
|
def test_call_with_no_parameters
|
@@ -145,7 +172,7 @@ class TestClient < MiniTest::Unit::TestCase
|
|
145
172
|
{
|
146
173
|
:credits => 48,
|
147
174
|
:users => [],
|
148
|
-
:added => Time.
|
175
|
+
:added => Time.utc(2015, 2, 1, 12, 07, 14),
|
149
176
|
:id => 'xyz',
|
150
177
|
:name => 'Person Name'
|
151
178
|
},
|
@@ -0,0 +1,151 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__))
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'tempfile'
|
5
|
+
require 'esgob'
|
6
|
+
|
7
|
+
class TestConfig < MiniTest::Unit::TestCase
|
8
|
+
def setup
|
9
|
+
# Clear environment variables before each test
|
10
|
+
ENV.delete('ESGOB_ACCOUNT')
|
11
|
+
ENV.delete('ESGOB_KEY')
|
12
|
+
end
|
13
|
+
|
14
|
+
def teardown
|
15
|
+
# Reset environment variables after each test
|
16
|
+
ENV.delete('ESGOB_ACCOUNT')
|
17
|
+
ENV.delete('ESGOB_KEY')
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_new
|
21
|
+
conf = Esgob::Config.new(:account => 'acct', :key => 'xyz')
|
22
|
+
assert_instance_of(Esgob::Config, conf)
|
23
|
+
assert_equal('acct', conf.account)
|
24
|
+
assert_equal('xyz', conf.key)
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_default_values
|
28
|
+
conf = Esgob::Config.new
|
29
|
+
assert_instance_of(Esgob::Config, conf)
|
30
|
+
assert_equal(nil, conf.account)
|
31
|
+
assert_equal('https://api.esgob.com/1.0/', conf.endpoint)
|
32
|
+
assert_equal(nil, conf.key)
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_default_filepaths
|
36
|
+
ENV['HOME'] = '/home/bob'
|
37
|
+
assert_instance_of(Array, Esgob::Config.default_filepaths)
|
38
|
+
assert_includes(Esgob::Config.default_filepaths, '/home/bob/.esgob')
|
39
|
+
assert_includes(Esgob::Config.default_filepaths, '/etc/esgob.conf')
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_load_from_env
|
43
|
+
ENV['ESGOB_ACCOUNT'] = 'envacct'
|
44
|
+
ENV['ESGOB_KEY'] = 'envkey'
|
45
|
+
conf = Esgob::Config.load
|
46
|
+
assert_instance_of(Esgob::Config, conf)
|
47
|
+
assert_equal('envacct', conf.account)
|
48
|
+
assert_equal('envkey', conf.key)
|
49
|
+
assert_equal(nil, conf.filepath)
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_load_from_specific_file
|
53
|
+
conf = Esgob::Config.load(fixture_path('config.txt'))
|
54
|
+
assert_instance_of(Esgob::Config, conf)
|
55
|
+
assert_equal('fileacct', conf.account)
|
56
|
+
assert_equal('filekey', conf.key)
|
57
|
+
assert_match(/test\/fixtures\/config\.txt$/, conf.filepath)
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_load_from_default_files
|
61
|
+
Esgob::Config.expects(:default_filepaths).with().returns([
|
62
|
+
'/doesnt/exist/shuuKee6',
|
63
|
+
'/doesnt/exist/ebah4kiH',
|
64
|
+
fixture_path('config.txt'),
|
65
|
+
'/doesnt/exist/Va5cu9en',
|
66
|
+
])
|
67
|
+
|
68
|
+
conf = Esgob::Config.load
|
69
|
+
assert_instance_of(Esgob::Config, conf)
|
70
|
+
assert_equal('fileacct', conf.account)
|
71
|
+
assert_equal('filekey', conf.key)
|
72
|
+
assert_match(/test\/fixtures\/config\.txt$/, conf.filepath)
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_load_unavailable
|
76
|
+
Esgob::Config.expects(:default_filepaths).with().returns([
|
77
|
+
'/doesnt/exist/shuuKee6'
|
78
|
+
])
|
79
|
+
|
80
|
+
conf = Esgob::Config.load
|
81
|
+
assert_nil(conf)
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_each_pair
|
85
|
+
conf = Esgob::Config.new(:key => 'xyz', :account => 'abc')
|
86
|
+
array = []
|
87
|
+
conf.each_pair { |k, v| array << "#{k}=#{v}" }
|
88
|
+
assert_equal(["account=abc", "key=xyz"], array)
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_save_config_to_default
|
92
|
+
tempfile = Tempfile.new('esgob-config-test')
|
93
|
+
tempfile.close
|
94
|
+
|
95
|
+
Esgob::Config.expects(:default_filepaths).with().returns([tempfile.path])
|
96
|
+
|
97
|
+
config = Esgob::Config.new
|
98
|
+
config.account = 'a'
|
99
|
+
config.key = 'k'
|
100
|
+
config.save
|
101
|
+
|
102
|
+
assert_equal(
|
103
|
+
"account a\n"+
|
104
|
+
"key k\n",
|
105
|
+
tempfile.open.read
|
106
|
+
)
|
107
|
+
|
108
|
+
assert_equal(tempfile.path, config.filepath)
|
109
|
+
|
110
|
+
tempfile.unlink
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_save_config_with_path
|
114
|
+
tempfile = Tempfile.new('esgob-config-test')
|
115
|
+
tempfile.close
|
116
|
+
|
117
|
+
config = Esgob::Config.new
|
118
|
+
config.account = 'a'
|
119
|
+
config.key = 'k'
|
120
|
+
config.save(tempfile.path)
|
121
|
+
|
122
|
+
assert_equal(
|
123
|
+
"account a\n"+
|
124
|
+
"key k\n",
|
125
|
+
tempfile.open.read
|
126
|
+
)
|
127
|
+
|
128
|
+
tempfile.unlink
|
129
|
+
end
|
130
|
+
|
131
|
+
def test_save_config_with_custom_endpoint
|
132
|
+
tempfile = Tempfile.new('esgob-config-test')
|
133
|
+
tempfile.close
|
134
|
+
|
135
|
+
config = Esgob::Config.new
|
136
|
+
config.account = 'a'
|
137
|
+
config.key = 'k'
|
138
|
+
config.endpoint = 'http://esgob.example.com/'
|
139
|
+
config.save(tempfile.path)
|
140
|
+
|
141
|
+
assert_equal(
|
142
|
+
"account a\n"+
|
143
|
+
"endpoint http://esgob.example.com/\n"+
|
144
|
+
"key k\n",
|
145
|
+
tempfile.open.read
|
146
|
+
)
|
147
|
+
|
148
|
+
tempfile.unlink
|
149
|
+
end
|
150
|
+
|
151
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: esgob
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nicholas Humfrey
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-05-
|
11
|
+
date: 2015-05-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|
@@ -141,13 +141,16 @@ files:
|
|
141
141
|
- lib/esgob.rb
|
142
142
|
- lib/esgob/cli.rb
|
143
143
|
- lib/esgob/client.rb
|
144
|
+
- lib/esgob/config.rb
|
144
145
|
- lib/esgob/version.rb
|
145
146
|
- test/esgob_cli_test.rb
|
146
147
|
- test/esgob_client_test.rb
|
148
|
+
- test/esgob_config_test.rb
|
147
149
|
- test/esgob_version_test.rb
|
148
150
|
- test/fixtures/accounts_get.json
|
149
151
|
- test/fixtures/code_1003.json
|
150
152
|
- test/fixtures/code_2007.json
|
153
|
+
- test/fixtures/config.txt
|
151
154
|
- test/fixtures/domains_list.json
|
152
155
|
- test/fixtures/domains_slaves_add.json
|
153
156
|
- test/fixtures/domains_slaves_axfrout_add.json
|
@@ -186,10 +189,12 @@ summary: Client library for talking to the Esgob anycast DNS API.
|
|
186
189
|
test_files:
|
187
190
|
- test/esgob_cli_test.rb
|
188
191
|
- test/esgob_client_test.rb
|
192
|
+
- test/esgob_config_test.rb
|
189
193
|
- test/esgob_version_test.rb
|
190
194
|
- test/fixtures/accounts_get.json
|
191
195
|
- test/fixtures/code_1003.json
|
192
196
|
- test/fixtures/code_2007.json
|
197
|
+
- test/fixtures/config.txt
|
193
198
|
- test/fixtures/domains_list.json
|
194
199
|
- test/fixtures/domains_slaves_add.json
|
195
200
|
- test/fixtures/domains_slaves_axfrout_add.json
|