github.com/operator-framework/operator-lifecycle-manager@v0.30.0/pkg/controller/operators/olm/labeler.go (about) 1 package olm 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/operator-framework/api/pkg/operators/v1alpha1" 8 "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/cache" 9 opregistry "github.com/operator-framework/operator-registry/pkg/registry" 10 extv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" 11 extv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" 12 "k8s.io/apimachinery/pkg/labels" 13 ) 14 15 const ( 16 // APILabelKeyPrefix is the key prefix for a CSV's APIs label 17 APILabelKeyPrefix = "olm.api." 18 ) 19 20 type operatorSurface struct { 21 ProvidedAPIs cache.APISet 22 RequiredAPIs cache.APISet 23 } 24 25 func apiSurfaceOfCSV(csv *v1alpha1.ClusterServiceVersion) (*operatorSurface, error) { 26 surface := operatorSurface{ 27 ProvidedAPIs: cache.EmptyAPISet(), 28 RequiredAPIs: cache.EmptyAPISet(), 29 } 30 31 for _, crdDef := range csv.Spec.CustomResourceDefinitions.Owned { 32 parts := strings.SplitN(crdDef.Name, ".", 2) 33 if len(parts) < 2 { 34 return nil, fmt.Errorf("error parsing crd name: %s", crdDef.Name) 35 } 36 surface.ProvidedAPIs[opregistry.APIKey{Plural: parts[0], Group: parts[1], Version: crdDef.Version, Kind: crdDef.Kind}] = struct{}{} 37 } 38 for _, api := range csv.Spec.APIServiceDefinitions.Owned { 39 surface.ProvidedAPIs[opregistry.APIKey{Group: api.Group, Version: api.Version, Kind: api.Kind, Plural: api.Name}] = struct{}{} 40 } 41 42 requiredAPIs := cache.EmptyAPISet() 43 for _, crdDef := range csv.Spec.CustomResourceDefinitions.Required { 44 parts := strings.SplitN(crdDef.Name, ".", 2) 45 if len(parts) < 2 { 46 return nil, fmt.Errorf("error parsing crd name: %s", crdDef.Name) 47 } 48 requiredAPIs[opregistry.APIKey{Plural: parts[0], Group: parts[1], Version: crdDef.Version, Kind: crdDef.Kind}] = struct{}{} 49 } 50 for _, api := range csv.Spec.APIServiceDefinitions.Required { 51 requiredAPIs[opregistry.APIKey{Group: api.Group, Version: api.Version, Kind: api.Kind, Plural: api.Name}] = struct{}{} 52 } 53 54 return &surface, nil 55 } 56 57 // LabelSetsFor returns API label sets for the given object. 58 // Concrete types other than OperatorSurface and CustomResource definition no-op. 59 func LabelSetsFor(obj interface{}) ([]labels.Set, error) { 60 switch v := obj.(type) { 61 case operatorSurface: 62 return labelSetsForOperatorSurface(v) 63 case *extv1beta1.CustomResourceDefinition: 64 return labelSetsForCRDv1beta1(v) 65 case *extv1.CustomResourceDefinition: 66 return labelSetsForCRDv1(v) 67 default: 68 return nil, nil 69 } 70 } 71 72 func labelSetsForOperatorSurface(surface operatorSurface) ([]labels.Set, error) { 73 labelSet := labels.Set{} 74 for key := range surface.ProvidedAPIs.StripPlural() { 75 hash, err := cache.APIKeyToGVKHash(key) 76 if err != nil { 77 return nil, err 78 } 79 labelSet[APILabelKeyPrefix+hash] = "provided" 80 } 81 for key := range surface.RequiredAPIs.StripPlural() { 82 hash, err := cache.APIKeyToGVKHash(key) 83 if err != nil { 84 return nil, err 85 } 86 labelSet[APILabelKeyPrefix+hash] = "required" 87 } 88 89 return []labels.Set{labelSet}, nil 90 } 91 92 func labelSetsForCRDv1beta1(crd *extv1beta1.CustomResourceDefinition) ([]labels.Set, error) { 93 labelSets := []labels.Set{} 94 if crd == nil { 95 return labelSets, nil 96 } 97 98 // Add label sets for each version 99 for _, version := range crd.Spec.Versions { 100 hash, err := cache.APIKeyToGVKHash(opregistry.APIKey{ 101 Group: crd.Spec.Group, 102 Version: version.Name, 103 Kind: crd.Spec.Names.Kind, 104 }) 105 if err != nil { 106 return nil, err 107 } 108 key := APILabelKeyPrefix + hash 109 sets := []labels.Set{ 110 { 111 key: "provided", 112 }, 113 { 114 key: "required", 115 }, 116 } 117 labelSets = append(labelSets, sets...) 118 } 119 120 return labelSets, nil 121 } 122 123 func labelSetsForCRDv1(crd *extv1.CustomResourceDefinition) ([]labels.Set, error) { 124 labelSets := []labels.Set{} 125 if crd == nil { 126 return labelSets, nil 127 } 128 129 // Add label sets for each version 130 for _, version := range crd.Spec.Versions { 131 hash, err := cache.APIKeyToGVKHash(opregistry.APIKey{ 132 Group: crd.Spec.Group, 133 Version: version.Name, 134 Kind: crd.Spec.Names.Kind, 135 }) 136 if err != nil { 137 return nil, err 138 } 139 key := APILabelKeyPrefix + hash 140 sets := []labels.Set{ 141 { 142 key: "provided", 143 }, 144 { 145 key: "required", 146 }, 147 } 148 labelSets = append(labelSets, sets...) 149 } 150 151 return labelSets, nil 152 }