Skip to content

Commit

Permalink
Implement teams_auth field and deprecate zta_provider (#2904)
Browse files Browse the repository at this point in the history
  • Loading branch information
aleDsz authored Dec 31, 2024
1 parent b21ef3e commit 433b801
Show file tree
Hide file tree
Showing 12 changed files with 66 additions and 85 deletions.
14 changes: 7 additions & 7 deletions lib/livebook/hubs/team_client.ex
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ defmodule Livebook.Hubs.TeamClient do

def handle_call(:identity_enabled?, _caller, %{deployment_group_id: id} = state) do
case fetch_deployment_group(id, state) do
{:ok, %{zta_provider: :livebook_teams}} -> {:reply, true, state}
{:ok, deployment_group} -> {:reply, deployment_group.teams_auth, state}
_ -> {:reply, false, state}
end
end
Expand Down Expand Up @@ -450,8 +450,8 @@ defmodule Livebook.Hubs.TeamClient do
agent_keys: agent_keys,
environment_variables: environment_variables,
clustering: nullify(deployment_group.clustering),
zta_provider: atomize(deployment_group.zta_provider),
url: nullify(deployment_group.url)
url: nullify(deployment_group.url),
teams_auth: deployment_group.teams_auth
}
end

Expand All @@ -467,8 +467,8 @@ defmodule Livebook.Hubs.TeamClient do
agent_keys: agent_keys,
environment_variables: [],
clustering: nullify(deployment_group_created.clustering),
zta_provider: atomize(deployment_group_created.zta_provider),
url: nullify(deployment_group_created.url)
url: nullify(deployment_group_created.url),
teams_auth: deployment_group_created.teams_auth
}
end

Expand All @@ -486,8 +486,8 @@ defmodule Livebook.Hubs.TeamClient do
agent_keys: agent_keys,
environment_variables: environment_variables,
clustering: atomize(deployment_group_updated.clustering),
zta_provider: atomize(deployment_group_updated.zta_provider),
url: nullify(deployment_group_updated.url)
url: nullify(deployment_group_updated.url),
teams_auth: deployment_group_updated.teams_auth
}
end

Expand Down
68 changes: 26 additions & 42 deletions lib/livebook/teams/deployment_group.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,69 +12,53 @@ defmodule Livebook.Teams.DeploymentGroup do
mode: :online | :offline,
clustering: :auto | :dns | nil,
hub_id: String.t() | nil,
teams_auth: boolean(),
secrets: Ecto.Schema.has_many(Secret.t()),
agent_keys: Ecto.Schema.has_many(AgentKey.t()),
environment_variables: Ecto.Schema.has_many(EnvironmentVariable.t()),
zta_provider:
:basic_auth
| :cloudflare
| :google_iap
| :livebook_teams
| :tailscale
| nil
environment_variables: Ecto.Schema.has_many(EnvironmentVariable.t())
}

# TODO: Update this list to be only `:livebook_teams` in the future.
@zta_providers [:basic_auth, :cloudflare, :google_iap, :livebook_teams, :tailscale]

@primary_key {:id, :string, autogenerate: false}
embedded_schema do
field :name, :string
field :mode, Ecto.Enum, values: [:online, :offline], default: :online
field :hub_id, :string
field :clustering, Ecto.Enum, values: [:auto, :dns]
field :zta_provider, Ecto.Enum, values: @zta_providers, default: :livebook_teams
field :url, :string
field :teams_auth, :boolean, default: true

has_many :secrets, Secret
has_many :agent_keys, AgentKey
has_many :environment_variables, EnvironmentVariable
end

def changeset(deployment_group, attrs \\ %{}) do
changeset =
deployment_group
|> cast(attrs, [:id, :name, :mode, :hub_id, :clustering, :zta_provider, :url])
|> validate_required([:name, :mode])
|> update_change(:url, fn url ->
if url do
String.trim_trailing(url, "/")
end
end)
|> validate_change(:url, fn :url, url ->
case URI.new(url) do
{:ok, uri} ->
cond do
uri.scheme not in ["http", "https"] ->
[url: ~s(must start with "http://" or "https://")]

uri.host in ["", nil] ->
[url: "must be a well-formed URL"]
deployment_group
|> cast(attrs, [:id, :name, :mode, :hub_id, :clustering, :url, :teams_auth])
|> validate_required([:name, :mode])
|> update_change(:url, fn url ->
if url do
String.trim_trailing(url, "/")
end
end)
|> validate_change(:url, fn :url, url ->
case URI.new(url) do
{:ok, uri} ->
cond do
uri.scheme not in ["http", "https"] ->
[url: ~s(must start with "http://" or "https://")]

true ->
[]
end
uri.host in ["", nil] ->
[url: "must be a well-formed URL"]

{:error, _} ->
[url: "must be a well-formed URL"]
end
end)
true ->
[]
end

if get_field(changeset, :mode) == :offline do
delete_change(changeset, :zta_provider)
else
changeset
end
{:error, _} ->
[url: "must be a well-formed URL"]
end
end)
end

