func (v FlattenListVisitor) Visit(fn VisitorFunc) error { return v.Visitor.Visit(func(info *Info) error { if info.Object == nil { return fn(info) } items, err := runtime.ExtractList(info.Object) if err != nil { return fn(info) } if errs := runtime.DecodeList(items, struct { runtime.ObjectTyper runtime.Decoder }{v.Mapper, info.Mapping.Codec}); len(errs) > 0 { return errors.NewAggregate(errs) } for i := range items { item, err := v.InfoForObject(items[i]) if err != nil { return err } if len(info.ResourceVersion) != 0 { item.ResourceVersion = info.ResourceVersion } if err := fn(item); err != nil { return err } } return nil }) }
func (o objects) Add(obj runtime.Object) error { _, kind, err := o.scheme.ObjectVersionAndKind(obj) if err != nil { return err } switch { case runtime.IsListType(obj): if kind != "List" { o.types[kind] = append(o.types[kind], obj) } list, err := runtime.ExtractList(obj) if err != nil { return err } if errs := runtime.DecodeList(list, o.decoder); len(errs) > 0 { return errs[0] } for _, obj := range list { if err := o.Add(obj); err != nil { return err } } default: if status, ok := obj.(*api.Status); ok && status.Details != nil { kind = status.Details.Kind } o.types[kind] = append(o.types[kind], obj) } return nil }
func TestDecodeList(t *testing.T) { pl := &api.List{ Items: []runtime.Object{ &api.Pod{ObjectMeta: api.ObjectMeta{Name: "1"}}, &runtime.Unknown{TypeMeta: runtime.TypeMeta{Kind: "Pod", APIVersion: testapi.Version()}, RawJSON: []byte(`{"kind":"Pod","apiVersion":"` + testapi.Version() + `","metadata":{"name":"test"}}`)}, &runtime.Unstructured{TypeMeta: runtime.TypeMeta{Kind: "Foo", APIVersion: "Bar"}, Object: map[string]interface{}{"test": "value"}}, }, } if errs := runtime.DecodeList(pl.Items, api.Scheme); len(errs) != 0 { t.Fatalf("unexpected error %v", errs) } if pod, ok := pl.Items[1].(*api.Pod); !ok || pod.Name != "test" { t.Errorf("object not converted: %#v", pl.Items[1]) } }
func TestDecodeUnstructured(t *testing.T) { pl := &api.List{ Items: []runtime.Object{ &api.Pod{ObjectMeta: api.ObjectMeta{Name: "1"}}, &runtime.Unknown{TypeMeta: runtime.TypeMeta{Kind: "Pod", APIVersion: "v1beta3"}, RawJSON: []byte(`{"kind":"Pod","apiVersion":"v1beta3","metadata":{"name":"test"}}`)}, &runtime.Unknown{TypeMeta: runtime.TypeMeta{Kind: "", APIVersion: "v1beta3"}, RawJSON: []byte(`{"kind":"Pod","apiVersion":"v1beta3","metadata":{"name":"test"}}`)}, &runtime.Unknown{TypeMeta: runtime.TypeMeta{Kind: "Pod", APIVersion: "v1"}, RawJSON: []byte(`{"kind":"Pod","apiVersion":"v1","metadata":{"name":"test"}}`)}, &runtime.Unknown{TypeMeta: runtime.TypeMeta{Kind: "", APIVersion: "v1"}, RawJSON: []byte(`{"kind":"Pod","apiVersion":"v1","metadata":{"name":"test"}}`)}, &runtime.Unstructured{TypeMeta: runtime.TypeMeta{Kind: "Foo", APIVersion: "Bar"}, Object: map[string]interface{}{"test": "value"}}, }, } if errs := runtime.DecodeList(pl.Items, runtime.UnstructuredJSONScheme); len(errs) == 1 { t.Fatalf("unexpected error %v", errs) } if pod, ok := pl.Items[1].(*runtime.Unstructured); !ok || pod.Object["kind"] != "Pod" || pod.Object["metadata"].(map[string]interface{})["name"] != "test" { t.Errorf("object not converted: %#v", pl.Items[1]) } if _, ok := pl.Items[2].(*runtime.Unknown); !ok { t.Errorf("object should not have been converted: %#v", pl.Items[2]) } }
func TestArrayOfRuntimeObject(t *testing.T) { s := runtime.NewScheme() s.AddKnownTypes("", &EmbeddedTest{}) s.AddKnownTypeWithName("v1test", "EmbeddedTest", &EmbeddedTestExternal{}) s.AddKnownTypes("", &ObjectTest{}) s.AddKnownTypeWithName("v1test", "ObjectTest", &ObjectTestExternal{}) internal := &ObjectTest{ Items: []runtime.Object{ &EmbeddedTest{ID: "foo"}, &EmbeddedTest{ID: "bar"}, // TODO: until YAML is removed, this JSON must be in ascending key order to ensure consistent roundtrip serialization &runtime.Unknown{RawJSON: []byte(`{"apiVersion":"unknown","foo":"bar","kind":"OtherTest"}`)}, &ObjectTest{ Items: []runtime.Object{ &EmbeddedTest{ID: "baz"}, }, }, }, } wire, err := s.EncodeToVersion(internal, "v1test") if err != nil { t.Fatalf("unexpected error: %v", err) } t.Logf("Wire format is:\n%s\n", string(wire)) obj := &ObjectTestExternal{} if err := json.Unmarshal(wire, obj); err != nil { t.Fatalf("unexpected error: %v", err) } t.Logf("exact wire is: %s", string(obj.Items[0].RawJSON)) decoded, err := s.Decode(wire) if err != nil { t.Fatalf("unexpected error: %v", err) } list, err := runtime.ExtractList(decoded) if err != nil { t.Fatalf("unexpected error: %v", err) } if errs := runtime.DecodeList(list, s); len(errs) > 0 { t.Fatalf("unexpected error: %v", errs) } list2, err := runtime.ExtractList(list[3]) if err != nil { t.Fatalf("unexpected error: %v", err) } if errs := runtime.DecodeList(list2, s); len(errs) > 0 { t.Fatalf("unexpected error: %v", errs) } if err := runtime.SetList(list[3], list2); err != nil { t.Fatalf("unexpected error: %v", err) } internal.Items[2].(*runtime.Unknown).Kind = "OtherTest" internal.Items[2].(*runtime.Unknown).APIVersion = "unknown" if e, a := internal.Items, list; !reflect.DeepEqual(e, a) { t.Errorf("mismatched decoded: %s", util.ObjectDiff(e, a)) } }