diff --git a/pkg/kubectl/cmd/testing/fake.go b/pkg/kubectl/cmd/testing/fake.go index b304228d919..402edf38947 100644 --- a/pkg/kubectl/cmd/testing/fake.go +++ b/pkg/kubectl/cmd/testing/fake.go @@ -418,11 +418,15 @@ func (f *TestFactory) RESTClient() (*restclient.RESTClient, error) { func (f *TestFactory) DiscoveryClient() (discovery.CachedDiscoveryInterface, error) { fakeClient := f.Client.(*fake.RESTClient) - discoveryClient := discovery.NewDiscoveryClientForConfigOrDie(f.ClientConfigVal) - discoveryClient.RESTClient().(*restclient.RESTClient).Client = fakeClient.Client cacheDir := filepath.Join("", ".kube", "cache", "discovery") - return cmdutil.NewCachedDiscoveryClient(discoveryClient, cacheDir, time.Duration(10*time.Minute)), nil + cachedClient, err := discovery.NewCachedDiscoveryClientForConfig(f.ClientConfigVal, cacheDir, "", time.Duration(10*time.Minute)) + if err != nil { + return nil, err + } + cachedClient.RESTClient().(*restclient.RESTClient).Client = fakeClient.Client + + return cachedClient, nil } func (f *TestFactory) ClientSetForVersion(requiredVersion *schema.GroupVersion) (internalclientset.Interface, error) { diff --git a/pkg/kubectl/cmd/util/BUILD b/pkg/kubectl/cmd/util/BUILD index d344db58e64..ca6446fda35 100644 --- a/pkg/kubectl/cmd/util/BUILD +++ b/pkg/kubectl/cmd/util/BUILD @@ -3,7 +3,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "go_default_library", srcs = [ - "cached_discovery.go", "config_flags.go", "conversion.go", "factory.go", @@ -30,17 +29,14 @@ go_library( "//pkg/kubectl/cmd/templates:go_default_library", "//pkg/kubectl/cmd/util/openapi:go_default_library", "//pkg/kubectl/cmd/util/openapi/validation:go_default_library", - "//pkg/kubectl/cmd/util/transport:go_default_library", "//pkg/kubectl/genericclioptions/resource:go_default_library", "//pkg/kubectl/plugins:go_default_library", - "//pkg/kubectl/scheme:go_default_library", "//pkg/kubectl/validation:go_default_library", "//pkg/printers:go_default_library", "//pkg/printers/internalversion:go_default_library", "//pkg/version:go_default_library", "//vendor/github.com/evanphx/json-patch:go_default_library", "//vendor/github.com/golang/glog:go_default_library", - "//vendor/github.com/googleapis/gnostic/OpenAPIv2:go_default_library", "//vendor/github.com/spf13/cobra:go_default_library", "//vendor/github.com/spf13/pflag:go_default_library", "//vendor/k8s.io/api/apps/v1:go_default_library", @@ -61,7 +57,6 @@ go_library( "//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/yaml:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/version:go_default_library", "//vendor/k8s.io/apimachinery/pkg/watch:go_default_library", "//vendor/k8s.io/apiserver/pkg/util/flag:go_default_library", "//vendor/k8s.io/client-go/discovery:go_default_library", @@ -79,14 +74,12 @@ go_library( go_test( name = "go_default_test", srcs = [ - "cached_discovery_test.go", "factory_object_mapping_test.go", "factory_test.go", "helpers_test.go", ], embed = [":go_default_library"], deps = [ - "//pkg/api/legacyscheme:go_default_library", "//pkg/api/testapi:go_default_library", "//pkg/api/testing:go_default_library", "//pkg/apis/apps:go_default_library", @@ -97,14 +90,10 @@ go_test( "//pkg/client/clientset_generated/internalclientset/fake:go_default_library", "//pkg/controller:go_default_library", "//pkg/kubectl:go_default_library", - "//pkg/kubectl/genericclioptions/resource:go_default_library", - "//vendor/github.com/googleapis/gnostic/OpenAPIv2:go_default_library", - "//vendor/github.com/stretchr/testify/assert:go_default_library", "//vendor/k8s.io/api/core/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/api/meta/testrestmapper:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/labels:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", @@ -112,12 +101,7 @@ go_test( "//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/version:go_default_library", "//vendor/k8s.io/apimachinery/pkg/watch:go_default_library", - "//vendor/k8s.io/client-go/discovery:go_default_library", - "//vendor/k8s.io/client-go/rest:go_default_library", - "//vendor/k8s.io/client-go/rest/fake:go_default_library", - "//vendor/k8s.io/client-go/restmapper:go_default_library", "//vendor/k8s.io/client-go/testing:go_default_library", "//vendor/k8s.io/utils/exec:go_default_library", ], @@ -139,7 +123,6 @@ filegroup( "//pkg/kubectl/cmd/util/jsonmerge:all-srcs", "//pkg/kubectl/cmd/util/openapi:all-srcs", "//pkg/kubectl/cmd/util/sanity:all-srcs", - "//pkg/kubectl/cmd/util/transport:all-srcs", ], tags = ["automanaged"], visibility = ["//build/visible_to:pkg_kubectl_cmd_util_CONSUMERS"], diff --git a/pkg/kubectl/cmd/util/config_flags.go b/pkg/kubectl/cmd/util/config_flags.go index 60d8d501c7a..8f3a4ba2f3b 100644 --- a/pkg/kubectl/cmd/util/config_flags.go +++ b/pkg/kubectl/cmd/util/config_flags.go @@ -18,7 +18,6 @@ package util import ( "fmt" - "net/http" "os" "path/filepath" "time" @@ -32,8 +31,6 @@ import ( "k8s.io/client-go/restmapper" "k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/util/homedir" - - "k8s.io/kubernetes/pkg/kubectl/cmd/util/transport" ) const ( @@ -55,6 +52,8 @@ const ( flagHTTPCacheDir = "cache-dir" ) +var defaultCacheDir = filepath.Join(homedir.HomeDir(), ".kube", "http-cache") + // TODO(juanvallejo): move to pkg/kubectl/genericclioptions once // the dependency on cmdutil is broken here. // ConfigFlags composes the set of values necessary @@ -179,27 +178,15 @@ func (f *ConfigFlags) ToDiscoveryClient() (discovery.CachedDiscoveryInterface, e // double it just so we don't end up here again for a while. This config is only used for discovery. config.Burst = 100 - cacheDir := filepath.Join(homedir.HomeDir(), ".kube", "http-cache") + // retrieve a user-provided value for the "cache-dir" + // defaulting to ~/.kube/http-cache if no user-value is given. + httpCacheDir := defaultCacheDir if f.CacheDir != nil { - cacheDir = *f.CacheDir + httpCacheDir = *f.CacheDir } - if len(cacheDir) > 0 { - wt := config.WrapTransport - config.WrapTransport = func(rt http.RoundTripper) http.RoundTripper { - if wt != nil { - rt = wt(rt) - } - return transport.NewCacheRoundTripper(cacheDir, rt) - } - } - - discoveryClient, err := discovery.NewDiscoveryClientForConfig(config) - if err != nil { - return nil, err - } - cacheDir = computeDiscoverCacheDir(filepath.Join(homedir.HomeDir(), ".kube", "cache", "discovery"), config.Host) - return NewCachedDiscoveryClient(discoveryClient, cacheDir, time.Duration(10*time.Minute)), nil + discoveryCacheDir := computeDiscoverCacheDir(filepath.Join(homedir.HomeDir(), ".kube", "cache", "discovery"), config.Host) + return discovery.NewCachedDiscoveryClientForConfig(config, discoveryCacheDir, httpCacheDir, time.Duration(10*time.Minute)) } // RESTMapper returns a mapper. @@ -293,6 +280,7 @@ func NewConfigFlags() *ConfigFlags { Timeout: stringptr("0"), KubeConfig: stringptr(""), + CacheDir: stringptr(defaultCacheDir), ClusterName: stringptr(""), AuthInfoName: stringptr(""), Context: stringptr(""), diff --git a/pkg/kubectl/cmd/util/factory_test.go b/pkg/kubectl/cmd/util/factory_test.go index a11473cf90f..2cc4eddb49a 100644 --- a/pkg/kubectl/cmd/util/factory_test.go +++ b/pkg/kubectl/cmd/util/factory_test.go @@ -24,23 +24,19 @@ import ( "time" "k8s.io/api/core/v1" + apiequality "k8s.io/apimachinery/pkg/api/equality" - "k8s.io/apimachinery/pkg/api/meta/testrestmapper" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/watch" - manualfake "k8s.io/client-go/rest/fake" - "k8s.io/client-go/restmapper" testcore "k8s.io/client-go/testing" - "k8s.io/kubernetes/pkg/api/legacyscheme" api "k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake" "k8s.io/kubernetes/pkg/controller" "k8s.io/kubernetes/pkg/kubectl" - "k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" ) func TestPortsForObject(t *testing.T) { @@ -439,44 +435,3 @@ func TestMakePortsString(t *testing.T) { } } } - -func fakeClient() resource.FakeClientFunc { - return func(version schema.GroupVersion) (resource.RESTClient, error) { - return &manualfake.RESTClient{}, nil - } -} - -func TestDiscoveryReplaceAliases(t *testing.T) { - tests := []struct { - name string - arg string - expected string - }{ - { - name: "no-replacement", - arg: "service", - expected: "service", - }, - { - name: "all-replacement", - arg: "all", - expected: "pods,replicationcontrollers,services,statefulsets.apps,horizontalpodautoscalers.autoscaling,jobs.batch,cronjobs.batch,daemonsets.extensions,deployments.extensions,replicasets.extensions", - }, - { - name: "alias-in-comma-separated-arg", - arg: "all,secrets", - expected: "pods,replicationcontrollers,services,statefulsets.apps,horizontalpodautoscalers.autoscaling,jobs.batch,cronjobs.batch,daemonsets.extensions,deployments.extensions,replicasets.extensions,secrets", - }, - } - - ds := &fakeDiscoveryClient{} - mapper := restmapper.NewShortcutExpander(testrestmapper.TestOnlyStaticRESTMapper(legacyscheme.Scheme), ds) - b := resource.NewFakeBuilder(fakeClient(), mapper, resource.FakeCategoryExpander) - - for _, test := range tests { - replaced := b.ReplaceAliases(test.arg) - if replaced != test.expected { - t.Errorf("%s: unexpected argument: expected %s, got %s", test.name, test.expected, replaced) - } - } -} diff --git a/pkg/kubectl/cmd/util/transport/BUILD b/pkg/kubectl/cmd/util/transport/BUILD deleted file mode 100644 index 0e968c1fb2a..00000000000 --- a/pkg/kubectl/cmd/util/transport/BUILD +++ /dev/null @@ -1,33 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") - -go_library( - name = "go_default_library", - srcs = ["round_tripper.go"], - importpath = "k8s.io/kubernetes/pkg/kubectl/cmd/util/transport", - visibility = ["//visibility:public"], - deps = [ - "//vendor/github.com/gregjones/httpcache:go_default_library", - "//vendor/github.com/gregjones/httpcache/diskcache:go_default_library", - "//vendor/github.com/peterbourgon/diskv:go_default_library", - ], -) - -go_test( - name = "go_default_test", - srcs = ["round_tripper_test.go"], - embed = [":go_default_library"], -) - -filegroup( - name = "package-srcs", - srcs = glob(["**"]), - tags = ["automanaged"], - visibility = ["//visibility:private"], -) - -filegroup( - name = "all-srcs", - srcs = [":package-srcs"], - tags = ["automanaged"], - visibility = ["//visibility:public"], -) diff --git a/pkg/kubectl/genericclioptions/resource/builder_test.go b/pkg/kubectl/genericclioptions/resource/builder_test.go index 517b0d8e61d..e6308a56687 100644 --- a/pkg/kubectl/genericclioptions/resource/builder_test.go +++ b/pkg/kubectl/genericclioptions/resource/builder_test.go @@ -557,6 +557,39 @@ func TestURLBuilderRequireNamespace(t *testing.T) { } } +func TestReplaceAliases(t *testing.T) { + tests := []struct { + name string + arg string + expected string + }{ + { + name: "no-replacement", + arg: "service", + expected: "service", + }, + { + name: "all-replacement", + arg: "all", + expected: "pods,replicationcontrollers,services,statefulsets.apps,horizontalpodautoscalers.autoscaling,jobs.batch,cronjobs.batch,daemonsets.extensions,deployments.extensions,replicasets.extensions", + }, + { + name: "alias-in-comma-separated-arg", + arg: "all,secrets", + expected: "pods,replicationcontrollers,services,statefulsets.apps,horizontalpodautoscalers.autoscaling,jobs.batch,cronjobs.batch,daemonsets.extensions,deployments.extensions,replicasets.extensions,secrets", + }, + } + + b := newDefaultBuilder() + + for _, test := range tests { + replaced := b.ReplaceAliases(test.arg) + if replaced != test.expected { + t.Errorf("%s: unexpected argument: expected %s, got %s", test.name, test.expected, replaced) + } + } +} + func TestResourceByName(t *testing.T) { pods, _ := testData() b := newDefaultBuilderWith(fakeClientWith("", t, map[string]string{ diff --git a/staging/src/k8s.io/apiextensions-apiserver/Godeps/Godeps.json b/staging/src/k8s.io/apiextensions-apiserver/Godeps/Godeps.json index 916bfc55869..799a2eb3e81 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/Godeps/Godeps.json +++ b/staging/src/k8s.io/apiextensions-apiserver/Godeps/Godeps.json @@ -486,6 +486,14 @@ "ImportPath": "github.com/googleapis/gnostic/extensions", "Rev": "0c5108395e2debce0d731cf0287ddf7242066aba" }, + { + "ImportPath": "github.com/gregjones/httpcache", + "Rev": "787624de3eb7bd915c329cba748687a3b22666a6" + }, + { + "ImportPath": "github.com/gregjones/httpcache/diskcache", + "Rev": "787624de3eb7bd915c329cba748687a3b22666a6" + }, { "ImportPath": "github.com/grpc-ecosystem/go-grpc-prometheus", "Rev": "2500245aa6110c562d17020fb31a2c133d737799" @@ -554,6 +562,10 @@ "ImportPath": "github.com/pborman/uuid", "Rev": "ca53cad383cad2479bbba7f7a1a05797ec1386e4" }, + { + "ImportPath": "github.com/peterbourgon/diskv", + "Rev": "5f041e8faa004a95c88a202771f4cc3e991971e6" + }, { "ImportPath": "github.com/pmezard/go-difflib/difflib", "Rev": "d8ed2627bdf02c080bf22230dbb337003b7aba2d" diff --git a/staging/src/k8s.io/apiserver/Godeps/Godeps.json b/staging/src/k8s.io/apiserver/Godeps/Godeps.json index 7afd42bc32e..138dc9e4c95 100644 --- a/staging/src/k8s.io/apiserver/Godeps/Godeps.json +++ b/staging/src/k8s.io/apiserver/Godeps/Godeps.json @@ -462,6 +462,14 @@ "ImportPath": "github.com/googleapis/gnostic/extensions", "Rev": "0c5108395e2debce0d731cf0287ddf7242066aba" }, + { + "ImportPath": "github.com/gregjones/httpcache", + "Rev": "787624de3eb7bd915c329cba748687a3b22666a6" + }, + { + "ImportPath": "github.com/gregjones/httpcache/diskcache", + "Rev": "787624de3eb7bd915c329cba748687a3b22666a6" + }, { "ImportPath": "github.com/grpc-ecosystem/go-grpc-prometheus", "Rev": "2500245aa6110c562d17020fb31a2c133d737799" @@ -526,6 +534,10 @@ "ImportPath": "github.com/pborman/uuid", "Rev": "ca53cad383cad2479bbba7f7a1a05797ec1386e4" }, + { + "ImportPath": "github.com/peterbourgon/diskv", + "Rev": "5f041e8faa004a95c88a202771f4cc3e991971e6" + }, { "ImportPath": "github.com/pmezard/go-difflib/difflib", "Rev": "d8ed2627bdf02c080bf22230dbb337003b7aba2d" diff --git a/staging/src/k8s.io/client-go/Godeps/Godeps.json b/staging/src/k8s.io/client-go/Godeps/Godeps.json index 25d06c7bd4d..f1337ce7868 100644 --- a/staging/src/k8s.io/client-go/Godeps/Godeps.json +++ b/staging/src/k8s.io/client-go/Godeps/Godeps.json @@ -86,6 +86,10 @@ "ImportPath": "github.com/golang/protobuf/ptypes/timestamp", "Rev": "1643683e1b54a9e88ad26d98f81400c8c9d9f4f9" }, + { + "ImportPath": "github.com/google/btree", + "Rev": "7d79101e329e5a3adf994758c578dab82b90c017" + }, { "ImportPath": "github.com/google/gofuzz", "Rev": "44d81051d367757e1c7c6a5a86423ece9afcf63c" @@ -130,6 +134,14 @@ "ImportPath": "github.com/gophercloud/gophercloud/pagination", "Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d" }, + { + "ImportPath": "github.com/gregjones/httpcache", + "Rev": "787624de3eb7bd915c329cba748687a3b22666a6" + }, + { + "ImportPath": "github.com/gregjones/httpcache/diskcache", + "Rev": "787624de3eb7bd915c329cba748687a3b22666a6" + }, { "ImportPath": "github.com/hashicorp/golang-lru", "Rev": "a0d98a5f288019575c6d1f4bb1573fef2d1fcdc4" @@ -154,6 +166,10 @@ "ImportPath": "github.com/modern-go/reflect2", "Rev": "05fbef0ca5da472bbf96c9322b84a53edc03c9fd" }, + { + "ImportPath": "github.com/peterbourgon/diskv", + "Rev": "5f041e8faa004a95c88a202771f4cc3e991971e6" + }, { "ImportPath": "github.com/pmezard/go-difflib/difflib", "Rev": "d8ed2627bdf02c080bf22230dbb337003b7aba2d" diff --git a/staging/src/k8s.io/client-go/discovery/BUILD b/staging/src/k8s.io/client-go/discovery/BUILD index 397a390a57c..bf66795e542 100644 --- a/staging/src/k8s.io/client-go/discovery/BUILD +++ b/staging/src/k8s.io/client-go/discovery/BUILD @@ -9,14 +9,20 @@ load( go_library( name = "go_default_library", srcs = [ + "cached_discovery.go", "discovery_client.go", "helper.go", + "round_tripper.go", "unstructured.go", ], importpath = "k8s.io/client-go/discovery", deps = [ + "//vendor/github.com/golang/glog:go_default_library", "//vendor/github.com/golang/protobuf/proto:go_default_library", "//vendor/github.com/googleapis/gnostic/OpenAPIv2:go_default_library", + "//vendor/github.com/gregjones/httpcache:go_default_library", + "//vendor/github.com/gregjones/httpcache/diskcache:go_default_library", + "//vendor/github.com/peterbourgon/diskv:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", @@ -65,16 +71,23 @@ filegroup( go_test( name = "go_default_test", - srcs = ["discovery_client_test.go"], + srcs = [ + "cached_discovery_test.go", + "discovery_client_test.go", + "round_tripper_test.go", + ], embed = [":go_default_library"], deps = [ "//vendor/github.com/gogo/protobuf/proto:go_default_library", "//vendor/github.com/googleapis/gnostic/OpenAPIv2:go_default_library", + "//vendor/github.com/stretchr/testify/assert:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//vendor/k8s.io/apimachinery/pkg/version:go_default_library", "//vendor/k8s.io/client-go/rest:go_default_library", + "//vendor/k8s.io/client-go/rest/fake:go_default_library", ], ) diff --git a/pkg/kubectl/cmd/util/cached_discovery.go b/staging/src/k8s.io/client-go/discovery/cached_discovery.go similarity index 76% rename from pkg/kubectl/cmd/util/cached_discovery.go rename to staging/src/k8s.io/client-go/discovery/cached_discovery.go index 60b3ed9bb48..aca46546e62 100644 --- a/pkg/kubectl/cmd/util/cached_discovery.go +++ b/staging/src/k8s.io/client-go/discovery/cached_discovery.go @@ -14,11 +14,12 @@ See the License for the specific language governing permissions and limitations under the License. */ -package util +package discovery import ( "errors" "io/ioutil" + "net/http" "os" "path/filepath" "sync" @@ -30,15 +31,14 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/version" - "k8s.io/client-go/discovery" + "k8s.io/client-go/kubernetes/scheme" restclient "k8s.io/client-go/rest" - "k8s.io/kubernetes/pkg/kubectl/scheme" ) // CachedDiscoveryClient implements the functions that discovery server-supported API groups, // versions and resources. type CachedDiscoveryClient struct { - delegate discovery.DiscoveryInterface + delegate DiscoveryInterface // cacheDirectory is the directory where discovery docs are held. It must be unique per host:port combination to work well. cacheDirectory string @@ -57,7 +57,7 @@ type CachedDiscoveryClient struct { fresh bool } -var _ discovery.CachedDiscoveryInterface = &CachedDiscoveryClient{} +var _ CachedDiscoveryInterface = &CachedDiscoveryClient{} // ServerResourcesForGroupVersion returns the supported resources for a group and version. func (d *CachedDiscoveryClient) ServerResourcesForGroupVersion(groupVersion string) (*metav1.APIResourceList, error) { @@ -91,7 +91,7 @@ func (d *CachedDiscoveryClient) ServerResourcesForGroupVersion(groupVersion stri // ServerResources returns the supported resources for all groups and versions. func (d *CachedDiscoveryClient) ServerResources() ([]*metav1.APIResourceList, error) { - return discovery.ServerResources(d) + return ServerResources(d) } func (d *CachedDiscoveryClient) ServerGroups() (*metav1.APIGroupList, error) { @@ -207,11 +207,11 @@ func (d *CachedDiscoveryClient) RESTClient() restclient.Interface { } func (d *CachedDiscoveryClient) ServerPreferredResources() ([]*metav1.APIResourceList, error) { - return discovery.ServerPreferredResources(d) + return ServerPreferredResources(d) } func (d *CachedDiscoveryClient) ServerPreferredNamespacedResources() ([]*metav1.APIResourceList, error) { - return discovery.ServerPreferredNamespacedResources(d) + return ServerPreferredNamespacedResources(d) } func (d *CachedDiscoveryClient) ServerVersion() (*version.Info, error) { @@ -238,8 +238,40 @@ func (d *CachedDiscoveryClient) Invalidate() { d.invalidated = true } +// NewCachedDiscoveryClientForConfig creates a new DiscoveryClient for the given config, and wraps +// the created client in a CachedDiscoveryClient. The provided configuration is updated with a +// custom transport that understands cache responses. +// We receive two distinct cache directories for now, in order to preserve old behavior +// which makes use of the --cache-dir flag value for storing cache data from the CacheRoundTripper, +// and makes use of the hardcoded destination (~/.kube/cache/discovery/...) for storing +// CachedDiscoveryClient cache data. If httpCacheDir is empty, the restconfig's transport will not +// be updated with a roundtripper that understands cache responses. +// If discoveryCacheDir is empty, cached server resource data will be looked up in the current directory. +// TODO(juanvallejo): the value of "--cache-dir" should be honored. Consolidate discoveryCacheDir with httpCacheDir +// so that server resources and http-cache data are stored in the same location, provided via config flags. +func NewCachedDiscoveryClientForConfig(config *restclient.Config, discoveryCacheDir, httpCacheDir string, ttl time.Duration) (*CachedDiscoveryClient, error) { + if len(httpCacheDir) > 0 { + // update the given restconfig with a custom roundtripper that + // understands how to handle cache responses. + wt := config.WrapTransport + config.WrapTransport = func(rt http.RoundTripper) http.RoundTripper { + if wt != nil { + rt = wt(rt) + } + return newCacheRoundTripper(httpCacheDir, rt) + } + } + + discoveryClient, err := NewDiscoveryClientForConfig(config) + if err != nil { + return nil, err + } + + return newCachedDiscoveryClient(discoveryClient, discoveryCacheDir, ttl), nil +} + // NewCachedDiscoveryClient creates a new DiscoveryClient. cacheDirectory is the directory where discovery docs are held. It must be unique per host:port combination to work well. -func NewCachedDiscoveryClient(delegate discovery.DiscoveryInterface, cacheDirectory string, ttl time.Duration) *CachedDiscoveryClient { +func newCachedDiscoveryClient(delegate DiscoveryInterface, cacheDirectory string, ttl time.Duration) *CachedDiscoveryClient { return &CachedDiscoveryClient{ delegate: delegate, cacheDirectory: cacheDirectory, diff --git a/pkg/kubectl/cmd/util/cached_discovery_test.go b/staging/src/k8s.io/client-go/discovery/cached_discovery_test.go similarity index 94% rename from pkg/kubectl/cmd/util/cached_discovery_test.go rename to staging/src/k8s.io/client-go/discovery/cached_discovery_test.go index 46cbc9c3872..278931c2d09 100644 --- a/pkg/kubectl/cmd/util/cached_discovery_test.go +++ b/staging/src/k8s.io/client-go/discovery/cached_discovery_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package util +package discovery import ( "io/ioutil" @@ -29,7 +29,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/version" - "k8s.io/client-go/discovery" restclient "k8s.io/client-go/rest" "k8s.io/client-go/rest/fake" ) @@ -42,7 +41,7 @@ func TestCachedDiscoveryClient_Fresh(t *testing.T) { defer os.RemoveAll(d) c := fakeDiscoveryClient{} - cdc := NewCachedDiscoveryClient(&c, d, 60*time.Second) + cdc := newCachedDiscoveryClient(&c, d, 60*time.Second) assert.True(cdc.Fresh(), "should be fresh after creation") cdc.ServerGroups() @@ -61,7 +60,7 @@ func TestCachedDiscoveryClient_Fresh(t *testing.T) { assert.True(cdc.Fresh(), "should be fresh after another resources call") assert.Equal(c.resourceCalls, 1) - cdc = NewCachedDiscoveryClient(&c, d, 60*time.Second) + cdc = newCachedDiscoveryClient(&c, d, 60*time.Second) cdc.ServerGroups() assert.False(cdc.Fresh(), "should NOT be fresh after recreation with existing groups cache") assert.Equal(c.groupCalls, 1) @@ -86,7 +85,7 @@ func TestNewCachedDiscoveryClient_TTL(t *testing.T) { defer os.RemoveAll(d) c := fakeDiscoveryClient{} - cdc := NewCachedDiscoveryClient(&c, d, 1*time.Nanosecond) + cdc := newCachedDiscoveryClient(&c, d, 1*time.Nanosecond) cdc.ServerGroups() assert.Equal(c.groupCalls, 1) @@ -105,7 +104,7 @@ type fakeDiscoveryClient struct { serverResourcesHandler func() ([]*metav1.APIResourceList, error) } -var _ discovery.DiscoveryInterface = &fakeDiscoveryClient{} +var _ DiscoveryInterface = &fakeDiscoveryClient{} func (c *fakeDiscoveryClient) RESTClient() restclient.Interface { return &fake.RESTClient{} diff --git a/pkg/kubectl/cmd/util/transport/round_tripper.go b/staging/src/k8s.io/client-go/discovery/round_tripper.go similarity index 90% rename from pkg/kubectl/cmd/util/transport/round_tripper.go rename to staging/src/k8s.io/client-go/discovery/round_tripper.go index 82e3e502e5e..2e352b888f2 100644 --- a/pkg/kubectl/cmd/util/transport/round_tripper.go +++ b/staging/src/k8s.io/client-go/discovery/round_tripper.go @@ -15,7 +15,7 @@ limitations under the License. */ // Package transport provides a round tripper capable of caching HTTP responses. -package transport +package discovery import ( "net/http" @@ -30,10 +30,10 @@ type cacheRoundTripper struct { rt *httpcache.Transport } -// NewCacheRoundTripper creates a roundtripper that reads the ETag on +// newCacheRoundTripper creates a roundtripper that reads the ETag on // response headers and send the If-None-Match header on subsequent // corresponding requests. -func NewCacheRoundTripper(cacheDir string, rt http.RoundTripper) http.RoundTripper { +func newCacheRoundTripper(cacheDir string, rt http.RoundTripper) http.RoundTripper { d := diskv.New(diskv.Options{ BasePath: cacheDir, TempDir: filepath.Join(cacheDir, ".diskv-temp"), diff --git a/pkg/kubectl/cmd/util/transport/round_tripper_test.go b/staging/src/k8s.io/client-go/discovery/round_tripper_test.go similarity index 97% rename from pkg/kubectl/cmd/util/transport/round_tripper_test.go rename to staging/src/k8s.io/client-go/discovery/round_tripper_test.go index e68e8e37223..b15e2e77183 100644 --- a/pkg/kubectl/cmd/util/transport/round_tripper_test.go +++ b/staging/src/k8s.io/client-go/discovery/round_tripper_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package transport +package discovery import ( "bytes" @@ -44,7 +44,7 @@ func TestCacheRoundTripper(t *testing.T) { if err != nil { t.Fatal(err) } - cache := NewCacheRoundTripper(cacheDir, rt) + cache := newCacheRoundTripper(cacheDir, rt) // First call, caches the response req := &http.Request{ diff --git a/staging/src/k8s.io/kube-aggregator/Godeps/Godeps.json b/staging/src/k8s.io/kube-aggregator/Godeps/Godeps.json index 873c9379268..843a6e7082f 100644 --- a/staging/src/k8s.io/kube-aggregator/Godeps/Godeps.json +++ b/staging/src/k8s.io/kube-aggregator/Godeps/Godeps.json @@ -170,6 +170,10 @@ "ImportPath": "github.com/golang/protobuf/ptypes/timestamp", "Rev": "1643683e1b54a9e88ad26d98f81400c8c9d9f4f9" }, + { + "ImportPath": "github.com/google/btree", + "Rev": "7d79101e329e5a3adf994758c578dab82b90c017" + }, { "ImportPath": "github.com/google/gofuzz", "Rev": "44d81051d367757e1c7c6a5a86423ece9afcf63c" @@ -186,6 +190,14 @@ "ImportPath": "github.com/googleapis/gnostic/extensions", "Rev": "0c5108395e2debce0d731cf0287ddf7242066aba" }, + { + "ImportPath": "github.com/gregjones/httpcache", + "Rev": "787624de3eb7bd915c329cba748687a3b22666a6" + }, + { + "ImportPath": "github.com/gregjones/httpcache/diskcache", + "Rev": "787624de3eb7bd915c329cba748687a3b22666a6" + }, { "ImportPath": "github.com/hashicorp/golang-lru", "Rev": "a0d98a5f288019575c6d1f4bb1573fef2d1fcdc4" @@ -238,6 +250,10 @@ "ImportPath": "github.com/pborman/uuid", "Rev": "ca53cad383cad2479bbba7f7a1a05797ec1386e4" }, + { + "ImportPath": "github.com/peterbourgon/diskv", + "Rev": "5f041e8faa004a95c88a202771f4cc3e991971e6" + }, { "ImportPath": "github.com/pmezard/go-difflib/difflib", "Rev": "d8ed2627bdf02c080bf22230dbb337003b7aba2d" diff --git a/staging/src/k8s.io/metrics/Godeps/Godeps.json b/staging/src/k8s.io/metrics/Godeps/Godeps.json index 0ebaea2c169..a6a0272e673 100644 --- a/staging/src/k8s.io/metrics/Godeps/Godeps.json +++ b/staging/src/k8s.io/metrics/Godeps/Godeps.json @@ -42,6 +42,10 @@ "ImportPath": "github.com/golang/protobuf/ptypes/timestamp", "Rev": "1643683e1b54a9e88ad26d98f81400c8c9d9f4f9" }, + { + "ImportPath": "github.com/google/btree", + "Rev": "7d79101e329e5a3adf994758c578dab82b90c017" + }, { "ImportPath": "github.com/google/gofuzz", "Rev": "44d81051d367757e1c7c6a5a86423ece9afcf63c" @@ -58,6 +62,14 @@ "ImportPath": "github.com/googleapis/gnostic/extensions", "Rev": "0c5108395e2debce0d731cf0287ddf7242066aba" }, + { + "ImportPath": "github.com/gregjones/httpcache", + "Rev": "787624de3eb7bd915c329cba748687a3b22666a6" + }, + { + "ImportPath": "github.com/gregjones/httpcache/diskcache", + "Rev": "787624de3eb7bd915c329cba748687a3b22666a6" + }, { "ImportPath": "github.com/json-iterator/go", "Rev": "2ddf6d758266fcb080a4f9e054b9f292c85e6798" @@ -70,6 +82,10 @@ "ImportPath": "github.com/modern-go/reflect2", "Rev": "05fbef0ca5da472bbf96c9322b84a53edc03c9fd" }, + { + "ImportPath": "github.com/peterbourgon/diskv", + "Rev": "5f041e8faa004a95c88a202771f4cc3e991971e6" + }, { "ImportPath": "golang.org/x/crypto/ssh/terminal", "Rev": "49796115aa4b964c318aad4f3084fdb41e9aa067" diff --git a/staging/src/k8s.io/sample-apiserver/Godeps/Godeps.json b/staging/src/k8s.io/sample-apiserver/Godeps/Godeps.json index a97149c8376..c4b92ce04bf 100644 --- a/staging/src/k8s.io/sample-apiserver/Godeps/Godeps.json +++ b/staging/src/k8s.io/sample-apiserver/Godeps/Godeps.json @@ -162,6 +162,10 @@ "ImportPath": "github.com/golang/protobuf/ptypes/timestamp", "Rev": "1643683e1b54a9e88ad26d98f81400c8c9d9f4f9" }, + { + "ImportPath": "github.com/google/btree", + "Rev": "7d79101e329e5a3adf994758c578dab82b90c017" + }, { "ImportPath": "github.com/google/gofuzz", "Rev": "44d81051d367757e1c7c6a5a86423ece9afcf63c" @@ -178,6 +182,14 @@ "ImportPath": "github.com/googleapis/gnostic/extensions", "Rev": "0c5108395e2debce0d731cf0287ddf7242066aba" }, + { + "ImportPath": "github.com/gregjones/httpcache", + "Rev": "787624de3eb7bd915c329cba748687a3b22666a6" + }, + { + "ImportPath": "github.com/gregjones/httpcache/diskcache", + "Rev": "787624de3eb7bd915c329cba748687a3b22666a6" + }, { "ImportPath": "github.com/hashicorp/golang-lru", "Rev": "a0d98a5f288019575c6d1f4bb1573fef2d1fcdc4" @@ -226,6 +238,10 @@ "ImportPath": "github.com/pborman/uuid", "Rev": "ca53cad383cad2479bbba7f7a1a05797ec1386e4" }, + { + "ImportPath": "github.com/peterbourgon/diskv", + "Rev": "5f041e8faa004a95c88a202771f4cc3e991971e6" + }, { "ImportPath": "github.com/prometheus/client_golang/prometheus", "Rev": "e7e903064f5e9eb5da98208bae10b475d4db0f8c" diff --git a/staging/src/k8s.io/sample-controller/Godeps/Godeps.json b/staging/src/k8s.io/sample-controller/Godeps/Godeps.json index 58b689d0628..a3817172799 100644 --- a/staging/src/k8s.io/sample-controller/Godeps/Godeps.json +++ b/staging/src/k8s.io/sample-controller/Godeps/Godeps.json @@ -50,6 +50,10 @@ "ImportPath": "github.com/golang/protobuf/ptypes/timestamp", "Rev": "1643683e1b54a9e88ad26d98f81400c8c9d9f4f9" }, + { + "ImportPath": "github.com/google/btree", + "Rev": "7d79101e329e5a3adf994758c578dab82b90c017" + }, { "ImportPath": "github.com/google/gofuzz", "Rev": "44d81051d367757e1c7c6a5a86423ece9afcf63c" @@ -66,6 +70,14 @@ "ImportPath": "github.com/googleapis/gnostic/extensions", "Rev": "0c5108395e2debce0d731cf0287ddf7242066aba" }, + { + "ImportPath": "github.com/gregjones/httpcache", + "Rev": "787624de3eb7bd915c329cba748687a3b22666a6" + }, + { + "ImportPath": "github.com/gregjones/httpcache/diskcache", + "Rev": "787624de3eb7bd915c329cba748687a3b22666a6" + }, { "ImportPath": "github.com/hashicorp/golang-lru", "Rev": "a0d98a5f288019575c6d1f4bb1573fef2d1fcdc4" @@ -90,6 +102,10 @@ "ImportPath": "github.com/modern-go/reflect2", "Rev": "05fbef0ca5da472bbf96c9322b84a53edc03c9fd" }, + { + "ImportPath": "github.com/peterbourgon/diskv", + "Rev": "5f041e8faa004a95c88a202771f4cc3e991971e6" + }, { "ImportPath": "github.com/spf13/pflag", "Rev": "583c0c0531f06d5278b7d917446061adc344b5cd" diff --git a/test/integration/apiserver/print_test.go b/test/integration/apiserver/print_test.go index 37ea8f8657b..16c7e0ff12c 100644 --- a/test/integration/apiserver/print_test.go +++ b/test/integration/apiserver/print_test.go @@ -156,10 +156,6 @@ func TestServerSidePrint(t *testing.T) { if err != nil { t.Errorf("unexpected error: %v", err) } - discoveryClient, err := discovery.NewDiscoveryClientForConfig(restConfig) - if err != nil { - t.Errorf("unexpected error: %v", err) - } cacheDir, err := ioutil.TempDir(os.TempDir(), "test-integration-apiserver-print") if err != nil { @@ -169,7 +165,12 @@ func TestServerSidePrint(t *testing.T) { os.Remove(cacheDir) }() - configFlags.WithDiscoveryClient(util.NewCachedDiscoveryClient(discoveryClient, cacheDir, time.Duration(10*time.Minute))) + cachedClient, err := discovery.NewCachedDiscoveryClientForConfig(restConfig, cacheDir, "", time.Duration(10*time.Minute)) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + + configFlags.WithDiscoveryClient(cachedClient) factory := util.NewFactory(configFlags) mapper, err := factory.RESTMapper()