bin/kube-nodes

#!/usr/bin/env bash
# bin/kube-nodes — pretty `kubectl get nodes` with allocation + ready status.

set -euo pipefail

ctx=$(kubectl config current-context 2>/dev/null || echo "<no-context>")
printf '== context: %s\n' "$ctx"

nodes_json=$(kubectl get nodes -o json)

# Ready / not-ready summary
ready=$(jq -r '.items[] | .status.conditions[] | select(.type=="Ready" and .status=="True") | .type' \
  <<<"$nodes_json" | wc -l | tr -d ' ')
total=$(jq -r '.items | length' <<<"$nodes_json")
printf '== nodes: %s/%s ready\n\n' "$ready" "$total"

# Table: name, roles, age, version, cpu (capacity), mem (capacity), os.
printf '%-32s %-20s %-6s %-10s %-6s %-10s %s\n' \
  NAME ROLES AGE VERSION CPU MEM OS

jq -r '
  .items[] | [
    .metadata.name,
    ([.metadata.labels // {} | to_entries[] | select(.key | startswith("node-role.kubernetes.io/")) | .key | split("/")[1]] | join(",") // "-"),
    (.metadata.creationTimestamp),
    (.status.nodeInfo.kubeletVersion),
    (.status.capacity.cpu),
    (.status.capacity.memory),
    (.status.nodeInfo.osImage)
  ] | @tsv
' <<<"$nodes_json" \
  | awk -F'\t' '
      function age(ts) {
        cmd = "date -d " ts " +%s 2>/dev/null || date -j -f %Y-%m-%dT%H:%M:%SZ " ts " +%s"
        cmd | getline then; close(cmd)
        now = systime()
        return int((now - then) / 86400) "d"
      }
      { printf "%-32s %-20s %-6s %-10s %-6s %-10s %s\n", $1, ($2?$2:"-"), age($3), $4, $5, $6, $7 }
    '