// RunAnnotate does the work func (o AnnotateOptions) RunAnnotate() error { r := o.builder.Do() if err := r.Err(); err != nil { return err } return r.Visit(func(info *resource.Info, err error) error { if err != nil { return err } name, namespace, obj := info.Name, info.Namespace, info.Object oldData, err := json.Marshal(obj) if err != nil { return err } // If we should record change-cause, add it to new annotations if cmdutil.ContainsChangeCause(info) || o.recordChangeCause { o.newAnnotations[kubectl.ChangeCauseAnnotation] = o.changeCause } if err := o.updateAnnotations(obj); err != nil { return err } newData, err := json.Marshal(obj) if err != nil { return err } patchBytes, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, obj) createdPatch := err == nil if err != nil { glog.V(2).Infof("couldn't compute patch: %v", err) } mapping := info.ResourceMapping() client, err := o.f.ClientForMapping(mapping) if err != nil { return err } helper := resource.NewHelper(client, mapping) var outputObj runtime.Object if createdPatch { outputObj, err = helper.Patch(namespace, name, api.StrategicMergePatchType, patchBytes) } else { outputObj, err = helper.Replace(namespace, name, false, obj) } if err != nil { return err } outputFormat := cmdutil.GetFlagString(o.cmd, "output") if outputFormat != "" { return o.f.PrintObject(o.cmd, outputObj, o.out) } mapper, _ := o.f.Object() cmdutil.PrintSuccess(mapper, false, o.out, info.Mapping.Resource, info.Name, "annotated") return nil }) }
func (o *ResourcesOptions) Run() error { allErrs := []error{} patches := CalculatePatches(o.Infos, o.Encoder, func(info *resource.Info) (bool, error) { transformed := false _, err := o.UpdatePodSpecForObject(info.Object, func(spec *api.PodSpec) error { containers, _ := selectContainers(spec.Containers, o.ContainerSelector) if len(containers) != 0 { for i := range containers { containers[i].Resources = o.ResourceRequirements transformed = true } } else { allErrs = append(allErrs, fmt.Errorf("error: unable to find container named %s", o.ContainerSelector)) } return nil }) return transformed, err }) for _, patch := range patches { info := patch.Info if patch.Err != nil { allErrs = append(allErrs, fmt.Errorf("error: %s/%s %v\n", info.Mapping.Resource, info.Name, patch.Err)) continue } //no changes if string(patch.Patch) == "{}" || len(patch.Patch) == 0 { allErrs = append(allErrs, fmt.Errorf("info: %s %q was not changed\n", info.Mapping.Resource, info.Name)) continue } if cmdutil.GetDryRunFlag(o.Cmd) { fmt.Fprintln(o.Err, "info: running in local mode...") return o.PrintObject(o.Cmd, o.Mapper, info.Object, o.Out) } obj, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, api.StrategicMergePatchType, patch.Patch) if err != nil { allErrs = append(allErrs, fmt.Errorf("failed to patch limit update to pod template %v\n", err)) continue } info.Refresh(obj, true) //record this change (for rollout history) if o.Record || cmdutil.ContainsChangeCause(info) { if err := cmdutil.RecordChangeCause(obj, o.ChangeCause); err == nil { if obj, err = resource.NewHelper(info.Client, info.Mapping).Replace(info.Namespace, info.Name, false, obj); err != nil { allErrs = append(allErrs, fmt.Errorf("changes to %s/%s can't be recorded: %v\n", info.Mapping.Resource, info.Name, err)) } } } info.Refresh(obj, true) cmdutil.PrintSuccess(o.Mapper, o.ShortOutput, o.Out, info.Mapping.Resource, info.Name, false, "resource requirements updated") } return utilerrors.NewAggregate(allErrs) }
// RunSelector executes the command. func (o *SelectorOptions) RunSelector() error { if !o.local { o.builder = o.builder.ResourceTypeOrNameArgs(o.all, o.resources...). Latest() } r := o.builder.Do() err := r.Err() if err != nil { return err } return r.Visit(func(info *resource.Info, err error) error { patch := &Patch{Info: info} CalculatePatch(patch, o.encoder, func(info *resource.Info) ([]byte, error) { selectErr := updateSelectorForObject(info.Object, *o.selector) if selectErr == nil { return runtime.Encode(o.encoder, info.Object) } return nil, selectErr }) if patch.Err != nil { return patch.Err } if o.local || o.dryrun { fmt.Fprintln(o.out, "running in local/dry-run mode...") o.PrintObject(info.Object) return nil } patched, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, api.StrategicMergePatchType, patch.Patch) if err != nil { return err } if o.record || cmdutil.ContainsChangeCause(info) { if err := cmdutil.RecordChangeCause(patched, o.changeCause); err == nil { if patched, err = resource.NewHelper(info.Client, info.Mapping).Replace(info.Namespace, info.Name, false, patched); err != nil { return fmt.Errorf("changes to %s/%s can't be recorded: %v\n", info.Mapping.Resource, info.Name, err) } } } info.Refresh(patched, true) cmdutil.PrintSuccess(o.mapper, false, o.out, info.Mapping.Resource, info.Name, o.dryrun, "selector updated") return nil }) }
func (o *ImageOptions) Run() error { allErrs := []error{} patches := CalculatePatches(o.Infos, o.Encoder, func(info *resource.Info) (bool, error) { transformed := false _, err := o.UpdatePodSpecForObject(info.Object, func(spec *api.PodSpec) error { for name, image := range o.ContainerImages { containerFound := false // Find the container to update, and update its image for i, c := range spec.Containers { if c.Name == name || name == "*" { spec.Containers[i].Image = image containerFound = true // Perform updates transformed = true } } // Add a new container if not found if !containerFound { allErrs = append(allErrs, fmt.Errorf("error: unable to find container named %q", name)) } } return nil }) return transformed, err }) for _, patch := range patches { info := patch.Info if patch.Err != nil { allErrs = append(allErrs, fmt.Errorf("error: %s/%s %v\n", info.Mapping.Resource, info.Name, patch.Err)) continue } // no changes if string(patch.Patch) == "{}" || len(patch.Patch) == 0 { continue } if o.Local { fmt.Fprintln(o.Out, "running in local mode...") return o.PrintObject(o.Cmd, o.Mapper, info.Object, o.Out) } // patch the change obj, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, api.StrategicMergePatchType, patch.Patch) if err != nil { allErrs = append(allErrs, fmt.Errorf("failed to patch image update to pod template: %v\n", err)) continue } info.Refresh(obj, true) // record this change (for rollout history) if o.Record || cmdutil.ContainsChangeCause(info) { if patch, err := cmdutil.ChangeResourcePatch(info, o.ChangeCause); err == nil { if obj, err = resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, api.StrategicMergePatchType, patch); err != nil { fmt.Fprintf(o.Err, "WARNING: changes to %s/%s can't be recorded: %v\n", info.Mapping.Resource, info.Name, err) } } } info.Refresh(obj, true) cmdutil.PrintSuccess(o.Mapper, o.ShortOutput, o.Out, info.Mapping.Resource, info.Name, false, "image updated") } return utilerrors.NewAggregate(allErrs) }
func (o *ImageOptions) Run() error { allErrs := []error{} patches := CalculatePatches(o.Infos, o.Encoder, func(info *resource.Info) ([]byte, error) { transformed := false _, err := o.UpdatePodSpecForObject(info.Object, func(spec *api.PodSpec) error { for name, image := range o.ContainerImages { var ( containerFound bool err error resolved string ) // Find the container to update, and update its image for i, c := range spec.Containers { if c.Name == name || name == "*" { containerFound = true if len(resolved) == 0 { if resolved, err = o.ResolveImage(image); err != nil { allErrs = append(allErrs, fmt.Errorf("error: unable to resolve image %q for container %q: %v", image, name, err)) // Do not loop again if the image resolving failed for wildcard case as we // will report the same error again for the next container. if name == "*" { break } continue } } spec.Containers[i].Image = resolved // Perform updates transformed = true } } // Add a new container if not found if !containerFound { allErrs = append(allErrs, fmt.Errorf("error: unable to find container named %q", name)) } } return nil }) if transformed && err == nil { return runtime.Encode(o.Encoder, info.Object) } return nil, err }) for _, patch := range patches { info := patch.Info if patch.Err != nil { allErrs = append(allErrs, fmt.Errorf("error: %s/%s %v\n", info.Mapping.Resource, info.Name, patch.Err)) continue } // no changes if string(patch.Patch) == "{}" || len(patch.Patch) == 0 { continue } if o.PrintObject != nil && (o.Local || o.DryRun) { return o.PrintObject(o.Cmd, o.Mapper, info.Object, o.Out) } // patch the change obj, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, types.StrategicMergePatchType, patch.Patch) if err != nil { allErrs = append(allErrs, fmt.Errorf("failed to patch image update to pod template: %v\n", err)) continue } info.Refresh(obj, true) // record this change (for rollout history) if o.Record || cmdutil.ContainsChangeCause(info) { if patch, err := cmdutil.ChangeResourcePatch(info, o.ChangeCause); err == nil { if obj, err = resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, types.StrategicMergePatchType, patch); err != nil { fmt.Fprintf(o.Err, "WARNING: changes to %s/%s can't be recorded: %v\n", info.Mapping.Resource, info.Name, err) } } } info.Refresh(obj, true) if len(o.Output) > 0 { return o.PrintObject(o.Cmd, o.Mapper, obj, o.Out) } cmdutil.PrintSuccess(o.Mapper, o.ShortOutput, o.Out, info.Mapping.Resource, info.Name, o.DryRun, "image updated") } return utilerrors.NewAggregate(allErrs) }
// RunAnnotate does the work func (o AnnotateOptions) RunAnnotate(f cmdutil.Factory, cmd *cobra.Command) error { namespace, enforceNamespace, err := f.DefaultNamespace() if err != nil { return err } changeCause := f.Command() mapper, typer := f.Object() b := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). ContinueOnError(). NamespaceParam(namespace).DefaultNamespace(). FilenameParam(enforceNamespace, &o.FilenameOptions). Flatten() if !o.local { b = b.SelectorParam(o.selector). ResourceTypeOrNameArgs(o.all, o.resources...). Latest() } r := b.Do() if err := r.Err(); err != nil { return err } var singularResource bool r.IntoSingular(&singularResource) // only apply resource version locking on a single resource. // we must perform this check after o.builder.Do() as // []o.resources can not not accurately return the proper number // of resources when they are not passed in "resource/name" format. if !singularResource && 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, err := cmdutil.MaybeConvertObject(info.Object, info.Mapping.GroupVersionKind.GroupVersion(), info.Mapping) if err != nil { return err } if o.dryrun || o.local { if err := o.updateAnnotations(obj); err != nil { return err } outputObj = obj } else { name, namespace := info.Name, info.Namespace oldData, err := json.Marshal(obj) if err != nil { return err } // If we should record change-cause, add it to new annotations if cmdutil.ContainsChangeCause(info) || o.recordChangeCause { o.newAnnotations[kubectl.ChangeCauseAnnotation] = changeCause } if err := o.updateAnnotations(obj); err != nil { return err } newData, err := json.Marshal(obj) if err != nil { return err } patchBytes, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, obj) createdPatch := err == nil if err != nil { glog.V(2).Infof("couldn't compute patch: %v", err) } mapping := info.ResourceMapping() client, err := f.ClientForMapping(mapping) if err != nil { return err } helper := resource.NewHelper(client, mapping) if createdPatch { outputObj, err = helper.Patch(namespace, name, api.StrategicMergePatchType, patchBytes) } else { outputObj, err = helper.Replace(namespace, name, false, obj) } if err != nil { return err } } if o.outputFormat != "" { return f.PrintObject(cmd, mapper, outputObj, o.out) } cmdutil.PrintSuccess(mapper, false, o.out, info.Mapping.Resource, info.Name, o.dryrun, "annotated") return nil }) }
// RunAnnotate does the work func (o AnnotateOptions) RunAnnotate() error { r := o.builder.Do() if err := r.Err(); err != nil { return err } var singularResource bool r.IntoSingular(&singularResource) // only apply resource version locking on a single resource. // we must perform this check after o.builder.Do() as // []o.resources can not not accurately return the proper number // of resources when they are not passed in "resource/name" format. if !singularResource && 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 } obj, err := cmdutil.MaybeConvertObject(info.Object, info.Mapping.GroupVersionKind.GroupVersion(), info.Mapping) if err != nil { return err } name, namespace := info.Name, info.Namespace oldData, err := json.Marshal(obj) if err != nil { return err } // If we should record change-cause, add it to new annotations if cmdutil.ContainsChangeCause(info) || o.recordChangeCause { o.newAnnotations[kubectl.ChangeCauseAnnotation] = o.changeCause } if err := o.updateAnnotations(obj); err != nil { return err } newData, err := json.Marshal(obj) if err != nil { return err } patchBytes, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, obj) createdPatch := err == nil if err != nil { glog.V(2).Infof("couldn't compute patch: %v", err) } mapping := info.ResourceMapping() client, err := o.f.ClientForMapping(mapping) if err != nil { return err } helper := resource.NewHelper(client, mapping) var outputObj runtime.Object if createdPatch { outputObj, err = helper.Patch(namespace, name, api.StrategicMergePatchType, patchBytes) } else { outputObj, err = helper.Replace(namespace, name, false, obj) } if err != nil { return err } mapper, _ := o.f.Object() outputFormat := cmdutil.GetFlagString(o.cmd, "output") if outputFormat != "" { return o.f.PrintObject(o.cmd, mapper, outputObj, o.out) } cmdutil.PrintSuccess(mapper, false, o.out, info.Mapping.Resource, info.Name, false, "annotated") return nil }) }