From 3e3904cd4fc402b1dd0ae160dc385f768d22c7bb Mon Sep 17 00:00:00 2001 From: "Dustin C. Hatch" Date: Sun, 2 Oct 2022 17:58:44 -0500 Subject: [PATCH] events: Delete bootstrap tokens on termination When an instance is terminated, any bootstrap tokens assigned to it are now deleted. Though these would expire anyway, deleting them ensures that they cannot be used again if they happened to be leaked while the instance was running. Further, it ensures that attempting to fetch the `kubeadm` configuration for the instance will return an HTTP 404 Not Found response once the instance has terminated. --- src/events.rs | 10 +++++++++- src/k8s.rs | 15 +++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/events.rs b/src/events.rs index feee1fc..72d869d 100644 --- a/src/events.rs +++ b/src/events.rs @@ -6,7 +6,8 @@ use log::{debug, error}; use crate::k8s::{ - assign_wireguard_config, create_bootstrap_token, unassign_wireguard_config, + assign_wireguard_config, create_bootstrap_token, delete_bootstrap_tokens, + unassign_wireguard_config, }; use crate::model::events::*; @@ -22,6 +23,7 @@ use crate::model::events::*; /// /// When an instance is terminated: /// 1. Any WireGuard configs assigned to the instance are unassigned +/// 2. All bootstrap tokens for the instance are deleted pub async fn on_ec2_instance_state_change(evt: Ec2InstanceStateChange) { debug!("EC2 instance {} is now {}", &evt.instance_id, &evt.state); if evt.state == "running" { @@ -45,5 +47,11 @@ pub async fn on_ec2_instance_state_change(evt: Ec2InstanceStateChange) { &evt.instance_id, e ); } + if let Err(e) = delete_bootstrap_tokens(&evt.instance_id).await { + error!( + "Failed to delete bootstrap tokens for instance {}: {}", + &evt.instance_id, e + ); + } } } diff --git a/src/k8s.rs b/src/k8s.rs index b9fd111..ed1bf5f 100644 --- a/src/k8s.rs +++ b/src/k8s.rs @@ -314,6 +314,21 @@ pub async fn create_bootstrap_token>( Ok(()) } +/// Delete bootstrap tokens associated withthe specified EC2 instance +pub async fn delete_bootstrap_tokens>( + instance_id: I, +) -> Result<(), kube::Error> { + let instance_id = instance_id.as_ref(); + info!("Deleting bootstrap tokens for instance {}", &instance_id); + let client = Client::try_default().await?; + let secrets: Api = Api::namespaced(client, "kube-system"); + let lp = ListParams::default() + .fields("type=bootstrap.kubernetes.io/token") + .labels(&format!("dynk8s.du5t1n.me/ec2-instance-id={}", &instance_id)); + secrets.delete_collection(&Default::default(), &lp).await?; + Ok(()) +} + /// Get the `kubeadm join` configuration for the specified EC2 instance /// /// This function creates a kubeconfig file that can be passed to `kubeadm