Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pass runtime.Object to Helper.Create/Replace #16441

Merged
merged 1 commit into from Oct 30, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 1 addition & 6 deletions pkg/kubectl/cmd/autoscale.go
Expand Up @@ -140,12 +140,7 @@ func RunAutoscale(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []
return err
}

// Serialize the object with the annotation applied.
data, err := hpa.Mapping.Codec.Encode(object)
if err != nil {
return err
}
object, err = resource.NewHelper(hpa.Client, hpa.Mapping).Create(namespace, false, data)
object, err = resource.NewHelper(hpa.Client, hpa.Mapping).Create(namespace, false, object)
if err != nil {
return err
}
Expand Down
8 changes: 1 addition & 7 deletions pkg/kubectl/cmd/create.go
Expand Up @@ -112,13 +112,7 @@ func RunCreate(f *cmdutil.Factory, cmd *cobra.Command, out io.Writer, options *C
return cmdutil.AddSourceToErr("creating", info.Source, err)
}

// Serialize the object with the annotation applied.
data, err := info.Mapping.Codec.Encode(info.Object)
if err != nil {
return cmdutil.AddSourceToErr("creating", info.Source, err)
}

obj, err := resource.NewHelper(info.Client, info.Mapping).Create(info.Namespace, true, data)
obj, err := resource.NewHelper(info.Client, info.Mapping).Create(info.Namespace, true, info.Object)
if err != nil {
return cmdutil.AddSourceToErr("creating", info.Source, err)
}
Expand Down
6 changes: 1 addition & 5 deletions pkg/kubectl/cmd/expose.go
Expand Up @@ -207,11 +207,7 @@ func RunExpose(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str
}

// Serialize the object with the annotation applied.
data, err := info.Mapping.Codec.Encode(object)
if err != nil {
return err
}
object, err = resource.NewHelper(info.Client, info.Mapping).Create(namespace, false, data)
object, err = resource.NewHelper(info.Client, info.Mapping).Create(namespace, false, object)
if err != nil {
return err
}
Expand Down
15 changes: 2 additions & 13 deletions pkg/kubectl/cmd/replace.go
Expand Up @@ -134,12 +134,7 @@ func RunReplace(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []st
}

// Serialize the object with the annotation applied.
data, err := info.Mapping.Codec.Encode(info.Object)
if err != nil {
return cmdutil.AddSourceToErr("replacing", info.Source, err)
}

obj, err := resource.NewHelper(info.Client, info.Mapping).Replace(info.Namespace, info.Name, true, data)
obj, err := resource.NewHelper(info.Client, info.Mapping).Replace(info.Namespace, info.Name, true, info.Object)
if err != nil {
return cmdutil.AddSourceToErr("replacing", info.Source, err)
}
Expand Down Expand Up @@ -226,13 +221,7 @@ func forceReplace(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []
return err
}

// Serialize the object with the annotation applied.
data, err := info.Mapping.Codec.Encode(info.Object)
if err != nil {
return err
}

obj, err := resource.NewHelper(info.Client, info.Mapping).Create(info.Namespace, true, data)
obj, err := resource.NewHelper(info.Client, info.Mapping).Create(info.Namespace, true, info.Object)
if err != nil {
return err
}
Expand Down
8 changes: 1 addition & 7 deletions pkg/kubectl/cmd/run.go
Expand Up @@ -376,13 +376,7 @@ func createGeneratedObject(f *cmdutil.Factory, cmd *cobra.Command, generator kub
return nil, "", nil, nil, err
}

// Serialize the object with the annotation applied.
data, err := mapping.Codec.Encode(info.Object)
if err != nil {
return nil, "", nil, nil, err
}

obj, err = resource.NewHelper(client, mapping).Create(namespace, false, data)
obj, err = resource.NewHelper(client, mapping).Create(namespace, false, info.Object)
if err != nil {
return nil, "", nil, nil, err
}
Expand Down
7 changes: 1 addition & 6 deletions pkg/kubectl/cmd/util/helpers.go
Expand Up @@ -414,12 +414,7 @@ func UpdateObject(info *resource.Info, updateFn func(runtime.Object) error) (run
return nil, err
}

data, err := helper.Codec.Encode(info.Object)
if err != nil {
return nil, err
}

if _, err := helper.Replace(info.Namespace, info.Name, true, data); err != nil {
if _, err := helper.Replace(info.Namespace, info.Name, true, info.Object); err != nil {
return nil, err
}

Expand Down
44 changes: 11 additions & 33 deletions pkg/kubectl/resource/helper.go
Expand Up @@ -99,37 +99,26 @@ func (m *Helper) Delete(namespace, name string) error {
Error()
}

func (m *Helper) Create(namespace string, modify bool, data []byte) (runtime.Object, error) {
func (m *Helper) Create(namespace string, modify bool, obj runtime.Object) (runtime.Object, 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 m.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 m.createResource(m.RESTClient, m.Resource, namespace, data)
return m.createResource(m.RESTClient, m.Resource, namespace, obj)
}
if version != "" {
if err := m.Versioner.SetResourceVersion(obj, ""); err != nil {
return nil, err
}
newData, err := m.Codec.Encode(obj)
if err != nil {
return nil, err
}
data = newData
}
}

return m.createResource(m.RESTClient, m.Resource, namespace, data)
return m.createResource(m.RESTClient, m.Resource, namespace, obj)
}

