lunanode 0.1.6 → 0.2.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b4a86afa70afc9876d468543733644a5d6250c43
4
- data.tar.gz: 653e08f16c13c01829deda1e1193a99b6a85d394
3
+ metadata.gz: e34a9df27d3a00d606d1de48db6eb9bbf2f2c403
4
+ data.tar.gz: f2937c563d7e2ce7ac80a8f12e77ca8223a8643d
5
5
  SHA512:
6
- metadata.gz: ecb1f25922f283901cd4a2c97d17feda5754b8c9858f57d3bf1a5678be512e38ca534c366d995c16c1937e2fb172ea8c48939b8ba8f7478d99c54185f3e3327c
7
- data.tar.gz: 989713bca6baddc11020910e6a982cc98ddb0415ca2071b239b99af6ab573631ffd71b5ba5bd73bacc4ce1967a6d0a7b2d016609cc214ef2e1742cd58a5367b1
6
+ metadata.gz: 70914da6f5a7bc35141a03338abd3f98cc81179413d2d4ceb687bcd89cc2ec689332be581e539c98fd4936b27ef773d2003cbf68785aaf784a92a40bf425f7fd
7
+ data.tar.gz: 2bd8e4a9053eb640dd53b0ee359f4be4eb0fe608afc8d3cdfc760aa5e73ed08a4a8d953b3948141f8d8ce30866ffba5a0b459f8edc1f9b6655b5bfd407596291
data/.rubocop.yml CHANGED
@@ -50,7 +50,8 @@ Metrics/ParameterLists:
50
50
  Description: 'Avoid parameter lists longer than three or four parameters.'
51
51
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#too-many-params'
52
52
  Enabled: true
53
- Max: 13
53
+ Max: 4
54
+ CountKeywordArgs: false
54
55
 
55
56
  Metrics/PerceivedComplexity:
56
57
  Description: >-
