#[cfg(feature = "docker")]
pub mod docker;
#[cfg(feature = "kubernetes")]
pub mod kubernetes;
use crate::cli::{CollectionOptions, PollingOptions, RunCommand};
use crate::shared::CollectionEvent;
use crate::shell::Shell;
#[cfg(feature = "kubernetes")]
use std::path::PathBuf;
use std::sync::Arc;
use clap::{Clap, ValueHint};
use failure::{Error, Fail};
use serde::{Serialize, Serializer};
#[derive(Debug, Fail)]
#[fail(display = "{}", suggestion)]
pub struct InitializationError {
pub suggestion: String,
pub original: Option<Error>,
}
pub trait Provider {
fn initialize(
&mut self,
opts: &RunCommand,
shell: Arc<Shell>,
) -> Result<(), InitializationError>;
fn poll(&mut self) -> Result<Vec<CollectionEvent>, Error>;
}
pub use provider_type::ProviderType;
mod provider_type {
#![allow(clippy::default_trait_access)]
#[cfg(feature = "docker")]
use super::DockerOptions;
#[cfg(feature = "kubernetes")]
use super::KubernetesOptions;
use crate::cli::{AUTHORS, VERSION};
use clap::Clap;
use strum_macros::IntoStaticStr;
#[derive(IntoStaticStr, Clap, Clone, Debug, PartialEq)]
#[strum(serialize_all = "snake_case")]
pub enum ProviderType {
#[cfg(feature = "docker")]
#[clap(
version = VERSION.unwrap_or("unknown"),
author = AUTHORS.as_deref().unwrap_or("contributors"),
about = "Runs collection using docker as the target backend; collecting stats for \
each container"
)]
Docker(DockerOptions),
#[cfg(feature = "kubernetes")]
#[clap(
version = VERSION.unwrap_or("unknown"),
author = AUTHORS.as_deref().unwrap_or("contributors"),
about = "Runs collection using kubernetes as the target backend; collecting stats for \
each pod"
)]
Kubernetes(KubernetesOptions),
}
}
impl Serialize for ProviderType {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(self.into())
}
}
impl ProviderType {
#[must_use]
#[cfg(feature = "kubernetes")]
pub fn into_inner_kubernetes(self) -> KubernetesOptions {
match self {
#[cfg(feature = "docker")]
Self::Docker(_) => panic!("Cannot unwrap Docker provider to Kubernetes options"),
Self::Kubernetes(opts) => opts,
}
}
#[must_use]
#[cfg(feature = "docker")]
pub fn into_inner_docker(self) -> DockerOptions {
match self {
Self::Docker(opts) => opts,
#[cfg(feature = "kubernetes")]
Self::Kubernetes(_) => panic!("Cannot unwrap Kubernetes provider to Docker options"),
}
}
#[must_use]
pub fn get_impl(&self) -> Box<dyn Provider> {
match self {
#[cfg(feature = "docker")]
Self::Docker(_) => Box::new(docker::Docker::new()),
#[cfg(feature = "kubernetes")]
Self::Kubernetes(_) => Box::new(kubernetes::Kubernetes::new()),
}
}
#[must_use]
pub const fn collection(&self) -> &CollectionOptions {
match self {
#[cfg(feature = "docker")]
Self::Docker(opts) => &opts.collection,
#[cfg(feature = "kubernetes")]
Self::Kubernetes(opts) => &opts.collection,
}
}
#[must_use]
pub const fn polling(&self) -> &PollingOptions {
match self {
#[cfg(feature = "docker")]
Self::Docker(opts) => &opts.polling,
#[cfg(feature = "kubernetes")]
Self::Kubernetes(opts) => &opts.polling,
}
}
}
#[cfg(feature = "docker")]
#[derive(Clap, Clone, Debug, PartialEq)]
pub struct DockerOptions {
#[clap(flatten)]
pub polling: PollingOptions,
#[clap(flatten)]
pub collection: CollectionOptions,
}
#[cfg(feature = "kubernetes")]
#[derive(Clap, Clone, Debug, PartialEq)]
pub struct KubernetesOptions {
#[clap(
parse(from_os_str),
short = 'k',
long = "kube-config",
value_hint = ValueHint::FilePath
)]
pub kube_config: Option<PathBuf>,
#[clap(flatten)]
pub polling: PollingOptions,
#[clap(flatten)]
pub collection: CollectionOptions,
}