diff --git a/go.mod b/go.mod index 9b36bfa77fcc1..4486011031529 100644 --- a/go.mod +++ b/go.mod @@ -275,6 +275,7 @@ require ( k8s.io/component-base v0.34.1 k8s.io/klog/v2 v2.130.1 k8s.io/kubectl v0.34.1 + k8s.io/metrics v0.34.1 k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 sigs.k8s.io/controller-runtime v0.22.1 sigs.k8s.io/controller-tools v0.17.1 @@ -628,7 +629,6 @@ require ( gotest.tools/gotestsum v1.13.0 // indirect k8s.io/component-helpers v0.34.1 // indirect k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect - k8s.io/metrics v0.34.1 // indirect mvdan.cc/sh/v3 v3.7.0 // indirect oras.land/oras-go/v2 v2.6.0 // indirect sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect diff --git a/integrations/terraform-mwi/go.mod b/integrations/terraform-mwi/go.mod index 505fcff8e1999..bed4b9c78ec1c 100644 --- a/integrations/terraform-mwi/go.mod +++ b/integrations/terraform-mwi/go.mod @@ -528,6 +528,7 @@ require ( k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect k8s.io/kubectl v0.34.1 // indirect + k8s.io/metrics v0.34.1 // indirect k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect mvdan.cc/sh/v3 v3.7.0 // indirect oras.land/oras-go/v2 v2.6.0 // indirect diff --git a/integrations/terraform-mwi/go.sum b/integrations/terraform-mwi/go.sum index ebf46b62f63ad..f9d529d9fd7d0 100644 --- a/integrations/terraform-mwi/go.sum +++ b/integrations/terraform-mwi/go.sum @@ -3075,6 +3075,8 @@ k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b h1:MloQ9/bdJyIu9lb1PzujOP k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b/go.mod h1:UZ2yyWbFTpuhSbFhv24aGNOdoRdJZgsIObGBUaYVsts= k8s.io/kubectl v0.34.1 h1:1qP1oqT5Xc93K+H8J7ecpBjaz511gan89KO9Vbsh/OI= k8s.io/kubectl v0.34.1/go.mod h1:JRYlhJpGPyk3dEmJ+BuBiOB9/dAvnrALJEiY/C5qa6A= +k8s.io/metrics v0.34.1 h1:374Rexmp1xxgRt64Bi0TsjAM8cA/Y8skwCoPdjtIslE= +k8s.io/metrics v0.34.1/go.mod h1:Drf5kPfk2NJrlpcNdSiAAHn/7Y9KqxpRNagByM7Ei80= k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= diff --git a/integrations/terraform/go.mod b/integrations/terraform/go.mod index b75208aaf4a9f..44be0d30ae8fd 100644 --- a/integrations/terraform/go.mod +++ b/integrations/terraform/go.mod @@ -528,6 +528,7 @@ require ( k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect k8s.io/kubectl v0.34.1 // indirect + k8s.io/metrics v0.34.1 // indirect k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect mvdan.cc/sh/v3 v3.7.0 // indirect oras.land/oras-go/v2 v2.6.0 // indirect diff --git a/integrations/terraform/go.sum b/integrations/terraform/go.sum index bcb96a57d509c..51076f2f9bcfb 100644 --- a/integrations/terraform/go.sum +++ b/integrations/terraform/go.sum @@ -3188,6 +3188,8 @@ k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b h1:MloQ9/bdJyIu9lb1PzujOP k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b/go.mod h1:UZ2yyWbFTpuhSbFhv24aGNOdoRdJZgsIObGBUaYVsts= k8s.io/kubectl v0.34.1 h1:1qP1oqT5Xc93K+H8J7ecpBjaz511gan89KO9Vbsh/OI= k8s.io/kubectl v0.34.1/go.mod h1:JRYlhJpGPyk3dEmJ+BuBiOB9/dAvnrALJEiY/C5qa6A= +k8s.io/metrics v0.34.1 h1:374Rexmp1xxgRt64Bi0TsjAM8cA/Y8skwCoPdjtIslE= +k8s.io/metrics v0.34.1/go.mod h1:Drf5kPfk2NJrlpcNdSiAAHn/7Y9KqxpRNagByM7Ei80= k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= diff --git a/lib/kube/proxy/scheme.go b/lib/kube/proxy/scheme.go index d21dd7bb60729..c3735451969c1 100644 --- a/lib/kube/proxy/scheme.go +++ b/lib/kube/proxy/scheme.go @@ -38,6 +38,8 @@ import ( "k8s.io/client-go/discovery" "k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes/scheme" + "k8s.io/metrics/pkg/apis/metrics" + metricsv1beta1 "k8s.io/metrics/pkg/apis/metrics/v1beta1" ) const ( @@ -69,6 +71,15 @@ func init() { func registerDefaultKubeTypes(s *runtime.Scheme) error { // Register external types for Scheme metav1.AddToGroupVersion(s, schema.GroupVersion{Group: "", Version: "v1"}) + + if err := metrics.AddToScheme(s); err != nil { + return trace.Wrap(err) + } + + if err := metricsv1beta1.AddToScheme(s); err != nil { + return trace.Wrap(err) + } + if err := metav1.AddMetaToScheme(s); err != nil { return trace.Wrap(err) } diff --git a/lib/kube/proxy/scheme_test.go b/lib/kube/proxy/scheme_test.go index 1ce10bfa44c95..8e3df55e3e75c 100644 --- a/lib/kube/proxy/scheme_test.go +++ b/lib/kube/proxy/scheme_test.go @@ -22,9 +22,14 @@ import ( "testing" "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/discovery" "k8s.io/client-go/kubernetes" + "k8s.io/metrics/pkg/apis/metrics" + metricsv1beta1 "k8s.io/metrics/pkg/apis/metrics/v1beta1" "github.com/gravitational/teleport/lib/utils/log/logtest" ) @@ -61,3 +66,76 @@ func (c *clientSet) ServerGroupsAndResources() ([]*metav1.APIGroup, []*metav1.AP &fakeAPIResource, }, nil } + +func TestRegisterDefaultKubeTypes(t *testing.T) { + scheme := runtime.NewScheme() + err := registerDefaultKubeTypes(scheme) + require.NoError(t, err) + + // Check that some known types are registered + tests := []struct { + gvk schema.GroupVersionKind + expectedType runtime.Object + }{ + { + gvk: schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Pod"}, + expectedType: &corev1.Pod{}, + }, + { + gvk: schema.GroupVersionKind{Group: "", Version: "v1", Kind: "PodList"}, + expectedType: &corev1.PodList{}, + }, + { + gvk: schema.GroupVersionKind{Group: "metrics.k8s.io", Version: "v1beta1", Kind: "PodMetrics"}, + expectedType: &metricsv1beta1.PodMetrics{}, + }, + { + gvk: schema.GroupVersionKind{Group: "metrics.k8s.io", Version: "v1beta1", Kind: "NodeMetrics"}, + expectedType: &metricsv1beta1.NodeMetrics{}, + }, + { + gvk: schema.GroupVersionKind{Group: "metrics.k8s.io", Version: runtime.APIVersionInternal, Kind: "PodMetrics"}, + expectedType: &metrics.PodMetrics{}, + }, + { + gvk: schema.GroupVersionKind{Group: "metrics.k8s.io", Version: runtime.APIVersionInternal, Kind: "NodeMetrics"}, + expectedType: &metrics.NodeMetrics{}, + }, + + // --- metav1 types --- + { + gvk: schema.GroupVersionKind{Group: "meta.k8s.io", Version: "v1", Kind: "PartialObjectMetadata"}, + expectedType: &metav1.PartialObjectMetadata{}, + }, + { + gvk: schema.GroupVersionKind{Group: "meta.k8s.io", Version: "v1", Kind: "PartialObjectMetadataList"}, + expectedType: &metav1.PartialObjectMetadataList{}, + }, + { + gvk: schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Status"}, + expectedType: &metav1.Status{}, + }, + { + gvk: schema.GroupVersionKind{Group: "", Version: "v1", Kind: "APIVersions"}, + expectedType: &metav1.APIVersions{}, + }, + { + gvk: schema.GroupVersionKind{Group: "", Version: "v1", Kind: "APIGroupList"}, + expectedType: &metav1.APIGroupList{}, + }, + { + gvk: schema.GroupVersionKind{Group: "", Version: "v1", Kind: "APIGroup"}, + expectedType: &metav1.APIGroup{}, + }, + { + gvk: schema.GroupVersionKind{Group: "", Version: "v1", Kind: "APIResourceList"}, + expectedType: &metav1.APIResourceList{}, + }, + } + + for _, testCase := range tests { + newType, err := scheme.New(testCase.gvk) + require.NoError(t, err, "expected type %v to be registered", testCase.gvk) + require.IsType(t, testCase.expectedType, newType, "expected type %v to be of type %T", testCase.gvk, testCase.expectedType) + } +}