Skip to content

Commit

Permalink
s/conf/conn/ refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
coryodaniel committed Aug 21, 2019
1 parent 036b2c4 commit c18927d
Show file tree
Hide file tree
Showing 12 changed files with 81 additions and 80 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed
- Renamed `K8s.Conf` to `K8s.Conn`
- Refactored `:conf` configuration key to `:conn`

## [0.3.2] - 2019-08-15

Expand Down
4 changes: 2 additions & 2 deletions config/dev.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ config :k8s,
auth_providers: [],
clusters: %{
dev: %{
conf: "~/.kube/config",
conf_opts: [context: "docker-for-desktop"]
conn: "~/.kube/config",
conn_opts: [context: "docker-for-desktop"]
}
}
2 changes: 1 addition & 1 deletion config/test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ config :k8s,
http_provider: K8s.Client.DynamicHTTPProvider,
clusters: %{
test: %{
conf: "test/support/kube-config.yaml"
conn: "test/support/kube-config.yaml"
}
}
28 changes: 14 additions & 14 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ Kubernetes API resources are auto-discovered at boot time. This library is curre
The below will register a cluster named `:prod` using `~/.kube.config` to connect. There are many options for loading a config, this will load the user and cluster from the `current-context`.

```elixir
conf = K8s.Conn.from_file("~/.kube/config")
K8s.Cluster.Registry.add(:prod, conf)
conn = K8s.Conn.from_file("~/.kube/config")
K8s.Cluster.Registry.add(:prod, conn)
```

Registering a cluster using the k8s' ServiceAccount of the pod:

```elixir
conf = K8s.Conn.from_service_account()
K8s.Cluster.Registry.add(:prod, conf)
conn = K8s.Conn.from_service_account()
K8s.Cluster.Registry.add(:prod, conn)
```

### Registering Clusters at Compile Time (config.exs)
Expand All @@ -32,7 +32,7 @@ Adding a cluster named `:default` using `~/.kube/config`. Defaults to `current-c
config :k8s,
clusters: %{
default: %{
conf: "~/.kube/config"
conn: "~/.kube/config"
}
}
```
Expand All @@ -43,8 +43,8 @@ Using an alternate context:
config :k8s,
clusters: %{
default: %{
conf: "~/.kube/config"
conf_opts: [context: "other-context"]
conn: "~/.kube/config"
conn_opts: [context: "other-context"]
}
}
```
Expand All @@ -55,8 +55,8 @@ Setting cluster and user explicitly:
config :k8s,
clusters: %{
default: %{
conf: "~/.kube/config"
conf_opts: [user: "some-user", cluster: "prod-cluster"]
conn: "~/.kube/config"
conn_opts: [user: "some-user", cluster: "prod-cluster"]
}
}
```
Expand Down Expand Up @@ -277,15 +277,15 @@ Copying a workloads between two clusters:
Register a staging cluster:

```elixir
staging_conf = K8s.Conn.from_file("~/.kube/config")
{:ok, staging} = K8s.Cluster.Registry.add(:staging, staging_conf)
staging_conn = K8s.Conn.from_file("~/.kube/config")
{:ok, staging} = K8s.Cluster.Registry.add(:staging, staging_conn)
```

Register a prod cluster:

```elixir
prod_conf = K8s.Conn.from_service_account() # or from_file/2
{:ok, prod} = K8s.Cluster.Registry.add(:prod, staging_conf)
prod_conn = K8s.Conn.from_service_account() # or from_file/2
{:ok, prod} = K8s.Cluster.Registry.add(:prod, staging_conn)
```

Get a list of all deployments in the `default` prod namespace:
Expand Down Expand Up @@ -313,7 +313,7 @@ Providers are checked in order, the first to return an authorization struct wins

Custom providers are processed before default providers.

For protocol and behavior implementation examples check out `Certificate`, `Token`, or `AuthProvider` [here](../lib/k8s/conf/auth/).
For protocol and behavior implementation examples check out `Certificate`, `Token`, or `AuthProvider` [here](../lib/k8s/conn/auth/).

## Performing sub-resource operations

Expand Down
4 changes: 2 additions & 2 deletions lib/k8s/client/runner/base.ex
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ defmodule K8s.Client.Runner.Base do
@spec run(Operation.t(), atom, map(), keyword()) :: result_t
def run(%Operation{} = operation, cluster_name, body, opts \\ []) do
with {:ok, url} <- Cluster.url_for(operation, cluster_name),
{:ok, conf} <- Cluster.conf(cluster_name),
{:ok, request_options} <- RequestOptions.generate(conf),
{:ok, conn} <- Cluster.conn(cluster_name),
{:ok, request_options} <- RequestOptions.generate(conn),
{:ok, http_body} <- encode(body, operation.method) do
http_headers = K8s.http_provider().headers(operation.method, request_options)

