Current section
Files
Jump to
Current section
Files
lib/kubex.ex
defmodule Kubex do
alias Kubex.Deployment
alias Kubex.Ingress
alias Kubex.Namespace
alias Kubex.Service
defmacro __using__(_options \\ []) do
quote do
alias Kubex.Deployment
alias Kubex.Deployment.Container
alias Kubex.Ingress
alias Kubex.Ingress.Path
alias Kubex.Namespace
alias Kubex.Service
alias Kubex.Service.Port
import Kubex
import Deployment, except: [__resource__: 0]
import Ingress, except: [__resource__: 0]
import Namespace, except: [__resource__: 0]
import Service, except: [__resource__: 0]
end
end
def api(module, version) when is_atom(module) do
module.__default__
|> api(version)
end
def api(object, version) do
Map.put(object, :apiVersion, version)
end
def namespace(module, namespace) when is_atom(module) do
module.__default__
|> namespace(namespace)
end
def namespace(object, namespace) do
object
|> Map.put_new(:metadata, %{})
|> put_in([:metadata, :namespace], namespace)
end
def name(module, name, namespace) when is_atom(module) do
module.__default__
|> name(name, namespace)
end
def name(object, name, namespace) do
object
|> Map.put_new(:metadata, %{})
|> put_in([:metadata, :name], name)
|> put_in([:metadata, :namespace], namespace || "default")
end
def name(module, name) when is_atom(module) do
module.__default__
|> name(name)
end
def name(object, name) do
object
|> Map.put_new(:metadata, %{})
|> put_in([:metadata, :name], name)
end
### Apply and Delete
def create(object = %{kind: kind}, options \\ []) do
pretty =
case options[:dry] do
true -> [pretty: true]
_ -> []
end
data =
object
|> Map.put(:kind, kind |> to_string |> String.split(".") |> List.last)
|> Poison.encode!(pretty)
url = generate_url(object, :post)
if options[:dry] do
IO.puts "Post: #{url}\r\n---"
IO.puts data
IO.puts "---"
else
HTTPX.post(url, data, request_options())
end
end
def delete(object) do
url = generate_url(object, :delete)
HTTPX.request(:delete, url, request_options())
end
### Find
def get(object) do
url = generate_url(object, :get)
HTTPX.request(:get, url, request_options())
end
def list(object) do
url = generate_url(object, :index)
with {:ok, data} <- HTTPX.request(:get, url, request_options()),
%{body: json} <- data,
%{items: items} <- json
do
{:ok, items}
else
error = {:error, _reason} -> error
_ -> {:error, :can_not_list_resource}
end
end
### Helpers
defp generate_url(object = %{apiVersion: version, kind: kind}, type) do
base = Application.fetch_env!(:kubernetex, :url)
api =
case version do
:v1 -> "api/v1"
_ -> "apis/#{version}"
end
url =
if kind in [Namespace] do
"#{base}#{api}/namespaces"
else
resource = kind.__resource__
namespace = object |> Map.get(:metadata) |> Map.get(:namespace, "default")
"#{base}#{api}/namespaces/#{namespace}/#{resource}"
end
case type do
:delete -> url <> "/" <> object.metadata.name
:get -> url <> "/" <> object.metadata.name
:index -> url
:post -> url
:put -> url <> "/" <> object.metadata.name
end
end
defp generate_url(kind, type) do
kind.__default__
|> Map.put(:metadata, %{name: nil})
|> generate_url(type)
end
defp request_options do
[
headers: [
bearer(),
{"Content-Type", "application/json"},
],
format: :json_atoms,
settings: [
ssl_options: [
{:verify, :verify_none},
{:server_name_indication, :disable},
],
],
]
end
defp bearer do
token =
:kubernetex
|> Application.fetch_env!(:secret)
|> File.read!
|> Poison.decode!
|> Map.get("data")
|> Map.get("token")
|> Base.decode64!
{"authorization", "Bearer " <> token}
end
end