// PrinterForMapping returns a printer suitable for displaying the provided resource type. // Requires that printer flags have been added to cmd (see AddPrinterFlags). func (f *Factory) PrinterForMapping(cmd *cobra.Command, mapping *meta.RESTMapping, withNamespace bool) (kubectl.ResourcePrinter, error) { printer, ok, err := PrinterForCommand(cmd) if err != nil { return nil, err } if ok { clientConfig, err := f.ClientConfig() if err != nil { return nil, err } defaultVersion := clientConfig.Version version := OutputVersion(cmd, defaultVersion) if len(version) == 0 { version = mapping.APIVersion } if len(version) == 0 { return nil, fmt.Errorf("you must specify an output-version when using this output format") } printer = kubectl.NewVersionedPrinter(printer, mapping.ObjectConvertor, version, mapping.APIVersion) } else { printer, err = f.Printer(mapping, GetFlagBool(cmd, "no-headers"), withNamespace, GetWideFlag(cmd), GetFlagStringList(cmd, "label-columns")) if err != nil { return nil, err } } return printer, nil }
// PrinterForMapping returns a printer suitable for displaying the provided resource type. // Requires that printer flags have been added to cmd (see AddPrinterFlags). func PrinterForMapping(f *Factory, cmd *cobra.Command, mapping *meta.RESTMapping) (kubectl.ResourcePrinter, error) { printer, ok, err := PrinterForCommand(cmd) if err != nil { return nil, err } if ok { clientConfig, err := f.ClientConfig(cmd) checkErr(err) defaultVersion := clientConfig.Version version := outputVersion(cmd, defaultVersion) if len(version) == 0 { version = mapping.APIVersion } if len(version) == 0 { return nil, fmt.Errorf("you must specify an output-version when using this output format") } printer = kubectl.NewVersionedPrinter(printer, mapping.ObjectConvertor, version) } else { printer, err = f.Printer(cmd, mapping, GetFlagBool(cmd, "no-headers")) if err != nil { return nil, err } } return printer, nil }
// Print prints a deployment config in the specified format with the given // template. func (r *helper) Print(config *deployapi.DeploymentConfig, format, template string, out io.Writer) error { printer, _, err := kubectl.GetPrinter(format, template) if err != nil { return err } versionedPrinter := kubectl.NewVersionedPrinter(printer, kapi.Scheme, latest.Version) versionedPrinter.PrintObj(config, out) return nil }
// PrintObject prints an api object given command line flags to modify the output format func PrintObject(cmd *cobra.Command, obj runtime.Object, f *Factory, out io.Writer) { mapper, _ := f.Object(cmd) _, kind, err := api.Scheme.ObjectVersionAndKind(obj) checkErr(err) mapping, err := mapper.RESTMapping(kind) checkErr(err) printer, ok, err := PrinterForCommand(cmd) checkErr(err) if ok { version := outputVersion(cmd) if len(version) == 0 { version = mapping.APIVersion } if len(version) == 0 { checkErr(fmt.Errorf("you must specify an output-version when using this output format")) } printer = kubectl.NewVersionedPrinter(printer, mapping.ObjectConvertor, version) } printer.PrintObj(obj, out) }
func NewCmdConfigView(out io.Writer, ConfigAccess ConfigAccess) *cobra.Command { options := &ViewOptions{ConfigAccess: ConfigAccess} cmd := &cobra.Command{ Use: "view", Short: "displays Merged kubeconfig settings or a specified kubeconfig file.", Long: view_long, Example: view_example, Run: func(cmd *cobra.Command, args []string) { options.Complete() printer, _, err := cmdutil.PrinterForCommand(cmd) if err != nil { glog.FatalDepth(1, err) } version := cmdutil.OutputVersion(cmd, latest.Version) printer = kubectl.NewVersionedPrinter(printer, clientcmdapi.Scheme, version) if err := options.Run(out, printer); err != nil { glog.FatalDepth(1, err) } }, } cmdutil.AddPrinterFlags(cmd) // Default to yaml cmd.Flags().Set("output", "yaml") options.Merge.Default(true) cmd.Flags().Var(&options.Merge, "merge", "merge together the full hierarchy of kubeconfig files") cmd.Flags().BoolVar(&options.RawByteData, "raw", false, "display raw byte data") cmd.Flags().BoolVar(&options.Flatten, "flatten", false, "flatten the resulting kubeconfig file into self contained output (useful for creating portable kubeconfig files)") cmd.Flags().BoolVar(&options.Minify, "minify", false, "remove all information not used by current-context from the output") return cmd }
// Run performs a rollback. func (o *RollbackOptions) Run() error { // Get the resource referenced in the command args. obj, err := o.findResource(o.TargetName) if err != nil { return err } // Interpret the resource to resolve a target for rollback. var target *kapi.ReplicationController switch r := obj.(type) { case *kapi.ReplicationController: // A specific deployment was used. target = r case *deployapi.DeploymentConfig: // A deploymentconfig was used. Find the target deployment by the // specified version, or by a lookup of the last completed deployment if // no version was supplied. deployment, err := o.findTargetDeployment(r, o.DesiredVersion) if err != nil { return err } target = deployment } if target == nil { return fmt.Errorf("%s is not a valid deployment or deploymentconfig", o.TargetName) } // Set up the rollback and generate a new rolled back config. rollback := &deployapi.DeploymentConfigRollback{ Spec: deployapi.DeploymentConfigRollbackSpec{ From: kapi.ObjectReference{ Name: target.Name, }, IncludeTemplate: true, IncludeTriggers: o.IncludeTriggers, IncludeStrategy: o.IncludeStrategy, IncludeReplicationMeta: o.IncludeScalingSettings, }, } newConfig, err := o.oc.DeploymentConfigs(o.Namespace).Rollback(rollback) if err != nil { return err } // If this is a dry run, print and exit. if o.DryRun { describer := describe.NewDeploymentConfigDescriberForConfig(o.oc, o.kc, newConfig) description, err := describer.Describe(newConfig.Namespace, newConfig.Name) if err != nil { return err } o.out.Write([]byte(description)) return nil } // If an output format is specified, print and exit. if len(o.Format) > 0 { printer, _, err := kubectl.GetPrinter(o.Format, o.Template) if err != nil { return err } versionedPrinter := kubectl.NewVersionedPrinter(printer, kapi.Scheme, latest.Version) versionedPrinter.PrintObj(newConfig, o.out) return nil } // Perform a real rollback. rolledback, err := o.oc.DeploymentConfigs(newConfig.Namespace).Update(newConfig) if err != nil { return err } // Print warnings about any image triggers disabled during the rollback. fmt.Fprintf(o.out, "#%d rolled back to %s\n", rolledback.LatestVersion, rollback.Spec.From.Name) for _, trigger := range rolledback.Triggers { disabled := []string{} if trigger.Type == deployapi.DeploymentTriggerOnImageChange && !trigger.ImageChangeParams.Automatic { disabled = append(disabled, trigger.ImageChangeParams.From.Name) } if len(disabled) > 0 { reenable := fmt.Sprintf("oc deploy %s --enable-triggers", rolledback.Name) fmt.Fprintf(o.out, "Warning: the following images triggers were disabled: %s\n You can re-enable them with: %s\n", strings.Join(disabled, ","), reenable) } } return nil }
// RunGet implements the generic Get command // TODO: convert all direct flag accessors to a struct and pass that instead of cmd // TODO: return an error instead of using glog.Fatal and checkErr func RunGet(f *Factory, out io.Writer, cmd *cobra.Command, args []string) { selector := GetFlagString(cmd, "selector") mapper, typer := f.Object(cmd) cmdNamespace, err := f.DefaultNamespace(cmd) checkErr(err) // handle watch separately since we cannot watch multiple resource types isWatch, isWatchOnly := GetFlagBool(cmd, "watch"), GetFlagBool(cmd, "watch-only") if isWatch || isWatchOnly { r := resource.NewBuilder(mapper, typer, ClientMapperForCommand(cmd, f)). NamespaceParam(cmdNamespace).DefaultNamespace(). SelectorParam(selector). ResourceTypeOrNameArgs(args...). SingleResourceType(). Do() mapping, err := r.ResourceMapping() checkErr(err) printer, err := PrinterForMapping(f, cmd, mapping) checkErr(err) obj, err := r.Object() checkErr(err) rv, err := mapping.MetadataAccessor.ResourceVersion(obj) checkErr(err) // print the current object if !isWatchOnly { if err := printer.PrintObj(obj, out); err != nil { checkErr(fmt.Errorf("unable to output the provided object: %v", err)) } } // print watched changes w, err := r.Watch(rv) checkErr(err) kubectl.WatchLoop(w, func(e watch.Event) error { return printer.PrintObj(e.Object, out) }) return } b := resource.NewBuilder(mapper, typer, ClientMapperForCommand(cmd, f)). NamespaceParam(cmdNamespace).DefaultNamespace(). SelectorParam(selector). ResourceTypeOrNameArgs(args...). Latest() printer, generic, err := PrinterForCommand(cmd) checkErr(err) if generic { clientConfig, err := f.ClientConfig(cmd) checkErr(err) defaultVersion := clientConfig.Version // the outermost object will be converted to the output-version version := outputVersion(cmd, defaultVersion) if len(version) == 0 { // TODO: add a new ResourceBuilder mode for Object() that attempts to ensure the objects // are in the appropriate version if one exists (and if not, use the best effort). // TODO: ensure api-version is set with the default preferred api version by the client // builder on initialization version = latest.Version } printer = kubectl.NewVersionedPrinter(printer, api.Scheme, version) obj, err := b.Flatten().Do().Object() checkErr(err) err = printer.PrintObj(obj, out) checkErr(err) return } // use the default printer for each object err = b.Do().Visit(func(r *resource.Info) error { printer, err := PrinterForMapping(f, cmd, r.Mapping) if err != nil { return err } return printer.PrintObj(r.Object, out) }) checkErr(err) }
// RunProject contains all the necessary functionality for the OpenShift cli process command func RunProcess(f *clientcmd.Factory, out io.Writer, cmd *cobra.Command, args []string) error { storedTemplate := "" if len(args) > 0 { storedTemplate = args[0] } filename := kcmdutil.GetFlagString(cmd, "filename") if len(storedTemplate) == 0 && len(filename) == 0 { return kcmdutil.UsageError(cmd, "Must pass a filename or name of stored template") } namespace, err := f.DefaultNamespace() if err != nil { return err } mapper, typer := f.Object() client, _, err := f.Clients() if err != nil { return err } var ( objects []runtime.Object infos []*resource.Info mapping *meta.RESTMapping ) version, kind, err := mapper.VersionAndKindForResource("template") if mapping, err = mapper.RESTMapping(kind, version); err != nil { return err } // When storedTemplate is not empty, then we fetch the template from the // server, otherwise we require to set the `-f` parameter. if len(storedTemplate) > 0 { templateObj, err := client.Templates(namespace).Get(storedTemplate) if err != nil { if errors.IsNotFound(err) { return fmt.Errorf("template %q could not be found", storedTemplate) } return err } templateObj.CreationTimestamp = util.Now() infos = append(infos, &resource.Info{Object: templateObj}) } else { infos, err = resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). NamespaceParam(namespace).RequireNamespace(). FilenameParam(filename). Do(). Infos() if err != nil { return err } } outputFormat := kcmdutil.GetFlagString(cmd, "output") for i := range infos { obj, ok := infos[i].Object.(*api.Template) if !ok { sourceName := filename if len(storedTemplate) > 0 { sourceName = namespace + "/" + storedTemplate } fmt.Fprintf(cmd.Out(), "unable to parse %q, not a valid Template but %s\n", sourceName, reflect.TypeOf(infos[i].Object)) continue } // If 'parameters' flag is set it does not do processing but only print // the template parameters to console for inspection. // If multiple templates are passed, this will print combined output for all // templates. if kcmdutil.GetFlagBool(cmd, "parameters") { if len(infos) > 1 { fmt.Fprintf(out, "\n%s:\n", obj.Name) } if err := describe.PrintTemplateParameters(obj.Parameters, out); err != nil { fmt.Fprintf(cmd.Out(), "error printing parameters for %q: %v\n", obj.Name, err) } continue } if label := kcmdutil.GetFlagString(cmd, "labels"); len(label) > 0 { lbl, err := kubectl.ParseLabels(label) if err != nil { fmt.Fprintf(cmd.Out(), "error parsing labels: %v\n", err) continue } if obj.ObjectLabels == nil { obj.ObjectLabels = make(map[string]string) } for key, value := range lbl { obj.ObjectLabels[key] = value } } // Override the values for the current template parameters // when user specify the --value if cmd.Flag("value").Changed { injectUserVars(cmd, obj) } resultObj, err := client.TemplateConfigs(namespace).Create(obj) if err != nil { fmt.Fprintf(cmd.Out(), "error processing the template %q: %v\n", obj.Name, err) continue } if outputFormat == "describe" { if s, err := (&describe.TemplateDescriber{ MetadataAccessor: meta.NewAccessor(), ObjectTyper: kapi.Scheme, ObjectDescriber: nil, }).DescribeTemplate(resultObj); err != nil { fmt.Fprintf(cmd.Out(), "error describing %q: %v\n", obj.Name, err) } else { fmt.Fprintf(out, s) } continue } objects = append(objects, resultObj.Objects...) } // Do not print the processed templates when asked to only show parameters or // describe. if kcmdutil.GetFlagBool(cmd, "parameters") || outputFormat == "describe" { return nil } p, _, err := kubectl.GetPrinter(outputFormat, "") if err != nil { return err } p = kubectl.NewVersionedPrinter(p, kapi.Scheme, kcmdutil.OutputVersion(cmd, mapping.APIVersion)) // use generic output if kcmdutil.GetFlagBool(cmd, "raw") { for i := range objects { p.PrintObj(objects[i], out) } return nil } return p.PrintObj(&kapi.List{ ListMeta: kapi.ListMeta{}, Items: objects, }, out) }