From 81ae13084d751f17b07189707ff74550f67c96c1 Mon Sep 17 00:00:00 2001 From: deads2k Date: Mon, 24 Oct 2016 10:58:05 -0400 Subject: [PATCH] handle non-generated client removal --- docs/proposals/api-group.md | 2 +- pkg/client/typed/discovery/BUILD | 19 ++ pkg/client/typed/discovery/helper.go | 135 +++++++++ .../discovery}/helper_blackbox_test.go | 10 +- pkg/client/unversioned/BUILD | 138 +-------- pkg/client/unversioned/conditions.go | 9 +- pkg/client/unversioned/helper.go | 265 ------------------ .../unversioned/testclient/simple/BUILD | 1 - pkg/kubectl/cmd/logs_test.go | 2 +- pkg/kubectl/cmd/testing/BUILD | 1 - pkg/kubectl/cmd/testing/fake.go | 10 +- pkg/kubectl/cmd/util/clientcache.go | 14 +- pkg/kubectl/describe.go | 7 +- pkg/kubectl/stop.go | 3 +- test/e2e/framework/util.go | 16 -- 15 files changed, 185 insertions(+), 447 deletions(-) create mode 100644 pkg/client/typed/discovery/helper.go rename pkg/client/{unversioned => typed/discovery}/helper_blackbox_test.go (95%) diff --git a/docs/proposals/api-group.md b/docs/proposals/api-group.md index e3f79764e43..1e039ac253b 100644 --- a/docs/proposals/api-group.md +++ b/docs/proposals/api-group.md @@ -117,7 +117,7 @@ Documentation for other releases can be found at 1. clients: - Currently we have structured (pkg/client/unversioned#ExperimentalClient, pkg/client/unversioned#Client) and unstructured (pkg/kubectl/resource#Helper) clients. The structured clients are not scalable because each of them implements specific interface, e.g., [here](../../pkg/client/unversioned/client.go#L32). Only the unstructured clients are scalable. We should either auto-generate the code for structured clients or migrate to use the unstructured clients as much as possible. + Currently we have structured (pkg/client/unversioned#ExperimentalClient, pkg/client/unversioned#Client) and unstructured (pkg/kubectl/resource#Helper) clients. The structured clients are not scalable because each of them implements specific interface, e.g., `[here]../../pkg/client/unversioned/client.go#L32`--fixed. Only the unstructured clients are scalable. We should either auto-generate the code for structured clients or migrate to use the unstructured clients as much as possible. We should also move the unstructured client to pkg/client/. diff --git a/pkg/client/typed/discovery/BUILD b/pkg/client/typed/discovery/BUILD index 70f6773f1bb..d6a7498b468 100644 --- a/pkg/client/typed/discovery/BUILD +++ b/pkg/client/typed/discovery/BUILD @@ -14,6 +14,7 @@ go_library( name = "go_default_library", srcs = [ "discovery_client.go", + "helper.go", "restmapper.go", "unstructured.go", ], @@ -27,7 +28,9 @@ go_library( "//pkg/client/restclient:go_default_library", "//pkg/runtime:go_default_library", "//pkg/runtime/serializer:go_default_library", + "//pkg/util/sets:go_default_library", "//pkg/version:go_default_library", + "//plugin/pkg/client/auth:go_default_library", "//vendor:github.com/emicklei/go-restful/swagger", ], ) @@ -48,3 +51,19 @@ go_test( "//vendor:github.com/emicklei/go-restful/swagger", ], ) + +go_test( + name = "go_default_xtest", + srcs = ["helper_blackbox_test.go"], + tags = ["automanaged"], + deps = [ + "//pkg/api:go_default_library", + "//pkg/api/testapi:go_default_library", + "//pkg/api/unversioned:go_default_library", + "//pkg/apimachinery/registered:go_default_library", + "//pkg/client/restclient:go_default_library", + "//pkg/client/typed/discovery:go_default_library", + "//pkg/client/unversioned/fake:go_default_library", + "//pkg/runtime:go_default_library", + ], +) diff --git a/pkg/client/typed/discovery/helper.go b/pkg/client/typed/discovery/helper.go new file mode 100644 index 00000000000..81efc6171d7 --- /dev/null +++ b/pkg/client/typed/discovery/helper.go @@ -0,0 +1,135 @@ +/* +Copyright 2016 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package discovery + +import ( + "fmt" + + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/client/restclient" + "k8s.io/kubernetes/pkg/util/sets" + "k8s.io/kubernetes/pkg/version" + // Import solely to initialize client auth plugins. + _ "k8s.io/kubernetes/plugin/pkg/client/auth" +) + +// 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(client DiscoveryInterface, c *restclient.Config) error { + var err error + if client == nil { + client, err = NewDiscoveryClientForConfig(c) + if err != nil { + return err + } + } + cVer := version.Get() + sVer, err := client.ServerVersion() + if err != nil { + return fmt.Errorf("couldn't read version from server: %v\n", err) + } + // GitVersion includes GitCommit and GitTreeState, but best to be safe? + if cVer.GitVersion != sVer.GitVersion || cVer.GitCommit != sVer.GitCommit || cVer.GitTreeState != sVer.GitTreeState { + return fmt.Errorf("server version (%#v) differs from client version (%#v)!\n", sVer, cVer) + } + + 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 registered client 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(client DiscoveryInterface, c *restclient.Config, requestedGV *unversioned.GroupVersion, clientRegisteredGVs []unversioned.GroupVersion) (*unversioned.GroupVersion, error) { + var err error + if client == nil { + client, err = NewDiscoveryClientForConfig(c) + if err != nil { + return nil, err + } + } + clientVersions := sets.String{} + for _, gv := range clientRegisteredGVs { + clientVersions.Insert(gv.String()) + } + groups, err := client.ServerGroups() + if err != nil { + // This is almost always a connection error, and higher level code should treat this as a generic error, + // not a negotiation specific error. + return nil, err + } + versions := unversioned.ExtractGroupVersions(groups) + serverVersions := sets.String{} + for _, v := range versions { + serverVersions.Insert(v) + } + + // If no version requested, use config version (may also be empty). + // make a copy of the original so we don't risk mutating input here or in the returned value + var preferredGV *unversioned.GroupVersion + switch { + case requestedGV != nil: + t := *requestedGV + preferredGV = &t + case c.GroupVersion != nil: + t := *c.GroupVersion + preferredGV = &t + } + + // 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 preferredGV != nil { + if !clientVersions.Has(preferredGV.String()) { + return nil, fmt.Errorf("client does not support API version %q; client supported API versions: %v", preferredGV, clientVersions) + + } + // If the server supports no versions, then we should just use the preferredGV + // This can happen because discovery fails due to 403 Forbidden errors + if len(serverVersions) == 0 { + return preferredGV, nil + } + if serverVersions.Has(preferredGV.String()) { + return preferredGV, nil + } + // If we are using an explicit config version the server does not support, fail. + if (c.GroupVersion != nil) && (*preferredGV == *c.GroupVersion) { + return nil, fmt.Errorf("server does not support API version %q", preferredGV) + } + } + + for _, clientGV := range clientRegisteredGVs { + if serverVersions.Has(clientGV.String()) { + // Version was not explicitly requested in command config (--api-version). + // Ok to fall back to a supported version with a warning. + // TODO: caesarxuchao: enable the warning message when we have + // proper fix. Please refer to issue #14895. + // if len(version) != 0 { + // glog.Warningf("Server does not support API version '%s'. Falling back to '%s'.", version, clientVersion) + // } + t := clientGV + return &t, nil + } + } + return nil, fmt.Errorf("failed to negotiate an api version; server supports: %v, client supports: %v", + serverVersions, clientVersions) +} diff --git a/pkg/client/unversioned/helper_blackbox_test.go b/pkg/client/typed/discovery/helper_blackbox_test.go similarity index 95% rename from pkg/client/unversioned/helper_blackbox_test.go rename to pkg/client/typed/discovery/helper_blackbox_test.go index 297e41c614f..bf0ee99663a 100644 --- a/pkg/client/unversioned/helper_blackbox_test.go +++ b/pkg/client/typed/discovery/helper_blackbox_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package unversioned_test +package discovery_test import ( "bytes" @@ -31,7 +31,7 @@ import ( uapi "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/apimachinery/registered" "k8s.io/kubernetes/pkg/client/restclient" - "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/client/typed/discovery" "k8s.io/kubernetes/pkg/client/unversioned/fake" "k8s.io/kubernetes/pkg/runtime" ) @@ -139,9 +139,9 @@ func TestNegotiateVersion(t *testing.T) { return &http.Response{StatusCode: test.statusCode, Header: header, Body: objBody(&uapi.APIVersions{Versions: test.serverVersions})}, nil }), } - c := unversioned.NewOrDie(test.config) - c.DiscoveryClient.RESTClient().(*restclient.RESTClient).Client = fakeClient.Client - response, err := unversioned.NegotiateVersion(c, test.config, test.version, test.clientVersions) + c := discovery.NewDiscoveryClientForConfigOrDie(test.config) + c.RESTClient().(*restclient.RESTClient).Client = fakeClient.Client + response, err := discovery.NegotiateVersion(c, test.config, test.version, test.clientVersions) if err == nil && test.expectErr != nil { t.Errorf("expected error, got nil for [%s].", test.name) } diff --git a/pkg/client/unversioned/BUILD b/pkg/client/unversioned/BUILD index 5cc5b776cb5..81c8c1cf2d6 100644 --- a/pkg/client/unversioned/BUILD +++ b/pkg/client/unversioned/BUILD @@ -13,115 +13,32 @@ load( go_library( name = "go_default_library", srcs = [ - "apps.go", - "authentication.go", - "authorization.go", - "autoscaling.go", - "batch.go", - "certificates.go", - "certificatesigningrequests.go", - "client.go", - "clusterrolebindings.go", - "clusterroles.go", - "componentstatuses.go", "conditions.go", - "configmap.go", - "containerinfo.go", - "daemon_sets.go", - "deployment.go", - "doc.go", - "endpoints.go", - "events.go", - "extensions.go", - "flags.go", "helper.go", - "horizontalpodautoscaler.go", - "import_known_versions.go", - "ingress.go", - "jobs.go", - "limit_ranges.go", - "namespaces.go", - "network_policys.go", - "nodes.go", - "persistentvolumeclaim.go", - "persistentvolumes.go", - "pet_sets.go", - "pod_disruption_budgets.go", - "pod_templates.go", - "pods.go", - "podsecuritypolicy.go", - "policy.go", - "rbac.go", - "replica_sets.go", - "replication_controllers.go", - "resource_quotas.go", - "rolebindings.go", - "roles.go", - "scale.go", - "scheduledjobs.go", - "secrets.go", - "service_accounts.go", - "services.go", - "storage.go", - "storageclasses.go", - "subjectaccessreview.go", - "thirdpartyresources.go", - "tokenreviews.go", ], tags = ["automanaged"], deps = [ "//pkg/api:go_default_library", "//pkg/api/errors:go_default_library", - "//pkg/api/install:go_default_library", - "//pkg/api/meta:go_default_library", "//pkg/api/unversioned:go_default_library", "//pkg/apimachinery/registered:go_default_library", "//pkg/apis/apps:go_default_library", - "//pkg/apis/apps/install:go_default_library", - "//pkg/apis/authentication:go_default_library", - "//pkg/apis/authentication/install:go_default_library", - "//pkg/apis/authorization:go_default_library", - "//pkg/apis/authorization/install:go_default_library", - "//pkg/apis/autoscaling:go_default_library", - "//pkg/apis/autoscaling/install:go_default_library", "//pkg/apis/batch:go_default_library", - "//pkg/apis/batch/install:go_default_library", - "//pkg/apis/certificates:go_default_library", - "//pkg/apis/certificates/install:go_default_library", - "//pkg/apis/componentconfig/install:go_default_library", "//pkg/apis/extensions:go_default_library", - "//pkg/apis/extensions/install:go_default_library", - "//pkg/apis/policy:go_default_library", - "//pkg/apis/policy/install:go_default_library", - "//pkg/apis/rbac:go_default_library", - "//pkg/apis/rbac/install:go_default_library", - "//pkg/apis/storage:go_default_library", - "//pkg/apis/storage/install:go_default_library", "//pkg/client/clientset_generated/internalclientset/typed/apps/unversioned:go_default_library", "//pkg/client/clientset_generated/internalclientset/typed/batch/unversioned:go_default_library", "//pkg/client/clientset_generated/internalclientset/typed/core/unversioned:go_default_library", "//pkg/client/clientset_generated/internalclientset/typed/extensions/unversioned:go_default_library", "//pkg/client/restclient:go_default_library", - "//pkg/client/typed/discovery:go_default_library", - "//pkg/fields:go_default_library", - "//pkg/runtime:go_default_library", - "//pkg/util/net:go_default_library", - "//pkg/util/sets:go_default_library", "//pkg/util/wait:go_default_library", - "//pkg/version:go_default_library", "//pkg/watch:go_default_library", "//plugin/pkg/client/auth:go_default_library", - "//vendor:github.com/google/cadvisor/info/v1", ], ) go_test( name = "go_default_test", - srcs = [ - "containerinfo_test.go", - "flags_test.go", - "helper_test.go", - ], + srcs = ["helper_test.go"], library = "go_default_library", tags = ["automanaged"], deps = [ @@ -131,58 +48,5 @@ go_test( "//pkg/apimachinery/registered:go_default_library", "//pkg/client/restclient:go_default_library", "//pkg/runtime:go_default_library", - "//pkg/util/sets:go_default_library", - "//vendor:github.com/google/cadvisor/info/v1", - "//vendor:github.com/google/cadvisor/info/v1/test", - ], -) - -go_test( - name = "go_default_xtest", - srcs = [ - "daemon_sets_test.go", - "deployment_test.go", - "endpoints_test.go", - "events_test.go", - "helper_blackbox_test.go", - "horizontalpodautoscaler_test.go", - "ingress_test.go", - "jobs_test.go", - "limit_ranges_test.go", - "namespaces_test.go", - "nodes_test.go", - "persistentvolume_test.go", - "persistentvolumeclaim_test.go", - "pet_sets_test.go", - "pod_templates_test.go", - "pods_test.go", - "podsecuritypolicy_test.go", - "replica_sets_test.go", - "replication_controllers_test.go", - "resource_quotas_test.go", - "scheduledjobs_test.go", - "services_test.go", - "storageclasses_test.go", - "thirdpartyresources_test.go", - ], - tags = ["automanaged"], - deps = [ - "//pkg/api:go_default_library", - "//pkg/api/resource:go_default_library", - "//pkg/api/testapi:go_default_library", - "//pkg/api/unversioned:go_default_library", - "//pkg/apimachinery/registered:go_default_library", - "//pkg/apis/apps:go_default_library", - "//pkg/apis/autoscaling:go_default_library", - "//pkg/apis/batch:go_default_library", - "//pkg/apis/batch/v2alpha1:go_default_library", - "//pkg/apis/extensions:go_default_library", - "//pkg/apis/storage:go_default_library", - "//pkg/client/restclient:go_default_library", - "//pkg/client/unversioned:go_default_library", - "//pkg/client/unversioned/fake:go_default_library", - "//pkg/client/unversioned/testclient/simple:go_default_library", - "//pkg/labels:go_default_library", - "//pkg/runtime:go_default_library", ], ) diff --git a/pkg/client/unversioned/conditions.go b/pkg/client/unversioned/conditions.go index 36401e8be30..6bc87ca05c0 100644 --- a/pkg/client/unversioned/conditions.go +++ b/pkg/client/unversioned/conditions.go @@ -77,6 +77,7 @@ func ReplicaSetHasDesiredReplicas(rsClient extensionsclient.ReplicaSetsGetter, r } } +// PetSetHasDesiredPets returns a conditon that checks the number of petset replicas func PetSetHasDesiredPets(psClient appsclient.PetSetsGetter, petset *apps.PetSet) wait.ConditionFunc { // TODO: Differentiate between 0 pets and a really quick scale down using generation. return func() (bool, error) { @@ -104,11 +105,11 @@ func JobHasDesiredParallelism(jobClient batchclient.JobsGetter, job *batch.Job) if job.Spec.Completions == nil { // A job without specified completions needs to wait for Active to reach Parallelism. return false, nil - } else { - // otherwise count successful - progress := *job.Spec.Completions - job.Status.Active - job.Status.Succeeded - return progress == 0, nil } + + // otherwise count successful + progress := *job.Spec.Completions - job.Status.Active - job.Status.Succeeded + return progress == 0, nil } } diff --git a/pkg/client/unversioned/helper.go b/pkg/client/unversioned/helper.go index b157e10d317..59a992ad75e 100644 --- a/pkg/client/unversioned/helper.go +++ b/pkg/client/unversioned/helper.go @@ -17,25 +17,9 @@ limitations under the License. package unversioned import ( - "fmt" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/apimachinery/registered" - "k8s.io/kubernetes/pkg/apis/apps" - "k8s.io/kubernetes/pkg/apis/authentication" - "k8s.io/kubernetes/pkg/apis/authorization" - "k8s.io/kubernetes/pkg/apis/autoscaling" - "k8s.io/kubernetes/pkg/apis/batch" - "k8s.io/kubernetes/pkg/apis/certificates" - "k8s.io/kubernetes/pkg/apis/extensions" - "k8s.io/kubernetes/pkg/apis/policy" - "k8s.io/kubernetes/pkg/apis/rbac" - "k8s.io/kubernetes/pkg/apis/storage" "k8s.io/kubernetes/pkg/client/restclient" - "k8s.io/kubernetes/pkg/client/typed/discovery" - "k8s.io/kubernetes/pkg/util/sets" - "k8s.io/kubernetes/pkg/version" // Import solely to initialize client auth plugins. _ "k8s.io/kubernetes/plugin/pkg/client/auth" ) @@ -45,255 +29,6 @@ const ( defaultAPIPath = "/apis" ) -// New creates a Kubernetes client for the given config. This client works with pods, -// replication controllers, daemons, and services. It allows operations such as list, get, update -// and delete on these objects. An error is returned if the provided configuration -// is not valid. -func New(c *restclient.Config) (*Client, error) { - config := *c - if err := SetKubernetesDefaults(&config); err != nil { - return nil, err - } - client, err := restclient.RESTClientFor(&config) - if err != nil { - return nil, err - } - - discoveryConfig := *c - discoveryClient, err := discovery.NewDiscoveryClientForConfig(&discoveryConfig) - if err != nil { - return nil, err - } - - var authorizationClient *AuthorizationClient - if registered.IsRegistered(authorization.GroupName) { - authorizationConfig := *c - authorizationClient, err = NewAuthorization(&authorizationConfig) - if err != nil { - return nil, err - } - } - - var autoscalingClient *AutoscalingClient - if registered.IsRegistered(autoscaling.GroupName) { - autoscalingConfig := *c - autoscalingClient, err = NewAutoscaling(&autoscalingConfig) - if err != nil { - return nil, err - } - } - - var authenticationClient *AuthenticationClient - if registered.IsRegistered(authentication.GroupName) { - authenticationConfig := *c - authenticationClient, err = NewAuthentication(&authenticationConfig) - if err != nil { - return nil, err - } - } - - var batchClient *BatchClient - if registered.IsRegistered(batch.GroupName) { - batchConfig := *c - batchClient, err = NewBatch(&batchConfig) - if err != nil { - return nil, err - } - } - - var extensionsClient *ExtensionsClient - if registered.IsRegistered(extensions.GroupName) { - extensionsConfig := *c - extensionsClient, err = NewExtensions(&extensionsConfig) - if err != nil { - return nil, err - } - } - var policyClient *PolicyClient - if registered.IsRegistered(policy.GroupName) { - policyConfig := *c - policyClient, err = NewPolicy(&policyConfig) - if err != nil { - return nil, err - } - } - var certsClient *CertificatesClient - if registered.IsRegistered(certificates.GroupName) { - certsConfig := *c - certsClient, err = NewCertificates(&certsConfig) - if err != nil { - return nil, err - } - } - - var appsClient *AppsClient - if registered.IsRegistered(apps.GroupName) { - appsConfig := *c - appsClient, err = NewApps(&appsConfig) - if err != nil { - return nil, err - } - } - - var rbacClient *RbacClient - if registered.IsRegistered(rbac.GroupName) { - rbacConfig := *c - rbacClient, err = NewRbac(&rbacConfig) - if err != nil { - return nil, err - } - } - - var storageClient *StorageClient - if registered.IsRegistered(storage.GroupName) { - storageConfig := *c - storageClient, err = NewStorage(&storageConfig) - if err != nil { - return nil, err - } - } - - return &Client{ - RESTClient: client, - AppsClient: appsClient, - AuthenticationClient: authenticationClient, - AuthorizationClient: authorizationClient, - AutoscalingClient: autoscalingClient, - BatchClient: batchClient, - CertificatesClient: certsClient, - DiscoveryClient: discoveryClient, - ExtensionsClient: extensionsClient, - PolicyClient: policyClient, - RbacClient: rbacClient, - StorageClient: storageClient, - }, 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(client *Client, c *restclient.Config) error { - var err error - if client == nil { - client, err = New(c) - if err != nil { - return err - } - } - cVer := version.Get() - sVer, err := client.Discovery().ServerVersion() - if err != nil { - return fmt.Errorf("couldn't read version from server: %v\n", err) - } - // GitVersion includes GitCommit and GitTreeState, but best to be safe? - if cVer.GitVersion != sVer.GitVersion || cVer.GitCommit != sVer.GitCommit || cVer.GitTreeState != sVer.GitTreeState { - return fmt.Errorf("server version (%#v) differs from client version (%#v)!\n", sVer, cVer) - } - - 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 registered client 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(client *Client, c *restclient.Config, requestedGV *unversioned.GroupVersion, clientRegisteredGVs []unversioned.GroupVersion) (*unversioned.GroupVersion, error) { - var err error - if client == nil { - client, err = New(c) - if err != nil { - return nil, err - } - } - clientVersions := sets.String{} - for _, gv := range clientRegisteredGVs { - clientVersions.Insert(gv.String()) - } - groups, err := client.ServerGroups() - if err != nil { - // This is almost always a connection error, and higher level code should treat this as a generic error, - // not a negotiation specific error. - return nil, err - } - versions := unversioned.ExtractGroupVersions(groups) - serverVersions := sets.String{} - for _, v := range versions { - serverVersions.Insert(v) - } - - // If no version requested, use config version (may also be empty). - // make a copy of the original so we don't risk mutating input here or in the returned value - var preferredGV *unversioned.GroupVersion - switch { - case requestedGV != nil: - t := *requestedGV - preferredGV = &t - case c.GroupVersion != nil: - t := *c.GroupVersion - preferredGV = &t - } - - // 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 preferredGV != nil { - if !clientVersions.Has(preferredGV.String()) { - return nil, fmt.Errorf("client does not support API version %q; client supported API versions: %v", preferredGV, clientVersions) - - } - // If the server supports no versions, then we should just use the preferredGV - // This can happen because discovery fails due to 403 Forbidden errors - if len(serverVersions) == 0 { - return preferredGV, nil - } - if serverVersions.Has(preferredGV.String()) { - return preferredGV, nil - } - // If we are using an explicit config version the server does not support, fail. - if (c.GroupVersion != nil) && (*preferredGV == *c.GroupVersion) { - return nil, fmt.Errorf("server does not support API version %q", preferredGV) - } - } - - for _, clientGV := range clientRegisteredGVs { - if serverVersions.Has(clientGV.String()) { - // Version was not explicitly requested in command config (--api-version). - // Ok to fall back to a supported version with a warning. - // TODO: caesarxuchao: enable the warning message when we have - // proper fix. Please refer to issue #14895. - // if len(version) != 0 { - // glog.Warningf("Server does not support API version '%s'. Falling back to '%s'.", version, clientVersion) - // } - t := clientGV - return &t, nil - } - } - return nil, fmt.Errorf("failed to negotiate an api version; server supports: %v, client supports: %v", - serverVersions, clientVersions) -} - -// NewOrDie creates a Kubernetes client and panics if the provided API version is not recognized. -func NewOrDie(c *restclient.Config) *Client { - client, err := New(c) - if err != nil { - panic(err) - } - return client -} - -// NewInCluster is a shortcut for calling InClusterConfig() and then New(). -func NewInCluster() (*Client, error) { - cc, err := restclient.InClusterConfig() - if err != nil { - return nil, err - } - return New(cc) -} - // SetKubernetesDefaults sets default values on the provided client config for accessing the // Kubernetes API or returns an error if any of the defaults are impossible or invalid. // TODO: this method needs to be split into one that sets defaults per group, expected to be fix in PR "Refactoring clientcache.go and helper.go #14592" diff --git a/pkg/client/unversioned/testclient/simple/BUILD b/pkg/client/unversioned/testclient/simple/BUILD index b50d16b72f4..4ae067539b0 100644 --- a/pkg/client/unversioned/testclient/simple/BUILD +++ b/pkg/client/unversioned/testclient/simple/BUILD @@ -21,7 +21,6 @@ go_library( "//pkg/apimachinery/registered:go_default_library", "//pkg/client/clientset_generated/internalclientset:go_default_library", "//pkg/client/restclient:go_default_library", - "//pkg/client/unversioned:go_default_library", "//pkg/fields:go_default_library", "//pkg/labels:go_default_library", "//pkg/runtime:go_default_library", diff --git a/pkg/kubectl/cmd/logs_test.go b/pkg/kubectl/cmd/logs_test.go index 39243eef180..ed2528aeb83 100644 --- a/pkg/kubectl/cmd/logs_test.go +++ b/pkg/kubectl/cmd/logs_test.go @@ -67,7 +67,7 @@ func TestLog(t *testing.T) { }), } tf.Namespace = "test" - tf.ClientConfig = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &unversioned.GroupVersion{Version: test.version}}} + tf.ClientConfig = &restclient.Config{APIPath: "/api", ContentConfig: restclient.ContentConfig{NegotiatedSerializer: api.Codecs, GroupVersion: &unversioned.GroupVersion{Version: test.version}}} buf := bytes.NewBuffer([]byte{}) cmd := NewCmdLogs(f, buf) diff --git a/pkg/kubectl/cmd/testing/BUILD b/pkg/kubectl/cmd/testing/BUILD index 05a4464aad2..caaebc5c73b 100644 --- a/pkg/kubectl/cmd/testing/BUILD +++ b/pkg/kubectl/cmd/testing/BUILD @@ -24,7 +24,6 @@ go_library( "//pkg/client/clientset_generated/internalclientset:go_default_library", "//pkg/client/restclient:go_default_library", "//pkg/client/typed/discovery:go_default_library", - "//pkg/client/unversioned:go_default_library", "//pkg/client/unversioned/fake:go_default_library", "//pkg/kubectl:go_default_library", "//pkg/kubectl/cmd/util:go_default_library", diff --git a/pkg/kubectl/cmd/testing/fake.go b/pkg/kubectl/cmd/testing/fake.go index 10e171401de..711ae9516d7 100644 --- a/pkg/kubectl/cmd/testing/fake.go +++ b/pkg/kubectl/cmd/testing/fake.go @@ -34,7 +34,6 @@ import ( "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" "k8s.io/kubernetes/pkg/client/restclient" "k8s.io/kubernetes/pkg/client/typed/discovery" - client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/client/unversioned/fake" "k8s.io/kubernetes/pkg/kubectl" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" @@ -447,9 +446,10 @@ func (f *fakeAPIFactory) Printer(mapping *meta.RESTMapping, options kubectl.Prin } func (f *fakeAPIFactory) LogsForObject(object, options runtime.Object) (*restclient.Request, error) { - fakeClient := f.tf.Client.(*fake.RESTClient) - c := client.NewOrDie(f.tf.ClientConfig) - c.Client = fakeClient.Client + c, err := f.ClientSet() + if err != nil { + panic(err) + } switch t := object.(type) { case *api.Pod: @@ -457,7 +457,7 @@ func (f *fakeAPIFactory) LogsForObject(object, options runtime.Object) (*restcli if !ok { return nil, errors.New("provided options object is not a PodLogOptions") } - return c.Pods(f.tf.Namespace).GetLogs(t.Name, opts), nil + return c.Core().Pods(f.tf.Namespace).GetLogs(t.Name, opts), nil default: fqKinds, _, err := api.Scheme.ObjectKinds(object) if err != nil { diff --git a/pkg/kubectl/cmd/util/clientcache.go b/pkg/kubectl/cmd/util/clientcache.go index 7ce30a94b24..fd580dbb2eb 100644 --- a/pkg/kubectl/cmd/util/clientcache.go +++ b/pkg/kubectl/cmd/util/clientcache.go @@ -22,7 +22,8 @@ import ( "k8s.io/kubernetes/pkg/apimachinery/registered" "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" "k8s.io/kubernetes/pkg/client/restclient" - client "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/client/typed/discovery" + oldclient "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" ) @@ -43,8 +44,9 @@ type ClientCache struct { fedClientSets map[unversioned.GroupVersion]fed_clientset.Interface configs map[unversioned.GroupVersion]*restclient.Config defaultConfig *restclient.Config - defaultClient *client.Client - matchVersion bool + // TODO this is only ever read. It should be moved to initialization at some point. + discoveryClient discovery.DiscoveryInterface + matchVersion bool } // ClientConfigForVersion returns the correct config for a server @@ -56,7 +58,7 @@ func (c *ClientCache) ClientConfigForVersion(version *unversioned.GroupVersion) } c.defaultConfig = config if c.matchVersion { - if err := client.MatchesServerVersion(c.defaultClient, config); err != nil { + if err := discovery.MatchesServerVersion(c.discoveryClient, config); err != nil { return nil, err } } @@ -77,8 +79,8 @@ func (c *ClientCache) ClientConfigForVersion(version *unversioned.GroupVersion) preferredGV = &versionCopy } - client.SetKubernetesDefaults(&config) - negotiatedVersion, err := client.NegotiateVersion(c.defaultClient, &config, preferredGV, registered.EnabledVersions()) + oldclient.SetKubernetesDefaults(&config) + negotiatedVersion, err := discovery.NegotiateVersion(c.discoveryClient, &config, preferredGV, registered.EnabledVersions()) if err != nil { return nil, err } diff --git a/pkg/kubectl/describe.go b/pkg/kubectl/describe.go index a7749a5fe54..e4342d00218 100644 --- a/pkg/kubectl/describe.go +++ b/pkg/kubectl/describe.go @@ -43,7 +43,8 @@ import ( "k8s.io/kubernetes/pkg/apis/storage" storageutil "k8s.io/kubernetes/pkg/apis/storage/util" clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - client "k8s.io/kubernetes/pkg/client/unversioned" + coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/unversioned" + extensionsclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/extensions/unversioned" deploymentutil "k8s.io/kubernetes/pkg/controller/deployment/util" "k8s.io/kubernetes/pkg/fieldpath" "k8s.io/kubernetes/pkg/fields" @@ -2186,7 +2187,7 @@ func (dd *DeploymentDescriber) Describe(namespace, name string, describerSetting // of getting all DS's and searching through them manually). // TODO: write an interface for controllers and fuse getReplicationControllersForLabels // and getDaemonSetsForLabels. -func getDaemonSetsForLabels(c client.DaemonSetInterface, labelsToMatch labels.Labels) ([]extensions.DaemonSet, error) { +func getDaemonSetsForLabels(c extensionsclient.DaemonSetInterface, labelsToMatch labels.Labels) ([]extensions.DaemonSet, error) { // Get all daemon sets // TODO: this needs a namespace scope as argument dss, err := c.List(api.ListOptions{}) @@ -2237,7 +2238,7 @@ func printReplicaSetsByLabels(matchingRSs []*extensions.ReplicaSet) string { return list } -func getPodStatusForController(c client.PodInterface, selector labels.Selector) (running, waiting, succeeded, failed int, err error) { +func getPodStatusForController(c coreclient.PodInterface, selector labels.Selector) (running, waiting, succeeded, failed int, err error) { options := api.ListOptions{LabelSelector: selector} rcPods, err := c.List(options) if err != nil { diff --git a/pkg/kubectl/stop.go b/pkg/kubectl/stop.go index 4dad40e8055..d252705f351 100644 --- a/pkg/kubectl/stop.go +++ b/pkg/kubectl/stop.go @@ -33,7 +33,6 @@ import ( batchclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/batch/unversioned" coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/unversioned" extensionsclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/extensions/unversioned" - client "k8s.io/kubernetes/pkg/client/unversioned" deploymentutil "k8s.io/kubernetes/pkg/controller/deployment/util" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/util" @@ -222,7 +221,7 @@ func (reaper *ReplicationControllerReaper) Stop(namespace, name string, timeout // TODO(madhusudancs): Implement it when controllerRef is implemented - https://github.com/kubernetes/kubernetes/issues/2210 // getOverlappingReplicaSets finds ReplicaSets that this ReplicaSet overlaps, as well as ReplicaSets overlapping this ReplicaSet. -func getOverlappingReplicaSets(c client.ReplicaSetInterface, rs *extensions.ReplicaSet) ([]extensions.ReplicaSet, []extensions.ReplicaSet, error) { +func getOverlappingReplicaSets(c extensionsclient.ReplicaSetInterface, rs *extensions.ReplicaSet) ([]extensions.ReplicaSet, []extensions.ReplicaSet, error) { var overlappingRSs, exactMatchRSs []extensions.ReplicaSet return overlappingRSs, exactMatchRSs, nil } diff --git a/test/e2e/framework/util.go b/test/e2e/framework/util.go index f827190017c..1372a6e3f47 100644 --- a/test/e2e/framework/util.go +++ b/test/e2e/framework/util.go @@ -1793,14 +1793,6 @@ func LoadFederatedConfig(overrides *clientcmd.ConfigOverrides) (*restclient.Conf return cfg, nil } -func loadClientFromConfig(config *restclient.Config) (*client.Client, error) { - c, err := client.New(config) - if err != nil { - return nil, fmt.Errorf("error creating client: %v", err.Error()) - } - return c, nil -} - func LoadFederationClientset_1_5() (*federation_release_1_5.Clientset, error) { config, err := LoadFederatedConfig(&clientcmd.ConfigOverrides{}) if err != nil { @@ -1814,14 +1806,6 @@ func LoadFederationClientset_1_5() (*federation_release_1_5.Clientset, error) { return c, nil } -func LoadClient() (*client.Client, error) { - config, err := LoadConfig() - if err != nil { - return nil, fmt.Errorf("error creating client: %v", err.Error()) - } - return loadClientFromConfig(config) -} - func LoadInternalClientset() (*clientset.Clientset, error) { config, err := LoadConfig() if err != nil {