func RunProxy(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command) error { port := cmdutil.GetFlagInt(cmd, "port") fmt.Fprintf(out, "Starting to serve on localhost:%d", port) clientConfig, err := f.ClientConfig() if err != nil { return err } staticPrefix := cmdutil.GetFlagString(cmd, "www-prefix") if !strings.HasSuffix(staticPrefix, "/") { staticPrefix += "/" } apiProxyPrefix := cmdutil.GetFlagString(cmd, "api-prefix") if !strings.HasSuffix(apiProxyPrefix, "/") { apiProxyPrefix += "/" } server, err := kubectl.NewProxyServer(cmdutil.GetFlagString(cmd, "www"), apiProxyPrefix, staticPrefix, clientConfig) if err != nil { return err } glog.Fatal(server.Serve(port)) return nil }
// RunNewApplication contains all the necessary functionality for the OpenShift cli new-app command func RunNewApplication(fullName string, f *clientcmd.Factory, out io.Writer, c *cobra.Command, args []string, config *newcmd.AppConfig) error { if err := setupAppConfig(f, c, args, config); err != nil { return err } if config.Querying() { result, err := config.RunQuery(out, c.Out()) if err != nil { return handleRunError(c, err) } if len(cmdutil.GetFlagString(c, "output")) != 0 { return f.Factory.PrintObject(c, result.List, out) } return printHumanReadableQueryResult(result, out, fullName) } if err := setAppConfigLabels(c, config); err != nil { return err } result, err := config.RunAll(out, c.Out()) if err != nil { return handleRunError(c, err) } if err := setLabels(config.Labels, result); err != nil { return err } if len(cmdutil.GetFlagString(c, "output")) != 0 { return f.Factory.PrintObject(c, result.List, out) } if err := createObjects(f, out, result); err != nil { return err } hasMissingRepo := false for _, item := range result.List.Items { switch t := item.(type) { case *kapi.Service: portMappings := "." if len(t.Spec.Ports) > 0 { portMappings = fmt.Sprintf(" with port mappings %s.", describeServicePorts(t.Spec)) } fmt.Fprintf(c.Out(), "Service %q created at %s%s\n", t.Name, t.Spec.ClusterIP, portMappings) case *buildapi.BuildConfig: fmt.Fprintf(c.Out(), "A build was created - you can run `%s start-build %s` to start it.\n", fullName, t.Name) case *imageapi.ImageStream: if len(t.Status.DockerImageRepository) == 0 { if hasMissingRepo { continue } hasMissingRepo = true fmt.Fprintf(c.Out(), "WARNING: We created an image stream %q, but it does not look like a Docker registry has been integrated with the server. Automatic builds and deployments depend on that integration to detect new images and will not function properly.\n", t.Name) } } } fmt.Fprintf(c.Out(), "Run '%s status' to view your app.\n", fullName) return nil }
func Run(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string) error { if len(os.Args) > 1 && os.Args[1] == "run-container" { printDeprecationWarning("run", "run-container") } if len(args) != 1 { return cmdutil.UsageError(cmd, "NAME is required for run") } namespace, _, err := f.DefaultNamespace() if err != nil { return err } client, err := f.Client() if err != nil { return err } generatorName := cmdutil.GetFlagString(cmd, "generator") generator, found := f.Generator(generatorName) if !found { return cmdutil.UsageError(cmd, fmt.Sprintf("Generator: %s not found.", generator)) } names := generator.ParamNames() params := kubectl.MakeParams(cmd, names) params["name"] = args[0] err = kubectl.ValidateParams(names, params) if err != nil { return err } controller, err := generator.Generate(params) if err != nil { return err } inline := cmdutil.GetFlagString(cmd, "overrides") if len(inline) > 0 { controller, err = cmdutil.Merge(controller, inline, "ReplicationController") if err != nil { return err } } // TODO: extract this flag to a central location, when such a location exists. if !cmdutil.GetFlagBool(cmd, "dry-run") { controller, err = client.ReplicationControllers(namespace).Create(controller.(*api.ReplicationController)) if err != nil { return err } } return f.PrintObject(cmd, controller, out) }
func NewCmdCreateSecret(name, fullName string, f *clientcmd.Factory, out io.Writer) *cobra.Command { options := NewCreateSecretOptions() options.Out = out cmd := &cobra.Command{ Use: fmt.Sprintf("%s NAME [KEY=]SOURCE ...", name), Short: "Create a new secret based on a key file or on files within a directory", Long: newLong, Example: fmt.Sprintf(newExamples, fullName), Run: func(c *cobra.Command, args []string) { cmdutil.CheckErr(options.Complete(args, f)) cmdutil.CheckErr(options.Validate()) if len(cmdutil.GetFlagString(c, "output")) != 0 { secret, err := options.BundleSecret() cmdutil.CheckErr(err) cmdutil.CheckErr(f.Factory.PrintObject(c, secret, out)) return } _, err := options.CreateSecret() cmdutil.CheckErr(err) }, } cmd.Flags().BoolVarP(&options.Quiet, "quiet", "q", options.Quiet, "Suppress warnings") cmd.Flags().StringVar(&options.SecretTypeName, "type", "", "The type of secret") cmdutil.AddPrinterFlags(cmd) return cmd }
func NewCmdStop(f *cmdutil.Factory, out io.Writer) *cobra.Command { flags := &struct { Filenames util.StringList }{} cmd := &cobra.Command{ Use: "stop (-f FILENAME | RESOURCE (NAME | -l label | --all))", Short: "Gracefully shut down a resource by name or filename.", Long: stop_long, Example: stop_example, Run: func(cmd *cobra.Command, args []string) { cmdutil.CheckErr(cmdutil.ValidateOutputArgs(cmd)) shortOutput := cmdutil.GetFlagString(cmd, "output") == "name" cmdutil.CheckErr(RunStop(f, cmd, args, flags.Filenames, out, shortOutput)) }, } usage := "Filename, directory, or URL to file of resource(s) to be stopped." kubectl.AddJsonFilenameFlag(cmd, &flags.Filenames, usage) cmd.Flags().StringP("selector", "l", "", "Selector (label query) to filter on.") cmd.Flags().Bool("all", false, "[-all] to select all the specified resources.") cmd.Flags().Bool("ignore-not-found", false, "Treat \"resource not found\" as a successful stop.") cmd.Flags().Int("grace-period", -1, "Period of time in seconds given to the resource to terminate gracefully. Ignored if negative.") cmd.Flags().Duration("timeout", 0, "The length of time to wait before giving up on a delete, zero means determine a timeout from the size of the object") cmdutil.AddOutputFlagsForMutation(cmd) return cmd }
func NewCmdReplace(f *cmdutil.Factory, out io.Writer) *cobra.Command { var filenames util.StringList cmd := &cobra.Command{ Use: "replace -f FILENAME", // update is deprecated. Aliases: []string{"update"}, Short: "Replace a resource by filename or stdin.", Long: replace_long, Example: replace_example, Run: func(cmd *cobra.Command, args []string) { cmdutil.CheckErr(cmdutil.ValidateOutputArgs(cmd)) shortOutput := cmdutil.GetFlagString(cmd, "output") == "name" err := RunReplace(f, out, cmd, args, filenames, shortOutput) cmdutil.CheckCustomErr("Replace failed", err) }, } usage := "Filename, directory, or URL to file to use to replace the resource." kubectl.AddJsonFilenameFlag(cmd, &filenames, usage) cmd.MarkFlagRequired("filename") cmd.Flags().Bool("force", false, "Delete and re-create the specified resource") cmd.Flags().Bool("cascade", false, "Only relevant during a force replace. If true, cascade the deletion of the resources managed by this resource (e.g. Pods created by a ReplicationController). Default true.") cmd.Flags().Int("grace-period", -1, "Only relevant during a force replace. Period of time in seconds given to the old resource to terminate gracefully. Ignored if negative.") cmd.Flags().Duration("timeout", 0, "Only relevant during a force replace. The length of time to wait before giving up on a delete of the old resource, zero means determine a timeout from the size of the object") cmdutil.AddOutputFlagsForMutation(cmd) return cmd }
func RunDelete(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, filenames util.StringList) error { cmdNamespace, enforceNamespace, err := f.DefaultNamespace() if err != nil { return err } mapper, typer := f.Object() r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, filenames...). SelectorParam(cmdutil.GetFlagString(cmd, "selector")). SelectAllParam(cmdutil.GetFlagBool(cmd, "all")). ResourceTypeOrNameArgs(false, args...).RequireObject(false). Flatten(). Do() err = r.Err() if err != nil { return err } ignoreNotFound := cmdutil.GetFlagBool(cmd, "ignore-not-found") // By default use a reaper to delete all related resources. if cmdutil.GetFlagBool(cmd, "cascade") { return ReapResult(r, f, out, cmdutil.GetFlagBool(cmd, "cascade"), ignoreNotFound, cmdutil.GetFlagDuration(cmd, "timeout"), cmdutil.GetFlagInt(cmd, "grace-period")) } return DeleteResult(r, out, ignoreNotFound) }
func NewCmdDelete(f *cmdutil.Factory, out io.Writer) *cobra.Command { var filenames util.StringList cmd := &cobra.Command{ Use: "delete ([-f FILENAME] | (RESOURCE [(NAME | -l label | --all)]", Short: "Delete a resource by filename, stdin, resource and name, or by resources and label selector.", Long: delete_long, Example: delete_example, Run: func(cmd *cobra.Command, args []string) { cmdutil.CheckErr(cmdutil.ValidateOutputArgs(cmd)) shortOutput := cmdutil.GetFlagString(cmd, "output") == "name" err := RunDelete(f, out, cmd, args, filenames, shortOutput) cmdutil.CheckErr(err) }, } usage := "Filename, directory, or URL to a file containing the resource to delete." kubectl.AddJsonFilenameFlag(cmd, &filenames, usage) cmd.Flags().StringP("selector", "l", "", "Selector (label query) to filter on.") cmd.Flags().Bool("all", false, "[-all] to select all the specified resources.") cmd.Flags().Bool("ignore-not-found", false, "Treat \"resource not found\" as a successful delete. Defaults to \"true\" when --all is specified.") cmd.Flags().Bool("cascade", true, "If true, cascade the deletion of the resources managed by this resource (e.g. Pods created by a ReplicationController). Default true.") cmd.Flags().Int("grace-period", -1, "Period of time in seconds given to the resource to terminate gracefully. Ignored if negative.") cmd.Flags().Duration("timeout", 0, "The length of time to wait before giving up on a delete, zero means determine a timeout from the size of the object") cmdutil.AddOutputFlagsForMutation(cmd) return cmd }
func RunUpdate(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, filenames util.StringList) error { schema, err := f.Validator() if err != nil { return err } cmdNamespace, err := f.DefaultNamespace() if err != nil { return err } patch := cmdutil.GetFlagString(cmd, "patch") if len(filenames) == 0 && len(patch) == 0 { return cmdutil.UsageError(cmd, "Must specify --filename or --patch to update") } if len(filenames) != 0 && len(patch) != 0 { return cmdutil.UsageError(cmd, "Can not specify both --filename and --patch") } // TODO: Make patching work with -f, updating with patched JSON input files if len(filenames) == 0 { name, err := updateWithPatch(cmd, args, f, patch) if err != nil { return err } fmt.Fprintf(out, "%s\n", name) return nil } if len(filenames) == 0 { return cmdutil.UsageError(cmd, "Must specify --filename to update") } mapper, typer := f.Object() r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). Schema(schema). ContinueOnError(). NamespaceParam(cmdNamespace).RequireNamespace(). FilenameParam(filenames...). Flatten(). Do() err = r.Err() if err != nil { return err } return r.Visit(func(info *resource.Info) error { data, err := info.Mapping.Codec.Encode(info.Object) if err != nil { return err } obj, err := resource.NewHelper(info.Client, info.Mapping).Update(info.Namespace, info.Name, true, data) if err != nil { return err } info.Refresh(obj, true) printObjectSpecificMessage(obj, out) fmt.Fprintf(out, "%s/%s\n", info.Mapping.Resource, info.Name) return nil }) }
func RunPortForward(f *Factory, cmd *cobra.Command, args []string) error { podName := util.GetFlagString(cmd, "pod") if len(podName) == 0 { return util.UsageError(cmd, "POD is required for exec") } if len(args) < 1 { return util.UsageError(cmd, "at least 1 PORT is required for port-forward") } namespace, err := f.DefaultNamespace() if err != nil { return err } client, err := f.Client() if err != nil { return err } pod, err := client.Pods(namespace).Get(podName) if err != nil { return err } if pod.Status.Phase != api.PodRunning { glog.Fatalf("Unable to execute command because pod is not running. Current status=%v", pod.Status.Phase) } config, err := f.ClientConfig() if err != nil { return err } signals := make(chan os.Signal, 1) signal.Notify(signals, os.Interrupt) defer signal.Stop(signals) stopCh := make(chan struct{}, 1) go func() { <-signals close(stopCh) }() req := client.RESTClient.Get(). Prefix("proxy"). Resource("minions"). Name(pod.Status.Host). Suffix("portForward", namespace, podName) pf, err := portforward.New(req, config, args, stopCh) if err != nil { return err } return pf.ForwardPorts() }
// RunScale executes the scaling func RunScale(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, shortOutput bool) error { if len(os.Args) > 1 && os.Args[1] == "resize" { printDeprecationWarning("scale", "resize") } count := cmdutil.GetFlagInt(cmd, "replicas") if count < 0 { return cmdutil.UsageError(cmd, "--replicas=COUNT RESOURCE NAME") } cmdNamespace, _, err := f.DefaultNamespace() if err != nil { return err } mapper, typer := f.Object() r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). ResourceTypeOrNameArgs(false, args...). Flatten(). Do() err = r.Err() if err != nil { return err } mapping, err := r.ResourceMapping() if err != nil { return err } infos, err := r.Infos() if err != nil { return err } if len(infos) > 1 { return fmt.Errorf("multiple resources provided: %v", args) } info := infos[0] scaler, err := f.Scaler(mapping) if err != nil { return err } resourceVersion := cmdutil.GetFlagString(cmd, "resource-version") currentSize := cmdutil.GetFlagInt(cmd, "current-replicas") precondition := &kubectl.ScalePrecondition{currentSize, resourceVersion} retry := kubectl.NewRetryParams(kubectl.Interval, kubectl.Timeout) waitForReplicas := kubectl.NewRetryParams(kubectl.Interval, kubectl.Timeout) if err := scaler.Scale(info.Namespace, info.Name, uint(count), precondition, retry, waitForReplicas); err != nil { return err } cmdutil.PrintSuccess(mapper, shortOutput, out, info.Mapping.Resource, info.Name, "scaled") return nil }
func setAppConfigLabels(c *cobra.Command, config *newcmd.AppConfig) error { labelStr := cmdutil.GetFlagString(c, "labels") if len(labelStr) != 0 { var err error config.Labels, err = ctl.ParseLabels(labelStr) if err != nil { return err } } return nil }
// RunNewApplication contains all the necessary functionality for the OpenShift cli new-app command func RunNewApplication(fullName string, f *clientcmd.Factory, out io.Writer, c *cobra.Command, args []string, config *newcmd.AppConfig) error { if err := setupAppConfig(f, c, args, config); err != nil { return err } result, err := config.RunAll(out, c.Out()) if err != nil { if errs, ok := err.(errors.Aggregate); ok { if len(errs.Errors()) == 1 { err = errs.Errors()[0] } } if err == newcmd.ErrNoInputs { // TODO: suggest things to the user return cmdutil.UsageError(c, "You must specify one or more images, image streams, templates or source code locations to create an application.") } return err } if err := setLabels(c, result); err != nil { return err } if len(cmdutil.GetFlagString(c, "output")) != 0 { return f.Factory.PrintObject(c, result.List, out) } if err := createObjects(f, out, result); err != nil { return err } hasMissingRepo := false for _, item := range result.List.Items { switch t := item.(type) { case *kapi.Service: portMappings := "." if len(t.Spec.Ports) > 0 { portMappings = fmt.Sprintf(" with port mappings %s.", describeServicePorts(t.Spec)) } fmt.Fprintf(c.Out(), "Service %q created at %s%s\n", t.Name, t.Spec.ClusterIP, portMappings) case *buildapi.BuildConfig: fmt.Fprintf(c.Out(), "A build was created - you can run `%s start-build %s` to start it.\n", fullName, t.Name) case *imageapi.ImageStream: if len(t.Status.DockerImageRepository) == 0 { if hasMissingRepo { continue } hasMissingRepo = true fmt.Fprintf(c.Out(), "WARNING: We created an ImageStream %q, but it does not look like a Docker registry has been integrated with the OpenShift server. Automatic builds and deployments depend on that integration to detect new images and will not function properly.\n", t.Name) } } } fmt.Fprintf(c.Out(), "Run '%s status' to view your app.\n", fullName) return nil }
func validateArguments(cmd *cobra.Command, args []string) (deploymentKey, filename, image, oldName string, err error) { deploymentKey = cmdutil.GetFlagString(cmd, "deployment-label-key") filename = cmdutil.GetFlagString(cmd, "filename") image = cmdutil.GetFlagString(cmd, "image") if len(deploymentKey) == 0 { return "", "", "", "", cmdutil.UsageError(cmd, "--deployment-label-key can not be empty") } if len(filename) == 0 && len(image) == 0 { return "", "", "", "", cmdutil.UsageError(cmd, "Must specify --filename or --image for new controller") } if len(filename) != 0 && len(image) != 0 { return "", "", "", "", cmdutil.UsageError(cmd, "--filename and --image can not both be specified") } if len(args) < 1 { return "", "", "", "", cmdutil.UsageError(cmd, "Must specify the controller to update") } return deploymentKey, filename, image, args[0], nil }
func RunResize(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string) error { count := cmdutil.GetFlagInt(cmd, "replicas") if len(args) != 2 || count < 0 { return cmdutil.UsageError(cmd, "--replicas=COUNT RESOURCE ID") } cmdNamespace, err := f.DefaultNamespace() if err != nil { return err } mapper, typer := f.Object() r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). ResourceTypeOrNameArgs(false, args...). Flatten(). Do() err = r.Err() if err != nil { return err } mapping, err := r.ResourceMapping() if err != nil { return err } infos, err := r.Infos() if err != nil { return err } info := infos[0] resizer, err := f.Resizer(mapping) if err != nil { return err } resourceVersion := cmdutil.GetFlagString(cmd, "resource-version") currentSize := cmdutil.GetFlagInt(cmd, "current-replicas") precondition := &kubectl.ResizePrecondition{currentSize, resourceVersion} cond := kubectl.ResizeCondition(resizer, precondition, info.Namespace, info.Name, uint(count)) msg := "resized" if err = wait.Poll(retryFrequency, retryTimeout, cond); err != nil { msg = fmt.Sprintf("Failed to resize controller in spite of retrying for %s", retryTimeout) if err != nil { return err } } fmt.Fprintf(out, "%s\n", msg) return nil }
func NewPathOptions(cmd *cobra.Command) *kubecmdconfig.PathOptions { return &kubecmdconfig.PathOptions{ GlobalFile: RecommendedHomeFile, EnvVar: OpenShiftConfigPathEnvVar, ExplicitFileFlag: OpenShiftConfigFlagName, LoadingRules: &kclientcmd.ClientConfigLoadingRules{ ExplicitPath: cmdutil.GetFlagString(cmd, OpenShiftConfigFlagName), }, } }
// validateFlags filters out flags that are not supposed to be used // when generating a route func validateFlags(cmd *cobra.Command) error { invalidFlags := []string{} if len(cmdutil.GetFlagString(cmd, "type")) != 0 { invalidFlags = append(invalidFlags, "--type") } if len(cmdutil.GetFlagString(cmd, "selector")) != 0 { invalidFlags = append(invalidFlags, "--selector") } if len(cmdutil.GetFlagString(cmd, "container-port")) != 0 { invalidFlags = append(invalidFlags, "--container-port") } if len(cmdutil.GetFlagString(cmd, "target-port")) != 0 { invalidFlags = append(invalidFlags, "--target-port") } if len(cmdutil.GetFlagString(cmd, "public-ip")) != 0 { invalidFlags = append(invalidFlags, "--public-ip") } if cmdutil.GetFlagInt(cmd, "port") != -1 { invalidFlags = append(invalidFlags, "--port") } if cmdutil.GetFlagBool(cmd, "create-external-load-balancer") { invalidFlags = append(invalidFlags, "--create-external-load-balancer") } msg := "" switch len(invalidFlags) { case 0: return nil case 1: msg = invalidFlags[0] default: commaSeparated, last := invalidFlags[:len(invalidFlags)-1], invalidFlags[len(invalidFlags)-1] msg = fmt.Sprintf("%s or %s", strings.Join(commaSeparated, ","), last) } return fmt.Errorf("cannot use %s when generating a route", msg) }
func RunClusterInfo(factory *cmdutil.Factory, out io.Writer, cmd *cobra.Command) error { if os.Args[1] == "clusterinfo" { printDeprecationWarning("cluster-info", "clusterinfo") } client, err := factory.ClientConfig() if err != nil { return err } printService(out, "Kubernetes master", client.Host) mapper, typer := factory.Object() cmdNamespace := cmdutil.GetFlagString(cmd, "namespace") if cmdNamespace == "" { cmdNamespace = api.NamespaceSystem } // TODO use generalized labels once they are implemented (#341) b := resource.NewBuilder(mapper, typer, factory.ClientMapperForCommand()). NamespaceParam(cmdNamespace).DefaultNamespace(). SelectorParam("kubernetes.io/cluster-service=true"). ResourceTypeOrNameArgs(false, []string{"services"}...). Latest() b.Do().Visit(func(r *resource.Info) error { services := r.Object.(*api.ServiceList).Items for _, service := range services { var link string if len(service.Status.LoadBalancer.Ingress) > 0 { ingress := service.Status.LoadBalancer.Ingress[0] ip := ingress.IP if ip == "" { ip = ingress.Hostname } for _, port := range service.Spec.Ports { link += "http://" + ip + ":" + strconv.Itoa(port.Port) + " " } } else { link = client.Host + "/api/" + client.Version + "/proxy/namespaces/" + service.ObjectMeta.Namespace + "/services/" + service.ObjectMeta.Name } name := service.ObjectMeta.Labels["kubernetes.io/name"] if len(name) == 0 { name = service.ObjectMeta.Name } printService(out, name, link) } return nil }) return nil // TODO consider printing more information about cluster }
func RunDescribe(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string) error { selector := cmdutil.GetFlagString(cmd, "selector") cmdNamespace, _, err := f.DefaultNamespace() if err != nil { return err } if len(args) == 0 { fmt.Fprint(out, "You must specify the type of resource to describe. ", valid_resources) return cmdutil.UsageError(cmd, "Required resource not specified.") } mapper, typer := f.Object() r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). SelectorParam(selector). ResourceTypeOrNameArgs(false, args...). Flatten(). Do() err = r.Err() if err != nil { return err } mapping, err := r.ResourceMapping() if err != nil { return err } describer, err := f.Describer(mapping) if err != nil { return err } infos, err := r.Infos() if err != nil { if apierrors.IsNotFound(err) && len(args) == 2 { return DescribeMatchingResources(mapper, typer, describer, f, cmdNamespace, args[0], args[1], out, err) } return err } for _, info := range infos { s, err := describer.Describe(info.Namespace, info.Name) if err != nil { return err } fmt.Fprintf(out, "%s\n\n", s) } return nil }
func RunLabel(f *Factory, out io.Writer, cmd *cobra.Command, args []string) error { if len(args) < 2 { return util.UsageError(cmd, "<resource> <name> is required") } if len(args) < 3 { return util.UsageError(cmd, "at least one label update is required.") } res := args[:2] cmdNamespace, err := f.DefaultNamespace() if err != nil { return err } mapper, _ := f.Object() // TODO: use resource.Builder instead mapping, namespace, name, err := util.ResourceFromArgs(cmd, res, mapper, cmdNamespace) if err != nil { return err } client, err := f.RESTClient(mapping) if err != nil { return err } labels, remove, err := parseLabels(args[2:]) if err != nil { return err } overwrite := util.GetFlagBool(cmd, "overwrite") resourceVersion := util.GetFlagString(cmd, "resource-version") obj, err := updateObject(client, mapping, namespace, name, func(obj runtime.Object) (runtime.Object, error) { outObj, err := labelFunc(obj, overwrite, resourceVersion, labels, remove) if err != nil { return nil, err } return outObj, nil }) if err != nil { return err } printer, err := f.PrinterForMapping(cmd, mapping) if err != nil { return err } printer.PrintObj(obj, out) return nil }
func (o *LoginOptions) Complete(f *osclientcmd.Factory, cmd *cobra.Command, args []string) error { kubeconfig, err := f.OpenShiftClientConfig.RawConfig() o.StartingKubeConfig = &kubeconfig if err != nil { if !os.IsNotExist(err) { return err } // build a valid object to use if we failed on a non-existent file o.StartingKubeConfig = kclientcmdapi.NewConfig() } addr := flagtypes.Addr{Value: "localhost:8443", DefaultScheme: "https", DefaultPort: 8443, AllowPrefix: true}.Default() if serverFlag := kcmdutil.GetFlagString(cmd, "server"); len(serverFlag) > 0 { if err := addr.Set(serverFlag); err != nil { return err } o.Server = addr.String() } else if len(args) == 1 { if err := addr.Set(args[0]); err != nil { return err } o.Server = addr.String() } else if len(o.Server) == 0 { if defaultContext, defaultContextExists := o.StartingKubeConfig.Contexts[o.StartingKubeConfig.CurrentContext]; defaultContextExists { if cluster, exists := o.StartingKubeConfig.Clusters[defaultContext.Cluster]; exists { o.Server = cluster.Server } } } o.CertFile = kcmdutil.GetFlagString(cmd, "client-certificate") o.KeyFile = kcmdutil.GetFlagString(cmd, "client-key") o.APIVersion = kcmdutil.GetFlagString(cmd, "api-version") // if the API version isn't explicitly passed, use the API version from the default context (same rules as the server above) if len(o.APIVersion) == 0 { if defaultContext, defaultContextExists := o.StartingKubeConfig.Contexts[o.StartingKubeConfig.CurrentContext]; defaultContextExists { if cluster, exists := o.StartingKubeConfig.Clusters[defaultContext.Cluster]; exists { o.APIVersion = cluster.APIVersion } } } o.CAFile = kcmdutil.GetFlagString(cmd, "certificate-authority") o.InsecureTLS = kcmdutil.GetFlagBool(cmd, "insecure-skip-tls-verify") o.Token = kcmdutil.GetFlagString(cmd, "token") o.DefaultNamespace, _ = f.OpenShiftClientConfig.Namespace() o.PathOptions = config.NewPathOptions(cmd) return nil }
// NewCmdLogin implements the OpenShift cli login command func NewCmdLogin(fullName string, f *osclientcmd.Factory, reader io.Reader, out io.Writer) *cobra.Command { options := &LoginOptions{ Reader: reader, Out: out, } cmds := &cobra.Command{ Use: "login [URL]", Short: "Log in to an OpenShift server", Long: loginLong, Example: fmt.Sprintf(loginExample, fullName), Run: func(cmd *cobra.Command, args []string) { if err := options.Complete(f, cmd, args); err != nil { kcmdutil.CheckErr(err) } if err := options.Validate(args, kcmdutil.GetFlagString(cmd, "server")); err != nil { kcmdutil.CheckErr(err) } err := RunLogin(cmd, options) if kapierrors.IsUnauthorized(err) { fmt.Fprintln(out, "Login failed (401 Unauthorized)") if err, isStatusErr := err.(*kapierrors.StatusError); isStatusErr { if details := err.Status().Details; details != nil { for _, cause := range details.Causes { fmt.Fprintln(out, cause.Message) } } } os.Exit(1) } else { kcmdutil.CheckErr(err) } }, } // Login is the only command that can negotiate a session token against the auth server using basic auth cmds.Flags().StringVarP(&options.Username, "username", "u", "", "Username, will prompt if not provided") cmds.Flags().StringVarP(&options.Password, "password", "p", "", "Password, will prompt if not provided") return cmds }
func setLabels(c *cobra.Command, result *newcmd.AppResult) error { label := cmdutil.GetFlagString(c, "labels") if len(label) != 0 { lbl, err := ctl.ParseLabels(label) if err != nil { return err } for _, object := range result.List.Items { err = util.AddObjectLabels(object, lbl) if err != nil { return err } } } return nil }
func RunPatch(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, shortOutput bool) error { cmdNamespace, _, err := f.DefaultNamespace() if err != nil { return err } patch := cmdutil.GetFlagString(cmd, "patch") if len(patch) == 0 { return cmdutil.UsageError(cmd, "Must specify -p to patch") } mapper, typer := f.Object() r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). ResourceTypeOrNameArgs(false, args...). Flatten(). Do() err = r.Err() if err != nil { return err } mapping, err := r.ResourceMapping() if err != nil { return err } client, err := f.RESTClient(mapping) if err != nil { return err } infos, err := r.Infos() if err != nil { return err } name, namespace := infos[0].Name, infos[0].Namespace helper := resource.NewHelper(client, mapping) _, err = helper.Patch(namespace, name, api.StrategicMergePatchType, []byte(patch)) if err != nil { return err } cmdutil.PrintSuccess(mapper, shortOutput, out, "", name, "patched") return nil }
// injectUserVars injects user specified variables into the Template func injectUserVars(cmd *cobra.Command, t *api.Template) { values := util.StringList{} values.Set(kcmdutil.GetFlagString(cmd, "value")) for _, keypair := range values { p := strings.SplitN(keypair, "=", 2) if len(p) != 2 { fmt.Fprintf(cmd.Out(), "invalid parameter assignment in %q: %q\n", t.Name, keypair) continue } if v := template.GetParameterByName(t, p[0]); v != nil { v.Value = p[1] v.Generate = "" template.AddParameter(t, *v) } else { fmt.Fprintf(cmd.Out(), "unknown parameter name %q\n", p[0]) } } }
func NewCmdPatch(f *cmdutil.Factory, out io.Writer) *cobra.Command { cmd := &cobra.Command{ Use: "patch RESOURCE NAME -p PATCH", Short: "Update field(s) of a resource by stdin.", Long: patch_long, Example: patch_example, Run: func(cmd *cobra.Command, args []string) { cmdutil.CheckErr(cmdutil.ValidateOutputArgs(cmd)) shortOutput := cmdutil.GetFlagString(cmd, "output") == "name" err := RunPatch(f, out, cmd, args, shortOutput) cmdutil.CheckErr(err) }, } cmd.Flags().StringP("patch", "p", "", "The patch to be applied to the resource JSON file.") cmd.MarkFlagRequired("patch") cmdutil.AddOutputFlagsForMutation(cmd) return cmd }
// NewCmdReconcileClusterRoles implements the OpenShift cli reconcile-cluster-roles command func NewCmdReconcileClusterRoles(name, fullName string, f *clientcmd.Factory, out io.Writer) *cobra.Command { o := &reconcileClusterOptions{Out: out} cmd := &cobra.Command{ Use: name, Short: "Replace cluster roles to match the recommended bootstrap policy", Long: reconcileLong, Example: fmt.Sprintf(reconcileExample, fullName), Run: func(cmd *cobra.Command, args []string) { if err := o.Complete(cmd, f, args); err != nil { kcmdutil.CheckErr(kcmdutil.UsageError(cmd, err.Error())) } changedClusterRoles, err := o.ChangedClusterRoles() kcmdutil.CheckErr(err) if len(changedClusterRoles) == 0 { return } if (len(kcmdutil.GetFlagString(cmd, "output")) != 0) && !o.Confirmed { list := &kapi.List{} for _, item := range changedClusterRoles { list.Items = append(list.Items, item) } kcmdutil.CheckErr(f.Factory.PrintObject(cmd, list, out)) } if o.Confirmed { kcmdutil.CheckErr(o.ReplaceChangedRoles(changedClusterRoles)) } }, } cmd.Flags().BoolVar(&o.Confirmed, "confirm", o.Confirmed, "Specify that cluster roles should be modified. Defaults to false, displaying what would be replaced but not actually replacing anything.") kcmdutil.AddPrinterFlags(cmd) cmd.Flags().Lookup("output").DefValue = "yaml" cmd.Flags().Lookup("output").Value.Set("yaml") return cmd }
func RunStop(f *cmdutil.Factory, cmd *cobra.Command, args []string, filenames util.StringList, out io.Writer) error { cmdNamespace, enforceNamespace, err := f.DefaultNamespace() if err != nil { return err } mapper, typer := f.Object() r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). ResourceTypeOrNameArgs(false, args...). FilenameParam(enforceNamespace, filenames...). SelectorParam(cmdutil.GetFlagString(cmd, "selector")). SelectAllParam(cmdutil.GetFlagBool(cmd, "all")). Flatten(). Do() if r.Err() != nil { return r.Err() } return ReapResult(r, f, out, false, cmdutil.GetFlagBool(cmd, "ignore-not-found"), cmdutil.GetFlagDuration(cmd, "timeout"), cmdutil.GetFlagInt(cmd, "grace-period")) }
func (f *Factory) NewCmdStop(out io.Writer) *cobra.Command { flags := &struct { Filenames util.StringList }{} cmd := &cobra.Command{ Use: "stop (-f FILENAME | RESOURCE (ID | -l label | --all))", Short: "Gracefully shut down a resource by id or filename.", Long: stop_long, Example: stop_example, Run: func(cmd *cobra.Command, args []string) { cmdNamespace, err := f.DefaultNamespace() cmdutil.CheckErr(err) mapper, typer := f.Object() r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand(cmd)). ContinueOnError(). NamespaceParam(cmdNamespace).RequireNamespace(). ResourceTypeOrNameArgs(false, args...). FilenameParam(flags.Filenames...). SelectorParam(cmdutil.GetFlagString(cmd, "selector")). SelectAllParam(cmdutil.GetFlagBool(cmd, "all")). Flatten(). Do() cmdutil.CheckErr(r.Err()) r.Visit(func(info *resource.Info) error { reaper, err := f.Reaper(info.Mapping) cmdutil.CheckErr(err) s, err := reaper.Stop(info.Namespace, info.Name) if err != nil { return err } fmt.Fprintf(out, "%s\n", s) return nil }) }, } cmd.Flags().VarP(&flags.Filenames, "filename", "f", "Filename, directory, or URL to file of resource(s) to be stopped") cmd.Flags().StringP("selector", "l", "", "Selector (label query) to filter on") cmd.Flags().Bool("all", false, "[-all] to select all the specified resources") return cmd }
func RunDelete(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, filenames util.StringList, shortOutput bool) error { cmdNamespace, enforceNamespace, err := f.DefaultNamespace() if err != nil { return err } deleteAll := cmdutil.GetFlagBool(cmd, "all") mapper, typer := f.Object() r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, filenames...). SelectorParam(cmdutil.GetFlagString(cmd, "selector")). SelectAllParam(deleteAll). ResourceTypeOrNameArgs(false, args...).RequireObject(false). Flatten(). Do() err = r.Err() if err != nil { return err } ignoreNotFound := cmdutil.GetFlagBool(cmd, "ignore-not-found") if deleteAll { f := cmd.Flags().Lookup("ignore-not-found") // The flag should never be missing if f == nil { return fmt.Errorf("missing --ignore-not-found flag") } // If the user didn't explicitly set the option, default to ignoring NotFound errors when used with --all if !f.Changed { ignoreNotFound = true } } // By default use a reaper to delete all related resources. if cmdutil.GetFlagBool(cmd, "cascade") { return ReapResult(r, f, out, cmdutil.GetFlagBool(cmd, "cascade"), ignoreNotFound, cmdutil.GetFlagDuration(cmd, "timeout"), cmdutil.GetFlagInt(cmd, "grace-period"), shortOutput, mapper) } return DeleteResult(r, out, ignoreNotFound, shortOutput, mapper) }