@@ -11,10 +11,9 @@ import (
11
11
"k8s.io/apimachinery/pkg/runtime/schema"
12
12
13
13
"github.com/operator-framework/api/pkg/operators/v1alpha1"
14
+ "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry"
14
15
"github.com/operator-framework/operator-registry/pkg/api"
15
16
opregistry "github.com/operator-framework/operator-registry/pkg/registry"
16
-
17
- "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry"
18
17
)
19
18
20
19
type APISet map [opregistry.APIKey ]struct {}
@@ -197,6 +196,7 @@ type OperatorSourceInfo struct {
197
196
StartingCSV string
198
197
Catalog registry.CatalogKey
199
198
DefaultChannel bool
199
+ Subscription * v1alpha1.Subscription
200
200
}
201
201
202
202
func (i * OperatorSourceInfo ) String () string {
@@ -216,7 +216,6 @@ type OperatorSurface interface {
216
216
SourceInfo () * OperatorSourceInfo
217
217
Bundle () * api.Bundle
218
218
Inline () bool
219
- Dependencies () []* api.Dependency
220
219
Properties () []* api.Property
221
220
Skips () []string
222
221
}
@@ -229,7 +228,6 @@ type Operator struct {
229
228
version * semver.Version
230
229
bundle * api.Bundle
231
230
sourceInfo * OperatorSourceInfo
232
- dependencies []* api.Dependency
233
231
properties []* api.Property
234
232
skips []string
235
233
}
@@ -261,21 +259,27 @@ func NewOperatorFromBundle(bundle *api.Bundle, startingCSV string, sourceKey reg
261
259
// legacy support - if the api doesn't contain properties/dependencies, build them from required/provided apis
262
260
properties := bundle .Properties
263
261
if len (properties ) == 0 {
264
- properties , err = apisToProperties (provided )
262
+ properties , err = providedAPIsToProperties (provided )
265
263
if err != nil {
266
264
return nil , err
267
265
}
268
266
}
269
- dependencies := bundle .Dependencies
270
- if len (dependencies ) == 0 {
271
- dependencies , err = apisToDependencies (required )
267
+ if len (bundle .Dependencies ) > 0 {
268
+ ps , err := legacyDependenciesToProperties (bundle .Dependencies )
269
+ if err != nil {
270
+ return nil , fmt .Errorf ("failed to translate legacy dependencies to properties: %w" , err )
271
+ }
272
+ properties = append (properties , ps ... )
273
+ } else {
274
+ ps , err := requiredAPIsToProperties (required )
272
275
if err != nil {
273
276
return nil , err
274
277
}
278
+ properties = append (properties , ps ... )
275
279
}
276
280
277
281
// legacy support - if the grpc api doesn't contain required/provided apis, fallback to csv parsing
278
- if len (required ) == 0 && len (provided ) == 0 && len (properties ) == 0 && len ( dependencies ) == 0 {
282
+ if len (required ) == 0 && len (provided ) == 0 && len (properties ) == 0 {
279
283
// fallback to csv parsing
280
284
if bundle .CsvJson == "" {
281
285
if bundle .GetBundlePath () != "" {
@@ -307,7 +311,6 @@ func NewOperatorFromBundle(bundle *api.Bundle, startingCSV string, sourceKey reg
307
311
requiredAPIs : required ,
308
312
bundle : bundle ,
309
313
sourceInfo : sourceInfo ,
310
- dependencies : dependencies ,
311
314
properties : properties ,
312
315
skips : bundle .Skips ,
313
316
}, nil
@@ -338,23 +341,22 @@ func NewOperatorFromV1Alpha1CSV(csv *v1alpha1.ClusterServiceVersion) (*Operator,
338
341
requiredAPIs [opregistry.APIKey {Group : api .Group , Version : api .Version , Kind : api .Kind , Plural : api .Name }] = struct {}{}
339
342
}
340
343
341
- dependencies , err := apisToDependencies ( requiredAPIs )
344
+ properties , err := providedAPIsToProperties ( providedAPIs )
342
345
if err != nil {
343
346
return nil , err
344
347
}
345
-
346
- properties , err := apisToProperties (providedAPIs )
348
+ dependencies , err := requiredAPIsToProperties (requiredAPIs )
347
349
if err != nil {
348
350
return nil , err
349
351
}
352
+ properties = append (properties , dependencies ... )
350
353
351
354
return & Operator {
352
355
name : csv .GetName (),
353
356
version : & csv .Spec .Version .Version ,
354
357
providedAPIs : providedAPIs ,
355
358
requiredAPIs : requiredAPIs ,
356
359
sourceInfo : & ExistingOperator ,
357
- dependencies : dependencies ,
358
360
properties : properties ,
359
361
}, nil
360
362
}
@@ -413,48 +415,48 @@ func (o *Operator) Inline() bool {
413
415
return o .bundle != nil && o .bundle .GetBundlePath () == ""
414
416
}
415
417
416
- func (o * Operator ) Dependencies () []* api.Dependency {
417
- return o .dependencies
418
- }
419
-
420
418
func (o * Operator ) Properties () []* api.Property {
421
419
return o .properties
422
420
}
423
421
424
422
func (o * Operator ) DependencyPredicates () (predicates []OperatorPredicate , err error ) {
425
423
predicates = make ([]OperatorPredicate , 0 )
426
- for _ , d := range o .Dependencies () {
427
- var p OperatorPredicate
428
- if d == nil || d .Type == "" {
429
- continue
430
- }
431
- p , err = PredicateForDependency (d )
424
+ for _ , property := range o .Properties () {
425
+ predicate , err := PredicateForProperty (property )
432
426
if err != nil {
433
- return
427
+ return nil , err
428
+ }
429
+ if predicate == nil {
430
+ continue
434
431
}
435
- predicates = append (predicates , p )
432
+ predicates = append (predicates , predicate )
436
433
}
437
434
return
438
435
}
439
436
440
- // TODO: this should go in its own dependency/predicate builder package
441
- // TODO: can we make this more extensible, i.e. via cue
442
- func PredicateForDependency (dependency * api.Dependency ) (OperatorPredicate , error ) {
443
- p , ok := predicates [dependency .Type ]
437
+ func PredicateForProperty (property * api.Property ) (OperatorPredicate , error ) {
438
+ if property == nil {
439
+ return nil , nil
440
+ }
441
+ p , ok := predicates [property .Type ]
444
442
if ! ok {
445
- return nil , fmt . Errorf ( "no predicate for dependency type %s" , dependency . Type )
443
+ return nil , nil
446
444
}
447
- return p (dependency .Value )
445
+ return p (property .Value )
448
446
}
449
447
450
448
var predicates = map [string ]func (string ) (OperatorPredicate , error ){
451
- opregistry . GVKType : predicateForGVKDependency ,
452
- opregistry . PackageType : predicateForPackageDependency ,
453
- opregistry . LabelType : predicateForLabelDependency ,
449
+ "olm.gvk.required" : predicateForRequiredGVKProperty ,
450
+ "olm.package.required" : predicateForRequiredPackageProperty ,
451
+ "olm.label.required" : predicateForRequiredLabelProperty ,
454
452
}
455
453
456
- func predicateForGVKDependency (value string ) (OperatorPredicate , error ) {
457
- var gvk opregistry.GVKDependency
454
+ func predicateForRequiredGVKProperty (value string ) (OperatorPredicate , error ) {
455
+ var gvk struct {
456
+ Group string `json:"group"`
457
+ Version string `json:"version"`
458
+ Kind string `json:"kind"`
459
+ }
458
460
if err := json .Unmarshal ([]byte (value ), & gvk ); err != nil {
459
461
return nil , err
460
462
}
@@ -465,44 +467,51 @@ func predicateForGVKDependency(value string) (OperatorPredicate, error) {
465
467
}), nil
466
468
}
467
469
468
- func predicateForPackageDependency (value string ) (OperatorPredicate , error ) {
469
- var pkg opregistry.PackageDependency
470
+ func predicateForRequiredPackageProperty (value string ) (OperatorPredicate , error ) {
471
+ var pkg struct {
472
+ PackageName string `json:"packageName"`
473
+ VersionRange string `json:"versionRange"`
474
+ }
470
475
if err := json .Unmarshal ([]byte (value ), & pkg ); err != nil {
471
476
return nil , err
472
477
}
473
- ver , err := semver .ParseRange (pkg .Version )
478
+ ver , err := semver .ParseRange (pkg .VersionRange )
474
479
if err != nil {
475
480
return nil , err
476
481
}
477
-
478
482
return And (WithPackage (pkg .PackageName ), WithVersionInRange (ver )), nil
479
483
}
480
484
481
- func predicateForLabelDependency (value string ) (OperatorPredicate , error ) {
482
- var label opregistry.LabelDependency
485
+ func predicateForRequiredLabelProperty (value string ) (OperatorPredicate , error ) {
486
+ var label struct {
487
+ Label string `json:"label"`
488
+ }
483
489
if err := json .Unmarshal ([]byte (value ), & label ); err != nil {
484
490
return nil , err
485
491
}
486
-
487
492
return WithLabel (label .Label ), nil
488
493
}
489
494
490
- func apisToDependencies (apis APISet ) (out []* api.Dependency , err error ) {
495
+ func requiredAPIsToProperties (apis APISet ) (out []* api.Property , err error ) {
491
496
if len (apis ) == 0 {
492
497
return
493
498
}
494
- out = make ([]* api.Dependency , 0 )
499
+ out = make ([]* api.Property , 0 )
495
500
for a := range apis {
496
- val , err := json .Marshal (opregistry.GVKDependency {
501
+ val , err := json .Marshal (struct {
502
+ Group string `json:"group"`
503
+ Version string `json:"version"`
504
+ Kind string `json:"kind"`
505
+ }{
497
506
Group : a .Group ,
498
- Kind : a .Kind ,
499
507
Version : a .Version ,
508
+ Kind : a .Kind ,
500
509
})
501
510
if err != nil {
502
511
return nil , err
503
512
}
504
- out = append (out , & api.Dependency {
505
- Type : opregistry . GVKType ,
513
+ out = append (out , & api.Property {
514
+ Type : "olm.gvk.required" ,
506
515
Value : string (val ),
507
516
})
508
517
}
@@ -512,13 +521,13 @@ func apisToDependencies(apis APISet) (out []*api.Dependency, err error) {
512
521
return nil , nil
513
522
}
514
523
515
- func apisToProperties (apis APISet ) (out []* api.Property , err error ) {
524
+ func providedAPIsToProperties (apis APISet ) (out []* api.Property , err error ) {
516
525
out = make ([]* api.Property , 0 )
517
526
for a := range apis {
518
527
val , err := json .Marshal (opregistry.GVKProperty {
519
528
Group : a .Group ,
520
- Kind : a .Kind ,
521
529
Version : a .Version ,
530
+ Kind : a .Kind ,
522
531
})
523
532
if err != nil {
524
533
panic (err )
@@ -533,3 +542,63 @@ func apisToProperties(apis APISet) (out []*api.Property, err error) {
533
542
}
534
543
return nil , nil
535
544
}
545
+
546
+ func legacyDependenciesToProperties (dependencies []* api.Dependency ) ([]* api.Property , error ) {
547
+ var result []* api.Property
548
+ for _ , dependency := range dependencies {
549
+ switch dependency .Type {
550
+ case "olm.gvk" :
551
+ type gvk struct {
552
+ Group string `json:"group"`
553
+ Version string `json:"version"`
554
+ Kind string `json:"kind"`
555
+ }
556
+ var vfrom gvk
557
+ if err := json .Unmarshal ([]byte (dependency .Value ), & vfrom ); err != nil {
558
+ return nil , fmt .Errorf ("failed to unmarshal legacy 'olm.gvk' dependency: %w" , err )
559
+ }
560
+ vto := gvk {
561
+ Group : vfrom .Group ,
562
+ Version : vfrom .Version ,
563
+ Kind : vfrom .Kind ,
564
+ }
565
+ vb , err := json .Marshal (& vto )
566
+ if err != nil {
567
+ return nil , fmt .Errorf ("unexpected error marshaling generated 'olm.package.required' property: %w" , err )
568
+ }
569
+ result = append (result , & api.Property {
570
+ Type : "olm.gvk.required" ,
571
+ Value : string (vb ),
572
+ })
573
+ case "olm.package" :
574
+ var vfrom struct {
575
+ PackageName string `json:"packageName"`
576
+ VersionRange string `json:"version"`
577
+ }
578
+ if err := json .Unmarshal ([]byte (dependency .Value ), & vfrom ); err != nil {
579
+ return nil , fmt .Errorf ("failed to unmarshal legacy 'olm.package' dependency: %w" , err )
580
+ }
581
+ vto := struct {
582
+ PackageName string `json:"packageName"`
583
+ VersionRange string `json:"versionRange"`
584
+ }{
585
+ PackageName : vfrom .PackageName ,
586
+ VersionRange : vfrom .VersionRange ,
587
+ }
588
+ vb , err := json .Marshal (& vto )
589
+ if err != nil {
590
+ return nil , fmt .Errorf ("unexpected error marshaling generated 'olm.package.required' property: %w" , err )
591
+ }
592
+ result = append (result , & api.Property {
593
+ Type : "olm.package.required" ,
594
+ Value : string (vb ),
595
+ })
596
+ case "olm.label" :
597
+ result = append (result , & api.Property {
598
+ Type : "olm.label.required" ,
599
+ Value : dependency .Value ,
600
+ })
601
+ }
602
+ }
603
+ return result , nil
604
+ }
0 commit comments