From d17985f1ad3ee18e42608aea8f882ba3b79a9240 Mon Sep 17 00:00:00 2001 From: Wojciech Tyczynski Date: Thu, 30 Jul 2015 09:27:38 +0200 Subject: [PATCH] Move StorageInterface to pkg/storage. --- cmd/kube-apiserver/app/server.go | 3 +- pkg/apiserver/authn.go | 6 +- pkg/master/master.go | 5 +- pkg/registry/controller/etcd/etcd.go | 4 +- pkg/registry/controller/etcd/etcd_test.go | 3 +- pkg/registry/endpoint/etcd/etcd.go | 4 +- pkg/registry/endpoint/etcd/etcd_test.go | 3 +- pkg/registry/etcd/etcd.go | 9 +- pkg/registry/event/registry.go | 4 +- pkg/registry/generic/etcd/etcd.go | 5 +- pkg/registry/limitrange/registry.go | 4 +- pkg/registry/minion/etcd/etcd.go | 4 +- pkg/registry/minion/etcd/etcd_test.go | 3 +- pkg/registry/namespace/etcd/etcd.go | 4 +- pkg/registry/namespace/etcd/etcd_test.go | 5 +- pkg/registry/persistentvolume/etcd/etcd.go | 4 +- .../persistentvolume/etcd/etcd_test.go | 3 +- .../persistentvolumeclaim/etcd/etcd.go | 4 +- .../persistentvolumeclaim/etcd/etcd_test.go | 3 +- pkg/registry/pod/etcd/etcd.go | 3 +- pkg/registry/pod/etcd/etcd_test.go | 5 +- pkg/registry/podtemplate/etcd/etcd.go | 4 +- pkg/registry/podtemplate/etcd/etcd_test.go | 3 +- pkg/registry/resourcequota/etcd/etcd.go | 4 +- pkg/registry/resourcequota/etcd/etcd_test.go | 5 +- pkg/registry/secret/etcd/etcd.go | 4 +- pkg/registry/secret/etcd/etcd_test.go | 3 +- pkg/registry/service/allocator/etcd/etcd.go | 5 +- .../service/allocator/etcd/etcd_test.go | 3 +- .../service/ipallocator/etcd/etcd_test.go | 3 +- pkg/registry/serviceaccount/etcd/etcd.go | 4 +- pkg/registry/serviceaccount/etcd/etcd_test.go | 3 +- pkg/serviceaccount/tokengetter.go | 4 +- pkg/storage/doc.go | 18 +++ pkg/storage/interfaces.go | 149 ++++++++++++++++++ pkg/tools/etcd_helper.go | 23 +-- pkg/tools/etcd_helper_test.go | 7 +- pkg/tools/etcd_object.go | 3 +- pkg/tools/etcd_watcher.go | 16 +- pkg/tools/etcd_watcher_test.go | 25 +-- pkg/tools/interfaces.go | 121 -------------- test/integration/framework/etcd_utils.go | 4 +- test/integration/framework/master_utils.go | 8 +- 43 files changed, 284 insertions(+), 223 deletions(-) create mode 100644 pkg/storage/doc.go create mode 100644 pkg/storage/interfaces.go diff --git a/cmd/kube-apiserver/app/server.go b/cmd/kube-apiserver/app/server.go index b9c811d82ca..cda6ca16448 100644 --- a/cmd/kube-apiserver/app/server.go +++ b/cmd/kube-apiserver/app/server.go @@ -38,6 +38,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider" "github.com/GoogleCloudPlatform/kubernetes/pkg/master" "github.com/GoogleCloudPlatform/kubernetes/pkg/master/ports" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" forked "github.com/GoogleCloudPlatform/kubernetes/third_party/forked/coreos/go-etcd/etcd" @@ -216,7 +217,7 @@ func (s *APIServer) verifyClusterIPFlags() { } } -func newEtcd(etcdConfigFile string, etcdServerList util.StringList, storageVersion string, pathPrefix string) (etcdStorage tools.StorageInterface, err error) { +func newEtcd(etcdConfigFile string, etcdServerList util.StringList, storageVersion string, pathPrefix string) (etcdStorage storage.StorageInterface, err error) { var client tools.EtcdClient if etcdConfigFile != "" { client, err = etcd.NewClientFromFile(etcdConfigFile) diff --git a/pkg/apiserver/authn.go b/pkg/apiserver/authn.go index eb71b372957..bb393f65043 100644 --- a/pkg/apiserver/authn.go +++ b/pkg/apiserver/authn.go @@ -22,7 +22,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/auth/authenticator" "github.com/GoogleCloudPlatform/kubernetes/pkg/auth/authenticator/bearertoken" "github.com/GoogleCloudPlatform/kubernetes/pkg/serviceaccount" - "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/auth/authenticator/password/passwordfile" "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/auth/authenticator/request/basicauth" @@ -32,7 +32,7 @@ import ( ) // NewAuthenticator returns an authenticator.Request or an error -func NewAuthenticator(basicAuthFile, clientCAFile, tokenFile, serviceAccountKeyFile string, serviceAccountLookup bool, storage tools.StorageInterface) (authenticator.Request, error) { +func NewAuthenticator(basicAuthFile, clientCAFile, tokenFile, serviceAccountKeyFile string, serviceAccountLookup bool, storage storage.StorageInterface) (authenticator.Request, error) { var authenticators []authenticator.Request if len(basicAuthFile) > 0 { @@ -104,7 +104,7 @@ func newAuthenticatorFromTokenFile(tokenAuthFile string) (authenticator.Request, } // newServiceAccountAuthenticator returns an authenticator.Request or an error -func newServiceAccountAuthenticator(keyfile string, lookup bool, storage tools.StorageInterface) (authenticator.Request, error) { +func newServiceAccountAuthenticator(keyfile string, lookup bool, storage storage.StorageInterface) (authenticator.Request, error) { publicKey, err := serviceaccount.ReadPublicKey(keyfile) if err != nil { return nil, err diff --git a/pkg/master/master.go b/pkg/master/master.go index d7cf999a78f..ad04378d5ad 100644 --- a/pkg/master/master.go +++ b/pkg/master/master.go @@ -69,6 +69,7 @@ import ( etcdallocator "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service/allocator/etcd" ipallocator "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service/ipallocator" serviceaccountetcd "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/serviceaccount/etcd" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/ui" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" @@ -87,7 +88,7 @@ const ( // Config is a structure used to configure a Master. type Config struct { - DatabaseStorage tools.StorageInterface + DatabaseStorage storage.StorageInterface EventTTL time.Duration MinionRegexp string KubeletClient client.KubeletClient @@ -225,7 +226,7 @@ type Master struct { // NewEtcdStorage returns a StorageInterface for the provided arguments or an error if the version // is incorrect. -func NewEtcdStorage(client tools.EtcdClient, version string, prefix string) (etcdStorage tools.StorageInterface, err error) { +func NewEtcdStorage(client tools.EtcdClient, version string, prefix string) (etcdStorage storage.StorageInterface, err error) { if version == "" { version = latest.Version } diff --git a/pkg/registry/controller/etcd/etcd.go b/pkg/registry/controller/etcd/etcd.go index 6fa75e4b11a..9acdd12e610 100644 --- a/pkg/registry/controller/etcd/etcd.go +++ b/pkg/registry/controller/etcd/etcd.go @@ -24,7 +24,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic" etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" - "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" ) // rest implements a RESTStorage for replication controllers against etcd @@ -37,7 +37,7 @@ type REST struct { var controllerPrefix = "/controllers" // NewREST returns a RESTStorage object that will work against replication controllers. -func NewREST(s tools.StorageInterface) *REST { +func NewREST(s storage.StorageInterface) *REST { store := &etcdgeneric.Etcd{ NewFunc: func() runtime.Object { return &api.ReplicationController{} }, diff --git a/pkg/registry/controller/etcd/etcd_test.go b/pkg/registry/controller/etcd/etcd_test.go index b2c309a2f1e..d2606cd1523 100644 --- a/pkg/registry/controller/etcd/etcd_test.go +++ b/pkg/registry/controller/etcd/etcd_test.go @@ -30,6 +30,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/coreos/go-etcd/etcd" @@ -40,7 +41,7 @@ const ( FAIL ) -func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, tools.StorageInterface) { +func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.StorageInterface) { fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient.TestIndex = true etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix()) diff --git a/pkg/registry/endpoint/etcd/etcd.go b/pkg/registry/endpoint/etcd/etcd.go index 7ca422d742e..2a0b10cb143 100644 --- a/pkg/registry/endpoint/etcd/etcd.go +++ b/pkg/registry/endpoint/etcd/etcd.go @@ -24,7 +24,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic" etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" - "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" ) // rest implements a RESTStorage for endpoints against etcd @@ -33,7 +33,7 @@ type REST struct { } // NewStorage returns a RESTStorage object that will work against endpoints. -func NewStorage(s tools.StorageInterface) *REST { +func NewStorage(s storage.StorageInterface) *REST { prefix := "/services/endpoints" return &REST{ &etcdgeneric.Etcd{ diff --git a/pkg/registry/endpoint/etcd/etcd_test.go b/pkg/registry/endpoint/etcd/etcd_test.go index 45adbe7c3b9..e7d75bd91cd 100644 --- a/pkg/registry/endpoint/etcd/etcd_test.go +++ b/pkg/registry/endpoint/etcd/etcd_test.go @@ -25,6 +25,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/fields" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" @@ -32,7 +33,7 @@ import ( "github.com/coreos/go-etcd/etcd" ) -func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, tools.StorageInterface) { +func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.StorageInterface) { fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient.TestIndex = true etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix()) diff --git a/pkg/registry/etcd/etcd.go b/pkg/registry/etcd/etcd.go index 16dab56f1e3..6a907f6753c 100644 --- a/pkg/registry/etcd/etcd.go +++ b/pkg/registry/etcd/etcd.go @@ -26,6 +26,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/endpoint" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch" ) @@ -44,13 +45,13 @@ const ( // Registry implements BindingRegistry, ControllerRegistry, EndpointRegistry, // MinionRegistry, PodRegistry and ServiceRegistry, backed by etcd. type Registry struct { - tools.StorageInterface + storage.StorageInterface pods pod.Registry endpoints endpoint.Registry } // NewRegistry creates an etcd registry. -func NewRegistry(storage tools.StorageInterface, pods pod.Registry, endpoints endpoint.Registry) *Registry { +func NewRegistry(storage storage.StorageInterface, pods pod.Registry, endpoints endpoint.Registry) *Registry { registry := &Registry{ StorageInterface: storage, pods: pods, @@ -171,10 +172,10 @@ func (r *Registry) WatchServices(ctx api.Context, label labels.Selector, field f return nil, err } // TODO: use generic.SelectionPredicate - return r.Watch(key, version, tools.Everything) + return r.Watch(key, version, storage.Everything) } if field.Empty() { - return r.WatchList(makeServiceListKey(ctx), version, tools.Everything) + return r.WatchList(makeServiceListKey(ctx), version, storage.Everything) } return nil, fmt.Errorf("only the 'name' and default (everything) field selectors are supported") } diff --git a/pkg/registry/event/registry.go b/pkg/registry/event/registry.go index 3856dbd9c6c..cf129c6493b 100644 --- a/pkg/registry/event/registry.go +++ b/pkg/registry/event/registry.go @@ -21,7 +21,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic" etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" - "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" ) // registry implements custom changes to generic.Etcd. @@ -31,7 +31,7 @@ type registry struct { // NewEtcdRegistry returns a registry which will store Events in the given // EtcdStorage. ttl is the time that Events will be retained by the system. -func NewEtcdRegistry(s tools.StorageInterface, ttl uint64) generic.Registry { +func NewEtcdRegistry(s storage.StorageInterface, ttl uint64) generic.Registry { prefix := "/events" return registry{ Etcd: &etcdgeneric.Etcd{ diff --git a/pkg/registry/generic/etcd/etcd.go b/pkg/registry/generic/etcd/etcd.go index 21db4d79ce2..c0a0db5d32e 100644 --- a/pkg/registry/generic/etcd/etcd.go +++ b/pkg/registry/generic/etcd/etcd.go @@ -29,6 +29,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch" @@ -103,7 +104,7 @@ type Etcd struct { ReturnDeletedObject bool // Used for all etcd access functions - Storage tools.StorageInterface + Storage storage.StorageInterface } // NamespaceKeyRootFunc is the default function for constructing etcd paths to resource directories enforcing namespace rules. @@ -282,7 +283,7 @@ func (e *Etcd) Update(ctx api.Context, obj runtime.Object) (runtime.Object, bool // TODO: expose TTL creating := false out := e.NewFunc() - err = e.Storage.GuaranteedUpdate(key, out, true, func(existing runtime.Object, res tools.ResponseMeta) (runtime.Object, *uint64, error) { + err = e.Storage.GuaranteedUpdate(key, out, true, func(existing runtime.Object, res storage.ResponseMeta) (runtime.Object, *uint64, error) { version, err := e.Storage.Versioner().ObjectResourceVersion(existing) if err != nil { return nil, nil, err diff --git a/pkg/registry/limitrange/registry.go b/pkg/registry/limitrange/registry.go index 45fd524d2eb..bca1ab6e2b4 100644 --- a/pkg/registry/limitrange/registry.go +++ b/pkg/registry/limitrange/registry.go @@ -21,7 +21,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic" etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" - "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" ) // registry implements custom changes to generic.Etcd. @@ -30,7 +30,7 @@ type registry struct { } // NewEtcdRegistry returns a registry which will store LimitRange in the given storage -func NewEtcdRegistry(s tools.StorageInterface) generic.Registry { +func NewEtcdRegistry(s storage.StorageInterface) generic.Registry { prefix := "/limitranges" return registry{ Etcd: &etcdgeneric.Etcd{ diff --git a/pkg/registry/minion/etcd/etcd.go b/pkg/registry/minion/etcd/etcd.go index 9c8bd7c73e3..1339d4f6f02 100644 --- a/pkg/registry/minion/etcd/etcd.go +++ b/pkg/registry/minion/etcd/etcd.go @@ -26,7 +26,7 @@ import ( etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/minion" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" - "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" ) type REST struct { @@ -49,7 +49,7 @@ func (r *StatusREST) Update(ctx api.Context, obj runtime.Object) (runtime.Object } // NewStorage returns a RESTStorage object that will work against nodes. -func NewStorage(s tools.StorageInterface, connection client.ConnectionInfoGetter) (*REST, *StatusREST) { +func NewStorage(s storage.StorageInterface, connection client.ConnectionInfoGetter) (*REST, *StatusREST) { prefix := "/minions" store := &etcdgeneric.Etcd{ NewFunc: func() runtime.Object { return &api.Node{} }, diff --git a/pkg/registry/minion/etcd/etcd_test.go b/pkg/registry/minion/etcd/etcd_test.go index 6fe9ed47239..2c22b8a62f2 100644 --- a/pkg/registry/minion/etcd/etcd_test.go +++ b/pkg/registry/minion/etcd/etcd_test.go @@ -29,6 +29,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/fields" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" @@ -47,7 +48,7 @@ func (fakeConnectionInfoGetter) GetConnectionInfo(host string) (string, uint, ht return "http", 12345, nil, nil } -func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, tools.StorageInterface) { +func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.StorageInterface) { fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient.TestIndex = true etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix()) diff --git a/pkg/registry/namespace/etcd/etcd.go b/pkg/registry/namespace/etcd/etcd.go index aad15116686..2ad947ba584 100644 --- a/pkg/registry/namespace/etcd/etcd.go +++ b/pkg/registry/namespace/etcd/etcd.go @@ -28,7 +28,7 @@ import ( etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/namespace" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" - "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" ) @@ -49,7 +49,7 @@ type FinalizeREST struct { } // NewStorage returns a RESTStorage object that will work against namespaces -func NewStorage(s tools.StorageInterface) (*REST, *StatusREST, *FinalizeREST) { +func NewStorage(s storage.StorageInterface) (*REST, *StatusREST, *FinalizeREST) { prefix := "/namespaces" store := &etcdgeneric.Etcd{ NewFunc: func() runtime.Object { return &api.Namespace{} }, diff --git a/pkg/registry/namespace/etcd/etcd_test.go b/pkg/registry/namespace/etcd/etcd_test.go index c1cbbd9fe67..88ac5a630fb 100644 --- a/pkg/registry/namespace/etcd/etcd_test.go +++ b/pkg/registry/namespace/etcd/etcd_test.go @@ -26,6 +26,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/namespace" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" @@ -33,14 +34,14 @@ import ( "github.com/coreos/go-etcd/etcd" ) -func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, tools.StorageInterface) { +func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.StorageInterface) { fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient.TestIndex = true etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix()) return fakeEtcdClient, etcdStorage } -func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient, tools.StorageInterface) { +func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient, storage.StorageInterface) { fakeEtcdClient, s := newEtcdStorage(t) storage, _, _ := NewStorage(s) return storage, fakeEtcdClient, s diff --git a/pkg/registry/persistentvolume/etcd/etcd.go b/pkg/registry/persistentvolume/etcd/etcd.go index dcb4c305641..a08077aea1c 100644 --- a/pkg/registry/persistentvolume/etcd/etcd.go +++ b/pkg/registry/persistentvolume/etcd/etcd.go @@ -26,7 +26,7 @@ import ( etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/persistentvolume" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" - "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" ) // rest implements a RESTStorage for persistentvolumes against etcd @@ -35,7 +35,7 @@ type REST struct { } // NewREST returns a RESTStorage object that will work against PersistentVolume objects. -func NewStorage(s tools.StorageInterface) (*REST, *StatusREST) { +func NewStorage(s storage.StorageInterface) (*REST, *StatusREST) { prefix := "/persistentvolumes" store := &etcdgeneric.Etcd{ NewFunc: func() runtime.Object { return &api.PersistentVolume{} }, diff --git a/pkg/registry/persistentvolume/etcd/etcd_test.go b/pkg/registry/persistentvolume/etcd/etcd_test.go index b1ea67d7913..36f2c223943 100644 --- a/pkg/registry/persistentvolume/etcd/etcd_test.go +++ b/pkg/registry/persistentvolume/etcd/etcd_test.go @@ -27,6 +27,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" @@ -38,7 +39,7 @@ type testRegistry struct { *registrytest.GenericRegistry } -func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient, tools.StorageInterface) { +func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient, storage.StorageInterface) { fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient.TestIndex = true etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix()) diff --git a/pkg/registry/persistentvolumeclaim/etcd/etcd.go b/pkg/registry/persistentvolumeclaim/etcd/etcd.go index 43c43b0e546..5461a53b2bc 100644 --- a/pkg/registry/persistentvolumeclaim/etcd/etcd.go +++ b/pkg/registry/persistentvolumeclaim/etcd/etcd.go @@ -24,7 +24,7 @@ import ( etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/persistentvolumeclaim" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" - "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" ) // rest implements a RESTStorage for persistentvolumeclaims against etcd @@ -33,7 +33,7 @@ type REST struct { } // NewREST returns a RESTStorage object that will work against PersistentVolumeClaim objects. -func NewStorage(s tools.StorageInterface) (*REST, *StatusREST) { +func NewStorage(s storage.StorageInterface) (*REST, *StatusREST) { prefix := "/persistentvolumeclaims" store := &etcdgeneric.Etcd{ NewFunc: func() runtime.Object { return &api.PersistentVolumeClaim{} }, diff --git a/pkg/registry/persistentvolumeclaim/etcd/etcd_test.go b/pkg/registry/persistentvolumeclaim/etcd/etcd_test.go index 3325abc448c..3eeb9ed4911 100644 --- a/pkg/registry/persistentvolumeclaim/etcd/etcd_test.go +++ b/pkg/registry/persistentvolumeclaim/etcd/etcd_test.go @@ -27,6 +27,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" @@ -38,7 +39,7 @@ type testRegistry struct { *registrytest.GenericRegistry } -func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient, tools.StorageInterface) { +func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient, storage.StorageInterface) { fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient.TestIndex = true etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix()) diff --git a/pkg/registry/pod/etcd/etcd.go b/pkg/registry/pod/etcd/etcd.go index bb7b4e2f716..dd402a6077d 100644 --- a/pkg/registry/pod/etcd/etcd.go +++ b/pkg/registry/pod/etcd/etcd.go @@ -35,6 +35,7 @@ import ( genericrest "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/rest" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/util/fielderrors" ) @@ -56,7 +57,7 @@ type REST struct { } // NewStorage returns a RESTStorage object that will work against pods. -func NewStorage(s tools.StorageInterface, k client.ConnectionInfoGetter) PodStorage { +func NewStorage(s storage.StorageInterface, k client.ConnectionInfoGetter) PodStorage { prefix := "/pods" store := &etcdgeneric.Etcd{ NewFunc: func() runtime.Object { return &api.Pod{} }, diff --git a/pkg/registry/pod/etcd/etcd_test.go b/pkg/registry/pod/etcd/etcd_test.go index e89ab1513f7..2cdc935dcdd 100644 --- a/pkg/registry/pod/etcd/etcd_test.go +++ b/pkg/registry/pod/etcd/etcd_test.go @@ -33,6 +33,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/securitycontext" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" @@ -40,14 +41,14 @@ import ( "github.com/coreos/go-etcd/etcd" ) -func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, tools.StorageInterface) { +func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.StorageInterface) { fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient.TestIndex = true etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix()) return fakeEtcdClient, etcdStorage } -func newStorage(t *testing.T) (*REST, *BindingREST, *StatusREST, *tools.FakeEtcdClient, tools.StorageInterface) { +func newStorage(t *testing.T) (*REST, *BindingREST, *StatusREST, *tools.FakeEtcdClient, storage.StorageInterface) { fakeEtcdClient, etcdStorage := newEtcdStorage(t) storage := NewStorage(etcdStorage, nil) return storage.Pod, storage.Binding, storage.Status, fakeEtcdClient, etcdStorage diff --git a/pkg/registry/podtemplate/etcd/etcd.go b/pkg/registry/podtemplate/etcd/etcd.go index 4140c0702a1..466940b7d7b 100644 --- a/pkg/registry/podtemplate/etcd/etcd.go +++ b/pkg/registry/podtemplate/etcd/etcd.go @@ -24,7 +24,7 @@ import ( etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/podtemplate" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" - "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" ) // rest implements a RESTStorage for pod templates against etcd @@ -33,7 +33,7 @@ type REST struct { } // NewREST returns a RESTStorage object that will work against pod templates. -func NewREST(s tools.StorageInterface) *REST { +func NewREST(s storage.StorageInterface) *REST { prefix := "/podtemplates" store := etcdgeneric.Etcd{ NewFunc: func() runtime.Object { return &api.PodTemplate{} }, diff --git a/pkg/registry/podtemplate/etcd/etcd_test.go b/pkg/registry/podtemplate/etcd/etcd_test.go index 0ac4adf5f22..8db20014533 100644 --- a/pkg/registry/podtemplate/etcd/etcd_test.go +++ b/pkg/registry/podtemplate/etcd/etcd_test.go @@ -22,11 +22,12 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest/resttest" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" ) -func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, tools.StorageInterface) { +func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.StorageInterface) { fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient.TestIndex = true etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix()) diff --git a/pkg/registry/resourcequota/etcd/etcd.go b/pkg/registry/resourcequota/etcd/etcd.go index 9b5b1c9eba5..e542593d928 100644 --- a/pkg/registry/resourcequota/etcd/etcd.go +++ b/pkg/registry/resourcequota/etcd/etcd.go @@ -24,7 +24,7 @@ import ( etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequota" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" - "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" ) // rest implements a RESTStorage for resourcequotas against etcd @@ -33,7 +33,7 @@ type REST struct { } // NewStorage returns a RESTStorage object that will work against ResourceQuota objects. -func NewStorage(s tools.StorageInterface) (*REST, *StatusREST) { +func NewStorage(s storage.StorageInterface) (*REST, *StatusREST) { prefix := "/resourcequotas" store := &etcdgeneric.Etcd{ NewFunc: func() runtime.Object { return &api.ResourceQuota{} }, diff --git a/pkg/registry/resourcequota/etcd/etcd_test.go b/pkg/registry/resourcequota/etcd/etcd_test.go index c7b7d5f16e3..71c9c909452 100644 --- a/pkg/registry/resourcequota/etcd/etcd_test.go +++ b/pkg/registry/resourcequota/etcd/etcd_test.go @@ -31,6 +31,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequota" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" @@ -38,14 +39,14 @@ import ( "github.com/coreos/go-etcd/etcd" ) -func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, tools.StorageInterface) { +func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.StorageInterface) { fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient.TestIndex = true etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix()) return fakeEtcdClient, etcdStorage } -func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient, tools.StorageInterface) { +func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient, storage.StorageInterface) { fakeEtcdClient, h := newEtcdStorage(t) storage, statusStorage := NewStorage(h) return storage, statusStorage, fakeEtcdClient, h diff --git a/pkg/registry/secret/etcd/etcd.go b/pkg/registry/secret/etcd/etcd.go index c9d6b0d7ca6..4a956041315 100644 --- a/pkg/registry/secret/etcd/etcd.go +++ b/pkg/registry/secret/etcd/etcd.go @@ -24,7 +24,7 @@ import ( etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/secret" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" - "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" ) // REST implements a RESTStorage for secrets against etcd @@ -33,7 +33,7 @@ type REST struct { } // NewStorage returns a registry which will store Secret in the given etcdStorage -func NewStorage(s tools.StorageInterface) *REST { +func NewStorage(s storage.StorageInterface) *REST { prefix := "/secrets" store := &etcdgeneric.Etcd{ diff --git a/pkg/registry/secret/etcd/etcd_test.go b/pkg/registry/secret/etcd/etcd_test.go index 83047bdc95b..b9a5bf6a1a4 100644 --- a/pkg/registry/secret/etcd/etcd_test.go +++ b/pkg/registry/secret/etcd/etcd_test.go @@ -22,11 +22,12 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest/resttest" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" ) -func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, tools.StorageInterface) { +func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.StorageInterface) { fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient.TestIndex = true etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix()) diff --git a/pkg/registry/service/allocator/etcd/etcd.go b/pkg/registry/service/allocator/etcd/etcd.go index 924391a83ed..2e17119beb6 100644 --- a/pkg/registry/service/allocator/etcd/etcd.go +++ b/pkg/registry/service/allocator/etcd/etcd.go @@ -27,6 +27,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service/allocator" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" ) @@ -42,7 +43,7 @@ type Etcd struct { lock sync.Mutex alloc allocator.Snapshottable - storage tools.StorageInterface + storage storage.StorageInterface last string baseKey string @@ -55,7 +56,7 @@ var _ service.RangeRegistry = &Etcd{} // NewEtcd returns an allocator that is backed by Etcd and can manage // persisting the snapshot state of allocation after each allocation is made. -func NewEtcd(alloc allocator.Snapshottable, baseKey string, kind string, storage tools.StorageInterface) *Etcd { +func NewEtcd(alloc allocator.Snapshottable, baseKey string, kind string, storage storage.StorageInterface) *Etcd { return &Etcd{ alloc: alloc, storage: storage, diff --git a/pkg/registry/service/allocator/etcd/etcd_test.go b/pkg/registry/service/allocator/etcd/etcd_test.go index a3d3c48b19b..90577494a80 100644 --- a/pkg/registry/service/allocator/etcd/etcd_test.go +++ b/pkg/registry/service/allocator/etcd/etcd_test.go @@ -26,11 +26,12 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service/allocator" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" ) -func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, tools.StorageInterface) { +func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.StorageInterface) { fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient.TestIndex = true etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix()) diff --git a/pkg/registry/service/ipallocator/etcd/etcd_test.go b/pkg/registry/service/ipallocator/etcd/etcd_test.go index 9c7620ecf5d..047a8dbeb10 100644 --- a/pkg/registry/service/ipallocator/etcd/etcd_test.go +++ b/pkg/registry/service/ipallocator/etcd/etcd_test.go @@ -29,11 +29,12 @@ import ( allocator_etcd "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service/allocator/etcd" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service/ipallocator" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" ) -func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, tools.StorageInterface) { +func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.StorageInterface) { fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient.TestIndex = true etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix()) diff --git a/pkg/registry/serviceaccount/etcd/etcd.go b/pkg/registry/serviceaccount/etcd/etcd.go index c160c3be8fa..23a5703ae81 100644 --- a/pkg/registry/serviceaccount/etcd/etcd.go +++ b/pkg/registry/serviceaccount/etcd/etcd.go @@ -24,7 +24,7 @@ import ( etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/serviceaccount" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" - "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" ) // REST implements a RESTStorage for service accounts against etcd @@ -35,7 +35,7 @@ type REST struct { const Prefix = "/serviceaccounts" // NewStorage returns a RESTStorage object that will work against service accounts objects. -func NewStorage(s tools.StorageInterface) *REST { +func NewStorage(s storage.StorageInterface) *REST { store := &etcdgeneric.Etcd{ NewFunc: func() runtime.Object { return &api.ServiceAccount{} }, NewListFunc: func() runtime.Object { return &api.ServiceAccountList{} }, diff --git a/pkg/registry/serviceaccount/etcd/etcd_test.go b/pkg/registry/serviceaccount/etcd/etcd_test.go index 3eef9c627d2..1cafbed79f2 100644 --- a/pkg/registry/serviceaccount/etcd/etcd_test.go +++ b/pkg/registry/serviceaccount/etcd/etcd_test.go @@ -22,11 +22,12 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest/resttest" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" ) -func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, tools.StorageInterface) { +func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.StorageInterface) { fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient.TestIndex = true etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix()) diff --git a/pkg/serviceaccount/tokengetter.go b/pkg/serviceaccount/tokengetter.go index 869cc92211e..edd2bd3bb3f 100644 --- a/pkg/serviceaccount/tokengetter.go +++ b/pkg/serviceaccount/tokengetter.go @@ -23,7 +23,7 @@ import ( secretetcd "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/secret/etcd" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/serviceaccount" serviceaccountetcd "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/serviceaccount/etcd" - "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" ) // ServiceAccountTokenGetter defines functions to retrieve a named service account and secret @@ -73,7 +73,7 @@ func (r *registryGetter) GetSecret(namespace, name string) (*api.Secret, error) // NewGetterFromStorageInterface returns a ServiceAccountTokenGetter that // uses the specified storage to retrieve service accounts and secrets. -func NewGetterFromStorageInterface(storage tools.StorageInterface) ServiceAccountTokenGetter { +func NewGetterFromStorageInterface(storage storage.StorageInterface) ServiceAccountTokenGetter { return NewGetterFromRegistries( serviceaccount.NewRegistry(serviceaccountetcd.NewStorage(storage)), secret.NewRegistry(secretetcd.NewStorage(storage)), diff --git a/pkg/storage/doc.go b/pkg/storage/doc.go new file mode 100644 index 00000000000..dca0d5b7096 --- /dev/null +++ b/pkg/storage/doc.go @@ -0,0 +1,18 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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. +*/ + +// Interfaces for database-related operations. +package storage diff --git a/pkg/storage/interfaces.go b/pkg/storage/interfaces.go new file mode 100644 index 00000000000..2e71d8bf8bd --- /dev/null +++ b/pkg/storage/interfaces.go @@ -0,0 +1,149 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 storage + +import ( + "time" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" + "github.com/GoogleCloudPlatform/kubernetes/pkg/watch" +) + +// StorageVersioner abstracts setting and retrieving metadata fields from database response +// onto the object ot list. +type StorageVersioner interface { + // UpdateObject sets storage metadata into an API object. Returns an error if the object + // cannot be updated correctly. May return nil if the requested object does not need metadata + // from database. + UpdateObject(obj runtime.Object, expiration *time.Time, resourceVersion uint64) error + // UpdateList sets the resource version into an API list object. Returns an error if the object + // cannot be updated correctly. May return nil if the requested object does not need metadata + // from database. + UpdateList(obj runtime.Object, resourceVersion uint64) error + // ObjectResourceVersion returns the resource version (for persistence) of the specified object. + // Should return an error if the specified object does not have a persistable version. + ObjectResourceVersion(obj runtime.Object) (uint64, error) +} + +// ResponseMeta contains information about the database metadata that is associated with +// an object. It abstracts the actual underlying objects to prevent coupling with concrete +// database and to improve testability. +type ResponseMeta struct { + // TTL is the time to live of the node that contained the returned object. It may be + // zero or negative in some cases (objects may be expired after the requested + // expiration time due to server lag). + TTL int64 + // Expiration is the time at which the node that contained the returned object will expire and be deleted. + // This can be nil if there is no expiration time set for the node. + Expiration *time.Time + // The resource version of the node that contained the returned object. + ResourceVersion uint64 +} + +// FilterFunc is a predicate which takes an API object and returns true +// iff the object should remain in the set. +type FilterFunc func(obj runtime.Object) bool + +// Everything is a FilterFunc which accepts all objects. +func Everything(runtime.Object) bool { + return true +} + +// Pass an StorageUpdateFunc to StorageInterface.GuaranteedUpdate to make an update +// that is guaranteed to succeed. +// See the comment for GuaranteedUpdate for more details. +type StorageUpdateFunc func(input runtime.Object, res ResponseMeta) (output runtime.Object, ttl *uint64, err error) + +// StorageInterface offers a common interface for object marshaling/unmarshling operations and +// hids all the storage-related operations behind it. +type StorageInterface interface { + // Returns list of servers addresses of the underyling database. + // TODO: This method is used only in a single place. Consider refactoring and getting rid + // of this method from the interface. + Backends() []string + + // Returns StorageVersioner associated with this interface. + Versioner() StorageVersioner + + // Create adds a new object at a key unless it already exists. 'ttl' is time-to-live + // in seconds (0 means forever). If no error is returned and out is not nil, out will be + // set to the read value from database. + Create(key string, obj, out runtime.Object, ttl uint64) error + + // Set marshals obj via json and stores in database under key. Will do an atomic update + // if obj's ResourceVersion field is set. 'ttl' is time-to-live in seconds (0 means forever). + // If no error is returned and out is not nil, out will be set to the read value from database. + Set(key string, obj, out runtime.Object, ttl uint64) error + + // Delete removes the specified key and returns the value that existed at that spot. + Delete(key string, out runtime.Object) error + + // RecursiveDelete removes the specified key. + // TODO: Get rid of this method and use Delete() instead. + RecursiveDelete(key string, recursive bool) error + + // Watch begins watching the specified key. Events are decoded into API objects, + // and any items passing 'filter' are sent down to returned watch.Interface. + // resourceVersion may be used to specify what version to begin watching + // (e.g. reconnecting without missing any updates). + Watch(key string, resourceVersion uint64, filter FilterFunc) (watch.Interface, error) + + // WatchList begins watching the specified key's items. Items are decoded into API + // objects and any item passing 'filter' are sent down to returned watch.Interface. + // resourceVersion may be used to specify what version to begin watching + // (e.g. reconnecting without missing any updates). + WatchList(key string, resourceVersion uint64, filter FilterFunc) (watch.Interface, error) + + // Get unmarshals json found at key into objPtr. On a not found error, will either + // return a zero object of the requested type, or an error, depending on ignoreNotFound. + // Treats empty responses and nil response nodes exactly like a not found error. + Get(key string, objPtr runtime.Object, ignoreNotFound bool) error + + // GetToList unmarshals json found at key and opaque it into *List api object + // (an object that satisfies the runtime.IsList definition). + GetToList(key string, listObj runtime.Object) error + + // List unmarshalls jsons found at directory defined by key and opaque them + // into *List api object (an object that satisfies runtime.IsList definition). + List(key string, listObj runtime.Object) error + + // GuaranteedUpdate keeps calling 'tryUpdate()' to update key 'key' (of type 'ptrToType') + // retrying the update until success if there is index conflict. + // Note that object passed to tryUpdate may change acress incovations of tryUpdate() if + // other writers are simultanously updateing it, to tryUpdate() needs to take into account + // the current contents of the object when deciding how the update object should look. + // + // Exmaple: + // + // s := /* implementation of StorageInterface */ + // err := s.GuaranteedUpdate( + // "myKey", &MyType{}, true, + // func(input runtime.Object, res ResponseMeta) (runtime.Object, *uint64, error) { + // // Before each incovation of the user defined function, "input" is reset to + // // current contents for "myKey" in database. + // curr := input.(*MyType) // Guaranteed to succeed. + // + // // Make the modification + // curr.Counter++ + // + // // Return the modified object - return an error to stop iterating. Return + // // a uint64 to alter the TTL on the object, or nil to keep it the same value. + // return cur, nil, nil + // } + // }) + GuaranteedUpdate(key string, ptrToType runtime.Object, ignoreNotFound bool, tryUpdate StorageUpdateFunc) error +} diff --git a/pkg/tools/etcd_helper.go b/pkg/tools/etcd_helper.go index 730faf3a617..f8322e7069e 100644 --- a/pkg/tools/etcd_helper.go +++ b/pkg/tools/etcd_helper.go @@ -27,6 +27,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/conversion" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/metrics" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch" @@ -35,7 +36,7 @@ import ( "github.com/golang/glog" ) -func NewEtcdStorage(client EtcdClient, codec runtime.Codec, prefix string) StorageInterface { +func NewEtcdStorage(client EtcdClient, codec runtime.Codec, prefix string) storage.StorageInterface { return &etcdHelper{ client: client, codec: codec, @@ -52,7 +53,7 @@ type etcdHelper struct { codec runtime.Codec copier runtime.ObjectCopier // optional, has to be set to perform any atomic operations - versioner StorageVersioner + versioner storage.StorageVersioner // prefix for all etcd keys pathPrefix string @@ -76,7 +77,7 @@ func (h *etcdHelper) Backends() []string { } // Implements StorageInterface. -func (h *etcdHelper) Versioner() StorageVersioner { +func (h *etcdHelper) Versioner() storage.StorageVersioner { return h.versioner } @@ -178,7 +179,7 @@ func (h *etcdHelper) RecursiveDelete(key string, recursive bool) error { } // Implements StorageInterface. -func (h *etcdHelper) Watch(key string, resourceVersion uint64, filter FilterFunc) (watch.Interface, error) { +func (h *etcdHelper) Watch(key string, resourceVersion uint64, filter storage.FilterFunc) (watch.Interface, error) { key = h.prefixEtcdKey(key) w := newEtcdWatcher(false, nil, filter, h.codec, h.versioner, nil, h) go w.etcdWatch(h.client, key, resourceVersion) @@ -186,7 +187,7 @@ func (h *etcdHelper) Watch(key string, resourceVersion uint64, filter FilterFunc } // Implements StorageInterface. -func (h *etcdHelper) WatchList(key string, resourceVersion uint64, filter FilterFunc) (watch.Interface, error) { +func (h *etcdHelper) WatchList(key string, resourceVersion uint64, filter storage.FilterFunc) (watch.Interface, error) { key = h.prefixEtcdKey(key) w := newEtcdWatcher(true, exceptKey(key), filter, h.codec, h.versioner, nil, h) go w.etcdWatch(h.client, key, resourceVersion) @@ -364,18 +365,18 @@ func (h *etcdHelper) listEtcdNode(key string) ([]*etcd.Node, uint64, error) { return result.Node.Nodes, result.EtcdIndex, nil } -type SimpleEtcdUpdateFunc func(runtime.Object) (runtime.Object, error) +type SimpleUpdateFunc func(runtime.Object) (runtime.Object, error) -// SimpleUpdateFunc converts SimpleEtcdUpdateFunc into EtcdUpdateFunc -func SimpleUpdate(fn SimpleEtcdUpdateFunc) StorageUpdateFunc { - return func(input runtime.Object, _ ResponseMeta) (runtime.Object, *uint64, error) { +// SimpleUpdateFunc converts SimpleUpdateFunc into StorageUpdateFunc +func SimpleUpdate(fn SimpleUpdateFunc) storage.StorageUpdateFunc { + return func(input runtime.Object, _ storage.ResponseMeta) (runtime.Object, *uint64, error) { out, err := fn(input) return out, nil, err } } // Implements StorageInterface. -func (h *etcdHelper) GuaranteedUpdate(key string, ptrToType runtime.Object, ignoreNotFound bool, tryUpdate StorageUpdateFunc) error { +func (h *etcdHelper) GuaranteedUpdate(key string, ptrToType runtime.Object, ignoreNotFound bool, tryUpdate storage.StorageUpdateFunc) error { v, err := conversion.EnforcePtr(ptrToType) if err != nil { // Panic is appropriate, because this is a programming error. @@ -388,7 +389,7 @@ func (h *etcdHelper) GuaranteedUpdate(key string, ptrToType runtime.Object, igno if err != nil { return err } - meta := ResponseMeta{} + meta := storage.ResponseMeta{} if node != nil { meta.TTL = node.TTL if node.Expiration != nil { diff --git a/pkg/tools/etcd_helper_test.go b/pkg/tools/etcd_helper_test.go index 32bcf3d2f92..9298fc5a6e1 100644 --- a/pkg/tools/etcd_helper_test.go +++ b/pkg/tools/etcd_helper_test.go @@ -34,6 +34,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi" "github.com/GoogleCloudPlatform/kubernetes/pkg/conversion" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/coreos/go-etcd/etcd" "github.com/stretchr/testify/assert" @@ -592,7 +593,7 @@ func TestGuaranteedUpdateTTL(t *testing.T) { // Create a new node. fakeClient.ExpectNotFoundGet(key) obj := &TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: 1} - err := helper.GuaranteedUpdate("/some/key", &TestResource{}, true, func(in runtime.Object, res ResponseMeta) (runtime.Object, *uint64, error) { + err := helper.GuaranteedUpdate("/some/key", &TestResource{}, true, func(in runtime.Object, res storage.ResponseMeta) (runtime.Object, *uint64, error) { if res.TTL != 0 { t.Fatalf("unexpected response meta: %#v", res) } @@ -618,7 +619,7 @@ func TestGuaranteedUpdateTTL(t *testing.T) { // Update an existing node. callbackCalled := false objUpdate := &TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: 2} - err = helper.GuaranteedUpdate("/some/key", &TestResource{}, true, func(in runtime.Object, res ResponseMeta) (runtime.Object, *uint64, error) { + err = helper.GuaranteedUpdate("/some/key", &TestResource{}, true, func(in runtime.Object, res storage.ResponseMeta) (runtime.Object, *uint64, error) { if res.TTL != 10 { t.Fatalf("unexpected response meta: %#v", res) } @@ -650,7 +651,7 @@ func TestGuaranteedUpdateTTL(t *testing.T) { // Update an existing node and change ttl callbackCalled = false objUpdate = &TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: 3} - err = helper.GuaranteedUpdate("/some/key", &TestResource{}, true, func(in runtime.Object, res ResponseMeta) (runtime.Object, *uint64, error) { + err = helper.GuaranteedUpdate("/some/key", &TestResource{}, true, func(in runtime.Object, res storage.ResponseMeta) (runtime.Object, *uint64, error) { if res.TTL != 10 { t.Fatalf("unexpected response meta: %#v", res) } diff --git a/pkg/tools/etcd_object.go b/pkg/tools/etcd_object.go index eda9532be62..362025b36a5 100644 --- a/pkg/tools/etcd_object.go +++ b/pkg/tools/etcd_object.go @@ -22,6 +22,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" ) @@ -74,4 +75,4 @@ func (a APIObjectVersioner) ObjectResourceVersion(obj runtime.Object) (uint64, e } // APIObjectVersioner implements StorageVersioner -var _ StorageVersioner = APIObjectVersioner{} +var _ storage.StorageVersioner = APIObjectVersioner{} diff --git a/pkg/tools/etcd_watcher.go b/pkg/tools/etcd_watcher.go index ab1ac597b81..7455a72cfeb 100644 --- a/pkg/tools/etcd_watcher.go +++ b/pkg/tools/etcd_watcher.go @@ -24,6 +24,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util/fielderrors" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch" @@ -41,15 +42,6 @@ const ( EtcdDelete = "delete" ) -// FilterFunc is a predicate which takes an API object and returns true -// iff the object should remain in the set. -type FilterFunc func(obj runtime.Object) bool - -// Everything is a FilterFunc which accepts all objects. -func Everything(runtime.Object) bool { - return true -} - // ParseWatchResourceVersion takes a resource version argument and converts it to // the etcd version we should pass to helper.Watch(). Because resourceVersion is // an opaque value, the default watch behavior for non-zero watch is to watch @@ -82,12 +74,12 @@ func exceptKey(except string) includeFunc { // etcdWatcher converts a native etcd watch to a watch.Interface. type etcdWatcher struct { encoding runtime.Codec - versioner StorageVersioner + versioner storage.StorageVersioner transform TransformFunc list bool // If we're doing a recursive watch, should be true. include includeFunc - filter FilterFunc + filter storage.FilterFunc etcdIncoming chan *etcd.Response etcdError chan error @@ -110,7 +102,7 @@ const watchWaitDuration = 100 * time.Millisecond // newEtcdWatcher returns a new etcdWatcher; if list is true, watch sub-nodes. If you provide a transform // and a versioner, the versioner must be able to handle the objects that transform creates. -func newEtcdWatcher(list bool, include includeFunc, filter FilterFunc, encoding runtime.Codec, versioner StorageVersioner, transform TransformFunc, cache etcdCache) *etcdWatcher { +func newEtcdWatcher(list bool, include includeFunc, filter storage.FilterFunc, encoding runtime.Codec, versioner storage.StorageVersioner, transform TransformFunc, cache etcdCache) *etcdWatcher { w := &etcdWatcher{ encoding: encoding, versioner: versioner, diff --git a/pkg/tools/etcd_watcher_test.go b/pkg/tools/etcd_watcher_test.go index a6e96129941..423892984ec 100644 --- a/pkg/tools/etcd_watcher_test.go +++ b/pkg/tools/etcd_watcher_test.go @@ -25,6 +25,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch" "github.com/coreos/go-etcd/etcd" @@ -165,7 +166,7 @@ func TestWatchInterpretations(t *testing.T) { } func TestWatchInterpretation_ResponseNotSet(t *testing.T) { - w := newEtcdWatcher(false, nil, Everything, codec, versioner, nil, &fakeEtcdCache{}) + w := newEtcdWatcher(false, nil, storage.Everything, codec, versioner, nil, &fakeEtcdCache{}) w.emit = func(e watch.Event) { t.Errorf("Unexpected emit: %v", e) } @@ -179,7 +180,7 @@ func TestWatchInterpretation_ResponseNotSet(t *testing.T) { func TestWatchInterpretation_ResponseNoNode(t *testing.T) { actions := []string{"create", "set", "compareAndSwap", "delete"} for _, action := range actions { - w := newEtcdWatcher(false, nil, Everything, codec, versioner, nil, &fakeEtcdCache{}) + w := newEtcdWatcher(false, nil, storage.Everything, codec, versioner, nil, &fakeEtcdCache{}) w.emit = func(e watch.Event) { t.Errorf("Unexpected emit: %v", e) } @@ -193,7 +194,7 @@ func TestWatchInterpretation_ResponseNoNode(t *testing.T) { func TestWatchInterpretation_ResponseBadData(t *testing.T) { actions := []string{"create", "set", "compareAndSwap", "delete"} for _, action := range actions { - w := newEtcdWatcher(false, nil, Everything, codec, versioner, nil, &fakeEtcdCache{}) + w := newEtcdWatcher(false, nil, storage.Everything, codec, versioner, nil, &fakeEtcdCache{}) w.emit = func(e watch.Event) { t.Errorf("Unexpected emit: %v", e) } @@ -220,7 +221,7 @@ func TestWatchEtcdError(t *testing.T) { fakeClient.WatchImmediateError = fmt.Errorf("immediate error") h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) - watching, err := h.Watch("/some/key", 4, Everything) + watching, err := h.Watch("/some/key", 4, storage.Everything) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -250,7 +251,7 @@ func TestWatch(t *testing.T) { fakeClient.expectNotFoundGetSet[prefixedKey] = struct{}{} h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) - watching, err := h.Watch(key, 0, Everything) + watching, err := h.Watch(key, 0, storage.Everything) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -425,7 +426,7 @@ func TestWatchEtcdState(t *testing.T) { } h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) - watching, err := h.Watch(baseKey, testCase.From, Everything) + watching, err := h.Watch(baseKey, testCase.From, storage.Everything) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -499,7 +500,7 @@ func TestWatchFromZeroIndex(t *testing.T) { fakeClient.Data[prefixedKey] = testCase.Response h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) - watching, err := h.Watch(key, 0, Everything) + watching, err := h.Watch(key, 0, storage.Everything) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -560,7 +561,7 @@ func TestWatchListFromZeroIndex(t *testing.T) { } h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) - watching, err := h.WatchList(key, 0, Everything) + watching, err := h.WatchList(key, 0, storage.Everything) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -600,7 +601,7 @@ func TestWatchListIgnoresRootKey(t *testing.T) { fakeClient := NewFakeEtcdClient(t) h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) - watching, err := h.WatchList(key, 1, Everything) + watching, err := h.WatchList(key, 1, storage.Everything) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -653,7 +654,7 @@ func TestWatchFromNotFound(t *testing.T) { } h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) - watching, err := h.Watch(key, 0, Everything) + watching, err := h.Watch(key, 0, storage.Everything) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -680,7 +681,7 @@ func TestWatchFromOtherError(t *testing.T) { } h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) - watching, err := h.Watch(key, 0, Everything) + watching, err := h.Watch(key, 0, storage.Everything) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -716,7 +717,7 @@ func TestWatchPurposefulShutdown(t *testing.T) { fakeClient.expectNotFoundGetSet[prefixedKey] = struct{}{} // Test purposeful shutdown - watching, err := h.Watch(key, 0, Everything) + watching, err := h.Watch(key, 0, storage.Everything) if err != nil { t.Fatalf("Unexpected error: %v", err) } diff --git a/pkg/tools/interfaces.go b/pkg/tools/interfaces.go index 589a0ca3435..02569cb28b5 100644 --- a/pkg/tools/interfaces.go +++ b/pkg/tools/interfaces.go @@ -17,11 +17,6 @@ limitations under the License. package tools import ( - "time" - - "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" - "github.com/GoogleCloudPlatform/kubernetes/pkg/watch" - "github.com/coreos/go-etcd/etcd" ) @@ -51,119 +46,3 @@ type EtcdClient interface { // the etcd client interface which doesn't, and it doesn't seem worth it to wrap the api. Watch(prefix string, waitIndex uint64, recursive bool, receiver chan *etcd.Response, stop chan bool) (*etcd.Response, error) } - -// StorageVersioner abstracts setting and retrieving metadata fields from the etcd response onto the object -// or list. -type StorageVersioner interface { - // UpdateObject sets etcd storage metadata into an API object. Returns an error if the object - // cannot be updated correctly. May return nil if the requested object does not need metadata - // from etcd. - UpdateObject(obj runtime.Object, expiration *time.Time, resourceVersion uint64) error - // UpdateList sets the resource version into an API list object. Returns an error if the object - // cannot be updated correctly. May return nil if the requested object does not need metadata - // from etcd. - UpdateList(obj runtime.Object, resourceVersion uint64) error - // ObjectResourceVersion returns the resource version (for persistence) of the specified object. - // Should return an error if the specified object does not have a persistable version. - ObjectResourceVersion(obj runtime.Object) (uint64, error) -} - -// ResponseMeta contains information about the etcd metadata that is associated with -// an object. It abstracts the actual underlying objects to prevent coupling with etcd -// and to improve testability. -type ResponseMeta struct { - // TTL is the time to live of the node that contained the returned object. It may be - // zero or negative in some cases (objects may be expired after the requested - // expiration time due to server lag). - TTL int64 - // Expiration is the time at which the node that contained the returned object will expire and be deleted. - // This can be nil if there is no expiration time set for the node. - Expiration *time.Time - // The resource version of the node that contained the returned object. - ResourceVersion uint64 -} - -// Pass an StorageUpdateFunc to StorageInterface.GuaranteedUpdate to make an update -// that is guaranteed to succeed. -// See the comment for GuaranteedUpdate for more details. -type StorageUpdateFunc func(input runtime.Object, res ResponseMeta) (output runtime.Object, ttl *uint64, err error) - -// StorageInterface offers a common interface for object marshaling/unmarshling operations and -// hids all the storage-related operations behind it. -type StorageInterface interface { - // Returns list of servers addresses of the underyling database. - // TODO: This method is used only in a single place. Consider refactoring and getting rid - // of this method from the interface. - Backends() []string - - // Returns StorageVersioner associated with this interface. - Versioner() StorageVersioner - - // Create adds a new object at a key unless it already exists. 'ttl' is time-to-live - // in seconds (0 means forever). If no error is returned and out is not nil, out will be - // set to the read value from etcd. - Create(key string, obj, out runtime.Object, ttl uint64) error - - // Set marshals obj via json and stores in etcd under key. Will do an atomic update - // if obj's ResourceVersion field is set. 'ttl' is time-to-live in seconds (0 means forever). - // If no error is returned and out is not nil, out will be set to the read value from etcd. - Set(key string, obj, out runtime.Object, ttl uint64) error - - // Delete removes the specified key and returns the value that existed at that spot. - Delete(key string, out runtime.Object) error - - // RecursiveDelete removes the specified key. - // TODO: Get rid of this method and use Delete() instead. - RecursiveDelete(key string, recursive bool) error - - // Watch begins watching the specified key. Events are decoded into API objects, - // and any items passing 'filter' are sent down to returned watch.Interface. - // resourceVersion may be used to specify what version to begin watching - // (e.g. reconnecting without missing any updates). - Watch(key string, resourceVersion uint64, filter FilterFunc) (watch.Interface, error) - - // WatchList begins watching the specified key's items. Items are decoded into API - // objects and any item passing 'filter' are sent down to returned watch.Interface. - // resourceVersion may be used to specify what version to begin watching - // (e.g. reconnecting without missing any updates). - WatchList(key string, resourceVersion uint64, filter FilterFunc) (watch.Interface, error) - - // Get unmarshals json found at key into objPtr. On a not found error, will either - // return a zero object of the requested type, or an error, depending on ignoreNotFound. - // Treats empty responses and nil response nodes exactly like a not found error. - Get(key string, objPtr runtime.Object, ignoreNotFound bool) error - - // GetToList unmarshals json found at key and opaque it into *List api object - // (an object that satisfies the runtime.IsList definition). - GetToList(key string, listObj runtime.Object) error - - // List unmarshalls jsons found at directory defined by key and opaque them - // into *List api object (an object that satisfies runtime.IsList definition). - List(key string, listObj runtime.Object) error - - // GuaranteedUpdate keeps calling 'tryUpdate()' to update key 'key' (of type 'ptrToType') - // retrying the update until success if there is etcd index conflict. - // Note that object passed to tryUpdate may change acress incovations of tryUpdate() if - // other writers are simultanously updateing it, to tryUpdate() needs to take into account - // the current contents of the object when deciding how the update object should look. - // - // Exmaple: - // - // s := /* implementation of StorageInterface */ - // err := s.GuaranteedUpdate( - // "myKey", &MyType{}, true, - // func(input runtime.Object, res ResponseMeta) (runtime.Object, *uint64, error) { - // // Before each incovation of the user defined function, "input" is reset to - // // etcd's current contents for "myKey". - // curr := input.(*MyType) // Guaranteed to succeed. - // - // // Make the modification - // curr.Counter++ - // - // // Return the modified object - return an error to stop iterating. Return - // // a uint64 to alter the TTL on the object, or nil to keep it the same value. - // return cur, nil, nil - // } - // }) - GuaranteedUpdate(key string, ptrToType runtime.Object, ignoreNotFound bool, tryUpdate StorageUpdateFunc) error -} diff --git a/test/integration/framework/etcd_utils.go b/test/integration/framework/etcd_utils.go index a46bd7bac2d..9bfac03d726 100644 --- a/test/integration/framework/etcd_utils.go +++ b/test/integration/framework/etcd_utils.go @@ -24,7 +24,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi" "github.com/GoogleCloudPlatform/kubernetes/pkg/master" - "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/coreos/go-etcd/etcd" "github.com/golang/glog" @@ -41,7 +41,7 @@ func NewEtcdClient() *etcd.Client { return etcd.NewClient([]string{}) } -func NewEtcdStorage() (tools.StorageInterface, error) { +func NewEtcdStorage() (storage.StorageInterface, error) { return master.NewEtcdStorage(NewEtcdClient(), testapi.Version(), etcdtest.PathPrefix()) } diff --git a/test/integration/framework/master_utils.go b/test/integration/framework/master_utils.go index 719972a126a..8f9220f13b0 100644 --- a/test/integration/framework/master_utils.go +++ b/test/integration/framework/master_utils.go @@ -35,7 +35,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/master" - "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" + "github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/admit" "github.com/golang/glog" @@ -72,7 +72,7 @@ type MasterComponents struct { // Used to stop master components individually, and via MasterComponents.Stop once sync.Once // Kubernetes etcd storage, has embedded etcd client - EtcdStorage tools.StorageInterface + EtcdStorage storage.StorageInterface } // Config is a struct of configuration directives for NewMasterComponents. @@ -119,13 +119,13 @@ func NewMasterComponents(c *Config) *MasterComponents { } // startMasterOrDie starts a kubernetes master and an httpserver to handle api requests -func startMasterOrDie(masterConfig *master.Config) (*master.Master, *httptest.Server, tools.StorageInterface) { +func startMasterOrDie(masterConfig *master.Config) (*master.Master, *httptest.Server, storage.StorageInterface) { var m *master.Master s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { m.Handler.ServeHTTP(w, req) })) - var etcdStorage tools.StorageInterface + var etcdStorage storage.StorageInterface var err error if masterConfig == nil { etcdStorage, err = master.NewEtcdStorage(NewEtcdClient(), "", etcdtest.PathPrefix())