From 91dd7ad9853cff24c2675f7c12035f536036fbe7 Mon Sep 17 00:00:00 2001 From: Graham McIntire Date: Sun, 15 Feb 2026 12:28:06 -0600 Subject: [PATCH] fix: allow site_id on device create regardless of use_sites setting The API was silently stripping site_id when use_sites was false, causing the Terraform provider to report inconsistent state after apply. --- .../controllers/api/v1/devices_controller.ex | 18 +-------------- .../api/v1/devices_controller_test.exs | 22 ++++++++++++++++++- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/lib/towerops_web/controllers/api/v1/devices_controller.ex b/lib/towerops_web/controllers/api/v1/devices_controller.ex index fd95beb5..52b8012d 100644 --- a/lib/towerops_web/controllers/api/v1/devices_controller.ex +++ b/lib/towerops_web/controllers/api/v1/devices_controller.ex @@ -8,7 +8,6 @@ defmodule ToweropsWeb.Api.V1.DevicesController do use ToweropsWeb, :controller alias Towerops.Devices - alias Towerops.Organizations alias Towerops.Workers.DiscoveryWorker @doc """ @@ -89,10 +88,7 @@ defmodule ToweropsWeb.Api.V1.DevicesController do organization_id = conn.assigns.current_organization_id current_user = conn.assigns[:current_user] - device_params = - device_params - |> default_organization_id(organization_id) - |> maybe_strip_site_id_if_sites_disabled(organization_id) + device_params = default_organization_id(device_params, organization_id) case verify_site_access(device_params["site_id"], organization_id) do :ok -> @@ -251,18 +247,6 @@ defmodule ToweropsWeb.Api.V1.DevicesController do end end - defp maybe_strip_site_id_if_sites_disabled(device_params, organization_id) do - organization = Organizations.get_organization!(organization_id) - - # If sites are disabled and a site_id was provided, remove it - # This ensures devices are assigned directly to the organization - if !organization.use_sites && device_params["site_id"] do - Map.delete(device_params, "site_id") - else - device_params - end - end - defp create_and_discover_device(conn, device_params, current_user) do opts = if current_user && current_user.is_superuser, do: [bypass_limits: true], else: [] diff --git a/test/towerops_web/controllers/api/v1/devices_controller_test.exs b/test/towerops_web/controllers/api/v1/devices_controller_test.exs index ae5a6e5a..569126ce 100644 --- a/test/towerops_web/controllers/api/v1/devices_controller_test.exs +++ b/test/towerops_web/controllers/api/v1/devices_controller_test.exs @@ -126,8 +126,28 @@ defmodule ToweropsWeb.Api.V1.DevicesControllerTest do assert is_binary(id) end + test "creates device with site_id even when use_sites is false", %{ + conn: conn, + organization: organization + } do + assert organization.use_sites == false + {:ok, site} = Sites.create_site(%{name: "Test Site", organization_id: organization.id}) + + device_params = %{ + "device" => %{ + "name" => "Test Router", + "ip_address" => "192.168.1.50", + "site_id" => site.id + } + } + + conn = post(conn, ~p"/api/v1/devices", device_params) + + assert %{"id" => _id, "site_id" => site_id} = json_response(conn, 201) + assert site_id == site.id + end + test "creates device with site_id", %{conn: conn, organization: organization} do - # Enable sites for this organization {:ok, organization} = Towerops.Organizations.update_organization(organization, %{use_sites: true}) {:ok, site} = Sites.create_site(%{name: "Test Site", organization_id: organization.id})