sk-store 2.1.0

SimKube trace store library
Documentation
mod config;
mod event_list;
mod filter;
mod index;
mod pod_owners_map;
mod store;
pub mod watchers;

use std::collections::HashMap;

use kube::api::DynamicObject;
use serde::{
    Deserialize,
    Serialize,
};
use sk_core::errors::*;
use sk_core::k8s::{
    PodLifecycleData,
    GVK,
};
use sk_core::prelude::*;

pub use crate::config::{
    TracerConfig,
    TrackedObjectConfig,
};
pub use crate::event_list::TraceEventList;
pub use crate::index::TraceIndex;
use crate::pod_owners_map::PodLifecyclesMap;
pub use crate::store::TraceStore;

#[derive(Clone, Copy, Debug)]
pub enum TraceAction {
    ObjectApplied,
    ObjectDeleted,
}

#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
pub struct TraceEvent {
    pub ts: i64,
    pub applied_objs: Vec<DynamicObject>,
    pub deleted_objs: Vec<DynamicObject>,
}

impl TraceEvent {
    pub fn len(&self) -> usize {
        self.applied_objs.len() + self.deleted_objs.len()
    }

    pub fn is_empty(&self) -> bool {
        self.applied_objs.is_empty() && self.deleted_objs.is_empty()
    }
}

pub struct TraceIterator<'a> {
    events: &'a TraceEventList,
    idx: usize,
}

const CURRENT_TRACE_FORMAT_VERSION: u16 = 2;

pub trait TraceStorable {
    fn create_or_update_obj(&mut self, obj: &DynamicObject, ts: i64, maybe_old_hash: Option<u64>) -> EmptyResult;
    fn delete_obj(&mut self, obj: &DynamicObject, ts: i64) -> EmptyResult;
    fn update_all_objs_for_gvk(&mut self, gvk: &GVK, objs: &[DynamicObject], ts: i64) -> EmptyResult;
    fn lookup_pod_lifecycle(&self, gvk: &GVK, owner_ns_name: &str, pod_hash: u64, seq: usize) -> PodLifecycleData;
    fn record_pod_lifecycle(
        &mut self,
        ns_name: &str,
        maybe_pod: Option<corev1::Pod>,
        owners: Vec<metav1::OwnerReference>,
        lifecycle_data: &PodLifecycleData,
    ) -> EmptyResult;
    fn config(&self) -> &TracerConfig;
    fn has_obj(&self, gvk: &GVK, ns_name: &str) -> bool;
    fn start_ts(&self) -> Option<i64>;
    fn end_ts(&self) -> Option<i64>;
    fn iter(&self) -> TraceIterator<'_>;
}

#[derive(Deserialize, Serialize)]
pub struct ExportedTrace {
    version: u16,
    config: TracerConfig,
    events: Vec<TraceEvent>,
    index: TraceIndex,
    pod_lifecycles: HashMap<(GVK, String), PodLifecyclesMap>,
}

impl ExportedTrace {
    pub fn prepend_event(&mut self, event: TraceEvent) {
        let mut tmp = vec![event];
        tmp.append(&mut self.events);
        self.events = tmp;
    }

    pub fn events(&self) -> Vec<TraceEvent> {
        self.events.clone()
    }
}

#[cfg(test)]
mod tests;

#[cfg(feature = "mock")]
pub mod mock {
    use mockall::mock;

    use super::*;

    mock! {
        pub TraceStore {}

        impl TraceStorable for TraceStore {
            fn create_or_update_obj(&mut self, obj: &DynamicObject, ts: i64, maybe_old_hash: Option<u64>) -> EmptyResult;
            fn delete_obj(&mut self, obj: &DynamicObject, ts: i64) -> EmptyResult;
            fn update_all_objs_for_gvk(&mut self, gvk: &GVK, objs: &[DynamicObject], ts: i64) -> EmptyResult;
            fn lookup_pod_lifecycle(&self, owner_gvk: &GVK, owner_ns_name: &str, pod_hash: u64, seq: usize) -> PodLifecycleData;
            fn record_pod_lifecycle(
                &mut self,
                ns_name: &str,
                maybe_pod: Option<corev1::Pod>,
                owners: Vec<metav1::OwnerReference>,
                lifecycle_data: &PodLifecycleData,
            ) -> EmptyResult;
            fn config(&self) -> &TracerConfig;
            fn has_obj(&self, gvk: &GVK, ns_name: &str) -> bool;
            fn start_ts(&self) -> Option<i64>;
            fn end_ts(&self) -> Option<i64>;
            fn iter<'a>(&'a self) -> TraceIterator<'a>;
        }
    }
}