// List returns a list object, with its resource version set. func (f *FakeControllerSource) List() (runtime.Object, error) { f.lock.RLock() defer f.lock.RUnlock() list := make([]runtime.Object, 0, len(f.items)) for _, obj := range f.items { // Must make a copy to allow clients to modify the object. // Otherwise, if they make a change and write it back, they // will inadvertently change the our canonical copy (in // addition to racing with other clients). objCopy, err := api.Scheme.DeepCopy(obj) if err != nil { return nil, err } list = append(list, objCopy.(runtime.Object)) } listObj := &api.List{} if err := runtime.SetList(listObj, list); err != nil { return nil, err } objMeta, err := api.ListMetaFor(listObj) if err != nil { return nil, err } resourceVersion := len(f.changes) objMeta.ResourceVersion = strconv.Itoa(resourceVersion) return listObj, nil }
// setListSelfLink sets the self link of a list to the base URL, then sets the self links // on all child objects returned. func setListSelfLink(obj runtime.Object, req *restful.Request, namer ScopeNamer) error { if !runtime.IsListType(obj) { return nil } // TODO: List SelfLink generation should return a full URL? path, query, err := namer.GenerateListLink(req) if err != nil { return err } newURL := *req.Request.URL newURL.Path = path newURL.RawQuery = query // use the path that got us here newURL.Fragment = "" if err := namer.SetSelfLink(obj, newURL.String()); err != nil { glog.V(4).Infof("Unable to set self link on object: %v", err) } // Set self-link of objects in the list. items, err := runtime.ExtractList(obj) if err != nil { return err } for i := range items { if err := setSelfLink(items[i], req, namer); err != nil { return err } } return runtime.SetList(obj, items) }
// FilterList filters any list object that conforms to the api conventions, // provided that 'm' works with the concrete type of list. d is an optional // decorator for the returned functions. Only matching items are decorated. func FilterList(list runtime.Object, m Matcher, d DecoratorFunc) (filtered runtime.Object, err error) { // TODO: push a matcher down into tools.EtcdHelper to avoid all this // nonsense. This is a lot of unnecessary copies. items, err := runtime.ExtractList(list) if err != nil { return nil, err } var filteredItems []runtime.Object for _, obj := range items { match, err := m.Matches(obj) if err != nil { return nil, err } if match { if d != nil { if err := d(obj); err != nil { return nil, err } } filteredItems = append(filteredItems, obj) } } err = runtime.SetList(list, filteredItems) if err != nil { return nil, err } return list, nil }
func (o objects) Kind(kind, name string) (runtime.Object, error) { empty, _ := o.scheme.New("", kind) nilValue := reflect.Zero(reflect.TypeOf(empty)).Interface().(runtime.Object) arr, ok := o.types[kind] if !ok { if strings.HasSuffix(kind, "List") { itemKind := kind[:len(kind)-4] arr, ok := o.types[itemKind] if !ok { return empty, nil } out, err := o.scheme.New("", kind) if err != nil { return nilValue, err } if err := runtime.SetList(out, arr); err != nil { return nilValue, err } if out, err = o.scheme.Copy(out); err != nil { return nilValue, err } return out, nil } return nilValue, errors.NewNotFound(kind, name) } index := o.last[kind] if index >= len(arr) { index = len(arr) - 1 } if index < 0 { return nilValue, errors.NewNotFound(kind, name) } out, err := o.scheme.Copy(arr[index]) if err != nil { return nilValue, err } o.last[kind] = index + 1 if status, ok := out.(*api.Status); ok { if status.Details != nil { status.Details.Kind = kind } if status.Status != api.StatusSuccess { return nilValue, &errors.StatusError{*status} } } return out, nil }
func TestSetListToRuntimeObjectArray(t *testing.T) { pl := &api.List{} list := []runtime.Object{ &api.Pod{ObjectMeta: api.ObjectMeta{Name: "1"}}, &api.Pod{ObjectMeta: api.ObjectMeta{Name: "2"}}, &api.Pod{ObjectMeta: api.ObjectMeta{Name: "3"}}, } err := runtime.SetList(pl, list) if err != nil { t.Fatalf("Unexpected error %v", err) } if e, a := len(list), len(pl.Items); e != a { t.Fatalf("Expected %v, got %v", e, a) } for i := range list { if e, a := list[i], pl.Items[i]; e != a { t.Fatalf("%d: unmatched: %s", i, util.ObjectDiff(e, a)) } } }
func TestSetList(t *testing.T) { pl := &api.PodList{} list := []runtime.Object{ &api.Pod{ObjectMeta: api.ObjectMeta{Name: "1"}}, &api.Pod{ObjectMeta: api.ObjectMeta{Name: "2"}}, &api.Pod{ObjectMeta: api.ObjectMeta{Name: "3"}}, } err := runtime.SetList(pl, list) if err != nil { t.Fatalf("Unexpected error %v", err) } if e, a := len(list), len(pl.Items); e != a { t.Fatalf("Expected %v, got %v", e, a) } for i := range list { if e, a := list[i].(*api.Pod).Name, pl.Items[i].Name; e != a { t.Fatalf("Expected %v, got %v", e, a) } } }
func TestSetExtractListRoundTrip(t *testing.T) { fuzzer := fuzz.New().NilChance(0).NumElements(1, 5) for i := 0; i < 5; i++ { start := &api.PodList{} fuzzer.Fuzz(&start.Items) list, err := runtime.ExtractList(start) if err != nil { t.Errorf("Unexpected error %v", err) continue } got := &api.PodList{} err = runtime.SetList(got, list) if err != nil { t.Errorf("Unexpected error %v", err) continue } if e, a := start, got; !reflect.DeepEqual(e, a) { t.Fatalf("Expected %#v, got %#v", e, a) } } }
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)) } }