def url_without_scheme(%__MODULE__{url: url} = _deployment_group) do
Expand Down
4 changes: 2 additions & 2 deletions lib/livebook/teams/requests.ex
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,8 @@ defmodule Livebook.Teams.Requests do
name: deployment_group.name,
mode: deployment_group.mode,
clustering: deployment_group.clustering,
zta_provider: deployment_group.zta_provider,
url: deployment_group.url
url: deployment_group.url,
teams_auth: deployment_group.teams_auth
}

post("/api/v1/org/deployment-groups", params, team)
Expand Down
4 changes: 1 addition & 3 deletions lib/livebook_web/components/app_components.ex
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ defmodule LivebookWeb.AppComponents do
<%= if Livebook.Hubs.Provider.type(@hub) == "team" and to_string(@form[:mode].value) == "online" do %>
<div class="flex flex-col gap-2">
<.checkbox_field
field={@form[:zta_provider]}
field={@form[:teams_auth]}
label="Authenticate via Livebook Teams"
help={
~S'''
Expand All @@ -143,8 +143,6 @@ defmodule LivebookWeb.AppComponents do
Livebook Teams for authentication.
'''
}
checked_value="livebook_teams"
unchecked_value=""
small
/>
</div>
Expand Down
4 changes: 3 additions & 1 deletion proto/lib/livebook_proto/deployment_group.pb.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ defmodule LivebookProto.DeploymentGroup do
field :mode, 3, type: :string
field :secrets, 4, repeated: true, type: LivebookProto.DeploymentGroupSecret
field :clustering, 5, type: :string
field :zta_provider, 6, type: :string, json_name: "ztaProvider"
field :zta_provider, 6, type: :string, json_name: "ztaProvider", deprecated: true
field :zta_key, 7, type: :string, json_name: "ztaKey", deprecated: true
field :agent_keys, 8, repeated: true, type: LivebookProto.AgentKey, json_name: "agentKeys"
field :url, 9, type: :string
Expand All @@ -15,4 +15,6 @@ defmodule LivebookProto.DeploymentGroup do
repeated: true,
type: LivebookProto.EnvironmentVariable,
json_name: "environmentVariables"

field :teams_auth, 11, type: :bool, json_name: "teamsAuth"
end
3 changes: 2 additions & 1 deletion proto/lib/livebook_proto/deployment_group_created.pb.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ defmodule LivebookProto.DeploymentGroupCreated do
field :name, 2, type: :string
field :mode, 3, type: :string
field :clustering, 5, type: :string
field :zta_provider, 6, type: :string, json_name: "ztaProvider"
field :zta_provider, 6, type: :string, json_name: "ztaProvider", deprecated: true
field :zta_key, 7, type: :string, json_name: "ztaKey", deprecated: true
field :agent_keys, 8, repeated: true, type: LivebookProto.AgentKey, json_name: "agentKeys"
field :url, 9, type: :string
field :teams_auth, 10, type: :bool, json_name: "teamsAuth"
end
4 changes: 3 additions & 1 deletion proto/lib/livebook_proto/deployment_group_updated.pb.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ defmodule LivebookProto.DeploymentGroupUpdated do
field :name, 2, type: :string
field :secrets, 3, repeated: true, type: LivebookProto.DeploymentGroupSecret
field :clustering, 4, type: :string
field :zta_provider, 5, type: :string, json_name: "ztaProvider"
field :zta_provider, 5, type: :string, json_name: "ztaProvider", deprecated: true
field :zta_key, 6, type: :string, json_name: "ztaKey", deprecated: true
field :agent_keys, 7, repeated: true, type: LivebookProto.AgentKey, json_name: "agentKeys"
field :url, 8, type: :string
Expand All @@ -14,4 +14,6 @@ defmodule LivebookProto.DeploymentGroupUpdated do
repeated: true,
type: LivebookProto.EnvironmentVariable,
json_name: "environmentVariables"

field :teams_auth, 10, type: :bool, json_name: "teamsAuth"
end
9 changes: 6 additions & 3 deletions proto/messages.proto
Original file line number Diff line number Diff line change
Expand Up @@ -60,34 +60,37 @@ message DeploymentGroup {
string mode = 3;
repeated DeploymentGroupSecret secrets = 4;
string clustering = 5;
string zta_provider = 6;
string zta_provider = 6 [deprecated = true];
string zta_key = 7 [deprecated = true];
repeated AgentKey agent_keys = 8;
string url = 9;
repeated EnvironmentVariable environment_variables = 10;
bool teams_auth = 11;
}

message DeploymentGroupCreated {
string id = 1;
string name = 2;
string mode = 3;
string clustering = 5;
string zta_provider = 6;
string zta_provider = 6 [deprecated = true];
string zta_key = 7 [deprecated = true];
repeated AgentKey agent_keys = 8;
string url = 9;
bool teams_auth = 10;
}

