convert more command to use a generated clientset

This commit is contained in:
deads2k 2016-09-07 16:29:57 -04:00
parent fc30bf7e8b
commit 9d43f7e52c
14 changed files with 130 additions and 88 deletions

View File

@ -47,12 +47,12 @@ func RunApiVersions(f *cmdutil.Factory, w io.Writer) error {
printDeprecationWarning("api-versions", "apiversions") printDeprecationWarning("api-versions", "apiversions")
} }
client, err := f.Client() clientset, err := f.ClientSet()
if err != nil { if err != nil {
return err return err
} }
groupList, err := client.Discovery().ServerGroups() groupList, err := clientset.Discovery().ServerGroups()
if err != nil { if err != nil {
return fmt.Errorf("Couldn't get available api versions from server: %v\n", err) return fmt.Errorf("Couldn't get available api versions from server: %v\n", err)
} }

View File

@ -102,7 +102,7 @@ func TestPodAndContainerAttach(t *testing.T) {
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { return nil, nil }), Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { return nil, nil }),
} }
tf.Namespace = "test" tf.Namespace = "test"
tf.ClientConfig = &restclient.Config{} tf.ClientConfig = defaultClientConfig()
cmd := &cobra.Command{} cmd := &cobra.Command{}
options := test.p options := test.p

View File

