Skip to content
This repository has been archived by the owner on Nov 1, 2022. It is now read-only.

Commit

Permalink
Recognise individual items in List resource
Browse files Browse the repository at this point in the history
It's not enough to be able to update images in a List resource, we
must be able to recognise them in the first place.

The YAML parser makes this a little tricky, because it doesn't give
you access to the bytes (like `UnmarshalJSON` does), so if we want
typed resources, we have to parse them generically and marshal them
back out to bytes. (Another way to do it would be to unmarshal into a
baseObject, then into the specific object based on the kind. That
might be a good refactoring.)
  • Loading branch information
squaremo committed Mar 5, 2018
1 parent 32b6b2a commit c34b730
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 1 deletion.
10 changes: 9 additions & 1 deletion cluster/kubernetes/resource/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,15 @@ func ParseMultidoc(multidoc []byte, source string) (map[string]resource.Resource
if obj == nil {
continue
}
objs[obj.ResourceID().String()] = obj
// Lists must be treated specially, since it's the
// contained resources we are after.
if list, ok := obj.(*List); ok {
for _, item := range list.Items {
objs[item.ResourceID().String()] = item
}
} else {
objs[obj.ResourceID().String()] = obj
}
}

if err := chunks.Err(); err != nil {
Expand Down
34 changes: 34 additions & 0 deletions cluster/kubernetes/resource/load_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"reflect"
"testing"

"github.com/weaveworks/flux"
"github.com/weaveworks/flux/cluster/kubernetes/testfiles"
"github.com/weaveworks/flux/resource"
)
Expand Down Expand Up @@ -117,6 +118,39 @@ data:
}
}

func TestUnmarshalList(t *testing.T) {
doc := `---
kind: List
metadata:
name: list
items:
- kind: Deployment
metadata:
name: foo
- kind: Service
metadata:
name: bar
`
res, err := unmarshalObject("", []byte(doc))
if err != nil {
t.Fatal(err)
}
list, ok := res.(*List)
if !ok {
t.Fatal("did not parse as a list")
}
if len(list.Items) != 2 {
t.Fatalf("expected two items, got %+v", list.Items)
}
for i, id := range []flux.ResourceID{
flux.MustParseResourceID("default:deployment/foo"),
flux.MustParseResourceID("default:service/bar")} {
if list.Items[i].ResourceID() != id {
t.Errorf("At %d, expected %q, got %q", i, id, list.Items[i].ResourceID())
}
}
}

func debyte(r resource.Resource) resource.Resource {
if res, ok := r.(interface {
debyte()
Expand Down
6 changes: 6 additions & 0 deletions cluster/kubernetes/resource/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,12 @@ func unmarshalKind(base baseObject, bytes []byte) (resource.Resource, error) {
return nil, err
}
return &ss, nil
case "List":
var list = List{baseObject: base}
if err := yaml.Unmarshal(bytes, &list); err != nil {
return nil, err
}
return &list, nil
case "":
// If there is an empty resource (due to eg an introduced comment),
// we are returning nil for the resource and nil for an error
Expand Down

0 comments on commit c34b730

Please sign in to comment.