@@ -46,6 +46,7 @@ import (
46
46
"github.com/openshift/cluster-version-operator/pkg/payload/precondition"
47
47
preconditioncv "github.com/openshift/cluster-version-operator/pkg/payload/precondition/clusterversion"
48
48
"github.com/openshift/cluster-version-operator/pkg/verify"
49
+ "github.com/openshift/cluster-version-operator/pkg/verify/verifyconfigmap"
49
50
)
50
51
51
52
const (
@@ -136,6 +137,9 @@ type Operator struct {
136
137
// verifier, if provided, will be used to check an update before it is executed.
137
138
// Any error will prevent an update payload from being accessed.
138
139
verifier verify.Interface
140
+ // signatureStore, if set, will be used to periodically persist signatures to
141
+ // the cluster as a config map
142
+ signatureStore * verify.StorePersister
139
143
140
144
configSync ConfigSyncWorker
141
145
// statusInterval is how often the configSync worker is allowed to retrigger
@@ -238,17 +242,21 @@ func (optr *Operator) InitializeFromPayload(restConfig *rest.Config, burstRestCo
238
242
}
239
243
// XXX: set this to the cincinnati version in preference
240
244
if _ , err := semver .Parse (update .ImageRef .Name ); err != nil {
241
- return fmt .Errorf ("The local release contents name %q is not a valid semantic version - no current version will be reported: %v" , update .ImageRef .Name , err )
245
+ return fmt .Errorf ("the local release contents name %q is not a valid semantic version - no current version will be reported: %v" , update .ImageRef .Name , err )
242
246
}
243
247
244
248
optr .releaseCreated = update .ImageRef .CreationTimestamp .Time
245
249
optr .releaseVersion = update .ImageRef .Name
246
250
247
251
// Wraps operator's HTTPClient method to allow releaseVerifier to create http client with up-to-date config.
248
252
clientBuilder := & verifyClientBuilder {builder : optr .HTTPClient }
253
+ configClient , err := coreclientsetv1 .NewForConfig (restConfig )
254
+ if err != nil {
255
+ return fmt .Errorf ("unable to create a configuration client: %v" , err )
256
+ }
249
257
250
258
// attempt to load a verifier as defined in the payload
251
- verifier , err := loadConfigMapVerifierDataFromUpdate (update , clientBuilder )
259
+ verifier , signatureStore , err := loadConfigMapVerifierDataFromUpdate (update , clientBuilder , configClient )
252
260
if err != nil {
253
261
return err
254
262
}
@@ -259,6 +267,7 @@ func (optr *Operator) InitializeFromPayload(restConfig *rest.Config, burstRestCo
259
267
verifier = verify .Reject
260
268
}
261
269
optr .verifier = verifier
270
+ optr .signatureStore = signatureStore
262
271
263
272
// after the verifier has been loaded, initialize the sync worker with a payload retriever
264
273
// which will consume the verifier
@@ -282,7 +291,7 @@ func (optr *Operator) InitializeFromPayload(restConfig *rest.Config, burstRestCo
282
291
// It returns an error if the data is not valid, or no verifier if no config map is found. See the verify
283
292
// package for more details on the algorithm for verification. If the annotation is set, a verifier or error
284
293
// is always returned.
285
- func loadConfigMapVerifierDataFromUpdate (update * payload.Update , clientBuilder verify.ClientBuilder ) (verify.Interface , error ) {
294
+ func loadConfigMapVerifierDataFromUpdate (update * payload.Update , clientBuilder verify.ClientBuilder , configMapClient coreclientsetv1. ConfigMapsGetter ) (verify.Interface , * verify. StorePersister , error ) {
286
295
configMapGVK := corev1 .SchemeGroupVersion .WithKind ("ConfigMap" )
287
296
for _ , manifest := range update .Manifests {
288
297
if manifest .GVK != configMapGVK {
@@ -294,15 +303,21 @@ func loadConfigMapVerifierDataFromUpdate(update *payload.Update, clientBuilder v
294
303
src := fmt .Sprintf ("the config map %s/%s" , manifest .Obj .GetNamespace (), manifest .Obj .GetName ())
295
304
data , _ , err := unstructured .NestedStringMap (manifest .Obj .Object , "data" )
296
305
if err != nil {
297
- return nil , errors .Wrapf (err , "%s is not valid: %v" , src , err )
306
+ return nil , nil , errors .Wrapf (err , "%s is not valid: %v" , src , err )
298
307
}
299
308
verifier , err := verify .NewFromConfigMap (src , data , clientBuilder )
300
309
if err != nil {
301
- return nil , err
310
+ return nil , nil , err
302
311
}
303
- return verifier , nil
312
+
313
+ // allow the verifier to consult the cluster for signature data, and also configure
314
+ // a process that writes signatures back to that store
315
+ signatureStore := verifyconfigmap .NewStore (configMapClient , nil )
316
+ verifier = verifier .WithStores (signatureStore )
317
+ persister := verify .NewSignatureStorePersister (signatureStore , verifier )
318
+ return verifier , persister , nil
304
319
}
305
- return nil , nil
320
+ return nil , nil , nil
306
321
}
307
322
308
323
// Run runs the cluster version operator until stopCh is completed. Workers is ignored for now.
@@ -339,6 +354,9 @@ func (optr *Operator) Run(ctx context.Context, workers int) {
339
354
utilruntime .HandleError (fmt .Errorf ("unable to perform final sync: %v" , err ))
340
355
}
341
356
}, time .Second , stopCh )
357
+ if optr .signatureStore != nil {
358
+ go optr .signatureStore .Run (ctx , optr .minimumUpdateCheckInterval * 2 )
359
+ }
342
360
343
361
<- stopCh
344
362
0 commit comments