-
-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Base.run/5 refactored to middleware. Stubs for response middleware.
- Loading branch information
1 parent
111e8b8
commit dd26242
Showing
25 changed files
with
421 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,8 @@ | ||
language: elixir | ||
sudo: false | ||
cache: | ||
directories: | ||
- priv/plts | ||
elixir: | ||
- 1.8 | ||
- 1.7 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
defmodule K8s.Middleware do | ||
@moduledoc "Interface for interacting with cluster middleware" | ||
|
||
alias K8s.Middleware.{Error, Request} | ||
|
||
@typedoc "Middleware type" | ||
@type type_t :: :request | :response | ||
|
||
@typedoc "List of middlewares" | ||
@type stack_t :: list(module()) | ||
|
||
@spec defaults(K8s.Middleware.type_t()) :: stack_t | ||
def defaults(:request), do: [Request.Initialize, Request.EncodeBody] | ||
def defaults(:response), do: [] | ||
|
||
@doc "Initialize a clusters middleware stacks" | ||
@spec initialize(atom) :: :ok | ||
def initialize(cluster) do | ||
K8s.Middleware.Registry.set(cluster, :request, defaults(:request)) | ||
K8s.Middleware.Registry.set(cluster, :response, defaults(:response)) | ||
end | ||
|
||
@doc """ | ||
Applies middlewares registered to a `K8s.Cluster` to a `K8s.Middleware.Request` | ||
""" | ||
@spec run(Request.t()) :: {:ok, Request.t()} | {:error, Error.t()} | ||
def run(req) do | ||
middlewares = K8s.Middleware.Registry.list(req.cluster, :request) | ||
run(req, middlewares) | ||
end | ||
|
||
@spec run(Request.t(), list(module())) :: {:ok, Request.t()} | {:error, Error.t()} | ||
def run(req, middlewares) do | ||
result = | ||
Enum.reduce_while(middlewares, req, fn middleware, req -> | ||
case apply(middleware, :call, [req]) do | ||
{:ok, updated_request} -> | ||
{:cont, updated_request} | ||
|
||
{:error, error} -> | ||
{:halt, error(middleware, req, error)} | ||
end | ||
end) | ||
|
||
case result do | ||
%Request{} -> {:ok, result} | ||
%Error{} -> {:error, result} | ||
end | ||
end | ||
|
||
@spec error(module(), Request.t(), any()) :: Error.t() | ||
defp error(middleware, req, error) do | ||
%K8s.Middleware.Error{ | ||
middleware: middleware, | ||
error: error, | ||
request: req | ||
} | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
defmodule K8s.Middleware.Error do | ||
@moduledoc "Encapsulates middleware process errors" | ||
|
||
@typedoc """ | ||
Middleware processing error | ||
* `middleware` middleware module that caused the error | ||
* `request` `K8s.Middleware.Request` | ||
* `error` actual error, can be `any()` type | ||
""" | ||
@type t :: %__MODULE__{ | ||
request: K8s.Middleware.Request.t() | nil, | ||
middleware: module(), | ||
error: any() | ||
} | ||
defstruct [:request, :middleware, :error] | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
defmodule K8s.Middleware.Registry do | ||
@moduledoc "Cluster middleware registry" | ||
use Agent | ||
|
||
@spec start_link(Keyword.t()) :: Agent.on_start() | ||
def start_link(_opts) do | ||
Agent.start_link(fn -> %{} end, name: __MODULE__) | ||
end | ||
|
||
@doc "Adds a middleware to the end of the middleware stack" | ||
@spec add(atom, K8s.Middleware.type_t(), module()) :: :ok | ||
def add(cluster, type, middleware) do | ||
Agent.update(__MODULE__, fn registry -> | ||
cluster_middlewares = Map.get(registry, cluster, %{}) | ||
middleware_list = Map.get(cluster_middlewares, type, []) | ||
|
||
updated_middleware_list = middleware_list ++ [middleware] | ||
updated_cluster_middlewares = Map.put(cluster_middlewares, type, updated_middleware_list) | ||
|
||
put_in(registry, [cluster], updated_cluster_middlewares) | ||
end) | ||
end | ||
|
||
@doc "Sets/replaces the middleware stack" | ||
@spec set(atom, K8s.Middleware.type_t(), list(module())) :: :ok | ||
def set(cluster, type, middlewares) do | ||
Agent.update(__MODULE__, fn registry -> | ||
cluster_middlewares = Map.get(registry, cluster, %{}) | ||
updated_cluster_middlewares = Map.put(cluster_middlewares, type, middlewares) | ||
|
||
put_in(registry, [cluster], updated_cluster_middlewares) | ||
end) | ||
end | ||
|
||
@doc "Returns middleware stack for a cluster and (request or response)" | ||
@spec list(atom, K8s.Middleware.type_t()) :: K8s.Middleware.stack_t() | ||
def list(cluster, type) do | ||
registry = Agent.get(__MODULE__, & &1[cluster]) || %{} | ||
Map.get(registry, type, []) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
defmodule K8s.Middleware.Request do | ||
@moduledoc "HTTP Request middleware" | ||
|
||
@typedoc "Middleware Request type" | ||
@type t :: %__MODULE__{ | ||
cluster: atom(), | ||
method: atom(), | ||
url: String.t(), | ||
body: String.t() | map() | list(map()) | nil, | ||
headers: Keyword.t() | nil, | ||
opts: Keyword.t() | nil | ||
} | ||
|
||
defstruct cluster: nil, method: nil, url: nil, body: nil, headers: [], opts: [] | ||
|
||
@doc "Request middleware callback" | ||
@callback call(t()) :: {:ok, t()} | {:error, any()} | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# defmodule K8s.Middleware.Request.BaseURL do | ||
# @behaviour K8s.Middleware.Request | ||
|
||
# @doc """ | ||
|
||
# ## Examples | ||
# iex> conn = K8s.Conn.from_file("./test/support/kube-config.yaml") | ||
# ...> K8s.Cluster.Registry.add(:test_cluster, conn) | ||
# ...> request = %K8s.Middleware.Request{cluster: :test_cluster} | ||
# ...> K8s.Middleware.Request.BaseURL.call(request) | ||
# {:ok, %K8s.Middleware.Request{cluster: :test_cluster, url: "https://localhost:6443"}} | ||
# """ | ||
# @impl true | ||
# def call(%K8s.Middleware.Request{} = req) do | ||
# {:ok, url} <- Cluster.url_for(operation, cluster_name) | ||
# {:ok, req} | ||
# end | ||
# end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
defmodule K8s.Middleware.Request.EncodeBody do | ||
@moduledoc """ | ||
Naive JSON body encoder. | ||
Encodes JSON payloads when given an modifiying HTTP verb, otherwise returns an empty string. | ||
""" | ||
@behaviour K8s.Middleware.Request | ||
alias K8s.Middleware.Request | ||
|
||
@impl true | ||
def call(%Request{method: method, body: body} = req) do | ||
case encode(body, method) do | ||
{:ok, encoded_body} -> | ||
req = %Request{req | body: encoded_body} | ||
{:ok, req} | ||
|
||
error -> | ||
error | ||
end | ||
end | ||
|
||
@spec encode(any(), atom()) :: {:ok, binary} | {:error, any} | ||
defp encode(body, http_method) when http_method in [:put, :patch, :post], do: Jason.encode(body) | ||
defp encode(_, _), do: {:ok, ""} | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
defmodule K8s.Middleware.Request.Initialize do | ||
@moduledoc """ | ||
Initializes a request with connection details (header and HTTPoison opts) from `K8s.Conn.RequestOptions` | ||
""" | ||
@behaviour K8s.Middleware.Request | ||
alias K8s.Middleware.Request | ||
|
||
@impl true | ||
def call(%Request{cluster: cluster, method: method, headers: headers, opts: opts} = req) do | ||
with {:ok, conn} <- K8s.Cluster.conn(cluster), | ||
{:ok, request_options} <- K8s.Conn.RequestOptions.generate(conn) do | ||
request_option_headers = K8s.http_provider().headers(method, request_options) | ||
updated_headers = Keyword.merge(headers, request_option_headers) | ||
updated_opts = Keyword.merge([ssl: request_options.ssl_options], opts) | ||
updated_request = %Request{req | headers: updated_headers, opts: updated_opts} | ||
{:ok, updated_request} | ||
end | ||
end | ||
end |
Oops, something went wrong.