Private
Public Access
1
0

feat: add host editing endpoint and frontend UI
All checks were successful
CI Pipeline / Rust Format Check (push) Successful in 3s
CI Pipeline / Clippy Lints (push) Successful in 53s
CI Pipeline / Rust Unit Tests (push) Successful in 1m12s
CI Pipeline / Security Audit (push) Successful in 4s
CI Pipeline / Frontend Lint & Type Check (push) Successful in 14s
CI Pipeline / Build .deb & Release (push) Successful in 3m51s

This commit is contained in:
2026-05-18 21:52:00 +00:00
parent b3ae42215b
commit f70c5e53f9
26 changed files with 254 additions and 65 deletions

View File

@ -97,6 +97,7 @@ impl AuditAction {
/// Computes a hash chain entry using the previous row's hash.
/// Non-fatal: logs errors but does not propagate them to avoid
/// disrupting the primary operation.
#[allow(clippy::too_many_arguments)]
pub async fn log_event(
pool: &PgPool,
action: AuditAction,
@ -126,6 +127,7 @@ pub async fn log_event(
}
}
#[allow(clippy::too_many_arguments)]
async fn write_audit_row(
pool: &PgPool,
action: AuditAction,

View File

@ -29,7 +29,7 @@ pub fn load_or_create_key(path: &Path) -> Result<[u8; 32], CryptoError> {
if let Some(parent) = path.parent() {
fs::create_dir_all(parent).map_err(CryptoError::Io)?;
}
fs::write(path, &key).map_err(CryptoError::Io)?;
fs::write(path, key).map_err(CryptoError::Io)?;
// Set permissions to 0600 (owner read/write only)
#[cfg(unix)]
{

View File

@ -72,9 +72,9 @@ pub async fn create_enrollment_request(
EnrollmentRequest,
>(
r#"
INSERT INTO enrollment_requests (machine_id, fqdn, ip_address, os_details, polling_token)
VALUES ($1, $2, $3::inet, $4, $5)
RETURNING id, machine_id, fqdn, ip_address::text, os_details, polling_token, created_at, expires_at
INSERT INTO enrollment_requests (machine_id, fqdn, ip_address, os_details, polling_token, hostname)
VALUES ($1, $2, $3::inet, $4, $5, $6)
RETURNING id, machine_id, fqdn, ip_address::text, os_details, polling_token, hostname, created_at, expires_at
"#,
)
.bind(req.machine_id)
@ -82,6 +82,7 @@ pub async fn create_enrollment_request(
.bind(req.ip_address)
.bind(req.os_details)
.bind(token_hash)
.bind(&req.hostname)
.fetch_one(pool)
.await
}
@ -90,7 +91,7 @@ pub async fn list_enrollment_requests(
pool: &PgPool,
) -> Result<Vec<EnrollmentRequest>, sqlx::Error> {
sqlx::query_as::<_, EnrollmentRequest>(
"SELECT id, machine_id, fqdn, ip_address::text, os_details, polling_token, created_at, expires_at FROM enrollment_requests ORDER BY created_at DESC",
"SELECT id, machine_id, fqdn, ip_address::text, os_details, polling_token, hostname, created_at, expires_at FROM enrollment_requests ORDER BY created_at DESC",
)
.fetch_all(pool)
.await

View File

@ -107,6 +107,14 @@ pub struct CreateHostRequest {
pub group_ids: Option<Vec<Uuid>>,
}
/// Payload for updating an existing host.
#[derive(Debug, Deserialize)]
pub struct UpdateHostRequest {
pub fqdn: Option<String>,
pub ip_address: Option<String>,
pub display_name: Option<String>,
}
/// Host list item (lighter projection for list views)
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct HostSummary {
@ -135,6 +143,8 @@ pub struct EnrollmentRequest {
pub ip_address: String,
pub os_details: serde_json::Value,
pub polling_token: String,
/// Short hostname provided during enrollment (optional).
pub hostname: Option<String>,
pub created_at: DateTime<Utc>,
pub expires_at: DateTime<Utc>,
}
@ -146,6 +156,8 @@ pub struct CreateEnrollmentRequest {
pub fqdn: String,
pub ip_address: String,
pub os_details: serde_json::Value,
/// Short hostname (from /etc/hostname, optional).
pub hostname: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]