esgob 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f029cb699d12ea2f9ebc3d62538b301ac22c4ce2
4
- data.tar.gz: 878e694007c2d41a71ed940fc5f7cf9215a4ad23
3
+ metadata.gz: 3f360864b7199c78e7842d5792c7557cbbead80e
4
+ data.tar.gz: ff27595eaf87037c471f87193e9cf4e71075dc94
5
5
  SHA512:
6
- metadata.gz: 48559b9d9ac0b9a5def0e60cd6ed4242d90e28a2ec617d71fb673c0fedadd4e6aee7a32a81c6db88d649d539a59df04ab8e83e8317c5bfe65f442a13929159f5
7
- data.tar.gz: 5ff773471a48fc33e975ae314aec3519f9d7422b8526301bebf66f5328955f886bf9c9a8d0fb03838766d2321df230988108810aca80091a00a9d17079945202
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
- Add this line to your application's Gemfile:
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
- $ gem install esgob
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
- ## Usage
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, it is also possible to pass in the account name and API key using environment variables set in the shell:
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 ESGOB_API_KEY=4472ed80e0f511e4aee13c0754043581
87
+ export ESGOB_KEY=4472ed80e0f511e4aee13c0754043581
37
88
 
38
89
  The client instance can then be initialised without passing any arguments:
39
90
 
@@ -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
@@ -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 ||= Esgob::Client.new(options[:account], options[:key])
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
@@ -3,36 +3,64 @@ require "uri"
3
3
  require "json"
4
4
 
5
5
  class Esgob::Client
6
- attr_accessor :endpoint
7
- attr_accessor :account
8
- attr_accessor :api_key
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.first.is_a?(Hash)
14
- args.first.each_pair { |k, v| send("#{k}=", v) }
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
- self.account = args[0]
17
- self.api_key = args[1]
39
+ raise(ArgumentError, "Unsupported arguments for creating Esgob::Client")
18
40
  end
19
41
 
20
- self.account ||= ENV['ESGOB_ACCOUNT']
21
- self.api_key ||= ENV['ESGOB_API_KEY']
22
- self.endpoint ||= DEFAULT_API_ENDPOINT
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 api_key.nil? or api_key.empty?
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
- def call(function_name, arguments = {})
34
- uri = URI(endpoint + function_name)
35
- uri.query = build_query(default_arguments.merge(arguments))
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=#{@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 => api_key,
238
+ :account => config.account,
239
+ :key => config.key,
188
240
  :f => 'json'
189
241
  }
190
242
  end
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Esgob
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -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('ESGOB_API_KEY')
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
- @client.expects(:domains_slaves_list).with().returns('a.com' => '195.177.253.169', 'b.com' => '195.177.253.169')
106
- @client.expects(:domains_slaves_delete).with('a.com').returns(:action => 'domain deleted')
107
- @client.expects(:domains_slaves_add).with('c.com', '195.177.253.169').returns(:action => 'domain added')
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
@@ -5,7 +5,9 @@ require 'esgob'
5
5
 
6
6
  class TestClient < MiniTest::Unit::TestCase
7
7
  def setup
8
- # Run before each test
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('ESGOB_API_KEY')
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['ESGOB_API_KEY'] = 'envkey'
23
+ ENV['ESGOB_KEY'] = 'envkey'
22
24
 
23
25
  client = Esgob::Client.new
24
- assert_equal 'envacct', client.account
25
- assert_equal 'envkey', client.api_key
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.api_key
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
- :api_key => 'hashkey',
41
+ :key => 'hashkey',
40
42
  :endpoint => 'http://api.example.com/'
41
43
  )
42
- assert_equal 'hashacct', client.account
43
- assert_equal 'hashkey', client.api_key
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 test_new_client_with_no_api_key
55
- ENV.delete('ESGOB_API_KEY')
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.parse('2015-02-01 12:07:14 +0000'),
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
@@ -0,0 +1,5 @@
1
+ # Comments allowed
2
+ account fileacct
3
+
4
+ key filekey
5
+
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.2
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-03 00:00:00.000000000 Z
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