data/CHANGELOG.md ADDED
@@ -0,0 +1,45 @@
1
+ # Change Log
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on [Keep a Changelog](http://keepachangelog.com/)
5
+ and this project adheres to [Semantic Versioning](http://semver.org/).
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [0.2.0]
10
+ ### Added
11
+ - Created this Changelog.
12
+ - API calls will now print potentially-useful information if $DEBUG=true
13
+
14
+ ### Changed
15
+ - Improved documentation (particularly for `API.new` and `API.params_for`).
16
+ - `API.new` will no longer instantiate without any parameters, though it is less
17
+ fussy about its parameters now.
18
+ - APIError now unescapes some HTML entities from the provided message for
19
+ improved readability.
20
+ - APIError will also pretty-print JSON responses.
21
+
22
+ ## [0.1.6] - 2017-02-08
23
+ ### Changed
24
+ - Minor README improvements.
25
+
26
+ ### Fixed
27
+ - Action names with hyphens were broken. The methods still use underscores
28
+ instead, but the proper hyphenated names are sent to the API.
29
+
30
+ ## [0.1.5] - 2017-02-07
31
+ First public release.
32
+
33
+ ### Changed
34
+ - Almost everything. Reorganized layout of gem to prepare for actual release.
35
+ This is the first point of reasonable functionality/stability.
36
+
37
+ ## [0.0.1] - 2017-02-07
38
+ ### Added
39
+ - Initial commit, not publicly released
40
+
41
+ [Unreleased]: https://github.com/nomoon/lunanode/compare/v0.2.0...HEAD
42
+ [0.2.0]: https://github.com/nomoon/lunanode/compare/v0.1.6...v0.2.0
43
+ [0.1.6]: https://github.com/nomoon/lunanode/compare/v0.1.5...v0.1.6
44
+ [0.1.5]: https://github.com/nomoon/lunanode/compare/v0.0.1...v0.1.5
45
+ [0.0.1]: https://github.com/nomoon/lunanode/releases/tag/v0.0.1
data/lib/lunanode/api.rb CHANGED
@@ -28,28 +28,24 @@ module Lunanode
28
28
  API_ENDPOINT = "https://dynamic.lunanode.com/api/".freeze
29
29
  @params_for = {}
30
30
 
31
- # Show parameter info for any API method.
31
+ # Show parameter info for any {API} instance method.
32
32
  #
33
- # @param method_name[#to_sym] The name of the API method
34
- # @return [Hash] information about the method parameters
33
+ # The keys of the hash results denote the type of parameter:
34
+ # - :keyreq => Required keyword argument
35
+ # - :key => Optional keyword argument
36
+ # - :keyrest => Arbitrary additional keyword arguments
37
+ # - :req => Required positional argument
38
+ # - :opt => Optional positional argument
39
+ # - :rest => Arbitrary additional positional arguments
35
40
  #
41
+ # @param method_name[#to_sym] The name of the API method
42
+ # @return [Hash] information about the method parameters.
36
43
  def self.params_for(method_name)
37
44
  @params_for[method_name] ||= begin
38
45
  method_name = method_name.to_sym
39
46
  param_groups = instance_method(method_name).parameters.group_by(&:first)
40
- out = {
41
- required: param_groups[:keyreq] && param_group[:keyreq].map(&:last),
42
- optional: param_groups[:key] && param_groups[:key].map(&:last),
43
- additional: param_groups.key?(:keyrest),
44
- }
45
- out.each do |k, v|
46
- if v
47
- v.freeze
48
- else
49
- out.delete(k)
50
- end
51
- end
52
- out.freeze
47
+ out = param_groups.map { |k, v| [k, v.map(&:last)] }.to_h
48
+ out.each_value(&:freeze).freeze
53
49
  end
54
50
  end
55
51
 
@@ -60,28 +56,33 @@ module Lunanode
60
56
  include APIActions
61
57
  attr_reader :api_id
62
58
 
59
+ # Instantiate an API object
60
+ #
61
+ # @return [API] an API instance.
62
+ #
63
63
  # @overload initialize(credentials_file)
64
64
  # Instantiate an API object from a credentials file.
65
- # @param credentials_file[IO,String] a JSON credentials file
65
+ # @param credentials_file[String,File] a JSON credentials file
66
66
  # (which contains the keys `api_id` and `api_key`)
67
67
  #
68
- # @overload initialize(api_id: nil, api_key: nil)
68
+ # @raise [JSON::ParserError] if the JSON file could not be read properly.
69
+ # @raise [KeyError] if any required key could not be found.
70
+ #
71
+ # @overload initialize(api_id: , api_key: )
69
72
  # Instantiate an API object from an API ID and API Key.
70
73
  # @param api_id[String] A LunaNode API ID
71
74
  # @param api_key[String] A LunaNode API Key
72
75
  #
73
- def initialize(credentials_file = nil, api_id: nil, api_key: nil)
74
- if !credentials_file.nil? && File.exist?(credentials_file)
76
+ # @raise [KeyError] if any required key could not be found.
77
+ #
78
+ def initialize(*args, **options)
79
+ credentials_file = args.compact.first.to_s
80
+ if File.exist?(credentials_file)
75
81
  credentials_data = File.read(credentials_file)
76
- credentials = JSON.parse(credentials_data, symbolize_names: true)
77
- @api_id = credentials[:api_id]
78
- @api_key = credentials[:api_key]
79
- else
80
- @api_id = api_id
81
- @api_key = api_key
82
+ options = JSON.parse(credentials_data, symbolize_names: true)
82
83
  end
83
- @api_id = @api_id.to_s.freeze
84
- @api_key = @api_key.to_s.freeze
84
+ @api_id = options.fetch(:api_id).to_s.dup.freeze
85
+ @api_key = options.fetch(:api_key).to_s.dup.freeze
85
86
  @rest_client = RestClient::Resource.new(
86
87
  API_ENDPOINT,
87
88
  verify_ssl: OpenSSL::SSL::VERIFY_PEER
@@ -98,7 +99,7 @@ module Lunanode
98
99
  #
99
100
  # @param category[#to_sym] The API action category (i.e. dns, image, vm...)
100
101
  # @param action[#to_sym] The API action name (i.e. create, list...)
101
- # @param params[Hash] Any parameters required for the action.
102
+ # @param params[**Hash] Any parameters required for the action.
102
103
  #
103
104
  # @return [Hash,Array,String] Response data from the API action.
104
105
  # @raise [APIError] If there was a problem with the action.
@@ -122,6 +123,14 @@ module Lunanode
122
123
  # Make an API call and return response.
123
124
  def call_api(handler_path, params)
124
125
  req_formdata = auth_request_formdata(handler_path, clean_params(params))
126
+ if $DEBUG
127
+ STDERR.puts "call_api()\n" + JSON.pretty_generate(
128
+ path: "#{rest_client.url}#{handler_path}",
129
+ req: JSON.parse(req_formdata[:req]),
130
+ signature: req_formdata[:signature],
131
+ nonce: req_formdata[:nonce]
132
+ )
133
+ end
125
134
  JSON.parse(rest_client[handler_path].post(req_formdata),
126
135
  symbolize_names: true)
127
136
  rescue RestClient::Exception => err
@@ -155,7 +164,7 @@ module Lunanode
155
164
  def raw_request_message(params)
156
165
  params[:api_id] = api_id
157
166
  params[:api_partialkey] = api_key.slice(0, 64)
158
- params.to_json
167
+ JSON.generate(params)
159
168
  end
160
169
 
161
170
  # Generate nonce for request
@@ -1,5 +1,16 @@
1
+ # frozen_string_literal: true
2
+ require "cgi"
3
+ require "json"
4
+
1
5
  module Lunanode
2
6
  # A RuntimeError raised when the API call returns unsuccessfully.
3
7
  class APIError < RuntimeError
8
+ def to_s
9
+ unescaped = CGI.unescapeHTML(super)
10
+ return unescaped unless unescaped.start_with?("\"{")
11
+ JSON.pretty_generate(JSON.parse(unescaped.gsub(/\A"|"\z/, "")))
12
+ rescue JSON::ParserError
13
+ unescaped
14
+ end
4
15
  end
5
16
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Lunanode
3
- VERSION = "0.1.6".freeze
3
+ VERSION = "0.2.0".freeze
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lunanode
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Bellefleur
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-02-08 00:00:00.000000000 Z
11
+ date: 2017-02-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rest-client
@@ -123,6 +123,7 @@ files:
123
123
  - ".ruby-version"
124
124
  - ".travis.yml"
125
125
  - ".yardopts"
126
+ - CHANGELOG.md
126
127
  - CODE_OF_CONDUCT.md
127
128
  - Gemfile
128
129
  - LICENSE.txt