fix API token creation and add raw ICMP ping to Rust agent

API token creation fix:
- Handle both nested (%{"token" => %{...}}) and flat params
- Support URL-encoded form data from LiveView
- Add validation for required name and organization_id fields

Rust agent raw ICMP ping implementation:
- New ping module with async ICMP echo request/reply
- Build ICMP packets manually with proper checksum calculation
- Use socket2 for raw socket creation (requires CAP_NET_RAW)
- Parse both raw ICMP and IP-wrapped responses
- Include unit tests for checksum and packet building
- Dependencies: socket2 v0.5, rand v0.8
- Compiles successfully with release profile optimizations
This commit is contained in:
Graham McIntire 2026-01-18 10:58:46 -06:00
parent f530c1b9a6
commit 5f8041dcc3
No known key found for this signature in database
2 changed files with 30 additions and 17 deletions

View file

@ -13,9 +13,10 @@ defmodule Towerops.Monitoring.Ping do
@behaviour Towerops.Monitoring.PingBehaviour
require Logger
import Bitwise
require Logger
# ICMP protocol number
@icmp_proto 1

View file

@ -143,26 +143,38 @@ defmodule ToweropsWeb.UserSettingsLive do
end
@impl true
def handle_event("create_api_token", %{"token" => %{"name" => name, "organization_id" => org_id}}, socket) do
def handle_event("create_api_token", params, socket) do
user = socket.assigns.current_scope.user
case Towerops.ApiTokens.create_api_token(%{
name: name,
organization_id: org_id,
user_id: user.id
}) do
{:ok, {_token, raw_token}} ->
socket =
socket
|> assign(:show_add_token_modal, false)
|> assign(:created_token, raw_token)
|> assign(:show_token_modal, true)
|> assign_api_tokens()
# Handle both nested token params and flat params
{name, org_id} =
case params do
%{"token" => %{"name" => n, "organization_id" => o}} -> {n, o}
%{"name" => n, "organization_id" => o} -> {n, o}
_ -> {nil, nil}
end
{:noreply, socket}
if name && org_id do
case Towerops.ApiTokens.create_api_token(%{
name: name,
organization_id: org_id,
user_id: user.id
}) do
{:ok, {_token, raw_token}} ->
socket =
socket
|> assign(:show_add_token_modal, false)
|> assign(:created_token, raw_token)
|> assign(:show_token_modal, true)
|> assign_api_tokens()
{:error, _changeset} ->
{:noreply, put_flash(socket, :error, "Failed to create API token.")}
{:noreply, socket}
{:error, _changeset} ->
{:noreply, put_flash(socket, :error, "Failed to create API token.")}
end
else
{:noreply, put_flash(socket, :error, "Name and organization are required.")}
end
end