Skip to content

Commit c879510

Browse files
committed
Working, prompting working
Signed-off-by: Brett Tofel <[email protected]>
1 parent 3a3f663 commit c879510

File tree

1 file changed

+26
-26
lines changed

1 file changed

+26
-26
lines changed

hack/tools/ownership_tree.py

+26-26
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
#!/usr/bin/env python3.11
22
import json
33
import os
4-
import openai
4+
from openai import OpenAI
5+
6+
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
57
import subprocess
68
import sys
79
import argparse
@@ -14,11 +16,15 @@
1416
parser.add_argument("--gather-cluster-extension-state", action="store_true",
1517
help="Gather and save a compressed fingerprint of the cluster extension state to a file.")
1618
parser.add_argument("--no-tree", action="store_true", help="Do not print the tree output (only used if gather-cluster-extension-state is set).")
19+
parser.add_argument("--prompt", action="store_true", help="Create the fingerprint file (if needed) and send it to OpenAI for diagnosis.")
1720
args = parser.parse_args()
1821

1922
NAMESPACE = args.namespace
2023

21-
# If gather-cluster-extension-state is used, we want full info regardless of other flags
24+
# If --prompt is used, we also want full info and to gather fingerprint, regardless of other flags
25+
if args.prompt:
26+
args.gather_cluster_extension_state = True
27+
2228
if args.gather_cluster_extension_state:
2329
SHOW_EVENTS = True
2430
WITH_EVENT_INFO = True
@@ -112,7 +118,6 @@ def get_resources_for_type(resource_name, namespaced):
112118

113119
# Collect resources
114120
for (kind, plural_name, is_namespaced) in resource_info:
115-
# If we are gathering CE state or SHOW_EVENTS is True, we process events, else skip if no events
116121
if kind == "Event" and not SHOW_EVENTS:
117122
continue
118123
items = get_resources_for_type(plural_name, is_namespaced)
@@ -139,6 +144,7 @@ def get_resources_for_type(resource_name, namespaced):
139144
uid_to_resource[uid] = res_entry
140145
all_uids.add(uid)
141146

147+
from collections import defaultdict
142148
owner_to_children = defaultdict(list)
143149
for uid, res in uid_to_resource.items():
144150
for (_, _, o_uid) in res["owners"]:
@@ -211,9 +217,6 @@ def print_tree(uid, prefix="", is_last=True):
211217
print_tree(c_uid, prefix=child_prefix, is_last=(i == len(children)-1))
212218

213219

214-
###############################
215-
# Code for gather fingerprint
216-
###############################
217220
def extract_resource_summary(kind, name, namespace):
218221
is_namespaced = (namespace is not None and namespace != "")
219222
cmd = ["kubectl", "get", kind.lower()+"/"+name]
@@ -274,12 +277,10 @@ def extract_resource_summary(kind, name, namespace):
274277
return summary
275278

276279
def load_fingerprint(file_path):
277-
"""Load the JSON fingerprint file from the specified path."""
278280
with open(file_path, 'r') as f:
279281
return json.load(f)
280282

281283
def generate_prompt(fingerprint):
282-
"""Generate the diagnostic prompt by embedding the fingerprint into the request."""
283284
prompt = """
284285
You are an expert in Kubernetes operations and diagnostics. I will provide you with a JSON file that represents a snapshot ("fingerprint") of the entire state of a Kubernetes namespace focusing on a particular ClusterExtension and all related resources. This fingerprint includes:
285286
@@ -308,26 +309,17 @@ def generate_prompt(fingerprint):
308309
return prompt
309310

310311
def send_to_openai(prompt, model="gpt-4o"):
311-
"""Send the prompt to OpenAI's completions API and get the response."""
312312
try:
313-
openai.api_key = os.getenv("OPENAI_API_KEY")
314-
if not openai.api_key:
313+
if os.getenv("OPENAI_API_KEY") is None:
315314
raise ValueError("OPENAI_API_KEY environment variable is not set.")
316-
317-
response = openai.ChatCompletion.create(
318-
model=model,
319-
messages=[{"role": "user", "content": prompt}]
320-
)
321-
322-
# Extract and return the assistant's message
323-
message_content = response['choices'][0]['message']['content']
315+
response = client.chat.completions.create(model=model,
316+
messages=[{"role": "user", "content": prompt}])
317+
message_content = response.choices[0].message.content
324318
return message_content
325-
326319
except Exception as e:
327320
return f"Error communicating with OpenAI API: {e}"
328321

329322
def gather_fingerprint(namespace):
330-
# Find cluster extension(s)
331323
ce_uids = [uid for uid, res in uid_to_resource.items() if res["kind"] == "ClusterExtension" and res["namespace"] == namespace]
332324
if not ce_uids:
333325
return []
@@ -342,7 +334,6 @@ def process_resource(uid):
342334
nm = r["name"]
343335
ns = r["namespace"]
344336
summary = extract_resource_summary(k, nm, ns)
345-
# Deduplicate images
346337
if "containers" in summary:
347338
new_containers = []
348339
for c in summary["containers"]:
@@ -360,7 +351,6 @@ def process_resource(uid):
360351
results = []
361352
for ce_uid in ce_uids:
362353
fingerprint = {}
363-
# Include all discovered resources
364354
for uid in uid_to_resource:
365355
r = uid_to_resource[uid]
366356
key = f"{r['kind']}/{r['name']}"
@@ -375,12 +365,10 @@ def process_resource(uid):
375365
results.append(fname)
376366
return results
377367

378-
# If gather-cluster-extension-state, generate state file(s)
379368
state_files = []
380369
if args.gather_cluster_extension_state:
381370
state_files = gather_fingerprint(NAMESPACE)
382371

383-
# Print tree unless --no-tree is given AND we are in gather-cluster-extension-state mode
384372
if not (args.gather_cluster_extension_state and args.no_tree):
385373
for i, uid in enumerate(top_level_kinds):
386374
print_tree(uid, prefix="", is_last=(i == len(top_level_kinds)-1))
@@ -389,4 +377,16 @@ def process_resource(uid):
389377
if not state_files:
390378
print("No ClusterExtension found in the namespace, no state file created.", file=sys.stderr)
391379
else:
392-
print("Created state file(s):", ", ".join(state_files))
380+
print("Created state file(s):", ", ".join(state_files))
381+
382+
# If --prompt is used, we already created the fingerprint file. Now load and send to OpenAI.
383+
if args.prompt:
384+
if not state_files:
385+
print("No ClusterExtension found, cannot prompt OpenAI.", file=sys.stderr)
386+
sys.exit(1)
387+
# Assume one ClusterExtension, take the first file
388+
fingerprint_data = load_fingerprint(state_files[0])
389+
prompt = generate_prompt(fingerprint_data)
390+
response = send_to_openai(prompt)
391+
print("\n--- OpenAI Diagnosis ---\n")
392+
print(response)

0 commit comments

Comments
 (0)