use chrono::Utc;
use k8s_openapi::api::core::v1::ObjectReference;
use k8s_openapi::api::events::v1::Event;
use k8s_openapi::apimachinery::pkg::apis::meta::v1::{MicroTime, ObjectMeta};
use kube::{Api, Client};
use tracing::info;
use crate::error::Result;
use crate::traits::KubeResource;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EventType {
Normal,
Warning,
}
impl EventType {
fn as_str(self) -> &'static str {
match self {
Self::Normal => "Normal",
Self::Warning => "Warning",
}
}
}
pub async fn record_event<T>(
client: Client,
resource: &T,
event_type: EventType,
action: impl Into<String>,
reason: impl Into<String>,
note: impl Into<String>,
reporting_controller: impl Into<String>,
) -> Result<()>
where
T: KubeResource,
{
let meta = resource.meta();
let resource_name = meta.name.as_deref().unwrap_or("unknown");
let namespace = meta.namespace.as_deref().unwrap_or("default");
let now = Utc::now();
let event_name = format!(
"{}.{:x}",
resource_name,
now.timestamp_nanos_opt().unwrap_or(0) as u64
);
let reporting_instance = std::env::var("POD_NAME")
.or_else(|_| std::env::var("HOSTNAME"))
.unwrap_or_else(|_| "unknown".to_string());
let action = action.into();
let reason = reason.into();
let type_str = event_type.as_str();
info!(
resource = %resource_name,
%namespace,
%reason,
event_type = type_str,
"Recording event"
);
let regarding = ObjectReference {
api_version: Some(T::api_version(&()).to_string()),
kind: Some(T::kind(&()).to_string()),
name: meta.name.clone(),
namespace: meta.namespace.clone(),
uid: meta.uid.clone(),
resource_version: meta.resource_version.clone(),
..Default::default()
};
let event = Event {
metadata: ObjectMeta {
name: Some(event_name),
namespace: Some(namespace.to_string()),
..Default::default()
},
event_time: Some(MicroTime(now)),
regarding: Some(regarding),
action: Some(action),
reason: Some(reason),
note: Some(note.into()),
type_: Some(type_str.to_string()),
reporting_controller: Some(reporting_controller.into()),
reporting_instance: Some(reporting_instance),
..Default::default()
};
let api: Api<Event> = Api::namespaced(client, namespace);
api.create(&kube::api::PostParams::default(), &event)
.await?;
Ok(())
}