|
1 | 1 | package internal |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "encoding/json" |
4 | 5 | "fmt" |
| 6 | + "io/ioutil" |
5 | 7 | "net/mail" |
6 | 8 | "net/url" |
| 9 | + "os" |
| 10 | + "path/filepath" |
7 | 11 | "strings" |
8 | 12 |
|
9 | 13 | "github.com/blang/semver" |
@@ -148,12 +152,57 @@ func validateHubCSVSpec(csv v1alpha1.ClusterServiceVersion) []error { |
148 | 152 | if categories, ok := csv.ObjectMeta.Annotations["categories"]; ok { |
149 | 153 | categorySlice := strings.Split(categories, ",") |
150 | 154 |
|
151 | | - for _, category := range categorySlice { |
152 | | - if _, ok := validCategories[category]; !ok { |
153 | | - errs = append(errs, fmt.Errorf("csv.Metadata.Annotations.Categories %s is not a valid category", category)) |
| 155 | + // use custom categories for validation if provided |
| 156 | + customCategoriesPath := os.Getenv("OPERATOR_BUNDLE_CATEGORIES") |
| 157 | + if customCategoriesPath != "" { |
| 158 | + customCategories, err := extractCategories(customCategoriesPath) |
| 159 | + if err != nil { |
| 160 | + errs = append(errs, fmt.Errorf("could not extract custom categories from categories %#v: %s", customCategories, err)) |
| 161 | + return errs |
| 162 | + } |
| 163 | + for _, category := range categorySlice { |
| 164 | + if _, ok := customCategories[category]; !ok { |
| 165 | + errs = append(errs, fmt.Errorf("csv.Metadata.Annotations.Categories %s is not a valid custom category", category)) |
| 166 | + } |
| 167 | + } |
| 168 | + } else { |
| 169 | + // use default categories |
| 170 | + for _, category := range categorySlice { |
| 171 | + if _, ok := validCategories[category]; !ok { |
| 172 | + errs = append(errs, fmt.Errorf("csv.Metadata.Annotations.Categories %s is not a valid category", category)) |
| 173 | + } |
154 | 174 | } |
155 | 175 | } |
156 | 176 | } |
157 | 177 |
|
158 | 178 | return errs |
159 | 179 | } |
| 180 | + |
| 181 | +type categories struct { |
| 182 | + Contents []string `json:"categories"` |
| 183 | +} |
| 184 | + |
| 185 | +// extractCategories reads a custom categories file and returns the contents in a map[string]struct{} |
| 186 | +func extractCategories(path string) (map[string]struct{}, error) { |
| 187 | + path, err := filepath.Abs(path) |
| 188 | + if err != nil { |
| 189 | + return nil, fmt.Errorf("finding category file: %w", err) |
| 190 | + } |
| 191 | + |
| 192 | + data, err := ioutil.ReadFile(path) |
| 193 | + if err != nil { |
| 194 | + return nil, fmt.Errorf("reading category file: %w", err) |
| 195 | + } |
| 196 | + |
| 197 | + cat := categories{} |
| 198 | + err = json.Unmarshal(data, &cat) |
| 199 | + if err != nil { |
| 200 | + return nil, fmt.Errorf("unmarshaling category file: %w", err) |
| 201 | + } |
| 202 | + |
| 203 | + customCategories := make(map[string]struct{}) |
| 204 | + for _, c := range cat.Contents { |
| 205 | + customCategories[c] = struct{}{} |
| 206 | + } |
| 207 | + return customCategories, nil |
| 208 | +} |
0 commit comments