Expand Down
26 changes: 13 additions & 13 deletions lib/k8s/cluster.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,20 @@ defmodule K8s.Cluster do
## Examples
iex> conf = K8s.Conn.from_file("./test/support/kube-config.yaml")
...> K8s.Cluster.Registry.add(:test_cluster, conf)
iex> conn = K8s.Conn.from_file("./test/support/kube-config.yaml")
...> K8s.Cluster.Registry.add(:test_cluster, conn)
...> operation = K8s.Operation.build(:get, "apps/v1", :deployments, [namespace: "default", name: "nginx"])
...> K8s.Cluster.url_for(operation, :test_cluster)
{:ok, "https://localhost:6443/apis/apps/v1/namespaces/default/deployments/nginx"}
"""
@spec url_for(Operation.t(), atom) :: {:ok, binary} | {:error, atom(), binary()}
def url_for(%Operation{api_version: api_version, name: name, verb: verb} = operation, cluster) do
with {:ok, conf} <- Cluster.conf(cluster),
with {:ok, conn} <- Cluster.conn(cluster),
{:ok, name} <- Cluster.Group.resource_name_for_kind(cluster, api_version, name),
operation <- Map.put(operation, :name, name),
{:ok, path} <- Operation.to_path(operation) do
{:ok, Path.join(conf.url, path)}
{:ok, Path.join(conn.url, path)}
end
end

Expand All @@ -32,15 +32,15 @@ defmodule K8s.Cluster do
## Examples
iex> conf = K8s.Conn.from_file("./test/support/kube-config.yaml")
...> K8s.Cluster.Registry.add(:test_cluster, conf)
iex> conn = K8s.Conn.from_file("./test/support/kube-config.yaml")
...> K8s.Cluster.Registry.add(:test_cluster, conn)
...> K8s.Cluster.base_url(:test_cluster)
{:ok, "https://localhost:6443"}
"""
@spec base_url(atom) :: {:ok, binary()} | {:error, atom} | {:error, binary}
def base_url(cluster) do
with {:ok, conf} <- Cluster.conf(cluster) do
{:ok, conf.url}
with {:ok, conn} <- Cluster.conn(cluster) do
{:ok, conn.url}
end
end

