routes: Add WireGuard configuration resource
The * GET /wireguard/config/<instance-id>* resource returns the WireGuard client configuration assigned to the specified instance ID. The resource contents are stored in the Kubernetes Secret, in a data field named `wireguard-config`. The contents of this field are returned directly as a string, without any transformation. Thus, the value must be a complete, valid WireGuard configuration document. Instances will fetch and save this configuration when they first launch, to configure their access to the VPN.master
parent
3f17373624
commit
25524d5290
36
src/k8s.rs
36
src/k8s.rs
|
@ -257,6 +257,42 @@ pub async fn unassign_wireguard_config(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Retrieve the WireGuard config assigned to the specified EC2 instance
|
||||||
|
///
|
||||||
|
/// This function finds the first WireGuard client configuration, stored as a
|
||||||
|
/// Kubernetes Secret resource, associated with the specified EC2 instance.
|
||||||
|
///
|
||||||
|
/// If multiple WireGuard configs are assigned to an EC2 instance, only the
|
||||||
|
/// first one returned by the Kubernetes list query is returned.
|
||||||
|
pub async fn get_wireguard_config(
|
||||||
|
instance_id: &str,
|
||||||
|
) -> Result<Option<String>, kube::Error> {
|
||||||
|
let client = Client::try_default().await?;
|
||||||
|
let secrets: Api<Secret> = Api::default_namespaced(client);
|
||||||
|
let lp = ListParams::default()
|
||||||
|
.fields("type=dynk8s.du5t1n.me/wireguard-config")
|
||||||
|
.labels(&format!("dynk8s.du5t1n.me/ec2-instance-id={}", instance_id));
|
||||||
|
for s in secrets.list(&lp).await? {
|
||||||
|
if let Some(data) = s.data {
|
||||||
|
match data.get("wireguard-config") {
|
||||||
|
Some(s) => match String::from_utf8(s.0.clone()) {
|
||||||
|
Ok(s) => return Ok(Some(s)),
|
||||||
|
Err(e) => {
|
||||||
|
error!("Invalid WireGuard configuration: {}", e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
error!(concat!(
|
||||||
|
"Invalid WireGuard configuration: ",
|
||||||
|
"missing wireguard-config property"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
|
||||||
/// Generate and store a bootstrap token for the specified EC2 instance
|
/// Generate and store a bootstrap token for the specified EC2 instance
|
||||||
///
|
///
|
||||||
/// This function generates a new bootstrap token and stores it as a Kubernetes
|
/// This function generates a new bootstrap token and stores it as a Kubernetes
|
||||||
|
|
|
@ -12,6 +12,7 @@ fn rocket() -> _ {
|
||||||
"/",
|
"/",
|
||||||
rocket::routes![
|
rocket::routes![
|
||||||
routes::health::get_health,
|
routes::health::get_health,
|
||||||
|
routes::wireguard::get_node_wireguard,
|
||||||
routes::sns::post_sns_notify,
|
routes::sns::post_sns_notify,
|
||||||
routes::sns::get_sns_notify,
|
routes::sns::get_sns_notify,
|
||||||
routes::sns::put_sns_notify,
|
routes::sns::put_sns_notify,
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
//! Rocket route handlers
|
//! Rocket route handlers
|
||||||
pub mod health;
|
pub mod health;
|
||||||
pub mod sns;
|
pub mod sns;
|
||||||
|
pub mod wireguard;
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
use crate::k8s::get_wireguard_config;
|
||||||
|
|
||||||
|
#[rocket::get("/wireguard/config/<instance_id>")]
|
||||||
|
pub async fn get_node_wireguard(instance_id: String) -> Option<String> {
|
||||||
|
if let Ok(Some(token)) = get_wireguard_config(&instance_id).await {
|
||||||
|
Some(token)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
use crate::rocket;
|
||||||
|
use rocket::http::Status;
|
||||||
|
use rocket::local::blocking::Client;
|
||||||
|
use rocket::uri;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_get_node_wireguard_404() {
|
||||||
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
|
let res = client
|
||||||
|
.get(uri!(get_node_wireguard(
|
||||||
|
instance_id = "i-0a1b2c3d4e5f6f7f8"
|
||||||
|
)))
|
||||||
|
.dispatch();
|
||||||
|
assert_eq!(res.status(), Status::NotFound);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue