Skip to content

Commit b9294a7

Browse files
authored
combine bundle properties from csv and metadata/properties.yaml (#1495)
Signed-off-by: Joe Lanford <[email protected]>
1 parent a723f9a commit b9294a7

File tree

5 files changed

+86
-3
lines changed

5 files changed

+86
-3
lines changed

internal/rukpak/convert/registryv1.go

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"crypto/sha256"
66
"encoding/json"
7+
"errors"
78
"fmt"
89
"io/fs"
910
"path/filepath"
@@ -23,6 +24,7 @@ import (
2324
"sigs.k8s.io/yaml"
2425

2526
"github.com/operator-framework/api/pkg/operators/v1alpha1"
27+
"github.com/operator-framework/operator-registry/alpha/property"
2628
registrybundle "github.com/operator-framework/operator-registry/pkg/lib/bundle"
2729

2830
registry "github.com/operator-framework/operator-controller/internal/rukpak/operator-registry"
@@ -43,12 +45,12 @@ func RegistryV1ToHelmChart(ctx context.Context, rv1 fs.FS, installNamespace stri
4345
l := log.FromContext(ctx)
4446

4547
reg := RegistryV1{}
46-
fileData, err := fs.ReadFile(rv1, filepath.Join("metadata", "annotations.yaml"))
48+
annotationsFileData, err := fs.ReadFile(rv1, filepath.Join("metadata", "annotations.yaml"))
4749
if err != nil {
4850
return nil, err
4951
}
5052
annotationsFile := registry.AnnotationsFile{}
51-
if err := yaml.Unmarshal(fileData, &annotationsFile); err != nil {
53+
if err := yaml.Unmarshal(annotationsFileData, &annotationsFile); err != nil {
5254
return nil, err
5355
}
5456
reg.PackageName = annotationsFile.Annotations.PackageName
@@ -101,9 +103,61 @@ func RegistryV1ToHelmChart(ctx context.Context, rv1 fs.FS, installNamespace stri
101103
return nil, err
102104
}
103105

106+
if err := copyMetadataPropertiesToCSV(&reg.CSV, rv1); err != nil {
107+
return nil, err
108+
}
109+
104110
return toChart(reg, installNamespace, watchNamespaces)
105111
}
106112

113+
// copyMetadataPropertiesToCSV copies properties from `metadata/propeties.yaml` (in the filesystem fsys) into
114+
// the CSV's `.metadata.annotations['olm.properties']` value, preserving any properties that are already
115+
// present in the annotations.
116+
func copyMetadataPropertiesToCSV(csv *v1alpha1.ClusterServiceVersion, fsys fs.FS) error {
117+
var allProperties []property.Property
118+
119+
// First load existing properties from the CSV. We want to preserve these.
120+
if csvPropertiesJSON, ok := csv.Annotations["olm.properties"]; ok {
121+
var csvProperties []property.Property
122+
if err := json.Unmarshal([]byte(csvPropertiesJSON), &csvProperties); err != nil {
123+
return fmt.Errorf("failed to unmarshal csv.metadata.annotations['olm.properties']: %w", err)
124+
}
125+
allProperties = append(allProperties, csvProperties...)
126+
}
127+
128+
// Next, load properties from the metadata/properties.yaml file, if it exists.
129+
metadataPropertiesJSON, err := fs.ReadFile(fsys, filepath.Join("metadata", "properties.yaml"))
130+
if err != nil && !errors.Is(err, fs.ErrNotExist) {
131+
return fmt.Errorf("failed to read properties.yaml file: %w", err)
132+
}
133+
134+
// If there are no properties, we can stick with whatever
135+
// was already present in the CSV annotations.
136+
if len(metadataPropertiesJSON) == 0 {
137+
return nil
138+
}
139+
140+
// Otherwise, we need to parse the properties.yaml file and
141+
// append its properties into the CSV annotation.
142+
type registryV1Properties struct {
143+
Properties []property.Property `json:"properties"`
144+
}
145+
146+
var metadataProperties registryV1Properties
147+
if err := yaml.Unmarshal(metadataPropertiesJSON, &metadataProperties); err != nil {
148+
return fmt.Errorf("failed to unmarshal metadata/properties.yaml: %w", err)
149+
}
150+
allProperties = append(allProperties, metadataProperties.Properties...)
151+
152+
// Lastly re-marshal all the properties back into a JSON array and update the CSV annotation
153+
allPropertiesJSON, err := json.Marshal(allProperties)
154+
if err != nil {
155+
return fmt.Errorf("failed to marshal registry+v1 properties to json: %w", err)
156+
}
157+
csv.Annotations["olm.properties"] = string(allPropertiesJSON)
158+
return nil
159+
}
160+
107161
func toChart(in RegistryV1, installNamespace string, watchNamespaces []string) (*chart.Chart, error) {
108162
plain, err := Convert(in, installNamespace, watchNamespaces)
109163
if err != nil {

internal/rukpak/convert/registryv1_test.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package convert
22

33
import (
4+
"context"
45
"fmt"
6+
"os"
57
"strings"
68
"testing"
79

@@ -24,7 +26,7 @@ import (
2426

2527
func TestRegistryV1Converter(t *testing.T) {
2628
RegisterFailHandler(Fail)
27-
RunSpecs(t, "RegstryV1 suite")
29+
RunSpecs(t, "RegistryV1 suite")
2830
}
2931

3032
var _ = Describe("RegistryV1 Suite", func() {
@@ -418,6 +420,17 @@ var _ = Describe("RegistryV1 Suite", func() {
418420
})
419421
})
420422

423+
Context("Should read the registry+v1 bundle filesystem correctly", func() {
424+
It("should include metadata/properties.yaml and csv.metadata.annotations['olm.properties'] in chart metadata", func() {
425+
fsys := os.DirFS("testdata/combine-properties-bundle")
426+
chrt, err := RegistryV1ToHelmChart(context.Background(), fsys, "", nil)
427+
Expect(err).NotTo(HaveOccurred())
428+
Expect(chrt).NotTo(BeNil())
429+
Expect(chrt.Metadata).NotTo(BeNil())
430+
Expect(chrt.Metadata.Annotations).To(HaveKeyWithValue("olm.properties", `[{"type":"from-csv-annotations-key","value":"from-csv-annotations-value"},{"type":"from-file-key","value":"from-file-value"}]`))
431+
})
432+
})
433+
421434
Context("Should enforce limitations", func() {
422435
It("should not allow bundles with webhooks", func() {
423436
By("creating a registry v1 bundle")
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
apiVersion: operators.operatorframework.io/v1alpha1
2+
kind: ClusterServiceVersion
3+
metadata:
4+
name: test.v1.0.0
5+
annotations:
6+
olm.properties: '[{"type":"from-csv-annotations-key", "value":"from-csv-annotations-value"}]'
7+
spec:
8+
installModes:
9+
- type: AllNamespaces
10+
supported: true
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
annotations:
2+
operators.operatorframework.io.bundle.mediatype.v1: registry+v1
3+
operators.operatorframework.io.bundle.package.v1: test
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
properties:
2+
- type: "from-file-key"
3+
value: "from-file-value"

0 commit comments

Comments
 (0)