1pub mod certificates;
2pub mod context;
3
4use context::CommonContext;
5use hightower_client::HightowerConnection;
6use tracing::{debug, error};
7
8const GATEWAY_URL_KEY: &[u8] = b"gateway/url";
9
10pub async fn run(context: &CommonContext) -> Result<HightowerConnection, String> {
11 let gateway_url = context
13 .kv
14 .get_bytes(GATEWAY_URL_KEY)
15 .ok()
16 .flatten()
17 .and_then(|bytes| String::from_utf8(bytes).ok())
18 .unwrap_or_else(|| "http://127.0.0.1:8008".to_string());
19
20 let auth_token = context
22 .kv
23 .get_bytes(context::HT_AUTH_KEY)
24 .map_err(|e| format!("Failed to get auth token: {:?}", e))?
25 .ok_or_else(|| "Auth token not found in context".to_string())?;
26
27 let auth_token = String::from_utf8(auth_token)
28 .map_err(|e| format!("Invalid auth token encoding: {:?}", e))?;
29
30 debug!(gateway_url = %gateway_url, "Connecting to gateway");
31
32 let connection = HightowerConnection::connect(&gateway_url, &auth_token)
40 .await
41 .map_err(|e| {
42 error!(error = ?e, "Failed to connect to gateway");
43 format!("Failed to connect to gateway: {:?}", e)
44 })?;
45
46 debug!(
47 node_id = %connection.node_id(),
48 assigned_ip = %connection.assigned_ip(),
49 "Connected to gateway"
50 );
51
52 if let Err(e) = connection.ping_gateway().await {
54 error!(error = ?e, "Failed to ping gateway over WireGuard");
55 } else {
56 debug!("Successfully pinged gateway over WireGuard");
57 }
58
59 Ok(connection)
60}
61
62pub async fn deregister(connection: HightowerConnection) -> Result<(), String> {
63 connection
64 .disconnect()
65 .await
66 .map_err(|e| format!("Failed to disconnect: {:?}", e))
67}
68
69#[cfg(test)]
70mod tests {
71 use super::*;
72 use context::fixtures;
73
74 #[tokio::test]
75 async fn run_connects_to_gateway() {
76 let ctx = fixtures::context();
77 ctx.kv.put_secret(context::HT_AUTH_KEY, b"test-auth-key");
78
79 match run(&ctx).await {
82 Ok(connection) => {
83 assert!(!connection.node_id().is_empty());
84 assert!(!connection.assigned_ip().is_empty());
85
86 let _ = deregister(connection).await;
88 }
89 Err(e) => {
90 assert!(e.contains("Failed to connect"));
92 }
93 }
94 }
95}