func()

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)
	})
}