mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-27 02:18:47 +00:00
chore(portal): version gate resource can change sites (#10608)
On clients prior to https://github.com/firezone/firezone/pull/10604, sending `resource_created_or_updated` for a site change would cause a panic. With the introduction of that PR, the portal can now send this message without needing to "toggle" the resource first by sending `resource_deleted`. Fixes: #10593
This commit is contained in:
10
elixir/apps/domain/lib/domain/cache/client.ex
vendored
10
elixir/apps/domain/lib/domain/cache/client.ex
vendored
@@ -51,7 +51,7 @@ defmodule Domain.Cache.Client do
|
||||
|
||||
"""
|
||||
|
||||
alias Domain.{Actors, Auth, Clients, Cache, Gateways, Resources, Policies}
|
||||
alias Domain.{Actors, Auth, Clients, Cache, Gateways, Resources, Policies, Version}
|
||||
require Logger
|
||||
require OpenTelemetry.Tracer
|
||||
import Ecto.UUID, only: [dump!: 1, load!: 1]
|
||||
@@ -159,8 +159,8 @@ defmodule Domain.Cache.Client do
|
||||
|
||||
added_ids = Enum.map(added, & &1.id)
|
||||
|
||||
# connlib can handle all resource attribute changes except for changing sites, so we can omit the deleted IDs
|
||||
# of added resources since they'll be updated gracefully.
|
||||
# connlib can handle all resource attribute changes except for changing sites (on older clients),
|
||||
# so we can omit the deleted IDs of added resources since they'll be updated gracefully.
|
||||
removed_ids =
|
||||
for r <- cache.connectable_resources -- connectable_resources,
|
||||
toggle or r.id not in added_ids do
|
||||
@@ -273,9 +273,11 @@ defmodule Domain.Cache.Client do
|
||||
|
||||
cache = %{cache | resources: resources}
|
||||
|
||||
toggle = Version.resource_cannot_change_sites_on_client?(client)
|
||||
|
||||
# For these updates we need to make sure the resource is toggled deleted then created.
|
||||
# See https://github.com/firezone/firezone/issues/9881
|
||||
recompute_connectable_resources(cache, client, toggle: true)
|
||||
recompute_connectable_resources(cache, client, toggle: toggle)
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
||||
@@ -58,6 +58,16 @@ defmodule Domain.ComponentVersions do
|
||||
end
|
||||
end
|
||||
|
||||
def get_component_type(%Client{last_seen_user_agent: "Mac OS" <> _rest}), do: :apple
|
||||
def get_component_type(%Client{last_seen_user_agent: "iOS" <> _rest}), do: :apple
|
||||
|
||||
def get_component_type(%Client{last_seen_user_agent: "Android" <> _rest}),
|
||||
do: :android
|
||||
|
||||
def get_component_type(%Client{actor: %Actor{type: :service_account}}), do: :headless
|
||||
|
||||
def get_component_type(_), do: :gui
|
||||
|
||||
defp fetch_config! do
|
||||
Domain.Config.fetch_env!(:domain, __MODULE__)
|
||||
end
|
||||
@@ -98,14 +108,4 @@ defmodule Domain.ComponentVersions do
|
||||
|> Keyword.fetch!(:versions)
|
||||
end
|
||||
end
|
||||
|
||||
defp get_component_type(%Client{last_seen_user_agent: "Mac OS" <> _rest}), do: :apple
|
||||
defp get_component_type(%Client{last_seen_user_agent: "iOS" <> _rest}), do: :apple
|
||||
|
||||
defp get_component_type(%Client{last_seen_user_agent: "Android" <> _rest}),
|
||||
do: :android
|
||||
|
||||
defp get_component_type(%Client{actor: %Actor{type: :service_account}}), do: :headless
|
||||
|
||||
defp get_component_type(_), do: :gui
|
||||
end
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
defmodule Domain.Version do
|
||||
alias Domain.{
|
||||
Clients.Client,
|
||||
ComponentVersions
|
||||
}
|
||||
|
||||
def fetch_version(user_agent) when is_binary(user_agent) do
|
||||
user_agent
|
||||
|> String.split(" ")
|
||||
@@ -21,4 +26,15 @@ defmodule Domain.Version do
|
||||
def fetch_gateway_version(_user_agent) do
|
||||
{:error, :invalid_user_agent}
|
||||
end
|
||||
|
||||
# TODO: Remove once all clients are on versions that support resources changing sites.
|
||||
# Connlib didn't support resources changing sites until https://github.com/firezone/firezone/pull/10604
|
||||
def resource_cannot_change_sites_on_client?(%Client{last_seen_version: version} = client) do
|
||||
case ComponentVersions.get_component_type(client) do
|
||||
:apple -> Version.compare(version, "1.5.9") == :lt
|
||||
:android -> Version.compare(version, "1.5.5") == :lt
|
||||
:headless -> Version.compare(version, "1.5.5") == :lt
|
||||
:gui -> Version.compare(version, "1.5.9") == :lt
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
defmodule Domain.VersionTest do
|
||||
use ExUnit.Case, async: true
|
||||
|
||||
describe "fetch_version" do
|
||||
describe "fetch_version/1" do
|
||||
test "can decode linux headless-client version" do
|
||||
assert Domain.Version.fetch_version("Fedora/42.0.0 headless-client/1.4.5 (arm64; 24.1.0)") ==
|
||||
{:ok, "1.4.5"}
|
||||
@@ -39,4 +39,114 @@ defmodule Domain.VersionTest do
|
||||
{:ok, "1.4.5"}
|
||||
end
|
||||
end
|
||||
|
||||
describe "resource_cannot_change_sites_on_client?/1" do
|
||||
test "apple client below version cannot change sites" do
|
||||
client = %Domain.Clients.Client{
|
||||
last_seen_version: "1.5.7",
|
||||
last_seen_user_agent: "Mac OS X"
|
||||
}
|
||||
|
||||
assert Domain.Version.resource_cannot_change_sites_on_client?(client)
|
||||
end
|
||||
|
||||
test "apple client at version cannot change sites" do
|
||||
client = %Domain.Clients.Client{
|
||||
last_seen_version: "1.5.8",
|
||||
last_seen_user_agent: "Mac OS X"
|
||||
}
|
||||
|
||||
assert Domain.Version.resource_cannot_change_sites_on_client?(client)
|
||||
end
|
||||
|
||||
test "apple client above version can change sites" do
|
||||
client = %Domain.Clients.Client{
|
||||
last_seen_version: "1.5.9",
|
||||
last_seen_user_agent: "Mac OS X"
|
||||
}
|
||||
|
||||
refute Domain.Version.resource_cannot_change_sites_on_client?(client)
|
||||
end
|
||||
|
||||
test "android client below version cannot change sites" do
|
||||
client = %Domain.Clients.Client{
|
||||
last_seen_version: "1.5.3",
|
||||
last_seen_user_agent: "Android"
|
||||
}
|
||||
|
||||
assert Domain.Version.resource_cannot_change_sites_on_client?(client)
|
||||
end
|
||||
|
||||
test "android client at version cannot change sites" do
|
||||
client = %Domain.Clients.Client{
|
||||
last_seen_version: "1.5.4",
|
||||
last_seen_user_agent: "Android"
|
||||
}
|
||||
|
||||
assert Domain.Version.resource_cannot_change_sites_on_client?(client)
|
||||
end
|
||||
|
||||
test "android client above version can change sites" do
|
||||
client = %Domain.Clients.Client{
|
||||
last_seen_version: "1.5.5",
|
||||
last_seen_user_agent: "Android"
|
||||
}
|
||||
|
||||
refute Domain.Version.resource_cannot_change_sites_on_client?(client)
|
||||
end
|
||||
|
||||
test "headless client below version cannot change sites" do
|
||||
client = %Domain.Clients.Client{
|
||||
last_seen_version: "1.5.3",
|
||||
actor: %Domain.Actors.Actor{type: :service_account}
|
||||
}
|
||||
|
||||
assert Domain.Version.resource_cannot_change_sites_on_client?(client)
|
||||
end
|
||||
|
||||
test "headless client at version cannot change sites" do
|
||||
client = %Domain.Clients.Client{
|
||||
last_seen_version: "1.5.4",
|
||||
actor: %Domain.Actors.Actor{type: :service_account}
|
||||
}
|
||||
|
||||
assert Domain.Version.resource_cannot_change_sites_on_client?(client)
|
||||
end
|
||||
|
||||
test "headless client above version can change sites" do
|
||||
client = %Domain.Clients.Client{
|
||||
last_seen_version: "1.5.5",
|
||||
actor: %Domain.Actors.Actor{type: :service_account}
|
||||
}
|
||||
|
||||
refute Domain.Version.resource_cannot_change_sites_on_client?(client)
|
||||
end
|
||||
|
||||
test "gui client below version cannot change sites" do
|
||||
client = %Domain.Clients.Client{
|
||||
last_seen_version: "1.5.7",
|
||||
last_seen_user_agent: "Windows"
|
||||
}
|
||||
|
||||
assert Domain.Version.resource_cannot_change_sites_on_client?(client)
|
||||
end
|
||||
|
||||
test "gui client at version cannot change sites" do
|
||||
client = %Domain.Clients.Client{
|
||||
last_seen_version: "1.5.8",
|
||||
last_seen_user_agent: "Windows"
|
||||
}
|
||||
|
||||
assert Domain.Version.resource_cannot_change_sites_on_client?(client)
|
||||
end
|
||||
|
||||
test "gui client above version can change sites" do
|
||||
client = %Domain.Clients.Client{
|
||||
last_seen_version: "1.5.9",
|
||||
last_seen_user_agent: "Windows"
|
||||
}
|
||||
|
||||
refute Domain.Version.resource_cannot_change_sites_on_client?(client)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user