func (o *OpenShiftLogsOptions) Complete(f *clientcmd.Factory, out io.Writer, cmd *cobra.Command, args []string) error { switch len(args) { case 0: return cmdutil.UsageError(cmd, "RESOURCE is required for log") case 1: o.ResourceString = args[0] case 2: o.ResourceString = args[0] o.ContainerName = args[1] default: return cmdutil.UsageError(cmd, "log RESOURCE") } var err error o.Namespace, _, err = f.DefaultNamespace() if err != nil { return err } o.OriginClient, o.KubeClient, err = f.Clients() if err != nil { return err } return nil }
// Complete verifies command line arguments and loads data from the command environment func (o *RsyncOptions) Complete(f *clientcmd.Factory, cmd *cobra.Command, args []string) error { switch n := len(args); { case n == 0: cmd.Help() fallthrough case n < 2: return kcmdutil.UsageError(cmd, "SOURCE_DIR and POD:DESTINATION_DIR are required arguments") case n > 2: return kcmdutil.UsageError(cmd, "only SOURCE_DIR and POD:DESTINATION_DIR should be specified as arguments") } // Set main command arguments var err error o.Source, err = parsePathSpec(args[0]) if err != nil { return err } o.Destination, err = parsePathSpec(args[1]) if err != nil { return err } namespace, _, err := f.DefaultNamespace() if err != nil { return err } o.Namespace = namespace o.Strategy, err = o.determineStrategy(f, cmd, o.StrategyName) if err != nil { return err } return nil }
func NewCmdSyncGroups(name, fullName string, f *clientcmd.Factory, out io.Writer) *cobra.Command { options := NewSyncGroupsOptions() options.Out = out cmd := &cobra.Command{ Use: fmt.Sprintf("%s [SOURCE SCOPE WHITELIST --whitelist=WHITELIST-FILE] --sync-config=CONFIG-SOURCE", name), Short: "Sync OpenShift Groups with records from an external provider.", Long: syncGroupsLong, Example: fmt.Sprintf(syncGroupsExamples, fullName), Run: func(c *cobra.Command, args []string) { if err := options.Complete(args, f); err != nil { cmdutil.CheckErr(cmdutil.UsageError(c, err.Error())) } if err := options.Validate(); err != nil { cmdutil.CheckErr(cmdutil.UsageError(c, err.Error())) } err := options.Run() cmdutil.CheckErr(err) }, } cmd.Flags().StringVar(&options.WhitelistSource, "whitelist", "", "The path to the group whitelist") cmd.Flags().StringVar(&options.ConfigSource, "sync-config", "", "The path to the sync config") cmd.Flags().BoolVar(&options.SyncExisting, "existing", false, "Sync only existing, previously-synced groups") return cmd }
func setupAppConfig(f *clientcmd.Factory, out io.Writer, c *cobra.Command, args []string, config *newcmd.AppConfig) error { namespace, _, err := f.DefaultNamespace() if err != nil { return err } dockerClient, _, err := dockerutil.NewHelper().GetClient() if err == nil { if err = dockerClient.Ping(); err == nil { config.SetDockerClient(dockerClient) } else { glog.V(4).Infof("Docker client did not respond to a ping: %v", err) } } if err != nil { glog.V(2).Infof("No local Docker daemon detected: %v", err) } osclient, kclient, err := f.Clients() if err != nil { return err } config.KubeClient = kclient config.SetOpenShiftClient(osclient, namespace) // Only output="" should print descriptions of intermediate steps. Everything // else should print only some specific output (json, yaml, go-template, ...) output := cmdutil.GetFlagString(c, "output") if len(output) == 0 { config.Out = out } else { config.Out = ioutil.Discard } config.ErrOut = c.Out() if config.AllowSecretUse { cfg, err := f.OpenShiftClientConfig.ClientConfig() if err != nil { return err } config.SecretAccessor = newConfigSecretRetriever(cfg) } unknown := config.AddArguments(args) if len(unknown) != 0 { return cmdutil.UsageError(c, "Did not recognize the following arguments: %v", unknown) } if config.AllowMissingImages && config.AsSearch { return cmdutil.UsageError(c, "--allow-missing-images and --search are mutually exclusive.") } if len(config.SourceImage) != 0 && len(config.SourceImagePath) == 0 { return cmdutil.UsageError(c, "--source-image-path must be specified when --source-image is specified.") } if len(config.SourceImage) == 0 && len(config.SourceImagePath) != 0 { return cmdutil.UsageError(c, "--source-image must be specified when --source-image-path is specified.") } return nil }
// NewCmdAddSecret creates a command object for adding a secret reference to a service account func NewCmdAddSecret(name, fullName string, f *cmdutil.Factory, out io.Writer) *cobra.Command { o := &AddSecretOptions{Out: out} var typeFlags util.StringList cmd := &cobra.Command{ Use: fmt.Sprintf("%s serviceaccounts/sa-name secrets/secret-name [secrets/another-secret-name]...", name), Short: "Add secrets to a ServiceAccount", Long: fmt.Sprintf(addSecretLong, fullName), Run: func(c *cobra.Command, args []string) { if err := o.Complete(f, args, typeFlags); err != nil { cmdutil.CheckErr(cmdutil.UsageError(c, err.Error())) } if err := o.Validate(); err != nil { cmdutil.CheckErr(cmdutil.UsageError(c, err.Error())) } if err := o.AddSecrets(); err != nil { cmdutil.CheckErr(err) } }, } forFlag := &pflag.Flag{ Name: "for", Usage: "type of secret to add: mount or pull", Value: &typeFlags, DefValue: "mount", } cmd.Flags().AddFlag(forFlag) return cmd }
func setupAppConfig(f *clientcmd.Factory, out io.Writer, c *cobra.Command, args []string, config *newcmd.AppConfig) error { namespace, _, err := f.DefaultNamespace() if err != nil { return err } dockerClient, _, err := dockerutil.NewHelper().GetClient() if err == nil { if err = dockerClient.Ping(); err == nil { config.SetDockerClient(dockerClient) } } if err != nil { glog.V(2).Infof("No local Docker daemon detected: %v", err) } osclient, _, err := f.Clients() if err != nil { return err } config.SetOpenShiftClient(osclient, namespace) config.Out = out config.ErrOut = c.Out() unknown := config.AddArguments(args) if len(unknown) != 0 { return cmdutil.UsageError(c, "Did not recognize the following arguments: %v", unknown) } if config.AllowMissingImages && config.AsSearch { return cmdutil.UsageError(c, "--allow-missing-images and --search are mutually exclusive.") } return nil }
// NewCmdLinkSecret creates a command object for linking a secret reference to a service account func NewCmdLinkSecret(name, fullName string, f *kcmdutil.Factory, out io.Writer) *cobra.Command { o := &LinkSecretOptions{SecretOptions{Out: out}, false, false, nil} cmd := &cobra.Command{ Use: fmt.Sprintf("%s serviceaccounts-name secret-name [another-secret-name]...", name), Short: "Link secrets to a ServiceAccount", Long: linkSecretLong, Example: fmt.Sprintf(linkSecretExample, fullName), Run: func(c *cobra.Command, args []string) { if err := o.Complete(f, args); err != nil { kcmdutil.CheckErr(kcmdutil.UsageError(c, err.Error())) } if err := o.Validate(); err != nil { kcmdutil.CheckErr(kcmdutil.UsageError(c, err.Error())) } if err := o.LinkSecrets(); err != nil { kcmdutil.CheckErr(err) } }, } cmd.Flags().StringSliceVar(&o.typeFlags, "for", []string{"mount"}, "type of secret to link: mount or pull") return cmd }
// CreateSecretDockerRegistry is the implementation of the create secret docker-registry command func CreateSecretDockerRegistry(f cmdutil.Factory, cmdOut io.Writer, cmd *cobra.Command, args []string) error { name, err := NameFromCommandArgs(cmd, args) if err != nil { return err } requiredFlags := []string{"docker-username", "docker-password", "docker-email", "docker-server"} for _, requiredFlag := range requiredFlags { if value := cmdutil.GetFlagString(cmd, requiredFlag); len(value) == 0 { return cmdutil.UsageError(cmd, "flag %s is required", requiredFlag) } } var generator kubectl.StructuredGenerator switch generatorName := cmdutil.GetFlagString(cmd, "generator"); generatorName { case cmdutil.SecretForDockerRegistryV1GeneratorName: generator = &kubectl.SecretForDockerRegistryGeneratorV1{ Name: name, Username: cmdutil.GetFlagString(cmd, "docker-username"), Email: cmdutil.GetFlagString(cmd, "docker-email"), Password: cmdutil.GetFlagString(cmd, "docker-password"), Server: cmdutil.GetFlagString(cmd, "docker-server"), } default: return cmdutil.UsageError(cmd, fmt.Sprintf("Generator: %s not supported.", generatorName)) } return RunCreateSubcommand(f, cmd, cmdOut, &CreateSubcommandOptions{ Name: name, StructuredGenerator: generator, DryRun: cmdutil.GetDryRunFlag(cmd), OutputFormat: cmdutil.GetFlagString(cmd, "output"), }) }
func (o *NewServiceAccountTokenOptions) Complete(args []string, requestedLabels string, f *clientcmd.Factory, cmd *cobra.Command) error { if len(args) != 1 { return cmdutil.UsageError(cmd, fmt.Sprintf("expected one service account name as an argument, got %q", args)) } o.SAName = args[0] if len(requestedLabels) > 0 { labels, err := kubectl.ParseLabels(requestedLabels) if err != nil { return cmdutil.UsageError(cmd, err.Error()) } o.Labels = labels } client, err := f.Client() if err != nil { return err } namespace, _, err := f.DefaultNamespace() if err != nil { return fmt.Errorf("could not retrieve default namespace: %v", err) } o.SAClient = client.ServiceAccounts(namespace) o.SecretsClient = client.Secrets(namespace) return nil }
// Complete verifies command line arguments and loads data from the command environment func (p *AttachOptions) Complete(f *cmdutil.Factory, cmd *cobra.Command, argsIn []string) error { if len(argsIn) == 0 { return cmdutil.UsageError(cmd, "POD is required for attach") } if len(argsIn) > 1 { return cmdutil.UsageError(cmd, fmt.Sprintf("expected a single argument: POD, saw %d: %s", len(argsIn), argsIn)) } p.PodName = argsIn[0] namespace, _, err := f.DefaultNamespace() if err != nil { return err } p.Namespace = namespace config, err := f.ClientConfig() if err != nil { return err } p.Config = config client, err := f.Client() if err != nil { return err } p.Client = client return nil }
// NewCmdAddSecret creates a command object for adding a secret reference to a service account func NewCmdAddSecret(name, fullName string, f *cmdutil.Factory, out io.Writer) *cobra.Command { o := &AddSecretOptions{Out: out} var typeFlags []string cmd := &cobra.Command{ Use: fmt.Sprintf("%s serviceaccounts/sa-name secrets/secret-name [secrets/another-secret-name]...", name), Short: "Add secrets to a ServiceAccount", Long: addSecretLong, Example: fmt.Sprintf(addSecretExample, fullName), Run: func(c *cobra.Command, args []string) { if err := o.Complete(f, args, typeFlags); err != nil { cmdutil.CheckErr(cmdutil.UsageError(c, err.Error())) } if err := o.Validate(); err != nil { cmdutil.CheckErr(cmdutil.UsageError(c, err.Error())) } if err := o.AddSecrets(); err != nil { cmdutil.CheckErr(err) } }, } cmd.Flags().StringSliceVar(&typeFlags, "for", []string{"mount"}, "type of secret to add: mount or pull") return cmd }
func (o *LogsOptions) Complete(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string) error { switch len(args) { case 0: return cmdutil.UsageError(cmd, "POD is required for log") case 1: o.PodName = args[0] case 2: o.PodName = args[0] o.ContainerName = args[1] default: return cmdutil.UsageError(cmd, "log POD [CONTAINER]") } var err error o.PodNamespace, _, err = f.DefaultNamespace() if err != nil { return err } o.Client, err = f.Client() if err != nil { return err } return nil }
func validateArguments(cmd *cobra.Command, args []string) (deploymentKey, filename, image, oldName string, err error) { deploymentKey = cmdutil.GetFlagString(cmd, "deployment-label-key") image = cmdutil.GetFlagString(cmd, "image") filenames := cmdutil.GetFlagStringSlice(cmd, "filename") filename = "" if len(deploymentKey) == 0 { return "", "", "", "", cmdutil.UsageError(cmd, "--deployment-label-key can not be empty") } if len(filenames) > 1 { return "", "", "", "", cmdutil.UsageError(cmd, "May only specificy a single filename for new controller") } if len(filenames) > 0 { filename = filenames[0] } if len(filenames) == 0 && len(image) == 0 { return "", "", "", "", cmdutil.UsageError(cmd, "Must specify --filename or --image for new controller") } if len(filenames) != 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 (o *DockerbuildOptions) Complete(f *clientcmd.Factory, cmd *cobra.Command, args []string) error { paths, envArgs, ok := cmdutil.SplitEnvironmentFromResources(args) if !ok { return kcmdutil.UsageError(cmd, "context directory must be specified before environment changes: %s", strings.Join(args, " ")) } if len(paths) != 2 { return kcmdutil.UsageError(cmd, "the directory to build and tag must be specified") } o.Arguments, _, _ = cmdutil.ParseEnvironmentArguments(envArgs) o.Directory = paths[0] o.Tag = paths[1] if len(o.DockerfilePath) == 0 { o.DockerfilePath = filepath.Join(o.Directory, "Dockerfile") } var mounts []dockerbuilder.Mount for _, s := range o.MountSpecs { segments := strings.Split(s, ":") if len(segments) != 2 { return kcmdutil.UsageError(cmd, "--mount must be of the form SOURCE:DEST") } mounts = append(mounts, dockerbuilder.Mount{SourcePath: segments[0], DestinationPath: segments[1]}) } o.Mounts = mounts client, err := docker.NewClientFromEnv() if err != nil { return err } o.Client = client o.Keyring = credentialprovider.NewDockerKeyring() return nil }
// NewCmdUnlinkSecret creates a command object for detaching one or more secret references from a service account func NewCmdUnlinkSecret(name, fullName string, f *kcmdutil.Factory, out io.Writer) *cobra.Command { o := &UnlinkSecretOptions{SecretOptions{Out: out}} cmd := &cobra.Command{ Use: fmt.Sprintf("%s serviceaccount-name secret-name [another-secret-name] ...", name), Short: "Detach secrets from a ServiceAccount", Long: unlinkSecretLong, Example: fmt.Sprintf(unlinkSecretExample, fullName), Run: func(c *cobra.Command, args []string) { if err := o.Complete(f, args); err != nil { kcmdutil.CheckErr(kcmdutil.UsageError(c, err.Error())) } if err := o.Validate(); err != nil { kcmdutil.CheckErr(kcmdutil.UsageError(c, err.Error())) } if err := o.UnlinkSecrets(); err != nil { kcmdutil.CheckErr(err) } }, } return cmd }
// CreateSecretTLS is the implementation of the create secret tls command func CreateSecretTLS(f cmdutil.Factory, cmdOut io.Writer, cmd *cobra.Command, args []string) error { name, err := NameFromCommandArgs(cmd, args) if err != nil { return err } requiredFlags := []string{"cert", "key"} for _, requiredFlag := range requiredFlags { if value := cmdutil.GetFlagString(cmd, requiredFlag); len(value) == 0 { return cmdutil.UsageError(cmd, "flag %s is required", requiredFlag) } } var generator kubectl.StructuredGenerator switch generatorName := cmdutil.GetFlagString(cmd, "generator"); generatorName { case cmdutil.SecretForTLSV1GeneratorName: generator = &kubectl.SecretForTLSGeneratorV1{ Name: name, Key: cmdutil.GetFlagString(cmd, "key"), Cert: cmdutil.GetFlagString(cmd, "cert"), } default: return cmdutil.UsageError(cmd, fmt.Sprintf("Generator: %s not supported.", generatorName)) } return RunCreateSubcommand(f, cmd, cmdOut, &CreateSubcommandOptions{ Name: name, StructuredGenerator: generator, DryRun: cmdutil.GetFlagBool(cmd, "dry-run"), OutputFormat: cmdutil.GetFlagString(cmd, "output"), }) }
// NewCmdRollback creates a CLI rollback command. func NewCmdRollback(fullName string, f *clientcmd.Factory, out io.Writer) *cobra.Command { opts := &RollbackOptions{} cmd := &cobra.Command{ Use: "rollback (DEPLOYMENTCONFIG | DEPLOYMENT)", Short: "Revert part of an application back to a previous deployment", Long: rollbackLong, Example: fmt.Sprintf(rollbackExample, fullName), Run: func(cmd *cobra.Command, args []string) { if err := opts.Complete(f, args, out); err != nil { kcmdutil.CheckErr(kcmdutil.UsageError(cmd, err.Error())) } if err := opts.Validate(); err != nil { kcmdutil.CheckErr(kcmdutil.UsageError(cmd, err.Error())) } if err := opts.Run(); err != nil { kcmdutil.CheckErr(err) } }, } cmd.Flags().BoolVar(&opts.IncludeTriggers, "change-triggers", false, "Include the previous deployment's triggers in the rollback") cmd.Flags().BoolVar(&opts.IncludeStrategy, "change-strategy", false, "Include the previous deployment's strategy in the rollback") cmd.Flags().BoolVar(&opts.IncludeScalingSettings, "change-scaling-settings", false, "Include the previous deployment's replicationController replica count and selector in the rollback") cmd.Flags().BoolVarP(&opts.DryRun, "dry-run", "d", false, "Instead of performing the rollback, describe what the rollback will look like in human-readable form") cmd.Flags().StringVarP(&opts.Format, "output", "o", "", "Instead of performing the rollback, print the updated deployment configuration in the specified format (json|yaml|name|template|templatefile)") cmd.Flags().StringVarP(&opts.Template, "template", "t", "", "Template string or path to template file to use when -o=template or -o=templatefile.") cmd.MarkFlagFilename("template") cmd.Flags().Int64Var(&opts.DesiredVersion, "to-version", 0, "A config version to rollback to. Specifying version 0 is the same as omitting a version (the version will be auto-detected). This option is ignored when specifying a deployment.") return cmd }
// RunLog retrieves a pod log func RunLog(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, p *logParams) error { if len(os.Args) > 1 && os.Args[1] == "log" { printDeprecationWarning("logs", "log") } if len(args) == 0 { return cmdutil.UsageError(cmd, "POD is required for log") } if len(args) > 2 { return cmdutil.UsageError(cmd, "log POD [CONTAINER]") } namespace, _, err := f.DefaultNamespace() if err != nil { return err } client, err := f.Client() if err != nil { return err } podID := args[0] pod, err := client.Pods(namespace).Get(podID) if err != nil { return err } // [-c CONTAINER] container := p.containerName if len(container) == 0 { // [CONTAINER] (container as arg not flag) is supported as legacy behavior. See PR #10519 for more details. if len(args) == 1 { if len(pod.Spec.Containers) != 1 { podContainersNames := []string{} for _, container := range pod.Spec.Containers { podContainersNames = append(podContainersNames, container.Name) } return fmt.Errorf("Pod %s has the following containers: %s; please specify the container to print logs for with -c", pod.ObjectMeta.Name, strings.Join(podContainersNames, ", ")) } container = pod.Spec.Containers[0].Name } else { container = args[1] } } follow := false if cmdutil.GetFlagBool(cmd, "follow") { follow = true } previous := false if cmdutil.GetFlagBool(cmd, "previous") { previous = true } return handleLog(client, namespace, podID, container, follow, previous, out) }
func RunPortForward(f *cmdutil.Factory, cmd *cobra.Command, args []string, fw portForwarder) error { podName := cmdutil.GetFlagString(cmd, "pod") if len(podName) == 0 && len(args) == 0 { return cmdutil.UsageError(cmd, "POD is required for port-forward") } if len(podName) != 0 { printDeprecationWarning("port-forward POD", "-p POD") } else { podName = args[0] args = args[1:] } if len(args) < 1 { return cmdutil.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.Post(). Resource("pods"). Namespace(namespace). Name(pod.Name). SubResource("portforward") return fw.ForwardPorts("POST", req.URL(), config, args, stopCh) }
// Complete completes any options that are required by validate or run steps. func (opts *RegistryOptions) Complete(f *clientcmd.Factory, cmd *cobra.Command, out, errout io.Writer, args []string) error { if len(args) > 0 { return kcmdutil.UsageError(cmd, "No arguments are allowed to this command") } opts.image = opts.Config.ImageTemplate.ExpandOrDie(opts.Config.Type) opts.label = map[string]string{ "docker-registry": "default", } if opts.Config.Labels != defaultLabel { valid, remove, err := app.LabelsFromSpec(strings.Split(opts.Config.Labels, ",")) if err != nil { return err } if len(remove) > 0 { return kcmdutil.UsageError(cmd, "You may not pass negative labels in %q", opts.Config.Labels) } opts.label = valid } opts.nodeSelector = map[string]string{} if len(opts.Config.Selector) > 0 { valid, remove, err := app.LabelsFromSpec(strings.Split(opts.Config.Selector, ",")) if err != nil { return err } if len(remove) > 0 { return kcmdutil.UsageError(cmd, "You may not pass negative labels in selector %q", opts.Config.Selector) } opts.nodeSelector = valid } var portsErr error if opts.ports, portsErr = app.ContainerPortsFromString(opts.Config.Ports); portsErr != nil { return portsErr } var nsErr error if opts.namespace, _, nsErr = f.OpenShiftClientConfig.Namespace(); nsErr != nil { return fmt.Errorf("error getting namespace: %v", nsErr) } _, _, kClient, kClientErr := f.Clients() if kClientErr != nil { return fmt.Errorf("error getting client: %v", kClientErr) } opts.serviceClient = kClient.Core() opts.Config.Action.Bulk.Mapper = clientcmd.ResourceMapper(f) opts.Config.Action.Out, opts.Config.Action.ErrOut = out, errout opts.Config.Action.Bulk.Op = configcmd.Create opts.out = out opts.cmd = cmd opts.factory = f return nil }
func (o *LogsOptions) Complete(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string) error { containerName := cmdutil.GetFlagString(cmd, "container") switch len(args) { case 0: return cmdutil.UsageError(cmd, "POD is required for logs") case 1: o.ResourceArg = args[0] case 2: if cmd.Flag("container").Changed { return cmdutil.UsageError(cmd, "only one of -c, [CONTAINER] arg is allowed") } o.ResourceArg = args[0] containerName = args[1] default: return cmdutil.UsageError(cmd, "logs POD [-c CONTAINER]") } var err error o.Namespace, _, err = f.DefaultNamespace() if err != nil { return err } logOptions := &api.PodLogOptions{ Container: containerName, Follow: cmdutil.GetFlagBool(cmd, "follow"), Previous: cmdutil.GetFlagBool(cmd, "previous"), Timestamps: cmdutil.GetFlagBool(cmd, "timestamps"), } if sinceTime := cmdutil.GetFlagString(cmd, "since-time"); len(sinceTime) > 0 { t, err := api.ParseRFC3339(sinceTime, unversioned.Now) if err != nil { return err } logOptions.SinceTime = &t } if limit := cmdutil.GetFlagInt64(cmd, "limit-bytes"); limit != 0 { logOptions.LimitBytes = &limit } if tail := cmdutil.GetFlagInt64(cmd, "tail"); tail != -1 { logOptions.TailLines = &tail } if sinceSeconds := cmdutil.GetFlagDuration(cmd, "since"); sinceSeconds != 0 { // round up to the nearest second sec := int64(math.Ceil(float64(sinceSeconds) / float64(time.Second))) logOptions.SinceSeconds = &sec } o.Options = logOptions o.Mapper, o.Typer = f.Object() o.Decoder = f.Decoder(true) o.ClientMapper = resource.ClientMapperFunc(f.ClientForMapping) o.LogsForObject = f.LogsForObject o.Out = out return nil }
func validateArgsSnippet(cmd *cobra.Command, args []string) error { if len(args) > 1 { return cmdutil.UsageError(cmd, "Unexpected args: %v", args) } else if len(args) < 1 { return cmdutil.UsageError(cmd, "You need specify resource name. e.g. v1.Pod") } return nil }
func NewCmdSync(name, fullName string, f *clientcmd.Factory, out io.Writer) *cobra.Command { options := NewSyncOptions() options.Out = out typeArg := string(GroupSyncSourceLDAP) whitelistFile := "" blacklistFile := "" configFile := "" cmd := &cobra.Command{ Use: fmt.Sprintf("%s [--type=TYPE] [WHITELIST] [--whitelist=WHITELIST-FILE] --sync-config=CONFIG-FILE [--confirm]", name), Short: "Sync OpenShift groups with records from an external provider.", Long: syncLong, Example: fmt.Sprintf(syncExamples, fullName), Run: func(c *cobra.Command, args []string) { if err := options.Complete(typeArg, whitelistFile, blacklistFile, configFile, args, f); err != nil { cmdutil.CheckErr(cmdutil.UsageError(c, err.Error())) } if err := options.Validate(); err != nil { cmdutil.CheckErr(cmdutil.UsageError(c, err.Error())) } err := options.Run(c, f) if err != nil { if aggregate, ok := err.(kerrs.Aggregate); ok { for _, err := range aggregate.Errors() { fmt.Printf("%s\n", err) } os.Exit(1) } } cmdutil.CheckErr(err) }, } cmd.Flags().StringVar(&whitelistFile, "whitelist", whitelistFile, "path to the group whitelist file") cmd.MarkFlagFilename("whitelist", "txt") cmd.Flags().StringVar(&blacklistFile, "blacklist", whitelistFile, "path to the group blacklist file") cmd.MarkFlagFilename("blacklist", "txt") // TODO enable this we're able to support string slice elements that have commas // cmd.Flags().StringSliceVar(&options.Blacklist, "blacklist-group", options.Blacklist, "group to blacklist") cmd.Flags().StringVar(&configFile, "sync-config", configFile, "path to the sync config") cmd.MarkFlagFilename("sync-config", "yaml", "yml") cmd.Flags().StringVar(&typeArg, "type", typeArg, "which groups white- and blacklist entries refer to: "+strings.Join(AllowedSourceTypes, ",")) cmd.Flags().BoolVar(&options.Confirm, "confirm", false, "if true, modify OpenShift groups; if false, display results of a dry-run") cmdutil.AddPrinterFlags(cmd) cmd.Flags().Lookup("output").DefValue = "yaml" cmd.Flags().Lookup("output").Value.Set("yaml") return cmd }
// RunExplain executes the appropriate steps to print a model's documentation func RunExplain(f *cmdutil.Factory, out, cmdErr io.Writer, cmd *cobra.Command, args []string) error { if len(args) == 0 { fmt.Fprint(cmdErr, "You must specify the type of resource to explain. ", valid_resources) return cmdutil.UsageError(cmd, "Required resource not specified.") } if len(args) > 1 { return cmdutil.UsageError(cmd, "We accept only this format: explain RESOURCE") } recursive := cmdutil.GetFlagBool(cmd, "recursive") apiVersionString := cmdutil.GetFlagString(cmd, "api-version") apiVersion := unversioned.GroupVersion{} mapper, _ := f.Object(cmdutil.GetIncludeThirdPartyAPIs(cmd)) // TODO: After we figured out the new syntax to separate group and resource, allow // the users to use it in explain (kubectl explain <group><syntax><resource>). // Refer to issue #16039 for why we do this. Refer to PR #15808 that used "/" syntax. inModel, fieldsPath, err := kubectl.SplitAndParseResourceRequest(args[0], mapper) if err != nil { return err } // TODO: We should deduce the group for a resource by discovering the supported resources at server. fullySpecifiedGVR, groupResource := unversioned.ParseResourceArg(inModel) gvk := unversioned.GroupVersionKind{} if fullySpecifiedGVR != nil { gvk, _ = mapper.KindFor(*fullySpecifiedGVR) } if gvk.Empty() { gvk, err = mapper.KindFor(groupResource.WithVersion("")) if err != nil { return err } } if len(apiVersionString) == 0 { groupMeta, err := registered.Group(gvk.Group) if err != nil { return err } apiVersion = groupMeta.GroupVersion } else { apiVersion, err = unversioned.ParseGroupVersion(apiVersionString) if err != nil { return nil } } schema, err := f.SwaggerSchema(apiVersion.WithKind(gvk.Kind)) if err != nil { return err } return kubectl.PrintModelDescription(inModel, fieldsPath, out, schema, recursive) }
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 CompleteAppConfig(config *newcmd.AppConfig, f *clientcmd.Factory, c *cobra.Command, args []string) error { mapper, typer := f.Object(false) if config.Mapper == nil { config.Mapper = mapper } if config.Typer == nil { config.Typer = typer } if config.ClientMapper == nil { config.ClientMapper = resource.ClientMapperFunc(f.ClientForMapping) } namespace, _, err := f.DefaultNamespace() if err != nil { return err } osclient, _, kclient, err := f.Clients() if err != nil { return err } config.KubeClient = kclient dockerClient, _ := getDockerClient() config.SetOpenShiftClient(osclient, namespace, dockerClient) if config.AllowSecretUse { cfg, err := f.OpenShiftClientConfig.ClientConfig() if err != nil { return err } config.SecretAccessor = newConfigSecretRetriever(cfg) } unknown := config.AddArguments(args) if len(unknown) != 0 { return kcmdutil.UsageError(c, "Did not recognize the following arguments: %v", unknown) } if config.AllowMissingImages && config.AsSearch { return kcmdutil.UsageError(c, "--allow-missing-images and --search are mutually exclusive.") } if len(config.SourceImage) != 0 && len(config.SourceImagePath) == 0 { return kcmdutil.UsageError(c, "--source-image-path must be specified when --source-image is specified.") } if len(config.SourceImage) == 0 && len(config.SourceImagePath) != 0 { return kcmdutil.UsageError(c, "--source-image must be specified when --source-image-path is specified.") } if config.BinaryBuild && config.Strategy == generate.StrategyPipeline { return kcmdutil.UsageError(c, "specifying binary builds and the pipeline strategy at the same time is not allowed.") } return nil }
// NewCommandStartMasterAPI starts only the APIserver func NewCommandStartMasterAPI(name, basename string, out io.Writer) (*cobra.Command, *MasterOptions) { options := &MasterOptions{Output: out} options.DefaultsFromName(basename) cmd := &cobra.Command{ Use: name, Short: "Launch master API", Long: fmt.Sprintf(apiLong, basename, name), Run: func(c *cobra.Command, args []string) { if err := options.Complete(); err != nil { fmt.Fprintln(c.Out(), kcmdutil.UsageError(c, err.Error())) return } if len(options.ConfigFile) == 0 { fmt.Fprintln(c.Out(), kcmdutil.UsageError(c, "--config is required for this command")) return } if err := options.Validate(args); err != nil { fmt.Fprintln(c.Out(), kcmdutil.UsageError(c, err.Error())) return } startProfiler() if err := options.StartMaster(); err != nil { if kerrors.IsInvalid(err) { if details := err.(*kerrors.StatusError).ErrStatus.Details; details != nil { fmt.Fprintf(c.Out(), "Invalid %s %s\n", details.Kind, details.Name) for _, cause := range details.Causes { fmt.Fprintf(c.Out(), " %s: %s\n", cause.Field, cause.Message) } os.Exit(255) } } glog.Fatal(err) } }, } options.MasterArgs = NewDefaultMasterArgs() options.MasterArgs.StartAPI = true flags := cmd.Flags() // This command only supports reading from config and the listen argument flags.StringVar(&options.ConfigFile, "config", "", "Location of the master configuration file to run from. Required") cmd.MarkFlagFilename("config", "yaml", "yml") // TODO: add health and metrics endpoints on this listen argument BindListenArg(options.MasterArgs.ListenArg, flags, "") return cmd, options }
// NewCmdRsh attempts to open a shell session to the server. func NewCmdRsh(fullName string, f *clientcmd.Factory, in io.Reader, out, err io.Writer) *cobra.Command { options := &kubecmd.ExecOptions{ In: in, Out: out, Err: err, TTY: true, Stdin: true, Executor: &kubecmd.DefaultRemoteExecutor{}, } executable := "/bin/bash" forceTTY, disableTTY := false, false cmd := &cobra.Command{ Use: "rsh POD [command]", Short: "Start a shell session in a pod", Long: fmt.Sprintf(rshLong, fullName), Example: fmt.Sprintf(rshExample, fullName), Run: func(cmd *cobra.Command, args []string) { switch { case forceTTY && disableTTY: kcmdutil.CheckErr(kcmdutil.UsageError(cmd, "you may not specify -t and -T together")) case forceTTY: options.TTY = true case disableTTY: options.TTY = false default: options.TTY = cmdutil.IsTerminal(in) } if len(args) < 1 { kcmdutil.CheckErr(kcmdutil.UsageError(cmd, "rsh requires a single Pod to connect to")) } options.PodName = args[0] args = args[1:] if len(args) > 0 { options.Command = args } else { options.Command = []string{executable} } kcmdutil.CheckErr(RunRsh(options, f, cmd, args)) }, } cmd.Flags().BoolVarP(&forceTTY, "tty", "t", false, "Force a pseudo-terminal to be allocated") cmd.Flags().BoolVarP(&disableTTY, "no-tty", "T", false, "Disable pseudo-terminal allocation") cmd.Flags().StringVar(&executable, "shell", executable, "Path to shell command") cmd.Flags().StringVarP(&options.ContainerName, "container", "c", "", "Container name; defaults to first container") cmd.Flags().SetInterspersed(false) return cmd }
// NewCommandStartNode provides a CLI handler for 'start node' command func NewCommandStartNode(basename string, out io.Writer) (*cobra.Command, *NodeOptions) { options := &NodeOptions{Output: out} cmd := &cobra.Command{ Use: "node", Short: "Launch a node", Long: fmt.Sprintf(nodeLong, basename), Run: func(c *cobra.Command, args []string) { if err := options.Complete(); err != nil { fmt.Fprintln(c.Out(), kcmdutil.UsageError(c, err.Error())) return } if err := options.Validate(args); err != nil { fmt.Fprintln(c.Out(), kcmdutil.UsageError(c, err.Error())) return } startProfiler() if err := options.StartNode(); err != nil { if kerrors.IsInvalid(err) { if details := err.(*kerrors.StatusError).ErrStatus.Details; details != nil { fmt.Fprintf(c.Out(), "Invalid %s %s\n", details.Kind, details.Name) for _, cause := range details.Causes { fmt.Fprintf(c.Out(), " %s: %s\n", cause.Field, cause.Message) } os.Exit(255) } } glog.Fatal(err) } }, } flags := cmd.Flags() flags.StringVar(&options.ConfigFile, "config", "", "Location of the node configuration file to run from. When running from a configuration file, all other command-line arguments are ignored.") options.NodeArgs = NewDefaultNodeArgs() BindNodeArgs(options.NodeArgs, flags, "") BindListenArg(options.NodeArgs.ListenArg, flags, "") BindImageFormatArgs(options.NodeArgs.ImageFormatArgs, flags, "") BindKubeConnectionArgs(options.NodeArgs.KubeConnectionArgs, flags, "") // autocompletion hints cmd.MarkFlagFilename("config", "yaml", "yml") return cmd, options }
func RunCompletion(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string) error { if len(args) == 0 { return cmdutil.UsageError(cmd, "Shell not specified.") } if len(args) > 1 { return cmdutil.UsageError(cmd, "Too many arguments. Expected only the shell type.") } run, found := completion_shells[args[0]] if !found { return cmdutil.UsageError(cmd, "Unsupported shell type %q.", args[0]) } return run(out, cmd.Parent()) }