comms: answer node count queries
This commit is contained in:
parent
cd6eaff7cb
commit
5f0bc3832d
@ -16,7 +16,7 @@ spec:
|
|||||||
labels:
|
labels:
|
||||||
app: atlasbot
|
app: atlasbot
|
||||||
annotations:
|
annotations:
|
||||||
checksum/atlasbot-configmap: manual-atlasbot-5
|
checksum/atlasbot-configmap: manual-atlasbot-6
|
||||||
vault.hashicorp.com/agent-inject: "true"
|
vault.hashicorp.com/agent-inject: "true"
|
||||||
vault.hashicorp.com/role: "comms"
|
vault.hashicorp.com/role: "comms"
|
||||||
vault.hashicorp.com/agent-inject-secret-turn-secret: "kv/data/atlas/comms/turn-shared-secret"
|
vault.hashicorp.com/agent-inject-secret-turn-secret: "kv/data/atlas/comms/turn-shared-secret"
|
||||||
|
|||||||
@ -444,6 +444,28 @@ def vm_cluster_snapshot() -> str:
|
|||||||
parts.append(pr)
|
parts.append(pr)
|
||||||
return "\n".join(parts).strip()
|
return "\n".join(parts).strip()
|
||||||
|
|
||||||
|
def nodes_summary(cluster_name: str) -> str:
|
||||||
|
try:
|
||||||
|
data = k8s_get("/api/v1/nodes?limit=500")
|
||||||
|
except Exception:
|
||||||
|
return ""
|
||||||
|
items = data.get("items") or []
|
||||||
|
if not isinstance(items, list) or not items:
|
||||||
|
return ""
|
||||||
|
total = len(items)
|
||||||
|
ready = 0
|
||||||
|
for node in items:
|
||||||
|
conditions = node.get("status", {}).get("conditions") or []
|
||||||
|
for cond in conditions if isinstance(conditions, list) else []:
|
||||||
|
if cond.get("type") == "Ready":
|
||||||
|
if cond.get("status") == "True":
|
||||||
|
ready += 1
|
||||||
|
break
|
||||||
|
not_ready = max(total - ready, 0)
|
||||||
|
if not_ready:
|
||||||
|
return f"{cluster_name} cluster has {total} nodes: {ready} Ready, {not_ready} NotReady."
|
||||||
|
return f"{cluster_name} cluster has {total} nodes, all Ready."
|
||||||
|
|
||||||
def _strip_code_fence(text: str) -> str:
|
def _strip_code_fence(text: str) -> str:
|
||||||
cleaned = (text or "").strip()
|
cleaned = (text or "").strip()
|
||||||
match = CODE_FENCE_RE.match(cleaned)
|
match = CODE_FENCE_RE.match(cleaned)
|
||||||
@ -527,6 +549,7 @@ def ollama_reply(hist_key, prompt: str, *, context: str) -> str:
|
|||||||
"Be helpful, direct, and concise. "
|
"Be helpful, direct, and concise. "
|
||||||
"Prefer answering with exact repo paths and Kubernetes resource names. "
|
"Prefer answering with exact repo paths and Kubernetes resource names. "
|
||||||
"Never include or request secret values. "
|
"Never include or request secret values. "
|
||||||
|
"Respond in plain sentences; do not return JSON or code fences unless explicitly asked."
|
||||||
)
|
)
|
||||||
transcript_parts = [system]
|
transcript_parts = [system]
|
||||||
if context:
|
if context:
|
||||||
@ -601,6 +624,14 @@ def sync_loop(token: str, room_id: str):
|
|||||||
if not (is_dm or mentioned):
|
if not (is_dm or mentioned):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
lower_body = body.lower()
|
||||||
|
if re.search(r"\\bhow many nodes\\b|\\bnode count\\b|\\bnumber of nodes\\b", lower_body):
|
||||||
|
if any(word in lower_body for word in ("cluster", "atlas", "titan")):
|
||||||
|
summary = nodes_summary("Atlas")
|
||||||
|
if summary:
|
||||||
|
send_msg(token, rid, summary)
|
||||||
|
continue
|
||||||
|
|
||||||
# Only do live cluster/metrics introspection in DMs.
|
# Only do live cluster/metrics introspection in DMs.
|
||||||
allow_tools = is_dm
|
allow_tools = is_dm
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user