@ -25,7 +25,6 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/client/unversioned"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
) )
@ -86,17 +85,17 @@ func setupOutputWriter(cmd *cobra.Command, defaultWriter io.Writer, filename str
} }
func dumpClusterInfo(f *cmdutil.Factory, cmd *cobra.Command, args []string, out io.Writer) error { func dumpClusterInfo(f *cmdutil.Factory, cmd *cobra.Command, args []string, out io.Writer) error {
var c *unversioned.Client clientset, err := f.ClientSet()
var err error if err != nil {
if c, err = f.Client(); err != nil {
return err return err
} }
printer, _, err := kubectl.GetPrinter("json", "", false) printer, _, err := kubectl.GetPrinter("json", "", false)
if err != nil { if err != nil {
return err return err
} }
nodes, err := c.Nodes().List(api.ListOptions{}) nodes, err := clientset.Core().Nodes().List(api.ListOptions{})
if err != nil { if err != nil {
return err return err
} }
@ -107,7 +106,7 @@ func dumpClusterInfo(f *cmdutil.Factory, cmd *cobra.Command, args []string, out
var namespaces []string var namespaces []string
if cmdutil.GetFlagBool(cmd, "all-namespaces") { if cmdutil.GetFlagBool(cmd, "all-namespaces") {
namespaceList, err := c.Namespaces().List(api.ListOptions{}) namespaceList, err := clientset.Core().Namespaces().List(api.ListOptions{})
if err != nil { if err != nil {
return err return err
} }
@ -130,7 +129,7 @@ func dumpClusterInfo(f *cmdutil.Factory, cmd *cobra.Command, args []string, out
for _, namespace := range namespaces { for _, namespace := range namespaces {
// TODO: this is repetitive in the extreme. Use reflection or // TODO: this is repetitive in the extreme. Use reflection or
// something to make this a for loop. // something to make this a for loop.
events, err := c.Events(namespace).List(api.ListOptions{}) events, err := clientset.Core().Events(namespace).List(api.ListOptions{})
if err != nil { if err != nil {
return err return err
} }
@ -138,7 +137,7 @@ func dumpClusterInfo(f *cmdutil.Factory, cmd *cobra.Command, args []string, out
return err return err
} }
rcs, err := c.ReplicationControllers(namespace).List(api.ListOptions{}) rcs, err := clientset.Core().ReplicationControllers(namespace).List(api.ListOptions{})
if err != nil { if err != nil {
return err return err
} }
@ -146,7 +145,7 @@ func dumpClusterInfo(f *cmdutil.Factory, cmd *cobra.Command, args []string, out
return err return err
} }
svcs, err := c.Services(namespace).List(api.ListOptions{}) svcs, err := clientset.Core().Services(namespace).List(api.ListOptions{})
if err != nil { if err != nil {
return err return err
} }
@ -154,7 +153,7 @@ func dumpClusterInfo(f *cmdutil.Factory, cmd *cobra.Command, args []string, out
return err return err
} }
sets, err := c.DaemonSets(namespace).List(api.ListOptions{}) sets, err := clientset.Extensions().DaemonSets(namespace).List(api.ListOptions{})
if err != nil { if err != nil {
return err return err
} }
@ -162,7 +161,7 @@ func dumpClusterInfo(f *cmdutil.Factory, cmd *cobra.Command, args []string, out
return err return err
} }
deps, err := c.Deployments(namespace).List(api.ListOptions{}) deps, err := clientset.Extensions().Deployments(namespace).List(api.ListOptions{})
if err != nil { if err != nil {
return err return err
} }
@ -170,7 +169,7 @@ func dumpClusterInfo(f *cmdutil.Factory, cmd *cobra.Command, args []string, out
return err return err
} }
rps, err := c.ReplicaSets(namespace).List(api.ListOptions{}) rps, err := clientset.Extensions().ReplicaSets(namespace).List(api.ListOptions{})
if err != nil { if err != nil {
return err return err
} }
@ -178,7 +177,7 @@ func dumpClusterInfo(f *cmdutil.Factory, cmd *cobra.Command, args []string, out
return err return err
} }
pods, err := c.Pods(namespace).List(api.ListOptions{}) pods, err := clientset.Core().Pods(namespace).List(api.ListOptions{})
if err != nil { if err != nil {
return err return err
} }

View File

@ -37,7 +37,6 @@ import (
"k8s.io/kubernetes/pkg/client/restclient" "k8s.io/kubernetes/pkg/client/restclient"
"k8s.io/kubernetes/pkg/client/typed/discovery" "k8s.io/kubernetes/pkg/client/typed/discovery"
client "k8s.io/kubernetes/pkg/client/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned"
clientset "k8s.io/kubernetes/pkg/client/unversioned/adapters/internalclientset"
"k8s.io/kubernetes/pkg/client/unversioned/fake" "k8s.io/kubernetes/pkg/client/unversioned/fake"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
@ -61,13 +60,26 @@ func defaultHeader() http.Header {
func defaultClientConfig() *restclient.Config { func defaultClientConfig() *restclient.Config {
return &restclient.Config{ return &restclient.Config{
APIPath: "/api",
ContentConfig: restclient.ContentConfig{ ContentConfig: restclient.ContentConfig{
NegotiatedSerializer: api.Codecs,
ContentType: runtime.ContentTypeJSON, ContentType: runtime.ContentTypeJSON,
GroupVersion: testapi.Default.GroupVersion(), GroupVersion: testapi.Default.GroupVersion(),
}, },
} }
} }
func defaultClientConfigForVersion(version *unversioned.GroupVersion) *restclient.Config {
return &restclient.Config{
APIPath: "/api",
ContentConfig: restclient.ContentConfig{
NegotiatedSerializer: api.Codecs,
ContentType: runtime.ContentTypeJSON,
GroupVersion: version,
},
}
}
type internalType struct { type internalType struct {
Kind string Kind string
APIVersion string APIVersion string
@ -298,11 +310,24 @@ func NewAPIFactory() (*cmdutil.Factory, *testFactory, runtime.Codec, runtime.Neg
return c, t.Err return c, t.Err
}, },
ClientSet: func() (*internalclientset.Clientset, error) { ClientSet: func() (*internalclientset.Clientset, error) {
// Swap out the HTTP client out of the client with the fake's version.
fakeClient := t.Client.(*fake.RESTClient) fakeClient := t.Client.(*fake.RESTClient)
c := client.NewOrDie(t.ClientConfig) restClient, err := restclient.RESTClientFor(t.ClientConfig)
c.Client = fakeClient.Client if err != nil {
c.ExtensionsClient.Client = fakeClient.Client panic(err)
return clientset.FromUnversionedClient(c), nil }
restClient.Client = fakeClient.Client
return internalclientset.New(restClient), t.Err
},
RESTClient: func() (*restclient.RESTClient, error) {
// Swap out the HTTP client out of the client with the fake's version.
fakeClient := t.Client.(*fake.RESTClient)
restClient, err := restclient.RESTClientFor(t.ClientConfig)
if err != nil {
panic(err)
}
restClient.Client = fakeClient.Client
return restClient, t.Err
}, },
ClientForMapping: func(*meta.RESTMapping) (resource.RESTClient, error) { ClientForMapping: func(*meta.RESTMapping) (resource.RESTClient, error) {
return t.Client, t.Err return t.Client, t.Err

View File

@ -28,7 +28,8 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/meta"
client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/client/restclient"
"k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/fields"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/resource" "k8s.io/kubernetes/pkg/kubectl/resource"
@ -37,7 +38,8 @@ import (
) )
type DrainOptions struct { type DrainOptions struct {
client *client.Client client *internalclientset.Clientset
restClient *restclient.RESTClient
factory *cmdutil.Factory factory *cmdutil.Factory
Force bool Force bool
GracePeriodSeconds int GracePeriodSeconds int
@ -177,7 +179,12 @@ func (o *DrainOptions) SetupDrain(cmd *cobra.Command, args []string) error {
return cmdutil.UsageError(cmd, fmt.Sprintf("USAGE: %s [flags]", cmd.Use)) return cmdutil.UsageError(cmd, fmt.Sprintf("USAGE: %s [flags]", cmd.Use))
} }
if o.client, err = o.factory.Client(); err != nil { if o.client, err = o.factory.ClientSet(); err != nil {
return err
}
o.restClient, err = o.factory.RESTClient()
if err != nil {
return err return err
} }
@ -227,13 +234,13 @@ func (o *DrainOptions) RunDrain() error {
func (o *DrainOptions) getController(sr *api.SerializedReference) (interface{}, error) { func (o *DrainOptions) getController(sr *api.SerializedReference) (interface{}, error) {
switch sr.Reference.Kind { switch sr.Reference.Kind {
case "ReplicationController": case "ReplicationController":
return o.client.ReplicationControllers(sr.Reference.Namespace).Get(sr.Reference.Name) return o.client.Core().ReplicationControllers(sr.Reference.Namespace).Get(sr.Reference.Name)
case "DaemonSet": case "DaemonSet":
return o.client.DaemonSets(sr.Reference.Namespace).Get(sr.Reference.Name) return o.client.Extensions().DaemonSets(sr.Reference.Namespace).Get(sr.Reference.Name)
case "Job": case "Job":
return o.client.ExtensionsClient.Jobs(sr.Reference.Namespace).Get(sr.Reference.Name) return o.client.Batch().Jobs(sr.Reference.Namespace).Get(sr.Reference.Name)
case "ReplicaSet": case "ReplicaSet":
return o.client.ExtensionsClient.ReplicaSets(sr.Reference.Namespace).Get(sr.Reference.Name) return o.client.Extensions().ReplicaSets(sr.Reference.Namespace).Get(sr.Reference.Name)
} }
return nil, fmt.Errorf("Unknown controller kind %q", sr.Reference.Kind) return nil, fmt.Errorf("Unknown controller kind %q", sr.Reference.Kind)
} }
@ -284,7 +291,7 @@ func (o *DrainOptions) daemonsetFilter(pod api.Pod) (bool, *warning, *fatal) {
if sr == nil || sr.Reference.Kind != "DaemonSet" { if sr == nil || sr.Reference.Kind != "DaemonSet" {
return true, nil, nil return true, nil, nil
} }
if _, err := o.client.DaemonSets(sr.Reference.Namespace).Get(sr.Reference.Name); err != nil { if _, err := o.client.Extensions().DaemonSets(sr.Reference.Namespace).Get(sr.Reference.Name); err != nil {
return false, nil, &fatal{err.Error()} return false, nil, &fatal{err.Error()}
} }
if !o.IgnoreDaemonsets { if !o.IgnoreDaemonsets {
@ -335,7 +342,7 @@ func (ps podStatuses) Message() string {
// getPodsForDeletion returns all the pods we're going to delete. If there are // getPodsForDeletion returns all the pods we're going to delete. If there are
// any pods preventing us from deleting, we return that list in an error. // any pods preventing us from deleting, we return that list in an error.
func (o *DrainOptions) getPodsForDeletion() (pods []api.Pod, err error) { func (o *DrainOptions) getPodsForDeletion() (pods []api.Pod, err error) {
podList, err := o.client.Pods(api.NamespaceAll).List(api.ListOptions{ podList, err := o.client.Core().Pods(api.NamespaceAll).List(api.ListOptions{
FieldSelector: fields.SelectorFromSet(fields.Set{"spec.nodeName": o.nodeInfo.Name})}) FieldSelector: fields.SelectorFromSet(fields.Set{"spec.nodeName": o.nodeInfo.Name})})
if err != nil { if err != nil {
return pods, err return pods, err
@ -380,7 +387,7 @@ func (o *DrainOptions) deletePods(pods []api.Pod) error {
} }
for _, pod := range pods { for _, pod := range pods {
err := o.client.Pods(pod.Namespace).Delete(pod.Name, &deleteOptions) err := o.client.Core().Pods(pod.Namespace).Delete(pod.Name, &deleteOptions)
if err != nil { if err != nil {
return err return err
} }
@ -403,7 +410,7 @@ func (o *DrainOptions) RunCordonOrUncordon(desired bool) error {
if unsched.Bool() == desired { if unsched.Bool() == desired {
cmdutil.PrintSuccess(o.mapper, false, o.out, o.nodeInfo.Mapping.Resource, o.nodeInfo.Name, already(desired)) cmdutil.PrintSuccess(o.mapper, false, o.out, o.nodeInfo.Mapping.Resource, o.nodeInfo.Name, already(desired))
} else { } else {
helper := resource.NewHelper(o.client, o.nodeInfo.Mapping) helper := resource.NewHelper(o.restClient, o.nodeInfo.Mapping)
unsched.SetBool(desired) unsched.SetBool(desired)
_, err := helper.Replace(cmdNamespace, o.nodeInfo.Name, true, o.nodeInfo.Object) _, err := helper.Replace(cmdNamespace, o.nodeInfo.Name, true, o.nodeInfo.Object)
if err != nil { if err != nil {

View File

@ -552,7 +552,10 @@ type MyReq struct {
func (m *MyReq) isFor(method string, path string) bool { func (m *MyReq) isFor(method string, path string) bool {
req := m.Request req := m.Request
return method == req.Method && (req.URL.Path == path || req.URL.Path == strings.Join([]string{"/api/v1", path}, "") || req.URL.Path == strings.Join([]string{"/apis/extensions/v1beta1", path}, "")) return method == req.Method && (req.URL.Path == path ||
req.URL.Path == strings.Join([]string{"/api/v1", path}, "") ||
req.URL.Path == strings.Join([]string{"/apis/extensions/v1beta1", path}, "") ||
req.URL.Path == strings.Join([]string{"/apis/batch/v1", path}, ""))
} }
func refJson(t *testing.T, o runtime.Object) string { func refJson(t *testing.T, o runtime.Object) string {

View File

@ -24,9 +24,10 @@ import (
dockerterm "github.com/docker/docker/pkg/term" dockerterm "github.com/docker/docker/pkg/term"
"github.com/renstrom/dedent" "github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/unversioned"
"k8s.io/kubernetes/pkg/client/restclient" "k8s.io/kubernetes/pkg/client/restclient"
client "k8s.io/kubernetes/pkg/client/unversioned"
"k8s.io/kubernetes/pkg/client/unversioned/remotecommand" "k8s.io/kubernetes/pkg/client/unversioned/remotecommand"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
remotecommandserver "k8s.io/kubernetes/pkg/kubelet/server/remotecommand" remotecommandserver "k8s.io/kubernetes/pkg/kubelet/server/remotecommand"
@ -132,7 +133,7 @@ type ExecOptions struct {
FullCmdName string FullCmdName string
Executor RemoteExecutor Executor RemoteExecutor
Client *client.Client PodClient coreclient.PodsGetter
Config *restclient.Config Config *restclient.Config
} }
@ -172,11 +173,11 @@ func (p *ExecOptions) Complete(f *cmdutil.Factory, cmd *cobra.Command, argsIn []
} }
p.Config = config p.Config = config
client, err := f.Client() clientset, err := f.ClientSet()
if err != nil { if err != nil {
return err return err
} }
p.Client = client p.PodClient = clientset.Core()
return nil return nil
} }
@ -192,7 +193,7 @@ func (p *ExecOptions) Validate() error {
if p.Out == nil || p.Err == nil { if p.Out == nil || p.Err == nil {
return fmt.Errorf("both output and error output must be provided") return fmt.Errorf("both output and error output must be provided")
} }
if p.Executor == nil || p.Client == nil || p.Config == nil { if p.Executor == nil || p.PodClient == nil || p.Config == nil {
return fmt.Errorf("client, client config, and executor must be provided") return fmt.Errorf("client, client config, and executor must be provided")
} }
return nil return nil
@ -252,7 +253,7 @@ func (o *StreamOptions) setupTTY() term.TTY {
// Run executes a validated remote execution against a pod. // Run executes a validated remote execution against a pod.
func (p *ExecOptions) Run() error { func (p *ExecOptions) Run() error {
pod, err := p.Client.Pods(p.Namespace).Get(p.PodName) pod, err := p.PodClient.Pods(p.Namespace).Get(p.PodName)
if err != nil { if err != nil {
return err return err
} }
@ -283,8 +284,13 @@ func (p *ExecOptions) Run() error {
} }
fn := func() error { fn := func() error {
restClient, err := restclient.RESTClientFor(p.Config)
if err != nil {
return err
}
// TODO: consider abstracting into a client invocation or client helper // TODO: consider abstracting into a client invocation or client helper
req := p.Client.RESTClient.Post(). req := restClient.Post().
Resource("pods"). Resource("pods").
Name(pod.Name). Name(pod.Name).
Namespace(pod.Namespace). Namespace(pod.Namespace).

View File

@ -31,7 +31,6 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/client/restclient" "k8s.io/kubernetes/pkg/client/restclient"
"k8s.io/kubernetes/pkg/client/unversioned/fake" "k8s.io/kubernetes/pkg/client/unversioned/fake"
"k8s.io/kubernetes/pkg/util/term" "k8s.io/kubernetes/pkg/util/term"
@ -133,7 +132,7 @@ func TestPodAndContainer(t *testing.T) {
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { return nil, nil }), Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { return nil, nil }),
} }
tf.Namespace = "test" tf.Namespace = "test"
tf.ClientConfig = &restclient.Config{} tf.ClientConfig = defaultClientConfig()
cmd := &cobra.Command{} cmd := &cobra.Command{}
options := test.p options := test.p
@ -162,20 +161,18 @@ func TestPodAndContainer(t *testing.T) {
func TestExec(t *testing.T) { func TestExec(t *testing.T) {
version := testapi.Default.GroupVersion().Version version := testapi.Default.GroupVersion().Version
tests := []struct { tests := []struct {
name, version, podPath, execPath, container string name, podPath, execPath, container string
pod *api.Pod pod *api.Pod
execErr bool execErr bool
}{ }{
{ {
name: "pod exec", name: "pod exec",
version: version,
podPath: "/api/" + version + "/namespaces/test/pods/foo", podPath: "/api/" + version + "/namespaces/test/pods/foo",
execPath: "/api/" + version + "/namespaces/test/pods/foo/exec", execPath: "/api/" + version + "/namespaces/test/pods/foo/exec",
pod: execPod(), pod: execPod(),
}, },
{ {
name: "pod exec error", name: "pod exec error",
version: version,
podPath: "/api/" + version + "/namespaces/test/pods/foo", podPath: "/api/" + version + "/namespaces/test/pods/foo",
execPath: "/api/" + version + "/namespaces/test/pods/foo/exec", execPath: "/api/" + version + "/namespaces/test/pods/foo/exec",
pod: execPod(), pod: execPod(),
@ -199,7 +196,7 @@ func TestExec(t *testing.T) {
}), }),
} }
tf.Namespace = "test" tf.Namespace = "test"
tf.ClientConfig = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &unversioned.GroupVersion{Version: test.version}}} tf.ClientConfig = defaultClientConfig()
bufOut := bytes.NewBuffer([]byte{}) bufOut := bytes.NewBuffer([]byte{})
bufErr := bytes.NewBuffer([]byte{}) bufErr := bytes.NewBuffer([]byte{})
bufIn := bytes.NewBuffer([]byte{}) bufIn := bytes.NewBuffer([]byte{})

View File

@ -22,6 +22,7 @@ import (
"github.com/renstrom/dedent" "github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
@ -126,12 +127,12 @@ func NewCmdGet(f *cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Comma
// TODO: convert all direct flag accessors to a struct and pass that instead of cmd // TODO: convert all direct flag accessors to a struct and pass that instead of cmd
func RunGet(f *cmdutil.Factory, out io.Writer, errOut io.Writer, cmd *cobra.Command, args []string, options *GetOptions) error { func RunGet(f *cmdutil.Factory, out io.Writer, errOut io.Writer, cmd *cobra.Command, args []string, options *GetOptions) error {
if len(options.Raw) > 0 { if len(options.Raw) > 0 {
client, err := f.Client() restClient, err := f.RESTClient()
if err != nil { if err != nil {
return err return err
} }
stream, err := client.RESTClient.Get().RequestURI(options.Raw).Stream() stream, err := restClient.Get().RequestURI(options.Raw).Stream()
if err != nil { if err != nil {
return err return err
} }

View File

@ -25,9 +25,10 @@ import (
"github.com/renstrom/dedent" "github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/unversioned"
"k8s.io/kubernetes/pkg/client/restclient" "k8s.io/kubernetes/pkg/client/restclient"
client "k8s.io/kubernetes/pkg/client/unversioned"
"k8s.io/kubernetes/pkg/client/unversioned/portforward" "k8s.io/kubernetes/pkg/client/unversioned/portforward"
"k8s.io/kubernetes/pkg/client/unversioned/remotecommand" "k8s.io/kubernetes/pkg/client/unversioned/remotecommand"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
@ -37,8 +38,9 @@ import (
type PortForwardOptions struct { type PortForwardOptions struct {
Namespace string Namespace string
PodName string PodName string
RESTClient *restclient.RESTClient
Config *restclient.Config Config *restclient.Config
Client *client.Client PodClient coreclient.PodsGetter
Ports []string Ports []string
PortForwarder portForwarder PortForwarder portForwarder
StopChannel chan struct{} StopChannel chan struct{}
@ -130,15 +132,20 @@ func (o *PortForwardOptions) Complete(f *cmdutil.Factory, cmd *cobra.Command, ar
return err return err
} }
o.Client, err = f.Client() clientset, err := f.ClientSet()
if err != nil { if err != nil {
return err return err
} }
o.PodClient = clientset.Core()
o.Config, err = f.ClientConfig() o.Config, err = f.ClientConfig()
if err != nil { if err != nil {
return err return err
} }
o.RESTClient, err = f.RESTClient()
if err != nil {
return err
}
o.StopChannel = make(chan struct{}, 1) o.StopChannel = make(chan struct{}, 1)
o.ReadyChannel = make(chan struct{}) o.ReadyChannel = make(chan struct{})
@ -155,15 +162,15 @@ func (o PortForwardOptions) Validate() error {
return fmt.Errorf("at least 1 PORT is required for port-forward") return fmt.Errorf("at least 1 PORT is required for port-forward")
} }
if o.PortForwarder == nil || o.Client == nil || o.Config == nil { if o.PortForwarder == nil || o.PodClient == nil || o.RESTClient == nil || o.Config == nil {
return fmt.Errorf("client, client config, and portforwarder must be provided") return fmt.Errorf("client, client config, restClient, and portforwarder must be provided")
} }
return nil return nil
} }
// RunPortForward implements all the necessary functionality for port-forward cmd. // RunPortForward implements all the necessary functionality for port-forward cmd.
func (o PortForwardOptions) RunPortForward() error { func (o PortForwardOptions) RunPortForward() error {
pod, err := o.Client.Pods(o.Namespace).Get(o.PodName) pod, err := o.PodClient.Pods(o.Namespace).Get(o.PodName)
if err != nil { if err != nil {
return err return err
} }
@ -183,7 +190,7 @@ func (o PortForwardOptions) RunPortForward() error {
} }
}() }()
req := o.Client.RESTClient.Post(). req := o.RESTClient.Post().
Resource("pods"). Resource("pods").
Namespace(o.Namespace). Namespace(o.Namespace).
Name(pod.Name). Name(pod.Name).

View File

@ -27,8 +27,6 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/client/restclient"
"k8s.io/kubernetes/pkg/client/unversioned/fake" "k8s.io/kubernetes/pkg/client/unversioned/fake"
) )
@ -48,20 +46,19 @@ func TestPortForward(t *testing.T) {
version := testapi.Default.GroupVersion().Version version := testapi.Default.GroupVersion().Version
tests := []struct { tests := []struct {
name, version, podPath, pfPath, container string name string
podPath, pfPath, container string
pod *api.Pod pod *api.Pod
pfErr bool pfErr bool
}{ }{
{ {
name: "pod portforward", name: "pod portforward",
version: version,
podPath: "/api/" + version + "/namespaces/test/pods/foo", podPath: "/api/" + version + "/namespaces/test/pods/foo",
pfPath: "/api/" + version + "/namespaces/test/pods/foo/portforward", pfPath: "/api/" + version + "/namespaces/test/pods/foo/portforward",
pod: execPod(), pod: execPod(),
}, },
{ {
name: "pod portforward error", name: "pod portforward error",
version: version,
podPath: "/api/" + version + "/namespaces/test/pods/foo", podPath: "/api/" + version + "/namespaces/test/pods/foo",
pfPath: "/api/" + version + "/namespaces/test/pods/foo/portforward", pfPath: "/api/" + version + "/namespaces/test/pods/foo/portforward",
pod: execPod(), pod: execPod(),
@ -86,7 +83,7 @@ func TestPortForward(t *testing.T) {
}), }),
} }
tf.Namespace = "test" tf.Namespace = "test"
tf.ClientConfig = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &unversioned.GroupVersion{Version: test.version}}} tf.ClientConfig = defaultClientConfig()
ff := &fakePortForwarder{} ff := &fakePortForwarder{}
if test.pfErr { if test.pfErr {
ff.pfErr = fmt.Errorf("pf error") ff.pfErr = fmt.Errorf("pf error")
@ -130,20 +127,18 @@ func TestPortForwardWithPFlag(t *testing.T) {
version := testapi.Default.GroupVersion().Version version := testapi.Default.GroupVersion().Version
tests := []struct { tests := []struct {
name, version, podPath, pfPath, container string name, podPath, pfPath, container string
pod *api.Pod pod *api.Pod
pfErr bool pfErr bool
}{ }{
{ {
name: "pod portforward", name: "pod portforward",
version: version,
podPath: "/api/" + version + "/namespaces/test/pods/foo", podPath: "/api/" + version + "/namespaces/test/pods/foo",
pfPath: "/api/" + version + "/namespaces/test/pods/foo/portforward", pfPath: "/api/" + version + "/namespaces/test/pods/foo/portforward",
pod: execPod(), pod: execPod(),
}, },
{ {
name: "pod portforward error", name: "pod portforward error",
version: version,
podPath: "/api/" + version + "/namespaces/test/pods/foo", podPath: "/api/" + version + "/namespaces/test/pods/foo",
pfPath: "/api/" + version + "/namespaces/test/pods/foo/portforward", pfPath: "/api/" + version + "/namespaces/test/pods/foo/portforward",
pod: execPod(), pod: execPod(),
@ -168,7 +163,7 @@ func TestPortForwardWithPFlag(t *testing.T) {
}), }),
} }
tf.Namespace = "test" tf.Namespace = "test"
tf.ClientConfig = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &unversioned.GroupVersion{Version: test.version}}} tf.ClientConfig = defaultClientConfig()
ff := &fakePortForwarder{} ff := &fakePortForwarder{}
if test.pfErr { if test.pfErr {
ff.pfErr = fmt.Errorf("pf error") ff.pfErr = fmt.Errorf("pf error")

View File

@ -101,6 +101,8 @@ type Factory struct {
Client func() (*client.Client, error) Client func() (*client.Client, error)
// ClientSet gives you back an internal, generated clientset // ClientSet gives you back an internal, generated clientset
ClientSet func() (*internalclientset.Clientset, error) ClientSet func() (*internalclientset.Clientset, error)
// Returns a RESTClient for accessing Kubernetes resources or an error.
RESTClient func() (*restclient.RESTClient, error)
// Returns a client.Config for accessing the Kubernetes server. // Returns a client.Config for accessing the Kubernetes server.
ClientConfig func() (*restclient.Config, error) ClientConfig func() (*restclient.Config, error)
// Returns a RESTClient for working with the specified RESTMapping or an error. This is intended // Returns a RESTClient for working with the specified RESTMapping or an error. This is intended
@ -421,7 +423,13 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
Client: func() (*client.Client, error) { Client: func() (*client.Client, error) {
return clients.ClientForVersion(nil) return clients.ClientForVersion(nil)
}, },
RESTClient: func() (*restclient.RESTClient, error) {
clientConfig, err := clients.ClientConfigForVersion(nil)
if err != nil {
return nil, err
}
return restclient.RESTClientFor(clientConfig)
},
ClientSet: func() (*internalclientset.Clientset, error) { ClientSet: func() (*internalclientset.Clientset, error) {
cfg, err := clients.ClientConfigForVersion(nil) cfg, err := clients.ClientConfigForVersion(nil)
if err != nil { if err != nil {

View File

@ -17,6 +17,7 @@ limitations under the License.
package cmd package cmd
import ( import (
"fmt"
"io" "io"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -45,11 +46,16 @@ func RunVersion(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command) error {
return nil return nil
} }
client, err := f.Client() clientset, err := f.ClientSet()
if err != nil { if err != nil {
return err return err
} }
kubectl.GetServerVersion(out, client) serverVersion, err := clientset.Discovery().ServerVersion()
if err != nil {
return err
}
fmt.Fprintf(out, "Server Version: %#v\n", *serverVersion)
return nil return nil
} }

View File

@ -19,22 +19,10 @@ package kubectl
import ( import (
"fmt" "fmt"
"io" "io"
"os"
client "k8s.io/kubernetes/pkg/client/unversioned"
"k8s.io/kubernetes/pkg/version" "k8s.io/kubernetes/pkg/version"
) )
func GetServerVersion(w io.Writer, kubeClient client.Interface) {
serverVersion, err := kubeClient.Discovery().ServerVersion()
if err != nil {
fmt.Printf("Couldn't read server version from server: %v\n", err)
os.Exit(1)
}
fmt.Fprintf(w, "Server Version: %#v\n", *serverVersion)
}
func GetClientVersion(w io.Writer) { func GetClientVersion(w io.Writer) {
fmt.Fprintf(w, "Client Version: %#v\n", version.Get()) fmt.Fprintf(w, "Client Version: %#v\n", version.Get())
} }