mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-12-18 22:21:32 +08:00
Load LB_ env vars as app secrets (#1615)
This commit is contained in:
parent
9e328e83ca
commit
d4bda6042c
5 changed files with 74 additions and 22 deletions
|
|
@ -46,6 +46,7 @@ defmodule Livebook.Application do
|
||||||
|
|
||||||
case Supervisor.start_link(children, opts) do
|
case Supervisor.start_link(children, opts) do
|
||||||
{:ok, _} = result ->
|
{:ok, _} = result ->
|
||||||
|
load_lb_env_vars()
|
||||||
clear_env_vars()
|
clear_env_vars()
|
||||||
display_startup_info()
|
display_startup_info()
|
||||||
insert_development_hub()
|
insert_development_hub()
|
||||||
|
|
@ -169,6 +170,16 @@ defmodule Livebook.Application do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp load_lb_env_vars do
|
||||||
|
secrets =
|
||||||
|
for {"LB_" <> name = var, value} <- System.get_env() do
|
||||||
|
System.delete_env(var)
|
||||||
|
%Livebook.Secrets.Secret{name: name, value: value}
|
||||||
|
end
|
||||||
|
|
||||||
|
Livebook.Secrets.set_temporary_secrets(secrets)
|
||||||
|
end
|
||||||
|
|
||||||
defp config_env_var?("LIVEBOOK_" <> _), do: true
|
defp config_env_var?("LIVEBOOK_" <> _), do: true
|
||||||
defp config_env_var?("RELEASE_" <> _), do: true
|
defp config_env_var?("RELEASE_" <> _), do: true
|
||||||
defp config_env_var?(_), do: false
|
defp config_env_var?(_), do: false
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,19 @@ defmodule Livebook.Secrets do
|
||||||
alias Livebook.Storage
|
alias Livebook.Storage
|
||||||
alias Livebook.Secrets.Secret
|
alias Livebook.Secrets.Secret
|
||||||
|
|
||||||
|
@temporary_key :livebook_temporary_secrets
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Get the secrets list from storage.
|
Get the secrets list from storage.
|
||||||
"""
|
"""
|
||||||
@spec fetch_secrets() :: list(Secret.t())
|
@spec fetch_secrets() :: list(Secret.t())
|
||||||
def fetch_secrets() do
|
def fetch_secrets do
|
||||||
|
temporary_secrets = :persistent_term.get(@temporary_key, [])
|
||||||
|
|
||||||
for fields <- Storage.all(:secrets) do
|
for fields <- Storage.all(:secrets) do
|
||||||
struct!(Secret, Map.delete(fields, :id))
|
struct!(Secret, Map.delete(fields, :id))
|
||||||
end
|
end
|
||||||
|
|> Enum.concat(temporary_secrets)
|
||||||
|> Enum.sort()
|
|> Enum.sort()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -69,6 +74,14 @@ defmodule Livebook.Secrets do
|
||||||
:ok
|
:ok
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Sets additional secrets that are kept only in memory.
|
||||||
|
"""
|
||||||
|
@spec set_temporary_secrets(list(Secret.t())) :: :ok
|
||||||
|
def set_temporary_secrets(secrets) do
|
||||||
|
:persistent_term.put(@temporary_key, secrets)
|
||||||
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Subscribe to secrets updates.
|
Subscribe to secrets updates.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -703,22 +703,24 @@ defmodule LivebookWeb.SessionLive do
|
||||||
<span class="text-sm font-mono break-all flex-row">
|
<span class="text-sm font-mono break-all flex-row">
|
||||||
<%= secret_value %>
|
<%= secret_value %>
|
||||||
</span>
|
</span>
|
||||||
<button
|
<%= if Secrets.secret_exists?(secret_name) do %>
|
||||||
id={"app-secret-#{secret_name}-delete"}
|
<button
|
||||||
type="button"
|
id={"app-secret-#{secret_name}-delete"}
|
||||||
phx-click={
|
type="button"
|
||||||
with_confirm(
|
phx-click={
|
||||||
JS.push("delete_app_secret", value: %{secret_name: secret_name}),
|
with_confirm(
|
||||||
title: "Delete app secret - #{secret_name}",
|
JS.push("delete_app_secret", value: %{secret_name: secret_name}),
|
||||||
description: "Are you sure you want to delete this app secret?",
|
title: "Delete app secret - #{secret_name}",
|
||||||
confirm_text: "Delete",
|
description: "Are you sure you want to delete this app secret?",
|
||||||
confirm_icon: "delete-bin-6-line"
|
confirm_text: "Delete",
|
||||||
)
|
confirm_icon: "delete-bin-6-line"
|
||||||
}
|
)
|
||||||
class="hover:text-red-600"
|
}
|
||||||
>
|
class="hover:text-red-600"
|
||||||
<.remix_icon icon="delete-bin-line" />
|
>
|
||||||
</button>
|
<.remix_icon icon="delete-bin-line" />
|
||||||
|
</button>
|
||||||
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,28 @@ defmodule Livebook.SecretsTest do
|
||||||
alias Livebook.Secrets
|
alias Livebook.Secrets
|
||||||
alias Livebook.Secrets.Secret
|
alias Livebook.Secrets.Secret
|
||||||
|
|
||||||
test "fetch secrets" do
|
describe "fetch_secrets/0" do
|
||||||
Secrets.set_secret(%Secret{name: "FOO", value: "111"})
|
test "returns a list of secrets from storage" do
|
||||||
assert %Secret{name: "FOO", value: "111"} in Secrets.fetch_secrets()
|
secret = %Secret{name: "FOO", value: "111"}
|
||||||
|
|
||||||
Secrets.unset_secret("FOO")
|
Secrets.set_secret(secret)
|
||||||
refute %Secret{name: "FOO", value: "111"} in Secrets.fetch_secrets()
|
assert secret in Secrets.fetch_secrets()
|
||||||
|
|
||||||
|
Secrets.unset_secret(secret.name)
|
||||||
|
refute secret in Secrets.fetch_secrets()
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns a list of secrets from temporary storage" do
|
||||||
|
secret = %Secret{name: "BAR", value: "222"}
|
||||||
|
|
||||||
|
Secrets.set_temporary_secrets([secret])
|
||||||
|
assert secret in Secrets.fetch_secrets()
|
||||||
|
|
||||||
|
# We can't delete from temporary storage, since it will be deleted
|
||||||
|
# on next startup, if not provided
|
||||||
|
Secrets.unset_secret(secret.name)
|
||||||
|
assert secret in Secrets.fetch_secrets()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
test "fetch an specific secret" do
|
test "fetch an specific secret" do
|
||||||
|
|
|
||||||
|
|
@ -1036,6 +1036,16 @@ defmodule LivebookWeb.SessionLiveTest do
|
||||||
|> element("span", "Add secret")
|
|> element("span", "Add secret")
|
||||||
|> has_element?()
|
|> has_element?()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "loads secret from temporary storage", %{conn: conn, session: session} do
|
||||||
|
secret = %Secret{name: "FOOBARBAZ", value: "ChonkyCat"}
|
||||||
|
Livebook.Secrets.set_temporary_secrets([secret])
|
||||||
|
|
||||||
|
{:ok, view, _} = live(conn, "/sessions/#{session.id}")
|
||||||
|
|
||||||
|
assert render(view) =~ secret.name
|
||||||
|
assert render(view) =~ secret.value
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "environment variables" do
|
describe "environment variables" do
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue