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.
master
Dustin 2022-10-02 17:58:44 -05:00
parent df39fe46eb
commit 3e3904cd4f
2 changed files with 24 additions and 1 deletions

View File

@ -6,7 +6,8 @@
use log::{debug, error}; use log::{debug, error};
use crate::k8s::{ 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::*; use crate::model::events::*;
@ -22,6 +23,7 @@ use crate::model::events::*;
/// ///
/// When an instance is terminated: /// When an instance is terminated:
/// 1. Any WireGuard configs assigned to the instance are unassigned /// 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) { 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" {
@ -45,5 +47,11 @@ pub async fn on_ec2_instance_state_change(evt: Ec2InstanceStateChange) {
&evt.instance_id, e &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
);
}
} }
} }

View File

@ -314,6 +314,21 @@ pub async fn create_bootstrap_token<I: AsRef<str>>(
Ok(()) Ok(())
} }
/// Delete bootstrap tokens associated withthe specified EC2 instance
pub async fn delete_bootstrap_tokens<I: AsRef<str>>(
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<Secret> = 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 /// Get the `kubeadm join` configuration for the specified EC2 instance
/// ///
/// This function creates a kubeconfig file that can be passed to `kubeadm /// This function creates a kubeconfig file that can be passed to `kubeadm