func ExamplePrintPodWithWideFormat() { f, tf, codec := NewAPIFactory() tf.Printer = kubectl.NewHumanReadablePrinter(false, false, true, []string{}) tf.Client = &client.FakeRESTClient{ Codec: codec, Client: nil, } nodeName := "kubernetes-minion-abcd" cmd := NewCmdRun(f, os.Stdout) pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "test1", CreationTimestamp: util.Time{time.Now().AddDate(-10, 0, 0)}, }, Spec: api.PodSpec{ Containers: make([]api.Container, 2), NodeName: nodeName, }, Status: api.PodStatus{ Phase: "podPhase", ContainerStatuses: []api.ContainerStatus{ {Ready: true, RestartCount: 3, State: api.ContainerState{Running: &api.ContainerStateRunning{}}}, {RestartCount: 3}, }, }, } err := f.PrintObject(cmd, pod, os.Stdout) if err != nil { fmt.Printf("Unexpected error: %v", err) } // Output: // NAME READY STATUS RESTARTS AGE NODE // test1 1/2 podPhase 6 10y kubernetes-minion-abcd }
// NewFactory creates a factory with the default Kubernetes resources defined func NewFactory() *Factory { mapper := kubectl.ShortcutExpander{latest.RESTMapper} flags := pflag.NewFlagSet("", pflag.ContinueOnError) clientConfig := DefaultClientConfig(flags) clients := &clientCache{ clients: make(map[string]*client.Client), loader: clientConfig, } return &Factory{ clients: clients, flags: flags, Mapper: mapper, Typer: api.Scheme, Client: func(cmd *cobra.Command) (*client.Client, error) { return clients.ClientForVersion("") }, ClientConfig: func(cmd *cobra.Command) (*client.Config, error) { return clients.ClientConfigForVersion("") }, RESTClient: func(cmd *cobra.Command, mapping *meta.RESTMapping) (kubectl.RESTClient, error) { client, err := clients.ClientForVersion(mapping.APIVersion) if err != nil { return nil, err } return client.RESTClient, nil }, Describer: func(cmd *cobra.Command, mapping *meta.RESTMapping) (kubectl.Describer, error) { client, err := clients.ClientForVersion(mapping.APIVersion) if err != nil { return nil, err } describer, ok := kubectl.DescriberFor(mapping.Kind, client) if !ok { return nil, fmt.Errorf("no description has been implemented for %q", mapping.Kind) } return describer, nil }, Printer: func(cmd *cobra.Command, mapping *meta.RESTMapping, noHeaders bool) (kubectl.ResourcePrinter, error) { return kubectl.NewHumanReadablePrinter(noHeaders), nil }, Validator: func(cmd *cobra.Command) (validation.Schema, error) { if GetFlagBool(cmd, "validate") { client, err := clients.ClientForVersion("") if err != nil { return nil, err } return &clientSwaggerSchema{client, api.Scheme}, nil } return validation.NullSchema{}, nil }, } }
// NewFactory creates a factory with the default Kubernetes resources defined func NewFactory() *Factory { return &Factory{ Mapper: latest.RESTMapper, Typer: api.Scheme, Client: func(cmd *cobra.Command, mapping *meta.RESTMapping) (kubectl.RESTClient, error) { return getKubeClient(cmd), nil }, Describer: func(cmd *cobra.Command, mapping *meta.RESTMapping) (kubectl.Describer, error) { describer, ok := kubectl.DescriberFor(mapping.Kind, getKubeClient(cmd)) if !ok { return nil, fmt.Errorf("No description has been implemented for %q", mapping.Kind) } return describer, nil }, Printer: func(cmd *cobra.Command, mapping *meta.RESTMapping, noHeaders bool) (kubectl.ResourcePrinter, error) { return kubectl.NewHumanReadablePrinter(noHeaders), nil }, } }
// NewCmdGet creates a command object for the generic "get" action, which // retrieves one or more resources from a server. func NewCmdGet(f *cmdutil.Factory, out io.Writer) *cobra.Command { p := kubectl.NewHumanReadablePrinter(false) validArgs := p.HandledResources() cmd := &cobra.Command{ Use: "get [(-o|--output=)json|yaml|template|...] (RESOURCE [NAME] | RESOURCE/NAME ...)", Short: "Display one or many resources", Long: get_long, Example: get_example, Run: func(cmd *cobra.Command, args []string) { err := RunGet(f, out, cmd, args) cmdutil.CheckErr(err) }, ValidArgs: validArgs, } cmdutil.AddPrinterFlags(cmd) cmd.Flags().StringP("selector", "l", "", "Selector (label query) to filter on") cmd.Flags().BoolP("watch", "w", false, "After listing/getting the requested object, watch for changes.") cmd.Flags().Bool("watch-only", false, "Watch for changes to the requested object(s), without listing/getting first.") return cmd }
func ExamplePrintReplicationControllerWithNamespace() { f, tf, codec := NewAPIFactory() tf.Printer = kubectl.NewHumanReadablePrinter(false, true, false, []string{}) tf.Client = &client.FakeRESTClient{ Codec: codec, Client: nil, } cmd := NewCmdRun(f, os.Stdout) ctrl := &api.ReplicationController{ ObjectMeta: api.ObjectMeta{ Name: "foo", Namespace: "beep", Labels: map[string]string{"foo": "bar"}, }, Spec: api.ReplicationControllerSpec{ Replicas: 1, Selector: map[string]string{"foo": "bar"}, Template: &api.PodTemplateSpec{ ObjectMeta: api.ObjectMeta{ Labels: map[string]string{"foo": "bar"}, }, Spec: api.PodSpec{ Containers: []api.Container{ { Name: "foo", Image: "someimage", }, }, }, }, }, } err := f.PrintObject(cmd, ctrl, os.Stdout) if err != nil { fmt.Printf("Unexpected error: %v", err) } // Output: // NAMESPACE CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS // beep foo foo someimage foo=bar 1 }
// NewCmdGet creates a command object for the generic "get" action, which // retrieves one or more resources from a server. func NewCmdGet(f *cmdutil.Factory, out io.Writer) *cobra.Command { p := kubectl.NewHumanReadablePrinter(false, false, false, []string{}) validArgs := p.HandledResources() cmd := &cobra.Command{ Use: "get [(-o|--output=)json|yaml|template|wide|...] (RESOURCE [NAME] | RESOURCE/NAME ...)", Short: "Display one or many resources", Long: get_long, Example: get_example, Run: func(cmd *cobra.Command, args []string) { err := RunGet(f, out, cmd, args) cmdutil.CheckErr(err) }, ValidArgs: validArgs, } cmdutil.AddPrinterFlags(cmd) cmd.Flags().StringP("selector", "l", "", "Selector (label query) to filter on") cmd.Flags().BoolP("watch", "w", false, "After listing/getting the requested object, watch for changes.") cmd.Flags().Bool("watch-only", false, "Watch for changes to the requested object(s), without listing/getting first.") cmd.Flags().Bool("all-namespaces", false, "If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace.") kubectl.AddLabelsToColumnsFlag(cmd, &util.StringList{}, "Accepts a comma separated list of labels that are going to be presented as columns. Names are case-sensitive. You can also use multiple flag statements like -L label1 -L label2...") return cmd }
// NewFactory creates a factory with the default Kubernetes resources defined // if optionalClientConfig is nil, then flags will be bound to a new clientcmd.ClientConfig. // if optionalClientConfig is not nil, then this factory will make use of it. func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory { mapper := kubectl.ShortcutExpander{latest.RESTMapper} flags := pflag.NewFlagSet("", pflag.ContinueOnError) flags.SetNormalizeFunc(util.WarnWordSepNormalizeFunc) // Warn for "_" flags generators := map[string]kubectl.Generator{ "run/v1": kubectl.BasicReplicationController{}, "service/v1": kubectl.ServiceGenerator{}, } clientConfig := optionalClientConfig if optionalClientConfig == nil { clientConfig = DefaultClientConfig(flags) } clients := NewClientCache(clientConfig) return &Factory{ clients: clients, flags: flags, generators: generators, Object: func() (meta.RESTMapper, runtime.ObjectTyper) { cfg, err := clientConfig.ClientConfig() CheckErr(err) cmdApiVersion := cfg.Version return kubectl.OutputVersionMapper{mapper, cmdApiVersion}, api.Scheme }, Client: func() (*client.Client, error) { return clients.ClientForVersion("") }, ClientConfig: func() (*client.Config, error) { return clients.ClientConfigForVersion("") }, RESTClient: func(mapping *meta.RESTMapping) (resource.RESTClient, error) { client, err := clients.ClientForVersion(mapping.APIVersion) if err != nil { return nil, err } return client.RESTClient, nil }, Describer: func(mapping *meta.RESTMapping) (kubectl.Describer, error) { client, err := clients.ClientForVersion(mapping.APIVersion) if err != nil { return nil, err } describer, ok := kubectl.DescriberFor(mapping.Kind, client) if !ok { return nil, fmt.Errorf("no description has been implemented for %q", mapping.Kind) } return describer, nil }, Printer: func(mapping *meta.RESTMapping, noHeaders, withNamespace bool, wide bool, columnLabels []string) (kubectl.ResourcePrinter, error) { return kubectl.NewHumanReadablePrinter(noHeaders, withNamespace, wide, columnLabels), nil }, PodSelectorForObject: func(object runtime.Object) (string, error) { // TODO: replace with a swagger schema based approach (identify pod selector via schema introspection) switch t := object.(type) { case *api.ReplicationController: return kubectl.MakeLabels(t.Spec.Selector), nil case *api.Pod: if len(t.Labels) == 0 { return "", fmt.Errorf("the pod has no labels and cannot be exposed") } return kubectl.MakeLabels(t.Labels), nil case *api.Service: if t.Spec.Selector == nil { return "", fmt.Errorf("the service has no pod selector set") } return kubectl.MakeLabels(t.Spec.Selector), nil default: kind, err := meta.NewAccessor().Kind(object) if err != nil { return "", err } return "", fmt.Errorf("it is not possible to get a pod selector from %s", kind) } }, PortsForObject: func(object runtime.Object) ([]string, error) { // TODO: replace with a swagger schema based approach (identify pod selector via schema introspection) switch t := object.(type) { case *api.ReplicationController: return getPorts(t.Spec.Template.Spec), nil case *api.Pod: return getPorts(t.Spec), nil default: kind, err := meta.NewAccessor().Kind(object) if err != nil { return nil, err } return nil, fmt.Errorf("it is not possible to get ports from %s", kind) } }, LabelsForObject: func(object runtime.Object) (map[string]string, error) { return meta.NewAccessor().Labels(object) }, Scaler: func(mapping *meta.RESTMapping) (kubectl.Scaler, error) { client, err := clients.ClientForVersion(mapping.APIVersion) if err != nil { return nil, err } return kubectl.ScalerFor(mapping.Kind, kubectl.NewScalerClient(client)) }, Reaper: func(mapping *meta.RESTMapping) (kubectl.Reaper, error) { client, err := clients.ClientForVersion(mapping.APIVersion) if err != nil { return nil, err } return kubectl.ReaperFor(mapping.Kind, client) }, Validator: func() (validation.Schema, error) { if flags.Lookup("validate").Value.String() == "true" { client, err := clients.ClientForVersion("") if err != nil { return nil, err } return &clientSwaggerSchema{client, api.Scheme}, nil } return validation.NullSchema{}, nil }, DefaultNamespace: func() (string, error) { return clientConfig.Namespace() }, Generator: func(name string) (kubectl.Generator, bool) { generator, ok := generators[name] return generator, ok }, } }
func ExamplePrintServiceWithNamespacesAndLabels() { f, tf, codec := NewAPIFactory() tf.Printer = kubectl.NewHumanReadablePrinter(false, true, false, []string{"l1"}) tf.Client = &client.FakeRESTClient{ Codec: codec, Client: nil, } cmd := NewCmdRun(f, os.Stdout) svc := &api.ServiceList{ Items: []api.Service{ { ObjectMeta: api.ObjectMeta{ Name: "svc1", Namespace: "ns1", Labels: map[string]string{ "l1": "value", }, }, Spec: api.ServiceSpec{ Ports: []api.ServicePort{ {Protocol: "UDP", Port: 53}, {Protocol: "TCP", Port: 53}, }, Selector: map[string]string{ "s": "magic", }, ClusterIP: "10.1.1.1", }, Status: api.ServiceStatus{}, }, { ObjectMeta: api.ObjectMeta{ Name: "svc2", Namespace: "ns2", Labels: map[string]string{ "l1": "dolla-bill-yall", }, }, Spec: api.ServiceSpec{ Ports: []api.ServicePort{ {Protocol: "TCP", Port: 80}, {Protocol: "TCP", Port: 8080}, }, Selector: map[string]string{ "s": "kazam", }, ClusterIP: "10.1.1.2", }, Status: api.ServiceStatus{}, }}, } ld := util.NewLineDelimiter(os.Stdout, "|") defer ld.Flush() err := f.PrintObject(cmd, svc, ld) if err != nil { fmt.Printf("Unexpected error: %v", err) } // Output: // |NAMESPACE NAME LABELS SELECTOR IP(S) PORT(S) L1| // |ns1 svc1 l1=value s=magic 10.1.1.1 53/UDP value| // | 53/TCP | // |ns2 svc2 l1=dolla-bill-yall s=kazam 10.1.1.2 80/TCP dolla-bill-yall| // | 8080/TCP | // || }
// NewHumanReadablePrinter returns a new HumanReadablePrinter func NewHumanReadablePrinter(noHeaders, withNamespace, wide bool, columnLabels []string) *kctl.HumanReadablePrinter { // TODO: support cross namespace listing p := kctl.NewHumanReadablePrinter(noHeaders, withNamespace, wide, columnLabels) p.Handler(buildColumns, printBuild) p.Handler(buildColumns, printBuildList) p.Handler(buildConfigColumns, printBuildConfig) p.Handler(buildConfigColumns, printBuildConfigList) p.Handler(imageColumns, printImage) p.Handler(imageStreamTagColumns, printImageStreamTag) p.Handler(imageStreamImageColumns, printImageStreamImage) p.Handler(imageColumns, printImageList) p.Handler(imageStreamColumns, printImageStream) p.Handler(imageStreamColumns, printImageStreamList) p.Handler(projectColumns, printProject) p.Handler(projectColumns, printProjectList) p.Handler(routeColumns, printRoute) p.Handler(routeColumns, printRouteList) p.Handler(deploymentConfigColumns, printDeploymentConfig) p.Handler(deploymentConfigColumns, printDeploymentConfigList) p.Handler(templateColumns, printTemplate) p.Handler(templateColumns, printTemplateList) p.Handler(policyColumns, printPolicy) p.Handler(policyColumns, printPolicyList) p.Handler(policyBindingColumns, printPolicyBinding) p.Handler(policyBindingColumns, printPolicyBindingList) p.Handler(roleBindingColumns, printRoleBinding) p.Handler(roleBindingColumns, printRoleBindingList) p.Handler(roleColumns, printRole) p.Handler(roleColumns, printRoleList) p.Handler(policyColumns, printClusterPolicy) p.Handler(policyColumns, printClusterPolicyList) p.Handler(policyBindingColumns, printClusterPolicyBinding) p.Handler(policyBindingColumns, printClusterPolicyBindingList) p.Handler(roleColumns, printClusterRole) p.Handler(roleColumns, printClusterRoleList) p.Handler(roleBindingColumns, printClusterRoleBinding) p.Handler(roleBindingColumns, printClusterRoleBindingList) p.Handler(oauthClientColumns, printOAuthClient) p.Handler(oauthClientColumns, printOAuthClientList) p.Handler(oauthClientAuthorizationColumns, printOAuthClientAuthorization) p.Handler(oauthClientAuthorizationColumns, printOAuthClientAuthorizationList) p.Handler(oauthAccessTokenColumns, printOAuthAccessToken) p.Handler(oauthAccessTokenColumns, printOAuthAccessTokenList) p.Handler(oauthAuthorizeTokenColumns, printOAuthAuthorizeToken) p.Handler(oauthAuthorizeTokenColumns, printOAuthAuthorizeTokenList) p.Handler(userColumns, printUser) p.Handler(userColumns, printUserList) p.Handler(identityColumns, printIdentity) p.Handler(identityColumns, printIdentityList) p.Handler(userIdentityMappingColumns, printUserIdentityMapping) p.Handler(groupColumns, printGroup) p.Handler(groupColumns, printGroupList) p.Handler(IsPersonalSubjectAccessReviewColumns, printIsPersonalSubjectAccessReview) p.Handler(hostSubnetColumns, printHostSubnet) p.Handler(hostSubnetColumns, printHostSubnetList) p.Handler(clusterNetworkColumns, printClusterNetwork) p.Handler(clusterNetworkColumns, printClusterNetworkList) return p }
// NewFactory creates a factory with the default Kubernetes resources defined // if optionalClientConfig is nil, then flags will be bound to a new clientcmd.ClientConfig. // if optionalClientConfig is not nil, then this factory will make use of it. func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory { mapper := kubectl.ShortcutExpander{latest.RESTMapper} flags := pflag.NewFlagSet("", pflag.ContinueOnError) clientConfig := optionalClientConfig if optionalClientConfig == nil { clientConfig = DefaultClientConfig(flags) } clients := &clientCache{ clients: make(map[string]*client.Client), loader: clientConfig, } return &Factory{ clients: clients, flags: flags, Object: func() (meta.RESTMapper, runtime.ObjectTyper) { cfg, err := clientConfig.ClientConfig() cmdutil.CheckErr(err) cmdApiVersion := cfg.Version return kubectl.OutputVersionMapper{mapper, cmdApiVersion}, api.Scheme }, Client: func() (*client.Client, error) { return clients.ClientForVersion("") }, ClientConfig: func() (*client.Config, error) { return clients.ClientConfigForVersion("") }, RESTClient: func(mapping *meta.RESTMapping) (resource.RESTClient, error) { client, err := clients.ClientForVersion(mapping.APIVersion) if err != nil { return nil, err } return client.RESTClient, nil }, Describer: func(mapping *meta.RESTMapping) (kubectl.Describer, error) { client, err := clients.ClientForVersion(mapping.APIVersion) if err != nil { return nil, err } describer, ok := kubectl.DescriberFor(mapping.Kind, client) if !ok { return nil, fmt.Errorf("no description has been implemented for %q", mapping.Kind) } return describer, nil }, Printer: func(mapping *meta.RESTMapping, noHeaders bool) (kubectl.ResourcePrinter, error) { return kubectl.NewHumanReadablePrinter(noHeaders), nil }, Resizer: func(mapping *meta.RESTMapping) (kubectl.Resizer, error) { client, err := clients.ClientForVersion(mapping.APIVersion) if err != nil { return nil, err } return kubectl.ResizerFor(mapping.Kind, client) }, Reaper: func(mapping *meta.RESTMapping) (kubectl.Reaper, error) { client, err := clients.ClientForVersion(mapping.APIVersion) if err != nil { return nil, err } return kubectl.ReaperFor(mapping.Kind, client) }, Validator: func() (validation.Schema, error) { if flags.Lookup("validate").Value.String() == "true" { client, err := clients.ClientForVersion("") if err != nil { return nil, err } return &clientSwaggerSchema{client, api.Scheme}, nil } return validation.NullSchema{}, nil }, DefaultNamespace: func() (string, error) { return clientConfig.Namespace() }, } }
// NewFactory creates a factory with the default Kubernetes resources defined // if optionalClientConfig is nil, then flags will be bound to a new clientcmd.ClientConfig. // if optionalClientConfig is not nil, then this factory will make use of it. func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory { mapper := kubectl.ShortcutExpander{latest.RESTMapper} flags := pflag.NewFlagSet("", pflag.ContinueOnError) clientConfig := optionalClientConfig if optionalClientConfig == nil { clientConfig = DefaultClientConfig(flags) } clients := &clientCache{ clients: make(map[string]*client.Client), loader: clientConfig, } return &Factory{ clients: clients, flags: flags, Object: func() (meta.RESTMapper, runtime.ObjectTyper) { cfg, err := clientConfig.ClientConfig() CheckErr(err) cmdApiVersion := cfg.Version return kubectl.OutputVersionMapper{mapper, cmdApiVersion}, api.Scheme }, Client: func() (*client.Client, error) { return clients.ClientForVersion("") }, ClientConfig: func() (*client.Config, error) { return clients.ClientConfigForVersion("") }, RESTClient: func(mapping *meta.RESTMapping) (resource.RESTClient, error) { client, err := clients.ClientForVersion(mapping.APIVersion) if err != nil { return nil, err } return client.RESTClient, nil }, Describer: func(mapping *meta.RESTMapping) (kubectl.Describer, error) { client, err := clients.ClientForVersion(mapping.APIVersion) if err != nil { return nil, err } describer, ok := kubectl.DescriberFor(mapping.Kind, client) if !ok { return nil, fmt.Errorf("no description has been implemented for %q", mapping.Kind) } return describer, nil }, Printer: func(mapping *meta.RESTMapping, noHeaders bool) (kubectl.ResourcePrinter, error) { return kubectl.NewHumanReadablePrinter(noHeaders), nil }, PodSelectorForResource: func(mapping *meta.RESTMapping, namespace, name string) (string, error) { // TODO: replace with a swagger schema based approach (identify pod selector via schema introspection) client, err := clients.ClientForVersion("") if err != nil { return "", err } switch mapping.Kind { case "ReplicationController": rc, err := client.ReplicationControllers(namespace).Get(name) if err != nil { return "", err } return kubectl.MakeLabels(rc.Spec.Selector), nil case "Pod": rc, err := client.Pods(namespace).Get(name) if err != nil { return "", err } if len(rc.Labels) == 0 { return "", fmt.Errorf("the pod has no labels and cannot be exposed") } return kubectl.MakeLabels(rc.Labels), nil case "Service": rc, err := client.ReplicationControllers(namespace).Get(name) if err != nil { return "", err } if rc.Spec.Selector == nil { return "", fmt.Errorf("the service has no pod selector set") } return kubectl.MakeLabels(rc.Spec.Selector), nil default: return "", fmt.Errorf("it is not possible to get a pod selector from %s", mapping.Kind) } }, PortsForResource: func(mapping *meta.RESTMapping, namespace, name string) ([]string, error) { // TODO: replace with a swagger schema based approach (identify pod selector via schema introspection) client, err := clients.ClientForVersion("") if err != nil { return nil, err } switch mapping.Kind { case "ReplicationController": rc, err := client.ReplicationControllers(namespace).Get(name) if err != nil { return nil, err } return getPorts(rc.Spec.Template.Spec), nil case "Pod": pod, err := client.Pods(namespace).Get(name) if err != nil { return nil, err } return getPorts(pod.Spec), nil default: return nil, fmt.Errorf("it is not possible to get ports from %s", mapping.Kind) } }, Resizer: func(mapping *meta.RESTMapping) (kubectl.Resizer, error) { client, err := clients.ClientForVersion(mapping.APIVersion) if err != nil { return nil, err } return kubectl.ResizerFor(mapping.Kind, kubectl.NewResizerClient(client)) }, Reaper: func(mapping *meta.RESTMapping) (kubectl.Reaper, error) { client, err := clients.ClientForVersion(mapping.APIVersion) if err != nil { return nil, err } return kubectl.ReaperFor(mapping.Kind, client) }, Validator: func() (validation.Schema, error) { if flags.Lookup("validate").Value.String() == "true" { client, err := clients.ClientForVersion("") if err != nil { return nil, err } return &clientSwaggerSchema{client, api.Scheme}, nil } return validation.NullSchema{}, nil }, DefaultNamespace: func() (string, error) { return clientConfig.Namespace() }, } }