extern crate failure;
extern crate futures;
extern crate hyper;
extern crate hyper_tls;
extern crate kubernetes;
extern crate serde_json;
#[macro_use]
extern crate log;
extern crate pretty_env_logger;
use failure::Error;
use futures::prelude::*;
use hyper::rt;
use std::result::Result;
use kubernetes::api;
use kubernetes::api::core::v1::{ContainerState, Pod, PodList};
use kubernetes::api::meta::v1::{EventType, ListOptions};
use kubernetes::client::Client;
fn print_pod_state(p: &Pod) {
println!(
"pod {} - {:?}",
p.metadata
.name
.as_ref()
.map(String::as_str)
.unwrap_or("(no name)"),
p.status.phase.unwrap_or(api::core::v1::PodPhase::Unknown)
);
let c_statuses = p
.status
.init_container_statuses
.iter()
.chain(p.status.container_statuses.iter());
for c in c_statuses {
print!(" -> {}: ", c.name);
match c.state {
None => println!("state unknown"),
Some(ContainerState::Waiting(ref s)) => {
println!(
"waiting: {}",
s.message
.as_ref()
.or(s.reason.as_ref())
.map(String::as_str)
.unwrap_or("waiting")
);
}
Some(ContainerState::Running(ref s)) => {
print!("running");
if let Some(ref t) = s.started_at {
print!(" since {}", t);
}
println!("");
}
Some(ContainerState::Terminated(ref s)) => {
if let Some(ref msg) = s.message {
println!("terminated: {}", msg);
} else {
print!("exited with code {}", s.exit_code);
if let Some(ref t) = s.finished_at {
print!(" at {}", t);
}
println!("");
}
}
}
}
}
fn main_() -> Result<(), Error> {
let client = Client::new()?;
let pods = api::core::v1::GROUP_VERSION.with_resource("pods");
let namespace = Some("kube-system");
let work = client
.list(&pods, namespace, Default::default())
.inspect(|podlist: &PodList| {
podlist.items.iter().for_each(print_pod_state);
})
.and_then(move |podlist: PodList| {
debug!(
"Starting at resource version {}",
podlist.metadata.resource_version
);
let listopts = ListOptions {
resource_version: podlist.metadata.resource_version,
..Default::default()
};
client
.watch_list(&pods, namespace, listopts)
.for_each(|event| {
match event.typ {
EventType::Added | EventType::Modified => {
let p: Pod = serde_json::from_value(event.object)?;
print_pod_state(&p);
}
EventType::Deleted => {
let p: Pod = serde_json::from_value(event.object)?;
println!("deleted {}", p.metadata.name.unwrap_or("(no name)".into()));
}
EventType::Error => debug!("Ignoring error event {:#?}", event.object),
}
Ok(())
})
});
rt::run(work.map_err(|err| panic!("Error: {}", err)));
Ok(())
}
fn main() {
pretty_env_logger::init();
let status = match main_() {
Ok(_) => 0,
Err(e) => {
eprintln!("Error: {}", e);
for c in e.iter_chain().skip(1) {
eprintln!(" Caused by {}", c);
}
debug!("Backtrace: {}", e.backtrace());
1
}
};
::std::process::exit(status);
}