Class: Diplomat::Kv

Inherits:
RestClient show all
Defined in:
lib/diplomat/kv.rb

Overview

Methods for interacting with the Consul KV API endpoint

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from RestClient

access_method?, #concat_url, #configuration, #initialize, method_missing, respond_to?, respond_to_missing?, #use_named_parameter

Constructor Details

This class inherits a constructor from Diplomat::RestClient

Instance Attribute Details

#keyObject (readonly)

Returns the value of attribute key.



7
8
9
# File 'lib/diplomat/kv.rb', line 7

def key
  @key
end

#rawObject (readonly)

Returns the value of attribute raw.



7
8
9
# File 'lib/diplomat/kv.rb', line 7

def raw
  @raw
end

#valueObject (readonly)

Returns the value of attribute value.



7
8
9
# File 'lib/diplomat/kv.rb', line 7

def value
  @value
end

Instance Method Details

#delete(key, options = {}) ⇒ OpenStruct

Delete a value by its key

Parameters:

  • key (String)

    the key

  • options (Hash) (defaults to: {})

    the query params

Options Hash (options):

  • :dc (String)

    Target datacenter

  • :recurse (Boolean)

    If to make recursive get or not

Returns:

  • (OpenStruct)


177
178
179
180
181
182
183
184
185
# File 'lib/diplomat/kv.rb', line 177

def delete(key, options = {})
  key = normalize_key_for_uri(key)
  @key = key
  @options = options
  custom_params = []
  custom_params << recurse_get(@options)
  custom_params << dc(@options)
  @raw = send_delete_request(@conn, ["/v1/kv/#{@key}"], options, custom_params)
end

#get(key, options = {}, not_found = :reject, found = :return) ⇒ String

Note:

When trying to access a key, there are two possibilites:

  • The key doesn’t (yet) exist

  • The key exists. This may be its first value, there is no way to tell

The combination of not_found and found behaviour gives maximum possible flexibility. For X: reject, R: return, W: wait

  • X X - meaningless; never return a value

  • X R - “normal” non-blocking get operation. Default

  • X W - get the next value only (must have a current value)

  • R X - meaningless; never return a meaningful value

  • R R - “safe” non-blocking, non-throwing get-or-default operation

  • R W - get the next value or a default

  • W X - get the first value only (must not have a current value)

  • W R - get the first or current value; always return something, but

    block only when necessary
    
  • W W - get the first or next value; wait until there is an update

Get a value by its key, potentially blocking for the first or next value rubocop:disable Metrics/PerceivedComplexity, Metrics/MethodLength, Layout/LineLength, Metrics/CyclomaticComplexity

Parameters:

  • key (String)

    the key

  • options (Hash) (defaults to: {})

    the query params

  • not_found (Symbol) (defaults to: :reject)

    behaviour if the key doesn’t exist; :reject with exception, :return degenerate value, or :wait for it to appear

  • found (Symbol) (defaults to: :return)

    behaviour if the key does exist; :reject with exception, :return its current value, or :wait for its next value

Options Hash (options):

  • :recurse (Boolean)

    If to make recursive get or not

  • :consistency (String)

    The read consistency type

  • :dc (String)

    Target datacenter

  • :keys (Boolean)

    Only return key names.

  • :modify_index (Boolean)

    Only return ModifyIndex value.

  • :session (Boolean)

    Only return Session value.

  • :decode_values (Boolean)

    Return consul response with decoded values.

  • :separator (String)

    List only up to a given separator. Only applies when combined with :keys option.

  • :nil_values (Boolean)

    If to return keys/dirs with nil values

  • :convert_to_hash (Boolean)

    Take the data returned from consul and build a hash

  • :transformation (Callable)

    function to invoke on keys values

Returns:

  • (String)

    The base64-decoded value associated with the key



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/diplomat/kv.rb', line 46

def get(key, options = {}, not_found = :reject, found = :return)
  @options = options
  return_nil_values = @options && @options[:nil_values]
  transformation = @options && @options[:transformation] && @options[:transformation].methods.find_index(:call) ? @options[:transformation] : nil
  raw = get_raw(key, options)

  if raw.status == 404
    case not_found
    when :reject
      raise Diplomat::KeyNotFound, key
    when :return
      return @value = ''
    when :wait
      index = raw.headers['x-consul-index']
    end
  elsif raw.status == 200
    case found
    when :reject
      raise Diplomat::KeyAlreadyExists, key
    when :return
      @raw = raw
      @raw = parse_body
      return @raw.first['ModifyIndex'] if @options && @options[:modify_index]
      return @raw.first['Session'] if @options && @options[:session]
      return decode_values if @options && @options[:decode_values]
      return convert_to_hash(return_value(return_nil_values, transformation, true)) if @options && @options[:convert_to_hash]

      return return_value(return_nil_values, transformation)
    when :wait
      index = raw.headers['x-consul-index']
    end
  else
    raise Diplomat::UnknownStatus, "status #{raw.status}: #{raw.body}"
  end

  # Wait for first/next value
  @raw = wait_for_value(index, options)
  @raw = parse_body
  return_value(return_nil_values, transformation)
