@@ -2,17 +2,23 @@ package configadapter
2
2
3
3
import (
4
4
"context"
5
+ "encoding/json"
5
6
"fmt"
6
7
"path"
8
+ "regexp"
7
9
"strings"
8
10
11
+ depsv1 "get.porter.sh/porter/pkg/cnab/dependencies/v1"
12
+
9
13
"get.porter.sh/porter/pkg/cnab"
14
+ depsv2 "get.porter.sh/porter/pkg/cnab/dependencies/v2"
10
15
"get.porter.sh/porter/pkg/config"
11
16
"get.porter.sh/porter/pkg/manifest"
12
17
"get.porter.sh/porter/pkg/mixin"
13
18
"get.porter.sh/porter/pkg/tracing"
14
19
"github.com/cnabio/cnab-go/bundle"
15
20
"github.com/cnabio/cnab-go/bundle/definition"
21
+ "github.com/pkg/errors"
16
22
)
17
23
18
24
const SchemaVersion = "v1.0.0"
@@ -71,7 +77,11 @@ func (c *ManifestConverter) ToBundle(ctx context.Context) (cnab.ExtendedBundle,
71
77
b .Outputs = c .generateBundleOutputs (ctx , & b .Definitions )
72
78
b .Credentials = c .generateBundleCredentials ()
73
79
b .Images = c .generateBundleImages ()
74
- b .Custom = c .generateCustomExtensions (& b )
80
+ extensions , err := c .generateCustomExtensions (& b )
81
+ if err != nil {
82
+ return b , err
83
+ }
84
+ b .Custom = extensions
75
85
b .RequiredExtensions = c .generateRequiredExtensions (b )
76
86
77
87
b .Custom [config .CustomPorterKey ] = stamp
@@ -401,24 +411,39 @@ func (c *ManifestConverter) generateBundleImages() map[string]bundle.Image {
401
411
return images
402
412
}
403
413
404
- func (c * ManifestConverter ) generateDependencies () * cnab.Dependencies {
414
+ func (c * ManifestConverter ) generateDependencies () (interface {}, string , error ) {
415
+ if len (c .Manifest .Dependencies .Requires ) == 0 {
416
+ return nil , "" , nil
417
+ }
418
+
419
+ // Check if they are using v1 of the dependencies spec
420
+ if c .Manifest .Dependencies .Requires [0 ].Reference != "" {
421
+ deps := c .generateDependenciesV1 ()
422
+ return deps , cnab .DependenciesV1ExtensionKey , nil
423
+ }
424
+
425
+ // Ok we are using v2!
426
+ deps , err := c .generateDependenciesV2 ()
427
+ return deps , cnab .DependenciesV2ExtensionKey , err
428
+ }
405
429
406
- if len (c .Manifest .Dependencies .RequiredDependencies ) == 0 {
430
+ func (c * ManifestConverter ) generateDependenciesV1 () * depsv1.Dependencies {
431
+ if len (c .Manifest .Dependencies .Requires ) == 0 {
407
432
return nil
408
433
}
409
434
410
- deps := & cnab .Dependencies {
411
- Sequence : make ([]string , 0 , len (c .Manifest .Dependencies .RequiredDependencies )),
412
- Requires : make (map [string ]cnab .Dependency , len (c .Manifest .Dependencies .RequiredDependencies )),
435
+ deps := & depsv1 .Dependencies {
436
+ Sequence : make ([]string , 0 , len (c .Manifest .Dependencies .Requires )),
437
+ Requires : make (map [string ]depsv1 .Dependency , len (c .Manifest .Dependencies .Requires )),
413
438
}
414
439
415
- for _ , dep := range c .Manifest .Dependencies .RequiredDependencies {
416
- dependencyRef := cnab .Dependency {
440
+ for _ , dep := range c .Manifest .Dependencies .Requires {
441
+ dependencyRef := depsv1 .Dependency {
417
442
Name : dep .Name ,
418
443
Bundle : dep .Reference ,
419
444
}
420
445
if len (dep .Versions ) > 0 || dep .AllowPrereleases {
421
- dependencyRef .Version = & cnab .DependencyVersion {
446
+ dependencyRef .Version = & depsv1 .DependencyVersion {
422
447
AllowPrereleases : dep .AllowPrereleases ,
423
448
}
424
449
if len (dep .Versions ) > 0 {
@@ -433,6 +458,103 @@ func (c *ManifestConverter) generateDependencies() *cnab.Dependencies {
433
458
return deps
434
459
}
435
460
461
+ func (c * ManifestConverter ) generateDependenciesV2 () (* depsv2.Dependencies , error ) {
462
+ deps := & depsv2.Dependencies {
463
+ Requires : make (map [string ]depsv2.Dependency , len (c .Manifest .Dependencies .Requires )),
464
+ }
465
+
466
+ for _ , dep := range c .Manifest .Dependencies .Requires {
467
+ dependencyRef := depsv2.Dependency {
468
+ Name : dep .Name ,
469
+ Bundle : dep .Bundle .Reference ,
470
+ }
471
+
472
+ if len (dep .Bundle .Versions ) > 0 || dep .Bundle .AllowPrereleases {
473
+ dependencyRef .Version = & depsv2.DependencyVersion {
474
+ AllowPrereleases : dep .Bundle .AllowPrereleases ,
475
+ }
476
+ if len (dep .Bundle .Versions ) > 0 {
477
+ dependencyRef .Version .Ranges = make ([]string , len (dep .Bundle .Versions ))
478
+ copy (dependencyRef .Version .Ranges , dep .Bundle .Versions )
479
+ }
480
+ }
481
+
482
+ if dep .Bundle .Interface != nil {
483
+ if dep .Bundle .Interface .Reference != "" {
484
+ dependencyRef .Interface .Reference = dep .Bundle .Interface .Reference
485
+ }
486
+ if dep .Bundle .Interface .Document != nil {
487
+ bundleData , err := json .Marshal (dep .Bundle .Interface .Document )
488
+ if err != nil {
489
+ return nil , errors .Wrapf (err , "invalid bundle interface document for dependency %s" , dep .Name )
490
+ }
491
+ rawMessage := & json.RawMessage {}
492
+ err = rawMessage .UnmarshalJSON (bundleData )
493
+ if err != nil {
494
+ return nil , errors .Wrapf (err , "could not convert bundle interface document to a raw json message for dependency %s" , dep .Name )
495
+ }
496
+ dependencyRef .Interface .Document = rawMessage
497
+ }
498
+ }
499
+
500
+ if dep .Installation != nil {
501
+ dependencyRef .Installation = & depsv2.DependencyInstallation {
502
+ Labels : dep .Installation .Labels ,
503
+ }
504
+ if dep .Installation .Criteria != nil {
505
+ dependencyRef .Installation .Criteria = & depsv2.InstallationCriteria {
506
+ MatchInterface : dep .Installation .Criteria .MatchInterface ,
507
+ MatchNamespace : dep .Installation .Criteria .MatchNamespace ,
508
+ IgnoreLabels : dep .Installation .Criteria .IgnoreLabels ,
509
+ }
510
+ }
511
+ }
512
+
513
+ if len (dep .Parameters ) > 0 {
514
+ dependencyRef .Parameters = make (map [string ]depsv2.DependencySource , len (dep .Parameters ))
515
+ for param , source := range dep .Parameters {
516
+ dependencyRef .Parameters [param ] = parseDependencySource (source )
517
+ }
518
+ }
519
+
520
+ if len (dep .Credentials ) > 0 {
521
+ dependencyRef .Credentials = make (map [string ]depsv2.DependencySource , len (dep .Credentials ))
522
+ for cred , source := range dep .Credentials {
523
+ dependencyRef .Credentials [cred ] = parseDependencySource (source )
524
+ }
525
+ }
526
+
527
+ deps .Requires [dep .Name ] = dependencyRef
528
+ }
529
+
530
+ return deps , nil
531
+ }
532
+
533
+ // TODO: is there a way to feature flag this stuff so that if it's flakey or implemented
534
+ // incrementally we can just keep it off?
535
+ func parseDependencySource (value string ) depsv2.DependencySource {
536
+ regex := regexp .MustCompile (`bundle(\.dependencies)?\.([^.]+)\.([^.]+)\.(.+)` )
537
+ matches := regex .FindStringSubmatch (value )
538
+ if matches == nil || len (matches ) < 5 {
539
+ return depsv2.DependencySource {Value : value }
540
+ }
541
+
542
+ dependencyName := matches [2 ] // bundle.dependencies.DEPENDENCY_NAME
543
+ itemType := matches [3 ] // bundle.dependencies.dependency_name.PARAMETERS.name or bundle.OUTPUTS.name
544
+ itemName := matches [4 ] // bundle.dependencies.dependency_name.parameters.NAME or bundle.outputs.NAME
545
+
546
+ result := depsv2.DependencySource {Dependency : dependencyName }
547
+ switch itemType {
548
+ case "parameters" :
549
+ result .Parameter = itemName
550
+ case "credentials" :
551
+ result .Credential = itemName
552
+ case "outputs" :
553
+ result .Output = itemName
554
+ }
555
+ return result
556
+ }
557
+
436
558
func (c * ManifestConverter ) generateParameterSources (b * cnab.ExtendedBundle ) cnab.ParameterSources {
437
559
ps := cnab.ParameterSources {}
438
560
@@ -581,7 +703,7 @@ func toFloat(v float64) *float64 {
581
703
return & v
582
704
}
583
705
584
- func (c * ManifestConverter ) generateCustomExtensions (b * cnab.ExtendedBundle ) map [string ]interface {} {
706
+ func (c * ManifestConverter ) generateCustomExtensions (b * cnab.ExtendedBundle ) ( map [string ]interface {}, error ) {
585
707
customExtensions := map [string ]interface {}{
586
708
cnab .FileParameterExtensionKey : struct {}{},
587
709
}
@@ -592,9 +714,12 @@ func (c *ManifestConverter) generateCustomExtensions(b *cnab.ExtendedBundle) map
592
714
}
593
715
594
716
// Add the dependency extension
595
- deps := c .generateDependencies ()
596
- if deps != nil && len (deps .Requires ) > 0 {
597
- customExtensions [cnab .DependenciesExtensionKey ] = deps
717
+ deps , depsExtKey , err := c .generateDependencies ()
718
+ if err != nil {
719
+ return nil , err
720
+ }
721
+ if depsExtKey != "" {
722
+ customExtensions [depsExtKey ] = deps
598
723
}
599
724
600
725
// Add the parameter sources extension
@@ -608,15 +733,17 @@ func (c *ManifestConverter) generateCustomExtensions(b *cnab.ExtendedBundle) map
608
733
customExtensions [lookupExtensionKey (ext .Name )] = ext .Config
609
734
}
610
735
611
- return customExtensions
736
+ return customExtensions , nil
612
737
}
613
738
614
739
func (c * ManifestConverter ) generateRequiredExtensions (b cnab.ExtendedBundle ) []string {
615
740
requiredExtensions := []string {cnab .FileParameterExtensionKey }
616
741
617
742
// Add the appropriate dependencies key if applicable
618
- if b .HasDependencies () {
619
- requiredExtensions = append (requiredExtensions , cnab .DependenciesExtensionKey )
743
+ if b .HasDependenciesV1 () {
744
+ requiredExtensions = append (requiredExtensions , cnab .DependenciesV1ExtensionKey )
745
+ } else if b .HasDependenciesV2 () {
746
+ requiredExtensions = append (requiredExtensions , cnab .DependenciesV2ExtensionKey )
620
747
}
621
748
622
749
// Add the appropriate parameter sources key if applicable
0 commit comments