Skip to content

Commit 9b537bf

Browse files
authored
Prune API of the resolver package. (#2330)
* Remove generated FakeAPIIntersectionReconciler. It's a test stub that has only one consumer. Generating a fake into pkg/fakes with counterfeiter and using it for tests in pkg/controller/operators/olm introduces a number of transitive package dependencies that make it difficult to unwind the resolver package from other runtime components. Signed-off-by: Ben Luddy <[email protected]> * Move OperatorGroup surface logic to the olm package. It has been living in the resolver package as a holdover from earlier generations of resolution, but is only consumed by olm-operator as part of OperatorGroup reconciliation. Signed-off-by: Ben Luddy <[email protected]> * Move API labeler from the resolver package to the olm package. The only user of the provided/required API labeling functionality is olm-operator, but it was still residing in the resolver package. Signed-off-by: Ben Luddy <[email protected]> * Remove OperatorSurface interface from resolver. This interface is used only by olm-operator and doesn't provide a useful abstraction on top of directly reading fields from Operator structs. Signed-off-by: Ben Luddy <[email protected]> * Extract SourceQuerier from the resolver package. SourceQuerier is a holdover from the previous resolution implementation. Now, it only gets minor usage in catalog-operator. Unused methods have been removed, and SourceQuerier has moved to pkg/controller/operators/catalog beside where it is used. Signed-off-by: Ben Luddy <[email protected]>
1 parent 7c2f004 commit 9b537bf

31 files changed

+362
-1582
lines changed

pkg/controller/operators/catalog/operator.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -890,7 +890,7 @@ func (o *Operator) syncResolvingNamespace(obj interface{}) error {
890890
// get the set of sources that should be used for resolution and best-effort get their connections working
891891
logger.Debug("resolving sources")
892892

893-
querier := resolver.NewNamespaceSourceQuerier(o.sources.AsClients(o.namespace, namespace))
893+
querier := NewNamespaceSourceQuerier(o.sources.AsClients(o.namespace, namespace))
894894

895895
logger.Debug("checking if subscriptions need update")
896896

@@ -950,7 +950,7 @@ func (o *Operator) syncResolvingNamespace(obj interface{}) error {
950950
logger.Debug("resolving subscriptions in namespace")
951951

952952
// resolve a set of steps to apply to a cluster, a set of subscriptions to create/update, and any errors
953-
steps, bundleLookups, updatedSubs, err := o.resolver.ResolveSteps(namespace, querier)
953+
steps, bundleLookups, updatedSubs, err := o.resolver.ResolveSteps(namespace)
954954
if err != nil {
955955
go o.recorder.Event(ns, corev1.EventTypeWarning, "ResolutionFailed", err.Error())
956956
// If the error is constraints not satisfiable, then simply project the
@@ -1085,7 +1085,7 @@ func (o *Operator) ensureSubscriptionInstallPlanState(logger *logrus.Entry, sub
10851085
return updated, true, nil
10861086
}
10871087

1088-
func (o *Operator) ensureSubscriptionCSVState(logger *logrus.Entry, sub *v1alpha1.Subscription, querier resolver.SourceQuerier) (*v1alpha1.Subscription, bool, error) {
1088+
func (o *Operator) ensureSubscriptionCSVState(logger *logrus.Entry, sub *v1alpha1.Subscription, querier SourceQuerier) (*v1alpha1.Subscription, bool, error) {
10891089
if sub.Status.CurrentCSV == "" {
10901090
return sub, false, nil
10911091
}

pkg/controller/operators/catalog/operator_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1204,7 +1204,7 @@ func TestSyncResolvingNamespace(t *testing.T) {
12041204

12051205
o.sourcesLastUpdate.Set(tt.fields.sourcesLastUpdate.Time)
12061206
o.resolver = &fakes.FakeStepResolver{
1207-
ResolveStepsStub: func(string, resolver.SourceQuerier) ([]*v1alpha1.Step, []v1alpha1.BundleLookup, []*v1alpha1.Subscription, error) {
1207+
ResolveStepsStub: func(string) ([]*v1alpha1.Step, []v1alpha1.BundleLookup, []*v1alpha1.Subscription, error) {
12081208
return nil, nil, nil, tt.fields.resolveErr
12091209
},
12101210
}
+123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
//go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -o fakes/fake_registry_client.go ../../../../vendor/github.com/operator-framework/operator-registry/pkg/api.RegistryClient
2+
//go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -o fakes/fake_registry_interface.go ../../registry/registry_client.go ClientInterface
3+
package catalog
4+
5+
import (
6+
"context"
7+
"fmt"
8+
9+
"github.com/blang/semver/v4"
10+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
11+
"k8s.io/apimachinery/pkg/util/errors"
12+
13+
"github.com/operator-framework/operator-registry/pkg/api"
14+
"github.com/operator-framework/operator-registry/pkg/client"
15+
16+
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry"
17+
)
18+
19+
const SkipPackageAnnotationKey = "olm.skipRange"
20+
21+
type SourceRef struct {
22+
Address string
23+
Client client.Interface
24+
LastConnect metav1.Time
25+
LastHealthy metav1.Time
26+
}
27+
28+
type SourceQuerier interface {
29+
FindReplacement(currentVersion *semver.Version, bundleName, pkgName, channelName string, initialSource registry.CatalogKey) (*api.Bundle, *registry.CatalogKey, error)
30+
Queryable() error
31+
}
32+
33+
type NamespaceSourceQuerier struct {
34+
sources map[registry.CatalogKey]registry.ClientInterface
35+
}
36+
37+
var _ SourceQuerier = &NamespaceSourceQuerier{}
38+
39+
func NewNamespaceSourceQuerier(sources map[registry.CatalogKey]registry.ClientInterface) *NamespaceSourceQuerier {
40+
return &NamespaceSourceQuerier{
41+
sources: sources,
42+
}
43+
}
44+
45+
func (q *NamespaceSourceQuerier) Queryable() error {
46+
if len(q.sources) == 0 {
47+
return fmt.Errorf("no catalog sources available")
48+
}
49+
return nil
50+
}
51+
52+
func (q *NamespaceSourceQuerier) FindReplacement(currentVersion *semver.Version, bundleName, pkgName, channelName string, initialSource registry.CatalogKey) (*api.Bundle, *registry.CatalogKey, error) {
53+
errs := []error{}
54+
55+
if initialSource.Name != "" && initialSource.Namespace != "" {
56+
source, ok := q.sources[initialSource]
57+
if !ok {
58+
return nil, nil, fmt.Errorf("CatalogSource %s not found", initialSource.Name)
59+
}
60+
61+
bundle, err := q.findChannelHead(currentVersion, pkgName, channelName, source)
62+
if bundle != nil {
63+
return bundle, &initialSource, nil
64+
}
65+
if err != nil {
66+
errs = append(errs, err)
67+
}
68+
69+
bundle, err = source.GetReplacementBundleInPackageChannel(context.TODO(), bundleName, pkgName, channelName)
70+
if bundle != nil {
71+
return bundle, &initialSource, nil
72+
}
73+
if err != nil {
74+
errs = append(errs, err)
75+
}
76+
77+
return nil, nil, errors.NewAggregate(errs)
78+
}
79+
80+
for key, source := range q.sources {
81+
bundle, err := q.findChannelHead(currentVersion, pkgName, channelName, source)
82+
if bundle != nil {
83+
return bundle, &initialSource, nil
84+
}
85+
if err != nil {
86+
errs = append(errs, err)
87+
}
88+
89+
bundle, err = source.GetReplacementBundleInPackageChannel(context.TODO(), bundleName, pkgName, channelName)
90+
if bundle != nil {
91+
return bundle, &key, nil
92+
}
93+
if err != nil {
94+
errs = append(errs, err)
95+
}
96+
}
97+
return nil, nil, errors.NewAggregate(errs)
98+
}
99+
100+
func (q *NamespaceSourceQuerier) findChannelHead(currentVersion *semver.Version, pkgName, channelName string, source client.Interface) (*api.Bundle, error) {
101+
if currentVersion == nil {
102+
return nil, nil
103+
}
104+
105+
latest, err := source.GetBundleInPackageChannel(context.TODO(), pkgName, channelName)
106+
if err != nil {
107+
return nil, err
108+
}
109+
110+
if latest.SkipRange == "" {
111+
return nil, nil
112+
}
113+
114+
r, err := semver.ParseRange(latest.SkipRange)
115+
if err != nil {
116+
return nil, err
117+
}
118+
119+
if r(*currentVersion) {
120+
return latest, nil
121+
}
122+
return nil, nil
123+
}

0 commit comments

Comments
 (0)