Skip to content

Commit e8f5b41

Browse files
committed
feat(catalog): add grpc sourcetype to CatalogSources
grpc sourcetype takes a new `image` field which specifies an image which is expected to serve a registry API over grpc on port 50051.
1 parent 77b84ab commit e8f5b41

File tree

12 files changed

+816
-180
lines changed

12 files changed

+816
-180
lines changed

deploy/chart/templates/0000_30_05-catalogsource.crd.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,16 @@ spec:
5656
enum:
5757
- internal # deprecated
5858
- configmap
59+
- grpc
5960

6061
configMap:
6162
type: string
6263
description: The name of a ConfigMap that holds the entries for an in-memory catalog.
6364

65+
image:
66+
type: string
67+
description: An image that serves a grpc registry. Only valid for `grpc` sourceType.
68+
6469
displayName:
6570
type: string
6671
description: Pretty name for display

pkg/api/apis/operators/v1alpha1/catalogsource_types.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@ type SourceType string
2020
const (
2121
SourceTypeInternal SourceType = "internal"
2222
SourceTypeConfigmap SourceType = "configmap"
23+
SourceTypeGrpc SourceType = "grpc"
2324
)
2425

2526
type CatalogSourceSpec struct {
2627
SourceType SourceType `json:"sourceType"`
2728
ConfigMap string `json:"configMap,omitempty"`
29+
Image string `json:"image,omitempty"`
2830
Secrets []string `json:"secrets,omitempty"`
2931

3032
// Metadata

pkg/controller/operators/catalog/operator.go

Lines changed: 54 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import (
2929
"github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned"
3030
"github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions"
3131
olmerrors "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/errors"
32-
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry"
32+
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/reconciler"
3333
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver"
3434
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister"
3535
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil"
@@ -54,16 +54,16 @@ var timeNow = func() metav1.Time { return metav1.NewTime(time.Now().UTC()) }
5454
// resolving dependencies in a catalog.
5555
type Operator struct {
5656
*queueinformer.Operator
57-
client versioned.Interface
58-
lister operatorlister.OperatorLister
59-
namespace string
60-
sources map[resolver.CatalogKey]resolver.SourceRef
61-
sourcesLock sync.RWMutex
62-
sourcesLastUpdate metav1.Time
63-
resolver resolver.Resolver
64-
subQueue workqueue.RateLimitingInterface
65-
catSrcQueueSet queueinformer.ResourceQueueSet
66-
configmapRegistryReconciler registry.RegistryReconciler
57+
client versioned.Interface
58+
lister operatorlister.OperatorLister
59+
namespace string
60+
sources map[resolver.CatalogKey]resolver.SourceRef
61+
sourcesLock sync.RWMutex
62+
sourcesLastUpdate metav1.Time
63+
resolver resolver.Resolver
64+
subQueue workqueue.RateLimitingInterface
65+
catSrcQueueSet queueinformer.ResourceQueueSet
66+
reconciler reconciler.ReconcilerFactory
6767
}
6868

6969
// NewOperator creates a new Catalog Operator.
@@ -202,10 +202,10 @@ func NewOperator(kubeconfigPath string, logger *logrus.Logger, wakeupInterval ti
202202
op.lister.CoreV1().RegisterPodLister(namespace, podInformer.Lister())
203203
op.lister.CoreV1().RegisterConfigMapLister(namespace, configMapInformer.Lister())
204204
}
205-
op.configmapRegistryReconciler = &registry.ConfigMapRegistryReconciler{
206-
Image: configmapRegistryImage,
207-
OpClient: op.OpClient,
208-
Lister: op.lister,
205+
op.reconciler = &reconciler.RegistryReconcilerFactory{
206+
ConfigMapServerImage: configmapRegistryImage,
207+
OpClient: op.OpClient,
208+
Lister: op.lister,
209209
}
210210
return op, nil
211211
}
@@ -315,53 +315,45 @@ func (o *Operator) syncCatalogSources(obj interface{}) (syncError error) {
315315
"source": catsrc.GetName(),
316316
})
317317

318-
if catsrc.Spec.SourceType == v1alpha1.SourceTypeInternal || catsrc.Spec.SourceType == v1alpha1.SourceTypeConfigmap {
319-
return o.syncConfigMapSource(logger, catsrc)
320-
}
321-
322-
logger.WithField("sourceType", catsrc.Spec.SourceType).Warn("unknown source type")
323-
324-
// TODO: write status about invalid source type
325-
326-
return nil
327-
}
328-
329-
func (o *Operator) syncConfigMapSource(logger *logrus.Entry, catsrc *v1alpha1.CatalogSource) (syncError error) {
330-
// Get the catalog source's config map
331-
configMap, err := o.lister.CoreV1().ConfigMapLister().ConfigMaps(catsrc.GetNamespace()).Get(catsrc.Spec.ConfigMap)
332-
if err != nil {
333-
return fmt.Errorf("failed to get catalog config map %s: %s", catsrc.Spec.ConfigMap, err)
334-
}
335-
336318
out := catsrc.DeepCopy()
337319
sourceKey := resolver.CatalogKey{Name: catsrc.GetName(), Namespace: catsrc.GetNamespace()}
338320

339-
if catsrc.Status.ConfigMapResource == nil || catsrc.Status.ConfigMapResource.UID != configMap.GetUID() || catsrc.Status.ConfigMapResource.ResourceVersion != configMap.GetResourceVersion() {
340-
// configmap ref nonexistent or updated, write out the new configmap ref to status and exit
341-
out.Status.ConfigMapResource = &v1alpha1.ConfigMapResourceReference{
342-
Name: configMap.GetName(),
343-
Namespace: configMap.GetNamespace(),
344-
UID: configMap.GetUID(),
345-
ResourceVersion: configMap.GetResourceVersion(),
321+
if catsrc.Spec.SourceType == v1alpha1.SourceTypeInternal || catsrc.Spec.SourceType == v1alpha1.SourceTypeConfigmap {
322+
// Get the catalog source's config map
323+
configMap, err := o.lister.CoreV1().ConfigMapLister().ConfigMaps(catsrc.GetNamespace()).Get(catsrc.Spec.ConfigMap)
324+
if err != nil {
325+
return fmt.Errorf("failed to get catalog config map %s: %s", catsrc.Spec.ConfigMap, err)
346326
}
347-
out.Status.LastSync = timeNow()
348327

349-
// update status
350-
if _, err = o.client.OperatorsV1alpha1().CatalogSources(out.GetNamespace()).UpdateStatus(out); err != nil {
351-
return err
352-
}
328+
if catsrc.Status.ConfigMapResource == nil || catsrc.Status.ConfigMapResource.UID != configMap.GetUID() || catsrc.Status.ConfigMapResource.ResourceVersion != configMap.GetResourceVersion() {
329+
// configmap ref nonexistent or updated, write out the new configmap ref to status and exit
330+
out.Status.ConfigMapResource = &v1alpha1.ConfigMapResourceReference{
331+
Name: configMap.GetName(),
332+
Namespace: configMap.GetNamespace(),
333+
UID: configMap.GetUID(),
334+
ResourceVersion: configMap.GetResourceVersion(),
335+
}
336+
out.Status.LastSync = timeNow()
353337

354-
o.sourcesLastUpdate = timeNow()
338+
// update status
339+
if _, err = o.client.OperatorsV1alpha1().CatalogSources(out.GetNamespace()).UpdateStatus(out); err != nil {
340+
return err
341+
}
355342

356-
return nil
343+
o.sourcesLastUpdate = timeNow()
344+
345+
return nil
346+
}
357347
}
358348

359-
// configmap ref is up to date, continue parsing
360-
if catsrc.Status.RegistryServiceStatus == nil || catsrc.Status.RegistryServiceStatus.CreatedAt.Before(&catsrc.Status.LastSync) {
361-
// if registry pod hasn't been created or hasn't been updated since the last configmap update, recreate it
349+
reconciler := o.reconciler.ReconcilerForSourceType(catsrc.Spec.SourceType)
350+
if reconciler == nil {
351+
return fmt.Errorf("no reconciler for source type %s", catsrc.Spec.SourceType)
352+
}
362353

363-
out := catsrc.DeepCopy()
364-
if err := o.configmapRegistryReconciler.EnsureRegistryServer(out); err != nil {
354+
// if registry pod hasn't been created or hasn't been updated since the last configmap update, recreate it
355+
if catsrc.Status.RegistryServiceStatus == nil || catsrc.Status.RegistryServiceStatus.CreatedAt.Before(&catsrc.Status.LastSync) {
356+
if err := reconciler.EnsureRegistryServer(out); err != nil {
365357
logger.WithError(err).Warn("couldn't ensure registry server")
366358
return err
367359
}
@@ -371,7 +363,7 @@ func (o *Operator) syncConfigMapSource(logger *logrus.Entry, catsrc *v1alpha1.Ca
371363
}
372364

373365
// update status
374-
if _, err = o.client.OperatorsV1alpha1().CatalogSources(out.GetNamespace()).UpdateStatus(out); err != nil {
366+
if _, err := o.client.OperatorsV1alpha1().CatalogSources(out.GetNamespace()).UpdateStatus(out); err != nil {
375367
return err
376368
}
377369

@@ -380,6 +372,7 @@ func (o *Operator) syncConfigMapSource(logger *logrus.Entry, catsrc *v1alpha1.Ca
380372
return nil
381373
}
382374

375+
// update operator's view of sources
383376
sourcesUpdated := false
384377
func() {
385378
o.sourcesLock.Lock()
@@ -401,13 +394,14 @@ func (o *Operator) syncConfigMapSource(logger *logrus.Entry, catsrc *v1alpha1.Ca
401394
}
402395
}()
403396

404-
if sourcesUpdated {
405-
// record that we've done work here onto the status
406-
out := catsrc.DeepCopy()
407-
out.Status.LastSync = timeNow()
408-
if _, err = o.client.OperatorsV1alpha1().CatalogSources(out.GetNamespace()).UpdateStatus(out); err != nil {
409-
return err
410-
}
397+
if !sourcesUpdated {
398+
return nil
399+
}
400+
401+
// record that we've done work here onto the status
402+
out.Status.LastSync = timeNow()
403+
if _, err := o.client.OperatorsV1alpha1().CatalogSources(out.GetNamespace()).UpdateStatus(out); err != nil {
404+
return err
411405
}
412406

413407
// Sync any dependent Subscriptions

pkg/controller/operators/catalog/operator_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import (
2424
"github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/fake"
2525
"github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions"
2626
olmerrors "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/errors"
27-
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry"
27+
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/reconciler"
2828
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver"
2929
"github.com/operator-framework/operator-lifecycle-manager/pkg/fakes"
3030
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient"
@@ -146,7 +146,7 @@ func TestSyncCatalogSources(t *testing.T) {
146146
Data: fakeConfigMapData(),
147147
},
148148
expectedStatus: nil,
149-
expectedError: nil,
149+
expectedError: fmt.Errorf("no reconciler for source type nope"),
150150
},
151151
{
152152
testName: "CatalogSourceWithBackingConfigMap",
@@ -420,10 +420,10 @@ func NewFakeOperator(clientObjs []runtime.Object, k8sObjs []runtime.Object, extO
420420
resolver: &fakes.FakeResolver{},
421421
}
422422

423-
op.configmapRegistryReconciler = &registry.ConfigMapRegistryReconciler{
424-
Image: "test:pod",
425-
OpClient: op.OpClient,
426-
Lister: lister,
423+
op.reconciler = &reconciler.RegistryReconcilerFactory{
424+
ConfigMapServerImage: "test:pod",
425+
OpClient: op.OpClient,
426+
Lister: lister,
427427
}
428428

429429
var hasSyncedCheckFns []cache.InformerSynced

0 commit comments

Comments
 (0)