Skip to content

Commit 50277ce

Browse files
committed
feat: configuration minification is optional
1 parent fe62e31 commit 50277ce

File tree

4 files changed

+82
-19
lines changed

4 files changed

+82
-19
lines changed

pkg/kubernetes/configuration.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55
"k8s.io/client-go/tools/clientcmd/api/latest"
66
)
77

8-
func ConfigurationView() (string, error) {
8+
func ConfigurationView(minify bool) (string, error) {
99
var cfg clientcmdapi.Config
1010
var err error
1111
inClusterConfig, err := InClusterConfig()
@@ -26,8 +26,10 @@ func ConfigurationView() (string, error) {
2626
} else if cfg, err = resolveConfig().RawConfig(); err != nil {
2727
return "", err
2828
}
29-
if err = clientcmdapi.MinifyConfig(&cfg); err != nil {
30-
return "", err
29+
if minify {
30+
if err = clientcmdapi.MinifyConfig(&cfg); err != nil {
31+
return "", err
32+
}
3133
}
3234
if err = clientcmdapi.FlattenConfig(&cfg); err != nil {
3335
return "", err

pkg/mcp/common_test.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,19 +144,24 @@ func testCase(t *testing.T, test func(c *mcpContext)) {
144144
// withKubeConfig sets up a fake kubeconfig in the temp directory based on the provided rest.Config
145145
func (c *mcpContext) withKubeConfig(rc *rest.Config) *api.Config {
146146
fakeConfig := api.NewConfig()
147-
fakeConfig.CurrentContext = "fake-context"
148-
fakeConfig.Contexts["fake-context"] = api.NewContext()
149-
fakeConfig.Contexts["fake-context"].Cluster = "fake"
150-
fakeConfig.Contexts["fake-context"].AuthInfo = "fake"
151147
fakeConfig.Clusters["fake"] = api.NewCluster()
152148
fakeConfig.Clusters["fake"].Server = "https://example.com"
149+
fakeConfig.Clusters["additional-cluster"] = api.NewCluster()
153150
fakeConfig.AuthInfos["fake"] = api.NewAuthInfo()
151+
fakeConfig.AuthInfos["additional-auth"] = api.NewAuthInfo()
154152
if rc != nil {
155153
fakeConfig.Clusters["fake"].Server = rc.Host
156154
fakeConfig.Clusters["fake"].CertificateAuthorityData = rc.TLSClientConfig.CAData
157155
fakeConfig.AuthInfos["fake"].ClientKeyData = rc.TLSClientConfig.KeyData
158156
fakeConfig.AuthInfos["fake"].ClientCertificateData = rc.TLSClientConfig.CertData
159157
}
158+
fakeConfig.Contexts["fake-context"] = api.NewContext()
159+
fakeConfig.Contexts["fake-context"].Cluster = "fake"
160+
fakeConfig.Contexts["fake-context"].AuthInfo = "fake"
161+
fakeConfig.Contexts["additional-context"] = api.NewContext()
162+
fakeConfig.Contexts["additional-context"].Cluster = "additional-cluster"
163+
fakeConfig.Contexts["additional-context"].AuthInfo = "additional-auth"
164+
fakeConfig.CurrentContext = "fake-context"
160165
kubeConfig := filepath.Join(c.tempDir, "config")
161166
_ = clientcmd.WriteToFile(*fakeConfig, kubeConfig)
162167
_ = os.Setenv("KUBECONFIG", kubeConfig)

pkg/mcp/configuration.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,21 @@ func (s *Server) initConfiguration() []server.ServerTool {
1212
return []server.ServerTool{
1313
{mcp.NewTool("configuration_view",
1414
mcp.WithDescription("Get the current Kubernetes configuration content as a kubeconfig YAML"),
15+
mcp.WithBoolean("minified", mcp.Description("Return a minified version of the configuration. "+
16+
"If set to true, keeps only the current-context and the relevant pieces of the configuration for that context. "+
17+
"If set to false, all contexts, clusters, auth-infos, and users are returned in the configuration. "+
18+
"(Optional, default true)")),
1519
), configurationView},
1620
}
1721
}
1822

19-
func configurationView(_ context.Context, _ mcp.CallToolRequest) (*mcp.CallToolResult, error) {
20-
ret, err := kubernetes.ConfigurationView()
23+
func configurationView(_ context.Context, ctr mcp.CallToolRequest) (*mcp.CallToolResult, error) {
24+
minify := true
25+
minified := ctr.Params.Arguments["minified"]
26+
if _, ok := minified.(bool); ok {
27+
minify = minified.(bool)
28+
}
29+
ret, err := kubernetes.ConfigurationView(minify)
2130
if err != nil {
2231
err = fmt.Errorf("failed to get configuration: %v", err)
2332
}

pkg/mcp/configuration_test.go

Lines changed: 57 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,40 +26,87 @@ func TestConfigurationView(t *testing.T) {
2626
})
2727
t.Run("configuration_view returns current-context", func(t *testing.T) {
2828
if decoded.CurrentContext != "fake-context" {
29-
t.Fatalf("fake-context not found: %v", decoded.CurrentContext)
29+
t.Errorf("fake-context not found: %v", decoded.CurrentContext)
3030
}
3131
})
3232
t.Run("configuration_view returns context info", func(t *testing.T) {
3333
if len(decoded.Contexts) != 1 {
34-
t.Fatalf("invalid context count, expected 1, got %v", len(decoded.Contexts))
34+
t.Errorf("invalid context count, expected 1, got %v", len(decoded.Contexts))
3535
}
3636
if decoded.Contexts[0].Name != "fake-context" {
37-
t.Fatalf("fake-context not found: %v", decoded.Contexts)
37+
t.Errorf("fake-context not found: %v", decoded.Contexts)
3838
}
3939
if decoded.Contexts[0].Context.Cluster != "fake" {
40-
t.Fatalf("fake-cluster not found: %v", decoded.Contexts)
40+
t.Errorf("fake-cluster not found: %v", decoded.Contexts)
4141
}
4242
if decoded.Contexts[0].Context.AuthInfo != "fake" {
43-
t.Fatalf("fake-auth not found: %v", decoded.Contexts)
43+
t.Errorf("fake-auth not found: %v", decoded.Contexts)
4444
}
4545
})
4646
t.Run("configuration_view returns cluster info", func(t *testing.T) {
4747
if len(decoded.Clusters) != 1 {
48-
t.Fatalf("invalid cluster count, expected 1, got %v", len(decoded.Clusters))
48+
t.Errorf("invalid cluster count, expected 1, got %v", len(decoded.Clusters))
4949
}
5050
if decoded.Clusters[0].Name != "fake" {
51-
t.Fatalf("fake-cluster not found: %v", decoded.Clusters)
51+
t.Errorf("fake-cluster not found: %v", decoded.Clusters)
5252
}
5353
if decoded.Clusters[0].Cluster.Server != "https://example.com" {
54-
t.Fatalf("fake-server not found: %v", decoded.Clusters)
54+
t.Errorf("fake-server not found: %v", decoded.Clusters)
5555
}
5656
})
5757
t.Run("configuration_view returns auth info", func(t *testing.T) {
5858
if len(decoded.AuthInfos) != 1 {
59-
t.Fatalf("invalid auth info count, expected 1, got %v", len(decoded.AuthInfos))
59+
t.Errorf("invalid auth info count, expected 1, got %v", len(decoded.AuthInfos))
6060
}
6161
if decoded.AuthInfos[0].Name != "fake" {
62-
t.Fatalf("fake-auth not found: %v", decoded.AuthInfos)
62+
t.Errorf("fake-auth not found: %v", decoded.AuthInfos)
63+
}
64+
})
65+
toolResult, err = c.callTool("configuration_view", map[string]interface{}{
66+
"minified": false,
67+
})
68+
t.Run("configuration_view with minified=false returns configuration", func(t *testing.T) {
69+
if err != nil {
70+
t.Fatalf("call tool failed %v", err)
71+
}
72+
})
73+
err = yaml.Unmarshal([]byte(toolResult.Content[0].(mcp.TextContent).Text), &decoded)
74+
t.Run("configuration_view with minified=false has yaml content", func(t *testing.T) {
75+
if err != nil {
76+
t.Fatalf("invalid tool result content %v", err)
77+
}
78+
})
79+
t.Run("configuration_view with minified=false returns additional context info", func(t *testing.T) {
80+
if len(decoded.Contexts) != 2 {
81+
t.Errorf("invalid context count, expected2, got %v", len(decoded.Contexts))
82+
}
83+
if decoded.Contexts[0].Name != "additional-context" {
84+
t.Errorf("additional-context not found: %v", decoded.Contexts)
85+
}
86+
if decoded.Contexts[0].Context.Cluster != "additional-cluster" {
87+
t.Errorf("additional-cluster not found: %v", decoded.Contexts)
88+
}
89+
if decoded.Contexts[0].Context.AuthInfo != "additional-auth" {
90+
t.Errorf("additional-auth not found: %v", decoded.Contexts)
91+
}
92+
if decoded.Contexts[1].Name != "fake-context" {
93+
t.Errorf("fake-context not found: %v", decoded.Contexts)
94+
}
95+
})
96+
t.Run("configuration_view with minified=false returns cluster info", func(t *testing.T) {
97+
if len(decoded.Clusters) != 2 {
98+
t.Errorf("invalid cluster count, expected 2, got %v", len(decoded.Clusters))
99+
}
100+
if decoded.Clusters[0].Name != "additional-cluster" {
101+
t.Errorf("additional-cluster not found: %v", decoded.Clusters)
102+
}
103+
})
104+
t.Run("configuration_view with minified=false returns auth info", func(t *testing.T) {
105+
if len(decoded.AuthInfos) != 2 {
106+
t.Errorf("invalid auth info count, expected 2, got %v", len(decoded.AuthInfos))
107+
}
108+
if decoded.AuthInfos[0].Name != "additional-auth" {
109+
t.Errorf("additional-auth not found: %v", decoded.AuthInfos)
63110
}
64111
})
65112
})

0 commit comments

Comments
 (0)