delete agent close
This commit is contained in:
+4
-5
@@ -72,12 +72,11 @@ async function request<T>(path: string, init?: RequestInit): Promise<T> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
let detail = "";
|
const raw = await res.text();
|
||||||
|
let detail = raw;
|
||||||
try {
|
try {
|
||||||
detail = JSON.stringify(await res.json(), null, 2);
|
detail = JSON.stringify(JSON.parse(raw), null, 2);
|
||||||
} catch {
|
} catch {}
|
||||||
detail = await res.text();
|
|
||||||
}
|
|
||||||
throw new Error(`${res.status} ${res.statusText}\n${detail}`);
|
throw new Error(`${res.status} ${res.statusText}\n${detail}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ pub enum ClientMessage {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
#[serde(tag = "type", rename_all = "snake_case")]
|
#[serde(tag = "type", rename_all = "snake_case")]
|
||||||
pub enum ServerMessage {
|
pub enum ServerMessage {
|
||||||
Command {
|
Command {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use uuid::Uuid;
|
|||||||
use wakey_agent::protocol::{AgentCommand, ErrorPayload, RequestId, ServerMessage};
|
use wakey_agent::protocol::{AgentCommand, ErrorPayload, RequestId, ServerMessage};
|
||||||
|
|
||||||
use crate::api::json_error;
|
use crate::api::json_error;
|
||||||
use crate::runtime::{AgentReply, AppState};
|
use crate::runtime::{AgentReply, AppState, SessionEvent};
|
||||||
use crate::state::AuditEventInput;
|
use crate::state::AuditEventInput;
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
@@ -114,10 +114,10 @@ pub async fn run_command(
|
|||||||
warn!(error = %err, "failed to append audit event for command dispatch");
|
warn!(error = %err, "failed to append audit event for command dispatch");
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Err(err) = tx.send(ServerMessage::Command {
|
if let Err(err) = tx.send(SessionEvent::Message(ServerMessage::Command {
|
||||||
request_id,
|
request_id,
|
||||||
command: req.command,
|
command: req.command,
|
||||||
}) {
|
})) {
|
||||||
state.pending.lock().await.remove(&request_id_string);
|
state.pending.lock().await.remove(&request_id_string);
|
||||||
warn!(error = %err, "failed sending command to agent session");
|
warn!(error = %err, "failed sending command to agent session");
|
||||||
if let Err(audit_err) = state
|
if let Err(audit_err) = state
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
use tracing::{info, warn};
|
use tracing::{info, warn};
|
||||||
|
|
||||||
use crate::api::json_error;
|
use crate::api::json_error;
|
||||||
use crate::runtime::AppState;
|
use crate::runtime::{AppState, SessionEvent};
|
||||||
use crate::state::AuditEventInput;
|
use crate::state::AuditEventInput;
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
@@ -288,8 +288,10 @@ pub async fn revoke_agent(
|
|||||||
match state.store.revoke_agent(&agent_id).await {
|
match state.store.revoke_agent(&agent_id).await {
|
||||||
Ok(revoked) => {
|
Ok(revoked) => {
|
||||||
if revoked {
|
if revoked {
|
||||||
// Remove any active session so this credential is also cut off at runtime.
|
// Request a graceful websocket close, then remove session from active map.
|
||||||
state.sessions.write().await.remove(&agent_id);
|
if let Some(session) = state.sessions.write().await.remove(&agent_id) {
|
||||||
|
let _ = session.tx.send(SessionEvent::Close);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Err(err) = state
|
if let Err(err) = state
|
||||||
@@ -318,7 +320,10 @@ pub async fn revoke_agent(
|
|||||||
warn!(error = %err, "failed to append audit event for agent revoke");
|
warn!(error = %err, "failed to append audit event for agent revoke");
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok((StatusCode::OK, Json(RevokeAgentResponse { agent_id, revoked })))
|
Ok((
|
||||||
|
StatusCode::OK,
|
||||||
|
Json(RevokeAgentResponse { agent_id, revoked }),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
warn!(error = %err, "failed to revoke agent credentials");
|
warn!(error = %err, "failed to revoke agent credentials");
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ use crate::ws;
|
|||||||
|
|
||||||
mod admin;
|
mod admin;
|
||||||
mod process;
|
mod process;
|
||||||
pub use admin::{issue_enroll_token, list_enroll_tokens, revoke_enroll_token, state_stats};
|
|
||||||
pub use admin::revoke_agent;
|
pub use admin::revoke_agent;
|
||||||
|
pub use admin::{issue_enroll_token, list_enroll_tokens, revoke_enroll_token, state_stats};
|
||||||
pub use process::reload_daemon;
|
pub use process::reload_daemon;
|
||||||
use process::{remove_pid_file, write_pid_file};
|
use process::{remove_pid_file, write_pid_file};
|
||||||
|
|
||||||
@@ -44,7 +44,12 @@ pub struct AppState {
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct AgentSession {
|
pub struct AgentSession {
|
||||||
pub connection_id: String,
|
pub connection_id: String,
|
||||||
pub tx: mpsc::UnboundedSender<ServerMessage>,
|
pub tx: mpsc::UnboundedSender<SessionEvent>,
|
||||||
|
}
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub enum SessionEvent {
|
||||||
|
Message(ServerMessage),
|
||||||
|
Close,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum AgentReply {
|
pub enum AgentReply {
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ use std::time::Instant;
|
|||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
use tracing::{debug, info, info_span, warn};
|
use tracing::{debug, info, info_span, warn};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use wakey_agent::protocol::{ErrorPayload, RequestId, ServerMessage};
|
use wakey_agent::protocol::{ErrorPayload, RequestId};
|
||||||
|
|
||||||
use crate::runtime::{AgentReply, AgentSession, AppState};
|
use crate::runtime::{AgentReply, AgentSession, AppState, SessionEvent};
|
||||||
use crate::state::AuditEventInput;
|
use crate::state::AuditEventInput;
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
@@ -48,20 +48,28 @@ async fn handle_agent_socket(state: AppState, socket: WebSocket) {
|
|||||||
let connected_at = Instant::now();
|
let connected_at = Instant::now();
|
||||||
|
|
||||||
let (mut write, mut read) = socket.split();
|
let (mut write, mut read) = socket.split();
|
||||||
let (tx, mut rx) = mpsc::unbounded_channel::<ServerMessage>();
|
let (tx, mut rx) = mpsc::unbounded_channel::<SessionEvent>();
|
||||||
|
|
||||||
let writer = tokio::spawn(async move {
|
let writer = tokio::spawn(async move {
|
||||||
while let Some(msg) = rx.recv().await {
|
while let Some(event) = rx.recv().await {
|
||||||
let encoded = match serde_json::to_string(&msg) {
|
match event {
|
||||||
Ok(s) => s,
|
SessionEvent::Close => {
|
||||||
Err(err) => {
|
let _ = write.send(Message::Close(None)).await;
|
||||||
warn!(error = %err, "failed to encode server websocket message");
|
break;
|
||||||
continue;
|
}
|
||||||
|
SessionEvent::Message(msg) => {
|
||||||
|
let encoded = match serde_json::to_string(&msg) {
|
||||||
|
Ok(s) => s,
|
||||||
|
Err(err) => {
|
||||||
|
warn!(error = %err, "failed to encode server websocket message");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if let Err(err) = write.send(Message::Text(encoded.into())).await {
|
||||||
|
warn!(error = %err, "failed to send websocket message");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
if let Err(err) = write.send(Message::Text(encoded.into())).await {
|
|
||||||
warn!(error = %err, "failed to send websocket message");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
debug!("websocket writer loop ended");
|
debug!("websocket writer loop ended");
|
||||||
@@ -148,7 +156,7 @@ async fn handle_agent_socket(state: AppState, socket: WebSocket) {
|
|||||||
|
|
||||||
async fn process_agent_text(
|
async fn process_agent_text(
|
||||||
state: &AppState,
|
state: &AppState,
|
||||||
tx: &mpsc::UnboundedSender<ServerMessage>,
|
tx: &mpsc::UnboundedSender<SessionEvent>,
|
||||||
connection_id: &str,
|
connection_id: &str,
|
||||||
authed_agent_id: &mut Option<String>,
|
authed_agent_id: &mut Option<String>,
|
||||||
hello_at: &mut Option<Instant>,
|
hello_at: &mut Option<Instant>,
|
||||||
|
|||||||
Reference in New Issue
Block a user