@@ -3,6 +3,7 @@ package cincinnati
3
3
import (
4
4
"context"
5
5
"encoding/json"
6
+ "errors"
6
7
"fmt"
7
8
"io"
8
9
"net/http"
@@ -289,9 +290,9 @@ type graph struct {
289
290
}
290
291
291
292
type node struct {
292
- Version semver.Version `json:"version"`
293
- Image string `json:"payload"`
294
- Metadata map [string ]string `json:"metadata,omitempty"`
293
+ Version semver.Version `json:"version"`
294
+ Image string `json:"payload"`
295
+ Metadata map [string ]interface {} `json:"metadata,omitempty"`
295
296
}
296
297
297
298
type edge struct {
@@ -329,28 +330,65 @@ func (e *edge) UnmarshalJSON(data []byte) error {
329
330
}
330
331
331
332
func convertRetrievedUpdateToRelease (update node ) (configv1.Release , error ) {
332
- cvoUpdate := configv1.Release {
333
- Version : update .Version .String (),
334
- Image : update .Image ,
335
- }
336
- if urlString , ok := update .Metadata ["url" ]; ok {
337
- _ , err := url .Parse (urlString )
338
- if err != nil {
339
- return cvoUpdate , fmt .Errorf ("invalid URL for %s: %s" , cvoUpdate .Version , err )
333
+ release , err := ParseMetadata (update .Metadata )
334
+ release .Version = update .Version .String ()
335
+ release .Image = update .Image
336
+ return release , err
337
+ }
338
+
339
+ // ParseMetadata parses release metadata (URL, channels, etc.). It does not populate the version or image properties.
340
+ func ParseMetadata (metadata map [string ]interface {}) (configv1.Release , error ) {
341
+ release := configv1.Release {}
342
+ errs := []error {}
343
+ if urlInterface , hasURL := metadata ["url" ]; hasURL {
344
+ if urlString , isString := urlInterface .(string ); isString {
345
+ if _ , err := url .Parse (urlString ); err == nil {
346
+ release .URL = configv1 .URL (urlString )
347
+ } else {
348
+ errs = append (errs , fmt .Errorf ("invalid release URL: %s" , err ))
349
+ }
350
+ } else {
351
+ errs = append (errs , fmt .Errorf ("URL is not a string: %v" , urlInterface ))
340
352
}
341
- cvoUpdate .URL = configv1 .URL (urlString )
342
353
}
343
- if arch , ok := update .Metadata ["release.openshift.io/architecture" ]; ok {
344
- switch arch {
345
- case "multi" :
346
- cvoUpdate .Architecture = configv1 .ClusterVersionArchitectureMulti
347
- default :
348
- klog .Warningf ("Unrecognized release.openshift.io/architecture value %q" , arch )
354
+ if archInterface , hasArch := metadata ["release.openshift.io/architecture" ]; hasArch {
355
+ if arch , isString := archInterface .(string ); isString {
356
+ if arch == "multi" {
357
+ release .Architecture = configv1 .ClusterVersionArchitectureMulti
358
+ } else {
359
+ errs = append (errs , fmt .Errorf ("unrecognized release.openshift.io/architecture value %q" , arch ))
360
+ }
361
+ } else {
362
+ errs = append (errs , fmt .Errorf ("release.openshift.io/architecture is not a string: %v" , archInterface ))
349
363
}
350
364
}
351
- if channels , ok := update .Metadata ["io.openshift.upgrades.graph.release.channels" ]; ok {
352
- cvoUpdate .Channels = strings .Split (channels , "," )
353
- sort .Strings (cvoUpdate .Channels )
365
+ if channelsInterface , hasChannels := metadata ["io.openshift.upgrades.graph.release.channels" ]; hasChannels {
366
+ if channelsString , isString := channelsInterface .(string ); isString {
367
+ if len (channelsString ) == 0 {
368
+ errs = append (errs , fmt .Errorf ("io.openshift.upgrades.graph.release.channels is an empty string" ))
369
+ } else {
370
+ channels := strings .Split (channelsString , "," )
371
+ if len (channels ) == 0 {
372
+ errs = append (errs , fmt .Errorf ("no comma-delimited channels in io.openshift.upgrades.graph.release.channels %q" , channelsString ))
373
+ } else {
374
+ for i := len (channels ) - 1 ; i >= 0 ; i -- {
375
+ if len (channels [i ]) == 0 {
376
+ errs = append (errs , fmt .Errorf ("io.openshift.upgrades.graph.release.channels entry %d is an empty string: %q" , i , channelsString ))
377
+ channels = append (channels [:i ], channels [i + 1 :]... )
378
+ }
379
+ }
380
+ if len (channels ) == 0 {
381
+ errs = append (errs , fmt .Errorf ("no non-empty channels in io.openshift.upgrades.graph.release.channels %q" , channels ))
382
+ } else {
383
+ sort .Strings (channels )
384
+ release .Channels = channels
385
+ }
386
+ }
387
+ }
388
+ } else {
389
+ errs = append (errs , fmt .Errorf ("io.openshift.upgrades.graph.release.channels is not a string: %v" , channelsInterface ))
390
+ }
354
391
}
355
- return cvoUpdate , nil
392
+ klog .V (2 ).Infof ("parsed metadata: URL %q, architecture %q, channels %v, errors %v" , release .URL , release .Architecture , release .Channels , errs )
393
+ return release , errors .Join (errs ... )
356
394
}
0 commit comments