message DeploymentGroupUpdated {
string id = 1;
string name = 2;
repeated DeploymentGroupSecret secrets = 3;
string clustering = 4;
string zta_provider = 5;
string zta_provider = 5 [deprecated = true];
string zta_key = 6 [deprecated = true];
repeated AgentKey agent_keys = 7;
string url = 8;
repeated EnvironmentVariable environment_variables = 9;
bool teams_auth = 10;
}

message DeploymentGroupDeleted {
Expand Down
16 changes: 9 additions & 7 deletions test/livebook_teams/hubs/team_client_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -176,17 +176,18 @@ defmodule Livebook.Hubs.TeamClientTest do
id: "1",
name: "sleepy-cat-#{System.unique_integer([:positive])}",
mode: :offline,
hub_id: team.id
hub_id: team.id,
teams_auth: false
)

livebook_proto_deployment_group =
%LivebookProto.DeploymentGroup{
id: to_string(deployment_group.id),
name: deployment_group.name,
mode: to_string(deployment_group.mode),
zta_provider: to_string(deployment_group.zta_provider),
secrets: [],
agent_keys: []
agent_keys: [],
teams_auth: deployment_group.teams_auth
}

# creates the deployment group
Expand Down Expand Up @@ -471,8 +472,8 @@ defmodule Livebook.Hubs.TeamClientTest do
id: to_string(deployment_group.id),
name: deployment_group.name,
mode: to_string(deployment_group.mode),
zta_provider: to_string(deployment_group.zta_provider),
agent_keys: [livebook_proto_agent_key],
teams_auth: deployment_group.teams_auth,
secrets: [],
environment_variables: []
}
Expand Down Expand Up @@ -566,8 +567,8 @@ defmodule Livebook.Hubs.TeamClientTest do
id: to_string(deployment_group.id),
name: deployment_group.name,
mode: to_string(deployment_group.mode),
zta_provider: to_string(deployment_group.zta_provider),
secrets: [livebook_proto_deployment_group_secret]
secrets: [livebook_proto_deployment_group_secret],
teams_auth: deployment_group.teams_auth
}

agent_connected = %{agent_connected | deployment_groups: [livebook_proto_deployment_group]}
Expand Down Expand Up @@ -617,7 +618,8 @@ defmodule Livebook.Hubs.TeamClientTest do
name: deployment_group.name,
mode: to_string(deployment_group.mode),
secrets: [],
agent_keys: [livebook_proto_agent_key]
agent_keys: [livebook_proto_agent_key],
teams_auth: deployment_group.teams_auth
}

agent_connected = %{agent_connected | deployment_groups: [livebook_proto_deployment_group]}
Expand Down
17 changes: 4 additions & 13 deletions test/livebook_teams/teams_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -185,22 +185,13 @@ defmodule Livebook.TeamsTest do
test "creates a new deployment group with Livebook Teams authentication",
%{user: user, node: node} do
team = connect_to_teams(user, node)
attrs = params_for(:deployment_group, name: "DEPLOYMENT_GROUP_#{team.id}", mode: :online)

attrs =
params_for(:deployment_group,
name: "DEPLOYMENT_GROUP_#{team.id}",
mode: :online,
zta_provider: :livebook_teams
)

assert {:ok, deployment_group} = Teams.create_deployment_group(team, attrs)

%{id: id, name: name, mode: mode, zta_provider: zta_provider} = deployment_group

assert zta_provider == :livebook_teams
assert {:ok, %{id: id, name: name, mode: mode, teams_auth: true}} =
Teams.create_deployment_group(team, attrs)

assert_receive {:deployment_group_created,
%{id: ^id, name: ^name, mode: ^mode, zta_provider: ^zta_provider}}
%{id: ^id, name: ^name, mode: ^mode, teams_auth: true}}
end

test "returns changeset errors when the name is invalid", %{user: user, node: node} do
Expand Down
4 changes: 2 additions & 2 deletions test/livebook_teams/web/hub/deployment_group_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ defmodule LivebookWeb.Integration.Hub.DeploymentGroupTest do
name: deployment_group.name,
value: deployment_group.mode,
hub_id: deployment_group.hub_id,
zta_provider: :livebook_teams,
url: url
url: url,
teams_auth: true
}
}

Expand Down
4 changes: 1 addition & 3 deletions test/livebook_teams/zta/livebook_teams_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ defmodule Livebook.ZTA.LivebookTeamsTest do

setup %{test: test, node: node} do
Livebook.Teams.Broadcasts.subscribe([:agents])

{_agent_key, org, deployment_group, team} =
create_agent_team_hub(node, deployment_group: [zta_provider: :livebook_teams])
{_agent_key, org, deployment_group, team} = create_agent_team_hub(node)

# we wait until the agent_connected is received by livebook
hub_id = team.id
Expand Down

0 comments on commit 433b801

Please sign in to comment.