Skip to content

Commit 7e725f3

Browse files
committed
extract constants to common package
Signed-off-by: Nimisha Mehta <nimishamehta5@gmail.com>
1 parent 153edfb commit 7e725f3

File tree

11 files changed

+353
-327
lines changed

11 files changed

+353
-327
lines changed

pkg/common/const.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package common
2+
3+
const (
4+
ToolListResources = "list_resources"
5+
ToolGetResource = "get_resource"
6+
ToolReadResource = "read_resource"
7+
ToolApplyResource = "apply_resource"
8+
ToolDeleteResource = "delete_resource"
9+
)

pkg/mcp/apply_resource_test.go

Lines changed: 62 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,18 @@ import (
1212
"k8s.io/client-go/dynamic/fake"
1313
ktesting "k8s.io/client-go/testing"
1414

15+
"github.com/StacklokLabs/mkp/pkg/common"
1516
"github.com/StacklokLabs/mkp/pkg/k8s"
1617
)
1718

1819
func TestHandleApplyResourceClusteredSuccess(t *testing.T) {
1920
// Create a mock k8s client
2021
mockClient := &k8s.Client{}
21-
22+
2223
// Create a fake dynamic client
2324
scheme := runtime.NewScheme()
2425
fakeDynamicClient := fake.NewSimpleDynamicClient(scheme)
25-
26+
2627
// Create a test resource
2728
obj := &unstructured.Unstructured{
2829
Object: map[string]interface{}{
@@ -40,26 +41,26 @@ func TestHandleApplyResourceClusteredSuccess(t *testing.T) {
4041
},
4142
},
4243
}
43-
44+
4445
// Add a fake get response (resource not found)
4546
fakeDynamicClient.PrependReactor("get", "clusterroles", func(action ktesting.Action) (handled bool, ret runtime.Object, err error) {
4647
return true, nil, fmt.Errorf("not found: clusterroles \"test-cluster-role\" not found")
4748
})
48-
49+
4950
// Add a fake create response
5051
fakeDynamicClient.PrependReactor("create", "clusterroles", func(action ktesting.Action) (handled bool, ret runtime.Object, err error) {
5152
return true, obj, nil
5253
})
53-
54+
5455
// Set the dynamic client
5556
mockClient.SetDynamicClient(fakeDynamicClient)
56-
57+
5758
// Create an implementation
5859
impl := NewImplementation(mockClient)
59-
60+
6061
// Create a test request
6162
request := mcp.CallToolRequest{}
62-
request.Params.Name = "apply_resource"
63+
request.Params.Name = common.ToolApplyResource
6364
request.Params.Arguments = map[string]interface{}{
6465
"resource_type": "clustered",
6566
"group": "rbac.authorization.k8s.io",
@@ -80,20 +81,20 @@ func TestHandleApplyResourceClusteredSuccess(t *testing.T) {
8081
},
8182
},
8283
}
83-
84+
8485
// Test HandleApplyResource
8586
ctx := context.Background()
8687
result, err := impl.HandleApplyResource(ctx, request)
87-
88+
8889
// Verify there was no error
8990
assert.NoError(t, err, "HandleApplyResource should not return an error")
90-
91+
9192
// Verify the result is not nil
9293
assert.NotNil(t, result, "Result should not be nil")
93-
94+
9495
// Verify the result is successful
9596
assert.False(t, result.IsError, "Result should not be an error")
96-
97+
9798
// Verify the result contains the resource name
9899
textContent, ok := mcp.AsTextContent(result.Content[0])
99100
assert.True(t, ok, "Content should be TextContent")
@@ -103,11 +104,11 @@ func TestHandleApplyResourceClusteredSuccess(t *testing.T) {
103104
func TestHandleApplyResourceNamespacedSuccess(t *testing.T) {
104105
// Create a mock k8s client
105106
mockClient := &k8s.Client{}
106-
107+
107108
// Create a fake dynamic client
108109
scheme := runtime.NewScheme()
109110
fakeDynamicClient := fake.NewSimpleDynamicClient(scheme)
110-
111+
111112
// Create a test resource
112113
obj := &unstructured.Unstructured{
113114
Object: map[string]interface{}{
@@ -127,26 +128,26 @@ func TestHandleApplyResourceNamespacedSuccess(t *testing.T) {
127128
},
128129
},
129130
}
130-
131+
131132
// Add a fake get response (resource not found)
132133
fakeDynamicClient.PrependReactor("get", "services", func(action ktesting.Action) (handled bool, ret runtime.Object, err error) {
133134
return true, nil, fmt.Errorf("not found: services \"test-service\" not found")
134135
})
135-
136+
136137
// Add a fake create response
137138
fakeDynamicClient.PrependReactor("create", "services", func(action ktesting.Action) (handled bool, ret runtime.Object, err error) {
138139
return true, obj, nil
139140
})
140-
141+
141142
// Set the dynamic client
142143
mockClient.SetDynamicClient(fakeDynamicClient)
143-
144+
144145
// Create an implementation
145146
impl := NewImplementation(mockClient)
146-
147+
147148
// Create a test request
148149
request := mcp.CallToolRequest{}
149-
request.Params.Name = "apply_resource"
150+
request.Params.Name = common.ToolApplyResource
150151
request.Params.Arguments = map[string]interface{}{
151152
"resource_type": "namespaced",
152153
"group": "",
@@ -170,20 +171,20 @@ func TestHandleApplyResourceNamespacedSuccess(t *testing.T) {
170171
},
171172
},
172173
}
173-
174+
174175
// Test HandleApplyResource
175176
ctx := context.Background()
176177
result, err := impl.HandleApplyResource(ctx, request)
177-
178+
178179
// Verify there was no error
179180
assert.NoError(t, err, "HandleApplyResource should not return an error")
180-
181+
181182
// Verify the result is not nil
182183
assert.NotNil(t, result, "Result should not be nil")
183-
184+
184185
// Verify the result is successful
185186
assert.False(t, result.IsError, "Result should not be an error")
186-
187+
187188
// Verify the result contains the resource name
188189
textContent, ok := mcp.AsTextContent(result.Content[0])
189190
assert.True(t, ok, "Content should be TextContent")
@@ -193,18 +194,18 @@ func TestHandleApplyResourceNamespacedSuccess(t *testing.T) {
193194
func TestHandleApplyResourceMissingParameters(t *testing.T) {
194195
// Create a mock k8s client
195196
mockClient := &k8s.Client{}
196-
197+
197198
// Create an implementation
198199
impl := NewImplementation(mockClient)
199-
200+
200201
// Test cases for missing parameters
201202
testCases := []struct {
202203
name string
203204
arguments map[string]interface{}
204205
errorMsg string
205206
}{
206207
{
207-
name: "Missing resource_type",
208+
name: "Missing resource_type",
208209
arguments: map[string]interface{}{
209210
"group": "apps",
210211
"version": "v1",
@@ -214,7 +215,7 @@ func TestHandleApplyResourceMissingParameters(t *testing.T) {
214215
errorMsg: "resource_type is required",
215216
},
216217
{
217-
name: "Missing version",
218+
name: "Missing version",
218219
arguments: map[string]interface{}{
219220
"resource_type": "clustered",
220221
"group": "apps",
@@ -224,7 +225,7 @@ func TestHandleApplyResourceMissingParameters(t *testing.T) {
224225
errorMsg: "version is required",
225226
},
226227
{
227-
name: "Missing resource",
228+
name: "Missing resource",
228229
arguments: map[string]interface{}{
229230
"resource_type": "clustered",
230231
"group": "apps",
@@ -234,7 +235,7 @@ func TestHandleApplyResourceMissingParameters(t *testing.T) {
234235
errorMsg: "resource is required",
235236
},
236237
{
237-
name: "Missing namespace for namespaced resource",
238+
name: "Missing namespace for namespaced resource",
238239
arguments: map[string]interface{}{
239240
"resource_type": "namespaced",
240241
"group": "apps",
@@ -245,7 +246,7 @@ func TestHandleApplyResourceMissingParameters(t *testing.T) {
245246
errorMsg: "namespace is required for namespaced resources",
246247
},
247248
{
248-
name: "Missing manifest",
249+
name: "Missing manifest",
249250
arguments: map[string]interface{}{
250251
"resource_type": "clustered",
251252
"group": "apps",
@@ -255,27 +256,27 @@ func TestHandleApplyResourceMissingParameters(t *testing.T) {
255256
errorMsg: "manifest is required",
256257
},
257258
}
258-
259+
259260
for _, tc := range testCases {
260261
t.Run(tc.name, func(t *testing.T) {
261262
// Create a test request
262263
request := mcp.CallToolRequest{}
263-
request.Params.Name = "apply_resource"
264+
request.Params.Name = common.ToolApplyResource
264265
request.Params.Arguments = tc.arguments
265-
266+
266267
// Test HandleApplyResource
267268
ctx := context.Background()
268269
result, err := impl.HandleApplyResource(ctx, request)
269-
270+
270271
// Verify there was no error
271272
assert.NoError(t, err, "HandleApplyResource should not return an error")
272-
273+
273274
// Verify the result is not nil
274275
assert.NotNil(t, result, "Result should not be nil")
275-
276+
276277
// Verify the result is an error
277278
assert.True(t, result.IsError, "Result should be an error")
278-
279+
279280
// Verify the error message
280281
textContent, ok := mcp.AsTextContent(result.Content[0])
281282
assert.True(t, ok, "Content should be TextContent")
@@ -287,34 +288,34 @@ func TestHandleApplyResourceMissingParameters(t *testing.T) {
287288
func TestHandleApplyResourceInvalidResourceType(t *testing.T) {
288289
// Create a mock k8s client
289290
mockClient := &k8s.Client{}
290-
291+
291292
// Create an implementation
292293
impl := NewImplementation(mockClient)
293-
294+
294295
// Create a test request with invalid resource_type
295296
request := mcp.CallToolRequest{}
296-
request.Params.Name = "apply_resource"
297+
request.Params.Name = common.ToolApplyResource
297298
request.Params.Arguments = map[string]interface{}{
298299
"resource_type": "invalid",
299300
"group": "apps",
300301
"version": "v1",
301302
"resource": "deployments",
302303
"manifest": map[string]interface{}{},
303304
}
304-
305+
305306
// Test HandleApplyResource
306307
ctx := context.Background()
307308
result, err := impl.HandleApplyResource(ctx, request)
308-
309+
309310
// Verify there was no error
310311
assert.NoError(t, err, "HandleApplyResource should not return an error")
311-
312+
312313
// Verify the result is not nil
313314
assert.NotNil(t, result, "Result should not be nil")
314-
315+
315316
// Verify the result is an error
316317
assert.True(t, result.IsError, "Result should be an error")
317-
318+
318319
// Verify the error message
319320
textContent, ok := mcp.AsTextContent(result.Content[0])
320321
assert.True(t, ok, "Content should be TextContent")
@@ -324,30 +325,30 @@ func TestHandleApplyResourceInvalidResourceType(t *testing.T) {
324325
func TestHandleApplyResourceApplyError(t *testing.T) {
325326
// Create a mock k8s client
326327
mockClient := &k8s.Client{}
327-
328+
328329
// Create a fake dynamic client
329330
scheme := runtime.NewScheme()
330331
fakeDynamicClient := fake.NewSimpleDynamicClient(scheme)
331-
332+
332333
// Add a fake get response (resource not found)
333334
fakeDynamicClient.PrependReactor("get", "clusterroles", func(action ktesting.Action) (handled bool, ret runtime.Object, err error) {
334335
return true, nil, fmt.Errorf("not found: clusterroles \"test-cluster-role\" not found")
335336
})
336-
337+
337338
// Add a fake create response with error
338339
fakeDynamicClient.PrependReactor("create", "clusterroles", func(action ktesting.Action) (handled bool, ret runtime.Object, err error) {
339340
return true, nil, fmt.Errorf("failed to create resource")
340341
})
341-
342+
342343
// Set the dynamic client
343344
mockClient.SetDynamicClient(fakeDynamicClient)
344-
345+
345346
// Create an implementation
346347
impl := NewImplementation(mockClient)
347-
348+
348349
// Create a test request
349350
request := mcp.CallToolRequest{}
350-
request.Params.Name = "apply_resource"
351+
request.Params.Name = common.ToolApplyResource
351352
request.Params.Arguments = map[string]interface{}{
352353
"resource_type": "clustered",
353354
"group": "rbac.authorization.k8s.io",
@@ -361,22 +362,22 @@ func TestHandleApplyResourceApplyError(t *testing.T) {
361362
},
362363
},
363364
}
364-
365+
365366
// Test HandleApplyResource
366367
ctx := context.Background()
367368
result, err := impl.HandleApplyResource(ctx, request)
368-
369+
369370
// Verify there was no error
370371
assert.NoError(t, err, "HandleApplyResource should not return an error")
371-
372+
372373
// Verify the result is not nil
373374
assert.NotNil(t, result, "Result should not be nil")
374-
375+
375376
// Verify the result is an error
376377
assert.True(t, result.IsError, "Result should be an error")
377-
378+
378379
// Verify the error message
379380
textContent, ok := mcp.AsTextContent(result.Content[0])
380381
assert.True(t, ok, "Content should be TextContent")
381382
assert.Contains(t, textContent.Text, "Failed to apply resource", "Error message should contain 'Failed to apply resource'")
382-
}
383+
}

pkg/mcp/delete_resource.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"fmt"
66

7+
"github.com/StacklokLabs/mkp/pkg/common"
78
"github.com/mark3labs/mcp-go/mcp"
89
"k8s.io/apimachinery/pkg/runtime/schema"
910
)
@@ -67,7 +68,7 @@ func (m *Implementation) HandleDeleteResource(ctx context.Context, request mcp.C
6768

6869
// NewDeleteResourceTool creates a new delete_resource tool
6970
func NewDeleteResourceTool() mcp.Tool {
70-
return mcp.NewTool("delete_resource",
71+
return mcp.NewTool(common.ToolDeleteResource,
7172
mcp.WithDescription("Delete a Kubernetes resource"),
7273
mcp.WithString("resource_type",
7374
mcp.Description("Type of resource to delete (clustered or namespaced)"),

0 commit comments

Comments
 (0)