end

#get_all(key, options = {}, not_found = :reject, found = :return) ⇒ List

Get all keys recursively, potentially blocking for the first or next value rubocop:disable Metrics/PerceivedComplexity, Metrics/MethodLength, Layout/LineLength, Metrics/CyclomaticComplexity

Parameters:

  • key (String)

    the key

  • options (Hash) (defaults to: {})

    the query params

  • not_found (Symbol) (defaults to: :reject)

    behaviour if the key doesn’t exist; :reject with exception, :return degenerate value, or :wait for it to appear

  • found (Symbol) (defaults to: :return)

    behaviour if the key does exist; :reject with exception, :return its current value, or :wait for its next value

Options Hash (options):

  • :consistency (String)

    The read consistency type

  • :dc (String)

    Target datacenter

  • :keys (Boolean)

    Only return key names.

  • :decode_values (Boolean)

    Return consul response with decoded values.

  • :separator (String)

    List only up to a given separator. Only applies when combined with :keys option.

  • :nil_values (Boolean)

    If to return keys/dirs with nil values

  • :convert_to_hash (Boolean)

    Take the data returned from consul and build a hash

  • :transformation (Callable)

    function to invoke on keys values

Returns:

  • (List)

    List of hashes, one hash for each key-value returned



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/diplomat/kv.rb', line 106

def get_all(key, options = {}, not_found = :reject, found = :return)
  @options = options
  @options[:recurse] = true
  return_nil_values = @options && @options[:nil_values]
  transformation = @options && @options[:transformation] && @options[:transformation].methods.find_index(:call) ? @options[:transformation] : nil

  raw = get_raw(key, options)
  if raw.status == 404
    case not_found
    when :reject
      raise Diplomat::KeyNotFound, key
    when :return
      return @value = []
    when :wait
      index = raw.headers['x-consul-index']
    end
  elsif raw.status == 200
    case found
    when :reject
      raise Diplomat::KeyAlreadyExists, key
    when :return
      @raw = raw
      @raw = parse_body
      return decode_values if @options && @options[:decode_values]
      return convert_to_hash(return_value(return_nil_values, transformation, true)) if @options && @options[:convert_to_hash]

      return return_value(return_nil_values, transformation, true)
    when :wait
      index = raw.headers['x-consul-index']
    end
  else
    raise Diplomat::UnknownStatus, "status #{raw.status}: #{raw.body}"
  end

  # Wait for first/next value
  @raw = wait_for_value(index, options)
  @raw = parse_body
  return_value(return_nil_values, transformation, true)
end

#put(key, value, options = {}) ⇒ Bool

Associate a value with a key

Parameters:

  • key (String)

    the key

  • value (String)

    the value

  • options (Hash) (defaults to: {})

    the query params

Options Hash (options):

  • :cas (Integer)

    The modify index

  • :dc (String)

    Target datacenter

  • :acquire (String)

    Session to attach to key

Returns:

  • (Bool)

    Success or failure of the write (can fail in c-a-s mode)



155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/diplomat/kv.rb', line 155

def put(key, value, options = {})
  key = normalize_key_for_uri(key)
  @options = options
  custom_params = []
  custom_params << use_cas(@options)
  custom_params << dc(@options)
  custom_params << acquire(@options)
  @raw = send_put_request(@conn, ["/v1/kv/#{key}"], options, value, custom_params,
                          'application/x-www-form-urlencoded')
  if @raw.body.chomp == 'true'
    @key = key
    @value = value
  end
  @raw.body.chomp == 'true'
end

#txn(value, options = {}) ⇒ OpenStruct

Perform a key/value store transaction.

Examples:

Valid key/value store transaction format

[
  {
    'KV' => {
      'Verb' => 'get',
      'Key' => 'hello/world'
    }
  }
]

Parameters:

  • value (Array)

    an array of transaction hashes

  • options (Hash) (defaults to: {})

    transaction params

Options Hash (options):

  • :decode_values (Boolean)

    of any GET requests, default: true

  • :dc (String)

    Target datacenter

  • :consistency (String)

    the accepted staleness level of the transaction. Can be ‘stale’ or ‘consistent’

Returns:

  • (OpenStruct)

    result of the transaction

Raises:

See Also:

Since:

  • 1.3.0



208
209
210
211
212
213
214
215
216
217
# File 'lib/diplomat/kv.rb', line 208

def txn(value, options = {})
  # Verify the given value for the transaction
  transaction_verification(value)
  # Will return 409 if transaction was rolled back
  custom_params = []
  custom_params << dc(options)
  custom_params << transaction_consistency(options)
  raw = send_put_request(@conn_no_err, ['/v1/txn'], options, value, custom_params)
  transaction_return JSON.parse(raw.body), options
end