mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-27 13:37:30 +00:00
Like update, allow CLI create to clear resourceVersion
This commit is contained in:
parent
dbf28cbe51
commit
76648ffafb
@ -47,7 +47,7 @@ Examples:
|
|||||||
client, err := f.Client(cmd, mapping)
|
client, err := f.Client(cmd, mapping)
|
||||||
checkErr(err)
|
checkErr(err)
|
||||||
|
|
||||||
err = kubectl.NewRESTHelper(client, mapping).Create(namespace, data)
|
err = kubectl.NewRESTHelper(client, mapping).Create(namespace, true, data)
|
||||||
checkErr(err)
|
checkErr(err)
|
||||||
fmt.Fprintf(out, "%s\n", name)
|
fmt.Fprintf(out, "%s\n", name)
|
||||||
},
|
},
|
||||||
|
@ -53,8 +53,37 @@ func (m *RESTHelper) Delete(namespace, name string) error {
|
|||||||
return m.RESTClient.Delete().Path(m.Resource).Namespace(namespace).Path(name).Do().Error()
|
return m.RESTClient.Delete().Path(m.Resource).Namespace(namespace).Path(name).Do().Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *RESTHelper) Create(namespace string, data []byte) error {
|
func (m *RESTHelper) Create(namespace string, modify bool, data []byte) error {
|
||||||
return m.RESTClient.Post().Path(m.Resource).Namespace(namespace).Body(data).Do().Error()
|
if modify {
|
||||||
|
obj, err := m.Codec.Decode(data)
|
||||||
|
if err != nil {
|
||||||
|
// We don't know how to check a version on this object, but create it anyway
|
||||||
|
return createResource(m.RESTClient, m.Resource, namespace, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempt to version the object based on client logic.
|
||||||
|
version, err := m.Versioner.ResourceVersion(obj)
|
||||||
|
if err != nil {
|
||||||
|
// We don't know how to clear the version on this object, so send it to the server as is
|
||||||
|
return createResource(m.RESTClient, m.Resource, namespace, data)
|
||||||
|
}
|
||||||
|
if version != "" {
|
||||||
|
if err := m.Versioner.SetResourceVersion(obj, ""); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
newData, err := m.Codec.Encode(obj)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
data = newData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return createResource(m.RESTClient, m.Resource, namespace, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func createResource(c RESTClient, resourcePath, namespace string, data []byte) error {
|
||||||
|
return c.Post().Path(resourcePath).Namespace(namespace).Body(data).Do().Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *RESTHelper) Update(namespace, name string, overwrite bool, data []byte) error {
|
func (m *RESTHelper) Update(namespace, name string, overwrite bool, data []byte) error {
|
||||||
|
@ -133,13 +133,27 @@ func TestRESTHelperDelete(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestRESTHelperCreate(t *testing.T) {
|
func TestRESTHelperCreate(t *testing.T) {
|
||||||
|
expectPost := func(req *http.Request) bool {
|
||||||
|
if req.Method != "POST" {
|
||||||
|
t.Errorf("unexpected method: %#v", req)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if req.URL.Query().Get("namespace") != "bar" {
|
||||||
|
t.Errorf("url doesn't contain namespace: %#v", req)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
Resp *http.Response
|
Resp *http.Response
|
||||||
|
RespFunc httpClientFunc
|
||||||
HttpErr error
|
HttpErr error
|
||||||
|
Modify bool
|
||||||
Object runtime.Object
|
Object runtime.Object
|
||||||
|
|
||||||
|
ExpectObject runtime.Object
|
||||||
Err bool
|
Err bool
|
||||||
Data []byte
|
|
||||||
Req func(*http.Request) bool
|
Req func(*http.Request) bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
@ -159,47 +173,64 @@ func TestRESTHelperCreate(t *testing.T) {
|
|||||||
Body: objBody(&api.Status{Status: api.StatusSuccess}),
|
Body: objBody(&api.Status{Status: api.StatusSuccess}),
|
||||||
},
|
},
|
||||||
Object: &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}},
|
Object: &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}},
|
||||||
Req: func(req *http.Request) bool {
|
ExpectObject: &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}},
|
||||||
if req.Method != "POST" {
|
Req: expectPost,
|
||||||
t.Errorf("unexpected method: %#v", req)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if req.URL.Query().Get("namespace") != "bar" {
|
|
||||||
t.Errorf("url doesn't contain namespace: %#v", req)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Modify: false,
|
||||||
|
Object: &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(&api.Status{Status: api.StatusSuccess})},
|
||||||
|
Req: expectPost,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Modify: true,
|
||||||
|
Object: &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "10"}},
|
||||||
|
ExpectObject: &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}},
|
||||||
|
Resp: &http.Response{StatusCode: http.StatusOK, Body: objBody(&api.Status{Status: api.StatusSuccess})},
|
||||||
|
Req: expectPost,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, test := range tests {
|
for i, test := range tests {
|
||||||
client := &FakeRESTClient{
|
client := &FakeRESTClient{
|
||||||
Resp: test.Resp,
|
Resp: test.Resp,
|
||||||
Err: test.HttpErr,
|
Err: test.HttpErr,
|
||||||
}
|
}
|
||||||
|
if test.RespFunc != nil {
|
||||||
|
client.Client = test.RespFunc
|
||||||
|
}
|
||||||
modifier := &RESTHelper{
|
modifier := &RESTHelper{
|
||||||
RESTClient: client,
|
RESTClient: client,
|
||||||
|
Codec: testapi.Codec(),
|
||||||
|
Versioner: testapi.MetadataAccessor(),
|
||||||
}
|
}
|
||||||
data := test.Data
|
data := []byte{}
|
||||||
if test.Object != nil {
|
if test.Object != nil {
|
||||||
data = []byte(runtime.EncodeOrDie(testapi.Codec(), test.Object))
|
data = []byte(runtime.EncodeOrDie(testapi.Codec(), test.Object))
|
||||||
}
|
}
|
||||||
err := modifier.Create("bar", data)
|
err := modifier.Create("bar", test.Modify, data)
|
||||||
if (err != nil) != test.Err {
|
if (err != nil) != test.Err {
|
||||||
t.Errorf("unexpected error: %f %v", test.Err, err)
|
t.Errorf("%d: unexpected error: %f %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(client.Req) {
|
||||||
t.Errorf("unexpected request: %#v", client.Req)
|
t.Errorf("%d: unexpected request: %#v", i, client.Req)
|
||||||
}
|
}
|
||||||
if test.Data != nil {
|
body, err := ioutil.ReadAll(client.Req.Body)
|
||||||
body, _ := ioutil.ReadAll(client.Req.Body)
|
if err != nil {
|
||||||
if !reflect.DeepEqual(test.Data, body) {
|
t.Fatalf("%d: unexpected error: %#v", i, err)
|
||||||
t.Errorf("unexpected body: %s", string(body))
|
|
||||||
}
|
}
|
||||||
|
t.Logf("got body: %s", string(body))
|
||||||
|
expect := []byte{}
|
||||||
|
if test.ExpectObject != nil {
|
||||||
|
expect = []byte(runtime.EncodeOrDie(testapi.Codec(), test.ExpectObject))
|
||||||
}
|
}
|
||||||
|
if !reflect.DeepEqual(expect, body) {
|
||||||
|
t.Errorf("%d: unexpected body: %s", i, string(body))
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,6 +299,22 @@ func TestRESTHelperGet(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestRESTHelperUpdate(t *testing.T) {
|
func TestRESTHelperUpdate(t *testing.T) {
|
||||||
|
expectPut := func(req *http.Request) bool {
|
||||||
|
if req.Method != "PUT" {
|
||||||
|
t.Errorf("unexpected method: %#v", req)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if !strings.HasSuffix(req.URL.Path, "/foo") {
|
||||||
|
t.Errorf("url doesn't contain name: %#v", req)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if req.URL.Query().Get("namespace") != "bar" {
|
||||||
|
t.Errorf("url doesn't contain namespace: %#v", req)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
Resp *http.Response
|
Resp *http.Response
|
||||||
RespFunc httpClientFunc
|
RespFunc httpClientFunc
|
||||||
@ -298,21 +345,7 @@ func TestRESTHelperUpdate(t *testing.T) {
|
|||||||
StatusCode: http.StatusOK,
|
StatusCode: http.StatusOK,
|
||||||
Body: objBody(&api.Status{Status: api.StatusSuccess}),
|
Body: objBody(&api.Status{Status: api.StatusSuccess}),
|
||||||
},
|
},
|
||||||
Req: func(req *http.Request) bool {
|
Req: expectPut,
|
||||||
if req.Method != "PUT" {
|
|
||||||
t.Errorf("unexpected method: %#v", req)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if !strings.HasSuffix(req.URL.Path, "/foo") {
|
|
||||||
t.Errorf("url doesn't contain name: %#v", req)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if req.URL.Query().Get("namespace") != "bar" {
|
|
||||||
t.Errorf("url doesn't contain namespace: %#v", req)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Object: &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}},
|
Object: &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}},
|
||||||
@ -325,41 +358,13 @@ func TestRESTHelperUpdate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
return &http.Response{StatusCode: http.StatusOK, Body: objBody(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "10"}})}, nil
|
return &http.Response{StatusCode: http.StatusOK, Body: objBody(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "10"}})}, nil
|
||||||
},
|
},
|
||||||
Req: func(req *http.Request) bool {
|
Req: expectPut,
|
||||||
if req.Method != "PUT" {
|
|
||||||
t.Errorf("unexpected method: %#v", req)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if !strings.HasSuffix(req.URL.Path, "/foo") {
|
|
||||||
t.Errorf("url doesn't contain name: %#v", req)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if req.URL.Query().Get("namespace") != "bar" {
|
|
||||||
t.Errorf("url doesn't contain namespace: %#v", req)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Object: &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "10"}},
|
Object: &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "10"}},
|
||||||
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(&api.Status{Status: api.StatusSuccess})},
|
Resp: &http.Response{StatusCode: http.StatusOK, Body: objBody(&api.Status{Status: api.StatusSuccess})},
|
||||||
Req: func(req *http.Request) bool {
|
Req: expectPut,
|
||||||
if req.Method != "PUT" {
|
|
||||||
t.Errorf("unexpected method: %#v", req)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if !strings.HasSuffix(req.URL.Path, "/foo") {
|
|
||||||
t.Errorf("url doesn't contain name: %#v", req)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if req.URL.Query().Get("namespace") != "bar" {
|
|
||||||
t.Errorf("url doesn't contain namespace: %#v", req)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
|
Loading…
Reference in New Issue
Block a user