Change:
This seems like a bug to me No output, and command exits success... wat. Have to explicitly pass to see expected output. If the client version is greater the server version, it should be making requests based on the server's newest accepted apiversion.
cc

Discussion:
"time" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest" <ins> "github.com/GoogleCloudPlatform/kubernetes/pkg/api/registered" </ins> "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" <ins> "github.com/GoogleCloudPlatform/kubernetes/pkg/util" </ins> "github.com/GoogleCloudPlatform/kubernetes/pkg/version" <ins> "github.com/golang/glog" </ins> ) // Config holds the common attributes that can be passed to a Kubernetes client on

return &Client{client}, nil } <ins> // MatchesServerVersion queries the server to compares the build version // (git hash) of the client with the server's build version. It returns an error // if it failed to contact the server or if the versions are not an exact match. </ins> func MatchesServerVersion(c *Config) error { client, err := New(c) if err != nil {

return nil } <ins> // NegotiateVersion queries the server's supported api versions to find // a version that both client and server support. // - If no version is provided, try the client's registered versions in order of //   preference. // - If version is provided, but not default config (explicitly requested via //   commandline flag), and is unsupported by the server, print a warning to //   stderr and try client's registered versions in order of preference. // - If version is config default, and the server does not support it, //   return an error. func NegotiateVersion(c *Config, version string) (string, error) { client, err := New(c) if err != nil { return "", err } clientVersions := util.StringSet{} for _, v := range registered.RegisteredVersions { clientVersions.Insert(v) } apiVersions, err := client.ServerAPIVersions() if err != nil { return "", fmt.Errorf("couldn't read version from server: %vn", err) } serverVersions := util.StringSet{} for _, v := range apiVersions.Versions { serverVersions.Insert(v) } // If no version requested, use config version (may also be empty). if len(version) == 0 { version = c.Version } // If version explicitly requested verify that both client and server support it. // If server does not support warn, but try to negotiate a lower version. if len(version) != 0 { if !clientVersions.Has(version) { return "", fmt.Errorf("Client does not support API version '%s'. Client supported API versions: %v", version, clientVersions) } if serverVersions.Has(version) { return version, nil } // If we are using an explicit config version the server does not support, fail. if version == c.Version { return "", fmt.Errorf("Server does not support API version '%s'.", version) } } for _, clientVersion := range registered.RegisteredVersions { if serverVersions.Has(clientVersion) { // Version was not explicitly requested in command config (--api-version). // Ok to fall back to a supported version with a warning. if len(version) != 0 { glog.Warningf("Server does not support API version '%s'. Falling back to '%s'.", version, clientVersion) } return clientVersion, nil } } return "", fmt.Errorf("Failed to negotiate an api version. Server supports: %v. Client supports: %v.", serverVersions, registered.RegisteredVersions) } </ins> // NewOrDie creates a Kubernetes client and panics if the provided API version is not recognized. func NewOrDie(c *Config) *Client { client, err := New(c)

return ioutil.NopCloser(bytes.NewReader([]byte(body))) } <ins> // TODO(jlowdermilk): refactor the Factory so we can test client versions properly, // with different client/server version skew scenarios. </ins> // Verify that resource.RESTClients constructed from a factory respect mapping.APIVersion <del> func TestClientVersions(t *testing.T) { f := cmdutil.NewFactory(nil) version := testapi.Version() mapping := &meta.RESTMapping{ APIVersion: version, } c, err := f.RESTClient(mapping) if err != nil { t.Errorf("unexpected error: %v", err) } client := c.(*client.RESTClient) if client.APIVersion() != version { t.Errorf("unexpected Client APIVersion: %s %v", client.APIVersion, client) } } </del> <ins> //func TestClientVersions(t *testing.T) { //	f := cmdutil.NewFactory(nil) // //	version := testapi.Version() //	mapping := &meta.RESTMapping{ //		APIVersion: version, //	} //	c, err := f.RESTClient(mapping) //	if err != nil { //		t.Errorf("unexpected error: %v", err) //	} //	client := c.(*client.RESTClient) //	if client.APIVersion() != version { //		t.Errorf("unexpected Client APIVersion: %s %v", client.APIVersion, client) //	} //} </ins> func ExamplePrintReplicationController() { f, tf, codec := NewAPIFactory()

"github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd" ) <ins> func NewClientCache(loader clientcmd.ClientConfig) *clientCache { return &clientCache{ clients: make(map[string]*client.Client), configs: make(map[string]*client.Config), loader:  loader, } } </ins> // clientCache caches previously loaded clients for reuse, and ensures MatchServerVersion // is invoked only once type clientCache struct { loader        clientcmd.ClientConfig clients       map[string]*client.Client <ins> configs       map[string]*client.Config </ins> defaultConfig *client.Config matchVersion  bool }

} } } <ins> if config, ok := c.configs[version]; ok { return config, nil } </ins> // TODO: have a better config copy method config := *c.defaultConfig <del> if len(version) != 0 { config.Version = version </del> <ins> negotiatedVersion, err := client.NegotiateVersion(&config, version) if err != nil { return nil, err </ins> } <ins> config.Version = negotiatedVersion </ins> client.SetKubernetesDefaults(&config) <ins> c.configs[version] = &config </ins> return &config, nil }

// ClientForVersion initializes or reuses a client for the specified version, or returns an // error if that is not possible func (c *clientCache) ClientForVersion(version string) (*client.Client, error) { <ins> if client, ok := c.clients[version]; ok { return client, nil } </ins> config, err := c.ClientConfigForVersion(version) if err != nil { return nil, err } <del> if client, ok := c.clients[config.Version]; ok { return client, nil } </del> client, err := client.New(config) if err != nil { return nil, err

clientConfig = DefaultClientConfig(flags) } <del> clients := &clientCache{ clients: make(map[string]*client.Client), loader:  clientConfig, } </del> <ins> clients := NewClientCache(clientConfig) </ins> return &Factory{ clients:    clients,