mirror of
				https://github.com/k3s-io/kubernetes.git
				synced 2025-11-04 07:49:35 +00:00 
			
		
		
		
	Merge pull request #2082 from lavalamp/fix
Fix self linking of objects returned in lists.
This commit is contained in:
		@@ -269,6 +269,63 @@ func runAPIVersionsTest(c *client.Client) {
 | 
			
		||||
	glog.Infof("Version test passed")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func runSelfLinkTest(c *client.Client) {
 | 
			
		||||
	var svc api.Service
 | 
			
		||||
	err := c.Post().Path("services").Body(
 | 
			
		||||
		&api.Service{
 | 
			
		||||
			ObjectMeta: api.ObjectMeta{
 | 
			
		||||
				Name: "selflinktest",
 | 
			
		||||
				Labels: map[string]string{
 | 
			
		||||
					"name": "selflinktest",
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			Port: 12345,
 | 
			
		||||
			// This is here because validation requires it.
 | 
			
		||||
			Selector: map[string]string{
 | 
			
		||||
				"foo": "bar",
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	).Do().Into(&svc)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		glog.Fatalf("Failed creating selflinktest service: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
	err = c.Get().AbsPath(svc.SelfLink).Do().Into(&svc)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		glog.Fatalf("Failed listing service with supplied self link '%v': %v", svc.SelfLink, err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var svcList api.ServiceList
 | 
			
		||||
	err = c.Get().Path("services").Do().Into(&svcList)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		glog.Fatalf("Failed listing services: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = c.Get().AbsPath(svcList.SelfLink).Do().Into(&svcList)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		glog.Fatalf("Failed listing services with supplied self link '%v': %v", svcList.SelfLink, err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	found := false
 | 
			
		||||
	for i := range svcList.Items {
 | 
			
		||||
		item := &svcList.Items[i]
 | 
			
		||||
		if item.Name != "selflinktest" {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		found = true
 | 
			
		||||
		err = c.Get().AbsPath(item.SelfLink).Do().Into(&svc)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			glog.Fatalf("Failed listing service with supplied self link '%v': %v", item.SelfLink, err)
 | 
			
		||||
		}
 | 
			
		||||
		break
 | 
			
		||||
	}
 | 
			
		||||
	if !found {
 | 
			
		||||
		glog.Fatalf("never found selflinktest service")
 | 
			
		||||
	}
 | 
			
		||||
	glog.Infof("Self link test passed")
 | 
			
		||||
 | 
			
		||||
	// TODO: Should test PUT at some point, too.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func runAtomicPutTest(c *client.Client) {
 | 
			
		||||
	var svc api.Service
 | 
			
		||||
	err := c.Post().Path("services").Body(
 | 
			
		||||
@@ -507,6 +564,7 @@ func main() {
 | 
			
		||||
		runServiceTest,
 | 
			
		||||
		runAPIVersionsTest,
 | 
			
		||||
		runMasterServiceTest,
 | 
			
		||||
		runSelfLinkTest,
 | 
			
		||||
	}
 | 
			
		||||
	var wg sync.WaitGroup
 | 
			
		||||
	wg.Add(len(testFuncs))
 | 
			
		||||
 
 | 
			
		||||
@@ -62,7 +62,25 @@ func (h *RESTHandler) setSelfLink(obj runtime.Object, req *http.Request) error {
 | 
			
		||||
	newURL.Path = path.Join(h.canonicalPrefix, req.URL.Path)
 | 
			
		||||
	newURL.RawQuery = ""
 | 
			
		||||
	newURL.Fragment = ""
 | 
			
		||||
	return h.selfLinker.SetSelfLink(obj, newURL.String())
 | 
			
		||||
	err := h.selfLinker.SetSelfLink(obj, newURL.String())
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if !runtime.IsListType(obj) {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Set self-link of objects in the list.
 | 
			
		||||
	items, err := runtime.ExtractList(obj)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	for i := range items {
 | 
			
		||||
		if err := h.setSelfLinkAddName(items[i], req); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return runtime.SetList(obj, items)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Like setSelfLink, but appends the object's name.
 | 
			
		||||
 
 | 
			
		||||
@@ -23,6 +23,11 @@ import (
 | 
			
		||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func IsListType(obj Object) bool {
 | 
			
		||||
	_, err := GetItemsPtr(obj)
 | 
			
		||||
	return err == nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetItemsPtr returns a pointer to the list object's Items member.
 | 
			
		||||
// If 'list' doesn't have an Items member, it's not really a list type
 | 
			
		||||
// and an error will be returned.
 | 
			
		||||
 
 | 
			
		||||
@@ -26,6 +26,21 @@ import (
 | 
			
		||||
	"github.com/google/gofuzz"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestIsList(t *testing.T) {
 | 
			
		||||
	tests := []struct {
 | 
			
		||||
		obj    runtime.Object
 | 
			
		||||
		isList bool
 | 
			
		||||
	}{
 | 
			
		||||
		{&api.PodList{}, true},
 | 
			
		||||
		{&api.Pod{}, false},
 | 
			
		||||
	}
 | 
			
		||||
	for _, item := range tests {
 | 
			
		||||
		if e, a := item.isList, runtime.IsListType(item.obj); e != a {
 | 
			
		||||
			t.Errorf("%v: Expected %v, got %v", reflect.TypeOf(item.obj), e, a)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestExtractList(t *testing.T) {
 | 
			
		||||
	pl := &api.PodList{
 | 
			
		||||
		Items: []api.Pod{
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user