Skip to content

Commit c7caee6

Browse files
authored
Merge pull request #2553 from L3n41c/fix_gvrfromtype
fix: panic in `util.GVRFromType` for structured types
2 parents b6305cb + c3b1afe commit c7caee6

File tree

4 files changed

+47
-10
lines changed

4 files changed

+47
-10
lines changed

internal/discovery/discovery.go

+10-1
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,16 @@ func (r *CRDiscoverer) PollForCacheUpdates(
209209
// Update the list of enabled custom resources.
210210
var enabledCustomResources []string
211211
for _, factory := range customFactories {
212-
gvrString := util.GVRFromType(factory.Name(), factory.ExpectedType()).String()
212+
gvr, err := util.GVRFromType(factory.Name(), factory.ExpectedType())
213+
if err != nil {
214+
klog.ErrorS(err, "failed to update custom resource stores")
215+
}
216+
var gvrString string
217+
if gvr != nil {
218+
gvrString = gvr.String()
219+
} else {
220+
gvrString = factory.Name()
221+
}
213222
enabledCustomResources = append(enabledCustomResources, gvrString)
214223
}
215224
// Create clients for discovered factories.

internal/store/builder.go

+8-2
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,10 @@ func (b *Builder) DefaultGenerateCustomResourceStoresFunc() ksmtypes.BuildCustom
195195
func (b *Builder) WithCustomResourceStoreFactories(fs ...customresource.RegistryFactory) {
196196
for i := range fs {
197197
f := fs[i]
198-
gvr := util.GVRFromType(f.Name(), f.ExpectedType())
198+
gvr, err := util.GVRFromType(f.Name(), f.ExpectedType())
199+
if err != nil {
200+
klog.ErrorS(err, "Failed to get GVR from type", "resourceName", f.Name(), "expectedType", f.ExpectedType())
201+
}
199202
var gvrString string
200203
if gvr != nil {
201204
gvrString = gvr.String()
@@ -551,7 +554,10 @@ func (b *Builder) buildCustomResourceStores(resourceName string,
551554

552555
familyHeaders := generator.ExtractMetricFamilyHeaders(metricFamilies)
553556

554-
gvr := util.GVRFromType(resourceName, expectedType)
557+
gvr, err := util.GVRFromType(resourceName, expectedType)
558+
if err != nil {
559+
klog.ErrorS(err, "Failed to get GVR from type", "resourceName", resourceName, "expectedType", expectedType)
560+
}
555561
var gvrString string
556562
if gvr != nil {
557563
gvrString = gvr.String()

pkg/customresourcestate/config.go

+10-1
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,16 @@ func FromConfig(decoder ConfigDecoder, discovererInstance *discovery.CRDiscovere
205205
if err != nil {
206206
return nil, fmt.Errorf("failed to create metrics factory for %s: %w", resource.GroupVersionKind, err)
207207
}
208-
gvrString := util.GVRFromType(factory.Name(), factory.ExpectedType()).String()
208+
gvr, err := util.GVRFromType(factory.Name(), factory.ExpectedType())
209+
if err != nil {
210+
return nil, fmt.Errorf("failed to create GVR for %s: %w", resource.GroupVersionKind, err)
211+
}
212+
var gvrString string
213+
if gvr != nil {
214+
gvrString = gvr.String()
215+
} else {
216+
gvrString = factory.Name()
217+
}
209218
if _, ok := factoriesIndex[gvrString]; ok {
210219
klog.InfoS("reloaded factory", "GVR", gvrString)
211220
}

pkg/util/utils.go

+19-6
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import (
2121
"runtime"
2222
"strings"
2323

24-
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
24+
"k8s.io/apimachinery/pkg/api/meta"
2525
"k8s.io/apimachinery/pkg/runtime/schema"
2626
"k8s.io/client-go/discovery"
2727
clientset "k8s.io/client-go/kubernetes"
@@ -95,7 +95,16 @@ func CreateCustomResourceClients(apiserver string, kubeconfig string, factories
9595
if err != nil {
9696
return nil, err
9797
}
98-
gvrString := GVRFromType(f.Name(), f.ExpectedType()).String()
98+
gvr, err := GVRFromType(f.Name(), f.ExpectedType())
99+
if err != nil {
100+
return nil, err
101+
}
102+
var gvrString string
103+
if gvr != nil {
104+
gvrString = gvr.String()
105+
} else {
106+
gvrString = f.Name()
107+
}
99108
customResourceClients[gvrString] = customResourceClient
100109
}
101110
return customResourceClients, nil
@@ -119,12 +128,16 @@ func CreateDiscoveryClient(apiserver string, kubeconfig string) (*discovery.Disc
119128
}
120129

121130
// GVRFromType returns the GroupVersionResource for a given type.
122-
func GVRFromType(resourceName string, expectedType interface{}) *schema.GroupVersionResource {
131+
func GVRFromType(resourceName string, expectedType interface{}) (*schema.GroupVersionResource, error) {
123132
if _, ok := expectedType.(*testUnstructuredMock.Foo); ok {
124133
// testUnstructuredMock.Foo is a mock type for testing
125-
return nil
134+
return nil, nil
126135
}
127-
apiVersion := expectedType.(*unstructured.Unstructured).Object["apiVersion"].(string)
136+
t, err := meta.TypeAccessor(expectedType)
137+
if err != nil {
138+
return nil, fmt.Errorf("Failed to get type accessor for %T: %w", expectedType, err)
139+
}
140+
apiVersion := t.GetAPIVersion()
128141
g, v, found := strings.Cut(apiVersion, "/")
129142
if !found {
130143
g = "core"
@@ -135,7 +148,7 @@ func GVRFromType(resourceName string, expectedType interface{}) *schema.GroupVer
135148
Group: g,
136149
Version: v,
137150
Resource: r,
138-
}
151+
}, nil
139152
}
140153

141154
// GatherAndCount gathers all metrics from the provided Gatherer and counts

0 commit comments

Comments
 (0)