Skip to content

Commit 2116bf8

Browse files
committed
Add SelfSubjectAccessReviews in plan_mustgather
Signed-off-by: Swarup Ghosh <swghosh@redhat.com>
1 parent 12f9241 commit 2116bf8

File tree

1 file changed

+55
-2
lines changed

1 file changed

+55
-2
lines changed

pkg/toolsets/core/mustgather.go

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,39 @@ func mustGatherPlan(params api.ToolHandlerParams) (*api.ToolCallResult, error) {
344344
},
345345
}
346346

347+
allowChecks := map[string]struct {
348+
schema.GroupVersionResource
349+
name string
350+
verb string
351+
}{
352+
"create_namespace": {
353+
GroupVersionResource: schema.GroupVersionResource{Version: "v1", Resource: "namespace"},
354+
verb: "create",
355+
},
356+
"create_serviceaccount": {
357+
GroupVersionResource: schema.GroupVersionResource{Version: "v1", Resource: "serviceaccount"},
358+
verb: "create",
359+
},
360+
"create_clusterrolebinding": {
361+
GroupVersionResource: schema.GroupVersionResource{Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "clusterrolebindings"},
362+
verb: "create",
363+
},
364+
"create_pod": {
365+
GroupVersionResource: schema.GroupVersionResource{Version: "v1", Resource: "pod"},
366+
verb: "create",
367+
},
368+
"use_scc_hostnetwork": {
369+
GroupVersionResource: schema.GroupVersionResource{Group: "security.openshift.io", Version: "v1", Resource: "securitycontextconstraints"},
370+
name: "hostnetwork-v2",
371+
verb: "use",
372+
},
373+
}
374+
isAllowed := make(map[string]bool)
375+
376+
for k, check := range allowChecks {
377+
isAllowed[k] = params.CanIUse(params, &check.GroupVersionResource, "", check.verb)
378+
}
379+
347380
var result strings.Builder
348381
result.WriteString("The generated plan contains YAML manifests for must-gather pods and required resources (namespace, serviceaccount, clusterrolebinding). " +
349382
"Suggest how the user can apply the manifest and copy results locally (`oc cp` / `kubectl cp`). \n\n",
@@ -354,12 +387,12 @@ func mustGatherPlan(params api.ToolHandlerParams) (*api.ToolCallResult, error) {
354387
)
355388

356389
if !keepResources {
357-
result.WriteString("Once the must-gather collection is completed, the user may which to cleanup the created resources. \n" +
390+
result.WriteString("Once the must-gather collection is completed, the user may wish to cleanup the created resources. \n" +
358391
"- use the resources_delete tool to delete the namespace and the clusterrolebinding \n" +
359392
"- or, execute cleanup using `kubectl delete`. \n\n")
360393
}
361394

362-
if !namespaceExists {
395+
if !namespaceExists && isAllowed["create_namespace"] {
363396
namespaceYaml, err := yaml.Marshal(namespaceObj)
364397
if err != nil {
365398
return nil, fmt.Errorf("failed to marshal namespace to yaml: %w", err)
@@ -370,6 +403,10 @@ func mustGatherPlan(params api.ToolHandlerParams) (*api.ToolCallResult, error) {
370403
result.WriteString("```\n\n")
371404
}
372405

406+
if !namespaceExists && !isAllowed["create_namespace"] {
407+
result.WriteString("WARNING: The resources_create_or_update call does not have permission to create namespace(s).\n")
408+
}
409+
373410
// yaml(s) are dumped into individual code blocks of ``` ```
374411
// because resources_create_or_update tool call fails when content has more than one more resource,
375412
// some models are smart to detect an error and retry with one resource a time though.
@@ -382,6 +419,10 @@ func mustGatherPlan(params api.ToolHandlerParams) (*api.ToolCallResult, error) {
382419
result.Write(serviceAccountYaml)
383420
result.WriteString("```\n\n")
384421

422+
if !isAllowed["create_serviceaccount"] {
423+
result.WriteString("WARNING: The resources_create_or_update call does not have permission to create serviceaccount(s).\n")
424+
}
425+
385426
clusterRoleBindingYaml, err := yaml.Marshal(clusterRoleBinding)
386427
if err != nil {
387428
return nil, fmt.Errorf("failed to marshal cluster role binding to yaml: %w", err)
@@ -391,6 +432,10 @@ func mustGatherPlan(params api.ToolHandlerParams) (*api.ToolCallResult, error) {
391432
result.Write(clusterRoleBindingYaml)
392433
result.WriteString("```\n\n")
393434

435+
if !isAllowed["create_clusterrolebinding"] {
436+
result.WriteString("WARNING: The resources_create_or_update call does not have permission to create clusterrolebinding(s).\n")
437+
}
438+
394439
podYaml, err := yaml.Marshal(pod)
395440
if err != nil {
396441
return nil, fmt.Errorf("failed to marshal pod to yaml: %w", err)
@@ -400,6 +445,14 @@ func mustGatherPlan(params api.ToolHandlerParams) (*api.ToolCallResult, error) {
400445
result.Write(podYaml)
401446
result.WriteString("```\n")
402447

448+
if !isAllowed["create_pod"] {
449+
result.WriteString("WARNING: The resources_create_or_update call does not have permission to create pod(s).\n")
450+
}
451+
452+
if hostNetwork && !isAllowed["use_scc_hostnetwork"] {
453+
result.WriteString("WARNING: The resources_create_or_update call does not have permission to create pod(s) with hostNetwork: true.\n")
454+
}
455+
403456
return api.NewToolCallResult(result.String(), nil), nil
404457
}
405458

0 commit comments

Comments
 (0)