mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 12:18:16 +00:00 
			
		
		
		
	Merge pull request #21179 from smarterclayton/cant_replace_cluster_resource
Auto commit by PR queue bot
This commit is contained in:
		@@ -522,6 +522,31 @@ runTests() {
 | 
				
			|||||||
  #cleaning
 | 
					  #cleaning
 | 
				
			||||||
  rm /tmp/tmp-valid-pod.json
 | 
					  rm /tmp/tmp-valid-pod.json
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
 | 
					  ## replace of a cluster scoped resource can succeed
 | 
				
			||||||
 | 
					  # Pre-condition: a node exists
 | 
				
			||||||
 | 
					  kubectl create -f - "${kube_flags[@]}" << __EOF__
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  "kind": "Node",
 | 
				
			||||||
 | 
					  "apiVersion": "v1",
 | 
				
			||||||
 | 
					  "metadata": {
 | 
				
			||||||
 | 
					    "name": "node-${version}-test"
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					__EOF__
 | 
				
			||||||
 | 
					  kubectl replace -f - "${kube_flags[@]}" << __EOF__
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  "kind": "Node",
 | 
				
			||||||
 | 
					  "apiVersion": "v1",
 | 
				
			||||||
 | 
					  "metadata": {
 | 
				
			||||||
 | 
					    "name": "node-${version}-test",
 | 
				
			||||||
 | 
					    "annotations": {"a":"b"}
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					__EOF__
 | 
				
			||||||
 | 
					  # Post-condition: the node command succeeds
 | 
				
			||||||
 | 
					  kube::test::get_object_assert "node node-${version}-test" "{{.metadata.annotations.a}}" 'b'
 | 
				
			||||||
 | 
					  kubectl delete node node-${version}-test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ## kubectl edit can update the image field of a POD. tmp-editor.sh is a fake editor
 | 
					  ## kubectl edit can update the image field of a POD. tmp-editor.sh is a fake editor
 | 
				
			||||||
  echo -e '#!/bin/bash\nsed -i "s/nginx/gcr.io\/google_containers\/serve_hostname/g" $1' > /tmp/tmp-editor.sh
 | 
					  echo -e '#!/bin/bash\nsed -i "s/nginx/gcr.io\/google_containers\/serve_hostname/g" $1' > /tmp/tmp-editor.sh
 | 
				
			||||||
  chmod +x /tmp/tmp-editor.sh
 | 
					  chmod +x /tmp/tmp-editor.sh
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -144,7 +144,7 @@ func (m *Helper) Replace(namespace, name string, overwrite bool, obj runtime.Obj
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	if version == "" && overwrite {
 | 
						if version == "" && overwrite {
 | 
				
			||||||
		// Retrieve the current version of the object to overwrite the server object
 | 
							// Retrieve the current version of the object to overwrite the server object
 | 
				
			||||||
		serverObj, err := c.Get().Namespace(namespace).Resource(m.Resource).Name(name).Do().Get()
 | 
							serverObj, err := c.Get().NamespaceIfScoped(namespace, m.NamespaceScoped).Resource(m.Resource).Name(name).Do().Get()
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			// The object does not exist, but we want it to be created
 | 
								// The object does not exist, but we want it to be created
 | 
				
			||||||
			return m.replaceResource(c, m.Resource, namespace, name, obj)
 | 
								return m.replaceResource(c, m.Resource, namespace, name, obj)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -357,18 +357,13 @@ func TestHelperList(t *testing.T) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestHelperReplace(t *testing.T) {
 | 
					func TestHelperReplace(t *testing.T) {
 | 
				
			||||||
	expectPut := func(req *http.Request) bool {
 | 
						expectPut := func(path string, req *http.Request) bool {
 | 
				
			||||||
		if req.Method != "PUT" {
 | 
							if req.Method != "PUT" {
 | 
				
			||||||
			t.Errorf("unexpected method: %#v", req)
 | 
								t.Errorf("unexpected method: %#v", req)
 | 
				
			||||||
			return false
 | 
								return false
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		parts := splitPath(req.URL.Path)
 | 
							if req.URL.Path != path {
 | 
				
			||||||
		if parts[1] != "bar" {
 | 
								t.Errorf("unexpected url: %v", req.URL)
 | 
				
			||||||
			t.Errorf("url doesn't contain namespace: %#v", req.URL)
 | 
					 | 
				
			||||||
			return false
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if parts[2] != "foo" {
 | 
					 | 
				
			||||||
			t.Errorf("url doesn't contain name: %#v", req)
 | 
					 | 
				
			||||||
			return false
 | 
								return false
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return true
 | 
							return true
 | 
				
			||||||
@@ -380,16 +375,23 @@ func TestHelperReplace(t *testing.T) {
 | 
				
			|||||||
		HttpErr         error
 | 
							HttpErr         error
 | 
				
			||||||
		Overwrite       bool
 | 
							Overwrite       bool
 | 
				
			||||||
		Object          runtime.Object
 | 
							Object          runtime.Object
 | 
				
			||||||
 | 
							Namespace       string
 | 
				
			||||||
 | 
							NamespaceScoped bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ExpectPath   string
 | 
				
			||||||
		ExpectObject runtime.Object
 | 
							ExpectObject runtime.Object
 | 
				
			||||||
		Err          bool
 | 
							Err          bool
 | 
				
			||||||
		Req          func(*http.Request) bool
 | 
							Req          func(string, *http.Request) bool
 | 
				
			||||||
	}{
 | 
						}{
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 | 
								Namespace:       "bar",
 | 
				
			||||||
 | 
								NamespaceScoped: true,
 | 
				
			||||||
			HttpErr:         errors.New("failure"),
 | 
								HttpErr:         errors.New("failure"),
 | 
				
			||||||
			Err:             true,
 | 
								Err:             true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 | 
								Namespace:       "bar",
 | 
				
			||||||
 | 
								NamespaceScoped: true,
 | 
				
			||||||
			Object:          &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}},
 | 
								Object:          &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}},
 | 
				
			||||||
			Resp: &http.Response{
 | 
								Resp: &http.Response{
 | 
				
			||||||
				StatusCode: http.StatusNotFound,
 | 
									StatusCode: http.StatusNotFound,
 | 
				
			||||||
@@ -398,7 +400,10 @@ func TestHelperReplace(t *testing.T) {
 | 
				
			|||||||
			Err: true,
 | 
								Err: true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 | 
								Namespace:       "bar",
 | 
				
			||||||
 | 
								NamespaceScoped: true,
 | 
				
			||||||
			Object:          &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}},
 | 
								Object:          &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}},
 | 
				
			||||||
 | 
								ExpectPath:      "/namespaces/bar/foo",
 | 
				
			||||||
			ExpectObject:    &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}},
 | 
								ExpectObject:    &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}},
 | 
				
			||||||
			Resp: &http.Response{
 | 
								Resp: &http.Response{
 | 
				
			||||||
				StatusCode: http.StatusOK,
 | 
									StatusCode: http.StatusOK,
 | 
				
			||||||
@@ -406,11 +411,15 @@ func TestHelperReplace(t *testing.T) {
 | 
				
			|||||||
			},
 | 
								},
 | 
				
			||||||
			Req: expectPut,
 | 
								Req: expectPut,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							// namespace scoped resource
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 | 
								Namespace:       "bar",
 | 
				
			||||||
 | 
								NamespaceScoped: true,
 | 
				
			||||||
			Object: &api.Pod{
 | 
								Object: &api.Pod{
 | 
				
			||||||
				ObjectMeta: api.ObjectMeta{Name: "foo"},
 | 
									ObjectMeta: api.ObjectMeta{Name: "foo"},
 | 
				
			||||||
				Spec:       apitesting.DeepEqualSafePodSpec(),
 | 
									Spec:       apitesting.DeepEqualSafePodSpec(),
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
 | 
								ExpectPath: "/namespaces/bar/foo",
 | 
				
			||||||
			ExpectObject: &api.Pod{
 | 
								ExpectObject: &api.Pod{
 | 
				
			||||||
				ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "10"},
 | 
									ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "10"},
 | 
				
			||||||
				Spec:       apitesting.DeepEqualSafePodSpec(),
 | 
									Spec:       apitesting.DeepEqualSafePodSpec(),
 | 
				
			||||||
@@ -424,8 +433,29 @@ func TestHelperReplace(t *testing.T) {
 | 
				
			|||||||
			}),
 | 
								}),
 | 
				
			||||||
			Req: expectPut,
 | 
								Req: expectPut,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							// cluster scoped resource
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 | 
								Object: &api.Node{
 | 
				
			||||||
 | 
									ObjectMeta: api.ObjectMeta{Name: "foo"},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								ExpectObject: &api.Node{
 | 
				
			||||||
 | 
									ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "10"},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								Overwrite:  true,
 | 
				
			||||||
 | 
								ExpectPath: "/foo",
 | 
				
			||||||
 | 
								HTTPClient: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
 | 
				
			||||||
 | 
									if req.Method == "PUT" {
 | 
				
			||||||
 | 
										return &http.Response{StatusCode: http.StatusOK, Body: objBody(&unversioned.Status{Status: unversioned.StatusSuccess})}, nil
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									return &http.Response{StatusCode: http.StatusOK, Body: objBody(&api.Node{ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "10"}})}, nil
 | 
				
			||||||
 | 
								}),
 | 
				
			||||||
 | 
								Req: expectPut,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Namespace:       "bar",
 | 
				
			||||||
 | 
								NamespaceScoped: true,
 | 
				
			||||||
			Object:          &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "10"}},
 | 
								Object:          &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "10"}},
 | 
				
			||||||
 | 
								ExpectPath:      "/namespaces/bar/foo",
 | 
				
			||||||
			ExpectObject:    &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "10"}},
 | 
								ExpectObject:    &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "10"}},
 | 
				
			||||||
			Resp:            &http.Response{StatusCode: http.StatusOK, Body: objBody(&unversioned.Status{Status: unversioned.StatusSuccess})},
 | 
								Resp:            &http.Response{StatusCode: http.StatusOK, Body: objBody(&unversioned.Status{Status: unversioned.StatusSuccess})},
 | 
				
			||||||
			Req:             expectPut,
 | 
								Req:             expectPut,
 | 
				
			||||||
