knative.dev/pkg@v0.0.0-20260602142205-ac97e43f6622/kref/knative_reference.go (about) 1 /* 2 Copyright 2020 The Knative Authors 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package kref 18 19 import ( 20 "fmt" 21 22 apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" 23 apiextensionsv1lister "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1" 24 "k8s.io/apimachinery/pkg/api/meta" 25 "k8s.io/apimachinery/pkg/runtime/schema" 26 duckv1 "knative.dev/pkg/apis/duck/v1" 27 ) 28 29 // KReferenceResolver is an object that resolves the KReference.Group field 30 // Note: This API is EXPERIMENTAL and might break anytime. For more details: https://github.com/knative/eventing/issues/5086 31 type KReferenceResolver struct { 32 crdLister apiextensionsv1lister.CustomResourceDefinitionLister 33 } 34 35 // NewKReferenceResolver creates a new KReferenceResolver from a crdLister 36 // Note: This API is EXPERIMENTAL and might break anytime. For more details: https://github.com/knative/eventing/issues/5086 37 func NewKReferenceResolver(crdLister apiextensionsv1lister.CustomResourceDefinitionLister) *KReferenceResolver { 38 return &KReferenceResolver{crdLister: crdLister} 39 } 40 41 // ResolveGroup resolves the APIVersion of a KReference starting from the Group. 42 // In order to execute this method, you need RBAC to read the CRD of the Resource referred in this KReference. 43 // Note: This API is EXPERIMENTAL and might break anytime. For more details: https://github.com/knative/eventing/issues/5086 44 func (resolver *KReferenceResolver) ResolveGroup(kr *duckv1.KReference) (*duckv1.KReference, error) { 45 if kr.Group == "" { 46 // Nothing to do here 47 return kr, nil 48 } 49 50 kr = kr.DeepCopy() 51 52 actualGvk := schema.GroupVersionKind{Group: kr.Group, Kind: kr.Kind} 53 pluralGvk, _ := meta.UnsafeGuessKindToResource(actualGvk) 54 crd, err := resolver.crdLister.Get(pluralGvk.GroupResource().String()) 55 if err != nil { 56 return nil, err 57 } 58 59 actualGvk.Version, err = findCRDStorageVersion(crd) 60 if err != nil { 61 return nil, err 62 } 63 64 kr.APIVersion, kr.Kind = actualGvk.ToAPIVersionAndKind() 65 66 return kr, nil 67 } 68 69 // This function runs under the assumption that there must be exactly one "storage" version 70 func findCRDStorageVersion(crd *apiextensionsv1.CustomResourceDefinition) (string, error) { 71 for _, version := range crd.Spec.Versions { 72 if version.Storage { 73 return version.Name, nil 74 } 75 } 76 return "", fmt.Errorf("this CRD %s doesn't have a storage version! Kubernetes, you're drunk, go home", crd.Name) 77 }