Use name from server when displaying create/update
Allows generated names from files to be displayed so users can interact with them.
This commit is contained in:
parent
bb6b332a8b
commit
52c6c60b15
@ -232,7 +232,7 @@ Examples:
|
||||
|
||||
$ cat pod.json | kubectl update -f -
|
||||
<update a pod based on the json passed into stdin>
|
||||
|
||||
|
||||
$ kubectl update pods my-pod --patch='{ "apiVersion": "v1beta1", "desiredState": { "manifest": [{ "cpu": 100 }]}}'
|
||||
<update a pod by downloading it, applying the patch, then updating, requires apiVersion be specified>
|
||||
|
||||
|
@ -67,11 +67,12 @@ Examples:
|
||||
if err := schema.ValidateBytes(data); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := resource.NewHelper(info.Client, info.Mapping).Create(info.Namespace, true, data); err != nil {
|
||||
obj, err := resource.NewHelper(info.Client, info.Mapping).Create(info.Namespace, true, data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
count++
|
||||
// TODO: if generation of names added to server side, change this to use the server's name
|
||||
info.Refresh(obj, true)
|
||||
fmt.Fprintf(out, "%s\n", info.Name)
|
||||
return nil
|
||||
})
|
||||
|
@ -26,6 +26,7 @@ import (
|
||||
|
||||
func TestCreateObject(t *testing.T) {
|
||||
pods, _ := testData()
|
||||
pods.Items[0].Name = "redis-master"
|
||||
|
||||
f, tf, codec := NewAPIFactory()
|
||||
tf.Printer = &testPrinter{}
|
||||
@ -81,13 +82,15 @@ func TestCreateMultipleObject(t *testing.T) {
|
||||
cmd.Flags().Set("filename", "../../../examples/guestbook/frontend-service.json")
|
||||
cmd.Run(cmd, []string{})
|
||||
|
||||
if buf.String() != "redis-master\nfrontend\n" {
|
||||
// Names should come from the REST response, NOT the files
|
||||
if buf.String() != "foo\nbaz\n" {
|
||||
t.Errorf("unexpected output: %s", buf.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateDirectory(t *testing.T) {
|
||||
pods, svc := testData()
|
||||
pods.Items[0].Name = "redis-master"
|
||||
|
||||
f, tf, codec := NewAPIFactory()
|
||||
tf.Printer = &testPrinter{}
|
||||
@ -114,7 +117,7 @@ func TestCreateDirectory(t *testing.T) {
|
||||
cmd.Flags().Set("filename", "../../../examples/guestbook")
|
||||
cmd.Run(cmd, []string{})
|
||||
|
||||
if buf.String() != "frontend-controller\nfrontend\nredis-master\nredis-master\nredis-slave-controller\nredisslave\n" {
|
||||
if buf.String() != "baz\nbaz\nbaz\nredis-master\nbaz\nbaz\n" {
|
||||
t.Errorf("unexpected output: %s", buf.String())
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ Examples:
|
||||
|
||||
$ cat pod.json | kubectl update -f -
|
||||
<update a pod based on the json passed into stdin>
|
||||
|
||||
|
||||
$ kubectl update pods my-pod --patch='{ "apiVersion": "v1beta1", "desiredState": { "manifest": [{ "cpu": 100 }]}}'
|
||||
<update a pod by downloading it, applying the patch, then updating, requires apiVersion be specified>`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
@ -67,29 +67,32 @@ Examples:
|
||||
if len(flags.Filenames) != 0 && len(patch) != 0 {
|
||||
usageError(cmd, "Can not specify both --filename and --patch")
|
||||
}
|
||||
if len(flags.Filenames) > 0 {
|
||||
err := r.Visit(func(info *resource.Info) error {
|
||||
data, err := info.Mapping.Codec.Encode(info.Object)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := schema.ValidateBytes(data); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := resource.NewHelper(info.Client, info.Mapping).
|
||||
Update(info.Namespace, info.Name, true, data); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintf(out, "%s\n", info.Name)
|
||||
return nil
|
||||
})
|
||||
checkErr(err)
|
||||
} else {
|
||||
// TODO: Make patching work with -f, updating with patched JSON input files
|
||||
|
||||
// TODO: Make patching work with -f, updating with patched JSON input files
|
||||
if len(flags.Filenames) == 0 {
|
||||
name := updateWithPatch(cmd, args, f, patch)
|
||||
fmt.Fprintf(out, "%s\n", name)
|
||||
return
|
||||
}
|
||||
|
||||
err = r.Visit(func(info *resource.Info) error {
|
||||
data, err := info.Mapping.Codec.Encode(info.Object)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := schema.ValidateBytes(data); err != nil {
|
||||
return err
|
||||
}
|
||||
obj, err := resource.NewHelper(info.Client, info.Mapping).Update(info.Namespace, info.Name, true, data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
info.Refresh(obj, true)
|
||||
fmt.Fprintf(out, "%s\n", info.Name)
|
||||
return nil
|
||||
})
|
||||
checkErr(err)
|
||||
|
||||
},
|
||||
}
|
||||
cmd.Flags().VarP(&flags.Filenames, "filename", "f", "Filename, directory, or URL to file to use to update the resource")
|
||||
@ -115,7 +118,7 @@ func updateWithPatch(cmd *cobra.Command, args []string, f *Factory, patch string
|
||||
data, err := helper.Codec.Encode(obj)
|
||||
checkErr(err)
|
||||
|
||||
err = helper.Update(namespace, name, true, data)
|
||||
obj, err = helper.Update(namespace, name, true, data)
|
||||
checkErr(err)
|
||||
return name
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ func TestUpdateObject(t *testing.T) {
|
||||
cmd.Run(cmd, []string{})
|
||||
|
||||
// uses the name from the file, not the response
|
||||
if buf.String() != "redis-master\n" {
|
||||
if buf.String() != "foo\n" {
|
||||
t.Errorf("unexpected output: %s", buf.String())
|
||||
}
|
||||
}
|
||||
@ -104,7 +104,7 @@ func TestUpdateMultipleObject(t *testing.T) {
|
||||
cmd.Flags().Set("filename", "../../../examples/guestbook/frontend-service.json")
|
||||
cmd.Run(cmd, []string{})
|
||||
|
||||
if buf.String() != "redis-master\nfrontend\n" {
|
||||
if buf.String() != "foo\nbaz\n" {
|
||||
t.Errorf("unexpected output: %s", buf.String())
|
||||
}
|
||||
}
|
||||
@ -139,7 +139,7 @@ func TestUpdateDirectory(t *testing.T) {
|
||||
cmd.Flags().Set("namespace", "test")
|
||||
cmd.Run(cmd, []string{})
|
||||
|
||||
if buf.String() != "frontend-controller\nfrontend\nredis-master\nredis-master\nredis-slave-controller\nredisslave\n" {
|
||||
if buf.String() != "qux\nbaz\nbaz\nfoo\nqux\nbaz\n" {
|
||||
t.Errorf("unexpected output: %s", buf.String())
|
||||
}
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ func (m *Helper) Delete(namespace, name string) error {
|
||||
Error()
|
||||
}
|
||||
|
||||
func (m *Helper) Create(namespace string, modify bool, data []byte) error {
|
||||
func (m *Helper) Create(namespace string, modify bool, data []byte) (runtime.Object, error) {
|
||||
if modify {
|
||||
obj, err := m.Codec.Decode(data)
|
||||
if err != nil {
|
||||
@ -111,11 +111,11 @@ func (m *Helper) Create(namespace string, modify bool, data []byte) error {
|
||||
}
|
||||
if version != "" {
|
||||
if err := m.Versioner.SetResourceVersion(obj, ""); err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
newData, err := m.Codec.Encode(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
data = newData
|
||||
}
|
||||
@ -124,11 +124,11 @@ func (m *Helper) Create(namespace string, modify bool, data []byte) error {
|
||||
return createResource(m.RESTClient, m.Resource, namespace, data)
|
||||
}
|
||||
|
||||
func createResource(c RESTClient, resource, namespace string, data []byte) error {
|
||||
return c.Post().Namespace(namespace).Resource(resource).Body(data).Do().Error()
|
||||
func createResource(c RESTClient, resource, namespace string, data []byte) (runtime.Object, error) {
|
||||
return c.Post().Namespace(namespace).Resource(resource).Body(data).Do().Get()
|
||||
}
|
||||
|
||||
func (m *Helper) Update(namespace, name string, overwrite bool, data []byte) error {
|
||||
func (m *Helper) Update(namespace, name string, overwrite bool, data []byte) (runtime.Object, error) {
|
||||
c := m.RESTClient
|
||||
|
||||
obj, err := m.Codec.Decode(data)
|
||||
@ -152,14 +152,14 @@ func (m *Helper) Update(namespace, name string, overwrite bool, data []byte) err
|
||||
}
|
||||
serverVersion, err := m.Versioner.ResourceVersion(serverObj)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
if err := m.Versioner.SetResourceVersion(obj, serverVersion); err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
newData, err := m.Codec.Encode(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
data = newData
|
||||
}
|
||||
@ -167,6 +167,6 @@ func (m *Helper) Update(namespace, name string, overwrite bool, data []byte) err
|
||||
return updateResource(c, m.Resource, namespace, name, data)
|
||||
}
|
||||
|
||||
func updateResource(c RESTClient, resource, namespace, name string, data []byte) error {
|
||||
return c.Put().Namespace(namespace).Resource(resource).Name(name).Body(data).Do().Error()
|
||||
func updateResource(c RESTClient, resource, namespace, name string, data []byte) (runtime.Object, error) {
|
||||
return c.Put().Namespace(namespace).Resource(resource).Name(name).Body(data).Do().Get()
|
||||
}
|
||||
|
@ -193,7 +193,7 @@ func TestHelperCreate(t *testing.T) {
|
||||
if test.Object != nil {
|
||||
data = []byte(runtime.EncodeOrDie(testapi.Codec(), test.Object))
|
||||
}
|
||||
err := modifier.Create("bar", test.Modify, data)
|
||||
_, err := modifier.Create("bar", test.Modify, data)
|
||||
if (err != nil) != test.Err {
|
||||
t.Errorf("%d: unexpected error: %t %v", i, test.Err, err)
|
||||
}
|
||||
@ -448,7 +448,7 @@ func TestHelperUpdate(t *testing.T) {
|
||||
if test.Object != nil {
|
||||
data = []byte(runtime.EncodeOrDie(testapi.Codec(), test.Object))
|
||||
}
|
||||
err := modifier.Update("bar", "foo", test.Overwrite, data)
|
||||
_, err := modifier.Update("bar", "foo", test.Overwrite, data)
|
||||
if (err != nil) != test.Err {
|
||||
t.Errorf("%d: unexpected error: %t %v", i, test.Err, err)
|
||||
}
|
||||
|
@ -87,6 +87,7 @@ func (i *Info) Visit(fn VisitorFunc) error {
|
||||
return fn(i)
|
||||
}
|
||||
|
||||
// Get retrieves the object from the Namespace and Name fields
|
||||
func (i *Info) Get() error {
|
||||
obj, err := NewHelper(i.Client, i.Mapping).Get(i.Namespace, i.Name)
|
||||
if err != nil {
|
||||
@ -97,6 +98,38 @@ func (i *Info) Get() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Refresh updates the object with another object. If ignoreError is set
|
||||
// the Object will be updated even if name, namespace, or resourceVersion
|
||||
// attributes cannot be loaded from the object.
|
||||
func (i *Info) Refresh(obj runtime.Object, ignoreError bool) error {
|
||||
name, err := i.Mapping.MetadataAccessor.Name(obj)
|
||||
if err != nil {
|
||||
if !ignoreError {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
i.Name = name
|
||||
}
|
||||
namespace, err := i.Mapping.MetadataAccessor.Namespace(obj)
|
||||
if err != nil {
|
||||
if !ignoreError {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
i.Namespace = namespace
|
||||
}
|
||||
version, err := i.Mapping.MetadataAccessor.ResourceVersion(obj)
|
||||
if err != nil {
|
||||
if !ignoreError {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
i.ResourceVersion = version
|
||||
}
|
||||
i.Object = obj
|
||||
return nil
|
||||
}
|
||||
|
||||
// Watch returns server changes to this object after it was retrieved.
|
||||
func (i *Info) Watch(resourceVersion string) (watch.Interface, error) {
|
||||
return NewHelper(i.Client, i.Mapping).WatchSingle(i.Namespace, i.Name, resourceVersion)
|
||||
|
Loading…
Reference in New Issue
Block a user