Skip to content

Commit

Permalink
added: more event fields and limit
Browse files Browse the repository at this point in the history
  • Loading branch information
strowk committed Dec 8, 2024
1 parent 0805f0e commit e437297
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 24 deletions.
68 changes: 46 additions & 22 deletions internal/tools/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,51 +8,67 @@ import (

"github.com/strowk/foxy-contexts/pkg/fxctx"
"github.com/strowk/foxy-contexts/pkg/mcp"
"github.com/strowk/foxy-contexts/pkg/toolinput"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func NewListEventsTool(pool k8s.ClientPool) fxctx.Tool {
schema := toolinput.NewToolInputSchema(
toolinput.WithRequiredString("context", "Name of the Kubernetes context to use"),
toolinput.WithRequiredString("namespace", "Name of the namespace to list events from"),
toolinput.WithNumber("limit", "Maximum number of events to list"),
)
return fxctx.NewTool(
&mcp.Tool{
Name: "list-k8s-events",
Description: utils.Ptr("List Kubernetes events using specific context in a specified namespace"),
InputSchema: mcp.ToolInputSchema{
Type: "object",
Properties: map[string]map[string]interface{}{
"context": {
"type": "string",
},
"namespace": {
"type": "string",
},
},
Required: []string{
"context",
"namespace",
},
},
InputSchema: schema.GetMcpToolInputSchema(),
},
func(args map[string]interface{}) *mcp.CallToolResult {
k8sCtx := args["context"].(string)
k8sNamespace := args["namespace"].(string)
input, err := schema.Validate(args)
if err != nil {
return errResponse(err)
}

k8sCtx, err := input.String("context")
if err != nil {
return errResponse(err)
}

k8sNamespace, err := input.String("namespace")
if err != nil {
return errResponse(err)
}

clientset, err := pool.GetClientset(k8sCtx)

options := metav1.ListOptions{}
if limit, err := input.Number("limit"); err == nil {
options.Limit = int64(limit)
}

events, err := clientset.
CoreV1().
Events(k8sNamespace).
List(context.Background(), metav1.ListOptions{})
List(context.Background(), options)
if err != nil {
return errResponse(err)
}

var contents []interface{} = make([]interface{}, len(events.Items))
for i, event := range events.Items {
content, err := NewJsonContent(EventInList{
eventInList := EventInList{
Action: event.Action,
Message: event.Message,
})
Type: event.Type,
Reason: event.Reason,
InvolvedObject: InvolvedObject{
Kind: event.InvolvedObject.Kind,
Name: event.InvolvedObject.Name,
},
}
content, err := NewJsonContent(eventInList)
if err != nil {
return errResponse(err)
}
Expand All @@ -68,7 +84,15 @@ func NewListEventsTool(pool k8s.ClientPool) fxctx.Tool {
)
}

type InvolvedObject struct {
Kind string `json:"kind"`
Name string `json:"name"`
}

type EventInList struct {
Action string `json:"action"`
Message string `json:"message"`
Action string `json:"action"`
Message string `json:"message"`
Type string `json:"type"`
Reason string `json:"reason"`
InvolvedObject InvolvedObject `json:"involvedObject"`
}
17 changes: 15 additions & 2 deletions testdata/list_tools_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,21 @@ out:
"type": "object",
"properties":
{
"context": { "type": "string" },
"namespace": { "type": "string" },
"context":
{
"type": "string",
"description": "Name of the Kubernetes context to use",
},
"namespace":
{
"type": "string",
"description": "Name of the namespace to list events from",
},
"limit":
{
"type": "number",
"description": "Maximum number of events to list",
},
},
"required": ["context", "namespace"],
},
Expand Down
63 changes: 63 additions & 0 deletions testdata/with_k3d/list_k8s_events_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
case: List k8s events with missing required property

in:
{
"jsonrpc": "2.0",
"method": "tools/call",
"id": 2,
"params":
{
"name": "list-k8s-events",
"arguments": { "context": "k3d-mcp-k8s-integration-test" },
},
}
out:
{
"jsonrpc": "2.0",
"id": 2,
"result":
{
"content": [{ "type": "text", "text": "missing required property" }],
"isError": true,
},
}

---
## This don't work because content is a bit unpredictable
case: List k8s events

in:
{
"jsonrpc": "2.0",
"method": "tools/call",
"id": 2,
"params":
{
"name": "list-k8s-events",
"arguments":
{
"context": "k3d-mcp-k8s-integration-test",
"namespace": "default",
"limit": 1,
},
},
}

# "text": "missing required property",

out:
{
"jsonrpc": "2.0",
"id": 2,
"result":
{
"content":
[
{
"type": "text",
"text": '{"action":"Binding","message":"Successfully assigned default/busybox to k3d-mcp-k8s-integration-test-server-0","type":"Normal","reason":"Scheduled","involvedObject":{"kind":"Pod","name":"busybox"}}',
},
],
"isError": false,
},
}

0 comments on commit e437297

Please sign in to comment.