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
Dustin 2022-10-02 11:57:33 -05:00
parent 3916e0eac9
commit 3f17373624
2 changed files with 41 additions and 30 deletions

View File

@ -6,7 +6,7 @@
use log::{debug, error}; use log::{debug, error};
use crate::k8s::{ 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::*; use crate::model::events::*;
@ -16,18 +16,18 @@ use crate::model::events::*;
/// associated with ephemeral nodes running as EC2 instances. /// associated with ephemeral nodes running as EC2 instances.
/// ///
/// When an instance starts: /// 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 /// 2. A Kubernetes bootstrap token is generated, to be used by `kubeadm` to
/// add the node to the cluster. /// add the node to the cluster.
/// ///
/// When an instance is terminated: /// 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) { pub async fn on_ec2_instance_state_change(evt: Ec2InstanceStateChange) {
debug!("EC2 instance {} is now {}", &evt.instance_id, &evt.state); debug!("EC2 instance {} is now {}", &evt.instance_id, &evt.state);
if evt.state == "running" { 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!( error!(
"Failed to assign WireGuard key to instnce {}: {}", "Failed to assign WireGuard config to instnce {}: {}",
&evt.instance_id, e &evt.instance_id, e
); );
return; return;
@ -39,9 +39,9 @@ pub async fn on_ec2_instance_state_change(evt: Ec2InstanceStateChange) {
) )
}; };
} else if evt.state == "terminated" { } 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!( error!(
"Failed to unassign WireGuard key from instance: {}: {}", "Failed to unassign WireGuard config from instance: {}: {}",
&evt.instance_id, e &evt.instance_id, e
); );
} }

View File

@ -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 /// This function finds the first unused WireGuard client configuration, stored
/// Secret resource, and assigns it to the specified EC2 instance. Keys are /// as a Kubernetes Secret resource, and assigns it to the specified EC2
/// assigned by setting the `dynk8s.du5t1n.me/ec2-instance-id` label in the /// instance. Configs are assigned by setting the
/// Secret resource's metadata. /// `dynk8s.du5t1n.me/ec2-instance-id` label in the Secret resource's metadata.
/// ///
/// Secret resources for WireGuard keys have a *type* of /// Secret resources for WireGuard configuration have a *type* of
/// `dynk8s.du5t1n.me/wireguard-key`. They must be created ahead of time and /// `dynk8s.du5t1n.me/wireguard-config`. The Secret's `data` field must
/// must refer to working keys already configured on the WireGuard server. /// contain a `wireguard-config` property, which contains the WireGuard client
pub async fn assign_wireguard_key( /// 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, instance_id: &str,
) -> Result<(), kube::Error> { ) -> Result<(), kube::Error> {
let client = Client::try_default().await?; let client = Client::try_default().await?;
let secrets: Api<Secret> = Api::default_namespaced(client); let secrets: Api<Secret> = Api::default_namespaced(client);
debug!( debug!(
"Checking for WireGuard keys already assigned to instance {}", "Checking for WireGuard configs already assigned to instance {}",
instance_id instance_id
); );
let lp = ListParams::default() 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)); .labels(&format!("dynk8s.du5t1n.me/ec2-instance-id={}", instance_id));
let res = secrets.list(&lp).await?; let res = secrets.list(&lp).await?;
if !res.items.is_empty() { 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(()); return Ok(());
} }
debug!("Looking for available WireGuard keys"); debug!("Looking for available WireGuard configs");
let lp = ListParams::default() 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="); .labels("dynk8s.du5t1n.me/ec2-instance-id=");
let res = secrets.list(&lp).await?; let res = secrets.list(&lp).await?;
if res.items.is_empty() { if res.items.is_empty() {
error!("No WireGuard keys available for instance {}", &instance_id); error!(
"No WireGuard config available for instance {}",
&instance_id
);
} else { } else {
if let Some(name) = &res.items[0].metadata.name { if let Some(name) = &res.items[0].metadata.name {
let mut labels = BTreeMap::<String, String>::new(); 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(); let pp = PatchParams::apply(env!("CARGO_PKG_NAME")).force();
secrets.patch(&name, &pp, &patch).await?; secrets.patch(&name, &pp, &patch).await?;
info!( info!(
"Assigned WireGuard key {} to instance {}", "Assigned WireGuard config {} to instance {}",
name, &instance_id name, &instance_id
); );
} }
@ -212,21 +220,24 @@ pub async fn assign_wireguard_key(
Ok(()) 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. /// 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. /// the empty string.
pub async fn unassign_wireguard_key( pub async fn unassign_wireguard_config(
instance_id: &str, instance_id: &str,
) -> Result<(), kube::Error> { ) -> Result<(), kube::Error> {
let client = Client::try_default().await?; let client = Client::try_default().await?;
let secrets: Api<Secret> = Api::default_namespaced(client); let secrets: Api<Secret> = Api::default_namespaced(client);
let lp = ListParams::default() 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)); .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? { for s in secrets.list(&lp).await? {
if let Some(name) = &s.metadata.name { if let Some(name) = &s.metadata.name {
let mut labels = BTreeMap::<String, String>::new(); 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(); let pp = PatchParams::apply(env!("CARGO_PKG_NAME")).force();
secrets.patch(&name, &pp, &patch).await?; secrets.patch(&name, &pp, &patch).await?;
info!( info!(
"Unassigned WireGuard key {} from instance {}", "Unassigned WireGuard config {} from instance {}",
name, &instance_id name, &instance_id
); );
} }