Merge pull request #9762 from jlowdermilk/negotiate-api-version
kubectl negotiates api version to use based on client,server supported versions
This commit is contained in:
@@ -30,8 +30,11 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/registered"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/version"
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
// Config holds the common attributes that can be passed to a Kubernetes client on
|
||||
@@ -138,6 +141,9 @@ func New(c *Config) (*Client, error) {
|
||||
return &Client{client}, nil
|
||||
}
|
||||
|
||||
// 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.
|
||||
func MatchesServerVersion(c *Config) error {
|
||||
client, err := New(c)
|
||||
if err != nil {
|
||||
@@ -156,6 +162,66 @@ func MatchesServerVersion(c *Config) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 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: %v\n", 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)
|
||||
}
|
||||
|
||||
// NewOrDie creates a Kubernetes client and panics if the provided API version is not recognized.
|
||||
func NewOrDie(c *Config) *Client {
|
||||
client, err := New(c)
|
||||
|
Reference in New Issue
Block a user