Add UI forms for hierarchical SNMP configuration

Adds forms to organization, site, and equipment pages to configure SNMP
community strings with hierarchical fallback.

Changes:
- Organization settings: Add SNMP version and community fields
- Site form: Add SNMP config section with inheritance notice
- Equipment form: Update SNMP fields to show inheritance source and effective values

The UI now shows:
- Where the SNMP config is coming from (equipment, site, organization, or default)
- What the effective values are when inheriting
- Visual indicators for overrides vs inheritance

All forms use the Equipment.get_snmp_config/1 function for consistent
hierarchical resolution.
This commit is contained in:
Graham McIntire 2026-01-17 11:49:31 -06:00
parent ba1e8933e4
commit 60b97136c7
No known key found for this signature in database
4 changed files with 82 additions and 3 deletions

View file

@ -98,12 +98,18 @@ defmodule ToweropsWeb.EquipmentLive.Form do
equipment_with_agent = Map.put(equipment, :agent_token_id, agent_token_id)
changeset = Equipment.change_equipment(equipment, %{})
# Get effective SNMP configuration and source
snmp_config = Equipment.get_snmp_config(equipment)
socket
|> assign(:page_title, "Edit Equipment")
|> assign(:equipment, equipment_with_agent)
|> assign(:form, to_form(changeset))
|> assign(:agent_source, agent_source)
|> assign(:effective_agent_name, effective_agent_name)
|> assign(:snmp_config_source, snmp_config.source)
|> assign(:effective_snmp_version, snmp_config.version)
|> assign(:effective_snmp_community, snmp_config.community || "(not set)")
end
@impl true

View file

@ -107,8 +107,7 @@
field={@form[:snmp_version]}
type="select"
label="SNMP Version"
required
value={@form[:snmp_version].value || "2c"}
prompt="Inherit from site/organization"
options={[{"SNMPv1", "1"}, {"SNMPv2c", "2c"}]}
/>
@ -116,10 +115,35 @@
field={@form[:snmp_community]}
type="text"
label="Community String"
required
placeholder="Leave blank to inherit from site/organization"
autocomplete="off"
/>
<%= if @live_action == :edit and Map.has_key?(assigns, :snmp_config_source) do %>
<%= case @snmp_config_source do %>
<% :equipment -> %>
<p class="text-sm text-amber-600 dark:text-amber-400 flex items-center gap-1">
<.icon name="hero-exclamation-triangle" class="h-4 w-4" />
<strong>Overriding</strong> site/organization SNMP defaults
</p>
<% :site -> %>
<p class="text-sm text-zinc-600 dark:text-zinc-400 flex items-center gap-1">
<.icon name="hero-building-office" class="h-4 w-4" />
Inherited from site (v{@effective_snmp_version}, community: {@effective_snmp_community})
</p>
<% :organization -> %>
<p class="text-sm text-zinc-600 dark:text-zinc-400 flex items-center gap-1">
<.icon name="hero-building-office-2" class="h-4 w-4" />
Inherited from organization (v{@effective_snmp_version}, community: {@effective_snmp_community})
</p>
<% :default -> %>
<p class="text-sm text-zinc-600 dark:text-zinc-400 flex items-center gap-1">
<.icon name="hero-information-circle" class="h-4 w-4" />
Using default (v2c, no community set - configure at organization or site level)
</p>
<% end %>
<% end %>
<.input
field={@form[:snmp_port]}
type="number"

View file

@ -23,6 +23,33 @@
<.form for={@form} id="organization-form" phx-change="validate" phx-submit="save">
<.input field={@form[:name]} type="text" label="Organization Name" required />
<div class="mt-6 border-t pt-6">
<h3 class="text-lg font-medium mb-4">SNMP Configuration</h3>
<p class="text-sm text-zinc-600 dark:text-zinc-400 mb-4">
Set default SNMP settings for all devices in this organization. These can be overridden at the site or equipment level.
</p>
<.input
field={@form[:snmp_version]}
type="select"
label="SNMP Version"
prompt="Select SNMP version"
options={[{"SNMP v1", "1"}, {"SNMP v2c", "2c"}, {"SNMP v3", "3"}]}
/>
<.input
field={@form[:snmp_community]}
type="text"
label="SNMP Community String"
placeholder="e.g., public"
/>
<p class="mt-3 text-sm text-zinc-500 dark:text-zinc-400 italic">
<.icon name="hero-information-circle" class="h-4 w-4 inline" />
SNMP configuration hierarchy: Equipment > Site > Organization
</p>
</div>
<%= if @available_agents != [] do %>
<div class="mt-6 border-t pt-6">
<h3 class="text-lg font-medium mb-4">Default Agent</h3>

View file

@ -68,6 +68,28 @@
<% end %>
<% end %>
<div class="mt-6 border-t pt-6">
<h3 class="text-base font-medium mb-4">SNMP Configuration (Optional)</h3>
<p class="text-sm text-zinc-600 dark:text-zinc-400 mb-4">
Override organization SNMP defaults for all equipment at this site. Leave blank to inherit from organization.
</p>
<.input
field={@form[:snmp_version]}
type="select"
label="SNMP Version"
prompt="Inherit from organization"
options={[{"SNMP v1", "1"}, {"SNMP v2c", "2c"}, {"SNMP v3", "3"}]}
/>
<.input
field={@form[:snmp_community]}
type="text"
label="SNMP Community String"
placeholder="Leave blank to inherit from organization"
/>
</div>
<.input field={@form[:description]} type="textarea" label="Description" />
<div class="flex gap-3 mt-6">