Change WireGuard keys -> configs
Setting up the WireGuard client requires several pieces of information, beyond the node private key and peer's public key. The peer endpoint address/port, peer public key, and node IP address are also required. As such, naming the resource a "key" is somewhat misleading.master
parent
3916e0eac9
commit
3f17373624
|
@ -6,7 +6,7 @@
|
|||
use log::{debug, error};
|
||||
|
||||
use crate::k8s::{
|
||||
assign_wireguard_key, create_bootstrap_token, unassign_wireguard_key,
|
||||
assign_wireguard_config, create_bootstrap_token, unassign_wireguard_config,
|
||||
};
|
||||
use crate::model::events::*;
|
||||
|
||||
|
@ -16,18 +16,18 @@ use crate::model::events::*;
|
|||
/// associated with ephemeral nodes running as EC2 instances.
|
||||
///
|
||||
/// When an instance starts:
|
||||
/// 1. A WireGuard key is assigned to the instance
|
||||
/// 1. A WireGuard config is assigned to the instance
|
||||
/// 2. A Kubernetes bootstrap token is generated, to be used by `kubeadm` to
|
||||
/// add the node to the cluster.
|
||||
///
|
||||
/// When an instance is terminated:
|
||||
/// 1. Any WireGuard keys assigned to the instance are unassigned
|
||||
/// 1. Any WireGuard configs assigned to the instance are unassigned
|
||||
pub async fn on_ec2_instance_state_change(evt: Ec2InstanceStateChange) {
|
||||
debug!("EC2 instance {} is now {}", &evt.instance_id, &evt.state);
|
||||
if evt.state == "running" {
|
||||
if let Err(e) = assign_wireguard_key(&evt.instance_id).await {
|
||||
if let Err(e) = assign_wireguard_config(&evt.instance_id).await {
|
||||
error!(
|
||||
"Failed to assign WireGuard key to instnce {}: {}",
|
||||
"Failed to assign WireGuard config to instnce {}: {}",
|
||||
&evt.instance_id, e
|
||||
);
|
||||
return;
|
||||
|
@ -39,9 +39,9 @@ pub async fn on_ec2_instance_state_change(evt: Ec2InstanceStateChange) {
|
|||
)
|
||||
};
|
||||
} else if evt.state == "terminated" {
|
||||
if let Err(e) = unassign_wireguard_key(&evt.instance_id).await {
|
||||
if let Err(e) = unassign_wireguard_config(&evt.instance_id).await {
|
||||
error!(
|
||||
"Failed to unassign WireGuard key from instance: {}: {}",
|
||||
"Failed to unassign WireGuard config from instance: {}: {}",
|
||||
&evt.instance_id, e
|
||||
);
|
||||
}
|
||||
|
|
57
src/k8s.rs
57
src/k8s.rs
|
@ -157,40 +157,48 @@ impl Into<Secret> for BootstrapToken {
|
|||
}
|
||||
}
|
||||
|
||||
/// Assign an existing WireGuard key to the specified EC2 instance
|
||||
/// Assign an existing WireGuard configuration to the specified EC2 instance
|
||||
///
|
||||
/// This function finds the first unused WireGuard key, stored as a Kubernetes
|
||||
/// Secret resource, and assigns it to the specified EC2 instance. Keys are
|
||||
/// assigned by setting the `dynk8s.du5t1n.me/ec2-instance-id` label in the
|
||||
/// Secret resource's metadata.
|
||||
/// This function finds the first unused WireGuard client configuration, stored
|
||||
/// as a Kubernetes Secret resource, and assigns it to the specified EC2
|
||||
/// instance. Configs are assigned by setting the
|
||||
/// `dynk8s.du5t1n.me/ec2-instance-id` label in the Secret resource's metadata.
|
||||
///
|
||||
/// Secret resources for WireGuard keys have a *type* of
|
||||
/// `dynk8s.du5t1n.me/wireguard-key`. They must be created ahead of time and
|
||||
/// must refer to working keys already configured on the WireGuard server.
|
||||
pub async fn assign_wireguard_key(
|
||||
/// Secret resources for WireGuard configuration have a *type* of
|
||||
/// `dynk8s.du5t1n.me/wireguard-config`. The Secret's `data` field must
|
||||
/// contain a `wireguard-config` property, which contains the WireGuard client
|
||||
/// configuration the node should use. Configs must be created ahead of time
|
||||
/// and must refer to working keys already configured on the WireGuard server.
|
||||
pub async fn assign_wireguard_config(
|
||||
instance_id: &str,
|
||||
) -> Result<(), kube::Error> {
|
||||
let client = Client::try_default().await?;
|
||||
let secrets: Api<Secret> = Api::default_namespaced(client);
|
||||
debug!(
|
||||
"Checking for WireGuard keys already assigned to instance {}",
|
||||
"Checking for WireGuard configs already assigned to instance {}",
|
||||
instance_id
|
||||
);
|
||||
let lp = ListParams::default()
|
||||
.fields("type=dynk8s.du5t1n.me/wireguard-key")
|
||||
.fields("type=dynk8s.du5t1n.me/wireguard-config")
|
||||
.labels(&format!("dynk8s.du5t1n.me/ec2-instance-id={}", instance_id));
|
||||
let res = secrets.list(&lp).await?;
|
||||
if !res.items.is_empty() {
|
||||
info!("WireGuard key already assigned to instance {}", instance_id);
|
||||
info!(
|
||||
"WireGuard config already assigned to instance {}",
|
||||
instance_id
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
debug!("Looking for available WireGuard keys");
|
||||
debug!("Looking for available WireGuard configs");
|
||||
let lp = ListParams::default()
|
||||
.fields("type=dynk8s.du5t1n.me/wireguard-key")
|
||||
.fields("type=dynk8s.du5t1n.me/wireguard-config")
|
||||
.labels("dynk8s.du5t1n.me/ec2-instance-id=");
|
||||
let res = secrets.list(&lp).await?;
|
||||
if res.items.is_empty() {
|
||||
error!("No WireGuard keys available for instance {}", &instance_id);
|
||||
error!(
|
||||
"No WireGuard config available for instance {}",
|
||||
&instance_id
|
||||
);
|
||||
} else {
|
||||
if let Some(name) = &res.items[0].metadata.name {
|
||||
let mut labels = BTreeMap::<String, String>::new();
|
||||
|
@ -204,7 +212,7 @@ pub async fn assign_wireguard_key(
|
|||
let pp = PatchParams::apply(env!("CARGO_PKG_NAME")).force();
|
||||
secrets.patch(&name, &pp, &patch).await?;
|
||||
info!(
|
||||
"Assigned WireGuard key {} to instance {}",
|
||||
"Assigned WireGuard config {} to instance {}",
|
||||
name, &instance_id
|
||||
);
|
||||
}
|
||||
|
@ -212,21 +220,24 @@ pub async fn assign_wireguard_key(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Unassign all WireGuard keys from the specified EC2 instance
|
||||
/// Unassign all WireGuard configs from the specified EC2 instance
|
||||
///
|
||||
/// This function finds all WireGuard keys, stored as Kubernetes Secret
|
||||
/// This function finds all WireGuard configs, stored as Kubernetes Secret
|
||||
/// resources, associated with the specified EC2 instance and unassigns them.
|
||||
/// Unassigned keys have the `dynk8s.du5t1n.me/ec2-instance-id` label set to
|
||||
/// Unassigned configs have the `dynk8s.du5t1n.me/ec2-instance-id` label set to
|
||||
/// the empty string.
|
||||
pub async fn unassign_wireguard_key(
|
||||
pub async fn unassign_wireguard_config(
|
||||
instance_id: &str,
|
||||
) -> Result<(), 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-key")
|
||||
.fields("type=dynk8s.du5t1n.me/wireguard-config")
|
||||
.labels(&format!("dynk8s.du5t1n.me/ec2-instance-id={}", instance_id));
|
||||
info!("Unassigning WireGuard keys from instance {}", instance_id);
|
||||
info!(
|
||||
"Unassigning WireGuard configs from instance {}",
|
||||
instance_id
|
||||
);
|
||||
for s in secrets.list(&lp).await? {
|
||||
if let Some(name) = &s.metadata.name {
|
||||
let mut labels = BTreeMap::<String, String>::new();
|
||||
|
@ -238,7 +249,7 @@ pub async fn unassign_wireguard_key(
|
|||
let pp = PatchParams::apply(env!("CARGO_PKG_NAME")).force();
|
||||
secrets.patch(&name, &pp, &patch).await?;
|
||||
info!(
|
||||
"Unassigned WireGuard key {} from instance {}",
|
||||
"Unassigned WireGuard config {} from instance {}",
|
||||
name, &instance_id
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue