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  }