in pkg/cmd/label/label.go [250:396]
func (o *LabelOptions) RunLabel() 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()
}
one := false
r := b.Do().IntoSingleItemImplied(&one)
if err := r.Err(); err != nil {
return err
}
// only apply resource version locking on a single resource
if !one && len(o.resourceVersion) > 0 {
return fmt.Errorf("--resource-version may only be used with a single resource")
}
// TODO: support bulk generic output a la Get
return r.Visit(func(info *resource.Info, err error) error {
if err != nil {
return err
}
var outputObj runtime.Object
var dataChangeMsg string
obj := info.Object
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 o.dryRunStrategy == cmdutil.DryRunClient || o.local || o.list {
err = labelFunc(obj, o.overwrite, o.resourceVersion, o.newLabels, o.removeLabels)
if err != nil {
return err
}
newObj, err := json.Marshal(obj)
if err != nil {
return err
}
dataChangeMsg = updateDataChangeMsg(oldData, newObj, o.overwrite)
outputObj = info.Object
} else {
name, namespace := info.Name, info.Namespace
if err != nil {
return err
}
accessor, err := meta.Accessor(obj)
if err != nil {
return err
}
for _, label := range o.removeLabels {
if _, ok := accessor.GetLabels()[label]; !ok {
fmt.Fprintf(o.Out, "label %q not found.\n", label)
}
}
if err := labelFunc(obj, o.overwrite, o.resourceVersion, o.newLabels, o.removeLabels); err != nil {
return err
}
if err := o.Recorder.Record(obj); err != nil {
klog.V(4).Infof("error recording current command: %v", err)
}
newObj, err := json.Marshal(obj)
if err != nil {
return err
}
dataChangeMsg = updateDataChangeMsg(oldData, newObj, o.overwrite)
patchBytes, err := jsonpatch.CreateMergePatch(oldData, newObj)
createdPatch := err == nil
if err != nil {
klog.V(2).Infof("couldn't compute patch: %v", err)
}
mapping := info.ResourceMapping()
if o.dryRunStrategy == cmdutil.DryRunServer {
if err := o.dryRunVerifier.HasSupport(mapping.GroupVersionKind); err != nil {
return 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 !one {
indent = " "
gvks, _, err := unstructuredscheme.NewUnstructuredObjectTyper().ObjectKinds(info.Object)
if err != nil {
return err
}
fmt.Fprintf(o.Out, "Listing labels for %s.%s/%s:\n", gvks[0].Kind, gvks[0].Group, info.Name)
}
for k, v := range accessor.GetLabels() {
fmt.Fprintf(o.Out, "%s%s=%s\n", indent, k, v)
}
return nil
}
printer, err := o.ToPrinter(dataChangeMsg)
if err != nil {
return err
}
return printer.PrintObj(info.Object, o.Out)
})
}