@@ -8,57 +8,138 @@ import (
88
99 "sigs.k8s.io/controller-runtime/pkg/client"
1010 "sigs.k8s.io/yaml"
11+
12+ "github.com/operator-framework/api/pkg/operators/v1alpha1"
13+ "github.com/operator-framework/operator-registry/alpha/property"
14+
15+ "github.com/operator-framework/operator-controller/internal/operator-controller/rukpak/bundle/source"
16+ registry "github.com/operator-framework/operator-controller/internal/operator-controller/rukpak/operator-registry"
1117)
1218
1319const (
1420 BundlePathAnnotations = "metadata/annotations.yaml"
1521 BundlePathProperties = "metadata/properties.yaml"
1622 BundlePathManifests = "manifests"
17- BundlePathCSV = BundlePathManifests + "/csv.yaml"
1823)
1924
20- func NewBundleFS () fstest.MapFS {
21- annotationsYml := `
22- annotations:
23- operators.operatorframework.io.bundle.mediatype.v1: registry+v1
24- operators.operatorframework.io.bundle.package.v1: test
25- `
26-
27- propertiesYml := `
28- properties:
29- - type: "from-file-key"
30- value: "from-file-value"
31- `
32-
33- csvYml := `
34- apiVersion: operators.operatorframework.io/v1alpha1
35- kind: ClusterServiceVersion
36- metadata:
37- name: test.v1.0.0
38- annotations:
39- olm.properties: '[{"type":"from-csv-annotations-key", "value":"from-csv-annotations-value"}]'
40- spec:
41- installModes:
42- - type: AllNamespaces
43- supported: true
44- `
45-
46- return fstest.MapFS {
47- BundlePathAnnotations : & fstest.MapFile {Data : []byte (strings .Trim (annotationsYml , "\n " ))},
48- BundlePathProperties : & fstest.MapFile {Data : []byte (strings .Trim (propertiesYml , "\n " ))},
49- BundlePathCSV : & fstest.MapFile {Data : []byte (strings .Trim (csvYml , "\n " ))},
25+ // Builder builds a registry+v1 bundle filesystem
26+ type Builder interface {
27+ WithPackageName (packageName string ) Builder
28+ WithChannels (channels ... string ) Builder
29+ WithDefaultChannel (channel string ) Builder
30+ WithBundleProperty (propertyType string , value string ) Builder
31+ WithBundleResource (resourceName string , resource client.Object ) Builder
32+ WithCSV (csv v1alpha1.ClusterServiceVersion ) Builder
33+ Build () fstest.MapFS
34+ }
35+
36+ // bundleFSBuilder builds a registry+v1 bundle filesystem
37+ type bundleFSBuilder struct {
38+ annotations * registry.Annotations
39+ properties []property.Property
40+ resources map [string ]client.Object
41+ }
42+
43+ func BundleFSBuilder () Builder {
44+ return & bundleFSBuilder {}
45+ }
46+
47+ // WithPackageName is an option for NewBundleFS used to set the package name annotation in the
48+ // bundle filesystem metadata/annotations.yaml file
49+ func (b * bundleFSBuilder ) WithPackageName (packageName string ) Builder {
50+ if b .annotations == nil {
51+ b .annotations = & registry.Annotations {}
5052 }
53+ b .annotations .PackageName = packageName
54+ return b
5155}
5256
53- func AddManifest (bundleFS fstest.MapFS , obj client.Object ) error {
54- gvk := obj .GetObjectKind ().GroupVersionKind ()
55- manifestName := fmt .Sprintf ("%s%s_%s_%s%s.yaml" , gvk .Group , gvk .Version , gvk .Kind , obj .GetNamespace (), obj .GetName ())
56- bytes , err := yaml .Marshal (obj )
57- if err != nil {
58- return err
57+ // WithChannels is an option for NewBundleFS used to set the channels annotation in the
58+ // bundle filesystem metadata/annotations.yaml file
59+ func (b * bundleFSBuilder ) WithChannels (channels ... string ) Builder {
60+ if b .annotations == nil {
61+ b .annotations = & registry.Annotations {}
5962 }
60- bundleFS [filepath .Join (BundlePathManifests , manifestName )] = & fstest.MapFile {
61- Data : bytes ,
63+ b .annotations .Channels = strings .Join (channels , "," )
64+ return b
65+ }
66+
67+ // WithDefaultChannel is an option for NewBundleFS used to set the channel annotation in the
68+ // bundle filesystem metadata/annotations.yaml file
69+ func (b * bundleFSBuilder ) WithDefaultChannel (channel string ) Builder {
70+ if b .annotations == nil {
71+ b .annotations = & registry.Annotations {}
6272 }
63- return nil
73+ b .annotations .DefaultChannelName = channel
74+ return b
75+ }
76+
77+ // WithBundleProperty is an options for NewBundleFS used to add a property to the list of properties
78+ // in the bundle filesystem metadata/properties.yaml file
79+ func (b * bundleFSBuilder ) WithBundleProperty (propertyType string , value string ) Builder {
80+ b .properties = append (b .properties , property.Property {
81+ Type : propertyType ,
82+ Value : []byte (`"` + value + `"` ),
83+ })
84+ return b
85+ }
86+
87+ // WithBundleResource is an option for NewBundleFS use to add the yaml representation of resource to the
88+ // path manifests/<resourceName>.yaml on the bundles filesystem
89+ func (b * bundleFSBuilder ) WithBundleResource (resourceName string , resource client.Object ) Builder {
90+ if b .resources == nil {
91+ b .resources = make (map [string ]client.Object )
92+ }
93+ b .resources [resourceName ] = resource
94+ return b
95+ }
96+
97+ // WithCSV is an optiona for NewBundleFS used to add the yaml representation of csv to the
98+ // path manifests/csv.yaml on the bundle filesystem
99+ func (b * bundleFSBuilder ) WithCSV (csv v1alpha1.ClusterServiceVersion ) Builder {
100+ if b .resources == nil {
101+ b .resources = make (map [string ]client.Object )
102+ }
103+ b .resources ["csv.yaml" ] = & csv
104+ return b
105+ }
106+
107+ // Build creates a registry+v1 bundle filesystem with the applied options
108+ // By default, an empty registry+v1 bundle filesystem will be returned
109+ func (b * bundleFSBuilder ) Build () fstest.MapFS {
110+ bundleFS := fstest.MapFS {}
111+
112+ // Add annotations metadata
113+ if b .annotations != nil {
114+ annotationsYml , err := yaml .Marshal (registry.AnnotationsFile {
115+ Annotations : * b .annotations ,
116+ })
117+ if err != nil {
118+ panic (fmt .Errorf ("error building bundle fs: %w" , err ))
119+ }
120+ bundleFS [BundlePathAnnotations ] = & fstest.MapFile {Data : annotationsYml }
121+ }
122+
123+ // Add property metadata
124+ if len (b .properties ) > 0 {
125+ propertiesYml , err := yaml .Marshal (source.RegistryV1Properties {
126+ Properties : b .properties ,
127+ })
128+ if err != nil {
129+ panic (fmt .Errorf ("error building bundle fs: %w" , err ))
130+ }
131+ bundleFS [BundlePathProperties ] = & fstest.MapFile {Data : propertiesYml }
132+ }
133+
134+ // Add resources
135+ for name , obj := range b .resources {
136+ resourcePath := filepath .Join (BundlePathManifests , name )
137+ resourceYml , err := yaml .Marshal (obj )
138+ if err != nil {
139+ panic (fmt .Errorf ("error building bundle fs: %w" , err ))
140+ }
141+ bundleFS [resourcePath ] = & fstest.MapFile {Data : resourceYml }
142+ }
143+
144+ return bundleFS
64145}
0 commit comments