From ef3f64612edaddc4696beeecbb6f1ddeb4da3a6e Mon Sep 17 00:00:00 2001 From: jackgr Date: Thu, 10 Sep 2015 14:32:57 -0700 Subject: [PATCH] Add calls to set annotation for kubectl apply --- pkg/kubectl/apply.go | 19 +++++++++++++++++-- pkg/kubectl/cmd/apply.go | 4 ++-- pkg/kubectl/cmd/create.go | 9 +++++++++ pkg/kubectl/cmd/edit.go | 5 +++++ pkg/kubectl/cmd/expose.go | 9 ++++++++- pkg/kubectl/cmd/replace.go | 18 ++++++++++++++++++ pkg/kubectl/cmd/run.go | 15 ++++++++++++++- pkg/kubectl/cmd/util/helpers.go | 14 ++++++++++---- 8 files changed, 83 insertions(+), 10 deletions(-) diff --git a/pkg/kubectl/apply.go b/pkg/kubectl/apply.go index ea0abf2931..8b77abbd1f 100644 --- a/pkg/kubectl/apply.go +++ b/pkg/kubectl/apply.go @@ -58,8 +58,8 @@ func SetOriginalConfiguration(info *resource.Info, original []byte) error { return nil } - // Get the current annotations from the object. - annotations, err := info.Mapping.MetadataAccessor.Annotations(info.Object) + accessor := info.Mapping.MetadataAccessor + annotations, err := accessor.Annotations(info.Object) if err != nil { return err } @@ -162,3 +162,18 @@ func GetModifiedConfiguration(info *resource.Info, annotate bool) ([]byte, error return modified, nil } + +// UpdateApplyAnnotation gets the modified configuration of the object, +// without embedding it again, and then sets it on the object as the annotation. +func UpdateApplyAnnotation(info *resource.Info) error { + modified, err := GetModifiedConfiguration(info, false) + if err != nil { + return err + } + + if err := SetOriginalConfiguration(info, modified); err != nil { + return err + } + + return nil +} diff --git a/pkg/kubectl/cmd/apply.go b/pkg/kubectl/cmd/apply.go index 8daf7087e7..b9da210520 100644 --- a/pkg/kubectl/cmd/apply.go +++ b/pkg/kubectl/cmd/apply.go @@ -29,8 +29,8 @@ import ( "k8s.io/kubernetes/pkg/util/strategicpatch" ) -// ApplyOptions stores cmd.Flag values for apply. As new fields are added, add them here instead of -// referencing the cmd.Flags() +// ApplyOptions stores cmd.Flag values for apply. As new fields are added, +// add them here instead of referencing the cmd.Flags() type ApplyOptions struct { Filenames []string } diff --git a/pkg/kubectl/cmd/create.go b/pkg/kubectl/cmd/create.go index 4753340886..7693dce9e6 100644 --- a/pkg/kubectl/cmd/create.go +++ b/pkg/kubectl/cmd/create.go @@ -106,14 +106,23 @@ func RunCreate(f *cmdutil.Factory, cmd *cobra.Command, out io.Writer, options *C if err != nil { return err } + + // Update the annotation used by kubectl apply + if err := kubectl.UpdateApplyAnnotation(info); err != nil { + 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) if err != nil { return cmdutil.AddSourceToErr("creating", info.Source, err) } + count++ info.Refresh(obj, true) shortOutput := cmdutil.GetFlagString(cmd, "output") == "name" diff --git a/pkg/kubectl/cmd/edit.go b/pkg/kubectl/cmd/edit.go index f056563f85..83c5ed46a9 100644 --- a/pkg/kubectl/cmd/edit.go +++ b/pkg/kubectl/cmd/edit.go @@ -210,6 +210,11 @@ func RunEdit(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []strin return preservedFile(err, file, out) } + // annotate the edited object for kubectl apply + if err := kubectl.UpdateApplyAnnotation(updates); err != nil { + return preservedFile(err, file, out) + } + visitor := resource.NewFlattenListVisitor(updates, rmap) // need to make sure the original namespace wasn't changed while editing diff --git a/pkg/kubectl/cmd/expose.go b/pkg/kubectl/cmd/expose.go index 45bce2dcb9..df98797118 100644 --- a/pkg/kubectl/cmd/expose.go +++ b/pkg/kubectl/cmd/expose.go @@ -214,10 +214,17 @@ func RunExpose(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str if cmdutil.GetFlagBool(cmd, "dry-run") { fmt.Fprintln(out, "running in dry-run mode...") } else { - data, err := info.Mapping.Codec.Encode(object) + // Serialize the configuration into an annotation. + if err := kubectl.UpdateApplyAnnotation(info); err != nil { + return err + } + + // Serialize the object with the annotation applied. + data, err := info.Mapping.Codec.Encode(info.Object) if err != nil { return err } + object, err = resource.NewHelper(info.Client, info.Mapping).Create(namespace, false, data) if err != nil { return err diff --git a/pkg/kubectl/cmd/replace.go b/pkg/kubectl/cmd/replace.go index 34a0fcc2e7..6bdf4f3993 100644 --- a/pkg/kubectl/cmd/replace.go +++ b/pkg/kubectl/cmd/replace.go @@ -127,14 +127,23 @@ func RunReplace(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []st if err != nil { return err } + + // Serialize the configuration into an annotation. + if err := kubectl.UpdateApplyAnnotation(info); err != nil { + return err + } + + // 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) if err != nil { return cmdutil.AddSourceToErr("replacing", info.Source, err) } + info.Refresh(obj, true) printObjectSpecificMessage(obj, out) cmdutil.PrintSuccess(mapper, shortOutput, out, info.Mapping.Resource, info.Name, "replaced") @@ -211,14 +220,23 @@ func forceReplace(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args [] if err != nil { return err } + + // Serialize the configuration into an annotation. + if err := kubectl.UpdateApplyAnnotation(info); err != nil { + 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) if err != nil { return err } + count++ info.Refresh(obj, true) printObjectSpecificMessage(obj, out) diff --git a/pkg/kubectl/cmd/run.go b/pkg/kubectl/cmd/run.go index 2babe5730c..a4a3b01826 100644 --- a/pkg/kubectl/cmd/run.go +++ b/pkg/kubectl/cmd/run.go @@ -184,10 +184,23 @@ func Run(f *cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *cob // TODO: extract this flag to a central location, when such a location exists. if !cmdutil.GetFlagBool(cmd, "dry-run") { - data, err := mapping.Codec.Encode(obj) + resourceMapper := &resource.Mapper{ObjectTyper: typer, RESTMapper: mapper, ClientMapper: f.ClientMapperForCommand()} + info, err := resourceMapper.InfoForObject(obj) if err != nil { return err } + + // Serialize the configuration into an annotation. + if err := kubectl.UpdateApplyAnnotation(info); err != nil { + return err + } + + // Serialize the object with the annotation applied. + data, err := mapping.Codec.Encode(info.Object) + if err != nil { + return err + } + obj, err = resource.NewHelper(client, mapping).Create(namespace, false, data) if err != nil { return err diff --git a/pkg/kubectl/cmd/util/helpers.go b/pkg/kubectl/cmd/util/helpers.go index 32a3f89b30..9e3283fa46 100644 --- a/pkg/kubectl/cmd/util/helpers.go +++ b/pkg/kubectl/cmd/util/helpers.go @@ -34,6 +34,7 @@ import ( "k8s.io/kubernetes/pkg/api/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" + "k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl/resource" "k8s.io/kubernetes/pkg/runtime" utilerrors "k8s.io/kubernetes/pkg/util/errors" @@ -404,18 +405,23 @@ func DumpReaderToFile(reader io.Reader, filename string) error { func UpdateObject(info *resource.Info, updateFn func(runtime.Object) error) (runtime.Object, error) { helper := resource.NewHelper(info.Client, info.Mapping) - err := updateFn(info.Object) - if err != nil { + if err := updateFn(info.Object); err != nil { return nil, err } + + // Update the annotation used by kubectl apply + if err := kubectl.UpdateApplyAnnotation(info); err != nil { + return nil, err + } + data, err := helper.Codec.Encode(info.Object) if err != nil { return nil, err } - _, err = helper.Replace(info.Namespace, info.Name, true, data) - if err != nil { + if _, err := helper.Replace(info.Namespace, info.Name, true, data); err != nil { return nil, err } + return info.Object, nil }