@@ -12,7 +12,9 @@ import (
12
12
13
13
"github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/install"
14
14
"github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1"
15
+ listers "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1"
15
16
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/kubestate"
17
+ "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil"
16
18
)
17
19
18
20
var scheme = runtime .NewScheme ()
@@ -28,6 +30,7 @@ type subscriptionSyncer struct {
28
30
clock utilclock.Clock
29
31
reconcilers kubestate.ReconcilerChain
30
32
subscriptionCache cache.Indexer
33
+ installPlanLister listers.InstallPlanLister
31
34
globalCatalogNamespace string
32
35
notify kubestate.NotifyFunc
33
36
}
@@ -96,9 +99,9 @@ func (s *subscriptionSyncer) catalogSubscriptionKeys(namespace string) ([]string
96
99
return keys , err
97
100
}
98
101
99
- // catalogNotification notifies dependent subscriptions of the change with the given object.
100
- // The given object is assumed to be a Subscription, Subscription tombstone, or a cache.ExplicitKey.
101
- func (s * subscriptionSyncer ) catalogNotification (ctx context.Context , obj interface {}) {
102
+ // notifyOnCatalog notifies dependent subscriptions of the change with the given object.
103
+ // The given object is assumed to be a CatalogSource, CatalogSource tombstone, or a cache.ExplicitKey.
104
+ func (s * subscriptionSyncer ) notifyOnCatalog (ctx context.Context , obj interface {}) {
102
105
k , err := cache .DeletionHandlingMetaNamespaceKeyFunc (obj )
103
106
if err != nil {
104
107
s .logger .WithField ("resource" , obj ).Warn ("could not unpack key" )
@@ -127,6 +130,66 @@ func (s *subscriptionSyncer) catalogNotification(ctx context.Context, obj interf
127
130
logger .Trace ("dependent subscriptions notified" )
128
131
}
129
132
133
+ // notifyOnInstallPlan notifies dependent subscriptions of the change with the given object.
134
+ // The given object is assumed to be an InstallPlan, InstallPlan tombstone, or a cache.ExplicitKey.
135
+ func (s * subscriptionSyncer ) notifyOnInstallPlan (ctx context.Context , obj interface {}) {
136
+ plan , ok := obj .(* v1alpha1.InstallPlan )
137
+ if ! ok {
138
+ s .logger .WithField ("obj" , fmt .Sprintf ("%v" , obj )).Trace ("could not cast as installplan directly while notifying subscription syncer" )
139
+ if tombstone , ok := obj .(cache.DeletedFinalStateUnknown ); ok {
140
+ if plan , ok = tombstone .Obj .(* v1alpha1.InstallPlan ); ! ok {
141
+ s .logger .WithField ("tombstone" , tombstone ).Warn ("could not cast as installplan" )
142
+ return
143
+ }
144
+ } else {
145
+ k , err := cache .DeletionHandlingMetaNamespaceKeyFunc (obj )
146
+ if err != nil {
147
+ s .logger .WithField ("resource" , obj ).Warn ("could not unpack key" )
148
+ return
149
+ }
150
+ logger := s .logger .WithField ("key" , k )
151
+
152
+ ns , name , err := cache .SplitMetaNamespaceKey (k )
153
+ if err != nil {
154
+ logger .Warn ("could not split meta key" )
155
+ return
156
+ }
157
+
158
+ if plan , err = s .installPlanLister .InstallPlans (ns ).Get (name ); err != nil {
159
+ logger .WithError (err ).Warn ("could not get installplan" )
160
+ return
161
+ }
162
+ }
163
+ }
164
+
165
+ logger := s .logger .WithFields (logrus.Fields {
166
+ "namespace" : plan .GetNamespace (),
167
+ "installplan" : plan .GetName (),
168
+ })
169
+
170
+ // Notify dependent owner Subscriptions
171
+ owners := ownerutil .GetOwnersByKind (plan , v1alpha1 .SubscriptionKind )
172
+ for _ , owner := range owners {
173
+ subKey := fmt .Sprintf ("%s/%s" , plan .GetNamespace (), owner .Name )
174
+ logger .Tracef ("notifying subscription %s" , subKey )
175
+ s .Notify (kubestate .NewResourceEvent (kubestate .ResourceUpdated , cache .ExplicitKey (subKey )))
176
+ }
177
+ }
178
+
179
+ func eventHandlers (ctx context.Context , notify func (ctx context.Context , obj interface {})) cache.ResourceEventHandlerFuncs {
180
+ return cache.ResourceEventHandlerFuncs {
181
+ AddFunc : func (obj interface {}) {
182
+ notify (ctx , obj )
183
+ },
184
+ UpdateFunc : func (oldObj , newObj interface {}) {
185
+ notify (ctx , newObj )
186
+ },
187
+ DeleteFunc : func (obj interface {}) {
188
+ notify (ctx , obj )
189
+ },
190
+ }
191
+ }
192
+
130
193
// NewSyncer returns a syncer that syncs Subscription resources.
131
194
func NewSyncer (ctx context.Context , options ... SyncerOption ) (kubestate.Syncer , error ) {
132
195
config := defaultSyncerConfig ()
@@ -145,6 +208,7 @@ func newSyncerWithConfig(ctx context.Context, config *syncerConfig) (kubestate.S
145
208
clock : config .clock ,
146
209
reconcilers : config .reconcilers ,
147
210
subscriptionCache : config .subscriptionInformer .GetIndexer (),
211
+ installPlanLister : config .lister .OperatorsV1alpha1 ().InstallPlanLister (),
148
212
notify : func (event kubestate.ResourceEvent ) {
149
213
// Notify Subscriptions by enqueuing to the Subscription queue.
150
214
config .subscriptionQueue .Add (event )
@@ -154,6 +218,11 @@ func newSyncerWithConfig(ctx context.Context, config *syncerConfig) (kubestate.S
154
218
// Build a reconciler chain from the default and configured reconcilers
155
219
// Default reconcilers should always come first in the chain
156
220
defaultReconcilers := kubestate.ReconcilerChain {
221
+ & installPlanReconciler {
222
+ now : s .now ,
223
+ client : config .client ,
224
+ installPlanLister : config .lister .OperatorsV1alpha1 ().InstallPlanLister (),
225
+ },
157
226
& catalogHealthReconciler {
158
227
now : s .now ,
159
228
client : config .client ,
@@ -165,17 +234,8 @@ func newSyncerWithConfig(ctx context.Context, config *syncerConfig) (kubestate.S
165
234
s .reconcilers = append (defaultReconcilers , s .reconcilers ... )
166
235
167
236
// Add dependency notifications
168
- config .catalogInformer .AddEventHandler (cache.ResourceEventHandlerFuncs {
169
- AddFunc : func (obj interface {}) {
170
- s .catalogNotification (ctx , obj )
171
- },
172
- UpdateFunc : func (oldObj , newObj interface {}) {
173
- s .catalogNotification (ctx , newObj )
174
- },
175
- DeleteFunc : func (obj interface {}) {
176
- s .catalogNotification (ctx , obj )
177
- },
178
- })
237
+ config .installPlanInformer .AddEventHandler (eventHandlers (ctx , s .notifyOnInstallPlan ))
238
+ config .catalogInformer .AddEventHandler (eventHandlers (ctx , s .notifyOnCatalog ))
179
239
180
240
return s , nil
181
241
}
0 commit comments