defmodule Consul.Api.V1.Kv do
@moduledoc """
Higher level abstraction on top of Consul's Key Value API.
"""
alias Consul.{Connection, JsonCodec, Request, Response, YamlCodec}
@doc """
Get the value and metadata for a given key from the KV Store.
"""
def get(connection, key, optional_params \\ [], opts \\ []) do
optional_params_config = %{
:dc => :query,
:recurse => :query,
:raw => :query,
:keys => :query,
:separator => :query,
:ns => :query,
:index => :query,
:wait => :query
}
request =
Request.new()
|> Request.method(:get)
|> Request.url("/v1/kv/{key}", %{
"key" => key
})
|> Request.add_optional_params(optional_params_config, optional_params)
connection
|> Connection.execute(request)
|> Response.decode(opts ++ [as: %{}])
|> case do
{:ok, %{body: results} = env} when is_list(results) ->
result =
results
|> Enum.map(fn
%{"Value" => value} = map when value != nil ->
value = Base.decode64!(value)
value =
if Keyword.get(opts, :decode, true),
do: decode_value(value),
else: value
Map.put(map, "Value", value)
other ->
other
end)
{:ok, %{env | body: result}}
other ->
other
end
end
defp decode_value(value) do
case JsonCodec.decode(value) do
{:ok, map} ->
map
## poison new releases return the position
{:error, _, _pos} ->
check_yaml(value)
{:error, _} ->
check_yaml(value)
end
end
def check_yaml(value) do
case YamlCodec.read_from_string(value) do
{:ok, value} -> value
{:error, _} -> raise RuntimeError, "expected JSON or YAML value"
end
end
end