defmodule Skylab.Deploy do alias Skylab.{Image, Template, Config} @moduledoc """ 创建并配置 k8s 配置文件。 """ @yaml "deployments.yml" @kuberc "kuberc" def run(opts) do opts = Keyword.merge(Config.all(), opts) with {:kube, :ok} <- {:kube, prepair_kube_config(opts)}, {:yaml, :ok} <- {:yaml, prepair_yaml(opts)}, {:rpc, :ok} <- {:rpc, invoke_k8s(opts)}, {:clean, :ok} <- {:clean, cleanup(opts)} do :ok end end defp prepair_kube_config(opts) do case auth_kube?(opts) do false -> :ok _ -> content = fetch_kube_config(opts) :ok = File.write!(@kuberc, content) end end def auth_kube?(opts) do !!opts[:kube_config_secret_url] end def fetch_kube_config(opts) do headers = [ {"X-Vault-Token", opts[:vault_token]} ] Application.ensure_all_started(:jason) Application.ensure_all_started(:httpoison) {:ok, %{body: body, status_code: 200}} = opts |> Keyword.get(:kube_config_secret_url) |> HTTPoison.get(headers) body |> Jason.decode!() |> get_in(["data", "content"]) end defp prepair_yaml(opts) do eval_string = yaml_content(opts) File.write!(@yaml, eval_string) end def yaml_content(opts) do opts |> deploy_config() |> handle_yaml_file(opts) |> print(opts) end defp deploy_config(opts) do secret_names = Skylab.Config.all() |> Keyword.get(:secrets) opts |> Keyword.get(:deploy) |> Keyword.merge( image_name: Image.image_name(opts), full_image_name: Image.full_image_name_to_pull(opts), version: Image.app_version(opts), revision: Image.revision(opts), secrets: secret_names ) end defp invoke_k8s(opts) do case opts[:dry_run] do true -> :ok _ -> do_invoke_k8s(opts) end end defp do_invoke_k8s(opts) do args = opts |> kubectl_args() |> print(opts) {_, 0} = System.cmd( "kubectl", args, into: IO.stream(:stdio, :line) ) end def kubectl_args(opts) do cfg = deploy_config(opts) [ "-s", cfg[:k8s_server], "apply", "--namespace", cfg[:k8s_namespace], "--filename", @yaml, "--record" ] |> with_kube_config(opts) |> with_tls_cert_opt(opts) end defp with_kube_config(args, opts) do case auth_kube?(opts) do true -> ["--kubeconfig", @kuberc | args] _ -> args end end defp with_tls_cert_opt(args, opts) do case opts[:kube_skip_tls_verify] do true -> ["--insecure-skip-tls-verify" | args] _ -> args end end defp handle_yaml_file(config, opts) do "deployments.yml" |> Template.input_path(opts) |> EEx.eval_file(config) end defp print(content, opts) do case opts[:verbose] do true -> IO.puts(content) _ -> nil end content end defp cleanup(_) do File.rm(@kuberc) end end