func runDelete(namespace, name string, mapping *meta.RESTMapping, c resource.RESTClient, helper *resource.Helper, cascade bool, gracePeriod int, clientsetFunc func() (*internalclientset.Clientset, error)) error { if !cascade { if helper == nil { helper = resource.NewHelper(c, mapping) } return helper.Delete(namespace, name) } cs, err := clientsetFunc() if err != nil { return err } r, err := kubectl.ReaperFor(mapping.GroupVersionKind.GroupKind(), cs) if err != nil { if _, ok := err.(*kubectl.NoSuchReaperError); !ok { return err } return resource.NewHelper(c, mapping).Delete(namespace, name) } var options *api.DeleteOptions if gracePeriod >= 0 { options = api.NewDeleteOptions(int64(gracePeriod)) } if err := r.Stop(namespace, name, 2*time.Minute, options); err != nil { return err } 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 ResumeConfig) RunResume() error { allErrs := []error{} // Defaulting to SMPatchVersion_1_5 is safe, since Resumer only update a boolean variable for _, patch := range set.CalculatePatches(o.f, o.Infos, o.Encoder, strategicpatch.SMPatchVersion_1_5, o.Resumer) { info := patch.Info if patch.Err != nil { allErrs = append(allErrs, fmt.Errorf("error: %s %q %v", info.Mapping.Resource, info.Name, patch.Err)) continue } if string(patch.Patch) == "{}" || len(patch.Patch) == 0 { cmdutil.PrintSuccess(o.Mapper, false, o.Out, info.Mapping.Resource, info.Name, false, "already resumed") continue } 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: %v", err)) continue } info.Refresh(obj, true) cmdutil.PrintSuccess(o.Mapper, false, o.Out, info.Mapping.Resource, info.Name, false, "resumed") } return utilerrors.NewAggregate(allErrs) }
// popCluster fetches the cluster object with the given name, deletes // it and returns the deleted cluster object. func popCluster(f cmdutil.Factory, name string) (*federationapi.Cluster, error) { // Boilerplate to create the secret in the host cluster. mapper, typer := f.Object() gvks, _, err := typer.ObjectKinds(&federationapi.Cluster{}) if err != nil { return nil, err } gvk := gvks[0] mapping, err := mapper.RESTMapping(schema.GroupKind{Group: gvk.Group, Kind: gvk.Kind}, gvk.Version) if err != nil { return nil, err } client, err := f.ClientForMapping(mapping) if err != nil { return nil, err } rh := resource.NewHelper(client, mapping) obj, err := rh.Get("", name, false) if isNotFound(err) { // Cluster isn't registered, there isn't anything to be done here. return nil, nil } else if err != nil { return nil, err } cluster, ok := obj.(*federationapi.Cluster) if !ok { return nil, fmt.Errorf("unexpected object type: expected \"federation/v1beta1.Cluster\", got %T: obj: %#v", obj, obj) } // Remove the cluster resource in the federation API server by // calling rh.Delete() return cluster, rh.Delete("", name) }
// Create attempts to create each item generically, gathering all errors in the // event a failure occurs. The contents of list will be updated to include the // version from the server. func (b *Bulk) Create(list *kapi.List, namespace string) []error { resourceMapper := &resource.Mapper{b.Typer, b.Mapper, resource.ClientMapperFunc(b.RESTClientFactory)} after := b.After if after == nil { after = func(*resource.Info, error) {} } errs := []error{} for i, item := range list.Items { info, err := resourceMapper.InfoForObject(item) if err != nil { errs = append(errs, err) after(info, err) continue } data, err := info.Mapping.Codec.Encode(item) if err != nil { errs = append(errs, err) after(info, err) continue } obj, err := resource.NewHelper(info.Client, info.Mapping).Create(namespace, false, data) if err != nil { errs = append(errs, err) after(info, err) continue } info.Refresh(obj, true) list.Items[i] = obj after(info, nil) } return errs }
// applyPatch reads the latest version of the object, writes it to version, then attempts to merge // the changes onto it without conflict. If a conflict occurs jsonmerge.IsConflicting(err) is // true. The info object is mutated func applyPatch(delta *jsonmerge.Delta, info *resource.Info, version string) error { if err := info.Get(); err != nil { return patchError{err} } obj, err := resource.AsVersionedObject([]*resource.Info{info}, false, version) if err != nil { return patchError{err} } data, err := info.Mapping.Codec.Encode(obj) if err != nil { return patchError{err} } merged, err := delta.Apply(data) if err != nil { return patchError{err} } mergedObj, err := info.Mapping.Codec.Decode(merged) if err != nil { return patchError{err} } updated, err := resource.NewHelper(info.Client, info.Mapping).Replace(info.Namespace, info.Name, false, mergedObj) if err != nil { return err } info.Refresh(updated, true) return nil }
func (o *DeploymentHookOptions) Run() error { infos := o.Infos singular := len(o.Infos) <= 1 if o.Builder != nil { loaded, err := o.Builder.Do().IntoSingular(&singular).Infos() if err != nil { return err } infos = loaded } patches := CalculatePatches(infos, o.Encoder, func(info *resource.Info) (bool, error) { dc, ok := info.Object.(*deployapi.DeploymentConfig) if !ok { return false, nil } updated, err := o.updateDeploymentConfig(dc) return updated, err }) if singular && len(patches) == 0 { return fmt.Errorf("%s/%s is not a deployment config or does not have an applicable strategy", infos[0].Mapping.Resource, infos[0].Name) } if o.PrintObject != nil { object, err := resource.AsVersionedObject(infos, !singular, o.OutputVersion, kapi.Codecs.LegacyCodec(o.OutputVersion)) if err != nil { return err } return o.PrintObject(object) } failed := false for _, patch := range patches { info := patch.Info if patch.Err != nil { fmt.Fprintf(o.Err, "error: %s/%s %v\n", info.Mapping.Resource, info.Name, patch.Err) continue } if string(patch.Patch) == "{}" || len(patch.Patch) == 0 { fmt.Fprintf(o.Err, "info: %s %q was not changed\n", info.Mapping.Resource, info.Name) continue } obj, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, kapi.StrategicMergePatchType, patch.Patch) if err != nil { fmt.Fprintf(o.Err, "error: %v\n", err) failed = true continue } info.Refresh(obj, true) kcmdutil.PrintSuccess(o.Mapper, o.ShortOutput, o.Out, info.Mapping.Resource, info.Name, "updated") } if failed { return cmdutil.ErrExit } return nil }
// RunCordonOrUncordon runs either Cordon or Uncordon. The desired value for // "Unschedulable" is passed as the first arg. func (o *DrainOptions) RunCordonOrUncordon(desired bool) error { cmdNamespace, _, err := o.factory.DefaultNamespace() if err != nil { return err } if o.nodeInfo.Mapping.GroupVersionKind.Kind == "Node" { unsched := reflect.ValueOf(o.nodeInfo.Object).Elem().FieldByName("Spec").FieldByName("Unschedulable") if unsched.Bool() == desired { cmdutil.PrintSuccess(o.mapper, false, o.out, o.nodeInfo.Mapping.Resource, o.nodeInfo.Name, already(desired)) } else { helper := resource.NewHelper(o.client, o.nodeInfo.Mapping) unsched.SetBool(desired) _, err := helper.Replace(cmdNamespace, o.nodeInfo.Name, true, o.nodeInfo.Object) if err != nil { return err } cmdutil.PrintSuccess(o.mapper, false, o.out, o.nodeInfo.Mapping.Resource, o.nodeInfo.Name, changed(desired)) } } else { cmdutil.PrintSuccess(o.mapper, false, o.out, o.nodeInfo.Mapping.Resource, o.nodeInfo.Name, "skipped") } return nil }
func (o PauseConfig) RunPause() error { allErrs := []error{} for _, patch := range set.CalculatePatches(o.Infos, o.Encoder, o.Pauser) { info := patch.Info if patch.Err != nil { allErrs = append(allErrs, fmt.Errorf("error: %s %q %v", info.Mapping.Resource, info.Name, patch.Err)) continue } if string(patch.Patch) == "{}" || len(patch.Patch) == 0 { cmdutil.PrintSuccess(o.Mapper, false, o.Out, info.Mapping.Resource, info.Name, false, "already paused") continue } 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: %v", err)) continue } info.Refresh(obj, true) cmdutil.PrintSuccess(o.Mapper, false, o.Out, info.Mapping.Resource, info.Name, false, "paused") } return utilerrors.NewAggregate(allErrs) }
func deleteResource(info *resource.Info, out io.Writer, shortOutput bool, mapper meta.RESTMapper) error { if err := resource.NewHelper(info.Client, info.Mapping).Delete(info.Namespace, info.Name); err != nil { return cmdutil.AddSourceToErr("deleting", info.Source, err) } cmdutil.PrintSuccess(mapper, shortOutput, out, info.Mapping.Resource, info.Name, "deleted") return nil }
func encodeAndCreate(info *resource.Info, namespace string, obj runtime.Object) (runtime.Object, error) { data, err := info.Mapping.Codec.Encode(obj) if err != nil { return nil, err } return resource.NewHelper(info.Client, info.Mapping).Create(namespace, false, data) }
func (o *TriggersOptions) Run() error { infos := o.Infos singleItemImplied := len(o.Infos) <= 1 if o.Builder != nil { loaded, err := o.Builder.Do().IntoSingleItemImplied(&singleItemImplied).Infos() if err != nil { return err } infos = loaded } if o.PrintTable && o.PrintObject == nil { return o.printTriggers(infos) } updateTriggerFn := func(triggers *TriggerDefinition) error { o.updateTriggers(triggers) return nil } patches := CalculatePatches(infos, o.Encoder, func(info *resource.Info) (bool, error) { return UpdateTriggersForObject(info.Object, updateTriggerFn) }) if singleItemImplied && len(patches) == 0 { return fmt.Errorf("%s/%s is not a deployment config or build config", infos[0].Mapping.Resource, infos[0].Name) } if o.PrintObject != nil { return o.PrintObject(infos) } failed := false for _, patch := range patches { info := patch.Info if patch.Err != nil { failed = true fmt.Fprintf(o.Err, "error: %s/%s %v\n", info.Mapping.Resource, info.Name, patch.Err) continue } if string(patch.Patch) == "{}" || len(patch.Patch) == 0 { fmt.Fprintf(o.Err, "info: %s %q was not changed\n", info.Mapping.Resource, info.Name) continue } glog.V(4).Infof("Calculated patch %s", patch.Patch) obj, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, kapi.StrategicMergePatchType, patch.Patch) if err != nil { handlePodUpdateError(o.Err, err, "triggered") failed = true continue } info.Refresh(obj, true) kcmdutil.PrintSuccess(o.Mapper, o.ShortOutput, o.Out, info.Mapping.Resource, info.Name, false, "updated") } if failed { return cmdutil.ErrExit } return nil }
// save invokes the API to alter an object. The reporter passed to this method is the same returned by // the migration visitor method (for this type, transformImageReferences). It should return an error // if the input type cannot be saved. It returns migrate.ErrRecalculate if migration should be re-run // on the provided object. func (o *MigrateImageReferenceOptions) save(info *resource.Info, reporter migrate.Reporter) error { switch t := info.Object.(type) { case *imageapi.ImageStream: // update status first so that a subsequent spec update won't pull incorrect values if reporter.(imageChangeInfo).status { updated, err := o.Client.ImageStreams(t.Namespace).UpdateStatus(t) if err != nil { return migrate.DefaultRetriable(info, err) } info.Refresh(updated, true) return migrate.ErrRecalculate } if reporter.(imageChangeInfo).spec { updated, err := o.Client.ImageStreams(t.Namespace).Update(t) if err != nil { return migrate.DefaultRetriable(info, err) } info.Refresh(updated, true) } return nil default: if _, err := resource.NewHelper(info.Client, info.Mapping).Replace(info.Namespace, info.Name, false, info.Object); err != nil { return migrate.DefaultRetriable(info, err) } } return nil }
// Run executes the BackendOptions or returns an error. func (o *BackendsOptions) Run() error { infos := o.Infos singular := len(o.Infos) <= 1 if o.Builder != nil { loaded, err := o.Builder.Do().IntoSingular(&singular).Infos() if err != nil { return err } infos = loaded } if o.PrintTable && o.PrintObject == nil { return o.printBackends(infos) } patches := CalculatePatches(infos, o.Encoder, func(info *resource.Info) (bool, error) { return UpdateBackendsForObject(info.Object, o.Transform.Apply) }) if singular && len(patches) == 0 { return fmt.Errorf("%s/%s is not a deployment config or build config", infos[0].Mapping.Resource, infos[0].Name) } if o.PrintObject != nil { object, err := resource.AsVersionedObject(infos, !singular, o.OutputVersion, kapi.Codecs.LegacyCodec(o.OutputVersion)) if err != nil { return err } return o.PrintObject(object) } failed := false for _, patch := range patches { info := patch.Info if patch.Err != nil { failed = true fmt.Fprintf(o.Err, "error: %s/%s %v\n", info.Mapping.Resource, info.Name, patch.Err) continue } if string(patch.Patch) == "{}" || len(patch.Patch) == 0 { fmt.Fprintf(o.Err, "info: %s %q was not changed\n", info.Mapping.Resource, info.Name) continue } glog.V(4).Infof("Calculated patch %s", patch.Patch) obj, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, kapi.StrategicMergePatchType, patch.Patch) if err != nil { handlePodUpdateError(o.Err, err, "altered") failed = true continue } info.Refresh(obj, true) kcmdutil.PrintSuccess(o.Mapper, o.ShortOutput, o.Out, info.Mapping.Resource, info.Name, false, "updated") } if failed { return cmdutil.ErrExit } return nil }
func createGeneratedObject(f *cmdutil.Factory, cmd *cobra.Command, generator kubectl.Generator, names []kubectl.GeneratorParam, params map[string]interface{}, overrides, namespace string) (runtime.Object, string, meta.RESTMapper, *meta.RESTMapping, error) { err := kubectl.ValidateParams(names, params) if err != nil { return nil, "", nil, nil, err } // TODO: Validate flag usage against selected generator. More tricky since --expose was added. obj, err := generator.Generate(params) if err != nil { return nil, "", nil, nil, err } mapper, typer := f.Object() groupVersionKind, err := typer.ObjectKind(obj) if err != nil { return nil, "", nil, nil, err } if len(overrides) > 0 { codec := runtime.NewCodec(f.JSONEncoder(), f.Decoder(true)) obj, err = cmdutil.Merge(codec, obj, overrides, groupVersionKind.Kind) if err != nil { return nil, "", nil, nil, err } } mapping, err := mapper.RESTMapping(groupVersionKind.GroupKind(), groupVersionKind.Version) if err != nil { return nil, "", nil, nil, err } client, err := f.ClientForMapping(mapping) if err != nil { return nil, "", nil, nil, err } // TODO: extract this flag to a central location, when such a location exists. if !cmdutil.GetFlagBool(cmd, "dry-run") { resourceMapper := &resource.Mapper{ ObjectTyper: typer, RESTMapper: mapper, ClientMapper: resource.ClientMapperFunc(f.ClientForMapping), Decoder: f.Decoder(true), } info, err := resourceMapper.InfoForObject(obj) if err != nil { return nil, "", nil, nil, err } if err := kubectl.CreateOrUpdateAnnotation(cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag), info, f.JSONEncoder()); err != nil { return nil, "", nil, nil, err } obj, err = resource.NewHelper(client, mapping).Create(namespace, false, info.Object) if err != nil { return nil, "", nil, nil, err } } return obj, groupVersionKind.Kind, mapper, mapping, err }
func RunReplace(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, options *ReplaceOptions) error { if len(os.Args) > 1 && os.Args[1] == "update" { printDeprecationWarning("replace", "update") } schema, err := f.Validator(cmdutil.GetFlagBool(cmd, "validate"), cmdutil.GetFlagString(cmd, "schema-cache-dir")) if err != nil { return err } cmdNamespace, enforceNamespace, err := f.DefaultNamespace() if err != nil { return err } force := cmdutil.GetFlagBool(cmd, "force") if len(options.Filenames) == 0 { return cmdutil.UsageError(cmd, "Must specify --filename to replace") } shortOutput := cmdutil.GetFlagString(cmd, "output") == "name" if force { return forceReplace(f, out, cmd, args, shortOutput, options) } mapper, typer := f.Object() r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). Schema(schema). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, options.Filenames...). Flatten(). Do() err = r.Err() if err != nil { return err } return r.Visit(func(info *resource.Info, err error) error { 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. obj, err := resource.NewHelper(info.Client, info.Mapping).Replace(info.Namespace, info.Name, true, info.Object) 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") return nil }) }
func createGeneratedObject(f *cmdutil.Factory, cmd *cobra.Command, generator kubectl.Generator, names []kubectl.GeneratorParam, params map[string]interface{}, overrides, namespace string) (runtime.Object, string, meta.RESTMapper, *meta.RESTMapping, error) { err := kubectl.ValidateParams(names, params) if err != nil { return nil, "", nil, nil, err } obj, err := generator.Generate(params) if err != nil { return nil, "", nil, nil, err } mapper, typer := f.Object() version, kind, err := typer.ObjectVersionAndKind(obj) if err != nil { return nil, "", nil, nil, err } if len(overrides) > 0 { obj, err = cmdutil.Merge(obj, overrides, kind) if err != nil { return nil, "", nil, nil, err } } mapping, err := mapper.RESTMapping(kind, version) if err != nil { return nil, "", nil, nil, err } client, err := f.RESTClient(mapping) if err != nil { return nil, "", nil, nil, err } // TODO: extract this flag to a central location, when such a location exists. if !cmdutil.GetFlagBool(cmd, "dry-run") { resourceMapper := &resource.Mapper{ObjectTyper: typer, RESTMapper: mapper, ClientMapper: f.ClientMapperForCommand()} info, err := resourceMapper.InfoForObject(obj) if err != nil { return nil, "", nil, nil, err } // Serialize the configuration into an annotation. if err := kubectl.UpdateApplyAnnotation(info); err != nil { return nil, "", nil, nil, err } // Serialize the object with the annotation applied. data, err := mapping.Codec.Encode(info.Object) if err != nil { return nil, "", nil, nil, err } obj, err = resource.NewHelper(client, mapping).Create(namespace, false, data) if err != nil { return nil, "", nil, nil, err } } return obj, kind, mapper, mapping, err }
// createAndRefresh creates an object from input info and refreshes info with that object func createAndRefresh(info *resource.Info) error { obj, err := resource.NewHelper(info.Client, info.Mapping).Create(info.Namespace, true, info.Object) if err != nil { return err } info.Refresh(obj, true) return nil }
// 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 createGeneratedObject(f *cmdutil.Factory, cmd *cobra.Command, generator kubectl.Generator, names []kubectl.GeneratorParam, params map[string]interface{}, overrides, namespace string) (runtime.Object, string, meta.RESTMapper, *meta.RESTMapping, error) { err := kubectl.ValidateParams(names, params) if err != nil { return nil, "", nil, nil, err } obj, err := generator.Generate(params) if err != nil { return nil, "", nil, nil, err } mapper, typer := f.Object() gvString, kind, err := typer.ObjectVersionAndKind(obj) if err != nil { return nil, "", nil, nil, err } gv, err := unversioned.ParseGroupVersion(gvString) if err != nil { return nil, "", nil, nil, err } gvk := gv.WithKind(kind) if len(overrides) > 0 { obj, err = cmdutil.Merge(obj, overrides, kind) if err != nil { return nil, "", nil, nil, err } } mapping, err := mapper.RESTMapping(gvk.GroupKind(), gvk.Version) if err != nil { return nil, "", nil, nil, err } client, err := f.RESTClient(mapping) if err != nil { return nil, "", nil, nil, err } // TODO: extract this flag to a central location, when such a location exists. if !cmdutil.GetFlagBool(cmd, "dry-run") { resourceMapper := &resource.Mapper{ObjectTyper: typer, RESTMapper: mapper, ClientMapper: f.ClientMapperForCommand()} info, err := resourceMapper.InfoForObject(obj) if err != nil { return nil, "", nil, nil, err } if err := kubectl.CreateOrUpdateAnnotation(cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag), info); err != nil { return nil, "", nil, nil, err } obj, err = resource.NewHelper(client, mapping).Create(namespace, false, info.Object) if err != nil { return nil, "", nil, nil, err } } return obj, kind, mapper, mapping, err }
func RunCreate(f *cmdutil.Factory, cmd *cobra.Command, out io.Writer, options *CreateOptions) error { schema, err := f.Validator(cmdutil.GetFlagBool(cmd, "validate"), cmdutil.GetFlagString(cmd, "schema-cache-dir")) if err != nil { return err } cmdNamespace, enforceNamespace, err := f.DefaultNamespace() if err != nil { return err } mapper, typer := f.Object() r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). Schema(schema). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, options.Filenames...). Flatten(). Do() err = r.Err() if err != nil { return err } count := 0 err = r.Visit(func(info *resource.Info, err error) error { 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) } obj, err := resource.NewHelper(info.Client, info.Mapping).Create(info.Namespace, true, info.Object) if err != nil { return cmdutil.AddSourceToErr("creating", info.Source, err) } count++ info.Refresh(obj, true) shortOutput := cmdutil.GetFlagString(cmd, "output") == "name" if !shortOutput { printObjectSpecificMessage(info.Object, out) } cmdutil.PrintSuccess(mapper, shortOutput, out, info.Mapping.Resource, info.Name, "created") return nil }) if err != nil { return err } if count == 0 { return fmt.Errorf("no objects passed to create") } return nil }
func RunReplace(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string) error { if len(os.Args) > 1 && os.Args[1] == "update" { printDeprecationWarning("replace", "update") } schema, err := f.Validator() if err != nil { return err } cmdNamespace, enforceNamespace, err := f.DefaultNamespace() if err != nil { return err } force := cmdutil.GetFlagBool(cmd, "force") filenames := cmdutil.GetFlagStringSlice(cmd, "filename") if len(filenames) == 0 { return cmdutil.UsageError(cmd, "Must specify --filename to replace") } shortOutput := cmdutil.GetFlagString(cmd, "output") == "name" if force { return forceReplace(f, out, cmd, args, filenames, shortOutput) } mapper, typer := f.Object() r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). Schema(schema). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, filenames...). Flatten(). Do() err = r.Err() if err != nil { return err } return r.Visit(func(info *resource.Info, err error) error { if err != nil { return err } 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") return nil }) }
func RunCreate(f *cmdutil.Factory, cmd *cobra.Command, out io.Writer) error { schema, err := f.Validator() if err != nil { return err } cmdNamespace, enforceNamespace, err := f.DefaultNamespace() if err != nil { return err } filenames := cmdutil.GetFlagStringSlice(cmd, "filename") mapper, typer := f.Object() r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). Schema(schema). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, filenames...). Flatten(). Do() err = r.Err() if err != nil { return err } count := 0 err = r.Visit(func(info *resource.Info, err error) error { if err != nil { return err } 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" if !shortOutput { printObjectSpecificMessage(info.Object, out) } cmdutil.PrintSuccess(mapper, shortOutput, out, info.Mapping.Resource, info.Name, "created") return nil }) if err != nil { return err } if count == 0 { return fmt.Errorf("no objects passed to create") } return nil }
func RunPatch(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, shortOutput bool, options *PatchOptions) error { cmdNamespace, enforceNamespace, err := f.DefaultNamespace() if err != nil { return err } cmdTenant, enforceTenant, err := f.DefaultTenant() if err != nil { return err } patch := cmdutil.GetFlagString(cmd, "patch") if len(patch) == 0 { return cmdutil.UsageError(cmd, "Must specify -p to patch") } patchBytes, err := yaml.ToJSON([]byte(patch)) if err != nil { return fmt.Errorf("unable to parse %q: %v", patch, err) } mapper, typer := f.Object() r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). TenantParam(cmdTenant).DefaultTenant(). FilenameParam(enforceTenant, enforceNamespace, options.Filenames...). ResourceTypeOrNameArgs(false, args...). Flatten(). Do() err = r.Err() if err != nil { return err } infos, err := r.Infos() if err != nil { return err } if len(infos) > 1 { return fmt.Errorf("multiple resources provided") } info := infos[0] name, namespace := info.Name, info.Namespace mapping := info.ResourceMapping() client, err := f.RESTClient(mapping) if err != nil { return err } helper := resource.NewHelper(client, mapping) _, err = helper.Patch(namespace, name, api.StrategicMergePatchType, patchBytes) if err != nil { return err } cmdutil.PrintSuccess(mapper, shortOutput, out, "", name, "patched") return nil }
func (o *BuildHookOptions) Run() error { infos := o.Infos singular := len(o.Infos) <= 1 if o.Builder != nil { loaded, err := o.Builder.Do().IntoSingular(&singular).Infos() if err != nil { return err } infos = loaded } patches := CalculatePatches(infos, o.Encoder, func(info *resource.Info) (bool, error) { bc, ok := info.Object.(*buildapi.BuildConfig) if !ok { return false, nil } o.updateBuildConfig(bc) return true, nil }) if singular && len(patches) == 0 { return fmt.Errorf("%s/%s is not a build config", infos[0].Mapping.Resource, infos[0].Name) } if o.PrintObject != nil { return o.PrintObject(infos) } failed := false for _, patch := range patches { info := patch.Info if patch.Err != nil { fmt.Fprintf(o.Err, "error: %s/%s %v\n", info.Mapping.Resource, info.Name, patch.Err) continue } if string(patch.Patch) == "{}" || len(patch.Patch) == 0 { fmt.Fprintf(o.Err, "info: %s %q was not changed\n", info.Mapping.Resource, info.Name) continue } obj, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, kapi.StrategicMergePatchType, patch.Patch) if err != nil { fmt.Fprintf(o.Err, "error: %v\n", err) failed = true continue } info.Refresh(obj, true) kcmdutil.PrintSuccess(o.Mapper, o.ShortOutput, o.Out, info.Mapping.Resource, info.Name, false, "updated") } if failed { return cmdutil.ErrExit } return nil }
func (p *pruner) delete(namespace, name string, mapping *meta.RESTMapping, c resource.RESTClient) error { if !p.cascade { return resource.NewHelper(c, mapping).Delete(namespace, name) } cs, err := p.clientsetFunc() if err != nil { return err } r, err := kubectl.ReaperFor(mapping.GroupVersionKind.GroupKind(), cs) if err != nil { if _, ok := err.(*kubectl.NoSuchReaperError); !ok { return err } return resource.NewHelper(c, mapping).Delete(namespace, name) } if err := r.Stop(namespace, name, 2*time.Minute, api.NewDeleteOptions(int64(p.gracePeriod))); err != nil { return err } return nil }
func (o *BuildSecretOptions) Run() error { infos := o.Infos singular := len(o.Infos) <= 1 if o.Builder != nil { loaded, err := o.Builder.Do().IntoSingular(&singular).Infos() if err != nil { return err } infos = loaded } patches := CalculatePatches(infos, o.Encoder, func(info *resource.Info) (bool, error) { return o.setBuildSecret(info.Object) }) if singular && len(patches) == 0 { return fmt.Errorf("cannot set a build secret on %s/%s", infos[0].Mapping.Resource, infos[0].Name) } if o.PrintObject != nil { object, err := resource.AsVersionedObject(infos, !singular, o.OutputVersion, kapi.Codecs.LegacyCodec(o.OutputVersion)) if err != nil { return err } return o.PrintObject(object) } errs := []error{} for _, patch := range patches { info := patch.Info if patch.Err != nil { errs = append(errs, fmt.Errorf("%s/%s %v", info.Mapping.Resource, info.Name, patch.Err)) continue } if string(patch.Patch) == "{}" || len(patch.Patch) == 0 { fmt.Fprintf(o.Err, "info: %s %q was not changed\n", info.Mapping.Resource, info.Name) continue } obj, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, kapi.StrategicMergePatchType, patch.Patch) if err != nil { errs = append(errs, fmt.Errorf("%s/%s %v", info.Mapping.Resource, info.Name, err)) continue } info.Refresh(obj, true) kcmdutil.PrintSuccess(o.Mapper, o.ShortOutput, o.Out, info.Mapping.Resource, info.Name, "updated") } if len(errs) > 0 { return errors.NewAggregate(errs) } return nil }
func createAndRefresh(info *resource.Info) error { obj, err := resource.NewHelper(info.Client, info.Mapping).Create(info.Namespace, true, info.Object) if err != nil { if errors.IsAlreadyExists(err) { glog.V(5).Infof("Object %s/%s already exists", info.Namespace, info.Name) return nil } return err } info.Refresh(obj, true) return nil }
func updateResource(c *Client, target *resource.Info, currentObj runtime.Object, recreate bool) error { encoder := api.Codecs.LegacyCodec(registered.EnabledVersions()...) original, err := runtime.Encode(encoder, currentObj) if err != nil { return err } modified, err := runtime.Encode(encoder, target.Object) if err != nil { return err } if api.Semantic.DeepEqual(original, modified) { return ErrAlreadyExists{target.Name} } patch, err := strategicpatch.CreateTwoWayMergePatch(original, modified, currentObj) if err != nil { return err } // send patch to server helper := resource.NewHelper(target.Client, target.Mapping) _, err = helper.Patch(target.Namespace, target.Name, api.StrategicMergePatchType, patch) if err != nil { return err } if recreate { kind := target.Mapping.GroupVersionKind.Kind client, _ := c.ClientSet() switch kind { case "ReplicationController": rc := currentObj.(*v1.ReplicationController) err = recreatePods(client, target.Namespace, rc.Spec.Selector) case "DaemonSet": daemonSet := currentObj.(*v1beta1.DaemonSet) err = recreatePods(client, target.Namespace, daemonSet.Spec.Selector.MatchLabels) case "StatefulSet": petSet := currentObj.(*apps.StatefulSet) err = recreatePods(client, target.Namespace, petSet.Spec.Selector.MatchLabels) case "ReplicaSet": replicaSet := currentObj.(*v1beta1.ReplicaSet) err = recreatePods(client, target.Namespace, replicaSet.Spec.Selector.MatchLabels) } } return err }