11package kubernetes
22
33import (
4+ "context"
5+ "fmt"
6+
47 authorizationv1api "k8s.io/api/authorization/v1"
8+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
59 "k8s.io/apimachinery/pkg/runtime/schema"
610 "k8s.io/client-go/discovery"
711 "k8s.io/client-go/kubernetes"
812 authorizationv1 "k8s.io/client-go/kubernetes/typed/authorization/v1"
913 corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
1014 "k8s.io/client-go/rest"
15+ "k8s.io/metrics/pkg/apis/metrics"
16+ metricsv1beta1api "k8s.io/metrics/pkg/apis/metrics/v1beta1"
17+ metricsv1beta1 "k8s.io/metrics/pkg/client/clientset/versioned/typed/metrics/v1beta1"
1118
1219 "github.com/manusa/kubernetes-mcp-server/pkg/config"
1320)
@@ -18,6 +25,7 @@ import (
1825type AccessControlClientset struct {
1926 delegate kubernetes.Interface
2027 discoveryClient discovery.DiscoveryInterface
28+ metricsV1beta1 * metricsv1beta1.MetricsV1beta1Client
2129 staticConfig * config.StaticConfig // TODO: maybe just store the denied resource slice
2230}
2331
@@ -47,6 +55,29 @@ func (a *AccessControlClientset) PodsExec(namespace, name string) (*rest.Request
4755 SubResource ("exec" ), nil
4856}
4957
58+ func (a * AccessControlClientset ) PodsMetricses (ctx context.Context , namespace , name string , listOptions metav1.ListOptions ) (* metrics.PodMetricsList , error ) {
59+ gvk := & schema.GroupVersionKind {Group : metrics .GroupName , Version : metricsv1beta1api .SchemeGroupVersion .Version , Kind : "PodMetrics" }
60+ if ! isAllowed (a .staticConfig , gvk ) {
61+ return nil , isNotAllowedError (gvk )
62+ }
63+ versionedMetrics := & metricsv1beta1api.PodMetricsList {}
64+ var err error
65+ if name != "" {
66+ m , err := a .metricsV1beta1 .PodMetricses (namespace ).Get (ctx , name , metav1.GetOptions {})
67+ if err != nil {
68+ return nil , fmt .Errorf ("failed to get metrics for pod %s/%s: %w" , namespace , name , err )
69+ }
70+ versionedMetrics .Items = []metricsv1beta1api.PodMetrics {* m }
71+ } else {
72+ versionedMetrics , err = a .metricsV1beta1 .PodMetricses (namespace ).List (ctx , listOptions )
73+ if err != nil {
74+ return nil , fmt .Errorf ("failed to list pod metrics in namespace %s: %w" , namespace , err )
75+ }
76+ }
77+ convertedMetrics := & metrics.PodMetricsList {}
78+ return convertedMetrics , metricsv1beta1api .Convert_v1beta1_PodMetricsList_To_metrics_PodMetricsList (versionedMetrics , convertedMetrics , nil )
79+ }
80+
5081func (a * AccessControlClientset ) Services (namespace string ) (corev1.ServiceInterface , error ) {
5182 gvk := & schema.GroupVersionKind {Group : "" , Version : "v1" , Kind : "Service" }
5283 if ! isAllowed (a .staticConfig , gvk ) {
@@ -68,7 +99,14 @@ func NewAccessControlClientset(cfg *rest.Config, staticConfig *config.StaticConf
6899 if err != nil {
69100 return nil , err
70101 }
102+ metricsClient , err := metricsv1beta1 .NewForConfig (cfg )
103+ if err != nil {
104+ return nil , err
105+ }
71106 return & AccessControlClientset {
72- delegate : clientSet , discoveryClient : clientSet .DiscoveryClient , staticConfig : staticConfig ,
107+ delegate : clientSet ,
108+ discoveryClient : clientSet .DiscoveryClient ,
109+ metricsV1beta1 : metricsClient ,
110+ staticConfig : staticConfig ,
73111 }, nil
74112}
0 commit comments