+
Docker Compose Setup with Auto-Updates
-
+
This configuration includes Watchtower for automatic agent updates. The agent will automatically update to the latest version every 15 minutes during development.
-
services:
+ services:
towerops-agent:
image: {@agent_image}
container_name: towerops-agent
diff --git a/lib/towerops_web/live/agent_live/show.ex b/lib/towerops_web/live/agent_live/show.ex
index 1717a1ff..821d203e 100644
--- a/lib/towerops_web/live/agent_live/show.ex
+++ b/lib/towerops_web/live/agent_live/show.ex
@@ -62,7 +62,7 @@ defmodule ToweropsWeb.AgentLive.Show do
:direct -> "bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-300"
:site -> "bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-300"
:organization -> "bg-amber-100 text-amber-800 dark:bg-amber-900 dark:text-amber-300"
- :unknown -> "bg-zinc-100 text-zinc-800 dark:bg-zinc-800 dark:text-zinc-300"
+ :unknown -> "bg-gray-100 text-gray-800 dark:bg-gray-800 dark:text-gray-300"
end
end
end
diff --git a/lib/towerops_web/live/agent_live/show.html.heex b/lib/towerops_web/live/agent_live/show.html.heex
index 576c16aa..017c15fc 100644
--- a/lib/towerops_web/live/agent_live/show.html.heex
+++ b/lib/towerops_web/live/agent_live/show.html.heex
@@ -17,7 +17,7 @@
<.link
navigate={~p"/orgs/#{@current_organization.slug}/agents"}
- class="text-sm font-semibold text-zinc-700 dark:text-zinc-300 hover:text-zinc-900 dark:hover:text-zinc-100"
+ class="text-sm font-semibold text-gray-700 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white"
>
<.icon name="hero-arrow-left" class="h-5 w-5" /> Back to Agents
@@ -27,10 +27,10 @@
-
+
-
Status
+
Status
<% {status, label} = agent_status(@agent_token) %>
@@ -39,104 +39,104 @@
- <.icon name="hero-signal" class="h-8 w-8 text-zinc-400 dark:text-zinc-600" />
+ <.icon name="hero-signal" class="h-8 w-8 text-gray-400 dark:text-gray-500" />
-
+
-
Device
-
+
Device
+
{length(@polling_targets)}
-
+
{@direct_assignments} direct
- <.icon name="hero-server" class="h-8 w-8 text-zinc-400 dark:text-zinc-600" />
+ <.icon name="hero-server" class="h-8 w-8 text-gray-400 dark:text-gray-500" />
-
+
-
Last Seen
-
+
Last Seen
+
<.timestamp
datetime={@agent_token.last_seen_at}
timezone={@timezone}
/>
<%= if @agent_token.last_seen_at do %>
-
+
{format_datetime(@agent_token.last_seen_at, @timezone)}
<% end %>
<%= if @agent_token.last_ip do %>
-
+
{@agent_token.last_ip}
<% end %>
- <.icon name="hero-clock" class="h-8 w-8 text-zinc-400 dark:text-zinc-600 flex-shrink-0" />
+ <.icon name="hero-clock" class="h-8 w-8 text-gray-400 dark:text-gray-500 flex-shrink-0" />
-
+
-
Agent Info
+
Agent Info
<%= if @agent_token.metadata["version"] do %>
-
+
v{@agent_token.metadata["version"]}
<% else %>
-
+
Unknown
<% end %>
<%= if @agent_token.metadata["uptime_seconds"] do %>
-
+
Uptime: {format_uptime(@agent_token.metadata["uptime_seconds"])}
<% end %>
- <.icon name="hero-information-circle" class="h-8 w-8 text-zinc-400 dark:text-zinc-600" />
+ <.icon name="hero-information-circle" class="h-8 w-8 text-gray-400 dark:text-gray-500" />
<%= if @agent_token.metadata && map_size(@agent_token.metadata) > 0 do %>
-
-
+
+
Agent Metadata
<%= if @agent_token.metadata["hostname"] do %>
-
- Hostname
- -
+
- Hostname
+ -
{@agent_token.metadata["hostname"]}
<% end %>
<%= if @agent_token.metadata["version"] do %>
-
- Version
- -
+
- Version
+ -
{@agent_token.metadata["version"]}
<% end %>
<%= if @agent_token.metadata["uptime_seconds"] do %>
-
- Uptime
- -
+
- Uptime
+ -
{format_uptime(@agent_token.metadata["uptime_seconds"])}
@@ -146,40 +146,40 @@
<% end %>
-
-
+
+
Timestamps
-
- Created
- -
+
- Created
+ -
{format_datetime(@agent_token.inserted_at, @timezone)}
- -
+
-
<.timestamp datetime={@agent_token.inserted_at} timezone={@timezone} /> (created)
-
- Last Updated
- -
+
- Last Updated
+ -
{format_datetime(@agent_token.updated_at, @timezone)}
- -
+
-
<.timestamp datetime={@agent_token.updated_at} timezone={@timezone} />
-
-
+
-
Last Seen (Heartbeat)
- -
+
-
{format_datetime(@agent_token.last_seen_at, @timezone)}
<%= if @agent_token.last_seen_at do %>
- -
+
-
<.timestamp datetime={@agent_token.last_seen_at} timezone={@timezone} />
<% end %>
@@ -187,8 +187,8 @@
<%= if @agent_token.last_ip do %>
-
- Last IP Address
- -
+
- Last IP Address
+ -
{@agent_token.last_ip}
@@ -197,38 +197,38 @@
-
-
-
+
+
+
Polling Targets
-
+
Device that this agent is responsible for polling
<%= if @polling_targets == [] do %>
- <.icon name="hero-server" class="mx-auto h-12 w-12 text-zinc-400 dark:text-zinc-600" />
-
+ <.icon name="hero-server" class="mx-auto h-12 w-12 text-gray-400 dark:text-gray-500" />
+
No devices assigned
-
+
This agent is not currently polling any device.
<% else %>
-
+
<%= for device <- @polling_targets do %>
<.link
navigate={~p"/devices/#{device.id}"}
- class="block hover:bg-zinc-50 dark:hover:bg-zinc-800 transition-colors"
+ class="block hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors"
>
-
+
{device.name}
<% {source, source_label} = assignment_source(device, @agent_token.id) %>
@@ -236,7 +236,7 @@
{source_label}
-
+
<.icon name="hero-globe-alt" class="h-4 w-4" />
{device.ip_address}
@@ -249,7 +249,7 @@
<% end %>
- <.icon name="hero-chevron-right" class="h-5 w-5 text-zinc-400 dark:text-zinc-600" />
+ <.icon name="hero-chevron-right" class="h-5 w-5 text-gray-400 dark:text-gray-500" />
diff --git a/lib/towerops_web/live/alert_live/index.html.heex b/lib/towerops_web/live/alert_live/index.html.heex
index 3e560358..7a3d414e 100644
--- a/lib/towerops_web/live/alert_live/index.html.heex
+++ b/lib/towerops_web/live/alert_live/index.html.heex
@@ -11,7 +11,7 @@
-
+
<.link
patch={~p"/orgs/#{@current_organization.slug}/alerts"}
class={[
@@ -19,7 +19,7 @@
@filter == "active" &&
"bg-blue-600 text-white dark:bg-blue-500",
@filter != "active" &&
- "bg-white text-zinc-700 hover:bg-zinc-50 dark:bg-zinc-900 dark:text-zinc-300 dark:hover:bg-zinc-800"
+ "bg-white text-gray-700 hover:bg-gray-50 dark:bg-gray-800/50 dark:text-gray-300 dark:hover:bg-gray-800"
]}
>
Active Alerts
@@ -27,11 +27,11 @@
<.link
patch={~p"/orgs/#{@current_organization.slug}/alerts?filter=all"}
class={[
- "px-4 py-2 text-sm font-medium rounded-r-lg border-l border-zinc-200 dark:border-zinc-800",
+ "px-4 py-2 text-sm font-medium rounded-r-lg border-l border-gray-200 dark:border-white/10",
@filter == "all" &&
"bg-blue-600 text-white dark:bg-blue-500",
@filter != "all" &&
- "bg-white text-zinc-700 hover:bg-zinc-50 dark:bg-zinc-900 dark:text-zinc-300 dark:hover:bg-zinc-800"
+ "bg-white text-gray-700 hover:bg-gray-50 dark:bg-gray-800/50 dark:text-gray-300 dark:hover:bg-gray-800"
]}
>
All Alerts
@@ -41,9 +41,9 @@
<%= if Enum.empty?(@alerts) do %>
- <.icon name="hero-bell-slash" class="mx-auto h-12 w-12 text-zinc-400 dark:text-zinc-600" />
-
No alerts
-
+ <.icon name="hero-bell-slash" class="mx-auto h-12 w-12 text-gray-400 dark:text-gray-500" />
+
No alerts
+
<%= if @filter == "active" do %>
There are no active alerts for this organization.
<% else %>
@@ -60,7 +60,7 @@
alert.alert_type == :device_down && is_nil(alert.resolved_at) &&
"border-l-4 border-red-500 bg-red-50 dark:bg-red-950 dark:border-red-700",
(alert.alert_type != :device_down || alert.resolved_at) &&
- "border-zinc-200 bg-white dark:border-zinc-800 dark:bg-zinc-900"
+ "border-gray-200 bg-white dark:border-white/10 dark:bg-gray-800/50"
]}>
@@ -81,7 +81,7 @@
<%= if alert.resolved_at do %>
-
+
Resolved
<% end %>
@@ -93,7 +93,7 @@
<% end %>
-
+
<.link
navigate={~p"/devices/#{alert.device.id}"}
class="text-blue-600 hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300"
@@ -102,9 +102,9 @@
-
{alert.message}
+
{alert.message}
-
+
Triggered:
{ToweropsWeb.TimeHelpers.format_iso8601(alert.triggered_at, @timezone)}
diff --git a/lib/towerops_web/live/dashboard_live.html.heex b/lib/towerops_web/live/dashboard_live.html.heex
index 12026b2d..1c47203e 100644
--- a/lib/towerops_web/live/dashboard_live.html.heex
+++ b/lib/towerops_web/live/dashboard_live.html.heex
@@ -11,15 +11,15 @@
<%= if @sites_count == 0 do %>
-
+
<.icon
name="hero-light-bulb"
class="mx-auto h-16 w-16 text-blue-500 dark:text-blue-400"
/>
-
+
Let's get started!
-
+
Follow these steps to set up your network monitoring:
@@ -29,32 +29,32 @@
1
-
Create a Site
-
+
Create a Site
+
Sites represent your physical locations (offices, data centers, towers, etc.)
-
+
2
-
Add Device
-
+
Add Device
+
Add network devices (routers, switches, servers) to your sites
-
+
3
-
+
Monitor & Receive Alerts
-
+
Towerops will automatically monitor your devices and alert you of issues
@@ -71,30 +71,30 @@
<.link
navigate={~p"/sites"}
- class="rounded-lg border border-zinc-200 bg-white p-6 shadow-sm transition-shadow hover:shadow-md dark:border-zinc-800 dark:bg-zinc-900"
+ class="rounded-lg border border-gray-200 bg-white p-6 shadow-sm transition-shadow hover:shadow-md dark:border-white/10 dark:bg-gray-800/50"
>
-
Sites
-
{@sites_count}
-
Total sites
+
Sites
+
{@sites_count}
+
Total sites
<.link
navigate={~p"/devices"}
- class="rounded-lg border border-zinc-200 bg-white p-6 shadow-sm transition-shadow hover:shadow-md dark:border-zinc-800 dark:bg-zinc-900"
+ class="rounded-lg border border-gray-200 bg-white p-6 shadow-sm transition-shadow hover:shadow-md dark:border-white/10 dark:bg-gray-800/50"
>
-
Device
-
{@device_count}
+
Device
+
{@device_count}
-
+
{@device_up} Up
-
+
{@device_down} Down
-
-
+
+
{@device_unknown} Unknown
@@ -102,21 +102,21 @@
<.link
navigate={~p"/orgs/#{@current_organization.slug}/alerts"}
- class="rounded-lg border border-zinc-200 bg-white p-6 shadow-sm transition-shadow hover:shadow-md dark:border-zinc-800 dark:bg-zinc-900"
+ class="rounded-lg border border-gray-200 bg-white p-6 shadow-sm transition-shadow hover:shadow-md dark:border-white/10 dark:bg-gray-800/50"
>
-
Active Alerts
+
Active Alerts
0 && "text-red-600 dark:text-red-500") ||
- "text-zinc-900 dark:text-zinc-100"
+ "text-gray-900 dark:text-white"
]}>
{length(@active_alerts)}
-
Requires attention
+
Requires attention
-
-
System Status
+
+
System Status
0 do %>
-
Active Alerts
+
Active Alerts
<.link
navigate={~p"/orgs/#{@current_organization.slug}/alerts"}
class="text-sm font-medium text-blue-600 hover:text-blue-700 dark:text-blue-500 dark:hover:text-blue-400"
@@ -153,7 +153,7 @@
class="h-5 w-5 flex-shrink-0 text-red-600 dark:text-red-500"
/>
-
+
<.link
navigate={~p"/devices/#{alert.device.id}"}
class="hover:text-blue-600 hover:underline dark:hover:text-blue-400"
@@ -161,16 +161,16 @@
{alert.device.name}
-
{alert.message}
+
{alert.message}
-
+
{ToweropsWeb.TimeHelpers.format_datetime(alert.triggered_at, @timezone)}
<% end %>
<%= if length(@active_alerts) > 5 do %>
-
+
+ {length(@active_alerts) - 5} more alerts
<% end %>
@@ -179,7 +179,7 @@
<% end %>
-
Quick Actions
+
Quick Actions
<.link
navigate={~p"/sites"}
@@ -197,7 +197,7 @@
<.link
navigate={~p"/orgs/#{@current_organization.slug}/alerts"}
- class="inline-flex items-center gap-2 rounded-lg border border-zinc-300 bg-white px-4 py-2.5 text-sm font-semibold text-zinc-700 shadow-sm hover:bg-zinc-50 focus:outline-none focus:ring-2 focus:ring-blue-600 focus:ring-offset-2 dark:border-zinc-700 dark:bg-zinc-800 dark:text-zinc-200 dark:hover:bg-zinc-700"
+ class="inline-flex items-center gap-2 rounded-lg border border-gray-300 bg-white px-4 py-2.5 text-sm font-semibold text-gray-700 shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-600 focus:ring-offset-2 dark:border-white/10 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700"
>
<.icon name="hero-bell" class="h-5 w-5" />
View Alerts
diff --git a/lib/towerops_web/live/device_live/form.html.heex b/lib/towerops_web/live/device_live/form.html.heex
index 9af0efa4..ad6ac145 100644
--- a/lib/towerops_web/live/device_live/form.html.heex
+++ b/lib/towerops_web/live/device_live/form.html.heex
@@ -12,7 +12,7 @@
do: ~p"/devices/#{@device.id}",
else: ~p"/devices"
}
- class="inline-flex items-center gap-1 text-sm text-zinc-600 hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-zinc-100"
+ class="inline-flex items-center gap-1 text-sm text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white"
>
<.icon name="hero-arrow-left" class="h-4 w-4" />
{if @live_action == :edit, do: "Back to Device", else: "Back to Device List"}
@@ -82,22 +82,22 @@
this device is explicitly assigned
<% :site -> %>
-
+
<.icon name="hero-building-office" class="h-4 w-4" /> Inherited from site:
{@effective_agent_name}
<% :organization -> %>
-
+
<.icon name="hero-building-office-2" class="h-4 w-4" />
Inherited from organization: {@effective_agent_name}
<% :none -> %>
-
+
<.icon name="hero-cloud" class="h-4 w-4" /> No agent assigned - cloud polling
<% end %>
<% else %>
-
+
Assign this device to a remote agent for local SNMP polling. Leave empty to inherit from site or organization defaults.
<% end %>
@@ -108,7 +108,7 @@
-
+
-
+
<%= if @monitoring_mode == "snmp_and_icmp" do %>
Monitor device availability with ICMP pings and collect detailed information via SNMP
@@ -180,17 +180,17 @@
Overriding site/organization SNMP defaults
<% :site -> %>
-
+
<.icon name="hero-building-office" class="h-4 w-4" />
Inherited from site (v{@effective_snmp_version}, community: {@effective_snmp_community})
<% :organization -> %>
-
+
<.icon name="hero-building-office-2" class="h-4 w-4" />
Inherited from organization (v{@effective_snmp_version}, community: {@effective_snmp_community})
<% :default -> %>
-
+
<.icon name="hero-information-circle" class="h-4 w-4" />
Using default (v2c, no community set - configure at organization or site level)
@@ -246,9 +246,9 @@
<%= if @live_action == :edit do %>
-
+
Danger Zone
-
+
Once you delete this device, there is no going back. All monitoring history and alerts will be permanently deleted.
<.button
diff --git a/lib/towerops_web/live/device_live/index.html.heex b/lib/towerops_web/live/device_live/index.html.heex
index e1609aba..519b9ca8 100644
--- a/lib/towerops_web/live/device_live/index.html.heex
+++ b/lib/towerops_web/live/device_live/index.html.heex
@@ -32,15 +32,15 @@
<.icon
name="hero-building-office"
- class="mx-auto h-12 w-12 text-zinc-400 dark:text-zinc-600"
+ class="mx-auto h-12 w-12 text-gray-400 dark:text-gray-500"
/>
-
+
Create a site first
-
+
Before adding device, you need to create at least one site location.
-
+
Sites help you organize your devices by physical location.
@@ -52,9 +52,9 @@
<% else %>
<%= if @device == [] do %>
- <.icon name="hero-server" class="mx-auto h-12 w-12 text-zinc-400 dark:text-zinc-600" />
-
No devices
-
+ <.icon name="hero-server" class="mx-auto h-12 w-12 text-gray-400 dark:text-gray-500" />
+
No devices
+
Get started by adding your first device.
@@ -97,13 +97,13 @@
"bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200",
eq.status == :down && "bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200",
eq.status == :unknown &&
- "bg-zinc-100 text-zinc-800 dark:bg-zinc-800 dark:text-zinc-200"
+ "bg-gray-100 text-gray-800 dark:bg-gray-800 dark:text-gray-200"
]}>
{eq.status |> to_string() |> String.upcase()}
<:col :let={eq} label="Last Checked">
-
+
{ToweropsWeb.TimeHelpers.format_datetime(eq.last_checked_at, @timezone)}
diff --git a/lib/towerops_web/live/device_live/show.html.heex b/lib/towerops_web/live/device_live/show.html.heex
index ad6d7af4..42fa4b57 100644
--- a/lib/towerops_web/live/device_live/show.html.heex
+++ b/lib/towerops_web/live/device_live/show.html.heex
@@ -8,11 +8,11 @@