// 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
}
Example #2
0
// 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)

}
Example #3
0
// 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
}
Example #4
0
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
}
Example #5
0
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))
		}
	}
}
Example #6
0
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)
		}
	}
}
Example #7
0
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)
		}
	}
}
Example #8
0
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))
	}
}