func (m *Helper) createResource(c RESTClient, resource, namespace string, data []byte) (runtime.Object, error) {
return c.Post().NamespaceIfScoped(namespace, m.NamespaceScoped).Resource(resource).Body(data).Do().Get()
func (m *Helper) createResource(c RESTClient, resource, namespace string, obj runtime.Object) (runtime.Object, error) {
return c.Post().NamespaceIfScoped(namespace, m.NamespaceScoped).Resource(resource).Body(obj).Do().Get()
}
func (m *Helper) Patch(namespace, name string, pt api.PatchType, data []byte) (runtime.Object, error) {
return m.RESTClient.Patch(pt).
Expand All @@ -141,27 +130,21 @@ func (m *Helper) Patch(namespace, name string, pt api.PatchType, data []byte) (r
Get()
}

func (m *Helper) Replace(namespace, name string, overwrite bool, data []byte) (runtime.Object, error) {
func (m *Helper) Replace(namespace, name string, overwrite bool, obj runtime.Object) (runtime.Object, error) {
c := m.RESTClient

obj, err := m.Codec.Decode(data)
if err != nil {
// We don't know how to handle this object, but replace it anyway
return m.replaceResource(c, m.Resource, namespace, name, 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 version this object, so send it to the server as is
return m.replaceResource(c, m.Resource, namespace, name, data)
return m.replaceResource(c, m.Resource, namespace, name, obj)
}
if version == "" && overwrite {
// 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()
if err != nil {
// The object does not exist, but we want it to be created
return m.replaceResource(c, m.Resource, namespace, name, data)
return m.replaceResource(c, m.Resource, namespace, name, obj)
}
serverVersion, err := m.Versioner.ResourceVersion(serverObj)
if err != nil {
Expand All @@ -170,16 +153,11 @@ func (m *Helper) Replace(namespace, name string, overwrite bool, data []byte) (r
if err := m.Versioner.SetResourceVersion(obj, serverVersion); err != nil {
return nil, err
}
newData, err := m.Codec.Encode(obj)
if err != nil {
return nil, err
}
data = newData
}

return m.replaceResource(c, m.Resource, namespace, name, data)
return m.replaceResource(c, m.Resource, namespace, name, obj)
}

func (m *Helper) replaceResource(c RESTClient, resource, namespace, name string, data []byte) (runtime.Object, error) {
return c.Put().NamespaceIfScoped(namespace, m.NamespaceScoped).Resource(resource).Name(name).Body(data).Do().Get()
func (m *Helper) replaceResource(c RESTClient, resource, namespace, name string, obj runtime.Object) (runtime.Object, error) {
return c.Put().NamespaceIfScoped(namespace, m.NamespaceScoped).Resource(resource).Name(name).Body(obj).Do().Get()
}
24 changes: 11 additions & 13 deletions pkg/kubectl/resource/helper_test.go
Expand Up @@ -170,7 +170,10 @@ func TestHelperCreate(t *testing.T) {
},
{
Modify: true,
Object: &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "10"}},
Object: &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "10"},
Spec: apitesting.DeepEqualSafePodSpec(),
},
ExpectObject: &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo"},
Spec: apitesting.DeepEqualSafePodSpec(),
Expand All @@ -194,11 +197,7 @@ func TestHelperCreate(t *testing.T) {
Versioner: testapi.Default.MetadataAccessor(),
NamespaceScoped: true,
}
data := []byte{}
if test.Object != nil {
data = []byte(runtime.EncodeOrDie(testapi.Default.Codec(), test.Object))
}
_, err := modifier.Create("bar", test.Modify, data)
_, err := modifier.Create("bar", test.Modify, test.Object)
if (err != nil) != test.Err {
t.Errorf("%d: unexpected error: %t %v", i, test.Err, err)
}
Expand All @@ -218,7 +217,7 @@ func TestHelperCreate(t *testing.T) {
expect = []byte(runtime.EncodeOrDie(testapi.Default.Codec(), test.ExpectObject))
}
if !reflect.DeepEqual(expect, body) {
t.Errorf("%d: unexpected body: %s", i, string(body))
t.Errorf("%d: unexpected body: %s (expected %s)", i, string(body), string(expect))
}

}
Expand Down Expand Up @@ -413,7 +412,10 @@ func TestHelperReplace(t *testing.T) {
Req: expectPut,
},
{
Object: &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}},
Object: &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo"},
Spec: apitesting.DeepEqualSafePodSpec(),
},
ExpectObject: &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "10"},
Spec: apitesting.DeepEqualSafePodSpec(),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this illustrates the encode/decode/defaulting/encode that was happening client-side

Expand Down Expand Up @@ -449,11 +451,7 @@ func TestHelperReplace(t *testing.T) {
Versioner: testapi.Default.MetadataAccessor(),
NamespaceScoped: true,
}
data := []byte{}
if test.Object != nil {
data = []byte(runtime.EncodeOrDie(testapi.Default.Codec(), test.Object))
}
_, err := modifier.Replace("bar", "foo", test.Overwrite, data)
_, err := modifier.Replace("bar", "foo", test.Overwrite, test.Object)
if (err != nil) != test.Err {
t.Errorf("%d: unexpected error: %t %v", i, test.Err, err)
}
Expand Down