diff --git a/.rubocop.yml b/.rubocop.yml index 7681dd0..2983292 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -2,6 +2,12 @@ AllCops: DisplayCopNames: true +Metrics/AbcSize: + Max: 17 + +Metrics/CyclomaticComplexity: + Max: 7 + Metrics/LineLength: # This will disable the rule completely, regardless what other options you put Enabled: true @@ -11,3 +17,6 @@ Metrics/LineLength: # Allow classes longer than 100 lines of code ClassLength: Max: 250 + +Naming/UncommunicativeMethodParamName: + Enabled: false diff --git a/lib/diplomat.rb b/lib/diplomat.rb index e18f451..30ad53f 100644 --- a/lib/diplomat.rb +++ b/lib/diplomat.rb @@ -23,8 +23,8 @@ def require_libs(*libs) raise 'Diplomat only supports ruby >= 2.0.0' unless RUBY_VERSION.to_f >= 2.0 - self.root_path = File.expand_path '..', __FILE__ - self.lib_path = File.expand_path '../diplomat', __FILE__ + self.root_path = File.expand_path __dir__ + self.lib_path = File.expand_path 'diplomat', __dir__ require_libs 'configuration', 'rest_client', 'api_options', 'kv', 'datacenter', 'service', 'members', 'node', 'nodes', 'check', 'health', 'session', 'lock', diff --git a/lib/diplomat/acl.rb b/lib/diplomat/acl.rb index 8c0f599..383ea4b 100644 --- a/lib/diplomat/acl.rb +++ b/lib/diplomat/acl.rb @@ -15,7 +15,7 @@ def info(id, options = nil, not_found = :reject, found = :return) @options = options url = ["/v1/acl/info/#{id}"] url << check_acl_token - url << use_consistency(options) + url << use_consistency(options) if use_consistency(options) raw = @conn_no_err.get concat_url url if raw.status == 200 && raw.body.chomp != 'null' diff --git a/lib/diplomat/api_options.rb b/lib/diplomat/api_options.rb index 03ce558..c5f9ab2 100644 --- a/lib/diplomat/api_options.rb +++ b/lib/diplomat/api_options.rb @@ -9,10 +9,6 @@ def use_cas(options) options ? use_named_parameter('cas', options[:cas]) : [] end - def use_consistency(options) - options && options[:consistency] ? [options[:consistency].to_s] : [] - end - # Mapping for valid key/value store transaction verbs and required parameters # # @return [Hash] valid key/store transaction verbs and required parameters diff --git a/lib/diplomat/datacenter.rb b/lib/diplomat/datacenter.rb index a4808c6..c365390 100644 --- a/lib/diplomat/datacenter.rb +++ b/lib/diplomat/datacenter.rb @@ -5,9 +5,13 @@ class Datacenter < Diplomat::RestClient # Get an array of all avaliable datacenters accessible by the local consul agent # @param meta [Hash] output structure containing header information about the request (index) + # @param options [Hash] Options to use when performing request + # @option options [String] :dc string for dc specific query + # @option options [String] :consistency The read consistency type # @return [OpenStruct] all datacenters avaliable to this consul agent - def get(meta = nil) + def get(meta = nil, options = nil) url = ['/v1/catalog/datacenters'] + url << use_consistency(options) if use_consistency(options) ret = @conn.get concat_url url diff --git a/lib/diplomat/health.rb b/lib/diplomat/health.rb index 2dd18f2..dd1816e 100644 --- a/lib/diplomat/health.rb +++ b/lib/diplomat/health.rb @@ -6,11 +6,14 @@ class Health < Diplomat::RestClient # Get node health # @param n [String] the node - # @param options [Hash] :dc string for dc specific query + # @param options [Hash] Options to use when performing request + # @option options [String] :dc string for dc specific query + # @option options [String] :consistency The read consistency type # @return [OpenStruct] all data associated with the node def node(n, options = nil) url = ["/v1/health/node/#{n}"] url << use_named_parameter('dc', options[:dc]) if options && options[:dc] + url << use_consistency(options) if use_consistency(options) # If the request fails, it's probably due to a bad path # so return a PathNotFound error. @@ -22,11 +25,14 @@ def node(n, options = nil) # Get service checks # @param s [String] the service - # @param options [Hash] :dc string for dc specific query + # @param options [Hash] Options to use when performing request + # @option options [String] :dc string for dc specific query + # @option options [String] :consistency The read consistency type # @return [OpenStruct] all data associated with the node def checks(s, options = nil) url = ["/v1/health/checks/#{s}"] url << use_named_parameter('dc', options[:dc]) if options && options[:dc] + url << use_consistency(options) if use_consistency(options) # If the request fails, it's probably due to a bad path # so return a PathNotFound error. @@ -38,9 +44,12 @@ def checks(s, options = nil) # Get service health # @param s [String] the service - # @param options [Hash] :dc string for dc specific query + # @param options [Hash] Options to use when performing request + # @option options [String] :dc string for dc specific query + # @option options [String] :consistency The read consistency type # @param options [Hash] :passing boolean to return only checks in passing state # @param options [Hash] :tag string for specific tag + # @option options [String] :consistency The read consistency type # @return [OpenStruct] all data associated with the node # rubocop:disable PerceivedComplexity, CyclomaticComplexity, AbcSize def service(s, options = nil) @@ -49,6 +58,7 @@ def service(s, options = nil) url << 'passing' if options && options[:passing] url << use_named_parameter('tag', options[:tag]) if options && options[:tag] url << use_named_parameter('near', options[:near]) if options && options[:near] + url << use_consistency(options) if use_consistency(options) # If the request fails, it's probably due to a bad path # so return a PathNotFound error. @@ -61,13 +71,16 @@ def service(s, options = nil) # Get service health # @param s [String] the state ("any", "passing", "warning", or "critical") - # @param options [Hash] :dc string for dc specific query + # @param options [Hash] Options to use when performing request + # @option options [String] :dc string for dc specific query + # @option options [String] :consistency The read consistency type # @return [OpenStruct] all data associated with the node # rubocop:disable AbcSize def state(s, options = nil) url = ["/v1/health/state/#{s}"] url << use_named_parameter('dc', options[:dc]) if options && options[:dc] url << use_named_parameter('near', options[:near]) if options && options[:near] + url << use_consistency(options) if use_consistency(options) # If the request fails, it's probably due to a bad path # so return a PathNotFound error. diff --git a/lib/diplomat/kv.rb b/lib/diplomat/kv.rb index 64c070b..45c2d7a 100644 --- a/lib/diplomat/kv.rb +++ b/lib/diplomat/kv.rb @@ -50,7 +50,7 @@ def get(key, options = nil, not_found = :reject, found = :return) url = ["/v1/kv/#{@key}"] url += recurse_get(@options) url += check_acl_token - url += use_consistency(@options) + url += use_consistency(@options, []) url += dc(@options) url += keys(@options) url += separator(@options) @@ -256,7 +256,7 @@ def decode_transaction(transaction) # rubocop:disable Metrics/MethodLength next unless resp['KV']['Value'] begin resp['KV']['Value'] = Base64.decode64(resp['KV']['Value']) - rescue # rubocop:disable RescueWithoutErrorClass + rescue StandardError nil end end diff --git a/lib/diplomat/lock.rb b/lib/diplomat/lock.rb index da70a9c..96a1925 100644 --- a/lib/diplomat/lock.rb +++ b/lib/diplomat/lock.rb @@ -11,7 +11,6 @@ class Lock < Diplomat::RestClient # @param value [String] the value for the key # @param options [Hash] :dc string for dc specific query # @return [Boolean] If the lock was acquired - # rubocop:disable AbcSize def acquire(key, session, value = nil, options = nil) raw = @conn.put do |req| url = ["/v1/kv/#{key}"] @@ -24,7 +23,6 @@ def acquire(key, session, value = nil, options = nil) end raw.body.chomp == 'true' end - # rubocop:enable AbcSize # wait to aquire a lock # @param key [String] the key diff --git a/lib/diplomat/node.rb b/lib/diplomat/node.rb index f29af90..6188fb7 100644 --- a/lib/diplomat/node.rb +++ b/lib/diplomat/node.rb @@ -7,12 +7,15 @@ class Node < Diplomat::RestClient # Get a node by it's key # @param key [String] the key - # @param options [Hash] :dc string for dc specific query + # @param options [Hash] Options to use when performing request + # @option options [String] :dc string for dc specific query + # @option options [String] :consistency The read consistency type # @return [OpenStruct] all data associated with the node def get(key, options = nil) url = ["/v1/catalog/node/#{key}"] url += check_acl_token url << use_named_parameter('dc', options[:dc]) if options && options[:dc] + url << use_consistency(options) if use_consistency(options) # If the request fails, it's probably due to a bad path # so return a PathNotFound error. @@ -23,7 +26,9 @@ def get(key, options = nil) end # Get all the nodes - # @param options [Hash] :dc string for dc specific query + # @param options [Hash] Options to use when performing request + # @option options [String] :dc string for dc specific query + # @option options [String] :consistency The read consistency type # @return [OpenStruct] the list of all nodes def get_all(options = nil) url = ['/v1/catalog/nodes'] diff --git a/lib/diplomat/nodes.rb b/lib/diplomat/nodes.rb index 62cee13..c331234 100644 --- a/lib/diplomat/nodes.rb +++ b/lib/diplomat/nodes.rb @@ -7,14 +7,16 @@ class Nodes < Diplomat::RestClient # Get all nodes # @deprecated Please use Diplomat::Node instead. # @return [OpenStruct] all data associated with the nodes in catalog - def get + def get(options = nil) ret = @conn.get '/v1/catalog/nodes' + url << use_consistency(options) if use_consistency(options) JSON.parse(ret.body) end def get_all(options = nil) url = ['/v1/catalog/nodes'] url << use_named_parameter('dc', options[:dc]) if options && options[:dc] + url << use_consistency(options) if use_consistency(options) ret = @conn.get concat_url url JSON.parse(ret.body).map { |service| OpenStruct.new service } diff --git a/lib/diplomat/query.rb b/lib/diplomat/query.rb index da239ac..4153fbe 100644 --- a/lib/diplomat/query.rb +++ b/lib/diplomat/query.rb @@ -7,12 +7,15 @@ class Query < Diplomat::RestClient # Get a prepared query by it's key # @param key [String] the prepared query ID - # @param options [Hash] :dc string for dc specific query + # @param options [Hash] Options to use when performing request + # @option options [String] :dc string for dc specific query + # @option options [String] :consistency The read consistency type # @return [OpenStruct] all data associated with the prepared query def get(key, options = nil) url = ["/v1/query/#{key}"] url += check_acl_token url << use_named_parameter('dc', options[:dc]) if options && options[:dc] + url << use_consistency(options) if use_consistency(options) ret = @conn.get concat_url url JSON.parse(ret.body).map { |query| OpenStruct.new query } @@ -21,13 +24,15 @@ def get(key, options = nil) end # Get all prepared queries - # @param options [Hash] :dc Consul datacenter to query + # @param options [Hash] Options to use when performing request + # @option options [String] :dc string for dc specific query + # @option options [String] :consistency The read consistency type # @return [OpenStruct] the list of all prepared queries def get_all(options = nil) url = ['/v1/query'] url += check_acl_token url << use_named_parameter('dc', options[:dc]) if options && options[:dc] - + url << use_consistency(options) if use_consistency(options) ret = @conn.get concat_url url JSON.parse(ret.body).map { |query| OpenStruct.new query } rescue Faraday::ClientError @@ -36,7 +41,8 @@ def get_all(options = nil) # Create a prepared query or prepared query template # @param definition [Hash] Hash containing definition of prepared query - # @param options [Hash] :dc Consul datacenter to query + # @param options [Hash] Options to use when performing request + # @option options [String] :dc string for dc specific query # @return [String] the ID of the prepared query created def create(definition, options = nil) url = ['/v1/query'] @@ -54,7 +60,8 @@ def create(definition, options = nil) # Delete a prepared query or prepared query template # @param key [String] the prepared query ID - # @param options [Hash] :dc Consul datacenter to query + # @param options [Hash] Options to use when performing request + # @option options [String] :dc string for dc specific query # @return [Boolean] def delete(key, options = nil) url = ["/v1/query/#{key}"] @@ -68,7 +75,8 @@ def delete(key, options = nil) # Update a prepared query or prepared query template # @param key [String] the prepared query ID # @param definition [Hash] Hash containing updated definition of prepared query - # @param options [Hash] :dc Consul datacenter to query + # @param options [Hash] Options to use when performing request + # @option options [String] :dc string for dc specific query # @return [Boolean] def update(key, definition, options = nil) url = ["/v1/query/#{key}"] @@ -85,8 +93,9 @@ def update(key, definition, options = nil) # Execute a prepared query or prepared query template # @param key [String] the prepared query ID or name - # @param options [Hash] prepared query execution options - # @option dc [String] :dc Consul datacenter to query + # @param options [Hash] Options to use when performing request + # @option options [String] :dc string for dc specific query + # @option options [String] :consistency The read consistency type # @option near [String] node name to sort the resulting list in ascending order based on the # estimated round trip time from that node # @option limit [Integer] to limit the size of the return list to the given number of results @@ -98,7 +107,7 @@ def execute(key, options = nil) url << use_named_parameter('dc', options[:dc]) if options && options[:dc] url << use_named_parameter('near', options[:near]) if options && options[:near] url << use_named_parameter('limit', options[:limit]) if options && options[:limit] - + url << use_consistency(options) if use_consistency(options) ret = @conn.get concat_url url OpenStruct.new JSON.parse(ret.body) rescue Faraday::ClientError @@ -108,13 +117,15 @@ def execute(key, options = nil) # Get the fully rendered query template # @param key [String] the prepared query ID or name - # @param options [Hash] :dc Consul datacenter to query + # @param options [Hash] Options to use when performing request + # @option options [String] :dc string for dc specific query + # @option options [String] :consistency The read consistency type # @return [OpenStruct] the list of results from the prepared query or prepared query template def explain(key, options = nil) url = ["/v1/query/#{key}/explain"] url += check_acl_token url << use_named_parameter('dc', options[:dc]) if options && options[:dc] - + url << use_consistency(options) if use_consistency(options) ret = @conn.get concat_url url OpenStruct.new JSON.parse(ret.body) rescue Faraday::ClientError diff --git a/lib/diplomat/rest_client.rb b/lib/diplomat/rest_client.rb index efbee4a..d3019de 100644 --- a/lib/diplomat/rest_client.rb +++ b/lib/diplomat/rest_client.rb @@ -17,6 +17,21 @@ def use_named_parameter(name, value) value ? ["#{name}=#{value}"] : [] end + # Parse options and return consistency. + # If consistency is not found, will return default_value + def use_consistency(options, default_value = nil) + return default_value unless options + case options[:consistency] + when 'consistent' + return use_named_parameter('consistent', 'consistent') + when 'stale' + return use_named_parameter('stale', 'stale') + when 'leader' + return use_named_parameter('leader', 'leader') + end + default_value + end + # Assemble a url from an array of parts. # @param parts [Array] the url chunks to be assembled # @return [String] the resultant url string @@ -143,7 +158,7 @@ def decode_values @raw.each_with_object([]) do |acc, el| begin acc['Value'] = Base64.decode64(acc['Value']) - rescue # rubocop:disable RescueWithoutErrorClass + rescue StandardError nil end el << acc diff --git a/lib/diplomat/service.rb b/lib/diplomat/service.rb index 463607c..70bf75f 100644 --- a/lib/diplomat/service.rb +++ b/lib/diplomat/service.rb @@ -12,6 +12,7 @@ class Service < Diplomat::RestClient # @option wait [Integer] :wait string for wait time # @option index [String] :index for index of last query # @option dc [String] :dc data center to make request for + # @option options [String] :consistency The read consistency type # @option tag [String] :tag service tag to get # @param meta [Hash] output structure containing header information about the request (index) # @return [OpenStruct] all data associated with the service @@ -23,6 +24,7 @@ def get(key, scope = :first, options = nil, meta = nil) url << use_named_parameter('index', options[:index]) if options && options[:index] url << use_named_parameter('dc', options[:dc]) if options && options[:dc] url << use_named_parameter('tag', options[:tag]) if options && options[:tag] + url << use_consistency(options) if use_consistency(options) # If the request fails, it's probably due to a bad path # so return a PathNotFound error. @@ -47,12 +49,15 @@ def get(key, scope = :first, options = nil, meta = nil) # rubocop:enable PerceivedComplexity, MethodLength, CyclomaticComplexity, AbcSize # Get all the services - # @param options [Hash] :dc Consul datacenter to query + # @param options [Hash] Options to use when performing request + # @option options [String] :dc string for dc specific query + # @option options [String] :consistency The read consistency type # @return [OpenStruct] the list of all services def get_all(options = nil) url = ['/v1/catalog/services'] url += check_acl_token url << use_named_parameter('dc', options[:dc]) if options && options[:dc] + url << use_consistency(options) if use_consistency(options) begin ret = @conn.get concat_url url rescue Faraday::ClientError @@ -113,6 +118,5 @@ def maintenance(service_id, options = { enable: true }) end maintenance.status == 200 end - # rubocop:enable AbcSize end end