66 "github.com/manusa/kubernetes-mcp-server/pkg/helm"
77 v1 "k8s.io/api/core/v1"
88 "k8s.io/apimachinery/pkg/api/meta"
9- "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
109 "k8s.io/apimachinery/pkg/runtime"
11- "k8s.io/apimachinery/pkg/runtime/schema"
1210 "k8s.io/client-go/discovery"
1311 "k8s.io/client-go/discovery/cached/memory"
1412 "k8s.io/client-go/dynamic"
@@ -19,7 +17,6 @@ import (
1917 "k8s.io/client-go/tools/clientcmd"
2018 clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
2119 "k8s.io/klog/v2"
22- "k8s.io/metrics/pkg/apis/metrics"
2320 "strings"
2421)
2522
@@ -29,36 +26,11 @@ const (
2926
3027type CloseWatchKubeConfig func () error
3128
32- type Kubernetes interface {
33- WatchKubeConfig (onKubeConfigChange func () error )
34- Close ()
35- Derived (ctx context.Context ) DerivedKubernetes
36- ConfigurationView (minify bool ) (runtime.Object , error )
37- IsOpenShift (ctx context.Context ) bool
29+ type Kubernetes struct {
30+ manager * Manager
3831}
3932
40- type DerivedKubernetes interface {
41- IsOpenShift (ctx context.Context ) bool
42- CacheInvalidate ()
43- NewHelm () * helm.Helm
44- EventsList (ctx context.Context , namespace string ) ([]map [string ]any , error )
45- NamespacesList (ctx context.Context , options ResourceListOptions ) (runtime.Unstructured , error )
46- PodsListInAllNamespaces (ctx context.Context , options ResourceListOptions ) (runtime.Unstructured , error )
47- PodsListInNamespace (ctx context.Context , namespace string , options ResourceListOptions ) (runtime.Unstructured , error )
48- PodsGet (ctx context.Context , namespace , name string ) (* unstructured.Unstructured , error )
49- PodsDelete (ctx context.Context , namespace , name string ) (string , error )
50- PodsLog (ctx context.Context , namespace , name , container string ) (string , error )
51- PodsRun (ctx context.Context , namespace , name , image string , port int32 ) ([]* unstructured.Unstructured , error )
52- PodsTop (ctx context.Context , options PodsTopOptions ) (* metrics.PodMetricsList , error )
53- PodsExec (ctx context.Context , namespace , name , container string , command []string ) (string , error )
54- ProjectsList (ctx context.Context , options ResourceListOptions ) (runtime.Unstructured , error )
55- ResourcesList (ctx context.Context , gvk * schema.GroupVersionKind , namespace string , options ResourceListOptions ) (runtime.Unstructured , error )
56- ResourcesGet (ctx context.Context , gvk * schema.GroupVersionKind , namespace , name string ) (* unstructured.Unstructured , error )
57- ResourcesCreateOrUpdate (ctx context.Context , resource string ) ([]* unstructured.Unstructured , error )
58- ResourcesDelete (ctx context.Context , gvk * schema.GroupVersionKind , namespace , name string ) error
59- }
60-
61- type kubernetes struct {
33+ type Manager struct {
6234 // Kubeconfig path override
6335 Kubeconfig string
6436 cfg * rest.Config
@@ -72,8 +44,8 @@ type kubernetes struct {
7244 dynamicClient * dynamic.DynamicClient
7345}
7446
75- func NewKubernetes (kubeconfig string ) (Kubernetes , error ) {
76- k8s := & kubernetes {
47+ func NewKubernetes (kubeconfig string ) (* Manager , error ) {
48+ k8s := & Manager {
7749 Kubeconfig : kubeconfig ,
7850 }
7951 if err := resolveKubernetesConfigurations (k8s ); err != nil {
@@ -102,11 +74,11 @@ func NewKubernetes(kubeconfig string) (Kubernetes, error) {
10274 return k8s , nil
10375}
10476
105- func (k * kubernetes ) WatchKubeConfig (onKubeConfigChange func () error ) {
106- if k .clientCmdConfig == nil {
77+ func (m * Manager ) WatchKubeConfig (onKubeConfigChange func () error ) {
78+ if m .clientCmdConfig == nil {
10779 return
10880 }
109- kubeConfigFiles := k .clientCmdConfig .ConfigAccess ().GetLoadingPrecedence ()
81+ kubeConfigFiles := m .clientCmdConfig .ConfigAccess ().GetLoadingPrecedence ()
11082 if len (kubeConfigFiles ) == 0 {
11183 return
11284 }
@@ -132,33 +104,33 @@ func (k *kubernetes) WatchKubeConfig(onKubeConfigChange func() error) {
132104 }
133105 }
134106 }()
135- if k .CloseWatchKubeConfig != nil {
136- _ = k .CloseWatchKubeConfig ()
107+ if m .CloseWatchKubeConfig != nil {
108+ _ = m .CloseWatchKubeConfig ()
137109 }
138- k .CloseWatchKubeConfig = watcher .Close
110+ m .CloseWatchKubeConfig = watcher .Close
139111}
140112
141- func (k * kubernetes ) Close () {
142- if k .CloseWatchKubeConfig != nil {
143- _ = k .CloseWatchKubeConfig ()
113+ func (m * Manager ) Close () {
114+ if m .CloseWatchKubeConfig != nil {
115+ _ = m .CloseWatchKubeConfig ()
144116 }
145117}
146118
147- func (k * kubernetes ) ToDiscoveryClient () (discovery.CachedDiscoveryInterface , error ) {
148- return k .discoveryClient , nil
119+ func (m * Manager ) ToDiscoveryClient () (discovery.CachedDiscoveryInterface , error ) {
120+ return m .discoveryClient , nil
149121}
150122
151- func (k * kubernetes ) ToRESTMapper () (meta.RESTMapper , error ) {
152- return k .deferredDiscoveryRESTMapper , nil
123+ func (m * Manager ) ToRESTMapper () (meta.RESTMapper , error ) {
124+ return m .deferredDiscoveryRESTMapper , nil
153125}
154126
155- func (k * kubernetes ) Derived (ctx context.Context ) DerivedKubernetes {
127+ func (m * Manager ) Derived (ctx context.Context ) * Kubernetes {
156128 authorization , ok := ctx .Value (AuthorizationHeader ).(string )
157129 if ! ok || ! strings .HasPrefix (authorization , "Bearer " ) {
158- return k
130+ return & Kubernetes { manager : m }
159131 }
160132 klog .V (5 ).Infof ("%s header found (Bearer), using provided bearer token" , AuthorizationHeader )
161- derivedCfg := rest .CopyConfig (k .cfg )
133+ derivedCfg := rest .CopyConfig (m .cfg )
162134 derivedCfg .BearerToken = strings .TrimPrefix (authorization , "Bearer " )
163135 derivedCfg .BearerTokenFile = ""
164136 derivedCfg .Username = ""
@@ -167,41 +139,42 @@ func (k *kubernetes) Derived(ctx context.Context) DerivedKubernetes {
167139 derivedCfg .AuthConfigPersister = nil
168140 derivedCfg .ExecProvider = nil
169141 derivedCfg .Impersonate = rest.ImpersonationConfig {}
170- clientCmdApiConfig , err := k .clientCmdConfig .RawConfig ()
142+ clientCmdApiConfig , err := m .clientCmdConfig .RawConfig ()
171143 if err != nil {
172- return k
144+ return & Kubernetes { manager : m }
173145 }
174146 clientCmdApiConfig .AuthInfos = make (map [string ]* clientcmdapi.AuthInfo )
175- derived := & kubernetes {
176- Kubeconfig : k .Kubeconfig ,
147+ derived := & Kubernetes { manager : & Manager {
148+ Kubeconfig : m .Kubeconfig ,
177149 clientCmdConfig : clientcmd .NewDefaultClientConfig (clientCmdApiConfig , nil ),
178150 cfg : derivedCfg ,
179- scheme : k .scheme ,
180- parameterCodec : k .parameterCodec ,
181- }
182- derived .clientSet , err = clientgokubernetes .NewForConfig (derived .cfg )
151+ scheme : m .scheme ,
152+ parameterCodec : m .parameterCodec ,
153+ }}
154+ derived .manager . clientSet , err = clientgokubernetes .NewForConfig (derived . manager .cfg )
183155 if err != nil {
184- return k
156+ return & Kubernetes { manager : m }
185157 }
186- derived .discoveryClient = memory .NewMemCacheClient (discovery .NewDiscoveryClient (derived .clientSet .CoreV1 ().RESTClient ()))
187- derived .deferredDiscoveryRESTMapper = restmapper .NewDeferredDiscoveryRESTMapper (derived .discoveryClient )
188- derived .dynamicClient , err = dynamic .NewForConfig (derived .cfg )
158+ derived .manager . discoveryClient = memory .NewMemCacheClient (discovery .NewDiscoveryClient (derived . manager .clientSet .CoreV1 ().RESTClient ()))
159+ derived .manager . deferredDiscoveryRESTMapper = restmapper .NewDeferredDiscoveryRESTMapper (derived . manager .discoveryClient )
160+ derived .manager . dynamicClient , err = dynamic .NewForConfig (derived . manager .cfg )
189161 if err != nil {
190- return k
162+ return & Kubernetes { manager : m }
191163 }
192164 return derived
193165}
194166
195- func (k * kubernetes ) CacheInvalidate () {
196- if k .discoveryClient != nil {
197- k .discoveryClient .Invalidate ()
167+ // TODO: check test to see why cache isn't getting invalidated automatically https://github.com/manusa/kubernetes-mcp-server/pull/125#discussion_r2152194784
168+ func (k * Kubernetes ) CacheInvalidate () {
169+ if k .manager .discoveryClient != nil {
170+ k .manager .discoveryClient .Invalidate ()
198171 }
199- if k .deferredDiscoveryRESTMapper != nil {
200- k .deferredDiscoveryRESTMapper .Reset ()
172+ if k .manager . deferredDiscoveryRESTMapper != nil {
173+ k .manager . deferredDiscoveryRESTMapper .Reset ()
201174 }
202175}
203176
204- func (k * kubernetes ) NewHelm () * helm.Helm {
177+ func (k * Kubernetes ) NewHelm () * helm.Helm {
205178 // This is a derived Kubernetes, so it already has the Helm initialized
206- return helm .NewHelm (k )
179+ return helm .NewHelm (k . manager )
207180}
0 commit comments