1
1
package internal
2
2
3
3
import (
4
- "encoding/json"
5
4
"fmt"
6
5
7
6
"github.com/operator-framework/api/pkg/validation/errors"
8
7
interfaces "github.com/operator-framework/api/pkg/validation/interfaces"
9
8
10
- operatorsv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1"
11
9
"github.com/operator-framework/operator-registry/pkg/registry"
12
10
)
13
11
@@ -24,71 +22,82 @@ func validateBundles(objs ...interface{}) (results []errors.ManifestResult) {
24
22
}
25
23
26
24
func validateBundle (bundle * registry.Bundle ) (result errors.ManifestResult ) {
27
- bcsv , err := bundle .ClusterServiceVersion ()
25
+ csv , err := bundle .ClusterServiceVersion ()
28
26
if err != nil {
29
27
result .Add (errors .ErrInvalidParse ("error getting bundle CSV" , err ))
30
28
return result
31
29
}
32
- csv , rerr := bundleCSVToCSV (bcsv )
33
- if rerr != (errors.Error {}) {
34
- result .Add (rerr )
30
+
31
+ result = validateOwnedCRDs (bundle , csv )
32
+
33
+ if result .Name , err = csv .GetVersion (); err != nil {
34
+ result .Add (errors .ErrInvalidParse ("error getting bundle CSV version" , err ))
35
35
return result
36
36
}
37
- result = validateOwnedCRDs (bundle , csv )
38
- result .Name = csv .Spec .Version .String ()
39
37
return result
40
38
}
41
39
42
- func bundleCSVToCSV (bcsv * registry.ClusterServiceVersion ) (* operatorsv1alpha1.ClusterServiceVersion , errors.Error ) {
43
- spec := operatorsv1alpha1.ClusterServiceVersionSpec {}
44
- if err := json .Unmarshal (bcsv .Spec , & spec ); err != nil {
45
- return nil , errors .ErrInvalidParse (fmt .Sprintf ("converting bundle CSV %q" , bcsv .GetName ()), err )
40
+ func validateOwnedCRDs (bundle * registry.Bundle , csv * registry.ClusterServiceVersion ) (result errors.ManifestResult ) {
41
+ ownedKeys , _ , err := csv .GetCustomResourceDefintions ()
42
+ if err != nil {
43
+ result .Add (errors .ErrInvalidParse ("error getting CSV CRDs" , err ))
44
+ return result
46
45
}
47
- return & operatorsv1alpha1.ClusterServiceVersion {
48
- TypeMeta : bcsv .TypeMeta ,
49
- ObjectMeta : bcsv .ObjectMeta ,
50
- Spec : spec ,
51
- }, errors.Error {}
52
- }
53
46
54
- func validateOwnedCRDs (bundle * registry.Bundle , csv * operatorsv1alpha1.ClusterServiceVersion ) (result errors.ManifestResult ) {
55
- ownedCrdNames := getOwnedCustomResourceDefintionNames (csv )
56
- crdNames , err := getBundleCRDNames (bundle )
57
- if err != (errors.Error {}) {
58
- result .Add (err )
47
+ keySet , rerr := getBundleCRDKeys (bundle )
48
+ if rerr != (errors.Error {}) {
49
+ result .Add (rerr )
59
50
return result
60
51
}
61
52
62
- // validating names
63
- for _ , crdName := range ownedCrdNames {
64
- if _ , ok := crdNames [ crdName ]; ! ok {
65
- result .Add (errors .ErrInvalidBundle (fmt .Sprintf ("owned CRD %q not found in bundle %q" , crdName , bundle .Name ), crdName ))
53
+ // Validate all owned keys, and remove them from the set if seen.
54
+ for _ , ownedKey := range ownedKeys {
55
+ if _ , ok := keySet [ * ownedKey ]; ! ok {
56
+ result .Add (errors .ErrInvalidBundle (fmt .Sprintf ("owned CRD %s not found in bundle %q" , keyToString ( * ownedKey ) , bundle .Name ), * ownedKey ))
66
57
} else {
67
- delete (crdNames , crdName )
58
+ delete (keySet , * ownedKey )
68
59
}
69
60
}
70
61
// CRDs not defined in the CSV present in the bundle
71
- for crdName := range crdNames {
72
- result .Add (errors .WarnInvalidBundle (fmt .Sprintf ("owned CRD %q is present in bundle %q but not defined in CSV" , crdName , bundle .Name ), crdName ))
62
+ for key := range keySet {
63
+ result .Add (errors .WarnInvalidBundle (fmt .Sprintf ("CRD %s is present in bundle %q but not defined in CSV" , keyToString ( key ) , bundle .Name ), key ))
73
64
}
74
65
return result
75
66
}
76
67
77
- func getOwnedCustomResourceDefintionNames (csv * operatorsv1alpha1.ClusterServiceVersion ) (names []string ) {
78
- for _ , ownedCrd := range csv .Spec .CustomResourceDefinitions .Owned {
79
- names = append (names , ownedCrd .Name )
80
- }
81
- return names
82
- }
83
-
84
- func getBundleCRDNames (bundle * registry.Bundle ) (map [string ]struct {}, errors.Error ) {
68
+ func getBundleCRDKeys (bundle * registry.Bundle ) (map [registry.DefinitionKey ]struct {}, errors.Error ) {
85
69
crds , err := bundle .CustomResourceDefinitions ()
86
70
if err != nil {
87
71
return nil , errors .ErrInvalidParse ("error getting bundle CRDs" , err )
88
72
}
89
- crdNames := map [string ]struct {}{}
73
+ keySet := map [registry. DefinitionKey ]struct {}{}
90
74
for _ , crd := range crds {
91
- crdNames [crd .GetName ()] = struct {}{}
75
+ if len (crd .Spec .Versions ) == 0 {
76
+ // Skip group, which CSVs do not support.
77
+ key := registry.DefinitionKey {
78
+ Name : crd .GetName (),
79
+ Version : crd .Spec .Version ,
80
+ Kind : crd .Spec .Names .Kind ,
81
+ }
82
+ keySet [key ] = struct {}{}
83
+ } else {
84
+ for _ , version := range crd .Spec .Versions {
85
+ // Skip group, which CSVs do not support.
86
+ key := registry.DefinitionKey {
87
+ Name : crd .GetName (),
88
+ Version : version .Name ,
89
+ Kind : crd .Spec .Names .Kind ,
90
+ }
91
+ keySet [key ] = struct {}{}
92
+ }
93
+ }
94
+ }
95
+ return keySet , errors.Error {}
96
+ }
97
+
98
+ func keyToString (key registry.DefinitionKey ) string {
99
+ if key .Name == "" {
100
+ return fmt .Sprintf ("%s/%s %s" , key .Group , key .Version , key .Kind )
92
101
}
93
- return crdNames , errors. Error {}
102
+ return fmt . Sprintf ( "%s/%s" , key . Name , key . Version )
94
103
}
0 commit comments