in pkg/cmd/annotate/annotate.go [252:379]
func (o AnnotateOptions) RunAnnotate() error {
b := o.builder.
Unstructured().
LocalParam(o.local).
ContinueOnError().
NamespaceParam(o.namespace).DefaultNamespace().
FilenameParam(o.enforceNamespace, &o.FilenameOptions).
Flatten()
if !o.local {
b = b.LabelSelectorParam(o.selector).
FieldSelectorParam(o.fieldSelector).
AllNamespaces(o.allNamespaces).
ResourceTypeOrNameArgs(o.all, o.resources...).
Latest()
}
r := b.Do()
if err := r.Err(); err != nil {
return err
}
var singleItemImpliedResource bool
r.IntoSingleItemImplied(&singleItemImpliedResource)
// only apply resource version locking on a single resource.
// we must perform this check after o.builder.Do() as
// []o.resources can not accurately return the proper number
// of resources when they are not passed in "resource/name" format.
if !singleItemImpliedResource && len(o.resourceVersion) > 0 {
return fmt.Errorf("--resource-version may only be used with a single resource")
}
return r.Visit(func(info *resource.Info, err error) error {
if err != nil {
return err
}
var outputObj runtime.Object
obj := info.Object
if o.dryRunStrategy == cmdutil.DryRunClient || o.local || o.list {
if err := o.updateAnnotations(obj); err != nil {
return err
}
outputObj = obj
} else {
mapping := info.ResourceMapping()
if o.dryRunStrategy == cmdutil.DryRunServer {
if err := o.dryRunVerifier.HasSupport(mapping.GroupVersionKind); err != nil {
return err
}
}
name, namespace := info.Name, info.Namespace
if len(o.resourceVersion) != 0 {
// ensure resourceVersion is always sent in the patch by clearing it from the starting JSON
accessor, err := meta.Accessor(obj)
if err != nil {
return err
}
accessor.SetResourceVersion("")
}
oldData, err := json.Marshal(obj)
if err != nil {
return err
}
if err := o.Recorder.Record(info.Object); err != nil {
klog.V(4).Infof("error recording current command: %v", err)
}
if err := o.updateAnnotations(obj); err != nil {
return err
}
newData, err := json.Marshal(obj)
if err != nil {
return err
}
patchBytes, err := jsonpatch.CreateMergePatch(oldData, newData)
createdPatch := err == nil
if err != nil {
klog.V(2).Infof("couldn't compute patch: %v", err)
}
client, err := o.unstructuredClientForMapping(mapping)
if err != nil {
return err
}
helper := resource.
NewHelper(client, mapping).
DryRun(o.dryRunStrategy == cmdutil.DryRunServer).
WithFieldManager(o.fieldManager)
if createdPatch {
outputObj, err = helper.Patch(namespace, name, types.MergePatchType, patchBytes, nil)
} else {
outputObj, err = helper.Replace(namespace, name, false, obj)
}
if err != nil {
return err
}
}
if o.list {
accessor, err := meta.Accessor(outputObj)
if err != nil {
return err
}
indent := ""
if !singleItemImpliedResource {
indent = " "
gvks, _, err := unstructuredscheme.NewUnstructuredObjectTyper().ObjectKinds(info.Object)
if err != nil {
return err
}
fmt.Fprintf(o.Out, "Listing annotations for %s.%s/%s:\n", gvks[0].Kind, gvks[0].Group, info.Name)
}
for k, v := range accessor.GetAnnotations() {
fmt.Fprintf(o.Out, "%s%s=%s\n", indent, k, v)
}
return nil
}
return o.PrintObj(outputObj, o.Out)
})
}