@@ -441,23 +471,22 @@ func TestHelperReplace(t *testing.T) {
 | 
				
			|||||||
		modifier := &Helper{
 | 
							modifier := &Helper{
 | 
				
			||||||
			RESTClient:      client,
 | 
								RESTClient:      client,
 | 
				
			||||||
			Versioner:       testapi.Default.MetadataAccessor(),
 | 
								Versioner:       testapi.Default.MetadataAccessor(),
 | 
				
			||||||
			NamespaceScoped: true,
 | 
								NamespaceScoped: test.NamespaceScoped,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		_, err := modifier.Replace("bar", "foo", test.Overwrite, test.Object)
 | 
							_, err := modifier.Replace(test.Namespace, "foo", test.Overwrite, test.Object)
 | 
				
			||||||
		if (err != nil) != test.Err {
 | 
							if (err != nil) != test.Err {
 | 
				
			||||||
			t.Errorf("%d: unexpected error: %t %v", i, test.Err, err)
 | 
								t.Errorf("%d: unexpected error: %t %v", i, test.Err, err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if test.Req != nil && !test.Req(client.Req) {
 | 
							if test.Req != nil && !test.Req(test.ExpectPath, client.Req) {
 | 
				
			||||||
			t.Errorf("%d: unexpected request: %#v", i, client.Req)
 | 
								t.Errorf("%d: unexpected request: %#v", i, client.Req)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		body, err := ioutil.ReadAll(client.Req.Body)
 | 
							body, err := ioutil.ReadAll(client.Req.Body)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			t.Fatalf("%d: unexpected error: %#v", i, err)
 | 
								t.Fatalf("%d: unexpected error: %#v", i, err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		t.Logf("got body: %s", string(body))
 | 
					 | 
				
			||||||
		expect := []byte{}
 | 
							expect := []byte{}
 | 
				
			||||||
		if test.ExpectObject != nil {
 | 
							if test.ExpectObject != nil {
 | 
				
			||||||
			expect = []byte(runtime.EncodeOrDie(testapi.Default.Codec(), test.ExpectObject))
 | 
								expect = []byte(runtime.EncodeOrDie(testapi.Default.Codec(), test.ExpectObject))
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user