new status format, new podSelector field, more accurate pod stats

* renamed pod label prefix from "homepage" to "gethomepage.dev"
  which is more inline with typical kubernetes practices
This commit is contained in:
James Wynn 2022-12-08 16:03:29 -06:00
parent 174cb651b4
commit 09eb172079
8 changed files with 65 additions and 40 deletions

View file

@ -95,7 +95,7 @@ export default function Item({ service }) {
<button
type="button"
onClick={() => (statsOpen ? closeStats() : setStatsOpen(true))}
className="flex-shrink-0 flex items-center justify-center w-12 cursor-pointer"
className="flex-shrink-0 flex items-center justify-center cursor-pointer"
>
<KubernetesStatus service={service} />
<span className="sr-only">View container stats</span>
@ -121,7 +121,7 @@ export default function Item({ service }) {
"w-full overflow-hidden transition-all duration-300 ease-in-out"
)}
>
{statsOpen && <Kubernetes service={{ widget: { namespace: service.namespace, app: service.app } }} />}
{statsOpen && <Kubernetes service={{ widget: { namespace: service.namespace, app: service.app, podSelector: service.podSelector } }} />}
</div>
)}

View file

@ -1,19 +1,35 @@
import useSWR from "swr";
import { t } from "i18next";
export default function KubernetesStatus({ service }) {
const { data, error } = useSWR(`/api/kubernetes/status/${service.namespace}/${service.app}`);
const podSelectorString = service.podSelector !== undefined ? `podSelector=${service.podSelector}` : "";
const { data, error } = useSWR(`/api/kubernetes/status/${service.namespace}/${service.app}?${podSelectorString}`);
if (error) {
return <div className="w-3 h-3 bg-rose-300 dark:bg-rose-500 rounded-full" />;
<div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden" title={data.status}>
<div className="text-[8px] font-bold text-rose-500/80 uppercase">{t("docker.error")}</div>
</div>
}
if (data && data.status === "running") {
return <div className="w-3 h-3 bg-emerald-300 dark:bg-emerald-500 rounded-full" />;
return (
<div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden" title={data.health ?? data.status}>
<div className="text-[8px] font-bold text-emerald-500/80 uppercase">{data.health ?? data.status}</div>
</div>
);
}
if (data && data.status === "not found") {
return <div className="h-2.5 w-2.5 bg-orange-400/50 dark:bg-yellow-200/40 -rotate-45" />;
if (data && (data.status === "not found" || data.status === "down" || data.status === "partial")) {
return (
<div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden" title={data.status}>
<div className="text-[8px] font-bold text-orange-400/50 dark:text-orange-400/80 uppercase">{data.status}</div>
</div>
);
}
return <div className="w-3 h-3 bg-black/20 dark:bg-white/40 rounded-full" />;
return (
<div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden">
<div className="text-[8px] font-bold text-black/20 dark:text-white/40 uppercase">{t("docker.unknown")}</div>
</div>
);
}

View file

@ -48,10 +48,10 @@ export default function Widget({ options }) {
<div className="flex flex-col max-w:full sm:basis-auto self-center grow-0 flex-wrap">
<div className="flex flex-row self-center flex-wrap justify-between">
{cluster.show &&
<Node type="cluster" options={options.cluster} data={defaultData} />
<Node type="cluster" key="cluster" options={options.cluster} data={defaultData} />
}
{nodes.show &&
<Node type="node" options={options.nodes} data={defaultData} />
<Node type="node" key="nodes" options={options.nodes} data={defaultData} />
}
</div>
</div>
@ -62,11 +62,11 @@ export default function Widget({ options }) {
<div className="flex flex-col max-w:full sm:basis-auto self-center grow-0 flex-wrap">
<div className="flex flex-row self-center flex-wrap justify-between">
{cluster.show &&
<Node type="cluster" options={options.cluster} data={data.cluster} />
<Node key="cluster" type="cluster" options={options.cluster} data={data.cluster} />
}
{nodes.show && data.nodes &&
data.nodes.map((node) =>
<Node key={node} type="node" options={options.nodes} data={node} />)
<Node key={node.name} type="node" options={options.nodes} data={node} />)
}
</div>
</div>

View file

@ -9,7 +9,6 @@ import UsageBar from "./usage-bar";
export default function Node({ type, options, data }) {
const { t } = useTranslation();
console.log("Node", type, options, data);
function icon() {
if (type === "cluster") {