delegate service checks to agents and fix ui issues (#63)

- Skip HTTP/TCP/DNS checks in Phoenix when device is assigned to agent
- Agents now execute service checks from the device's network location
- Fix cancel button in service check modal (text link instead of button)
- Fix status badge alignment in checks table

Reviewed-on: graham/towerops-web#63
This commit is contained in:
Graham McIntire 2026-03-17 15:43:31 -05:00 committed by graham
parent b724aa4ab8
commit 150ffb421d
4 changed files with 24 additions and 10 deletions

View file

@ -40,6 +40,7 @@ defmodule Towerops.Workers.CheckExecutorWorker do
require Logger
@snmp_check_types ~w(snmp_sensor snmp_interface snmp_processor snmp_storage)
@service_check_types ~w(http tcp dns)
@impl Oban.Worker
def perform(%Oban.Job{args: %{"check_id" => check_id}}) do
@ -56,6 +57,9 @@ defmodule Towerops.Workers.CheckExecutorWorker do
should_skip_snmp_check?(check) ->
Logger.debug("Skipping SNMP check #{check_id} - Phoenix SNMP disabled or device assigned to agent")
should_skip_service_check?(check) ->
Logger.debug("Skipping service check #{check_id} - device assigned to agent")
true ->
execute_and_record(check)
schedule_next_check(check)
@ -72,6 +76,14 @@ defmodule Towerops.Workers.CheckExecutorWorker do
defp should_skip_snmp_check?(_check), do: false
defp should_skip_service_check?(%{check_type: check_type} = check) when check_type in @service_check_types do
# Skip service checks (HTTP/TCP/DNS) if device is assigned to an agent
# The agent will execute these checks from the device's network location
check.device_id != nil and not Agents.should_phoenix_poll_device?(%Device{id: check.device_id})
end
defp should_skip_service_check?(_check), do: false
defp execute_and_record(check) do
Logger.debug("Executing check #{check.id} (#{check.check_type})")

View file

@ -97,21 +97,21 @@ defmodule ToweropsWeb.CheckLive.FormComponent do
</div>
</div>
<div class="bg-gray-50 dark:bg-gray-900/50 px-4 py-3 sm:flex sm:flex-row-reverse sm:px-6 gap-2">
<div class="bg-gray-50 dark:bg-gray-900/50 px-4 py-3 sm:flex sm:flex-row-reverse sm:px-6 gap-3">
<.button
type="submit"
phx-disable-with={if @action == :edit, do: "Saving...", else: "Creating..."}
>
{if @action == :edit, do: "Save Changes", else: "Create Check"}
</.button>
<.button
<button
type="button"
phx-click="close"
phx-target={@myself}
class="bg-white dark:bg-gray-700"
class="text-sm font-semibold text-gray-700 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white"
>
Cancel
</.button>
</button>
</div>
</.form>
</div>

View file

@ -2698,8 +2698,10 @@
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900 dark:text-white">
{check.name}
</td>
<td class="px-4 py-3 whitespace-nowrap">
{render_status_badge(check.current_state)}
<td class="px-4 py-3 whitespace-nowrap text-left">
<div class="flex justify-start">
{render_status_badge(check.current_state)}
</div>
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">
<%= if check.last_check_at do %>

View file

@ -392,7 +392,7 @@ defmodule Towerops.Workers.CheckExecutorWorkerTest do
assert results == []
end
test "still executes non-SNMP checks when device is assigned to agent", %{
test "skips service checks (HTTP/TCP/DNS) when device is assigned to agent", %{
device: device,
organization: organization
} do
@ -413,12 +413,12 @@ defmodule Towerops.Workers.CheckExecutorWorkerTest do
Repo.delete_all(Oban.Job)
# HTTP checks should still execute even when device has an agent
# Service checks should be skipped when device has an agent (agent will execute them)
assert :ok = perform_job(CheckExecutorWorker, %{check_id: check.id})
# Should have a result (even if error from network)
# Should have no result since check was skipped
results = Repo.all(from(r in CheckResult, where: r.check_id == ^check.id))
assert length(results) == 1
assert results == []
end
test "skips SNMP check when phoenix_snmp_disabled is true", %{