use crate::events::with_events;
use crate::json::{items, text};
use crate::metadata::metadata;
use k8s_openapi::api::core::v1::Event;
use k8s_openapi::jiff::Timestamp;
use kube::api::DynamicObject;
use std::fmt::Write;
fn nonempty(s: &str, default: &str) -> String {
if s.is_empty() {
default.into()
} else {
s.into()
}
}
pub(crate) fn render(
object: &DynamicObject,
kind: &str,
events: Option<&[Event]>,
now: Timestamp,
) -> String {
let v = &object.data;
let mut out = metadata(&object.metadata);
if kind == "Endpoints" {
out.push_str("Subsets:\n");
for subset in items(&v["subsets"]) {
for (field, label) in [
("addresses", "Addresses"),
("notReadyAddresses", "NotReadyAddresses"),
] {
let addresses = items(&subset[field])
.iter()
.map(|a| text(&a["ip"]))
.collect::<Vec<_>>()
.join(",");
writeln!(out, " {label}:\t{}", nonempty(&addresses, "<none>")).unwrap();
}
let ports = items(&subset["ports"]);
if !ports.is_empty() {
out.push_str(" Ports:\n Name\tPort\tProtocol\n ----\t----\t--------\n");
for port in ports {
writeln!(
out,
" {}\t{}\t{}",
nonempty(text(&port["name"]), "<unset>"),
port["port"].as_i64().unwrap_or_default(),
text(&port["protocol"])
)
.unwrap();
}
}
out.push('\n');
}
} else {
writeln!(out, "AddressType:\t{}", text(&v["addressType"])).unwrap();
let ports = items(&v["ports"]);
if ports.is_empty() {
out.push_str("Ports: <unset>\n");
} else {
out.push_str("Ports:\n Name\tPort\tProtocol\n ----\t----\t--------\n");
for port in ports {
writeln!(
out,
" {}\t{}\t{}",
nonempty(text(&port["name"]), "<unset>"),
port["port"]
.as_i64()
.map(|n| n.to_string())
.unwrap_or("<unset>".into()),
text(&port["protocol"])
)
.unwrap();
}
}
let endpoints = items(&v["endpoints"]);
if endpoints.is_empty() {
out.push_str("Endpoints: <none>\n");
} else {
out.push_str("Endpoints:\n");
for endpoint in endpoints {
let addresses = items(&endpoint["addresses"])
.iter()
.map(text)
.collect::<Vec<_>>()
.join(", ");
writeln!(
out,
" - Addresses:\t{}\n Conditions:\n Ready:\t{}\n Hostname:\t{}",
nonempty(&addresses, "<none>"),
endpoint["conditions"]["ready"]
.as_bool()
.map(|b| b.to_string())
.unwrap_or("<unset>".into()),
endpoint["hostname"].as_str().unwrap_or("<unset>")
)
.unwrap();
if !endpoint["targetRef"].is_null() {
writeln!(
out,
" TargetRef:\t{}/{}",
text(&endpoint["targetRef"]["kind"]),
text(&endpoint["targetRef"]["name"])
)
.unwrap();
}
writeln!(
out,
" NodeName:\t{}\n Zone:\t{}",
endpoint["nodeName"].as_str().unwrap_or("<unset>"),
endpoint["zone"].as_str().unwrap_or("<unset>")
)
.unwrap();
}
}
}
with_events(out, events, now)
}