Skip to content

Commit 924c565

Browse files
committed
Add IndexFunc using ProvidedAPIs as key to look up CSVs
Signed-off-by: Vu Dinh <[email protected]>
1 parent 8cec21a commit 924c565

File tree

2 files changed

+94
-16
lines changed

2 files changed

+94
-16
lines changed

pkg/controller/operators/catalog/operator.go

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import (
3333
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/catalog/subscription"
3434
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/reconciler"
3535
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver"
36+
index "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/index"
3637
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient"
3738
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister"
3839
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil"
@@ -57,21 +58,22 @@ const (
5758
type Operator struct {
5859
queueinformer.Operator
5960

60-
logger *logrus.Logger
61-
clock utilclock.Clock
62-
opClient operatorclient.ClientInterface
63-
client versioned.Interface
64-
lister operatorlister.OperatorLister
65-
catsrcQueueSet *queueinformer.ResourceQueueSet
66-
subQueueSet *queueinformer.ResourceQueueSet
67-
ipQueueSet *queueinformer.ResourceQueueSet
68-
nsResolveQueue workqueue.RateLimitingInterface
69-
namespace string
70-
sources map[resolver.CatalogKey]resolver.SourceRef
71-
sourcesLock sync.RWMutex
72-
sourcesLastUpdate metav1.Time
73-
resolver resolver.Resolver
74-
reconciler reconciler.RegistryReconcilerFactory
61+
logger *logrus.Logger
62+
clock utilclock.Clock
63+
opClient operatorclient.ClientInterface
64+
client versioned.Interface
65+
lister operatorlister.OperatorLister
66+
catsrcQueueSet *queueinformer.ResourceQueueSet
67+
subQueueSet *queueinformer.ResourceQueueSet
68+
ipQueueSet *queueinformer.ResourceQueueSet
69+
nsResolveQueue workqueue.RateLimitingInterface
70+
namespace string
71+
sources map[resolver.CatalogKey]resolver.SourceRef
72+
sourcesLock sync.RWMutex
73+
sourcesLastUpdate metav1.Time
74+
resolver resolver.Resolver
75+
reconciler reconciler.RegistryReconcilerFactory
76+
csvProvidedAPIsIndexer map[string]cache.Indexer
7577
}
7678

7779
// NewOperator creates a new Catalog Operator.
@@ -123,6 +125,10 @@ func NewOperator(ctx context.Context, kubeconfigPath string, clock utilclock.Clo
123125
op.lister.OperatorsV1alpha1().RegisterClusterServiceVersionLister(namespace, csvInformer.Lister())
124126
op.RegisterInformer(csvInformer.Informer())
125127

128+
csvInformer.Informer().AddIndexers(cache.Indexers{index.ProvidedAPIsIndexFuncKey: index.ProvidedAPIsIndexFunc})
129+
csvIndexer := csvInformer.Informer().GetIndexer()
130+
op.csvProvidedAPIsIndexer[namespace] = csvIndexer
131+
126132
// TODO: Add namespace resolve sync
127133

128134
// Wire InstallPlans
@@ -1040,8 +1046,14 @@ func (o *Operator) ExecutePlan(plan *v1alpha1.InstallPlan) error {
10401046
if !reflect.DeepEqual(crd, *currentCRD) {
10411047
// Verify CRD ownership, only attempt to update if
10421048
// CRD has only one owner
1043-
if len(existingCRDOwners[currentCRD.GetName()]) == 1 {
1049+
// Example: provided=database.coreos.com/v1alpha1/EtcdCluster
1050+
matchedCSV, err := index.APIsIndexValues(o.csvProvidedAPIsIndexer, crd)
1051+
if err != nil {
1052+
return errorwrap.Wrapf(err, "error find matched CSV: %s", step.Resource.Name)
1053+
}
1054+
if len(matchedCSV) == 1 {
10441055
// Attempt to update CRD
1056+
crd.SetResourceVersion(currentCRD.GetResourceVersion())
10451057
_, err = o.OpClient.ApiextensionsV1beta1Interface().ApiextensionsV1beta1().CustomResourceDefinitions().Update(&crd)
10461058
if err != nil {
10471059
return errorwrap.Wrapf(err, "error update CRD: %s", step.Resource.Name)

pkg/lib/index/api.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package indexer
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
7+
"github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1"
8+
v1beta1ext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
9+
"k8s.io/client-go/tools/cache"
10+
)
11+
12+
const (
13+
// ProvidedAPIsIndexFuncKey is the recommended key to use for registering the index func with an indexer.
14+
ProvidedAPIsIndexFuncKey string = "providedAPIs"
15+
)
16+
17+
func ProvidedAPIsIndexFunc(obj interface{}) ([]string, error) {
18+
indicies := []string{}
19+
20+
csv, ok := obj.(*v1alpha1.ClusterServiceVersion)
21+
if !ok {
22+
return indicies, fmt.Errorf("invalid object of type: %T", obj)
23+
}
24+
25+
for _, crd := range csv.Spec.CustomResourceDefinitions.Owned {
26+
parts := strings.SplitN(crd.Name, ".", 2)
27+
if len(parts) < 2 {
28+
return indicies, fmt.Errorf("couldn't parse plural.group from crd name: %s", crd.Name)
29+
}
30+
indicies = append(indicies, fmt.Sprintf("provided=%s/%s/%s", parts[1], crd.Version, crd.Kind))
31+
}
32+
for _, api := range csv.Spec.APIServiceDefinitions.Owned {
33+
indicies = append(indicies, fmt.Sprintf("provided=%s/%s/%s", api.Group, api.Version, api.Kind))
34+
}
35+
36+
return indicies, nil
37+
}
38+
39+
// APIsIndexValues returns the names of CSVs that own the given CRD
40+
func APIsIndexValues(indexers map[string]cache.Indexer, crd v1beta1ext.CustomResourceDefinition) (map[string]struct{}, error) {
41+
csvSet := map[string]struct{}{}
42+
crdSpec := map[string]struct{}{}
43+
for _, v := range crd.Spec.Versions {
44+
crdSpec[fmt.Sprintf("provided=%s/%s/%s", crd.Spec.Group, v.Name, crd.Spec.Names.Kind)] = struct{}{}
45+
}
46+
if crd.Spec.Version != "" {
47+
crdSpec[fmt.Sprintf("provided=%s/%s/%s", crd.Spec.Group, crd.Spec.Version, crd.Spec.Names.Kind)] = struct{}{}
48+
}
49+
for _, indexer := range indexers {
50+
for key, _ := range crdSpec {
51+
csvs, err := indexer.ByIndex(ProvidedAPIsIndexFuncKey, key)
52+
if err != nil {
53+
return nil, err
54+
}
55+
for _, csv := range csvs {
56+
csv, ok := csv.(*v1alpha1.ClusterServiceVersion)
57+
if !ok {
58+
continue
59+
}
60+
// Add to set
61+
csvSet[csv.GetName()] = struct{}{}
62+
}
63+
}
64+
}
65+
return csvSet, nil
66+
}

0 commit comments

Comments
 (0)