Expand All @@ -51,15 +51,15 @@ defmodule K8s.Cluster do
iex> config_file = K8s.Conn.from_file("./test/support/kube-config.yaml", [user: "token-user"])
...> K8s.Cluster.Registry.add(:test_cluster, config_file)
...> {:ok, conf} = K8s.Cluster.conf(:test_cluster)
...> conf
...> {:ok, conn} = K8s.Cluster.conn(:test_cluster)
...> conn
%K8s.Conn{auth: %K8s.Conn.Auth.Token{token: "just-a-token-user-pun-intended"}, ca_cert: nil, cluster_name: "docker-for-desktop-cluster", insecure_skip_tls_verify: true, url: "https://localhost:6443",user_name: "token-user"}
"""
@spec conf(atom) :: {:ok, K8s.Conn.t()} | {:error, :cluster_not_registered}
def conf(cluster_name) do
@spec conn(atom) :: {:ok, K8s.Conn.t()} | {:error, :cluster_not_registered}
def conn(cluster_name) do
case :ets.lookup(K8s.Conn, cluster_name) do
[] -> {:error, :cluster_not_registered}
[{_, conf}] -> {:ok, conf}
[{_, conn}] -> {:ok, conn}
end
end

Expand Down
30 changes: 15 additions & 15 deletions lib/k8s/cluster/discovery/http_driver.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ defmodule K8s.Cluster.Discovery.HTTPDriver do
timeout = Config.discovery_http_timeout(cluster)
opts = Keyword.merge([timeout: timeout, recv_timeout: timeout], opts)

with {:ok, conf} <- Cluster.conf(cluster),
with {:ok, conn} <- Cluster.conn(cluster),
{:ok, api_versions} <- api_versions(cluster, opts) do
{:ok, get_resource_definitions(api_versions, conf, opts)}
{:ok, get_resource_definitions(api_versions, conn, opts)}
end
end

Expand All @@ -33,9 +33,9 @@ defmodule K8s.Cluster.Discovery.HTTPDriver do
# list Core/Legacy APIs
@spec api(atom, Keyword.t()) :: {:ok, list(binary())} | {:error, atom()}
defp api(cluster, opts) do
with {:ok, conf} <- Cluster.conf(cluster),
url <- Path.join(conf.url, @core_api_base_path),
{:ok, response} <- get(url, conf, opts),
with {:ok, conn} <- Cluster.conn(cluster),
url <- Path.join(conn.url, @core_api_base_path),
{:ok, response} <- get(url, conn, opts),
versions <- Map.get(response, "versions") do
{:ok, versions}
end
Expand All @@ -44,9 +44,9 @@ defmodule K8s.Cluster.Discovery.HTTPDriver do
# list Named Group / Custom Resource APIs
@spec apis(atom, Keyword.t()) :: {:ok, list(binary())} | {:error, atom()}
defp apis(cluster, opts) do
with {:ok, conf} <- Cluster.conf(cluster),
url <- Path.join(conf.url, @group_api_base_path),
{:ok, response} <- get(url, conf, opts),
with {:ok, conn} <- Cluster.conn(cluster),
url <- Path.join(conn.url, @group_api_base_path),
{:ok, response} <- get(url, conn, opts),
groups <- Map.get(response, "groups") do
api_versions = get_api_versions_from_groups(groups)

Expand All @@ -64,8 +64,8 @@ defmodule K8s.Cluster.Discovery.HTTPDriver do

@spec get(binary(), Conn.t(), Keyword.t()) ::
{:ok, HTTPoison.Response.t()} | {:error, atom}
defp get(url, conf, opts) do
case RequestOptions.generate(conf) do
defp get(url, conn, opts) do
case RequestOptions.generate(conn) do
{:ok, request_options} ->
headers = K8s.http_provider().headers(:get, request_options)
opts = Keyword.merge([ssl: request_options.ssl_options], opts)
Expand All @@ -78,30 +78,30 @@ defmodule K8s.Cluster.Discovery.HTTPDriver do
end

@spec get_resource_definitions(list(binary()), K8s.Conn.t(), Keyword.t()) :: list(map())
defp get_resource_definitions(api_versions, conf, opts) do
defp get_resource_definitions(api_versions, conn, opts) do
timeout = Keyword.get(opts, :timeout) || 5000

api_versions
|> Enum.reduce([], fn api_version, acc ->
task = get_api_version_resources(api_version, conf, opts)
task = get_api_version_resources(api_version, conn, opts)
[task | acc]
end)
|> Enum.map(fn task -> Task.await(task, timeout) end)
|> List.flatten()
end

@spec get_api_version_resources(binary(), K8s.Conn.t(), Keyword.t()) :: Task.t()
defp get_api_version_resources(api_version, conf, opts) do
defp get_api_version_resources(api_version, conn, opts) do
Task.async(fn ->
base_path =
case String.contains?(api_version, "/") do
true -> @group_api_base_path
false -> @core_api_base_path
end

url = Path.join([conf.url, base_path, api_version])
url = Path.join([conn.url, base_path, api_version])

case get(url, conf, opts) do
case get(url, conn, opts) do
{:ok, resource_definition} ->
resource_definition

Expand Down
24 changes: 12 additions & 12 deletions lib/k8s/cluster/registry.ex
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ defmodule K8s.Cluster.Registry do
## Examples
iex> conf = K8s.Conn.from_file("./test/support/kube-config.yaml")
...> K8s.Cluster.Registry.add(:test_cluster, conf)
iex> conn = K8s.Conn.from_file("./test/support/kube-config.yaml")
...> K8s.Cluster.Registry.add(:test_cluster, conn)
{:ok, :test_cluster}
"""
@spec add(atom(), K8s.Conn.t()) :: {:ok, atom()} | {:error, atom()}
def add(cluster, conf) do
with true <- :ets.insert(K8s.Conn, {cluster, conf}),
def add(cluster, conn) do
with true <- :ets.insert(K8s.Conn, {cluster, conn}),
{:ok, resources_by_group} <- Discovery.resources_by_group(cluster) do
K8s.Cluster.Group.insert_all(cluster, resources_by_group)
K8s.Sys.Event.cluster_registered(%{}, %{cluster: cluster})
Expand Down Expand Up @@ -62,8 +62,8 @@ defmodule K8s.Cluster.Registry do
config :k8s,
clusters: %{
default: %{
conf: "~/.kube/config"
conf_opts: [user: "some-user", cluster: "prod-cluster"]
conn: "~/.kube/config"
conn_opts: [user: "some-user", cluster: "prod-cluster"]
}
}
```
Expand All @@ -73,20 +73,20 @@ defmodule K8s.Cluster.Registry do
clusters = K8s.Config.clusters()

Enum.each(clusters, fn {name, details} ->
conf =
case Map.get(details, :conf) do
conn =
case Map.get(details, :conn) do
nil ->
K8s.Conn.from_service_account()

%{use_sa: true} ->
K8s.Conn.from_service_account()

conf_path ->
opts = details[:conf_opts] || []
K8s.Conn.from_file(conf_path, opts)
conn_path ->
opts = details[:conn_opts] || []
K8s.Conn.from_file(conn_path, opts)
end

add(name, conf)
add(name, conn)
end)

nil
Expand Down
26 changes: 13 additions & 13 deletions lib/k8s/config.ex
Original file line number Diff line number Diff line change
Expand Up @@ -67,24 +67,24 @@ defmodule K8s.Config do
## Examples
Overriding compile time configs
iex> env = %{"K8S_CLUSTER_CONF_PATH_dev" => "runtime/path/to/dev.conf"}
...> compile_config = %{dev: %{conf: "compiletime/path/to/dev.conf"}}
iex> env = %{"K8S_CLUSTER_CONF_PATH_dev" => "runtime/path/to/dev.kubeconfig.yaml"}
...> compile_config = %{dev: %{conn: "compiletime/path/to/dev.kubeconfig.yaml"}}
...> K8s.Config.runtime_clusters_config(env, compile_config)
%{dev: %{conf: "runtime/path/to/dev.conf"}}
%{dev: %{conn: "runtime/path/to/dev.kubeconfig.yaml"}}
Merging compile time configs
iex> env = %{"K8S_CLUSTER_CONF_CONTEXT_dev" => "runtime-context"}
...> compile_config = %{dev: %{conf: "compiletime/path/to/dev.conf"}}
...> compile_config = %{dev: %{conn: "compiletime/path/to/dev.kubeconfig.yaml"}}
...> K8s.Config.runtime_clusters_config(env, compile_config)
%{dev: %{conf: "compiletime/path/to/dev.conf", conf_opts: [context: "runtime-context"]}}
%{dev: %{conn: "compiletime/path/to/dev.kubeconfig.yaml", conn_opts: [context: "runtime-context"]}}
Adding clusters at runtime
iex> env = %{"K8S_CLUSTER_CONF_PATH_us_east" => "runtime/path/to/us_east.conf", "K8S_CLUSTER_CONF_CONTEXT_us_east" => "east-context"}
...> compile_config = %{us_west: %{conf: "compiletime/path/to/us_west.conf"}}
iex> env = %{"K8S_CLUSTER_CONF_PATH_us_east" => "runtime/path/to/us_east.kubeconfig.yaml", "K8S_CLUSTER_CONF_CONTEXT_us_east" => "east-context"}
...> compile_config = %{us_west: %{conn: "compiletime/path/to/us_west.kubeconfig.yaml"}}
...> K8s.Config.runtime_clusters_config(env, compile_config)
%{us_east: %{conf: "runtime/path/to/us_east.conf", conf_opts: [context: "east-context"]}, us_west: %{conf: "compiletime/path/to/us_west.conf"}}
%{us_east: %{conn: "runtime/path/to/us_east.kubeconfig.yaml", conn_opts: [context: "east-context"]}, us_west: %{conn: "compiletime/path/to/us_west.kubeconfig.yaml"}}
"""
@spec runtime_clusters_config(map, map) :: map
def runtime_clusters_config(env_vars, config) do
Expand All @@ -93,18 +93,18 @@ defmodule K8s.Config do
acc_cluster_config = Map.get(acc, cluster_name, %{})

{new_key, new_value} = get_config_kv(k, v)
updated_cluster_conf = Map.put(acc_cluster_config, new_key, new_value)
updated_cluster_conn = Map.put(acc_cluster_config, new_key, new_value)

Map.put(acc, cluster_name, updated_cluster_conf)
Map.put(acc, cluster_name, updated_cluster_conn)
end)
end

# given an env var name/value, map the config to the correct cluster
defp get_config_kv(@env_var_context_prefix <> _cluster_name, conf_opts_context),
do: {:conf_opts, [context: conf_opts_context]}
defp get_config_kv(@env_var_context_prefix <> _cluster_name, conn_opts_context),
do: {:conn_opts, [context: conn_opts_context]}

# given an env var name/value, map the config to the correct cluster
defp get_config_kv(@env_var_path_prefix <> _cluster_name, conf_path), do: {:conf, conf_path}
defp get_config_kv(@env_var_path_prefix <> _cluster_name, conn_path), do: {:conn, conn_path}
defp get_config_kv(@env_var_sa_prefix <> _cluster_name, "true"), do: {:use_sa, true}
defp get_config_kv(@env_var_sa_prefix <> _cluster_name, "false"), do: {:use_sa, false}

Expand Down

0 comments on commit c18927d

Please sign in to comment.