Merge pull request #11806 from wojtek-t/private_etcd_helper

Make EtcdHelper private - expose only StorageInterface
This commit is contained in:
Marek Grabowski 2015-07-27 11:21:28 +02:00
commit 7cc1855c27
56 changed files with 471 additions and 482 deletions

View File

@ -132,9 +132,9 @@ func startComponents(firstManifestURL, secondManifestURL, apiVersion string) (st
cl := client.NewOrDie(&client.Config{Host: apiServer.URL, Version: apiVersion}) cl := client.NewOrDie(&client.Config{Host: apiServer.URL, Version: apiVersion})
helper, err := master.NewEtcdHelper(etcdClient, "", etcdtest.PathPrefix()) etcdStorage, err := master.NewEtcdStorage(etcdClient, "", etcdtest.PathPrefix())
if err != nil { if err != nil {
glog.Fatalf("Unable to get etcd helper: %v", err) glog.Fatalf("Unable to get etcd storage: %v", err)
} }
// Master // Master
@ -154,7 +154,7 @@ func startComponents(firstManifestURL, secondManifestURL, apiVersion string) (st
// Create a master and install handlers into mux. // Create a master and install handlers into mux.
m := master.New(&master.Config{ m := master.New(&master.Config{
EtcdHelper: helper, DatabaseStorage: etcdStorage,
KubeletClient: fakeKubeletClient{}, KubeletClient: fakeKubeletClient{},
EnableCoreControllers: true, EnableCoreControllers: true,
EnableLogsSupport: false, EnableLogsSupport: false,

View File

@ -214,12 +214,12 @@ func (s *APIServer) verifyClusterIPFlags() {
} }
} }
func newEtcd(etcdConfigFile string, etcdServerList util.StringList, storageVersion string, pathPrefix string) (helper tools.EtcdHelper, err error) { func newEtcd(etcdConfigFile string, etcdServerList util.StringList, storageVersion string, pathPrefix string) (etcdStorage tools.StorageInterface, err error) {
var client tools.EtcdClient var client tools.EtcdClient
if etcdConfigFile != "" { if etcdConfigFile != "" {
client, err = etcd.NewClientFromFile(etcdConfigFile) client, err = etcd.NewClientFromFile(etcdConfigFile)
if err != nil { if err != nil {
return helper, err return nil, err
} }
} else { } else {
etcdClient := etcd.NewClient(etcdServerList) etcdClient := etcd.NewClient(etcdServerList)
@ -234,7 +234,7 @@ func newEtcd(etcdConfigFile string, etcdServerList util.StringList, storageVersi
client = etcdClient client = etcdClient
} }
return master.NewEtcdHelper(client, storageVersion, pathPrefix) return master.NewEtcdStorage(client, storageVersion, pathPrefix)
} }
// Run runs the specified APIServer. This should never exit. // Run runs the specified APIServer. This should never exit.
@ -298,7 +298,7 @@ func (s *APIServer) Run(_ []string) error {
glog.Fatalf("Invalid server address: %v", err) glog.Fatalf("Invalid server address: %v", err)
} }
helper, err := newEtcd(s.EtcdConfigFile, s.EtcdServerList, s.StorageVersion, s.EtcdPathPrefix) etcdStorage, err := newEtcd(s.EtcdConfigFile, s.EtcdServerList, s.StorageVersion, s.EtcdPathPrefix)
if err != nil { if err != nil {
glog.Fatalf("Invalid storage version or misconfigured etcd: %v", err) glog.Fatalf("Invalid storage version or misconfigured etcd: %v", err)
} }
@ -313,7 +313,7 @@ func (s *APIServer) Run(_ []string) error {
glog.Warning("no RSA key provided, service account token authentication disabled") glog.Warning("no RSA key provided, service account token authentication disabled")
} }
} }
authenticator, err := apiserver.NewAuthenticator(s.BasicAuthFile, s.ClientCAFile, s.TokenAuthFile, s.ServiceAccountKeyFile, s.ServiceAccountLookup, helper) authenticator, err := apiserver.NewAuthenticator(s.BasicAuthFile, s.ClientCAFile, s.TokenAuthFile, s.ServiceAccountKeyFile, s.ServiceAccountLookup, etcdStorage)
if err != nil { if err != nil {
glog.Fatalf("Invalid Authentication Config: %v", err) glog.Fatalf("Invalid Authentication Config: %v", err)
} }
@ -356,7 +356,7 @@ func (s *APIServer) Run(_ []string) error {
} }
} }
config := &master.Config{ config := &master.Config{
EtcdHelper: helper, DatabaseStorage: etcdStorage,
EventTTL: s.EventTTL, EventTTL: s.EventTTL,
KubeletClient: kubeletClient, KubeletClient: kubeletClient,
ServiceClusterIPRange: &n, ServiceClusterIPRange: &n,

View File

@ -78,14 +78,14 @@ func (h *delegateHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
func runApiServer(etcdClient tools.EtcdClient, addr net.IP, port int, masterServiceNamespace string) { func runApiServer(etcdClient tools.EtcdClient, addr net.IP, port int, masterServiceNamespace string) {
handler := delegateHandler{} handler := delegateHandler{}
helper, err := master.NewEtcdHelper(etcdClient, "", master.DefaultEtcdPathPrefix) etcdStorage, err := master.NewEtcdStorage(etcdClient, "", master.DefaultEtcdPathPrefix)
if err != nil { if err != nil {
glog.Fatalf("Unable to get etcd helper: %v", err) glog.Fatalf("Unable to get etcd storage: %v", err)
} }
// Create a master and install handlers into mux. // Create a master and install handlers into mux.
m := master.New(&master.Config{ m := master.New(&master.Config{
EtcdHelper: helper, DatabaseStorage: etcdStorage,
KubeletClient: &client.HTTPKubeletClient{ KubeletClient: &client.HTTPKubeletClient{
Client: http.DefaultClient, Client: http.DefaultClient,
Config: &client.KubeletConfig{Port: 10250}, Config: &client.KubeletConfig{Port: 10250},

View File

@ -32,7 +32,7 @@ import (
) )
// NewAuthenticator returns an authenticator.Request or an error // NewAuthenticator returns an authenticator.Request or an error
func NewAuthenticator(basicAuthFile, clientCAFile, tokenFile, serviceAccountKeyFile string, serviceAccountLookup bool, helper tools.EtcdHelper) (authenticator.Request, error) { func NewAuthenticator(basicAuthFile, clientCAFile, tokenFile, serviceAccountKeyFile string, serviceAccountLookup bool, storage tools.StorageInterface) (authenticator.Request, error) {
var authenticators []authenticator.Request var authenticators []authenticator.Request
if len(basicAuthFile) > 0 { if len(basicAuthFile) > 0 {
@ -60,7 +60,7 @@ func NewAuthenticator(basicAuthFile, clientCAFile, tokenFile, serviceAccountKeyF
} }
if len(serviceAccountKeyFile) > 0 { if len(serviceAccountKeyFile) > 0 {
serviceAccountAuth, err := newServiceAccountAuthenticator(serviceAccountKeyFile, serviceAccountLookup, helper) serviceAccountAuth, err := newServiceAccountAuthenticator(serviceAccountKeyFile, serviceAccountLookup, storage)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -104,7 +104,7 @@ func newAuthenticatorFromTokenFile(tokenAuthFile string) (authenticator.Request,
} }
// newServiceAccountAuthenticator returns an authenticator.Request or an error // newServiceAccountAuthenticator returns an authenticator.Request or an error
func newServiceAccountAuthenticator(keyfile string, lookup bool, helper tools.EtcdHelper) (authenticator.Request, error) { func newServiceAccountAuthenticator(keyfile string, lookup bool, storage tools.StorageInterface) (authenticator.Request, error) {
publicKey, err := serviceaccount.ReadPublicKey(keyfile) publicKey, err := serviceaccount.ReadPublicKey(keyfile)
if err != nil { if err != nil {
return nil, err return nil, err
@ -114,7 +114,7 @@ func newServiceAccountAuthenticator(keyfile string, lookup bool, helper tools.Et
if lookup { if lookup {
// If we need to look up service accounts and tokens, // If we need to look up service accounts and tokens,
// go directly to etcd to avoid recursive auth insanity // go directly to etcd to avoid recursive auth insanity
serviceAccountGetter = serviceaccount.NewGetterFromEtcdHelper(helper) serviceAccountGetter = serviceaccount.NewGetterFromStorageInterface(storage)
} }
tokenAuthenticator := serviceaccount.JWTTokenAuthenticator([]*rsa.PublicKey{publicKey}, lookup, serviceAccountGetter) tokenAuthenticator := serviceaccount.JWTTokenAuthenticator([]*rsa.PublicKey{publicKey}, lookup, serviceAccountGetter)

View File

@ -87,7 +87,7 @@ const (
// Config is a structure used to configure a Master. // Config is a structure used to configure a Master.
type Config struct { type Config struct {
EtcdHelper tools.EtcdHelper DatabaseStorage tools.StorageInterface
EventTTL time.Duration EventTTL time.Duration
MinionRegexp string MinionRegexp string
KubeletClient client.KubeletClient KubeletClient client.KubeletClient
@ -223,17 +223,17 @@ type Master struct {
clock util.Clock clock util.Clock
} }
// NewEtcdHelper returns an EtcdHelper for the provided arguments or an error if the version // NewEtcdStorage returns a StorageInterface for the provided arguments or an error if the version
// is incorrect. // is incorrect.
func NewEtcdHelper(client tools.EtcdClient, version string, prefix string) (helper tools.EtcdHelper, err error) { func NewEtcdStorage(client tools.EtcdClient, version string, prefix string) (etcdStorage tools.StorageInterface, err error) {
if version == "" { if version == "" {
version = latest.Version version = latest.Version
} }
versionInterfaces, err := latest.InterfacesFor(version) versionInterfaces, err := latest.InterfacesFor(version)
if err != nil { if err != nil {
return helper, err return etcdStorage, err
} }
return tools.NewEtcdHelper(client, versionInterfaces.Codec, prefix), nil return tools.NewEtcdStorage(client, versionInterfaces.Codec, prefix), nil
} }
// setDefaults fills in any fields not set that are required to have valid data. // setDefaults fills in any fields not set that are required to have valid data.
@ -420,37 +420,37 @@ func logStackOnRecover(panicReason interface{}, httpWriter http.ResponseWriter)
func (m *Master) init(c *Config) { func (m *Master) init(c *Config) {
healthzChecks := []healthz.HealthzChecker{} healthzChecks := []healthz.HealthzChecker{}
m.clock = util.RealClock{} m.clock = util.RealClock{}
podStorage := podetcd.NewStorage(c.EtcdHelper, c.KubeletClient) podStorage := podetcd.NewStorage(c.DatabaseStorage, c.KubeletClient)
podRegistry := pod.NewRegistry(podStorage.Pod) podRegistry := pod.NewRegistry(podStorage.Pod)
podTemplateStorage := podtemplateetcd.NewREST(c.EtcdHelper) podTemplateStorage := podtemplateetcd.NewREST(c.DatabaseStorage)
eventRegistry := event.NewEtcdRegistry(c.EtcdHelper, uint64(c.EventTTL.Seconds())) eventRegistry := event.NewEtcdRegistry(c.DatabaseStorage, uint64(c.EventTTL.Seconds()))
limitRangeRegistry := limitrange.NewEtcdRegistry(c.EtcdHelper) limitRangeRegistry := limitrange.NewEtcdRegistry(c.DatabaseStorage)
resourceQuotaStorage, resourceQuotaStatusStorage := resourcequotaetcd.NewStorage(c.EtcdHelper) resourceQuotaStorage, resourceQuotaStatusStorage := resourcequotaetcd.NewStorage(c.DatabaseStorage)
secretStorage := secretetcd.NewStorage(c.EtcdHelper) secretStorage := secretetcd.NewStorage(c.DatabaseStorage)
serviceAccountStorage := serviceaccountetcd.NewStorage(c.EtcdHelper) serviceAccountStorage := serviceaccountetcd.NewStorage(c.DatabaseStorage)
persistentVolumeStorage, persistentVolumeStatusStorage := pvetcd.NewStorage(c.EtcdHelper) persistentVolumeStorage, persistentVolumeStatusStorage := pvetcd.NewStorage(c.DatabaseStorage)
persistentVolumeClaimStorage, persistentVolumeClaimStatusStorage := pvcetcd.NewStorage(c.EtcdHelper) persistentVolumeClaimStorage, persistentVolumeClaimStatusStorage := pvcetcd.NewStorage(c.DatabaseStorage)
namespaceStorage, namespaceStatusStorage, namespaceFinalizeStorage := namespaceetcd.NewStorage(c.EtcdHelper) namespaceStorage, namespaceStatusStorage, namespaceFinalizeStorage := namespaceetcd.NewStorage(c.DatabaseStorage)
m.namespaceRegistry = namespace.NewRegistry(namespaceStorage) m.namespaceRegistry = namespace.NewRegistry(namespaceStorage)
endpointsStorage := endpointsetcd.NewStorage(c.EtcdHelper) endpointsStorage := endpointsetcd.NewStorage(c.DatabaseStorage)
m.endpointRegistry = endpoint.NewRegistry(endpointsStorage) m.endpointRegistry = endpoint.NewRegistry(endpointsStorage)
nodeStorage, nodeStatusStorage := nodeetcd.NewStorage(c.EtcdHelper, c.KubeletClient) nodeStorage, nodeStatusStorage := nodeetcd.NewStorage(c.DatabaseStorage, c.KubeletClient)
m.nodeRegistry = minion.NewRegistry(nodeStorage) m.nodeRegistry = minion.NewRegistry(nodeStorage)
// TODO: split me up into distinct storage registries // TODO: split me up into distinct storage registries
registry := etcd.NewRegistry(c.EtcdHelper, podRegistry, m.endpointRegistry) registry := etcd.NewRegistry(c.DatabaseStorage, podRegistry, m.endpointRegistry)
m.serviceRegistry = registry m.serviceRegistry = registry
var serviceClusterIPRegistry service.RangeRegistry var serviceClusterIPRegistry service.RangeRegistry
serviceClusterIPAllocator := ipallocator.NewAllocatorCIDRRange(m.serviceClusterIPRange, func(max int, rangeSpec string) allocator.Interface { serviceClusterIPAllocator := ipallocator.NewAllocatorCIDRRange(m.serviceClusterIPRange, func(max int, rangeSpec string) allocator.Interface {
mem := allocator.NewAllocationMap(max, rangeSpec) mem := allocator.NewAllocationMap(max, rangeSpec)
etcd := etcdallocator.NewEtcd(mem, "/ranges/serviceips", "serviceipallocation", c.EtcdHelper) etcd := etcdallocator.NewEtcd(mem, "/ranges/serviceips", "serviceipallocation", c.DatabaseStorage)
serviceClusterIPRegistry = etcd serviceClusterIPRegistry = etcd
return etcd return etcd
}) })
@ -459,13 +459,13 @@ func (m *Master) init(c *Config) {
var serviceNodePortRegistry service.RangeRegistry var serviceNodePortRegistry service.RangeRegistry
serviceNodePortAllocator := portallocator.NewPortAllocatorCustom(m.serviceNodePortRange, func(max int, rangeSpec string) allocator.Interface { serviceNodePortAllocator := portallocator.NewPortAllocatorCustom(m.serviceNodePortRange, func(max int, rangeSpec string) allocator.Interface {
mem := allocator.NewAllocationMap(max, rangeSpec) mem := allocator.NewAllocationMap(max, rangeSpec)
etcd := etcdallocator.NewEtcd(mem, "/ranges/servicenodeports", "servicenodeportallocation", c.EtcdHelper) etcd := etcdallocator.NewEtcd(mem, "/ranges/servicenodeports", "servicenodeportallocation", c.DatabaseStorage)
serviceNodePortRegistry = etcd serviceNodePortRegistry = etcd
return etcd return etcd
}) })
m.serviceNodePortAllocator = serviceNodePortRegistry m.serviceNodePortAllocator = serviceNodePortRegistry
controllerStorage := controlleretcd.NewREST(c.EtcdHelper) controllerStorage := controlleretcd.NewREST(c.DatabaseStorage)
// TODO: Factor out the core API registration // TODO: Factor out the core API registration
m.storage = map[string]rest.Storage{ m.storage = map[string]rest.Storage{
@ -701,7 +701,7 @@ func (m *Master) getServersToValidate(c *Config) map[string]apiserver.Server {
"controller-manager": {Addr: "127.0.0.1", Port: ports.ControllerManagerPort, Path: "/healthz"}, "controller-manager": {Addr: "127.0.0.1", Port: ports.ControllerManagerPort, Path: "/healthz"},
"scheduler": {Addr: "127.0.0.1", Port: ports.SchedulerPort, Path: "/healthz"}, "scheduler": {Addr: "127.0.0.1", Port: ports.SchedulerPort, Path: "/healthz"},
} }
for ix, machine := range c.EtcdHelper.Client.GetCluster() { for ix, machine := range c.DatabaseStorage.Backends() {
etcdUrl, err := url.Parse(machine) etcdUrl, err := url.Parse(machine)
if err != nil { if err != nil {
glog.Errorf("Failed to parse etcd url for validation: %v", err) glog.Errorf("Failed to parse etcd url for validation: %v", err)

View File

@ -31,8 +31,7 @@ func TestGetServersToValidate(t *testing.T) {
config := Config{} config := Config{}
fakeClient := tools.NewFakeEtcdClient(t) fakeClient := tools.NewFakeEtcdClient(t)
fakeClient.Machines = []string{"http://machine1:4001", "http://machine2", "http://machine3:4003"} fakeClient.Machines = []string{"http://machine1:4001", "http://machine2", "http://machine3:4003"}
config.EtcdHelper = tools.NewEtcdHelper(fakeClient, latest.Codec, etcdtest.PathPrefix()) config.DatabaseStorage = tools.NewEtcdStorage(fakeClient, latest.Codec, etcdtest.PathPrefix())
config.EtcdHelper.Versioner = nil
master.nodeRegistry = registrytest.NewMinionRegistry([]string{"node1", "node2"}, api.NodeResources{}) master.nodeRegistry = registrytest.NewMinionRegistry([]string{"node1", "node2"}, api.NodeResources{})

View File

@ -37,7 +37,7 @@ type REST struct {
var controllerPrefix = "/controllers" var controllerPrefix = "/controllers"
// NewREST returns a RESTStorage object that will work against replication controllers. // NewREST returns a RESTStorage object that will work against replication controllers.
func NewREST(h tools.EtcdHelper) *REST { func NewREST(s tools.StorageInterface) *REST {
store := &etcdgeneric.Etcd{ store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.ReplicationController{} }, NewFunc: func() runtime.Object { return &api.ReplicationController{} },
@ -69,7 +69,7 @@ func NewREST(h tools.EtcdHelper) *REST {
// Used to validate controller updates // Used to validate controller updates
UpdateStrategy: controller.Strategy, UpdateStrategy: controller.Strategy,
Helper: h, Storage: s,
} }
return &REST{store} return &REST{store}

View File

@ -40,17 +40,17 @@ const (
FAIL FAIL
) )
func newHelper(t *testing.T) (*tools.FakeEtcdClient, tools.EtcdHelper) { func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, tools.StorageInterface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true fakeEtcdClient.TestIndex = true
helper := tools.NewEtcdHelper(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix()) etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
return fakeEtcdClient, helper return fakeEtcdClient, etcdStorage
} }
// newStorage creates a REST storage backed by etcd helpers // newStorage creates a REST storage backed by etcd helpers
func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) { func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
fakeEtcdClient, h := newHelper(t) fakeEtcdClient, s := newEtcdStorage(t)
storage := NewREST(h) storage := NewREST(s)
return storage, fakeEtcdClient return storage, fakeEtcdClient
} }

View File

@ -33,7 +33,7 @@ type REST struct {
} }
// NewStorage returns a RESTStorage object that will work against endpoints. // NewStorage returns a RESTStorage object that will work against endpoints.
func NewStorage(h tools.EtcdHelper) *REST { func NewStorage(s tools.StorageInterface) *REST {
prefix := "/services/endpoints" prefix := "/services/endpoints"
return &REST{ return &REST{
&etcdgeneric.Etcd{ &etcdgeneric.Etcd{
@ -56,7 +56,7 @@ func NewStorage(h tools.EtcdHelper) *REST {
CreateStrategy: endpoint.Strategy, CreateStrategy: endpoint.Strategy,
UpdateStrategy: endpoint.Strategy, UpdateStrategy: endpoint.Strategy,
Helper: h, Storage: s,
}, },
} }
} }

View File

@ -32,16 +32,16 @@ import (
"github.com/coreos/go-etcd/etcd" "github.com/coreos/go-etcd/etcd"
) )
func newHelper(t *testing.T) (*tools.FakeEtcdClient, tools.EtcdHelper) { func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, tools.StorageInterface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true fakeEtcdClient.TestIndex = true
helper := tools.NewEtcdHelper(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix()) etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
return fakeEtcdClient, helper return fakeEtcdClient, etcdStorage
} }
func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) { func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
fakeEtcdClient, h := newHelper(t) fakeEtcdClient, s := newEtcdStorage(t)
storage := NewStorage(h) storage := NewStorage(s)
return storage, fakeEtcdClient return storage, fakeEtcdClient
} }

View File

@ -44,15 +44,15 @@ const (
// Registry implements BindingRegistry, ControllerRegistry, EndpointRegistry, // Registry implements BindingRegistry, ControllerRegistry, EndpointRegistry,
// MinionRegistry, PodRegistry and ServiceRegistry, backed by etcd. // MinionRegistry, PodRegistry and ServiceRegistry, backed by etcd.
type Registry struct { type Registry struct {
tools.EtcdHelper tools.StorageInterface
pods pod.Registry pods pod.Registry
endpoints endpoint.Registry endpoints endpoint.Registry
} }
// NewRegistry creates an etcd registry. // NewRegistry creates an etcd registry.
func NewRegistry(helper tools.EtcdHelper, pods pod.Registry, endpoints endpoint.Registry) *Registry { func NewRegistry(storage tools.StorageInterface, pods pod.Registry, endpoints endpoint.Registry) *Registry {
registry := &Registry{ registry := &Registry{
EtcdHelper: helper, StorageInterface: storage,
pods: pods, pods: pods,
endpoints: endpoints, endpoints: endpoints,
} }

View File

@ -38,16 +38,16 @@ import (
) )
func NewTestEtcdRegistry(client tools.EtcdClient) *Registry { func NewTestEtcdRegistry(client tools.EtcdClient) *Registry {
helper := tools.NewEtcdHelper(client, latest.Codec, etcdtest.PathPrefix()) storage := tools.NewEtcdStorage(client, latest.Codec, etcdtest.PathPrefix())
registry := NewRegistry(helper, nil, nil) registry := NewRegistry(storage, nil, nil)
return registry return registry
} }
func NewTestEtcdRegistryWithPods(client tools.EtcdClient) *Registry { func NewTestEtcdRegistryWithPods(client tools.EtcdClient) *Registry {
helper := tools.NewEtcdHelper(client, latest.Codec, etcdtest.PathPrefix()) etcdStorage := tools.NewEtcdStorage(client, latest.Codec, etcdtest.PathPrefix())
podStorage := podetcd.NewStorage(helper, nil) podStorage := podetcd.NewStorage(etcdStorage, nil)
endpointStorage := endpointetcd.NewStorage(helper) endpointStorage := endpointetcd.NewStorage(etcdStorage)
registry := NewRegistry(helper, pod.NewRegistry(podStorage.Pod), endpoint.NewRegistry(endpointStorage)) registry := NewRegistry(etcdStorage, pod.NewRegistry(podStorage.Pod), endpoint.NewRegistry(endpointStorage))
return registry return registry
} }

View File

@ -30,8 +30,8 @@ type registry struct {
} }
// NewEtcdRegistry returns a registry which will store Events in the given // NewEtcdRegistry returns a registry which will store Events in the given
// EtcdHelper. ttl is the time that Events will be retained by the system. // EtcdStorage. ttl is the time that Events will be retained by the system.
func NewEtcdRegistry(h tools.EtcdHelper, ttl uint64) generic.Registry { func NewEtcdRegistry(s tools.StorageInterface, ttl uint64) generic.Registry {
prefix := "/events" prefix := "/events"
return registry{ return registry{
Etcd: &etcdgeneric.Etcd{ Etcd: &etcdgeneric.Etcd{
@ -47,7 +47,7 @@ func NewEtcdRegistry(h tools.EtcdHelper, ttl uint64) generic.Registry {
TTLFunc: func(runtime.Object, uint64, bool) (uint64, error) { TTLFunc: func(runtime.Object, uint64, bool) (uint64, error) {
return ttl, nil return ttl, nil
}, },
Helper: h, Storage: s,
}, },
} }
} }

View File

@ -39,8 +39,8 @@ func NewTestEventEtcdRegistry(t *testing.T) (*tools.FakeEtcdClient, generic.Regi
f := tools.NewFakeEtcdClient(t) f := tools.NewFakeEtcdClient(t)
f.TestIndex = true f.TestIndex = true
h := tools.NewEtcdHelper(f, testapi.Codec(), etcdtest.PathPrefix()) s := tools.NewEtcdStorage(f, testapi.Codec(), etcdtest.PathPrefix())
return f, NewEtcdRegistry(h, testTTL) return f, NewEtcdRegistry(s, testTTL)
} }
func TestEventCreate(t *testing.T) { func TestEventCreate(t *testing.T) {

View File

@ -103,7 +103,7 @@ type Etcd struct {
ReturnDeletedObject bool ReturnDeletedObject bool
// Used for all etcd access functions // Used for all etcd access functions
Helper tools.EtcdHelper Storage tools.StorageInterface
} }
// NamespaceKeyRootFunc is the default function for constructing etcd paths to resource directories enforcing namespace rules. // NamespaceKeyRootFunc is the default function for constructing etcd paths to resource directories enforcing namespace rules.
@ -157,14 +157,14 @@ func (e *Etcd) ListPredicate(ctx api.Context, m generic.Matcher) (runtime.Object
if err != nil { if err != nil {
return nil, err return nil, err
} }
err = e.Helper.ExtractObjToList(key, list) err = e.Storage.ExtractObjToList(key, list)
trace.Step("Object extracted") trace.Step("Object extracted")
if err != nil { if err != nil {
return nil, err return nil, err
} }
} else { } else {
trace.Step("About to list directory") trace.Step("About to list directory")
err := e.Helper.ExtractToList(e.KeyRootFunc(ctx), list) err := e.Storage.ExtractToList(e.KeyRootFunc(ctx), list)
trace.Step("List extracted") trace.Step("List extracted")
if err != nil { if err != nil {
return nil, err return nil, err
@ -190,7 +190,7 @@ func (e *Etcd) CreateWithName(ctx api.Context, name string, obj runtime.Object)
if err != nil { if err != nil {
return err return err
} }
err = e.Helper.CreateObj(key, obj, nil, ttl) err = e.Storage.CreateObj(key, obj, nil, ttl)
err = etcderr.InterpretCreateError(err, e.EndpointName, name) err = etcderr.InterpretCreateError(err, e.EndpointName, name)
if err == nil && e.Decorator != nil { if err == nil && e.Decorator != nil {
err = e.Decorator(obj) err = e.Decorator(obj)
@ -219,7 +219,7 @@ func (e *Etcd) Create(ctx api.Context, obj runtime.Object) (runtime.Object, erro
} }
trace.Step("About to create object") trace.Step("About to create object")
out := e.NewFunc() out := e.NewFunc()
if err := e.Helper.CreateObj(key, obj, out, ttl); err != nil { if err := e.Storage.CreateObj(key, obj, out, ttl); err != nil {
err = etcderr.InterpretCreateError(err, e.EndpointName, name) err = etcderr.InterpretCreateError(err, e.EndpointName, name)
err = rest.CheckGeneratedNameError(e.CreateStrategy, err, obj) err = rest.CheckGeneratedNameError(e.CreateStrategy, err, obj)
return nil, err return nil, err
@ -249,7 +249,7 @@ func (e *Etcd) UpdateWithName(ctx api.Context, name string, obj runtime.Object)
if err != nil { if err != nil {
return err return err
} }
err = e.Helper.SetObj(key, obj, nil, ttl) err = e.Storage.SetObj(key, obj, nil, ttl)
err = etcderr.InterpretUpdateError(err, e.EndpointName, name) err = etcderr.InterpretUpdateError(err, e.EndpointName, name)
if err == nil && e.Decorator != nil { if err == nil && e.Decorator != nil {
err = e.Decorator(obj) err = e.Decorator(obj)
@ -274,7 +274,7 @@ func (e *Etcd) Update(ctx api.Context, obj runtime.Object) (runtime.Object, bool
// If AllowUnconditionalUpdate() is true and the object specified by the user does not have a resource version, // If AllowUnconditionalUpdate() is true and the object specified by the user does not have a resource version,
// then we populate it with the latest version. // then we populate it with the latest version.
// Else, we check that the version specified by the user matches the version of latest etcd object. // Else, we check that the version specified by the user matches the version of latest etcd object.
resourceVersion, err := e.Helper.Versioner.ObjectResourceVersion(obj) resourceVersion, err := e.Storage.Versioner().ObjectResourceVersion(obj)
if err != nil { if err != nil {
return nil, false, err return nil, false, err
} }
@ -282,8 +282,8 @@ func (e *Etcd) Update(ctx api.Context, obj runtime.Object) (runtime.Object, bool
// TODO: expose TTL // TODO: expose TTL
creating := false creating := false
out := e.NewFunc() out := e.NewFunc()
err = e.Helper.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 tools.ResponseMeta) (runtime.Object, *uint64, error) {
version, err := e.Helper.Versioner.ObjectResourceVersion(existing) version, err := e.Storage.Versioner().ObjectResourceVersion(existing)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@ -305,13 +305,13 @@ func (e *Etcd) Update(ctx api.Context, obj runtime.Object) (runtime.Object, bool
creating = false creating = false
if doUnconditionalUpdate { if doUnconditionalUpdate {
// Update the object's resource version to match the latest etcd object's resource version. // Update the object's resource version to match the latest etcd object's resource version.
err = e.Helper.Versioner.UpdateObject(obj, res.Expiration, res.ResourceVersion) err = e.Storage.Versioner().UpdateObject(obj, res.Expiration, res.ResourceVersion)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
} else { } else {
// Check if the object's resource version matches the latest resource version. // Check if the object's resource version matches the latest resource version.
newVersion, err := e.Helper.Versioner.ObjectResourceVersion(obj) newVersion, err := e.Storage.Versioner().ObjectResourceVersion(obj)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@ -372,7 +372,7 @@ func (e *Etcd) Get(ctx api.Context, name string) (runtime.Object, error) {
return nil, err return nil, err
} }
trace.Step("About to read object") trace.Step("About to read object")
if err := e.Helper.ExtractObj(key, obj, false); err != nil { if err := e.Storage.ExtractObj(key, obj, false); err != nil {
return nil, etcderr.InterpretGetError(err, e.EndpointName, name) return nil, etcderr.InterpretGetError(err, e.EndpointName, name)
} }
trace.Step("Object read") trace.Step("Object read")
@ -395,7 +395,7 @@ func (e *Etcd) Delete(ctx api.Context, name string, options *api.DeleteOptions)
trace := util.NewTrace("Delete " + reflect.TypeOf(obj).String()) trace := util.NewTrace("Delete " + reflect.TypeOf(obj).String())
defer trace.LogIfLong(time.Second) defer trace.LogIfLong(time.Second)
trace.Step("About to read object") trace.Step("About to read object")
if err := e.Helper.ExtractObj(key, obj, false); err != nil { if err := e.Storage.ExtractObj(key, obj, false); err != nil {
return nil, etcderr.InterpretDeleteError(err, e.EndpointName, name) return nil, etcderr.InterpretDeleteError(err, e.EndpointName, name)
} }
@ -413,7 +413,7 @@ func (e *Etcd) Delete(ctx api.Context, name string, options *api.DeleteOptions)
if graceful && *options.GracePeriodSeconds != 0 { if graceful && *options.GracePeriodSeconds != 0 {
trace.Step("Graceful deletion") trace.Step("Graceful deletion")
out := e.NewFunc() out := e.NewFunc()
if err := e.Helper.SetObj(key, obj, out, uint64(*options.GracePeriodSeconds)); err != nil { if err := e.Storage.SetObj(key, obj, out, uint64(*options.GracePeriodSeconds)); err != nil {
return nil, etcderr.InterpretUpdateError(err, e.EndpointName, name) return nil, etcderr.InterpretUpdateError(err, e.EndpointName, name)
} }
return e.finalizeDelete(out, true) return e.finalizeDelete(out, true)
@ -422,7 +422,7 @@ func (e *Etcd) Delete(ctx api.Context, name string, options *api.DeleteOptions)
// delete immediately, or no graceful deletion supported // delete immediately, or no graceful deletion supported
out := e.NewFunc() out := e.NewFunc()
trace.Step("About to delete object") trace.Step("About to delete object")
if err := e.Helper.DeleteObj(key, out); err != nil { if err := e.Storage.DeleteObj(key, out); err != nil {
return nil, etcderr.InterpretDeleteError(err, e.EndpointName, name) return nil, etcderr.InterpretDeleteError(err, e.EndpointName, name)
} }
return e.finalizeDelete(out, true) return e.finalizeDelete(out, true)
@ -480,10 +480,10 @@ func (e *Etcd) WatchPredicate(ctx api.Context, m generic.Matcher, resourceVersio
if err != nil { if err != nil {
return nil, err return nil, err
} }
return e.Helper.Watch(key, version, filterFunc) return e.Storage.Watch(key, version, filterFunc)
} }
return e.Helper.WatchList(e.KeyRootFunc(ctx), version, filterFunc) return e.Storage.WatchList(e.KeyRootFunc(ctx), version, filterFunc)
} }
// calculateTTL is a helper for retrieving the updated TTL for an object or returning an error // calculateTTL is a helper for retrieving the updated TTL for an object or returning an error

View File

@ -69,7 +69,7 @@ func hasCreated(t *testing.T, pod *api.Pod) func(runtime.Object) bool {
func NewTestGenericEtcdRegistry(t *testing.T) (*tools.FakeEtcdClient, *Etcd) { func NewTestGenericEtcdRegistry(t *testing.T) (*tools.FakeEtcdClient, *Etcd) {
f := tools.NewFakeEtcdClient(t) f := tools.NewFakeEtcdClient(t)
f.TestIndex = true f.TestIndex = true
h := tools.NewEtcdHelper(f, testapi.Codec(), etcdtest.PathPrefix()) s := tools.NewEtcdStorage(f, testapi.Codec(), etcdtest.PathPrefix())
strategy := &testRESTStrategy{api.Scheme, api.SimpleNameGenerator, true, false, true} strategy := &testRESTStrategy{api.Scheme, api.SimpleNameGenerator, true, false, true}
podPrefix := "/pods" podPrefix := "/pods"
return f, &Etcd{ return f, &Etcd{
@ -85,7 +85,7 @@ func NewTestGenericEtcdRegistry(t *testing.T) (*tools.FakeEtcdClient, *Etcd) {
return path.Join(podPrefix, id), nil return path.Join(podPrefix, id), nil
}, },
ObjectNameFunc: func(obj runtime.Object) (string, error) { return obj.(*api.Pod).Name, nil }, ObjectNameFunc: func(obj runtime.Object) (string, error) { return obj.(*api.Pod).Name, nil },
Helper: h, Storage: s,
} }
} }

View File

@ -141,7 +141,7 @@ type Registry interface {
// provided that 'm' works with the concrete type of list. d is an optional // provided that 'm' works with the concrete type of list. d is an optional
// decorator for the returned functions. Only matching items are decorated. // decorator for the returned functions. Only matching items are decorated.
func FilterList(list runtime.Object, m Matcher, d DecoratorFunc) (filtered runtime.Object, err error) { func FilterList(list runtime.Object, m Matcher, d DecoratorFunc) (filtered runtime.Object, err error) {
// TODO: push a matcher down into tools.EtcdHelper to avoid all this // TODO: push a matcher down into tools.etcdHelper to avoid all this
// nonsense. This is a lot of unnecessary copies. // nonsense. This is a lot of unnecessary copies.
items, err := runtime.ExtractList(list) items, err := runtime.ExtractList(list)
if err != nil { if err != nil {

View File

@ -29,8 +29,8 @@ type registry struct {
*etcdgeneric.Etcd *etcdgeneric.Etcd
} }
// NewEtcdRegistry returns a registry which will store LimitRange in the given helper // NewEtcdRegistry returns a registry which will store LimitRange in the given storage
func NewEtcdRegistry(h tools.EtcdHelper) generic.Registry { func NewEtcdRegistry(s tools.StorageInterface) generic.Registry {
prefix := "/limitranges" prefix := "/limitranges"
return registry{ return registry{
Etcd: &etcdgeneric.Etcd{ Etcd: &etcdgeneric.Etcd{
@ -43,7 +43,7 @@ func NewEtcdRegistry(h tools.EtcdHelper) generic.Registry {
KeyFunc: func(ctx api.Context, id string) (string, error) { KeyFunc: func(ctx api.Context, id string) (string, error) {
return etcdgeneric.NamespaceKeyFunc(ctx, prefix, id) return etcdgeneric.NamespaceKeyFunc(ctx, prefix, id)
}, },
Helper: h, Storage: s,
}, },
} }
} }

View File

@ -37,8 +37,8 @@ import (
func NewTestLimitRangeEtcdRegistry(t *testing.T) (*tools.FakeEtcdClient, generic.Registry) { func NewTestLimitRangeEtcdRegistry(t *testing.T) (*tools.FakeEtcdClient, generic.Registry) {
f := tools.NewFakeEtcdClient(t) f := tools.NewFakeEtcdClient(t)
f.TestIndex = true f.TestIndex = true
h := tools.NewEtcdHelper(f, testapi.Codec(), etcdtest.PathPrefix()) s := tools.NewEtcdStorage(f, testapi.Codec(), etcdtest.PathPrefix())
return f, NewEtcdRegistry(h) return f, NewEtcdRegistry(s)
} }
func TestLimitRangeCreate(t *testing.T) { func TestLimitRangeCreate(t *testing.T) {

View File

@ -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. // NewStorage returns a RESTStorage object that will work against nodes.
func NewStorage(h tools.EtcdHelper, connection client.ConnectionInfoGetter) (*REST, *StatusREST) { func NewStorage(s tools.StorageInterface, connection client.ConnectionInfoGetter) (*REST, *StatusREST) {
prefix := "/minions" prefix := "/minions"
store := &etcdgeneric.Etcd{ store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.Node{} }, NewFunc: func() runtime.Object { return &api.Node{} },
@ -69,7 +69,7 @@ func NewStorage(h tools.EtcdHelper, connection client.ConnectionInfoGetter) (*RE
CreateStrategy: minion.Strategy, CreateStrategy: minion.Strategy,
UpdateStrategy: minion.Strategy, UpdateStrategy: minion.Strategy,
Helper: h, Storage: s,
} }
statusStore := *store statusStore := *store

View File

@ -47,16 +47,16 @@ func (fakeConnectionInfoGetter) GetConnectionInfo(host string) (string, uint, ht
return "http", 12345, nil, nil return "http", 12345, nil, nil
} }
func newHelper(t *testing.T) (*tools.FakeEtcdClient, tools.EtcdHelper) { func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, tools.StorageInterface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true fakeEtcdClient.TestIndex = true
helper := tools.NewEtcdHelper(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix()) etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
return fakeEtcdClient, helper return fakeEtcdClient, etcdStorage
} }
func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) { func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
fakeEtcdClient, h := newHelper(t) fakeEtcdClient, s := newEtcdStorage(t)
storage, _ := NewStorage(h, fakeConnectionInfoGetter{}) storage, _ := NewStorage(s, fakeConnectionInfoGetter{})
return storage, fakeEtcdClient return storage, fakeEtcdClient
} }

View File

@ -49,7 +49,7 @@ type FinalizeREST struct {
} }
// NewStorage returns a RESTStorage object that will work against namespaces // NewStorage returns a RESTStorage object that will work against namespaces
func NewStorage(h tools.EtcdHelper) (*REST, *StatusREST, *FinalizeREST) { func NewStorage(s tools.StorageInterface) (*REST, *StatusREST, *FinalizeREST) {
prefix := "/namespaces" prefix := "/namespaces"
store := &etcdgeneric.Etcd{ store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.Namespace{} }, NewFunc: func() runtime.Object { return &api.Namespace{} },
@ -67,7 +67,7 @@ func NewStorage(h tools.EtcdHelper) (*REST, *StatusREST, *FinalizeREST) {
return namespace.MatchNamespace(label, field) return namespace.MatchNamespace(label, field)
}, },
EndpointName: "namespaces", EndpointName: "namespaces",
Helper: h, Storage: s,
} }
store.CreateStrategy = namespace.Strategy store.CreateStrategy = namespace.Strategy
store.UpdateStrategy = namespace.Strategy store.UpdateStrategy = namespace.Strategy

View File

@ -33,17 +33,17 @@ import (
"github.com/coreos/go-etcd/etcd" "github.com/coreos/go-etcd/etcd"
) )
func newHelper(t *testing.T) (*tools.FakeEtcdClient, tools.EtcdHelper) { func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, tools.StorageInterface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true fakeEtcdClient.TestIndex = true
helper := tools.NewEtcdHelper(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix()) etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
return fakeEtcdClient, helper return fakeEtcdClient, etcdStorage
} }
func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient, tools.EtcdHelper) { func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient, tools.StorageInterface) {
fakeEtcdClient, h := newHelper(t) fakeEtcdClient, s := newEtcdStorage(t)
storage, _, _ := NewStorage(h) storage, _, _ := NewStorage(s)
return storage, fakeEtcdClient, h return storage, fakeEtcdClient, s
} }
func validNewNamespace() *api.Namespace { func validNewNamespace() *api.Namespace {
@ -69,8 +69,8 @@ func TestStorage(t *testing.T) {
} }
func TestCreate(t *testing.T) { func TestCreate(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
storage, _, _ := NewStorage(helper) storage, _, _ := NewStorage(etcdStorage)
test := resttest.New(t, storage, fakeEtcdClient.SetError).ClusterScope() test := resttest.New(t, storage, fakeEtcdClient.SetError).ClusterScope()
namespace := validNewNamespace() namespace := validNewNamespace()
namespace.ObjectMeta = api.ObjectMeta{GenerateName: "foo"} namespace.ObjectMeta = api.ObjectMeta{GenerateName: "foo"}
@ -94,8 +94,8 @@ func expectNamespace(t *testing.T, out runtime.Object) (*api.Namespace, bool) {
} }
func TestCreateSetsFields(t *testing.T) { func TestCreateSetsFields(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
storage, _, _ := NewStorage(helper) storage, _, _ := NewStorage(etcdStorage)
namespace := validNewNamespace() namespace := validNewNamespace()
_, err := storage.Create(api.NewContext(), namespace) _, err := storage.Create(api.NewContext(), namespace)
if err != fakeEtcdClient.Err { if err != fakeEtcdClient.Err {
@ -108,7 +108,7 @@ func TestCreateSetsFields(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("unexpected key error: %v", err) t.Fatalf("unexpected key error: %v", err)
} }
if err := helper.ExtractObj(key, actual, false); err != nil { if err := etcdStorage.ExtractObj(key, actual, false); err != nil {
t.Fatalf("unexpected extraction error: %v", err) t.Fatalf("unexpected extraction error: %v", err)
} }
if actual.Name != namespace.Name { if actual.Name != namespace.Name {
@ -123,7 +123,7 @@ func TestCreateSetsFields(t *testing.T) {
} }
func TestListEmptyNamespaceList(t *testing.T) { func TestListEmptyNamespaceList(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
fakeEtcdClient.ChangeIndex = 1 fakeEtcdClient.ChangeIndex = 1
key := etcdtest.AddPrefix("/namespaces") key := etcdtest.AddPrefix("/namespaces")
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
@ -131,7 +131,7 @@ func TestListEmptyNamespaceList(t *testing.T) {
E: fakeEtcdClient.NewError(tools.EtcdErrorCodeNotFound), E: fakeEtcdClient.NewError(tools.EtcdErrorCodeNotFound),
} }
storage, _, _ := NewStorage(helper) storage, _, _ := NewStorage(etcdStorage)
namespaces, err := storage.List(api.NewContext(), labels.Everything(), fields.Everything()) namespaces, err := storage.List(api.NewContext(), labels.Everything(), fields.Everything())
if err != nil { if err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
@ -145,7 +145,7 @@ func TestListEmptyNamespaceList(t *testing.T) {
} }
func TestListNamespaceList(t *testing.T) { func TestListNamespaceList(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
key := etcdtest.AddPrefix("/namespaces") key := etcdtest.AddPrefix("/namespaces")
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
@ -165,7 +165,7 @@ func TestListNamespaceList(t *testing.T) {
}, },
}, },
} }
storage, _, _ := NewStorage(helper) storage, _, _ := NewStorage(etcdStorage)
namespacesObj, err := storage.List(api.NewContext(), labels.Everything(), fields.Everything()) namespacesObj, err := storage.List(api.NewContext(), labels.Everything(), fields.Everything())
namespaces := namespacesObj.(*api.NamespaceList) namespaces := namespacesObj.(*api.NamespaceList)
if err != nil { if err != nil {
@ -184,7 +184,7 @@ func TestListNamespaceList(t *testing.T) {
} }
func TestListNamespaceListSelection(t *testing.T) { func TestListNamespaceListSelection(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
key := etcdtest.AddPrefix("/namespaces") key := etcdtest.AddPrefix("/namespaces")
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
@ -213,7 +213,7 @@ func TestListNamespaceListSelection(t *testing.T) {
}, },
}, },
} }
storage, _, _ := NewStorage(helper) storage, _, _ := NewStorage(etcdStorage)
ctx := api.NewContext() ctx := api.NewContext()
table := []struct { table := []struct {
label, field string label, field string
@ -261,8 +261,8 @@ func TestListNamespaceListSelection(t *testing.T) {
} }
func TestNamespaceDecode(t *testing.T) { func TestNamespaceDecode(t *testing.T) {
_, helper := newHelper(t) _, etcdStorage := newEtcdStorage(t)
storage, _, _ := NewStorage(helper) storage, _, _ := NewStorage(etcdStorage)
expected := validNewNamespace() expected := validNewNamespace()
expected.Status.Phase = api.NamespaceActive expected.Status.Phase = api.NamespaceActive
expected.Spec.Finalizers = []api.FinalizerName{api.FinalizerKubernetes} expected.Spec.Finalizers = []api.FinalizerName{api.FinalizerKubernetes}
@ -311,9 +311,9 @@ func TestGet(t *testing.T) {
} }
func TestDeleteNamespace(t *testing.T) { func TestDeleteNamespace(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
fakeEtcdClient.ChangeIndex = 1 fakeEtcdClient.ChangeIndex = 1
storage, _, _ := NewStorage(helper) storage, _, _ := NewStorage(etcdStorage)
ctx := api.NewContext() ctx := api.NewContext()
key, err := storage.Etcd.KeyFunc(ctx, "foo") key, err := storage.Etcd.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
@ -340,7 +340,7 @@ func TestDeleteNamespace(t *testing.T) {
func TestDeleteNamespaceWithIncompleteFinalizers(t *testing.T) { func TestDeleteNamespaceWithIncompleteFinalizers(t *testing.T) {
now := util.Now() now := util.Now()
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
fakeEtcdClient.ChangeIndex = 1 fakeEtcdClient.ChangeIndex = 1
key := etcdtest.AddPrefix("/namespaces/foo") key := etcdtest.AddPrefix("/namespaces/foo")
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
@ -361,7 +361,7 @@ func TestDeleteNamespaceWithIncompleteFinalizers(t *testing.T) {
}, },
}, },
} }
storage, _, _ := NewStorage(helper) storage, _, _ := NewStorage(etcdStorage)
_, err := storage.Delete(api.NewContext(), "foo", nil) _, err := storage.Delete(api.NewContext(), "foo", nil)
if err == nil { if err == nil {
t.Fatalf("expected error: %v", err) t.Fatalf("expected error: %v", err)
@ -370,7 +370,7 @@ func TestDeleteNamespaceWithIncompleteFinalizers(t *testing.T) {
func TestDeleteNamespaceWithCompleteFinalizers(t *testing.T) { func TestDeleteNamespaceWithCompleteFinalizers(t *testing.T) {
now := util.Now() now := util.Now()
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
fakeEtcdClient.ChangeIndex = 1 fakeEtcdClient.ChangeIndex = 1
key := etcdtest.AddPrefix("/namespaces/foo") key := etcdtest.AddPrefix("/namespaces/foo")
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
@ -391,7 +391,7 @@ func TestDeleteNamespaceWithCompleteFinalizers(t *testing.T) {
}, },
}, },
} }
storage, _, _ := NewStorage(helper) storage, _, _ := NewStorage(etcdStorage)
_, err := storage.Delete(api.NewContext(), "foo", nil) _, err := storage.Delete(api.NewContext(), "foo", nil)
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)

View File

@ -35,7 +35,7 @@ type REST struct {
} }
// NewREST returns a RESTStorage object that will work against PersistentVolume objects. // NewREST returns a RESTStorage object that will work against PersistentVolume objects.
func NewStorage(h tools.EtcdHelper) (*REST, *StatusREST) { func NewStorage(s tools.StorageInterface) (*REST, *StatusREST) {
prefix := "/persistentvolumes" prefix := "/persistentvolumes"
store := &etcdgeneric.Etcd{ store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.PersistentVolume{} }, NewFunc: func() runtime.Object { return &api.PersistentVolume{} },
@ -54,7 +54,7 @@ func NewStorage(h tools.EtcdHelper) (*REST, *StatusREST) {
}, },
EndpointName: "persistentvolume", EndpointName: "persistentvolume",
Helper: h, Storage: s,
} }
store.CreateStrategy = persistentvolume.Strategy store.CreateStrategy = persistentvolume.Strategy

View File

@ -38,12 +38,12 @@ type testRegistry struct {
*registrytest.GenericRegistry *registrytest.GenericRegistry
} }
func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient, tools.EtcdHelper) { func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient, tools.StorageInterface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true fakeEtcdClient.TestIndex = true
helper := tools.NewEtcdHelper(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix()) etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
storage, statusStorage := NewStorage(helper) storage, statusStorage := NewStorage(etcdStorage)
return storage, statusStorage, fakeEtcdClient, helper return storage, statusStorage, fakeEtcdClient, etcdStorage
} }
func validNewPersistentVolume(name string) *api.PersistentVolume { func validNewPersistentVolume(name string) *api.PersistentVolume {
@ -320,7 +320,7 @@ func TestDeletePersistentVolumes(t *testing.T) {
} }
func TestEtcdUpdateStatus(t *testing.T) { func TestEtcdUpdateStatus(t *testing.T) {
storage, statusStorage, fakeClient, helper := newStorage(t) storage, statusStorage, fakeClient, etcdStorage := newStorage(t)
ctx := api.NewContext() ctx := api.NewContext()
fakeClient.TestIndex = true fakeClient.TestIndex = true
@ -350,7 +350,7 @@ func TestEtcdUpdateStatus(t *testing.T) {
} }
var pvOut api.PersistentVolume var pvOut api.PersistentVolume
key, _ = storage.KeyFunc(ctx, "foo") key, _ = storage.KeyFunc(ctx, "foo")
if err := helper.ExtractObj(key, &pvOut, false); err != nil { if err := etcdStorage.ExtractObj(key, &pvOut, false); err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
if !api.Semantic.DeepEqual(expected, pvOut) { if !api.Semantic.DeepEqual(expected, pvOut) {

View File

@ -33,7 +33,7 @@ type REST struct {
} }
// NewREST returns a RESTStorage object that will work against PersistentVolumeClaim objects. // NewREST returns a RESTStorage object that will work against PersistentVolumeClaim objects.
func NewStorage(h tools.EtcdHelper) (*REST, *StatusREST) { func NewStorage(s tools.StorageInterface) (*REST, *StatusREST) {
prefix := "/persistentvolumeclaims" prefix := "/persistentvolumeclaims"
store := &etcdgeneric.Etcd{ store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.PersistentVolumeClaim{} }, NewFunc: func() runtime.Object { return &api.PersistentVolumeClaim{} },
@ -52,7 +52,7 @@ func NewStorage(h tools.EtcdHelper) (*REST, *StatusREST) {
}, },
EndpointName: "persistentvolumeclaims", EndpointName: "persistentvolumeclaims",
Helper: h, Storage: s,
} }
store.CreateStrategy = persistentvolumeclaim.Strategy store.CreateStrategy = persistentvolumeclaim.Strategy

View File

@ -38,12 +38,12 @@ type testRegistry struct {
*registrytest.GenericRegistry *registrytest.GenericRegistry
} }
func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient, tools.EtcdHelper) { func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient, tools.StorageInterface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true fakeEtcdClient.TestIndex = true
helper := tools.NewEtcdHelper(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix()) etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
storage, statusStorage := NewStorage(helper) storage, statusStorage := NewStorage(etcdStorage)
return storage, statusStorage, fakeEtcdClient, helper return storage, statusStorage, fakeEtcdClient, etcdStorage
} }
func validNewPersistentVolumeClaim(name, ns string) *api.PersistentVolumeClaim { func validNewPersistentVolumeClaim(name, ns string) *api.PersistentVolumeClaim {
@ -318,7 +318,7 @@ func TestDeletePersistentVolumeClaims(t *testing.T) {
} }
func TestEtcdUpdateStatus(t *testing.T) { func TestEtcdUpdateStatus(t *testing.T) {
storage, statusStorage, fakeClient, helper := newStorage(t) storage, statusStorage, fakeClient, etcdStorage := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
fakeClient.TestIndex = true fakeClient.TestIndex = true
@ -357,7 +357,7 @@ func TestEtcdUpdateStatus(t *testing.T) {
} }
var pvcOut api.PersistentVolumeClaim var pvcOut api.PersistentVolumeClaim
key, _ = storage.KeyFunc(ctx, "foo") key, _ = storage.KeyFunc(ctx, "foo")
if err := helper.ExtractObj(key, &pvcOut, false); err != nil { if err := etcdStorage.ExtractObj(key, &pvcOut, false); err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
if !api.Semantic.DeepEqual(expected, pvcOut) { if !api.Semantic.DeepEqual(expected, pvcOut) {

View File

@ -55,7 +55,7 @@ type REST struct {
} }
// NewStorage returns a RESTStorage object that will work against pods. // NewStorage returns a RESTStorage object that will work against pods.
func NewStorage(h tools.EtcdHelper, k client.ConnectionInfoGetter) PodStorage { func NewStorage(s tools.StorageInterface, k client.ConnectionInfoGetter) PodStorage {
prefix := "/pods" prefix := "/pods"
store := &etcdgeneric.Etcd{ store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.Pod{} }, NewFunc: func() runtime.Object { return &api.Pod{} },
@ -74,7 +74,7 @@ func NewStorage(h tools.EtcdHelper, k client.ConnectionInfoGetter) PodStorage {
}, },
EndpointName: "pods", EndpointName: "pods",
Helper: h, Storage: s,
} }
statusStore := *store statusStore := *store
@ -142,7 +142,7 @@ func (r *BindingREST) setPodHostAndAnnotations(ctx api.Context, podID, oldMachin
if err != nil { if err != nil {
return nil, err return nil, err
} }
err = r.store.Helper.GuaranteedUpdate(podKey, &api.Pod{}, false, tools.SimpleUpdate(func(obj runtime.Object) (runtime.Object, error) { err = r.store.Storage.GuaranteedUpdate(podKey, &api.Pod{}, false, tools.SimpleUpdate(func(obj runtime.Object) (runtime.Object, error) {
pod, ok := obj.(*api.Pod) pod, ok := obj.(*api.Pod)
if !ok { if !ok {
return nil, fmt.Errorf("unexpected object: %#v", obj) return nil, fmt.Errorf("unexpected object: %#v", obj)

View File

@ -40,17 +40,17 @@ import (
"github.com/coreos/go-etcd/etcd" "github.com/coreos/go-etcd/etcd"
) )
func newHelper(t *testing.T) (*tools.FakeEtcdClient, tools.EtcdHelper) { func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, tools.StorageInterface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true fakeEtcdClient.TestIndex = true
helper := tools.NewEtcdHelper(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix()) etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
return fakeEtcdClient, helper return fakeEtcdClient, etcdStorage
} }
func newStorage(t *testing.T) (*REST, *BindingREST, *StatusREST, *tools.FakeEtcdClient, tools.EtcdHelper) { func newStorage(t *testing.T) (*REST, *BindingREST, *StatusREST, *tools.FakeEtcdClient, tools.StorageInterface) {
fakeEtcdClient, h := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
storage := NewStorage(h, nil) storage := NewStorage(etcdStorage, nil)
return storage.Pod, storage.Binding, storage.Status, fakeEtcdClient, h return storage.Pod, storage.Binding, storage.Status, fakeEtcdClient, etcdStorage
} }
func validNewPod() *api.Pod { func validNewPod() *api.Pod {
@ -91,8 +91,8 @@ func TestStorage(t *testing.T) {
} }
func TestCreate(t *testing.T) { func TestCreate(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
storage := NewStorage(helper, nil).Pod storage := NewStorage(etcdStorage, nil).Pod
test := resttest.New(t, storage, fakeEtcdClient.SetError) test := resttest.New(t, storage, fakeEtcdClient.SetError)
pod := validNewPod() pod := validNewPod()
pod.ObjectMeta = api.ObjectMeta{} pod.ObjectMeta = api.ObjectMeta{}
@ -109,8 +109,8 @@ func TestCreate(t *testing.T) {
} }
func TestDelete(t *testing.T) { func TestDelete(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
storage := NewStorage(helper, nil).Pod storage := NewStorage(etcdStorage, nil).Pod
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
key, _ := storage.Etcd.KeyFunc(ctx, "foo") key, _ := storage.Etcd.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
@ -147,9 +147,9 @@ func expectPod(t *testing.T, out runtime.Object) (*api.Pod, bool) {
} }
func TestCreateRegistryError(t *testing.T) { func TestCreateRegistryError(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
fakeEtcdClient.Err = fmt.Errorf("test error") fakeEtcdClient.Err = fmt.Errorf("test error")
storage := NewStorage(helper, nil).Pod storage := NewStorage(etcdStorage, nil).Pod
pod := validNewPod() pod := validNewPod()
_, err := storage.Create(api.NewDefaultContext(), pod) _, err := storage.Create(api.NewDefaultContext(), pod)
@ -159,8 +159,8 @@ func TestCreateRegistryError(t *testing.T) {
} }
func TestCreateSetsFields(t *testing.T) { func TestCreateSetsFields(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
storage := NewStorage(helper, nil).Pod storage := NewStorage(etcdStorage, nil).Pod
pod := validNewPod() pod := validNewPod()
_, err := storage.Create(api.NewDefaultContext(), pod) _, err := storage.Create(api.NewDefaultContext(), pod)
if err != fakeEtcdClient.Err { if err != fakeEtcdClient.Err {
@ -169,7 +169,7 @@ func TestCreateSetsFields(t *testing.T) {
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
key, _ := storage.Etcd.KeyFunc(ctx, "foo") key, _ := storage.Etcd.KeyFunc(ctx, "foo")
actual := &api.Pod{} actual := &api.Pod{}
if err := helper.ExtractObj(key, actual, false); err != nil { if err := etcdStorage.ExtractObj(key, actual, false); err != nil {
t.Fatalf("unexpected extraction error: %v", err) t.Fatalf("unexpected extraction error: %v", err)
} }
if actual.Name != pod.Name { if actual.Name != pod.Name {
@ -181,9 +181,9 @@ func TestCreateSetsFields(t *testing.T) {
} }
func TestListError(t *testing.T) { func TestListError(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
fakeEtcdClient.Err = fmt.Errorf("test error") fakeEtcdClient.Err = fmt.Errorf("test error")
storage := NewStorage(helper, nil).Pod storage := NewStorage(etcdStorage, nil).Pod
pods, err := storage.List(api.NewDefaultContext(), labels.Everything(), fields.Everything()) pods, err := storage.List(api.NewDefaultContext(), labels.Everything(), fields.Everything())
if err != fakeEtcdClient.Err { if err != fakeEtcdClient.Err {
t.Fatalf("Expected %#v, Got %#v", fakeEtcdClient.Err, err) t.Fatalf("Expected %#v, Got %#v", fakeEtcdClient.Err, err)
@ -194,10 +194,10 @@ func TestListError(t *testing.T) {
} }
func TestListEmptyPodList(t *testing.T) { func TestListEmptyPodList(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
fakeEtcdClient.ChangeIndex = 1 fakeEtcdClient.ChangeIndex = 1
ctx := api.NewContext() ctx := api.NewContext()
storage := NewStorage(helper, nil).Pod storage := NewStorage(etcdStorage, nil).Pod
key := storage.Etcd.KeyRootFunc(ctx) key := storage.Etcd.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
@ -219,9 +219,9 @@ func TestListEmptyPodList(t *testing.T) {
} }
func TestListPodList(t *testing.T) { func TestListPodList(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
storage := NewStorage(helper, nil).Pod storage := NewStorage(etcdStorage, nil).Pod
key := storage.Etcd.KeyRootFunc(ctx) key := storage.Etcd.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
@ -264,9 +264,9 @@ func TestListPodList(t *testing.T) {
} }
func TestListPodListSelection(t *testing.T) { func TestListPodListSelection(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
storage := NewStorage(helper, nil).Pod storage := NewStorage(etcdStorage, nil).Pod
rootKey := etcdtest.AddPrefix("pods/default") rootKey := etcdtest.AddPrefix("pods/default")
key := etcdtest.AddPrefix("pods/default/zot") key := etcdtest.AddPrefix("pods/default/zot")
fakeEtcdClient.Data[rootKey] = tools.EtcdResponseWithError{ fakeEtcdClient.Data[rootKey] = tools.EtcdResponseWithError{
@ -368,7 +368,8 @@ func TestListPodListSelection(t *testing.T) {
} }
func TestPodDecode(t *testing.T) { func TestPodDecode(t *testing.T) {
storage := NewStorage(tools.EtcdHelper{}, nil).Pod _, etcdStorage := newEtcdStorage(t)
storage := NewStorage(etcdStorage, nil).Pod
expected := validNewPod() expected := validNewPod()
body, err := latest.Codec.Encode(expected) body, err := latest.Codec.Encode(expected)
if err != nil { if err != nil {
@ -390,7 +391,7 @@ func TestGet(t *testing.T) {
expect.Status.Phase = api.PodRunning expect.Status.Phase = api.PodRunning
expect.Spec.NodeName = "machine" expect.Spec.NodeName = "machine"
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
key := etcdtest.AddPrefix("/pods/test/foo") key := etcdtest.AddPrefix("/pods/test/foo")
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
@ -399,7 +400,7 @@ func TestGet(t *testing.T) {
}, },
}, },
} }
storage := NewStorage(helper, nil).Pod storage := NewStorage(etcdStorage, nil).Pod
obj, err := storage.Get(api.WithNamespace(api.NewContext(), "test"), "foo") obj, err := storage.Get(api.WithNamespace(api.NewContext(), "test"), "foo")
pod := obj.(*api.Pod) pod := obj.(*api.Pod)
@ -414,9 +415,9 @@ func TestGet(t *testing.T) {
// TODO: remove, this is covered by RESTTest.TestCreate // TODO: remove, this is covered by RESTTest.TestCreate
func TestPodStorageValidatesCreate(t *testing.T) { func TestPodStorageValidatesCreate(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
fakeEtcdClient.Err = fmt.Errorf("test error") fakeEtcdClient.Err = fmt.Errorf("test error")
storage := NewStorage(helper, nil).Pod storage := NewStorage(etcdStorage, nil).Pod
pod := validNewPod() pod := validNewPod()
pod.Labels = map[string]string{ pod.Labels = map[string]string{
@ -433,8 +434,8 @@ func TestPodStorageValidatesCreate(t *testing.T) {
// TODO: remove, this is covered by RESTTest.TestCreate // TODO: remove, this is covered by RESTTest.TestCreate
func TestCreatePod(t *testing.T) { func TestCreatePod(t *testing.T) {
_, helper := newHelper(t) _, etcdStorage := newEtcdStorage(t)
storage := NewStorage(helper, nil).Pod storage := NewStorage(etcdStorage, nil).Pod
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
key, _ := storage.Etcd.KeyFunc(ctx, "foo") key, _ := storage.Etcd.KeyFunc(ctx, "foo")
@ -447,7 +448,7 @@ func TestCreatePod(t *testing.T) {
t.Fatalf("unexpected object: %#v", obj) t.Fatalf("unexpected object: %#v", obj)
} }
actual := &api.Pod{} actual := &api.Pod{}
if err := helper.ExtractObj(key, actual, false); err != nil { if err := etcdStorage.ExtractObj(key, actual, false); err != nil {
t.Fatalf("unexpected extraction error: %v", err) t.Fatalf("unexpected extraction error: %v", err)
} }
if !api.HasObjectMetaSystemFieldValues(&actual.ObjectMeta) { if !api.HasObjectMetaSystemFieldValues(&actual.ObjectMeta) {
@ -457,8 +458,8 @@ func TestCreatePod(t *testing.T) {
// TODO: remove, this is covered by RESTTest.TestCreate // TODO: remove, this is covered by RESTTest.TestCreate
func TestCreateWithConflictingNamespace(t *testing.T) { func TestCreateWithConflictingNamespace(t *testing.T) {
_, helper := newHelper(t) _, etcdStorage := newEtcdStorage(t)
storage := NewStorage(helper, nil).Pod storage := NewStorage(etcdStorage, nil).Pod
pod := validNewPod() pod := validNewPod()
pod.Namespace = "not-default" pod.Namespace = "not-default"
@ -475,8 +476,8 @@ func TestCreateWithConflictingNamespace(t *testing.T) {
} }
func TestUpdateWithConflictingNamespace(t *testing.T) { func TestUpdateWithConflictingNamespace(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
storage := NewStorage(helper, nil).Pod storage := NewStorage(etcdStorage, nil).Pod
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
key, _ := storage.Etcd.KeyFunc(ctx, "foo") key, _ := storage.Etcd.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
@ -600,8 +601,8 @@ func TestResourceLocation(t *testing.T) {
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
for _, tc := range testCases { for _, tc := range testCases {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
storage := NewStorage(helper, nil).Pod storage := NewStorage(etcdStorage, nil).Pod
key, _ := storage.Etcd.KeyFunc(ctx, "foo") key, _ := storage.Etcd.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
@ -631,9 +632,9 @@ func TestResourceLocation(t *testing.T) {
} }
func TestDeletePod(t *testing.T) { func TestDeletePod(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
fakeEtcdClient.ChangeIndex = 1 fakeEtcdClient.ChangeIndex = 1
storage := NewStorage(helper, nil).Pod storage := NewStorage(etcdStorage, nil).Pod
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
key, _ := storage.Etcd.KeyFunc(ctx, "foo") key, _ := storage.Etcd.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
@ -1158,7 +1159,7 @@ func TestEtcdUpdateScheduled(t *testing.T) {
} }
func TestEtcdUpdateStatus(t *testing.T) { func TestEtcdUpdateStatus(t *testing.T) {
registry, _, status, fakeClient, helper := newStorage(t) registry, _, status, fakeClient, etcdStorage := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
fakeClient.TestIndex = true fakeClient.TestIndex = true
@ -1221,7 +1222,7 @@ func TestEtcdUpdateStatus(t *testing.T) {
} }
var podOut api.Pod var podOut api.Pod
key, _ = registry.KeyFunc(ctx, "foo") key, _ = registry.KeyFunc(ctx, "foo")
if err := helper.ExtractObj(key, &podOut, false); err != nil { if err := etcdStorage.ExtractObj(key, &podOut, false); err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
if !api.Semantic.DeepEqual(expected, podOut) { if !api.Semantic.DeepEqual(expected, podOut) {

View File

@ -33,7 +33,7 @@ type REST struct {
} }
// NewREST returns a RESTStorage object that will work against pod templates. // NewREST returns a RESTStorage object that will work against pod templates.
func NewREST(h tools.EtcdHelper) *REST { func NewREST(s tools.StorageInterface) *REST {
prefix := "/podtemplates" prefix := "/podtemplates"
store := etcdgeneric.Etcd{ store := etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.PodTemplate{} }, NewFunc: func() runtime.Object { return &api.PodTemplate{} },
@ -56,7 +56,7 @@ func NewREST(h tools.EtcdHelper) *REST {
UpdateStrategy: podtemplate.Strategy, UpdateStrategy: podtemplate.Strategy,
ReturnDeletedObject: true, ReturnDeletedObject: true,
Helper: h, Storage: s,
} }
return &REST{store} return &REST{store}

View File

@ -26,11 +26,11 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
) )
func newHelper(t *testing.T) (*tools.FakeEtcdClient, tools.EtcdHelper) { func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, tools.StorageInterface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true fakeEtcdClient.TestIndex = true
helper := tools.NewEtcdHelper(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix()) etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix())
return fakeEtcdClient, helper return fakeEtcdClient, etcdStorage
} }
func validNewPodTemplate(name string) *api.PodTemplate { func validNewPodTemplate(name string) *api.PodTemplate {
@ -61,8 +61,8 @@ func validNewPodTemplate(name string) *api.PodTemplate {
} }
func TestCreate(t *testing.T) { func TestCreate(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
storage := NewREST(helper) storage := NewREST(etcdStorage)
test := resttest.New(t, storage, fakeEtcdClient.SetError) test := resttest.New(t, storage, fakeEtcdClient.SetError)
pod := validNewPodTemplate("foo") pod := validNewPodTemplate("foo")
pod.ObjectMeta = api.ObjectMeta{} pod.ObjectMeta = api.ObjectMeta{}
@ -77,8 +77,8 @@ func TestCreate(t *testing.T) {
} }
func TestUpdate(t *testing.T) { func TestUpdate(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
storage := NewREST(helper) storage := NewREST(etcdStorage)
test := resttest.New(t, storage, fakeEtcdClient.SetError) test := resttest.New(t, storage, fakeEtcdClient.SetError)
key, err := storage.KeyFunc(test.TestContext(), "foo") key, err := storage.KeyFunc(test.TestContext(), "foo")
if err != nil { if err != nil {

View File

@ -33,7 +33,7 @@ type REST struct {
} }
// NewStorage returns a RESTStorage object that will work against ResourceQuota objects. // NewStorage returns a RESTStorage object that will work against ResourceQuota objects.
func NewStorage(h tools.EtcdHelper) (*REST, *StatusREST) { func NewStorage(s tools.StorageInterface) (*REST, *StatusREST) {
prefix := "/resourcequotas" prefix := "/resourcequotas"
store := &etcdgeneric.Etcd{ store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.ResourceQuota{} }, NewFunc: func() runtime.Object { return &api.ResourceQuota{} },
@ -52,7 +52,7 @@ func NewStorage(h tools.EtcdHelper) (*REST, *StatusREST) {
}, },
EndpointName: "resourcequotas", EndpointName: "resourcequotas",
Helper: h, Storage: s,
} }
store.CreateStrategy = resourcequota.Strategy store.CreateStrategy = resourcequota.Strategy

View File

@ -38,15 +38,15 @@ import (
"github.com/coreos/go-etcd/etcd" "github.com/coreos/go-etcd/etcd"
) )
func newHelper(t *testing.T) (*tools.FakeEtcdClient, tools.EtcdHelper) { func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, tools.StorageInterface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true fakeEtcdClient.TestIndex = true
helper := tools.NewEtcdHelper(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix()) etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
return fakeEtcdClient, helper return fakeEtcdClient, etcdStorage
} }
func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient, tools.EtcdHelper) { func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient, tools.StorageInterface) {
fakeEtcdClient, h := newHelper(t) fakeEtcdClient, h := newEtcdStorage(t)
storage, statusStorage := NewStorage(h) storage, statusStorage := NewStorage(h)
return storage, statusStorage, fakeEtcdClient, h return storage, statusStorage, fakeEtcdClient, h
} }
@ -85,8 +85,8 @@ func TestStorage(t *testing.T) {
} }
func TestCreate(t *testing.T) { func TestCreate(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
storage, _ := NewStorage(helper) storage, _ := NewStorage(etcdStorage)
test := resttest.New(t, storage, fakeEtcdClient.SetError) test := resttest.New(t, storage, fakeEtcdClient.SetError)
resourcequota := validNewResourceQuota() resourcequota := validNewResourceQuota()
resourcequota.ObjectMeta = api.ObjectMeta{} resourcequota.ObjectMeta = api.ObjectMeta{}
@ -110,9 +110,9 @@ func expectResourceQuota(t *testing.T, out runtime.Object) (*api.ResourceQuota,
} }
func TestCreateRegistryError(t *testing.T) { func TestCreateRegistryError(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
fakeEtcdClient.Err = fmt.Errorf("test error") fakeEtcdClient.Err = fmt.Errorf("test error")
storage, _ := NewStorage(helper) storage, _ := NewStorage(etcdStorage)
resourcequota := validNewResourceQuota() resourcequota := validNewResourceQuota()
_, err := storage.Create(api.NewDefaultContext(), resourcequota) _, err := storage.Create(api.NewDefaultContext(), resourcequota)
@ -122,8 +122,8 @@ func TestCreateRegistryError(t *testing.T) {
} }
func TestCreateSetsFields(t *testing.T) { func TestCreateSetsFields(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
storage, _ := NewStorage(helper) storage, _ := NewStorage(etcdStorage)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
resourcequota := validNewResourceQuota() resourcequota := validNewResourceQuota()
_, err := storage.Create(api.NewDefaultContext(), resourcequota) _, err := storage.Create(api.NewDefaultContext(), resourcequota)
@ -133,7 +133,7 @@ func TestCreateSetsFields(t *testing.T) {
actual := &api.ResourceQuota{} actual := &api.ResourceQuota{}
key, _ := storage.Etcd.KeyFunc(ctx, "foo") key, _ := storage.Etcd.KeyFunc(ctx, "foo")
if err := helper.ExtractObj(key, actual, false); err != nil { if err := etcdStorage.ExtractObj(key, actual, false); err != nil {
t.Fatalf("unexpected extraction error: %v", err) t.Fatalf("unexpected extraction error: %v", err)
} }
if actual.Name != resourcequota.Name { if actual.Name != resourcequota.Name {
@ -145,9 +145,9 @@ func TestCreateSetsFields(t *testing.T) {
} }
func TestListError(t *testing.T) { func TestListError(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
fakeEtcdClient.Err = fmt.Errorf("test error") fakeEtcdClient.Err = fmt.Errorf("test error")
storage, _ := NewStorage(helper) storage, _ := NewStorage(etcdStorage)
resourcequotas, err := storage.List(api.NewDefaultContext(), labels.Everything(), fields.Everything()) resourcequotas, err := storage.List(api.NewDefaultContext(), labels.Everything(), fields.Everything())
if err != fakeEtcdClient.Err { if err != fakeEtcdClient.Err {
t.Fatalf("Expected %#v, Got %#v", fakeEtcdClient.Err, err) t.Fatalf("Expected %#v, Got %#v", fakeEtcdClient.Err, err)
@ -158,9 +158,9 @@ func TestListError(t *testing.T) {
} }
func TestListEmptyResourceQuotaList(t *testing.T) { func TestListEmptyResourceQuotaList(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
fakeEtcdClient.ChangeIndex = 1 fakeEtcdClient.ChangeIndex = 1
storage, _ := NewStorage(helper) storage, _ := NewStorage(etcdStorage)
ctx := api.NewContext() ctx := api.NewContext()
key := storage.Etcd.KeyRootFunc(ctx) key := storage.Etcd.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
@ -184,8 +184,8 @@ func TestListEmptyResourceQuotaList(t *testing.T) {
} }
func TestListResourceQuotaList(t *testing.T) { func TestListResourceQuotaList(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
storage, _ := NewStorage(helper) storage, _ := NewStorage(etcdStorage)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
key := storage.Etcd.KeyRootFunc(ctx) key := storage.Etcd.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
@ -225,8 +225,8 @@ func TestListResourceQuotaList(t *testing.T) {
} }
func TestListResourceQuotaListSelection(t *testing.T) { func TestListResourceQuotaListSelection(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
storage, _ := NewStorage(helper) storage, _ := NewStorage(etcdStorage)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
key := storage.Etcd.KeyRootFunc(ctx) key := storage.Etcd.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
@ -294,7 +294,8 @@ func TestListResourceQuotaListSelection(t *testing.T) {
} }
func TestResourceQuotaDecode(t *testing.T) { func TestResourceQuotaDecode(t *testing.T) {
storage, _ := NewStorage(tools.EtcdHelper{}) _, etcdStorage := newEtcdStorage(t)
storage, _ := NewStorage(etcdStorage)
expected := validNewResourceQuota() expected := validNewResourceQuota()
body, err := latest.Codec.Encode(expected) body, err := latest.Codec.Encode(expected)
if err != nil { if err != nil {
@ -313,8 +314,8 @@ func TestResourceQuotaDecode(t *testing.T) {
func TestGet(t *testing.T) { func TestGet(t *testing.T) {
expect := validNewResourceQuota() expect := validNewResourceQuota()
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
storage, _ := NewStorage(helper) storage, _ := NewStorage(etcdStorage)
key := "/resourcequotas/test/foo" key := "/resourcequotas/test/foo"
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
@ -336,9 +337,9 @@ func TestGet(t *testing.T) {
} }
func TestDeleteResourceQuota(t *testing.T) { func TestDeleteResourceQuota(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
fakeEtcdClient.ChangeIndex = 1 fakeEtcdClient.ChangeIndex = 1
storage, _ := NewStorage(helper) storage, _ := NewStorage(etcdStorage)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
key, _ := storage.Etcd.KeyFunc(ctx, "foo") key, _ := storage.Etcd.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
@ -470,7 +471,7 @@ func TestEtcdCreateAlreadyExisting(t *testing.T) {
} }
func TestEtcdUpdateStatus(t *testing.T) { func TestEtcdUpdateStatus(t *testing.T) {
registry, status, fakeClient, helper := newStorage(t) registry, status, fakeClient, etcdStorage := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
fakeClient.TestIndex = true fakeClient.TestIndex = true
@ -516,7 +517,7 @@ func TestEtcdUpdateStatus(t *testing.T) {
} }
var resourcequotaOut api.ResourceQuota var resourcequotaOut api.ResourceQuota
key, _ = registry.KeyFunc(ctx, "foo") key, _ = registry.KeyFunc(ctx, "foo")
if err := helper.ExtractObj(key, &resourcequotaOut, false); err != nil { if err := etcdStorage.ExtractObj(key, &resourcequotaOut, false); err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
if !api.Semantic.DeepEqual(expected, resourcequotaOut) { if !api.Semantic.DeepEqual(expected, resourcequotaOut) {

View File

@ -32,9 +32,8 @@ type REST struct {
*etcdgeneric.Etcd *etcdgeneric.Etcd
} }
// NewStorage returns a registry which will store Secret in the given helper // NewStorage returns a registry which will store Secret in the given etcdStorage
func NewStorage(h tools.EtcdHelper) *REST { func NewStorage(s tools.StorageInterface) *REST {
prefix := "/secrets" prefix := "/secrets"
store := &etcdgeneric.Etcd{ store := &etcdgeneric.Etcd{
@ -54,7 +53,7 @@ func NewStorage(h tools.EtcdHelper) *REST {
}, },
EndpointName: "secrets", EndpointName: "secrets",
Helper: h, Storage: s,
} }
store.CreateStrategy = secret.Strategy store.CreateStrategy = secret.Strategy

View File

@ -26,11 +26,11 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
) )
func newHelper(t *testing.T) (*tools.FakeEtcdClient, tools.EtcdHelper) { func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, tools.StorageInterface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true fakeEtcdClient.TestIndex = true
helper := tools.NewEtcdHelper(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix()) etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix())
return fakeEtcdClient, helper return fakeEtcdClient, etcdStorage
} }
func validNewSecret(name string) *api.Secret { func validNewSecret(name string) *api.Secret {
@ -46,8 +46,8 @@ func validNewSecret(name string) *api.Secret {
} }
func TestCreate(t *testing.T) { func TestCreate(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
storage := NewStorage(helper) storage := NewStorage(etcdStorage)
test := resttest.New(t, storage, fakeEtcdClient.SetError) test := resttest.New(t, storage, fakeEtcdClient.SetError)
secret := validNewSecret("foo") secret := validNewSecret("foo")
secret.ObjectMeta = api.ObjectMeta{GenerateName: "foo-"} secret.ObjectMeta = api.ObjectMeta{GenerateName: "foo-"}
@ -68,8 +68,8 @@ func TestCreate(t *testing.T) {
} }
func TestUpdate(t *testing.T) { func TestUpdate(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
storage := NewStorage(helper) storage := NewStorage(etcdStorage)
test := resttest.New(t, storage, fakeEtcdClient.SetError) test := resttest.New(t, storage, fakeEtcdClient.SetError)
key, err := storage.KeyFunc(test.TestContext(), "foo") key, err := storage.KeyFunc(test.TestContext(), "foo")
if err != nil { if err != nil {

View File

@ -42,7 +42,7 @@ type Etcd struct {
lock sync.Mutex lock sync.Mutex
alloc allocator.Snapshottable alloc allocator.Snapshottable
helper tools.EtcdHelper storage tools.StorageInterface
last string last string
baseKey string baseKey string
@ -55,10 +55,10 @@ var _ service.RangeRegistry = &Etcd{}
// NewEtcd returns an allocator that is backed by Etcd and can manage // NewEtcd returns an allocator that is backed by Etcd and can manage
// persisting the snapshot state of allocation after each allocation is made. // persisting the snapshot state of allocation after each allocation is made.
func NewEtcd(alloc allocator.Snapshottable, baseKey string, kind string, helper tools.EtcdHelper) *Etcd { func NewEtcd(alloc allocator.Snapshottable, baseKey string, kind string, storage tools.StorageInterface) *Etcd {
return &Etcd{ return &Etcd{
alloc: alloc, alloc: alloc,
helper: helper, storage: storage,
baseKey: baseKey, baseKey: baseKey,
kind: kind, kind: kind,
} }
@ -140,7 +140,7 @@ func (e *Etcd) Release(item int) error {
// tryUpdate performs a read-update to persist the latest snapshot state of allocation. // tryUpdate performs a read-update to persist the latest snapshot state of allocation.
func (e *Etcd) tryUpdate(fn func() error) error { func (e *Etcd) tryUpdate(fn func() error) error {
err := e.helper.GuaranteedUpdate(e.baseKey, &api.RangeAllocation{}, true, err := e.storage.GuaranteedUpdate(e.baseKey, &api.RangeAllocation{}, true,
tools.SimpleUpdate(func(input runtime.Object) (output runtime.Object, err error) { tools.SimpleUpdate(func(input runtime.Object) (output runtime.Object, err error) {
existing := input.(*api.RangeAllocation) existing := input.(*api.RangeAllocation)
if len(existing.ResourceVersion) == 0 { if len(existing.ResourceVersion) == 0 {
@ -170,7 +170,7 @@ func (e *Etcd) Refresh() (*api.RangeAllocation, error) {
defer e.lock.Unlock() defer e.lock.Unlock()
existing := &api.RangeAllocation{} existing := &api.RangeAllocation{}
if err := e.helper.ExtractObj(e.baseKey, existing, false); err != nil { if err := e.storage.ExtractObj(e.baseKey, existing, false); err != nil {
if tools.IsEtcdNotFound(err) { if tools.IsEtcdNotFound(err) {
return nil, nil return nil, nil
} }
@ -184,7 +184,7 @@ func (e *Etcd) Refresh() (*api.RangeAllocation, error) {
// etcd. If the key does not exist, the object will have an empty ResourceVersion. // etcd. If the key does not exist, the object will have an empty ResourceVersion.
func (e *Etcd) Get() (*api.RangeAllocation, error) { func (e *Etcd) Get() (*api.RangeAllocation, error) {
existing := &api.RangeAllocation{} existing := &api.RangeAllocation{}
if err := e.helper.ExtractObj(e.baseKey, existing, true); err != nil { if err := e.storage.ExtractObj(e.baseKey, existing, true); err != nil {
return nil, etcderr.InterpretGetError(err, e.kind, "") return nil, etcderr.InterpretGetError(err, e.kind, "")
} }
return existing, nil return existing, nil
@ -197,7 +197,7 @@ func (e *Etcd) CreateOrUpdate(snapshot *api.RangeAllocation) error {
defer e.lock.Unlock() defer e.lock.Unlock()
last := "" last := ""
err := e.helper.GuaranteedUpdate(e.baseKey, &api.RangeAllocation{}, true, err := e.storage.GuaranteedUpdate(e.baseKey, &api.RangeAllocation{}, true,
tools.SimpleUpdate(func(input runtime.Object) (output runtime.Object, err error) { tools.SimpleUpdate(func(input runtime.Object) (output runtime.Object, err error) {
existing := input.(*api.RangeAllocation) existing := input.(*api.RangeAllocation)
switch { switch {

View File

@ -30,18 +30,18 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
) )
func newHelper(t *testing.T) (*tools.FakeEtcdClient, tools.EtcdHelper) { func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, tools.StorageInterface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true fakeEtcdClient.TestIndex = true
helper := tools.NewEtcdHelper(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix()) etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix())
return fakeEtcdClient, helper return fakeEtcdClient, etcdStorage
} }
func newStorage(t *testing.T) (*Etcd, allocator.Interface, *tools.FakeEtcdClient) { func newStorage(t *testing.T) (*Etcd, allocator.Interface, *tools.FakeEtcdClient) {
fakeEtcdClient, h := newHelper(t) fakeEtcdClient, s := newEtcdStorage(t)
mem := allocator.NewAllocationMap(100, "rangeSpecValue") mem := allocator.NewAllocationMap(100, "rangeSpecValue")
etcd := NewEtcd(mem, "/ranges/serviceips", "serviceipallocation", h) etcd := NewEtcd(mem, "/ranges/serviceips", "serviceipallocation", s)
return etcd, mem, fakeEtcdClient return etcd, mem, fakeEtcdClient
} }
@ -101,7 +101,7 @@ func TestStore(t *testing.T) {
other := allocator.NewAllocationMap(100, "rangeSpecValue") other := allocator.NewAllocationMap(100, "rangeSpecValue")
allocation := &api.RangeAllocation{} allocation := &api.RangeAllocation{}
if err := storage.helper.ExtractObj(key(), allocation, false); err != nil { if err := storage.storage.ExtractObj(key(), allocation, false); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if allocation.ResourceVersion != "1" { if allocation.ResourceVersion != "1" {
@ -118,7 +118,7 @@ func TestStore(t *testing.T) {
} }
other = allocator.NewAllocationMap(100, "rangeSpecValue") other = allocator.NewAllocationMap(100, "rangeSpecValue")
otherStorage := NewEtcd(other, "/ranges/serviceips", "serviceipallocation", storage.helper) otherStorage := NewEtcd(other, "/ranges/serviceips", "serviceipallocation", storage.storage)
if ok, err := otherStorage.Allocate(2); ok || err != nil { if ok, err := otherStorage.Allocate(2); ok || err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@ -33,15 +33,15 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
) )
func newHelper(t *testing.T) (*tools.FakeEtcdClient, tools.EtcdHelper) { func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, tools.StorageInterface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true fakeEtcdClient.TestIndex = true
helper := tools.NewEtcdHelper(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix()) etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix())
return fakeEtcdClient, helper return fakeEtcdClient, etcdStorage
} }
func newStorage(t *testing.T) (ipallocator.Interface, allocator.Interface, *tools.FakeEtcdClient) { func newStorage(t *testing.T) (ipallocator.Interface, allocator.Interface, *tools.FakeEtcdClient) {
fakeEtcdClient, h := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
_, cidr, err := net.ParseCIDR("192.168.1.0/24") _, cidr, err := net.ParseCIDR("192.168.1.0/24")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -51,7 +51,7 @@ func newStorage(t *testing.T) (ipallocator.Interface, allocator.Interface, *tool
storage := ipallocator.NewAllocatorCIDRRange(cidr, func(max int, rangeSpec string) allocator.Interface { storage := ipallocator.NewAllocatorCIDRRange(cidr, func(max int, rangeSpec string) allocator.Interface {
mem := allocator.NewAllocationMap(max, rangeSpec) mem := allocator.NewAllocationMap(max, rangeSpec)
backing = mem backing = mem
etcd := allocator_etcd.NewEtcd(mem, "/ranges/serviceips", "serviceipallocation", h) etcd := allocator_etcd.NewEtcd(mem, "/ranges/serviceips", "serviceipallocation", etcdStorage)
return etcd return etcd
}) })

View File

@ -35,7 +35,7 @@ type REST struct {
const Prefix = "/serviceaccounts" const Prefix = "/serviceaccounts"
// NewStorage returns a RESTStorage object that will work against service accounts objects. // NewStorage returns a RESTStorage object that will work against service accounts objects.
func NewStorage(h tools.EtcdHelper) *REST { func NewStorage(s tools.StorageInterface) *REST {
store := &etcdgeneric.Etcd{ store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.ServiceAccount{} }, NewFunc: func() runtime.Object { return &api.ServiceAccount{} },
NewListFunc: func() runtime.Object { return &api.ServiceAccountList{} }, NewListFunc: func() runtime.Object { return &api.ServiceAccountList{} },
@ -53,7 +53,7 @@ func NewStorage(h tools.EtcdHelper) *REST {
}, },
EndpointName: "serviceaccounts", EndpointName: "serviceaccounts",
Helper: h, Storage: s,
} }
store.CreateStrategy = serviceaccount.Strategy store.CreateStrategy = serviceaccount.Strategy

View File

@ -26,11 +26,11 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
) )
func newHelper(t *testing.T) (*tools.FakeEtcdClient, tools.EtcdHelper) { func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, tools.StorageInterface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true fakeEtcdClient.TestIndex = true
helper := tools.NewEtcdHelper(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix()) etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix())
return fakeEtcdClient, helper return fakeEtcdClient, etcdStorage
} }
func validNewServiceAccount(name string) *api.ServiceAccount { func validNewServiceAccount(name string) *api.ServiceAccount {
@ -44,8 +44,8 @@ func validNewServiceAccount(name string) *api.ServiceAccount {
} }
func TestCreate(t *testing.T) { func TestCreate(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
storage := NewStorage(helper) storage := NewStorage(etcdStorage)
test := resttest.New(t, storage, fakeEtcdClient.SetError) test := resttest.New(t, storage, fakeEtcdClient.SetError)
serviceAccount := validNewServiceAccount("foo") serviceAccount := validNewServiceAccount("foo")
serviceAccount.ObjectMeta = api.ObjectMeta{GenerateName: "foo-"} serviceAccount.ObjectMeta = api.ObjectMeta{GenerateName: "foo-"}
@ -61,8 +61,8 @@ func TestCreate(t *testing.T) {
} }
func TestUpdate(t *testing.T) { func TestUpdate(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, etcdStorage := newEtcdStorage(t)
storage := NewStorage(helper) storage := NewStorage(etcdStorage)
test := resttest.New(t, storage, fakeEtcdClient.SetError) test := resttest.New(t, storage, fakeEtcdClient.SetError)
key, err := storage.KeyFunc(test.TestContext(), "foo") key, err := storage.KeyFunc(test.TestContext(), "foo")
if err != nil { if err != nil {

View File

@ -71,11 +71,11 @@ func (r *registryGetter) GetSecret(namespace, name string) (*api.Secret, error)
return r.secrets.GetSecret(ctx, name) return r.secrets.GetSecret(ctx, name)
} }
// NewGetterFromEtcdHelper returns a ServiceAccountTokenGetter that // NewGetterFromStorageInterface returns a ServiceAccountTokenGetter that
// uses the specified helper to retrieve service accounts and secrets. // uses the specified storage to retrieve service accounts and secrets.
func NewGetterFromEtcdHelper(helper tools.EtcdHelper) ServiceAccountTokenGetter { func NewGetterFromStorageInterface(storage tools.StorageInterface) ServiceAccountTokenGetter {
return NewGetterFromRegistries( return NewGetterFromRegistries(
serviceaccount.NewRegistry(serviceaccountetcd.NewStorage(helper)), serviceaccount.NewRegistry(serviceaccountetcd.NewStorage(storage)),
secret.NewRegistry(secretetcd.NewStorage(helper)), secret.NewRegistry(secretetcd.NewStorage(storage)),
) )
} }

View File

@ -34,27 +34,26 @@ import (
"github.com/golang/glog" "github.com/golang/glog"
) )
func NewEtcdHelper(client EtcdClient, codec runtime.Codec, prefix string) EtcdHelper { func NewEtcdStorage(client EtcdClient, codec runtime.Codec, prefix string) StorageInterface {
return EtcdHelper{ return &etcdHelper{
Client: client, client: client,
Codec: codec, codec: codec,
Versioner: APIObjectVersioner{}, versioner: APIObjectVersioner{},
Copier: api.Scheme, copier: api.Scheme,
PathPrefix: prefix, pathPrefix: prefix,
cache: util.NewCache(maxEtcdCacheEntries), cache: util.NewCache(maxEtcdCacheEntries),
} }
} }
// EtcdHelper is the reference implementation of StorageInterface. // etcdHelper is the reference implementation of StorageInterface.
// TODO(wojtekt): Make it private and expose only StorageInterface to outside world. type etcdHelper struct {
type EtcdHelper struct { client EtcdClient
Client EtcdClient codec runtime.Codec
Codec runtime.Codec copier runtime.ObjectCopier
Copier runtime.ObjectCopier
// optional, has to be set to perform any atomic operations // optional, has to be set to perform any atomic operations
Versioner EtcdVersioner versioner StorageVersioner
// prefix for all etcd keys // prefix for all etcd keys
PathPrefix string pathPrefix string
// We cache objects stored in etcd. For keys we use Node.ModifiedIndex which is equivalent // We cache objects stored in etcd. For keys we use Node.ModifiedIndex which is equivalent
// to resourceVersion. // to resourceVersion.
@ -71,20 +70,30 @@ func init() {
} }
// Implements StorageInterface. // Implements StorageInterface.
func (h *EtcdHelper) CreateObj(key string, obj, out runtime.Object, ttl uint64) error { func (h *etcdHelper) Backends() []string {
return h.client.GetCluster()
}
// Implements StorageInterface.
func (h *etcdHelper) Versioner() StorageVersioner {
return h.versioner
}
// Implements StorageInterface.
func (h *etcdHelper) CreateObj(key string, obj, out runtime.Object, ttl uint64) error {
key = h.prefixEtcdKey(key) key = h.prefixEtcdKey(key)
data, err := h.Codec.Encode(obj) data, err := h.codec.Encode(obj)
if err != nil { if err != nil {
return err return err
} }
if h.Versioner != nil { if h.versioner != nil {
if version, err := h.Versioner.ObjectResourceVersion(obj); err == nil && version != 0 { if version, err := h.versioner.ObjectResourceVersion(obj); err == nil && version != 0 {
return errors.New("resourceVersion may not be set on objects to be created") return errors.New("resourceVersion may not be set on objects to be created")
} }
} }
startTime := time.Now() startTime := time.Now()
response, err := h.Client.Create(key, string(data), ttl) response, err := h.client.Create(key, string(data), ttl)
metrics.RecordEtcdRequestLatency("create", getTypeName(obj), startTime) metrics.RecordEtcdRequestLatency("create", getTypeName(obj), startTime)
if err != nil { if err != nil {
return err return err
@ -99,20 +108,20 @@ func (h *EtcdHelper) CreateObj(key string, obj, out runtime.Object, ttl uint64)
} }
// Implements StorageInterface. // Implements StorageInterface.
func (h *EtcdHelper) SetObj(key string, obj, out runtime.Object, ttl uint64) error { func (h *etcdHelper) SetObj(key string, obj, out runtime.Object, ttl uint64) error {
var response *etcd.Response var response *etcd.Response
data, err := h.Codec.Encode(obj) data, err := h.codec.Encode(obj)
if err != nil { if err != nil {
return err return err
} }
key = h.prefixEtcdKey(key) key = h.prefixEtcdKey(key)
create := true create := true
if h.Versioner != nil { if h.versioner != nil {
if version, err := h.Versioner.ObjectResourceVersion(obj); err == nil && version != 0 { if version, err := h.versioner.ObjectResourceVersion(obj); err == nil && version != 0 {
create = false create = false
startTime := time.Now() startTime := time.Now()
response, err = h.Client.CompareAndSwap(key, string(data), ttl, "", version) response, err = h.client.CompareAndSwap(key, string(data), ttl, "", version)
metrics.RecordEtcdRequestLatency("compareAndSwap", getTypeName(obj), startTime) metrics.RecordEtcdRequestLatency("compareAndSwap", getTypeName(obj), startTime)
if err != nil { if err != nil {
return err return err
@ -122,7 +131,7 @@ func (h *EtcdHelper) SetObj(key string, obj, out runtime.Object, ttl uint64) err
if create { if create {
// Create will fail if a key already exists. // Create will fail if a key already exists.
startTime := time.Now() startTime := time.Now()
response, err = h.Client.Create(key, string(data), ttl) response, err = h.client.Create(key, string(data), ttl)
metrics.RecordEtcdRequestLatency("create", getTypeName(obj), startTime) metrics.RecordEtcdRequestLatency("create", getTypeName(obj), startTime)
} }
@ -140,14 +149,14 @@ func (h *EtcdHelper) SetObj(key string, obj, out runtime.Object, ttl uint64) err
} }
// Implements StorageInterface. // Implements StorageInterface.
func (h *EtcdHelper) DeleteObj(key string, out runtime.Object) error { func (h *etcdHelper) DeleteObj(key string, out runtime.Object) error {
key = h.prefixEtcdKey(key) key = h.prefixEtcdKey(key)
if _, err := conversion.EnforcePtr(out); err != nil { if _, err := conversion.EnforcePtr(out); err != nil {
panic("unable to convert output object to pointer") panic("unable to convert output object to pointer")
} }
startTime := time.Now() startTime := time.Now()
response, err := h.Client.Delete(key, false) response, err := h.client.Delete(key, false)
metrics.RecordEtcdRequestLatency("delete", getTypeName(out), startTime) metrics.RecordEtcdRequestLatency("delete", getTypeName(out), startTime)
if !IsEtcdNotFound(err) { if !IsEtcdNotFound(err) {
// if the object that existed prior to the delete is returned by etcd, update out. // if the object that existed prior to the delete is returned by etcd, update out.
@ -159,16 +168,16 @@ func (h *EtcdHelper) DeleteObj(key string, out runtime.Object) error {
} }
// Implements StorageInterface. // Implements StorageInterface.
func (h *EtcdHelper) Delete(key string, recursive bool) error { func (h *etcdHelper) Delete(key string, recursive bool) error {
key = h.prefixEtcdKey(key) key = h.prefixEtcdKey(key)
startTime := time.Now() startTime := time.Now()
_, err := h.Client.Delete(key, recursive) _, err := h.client.Delete(key, recursive)
metrics.RecordEtcdRequestLatency("delete", "UNKNOWN", startTime) metrics.RecordEtcdRequestLatency("delete", "UNKNOWN", startTime)
return err return err
} }
// Implements StorageInterface. // Implements StorageInterface.
func (h *EtcdHelper) ExtractObj(key string, objPtr runtime.Object, ignoreNotFound bool) error { func (h *etcdHelper) ExtractObj(key string, objPtr runtime.Object, ignoreNotFound bool) error {
key = h.prefixEtcdKey(key) key = h.prefixEtcdKey(key)
_, _, _, err := h.bodyAndExtractObj(key, objPtr, ignoreNotFound) _, _, _, err := h.bodyAndExtractObj(key, objPtr, ignoreNotFound)
return err return err
@ -176,9 +185,9 @@ func (h *EtcdHelper) ExtractObj(key string, objPtr runtime.Object, ignoreNotFoun
// bodyAndExtractObj performs the normal Get path to etcd, returning the parsed node and response for additional information // bodyAndExtractObj performs the normal Get path to etcd, returning the parsed node and response for additional information
// about the response, like the current etcd index and the ttl. // about the response, like the current etcd index and the ttl.
func (h *EtcdHelper) bodyAndExtractObj(key string, objPtr runtime.Object, ignoreNotFound bool) (body string, node *etcd.Node, res *etcd.Response, err error) { func (h *etcdHelper) bodyAndExtractObj(key string, objPtr runtime.Object, ignoreNotFound bool) (body string, node *etcd.Node, res *etcd.Response, err error) {
startTime := time.Now() startTime := time.Now()
response, err := h.Client.Get(key, false, false) response, err := h.client.Get(key, false, false)
metrics.RecordEtcdRequestLatency("get", getTypeName(objPtr), startTime) metrics.RecordEtcdRequestLatency("get", getTypeName(objPtr), startTime)
if err != nil && !IsEtcdNotFound(err) { if err != nil && !IsEtcdNotFound(err) {
@ -188,7 +197,7 @@ func (h *EtcdHelper) bodyAndExtractObj(key string, objPtr runtime.Object, ignore
return body, node, response, err return body, node, response, err
} }
func (h *EtcdHelper) extractObj(response *etcd.Response, inErr error, objPtr runtime.Object, ignoreNotFound, prevNode bool) (body string, node *etcd.Node, err error) { func (h *etcdHelper) extractObj(response *etcd.Response, inErr error, objPtr runtime.Object, ignoreNotFound, prevNode bool) (body string, node *etcd.Node, err error) {
if response != nil { if response != nil {
if prevNode { if prevNode {
node = response.PrevNode node = response.PrevNode
@ -210,16 +219,16 @@ func (h *EtcdHelper) extractObj(response *etcd.Response, inErr error, objPtr run
return "", nil, fmt.Errorf("unable to locate a value on the response: %#v", response) return "", nil, fmt.Errorf("unable to locate a value on the response: %#v", response)
} }
body = node.Value body = node.Value
err = h.Codec.DecodeInto([]byte(body), objPtr) err = h.codec.DecodeInto([]byte(body), objPtr)
if h.Versioner != nil { if h.versioner != nil {
_ = h.Versioner.UpdateObject(objPtr, node.Expiration, node.ModifiedIndex) _ = h.versioner.UpdateObject(objPtr, node.Expiration, node.ModifiedIndex)
// being unable to set the version does not prevent the object from being extracted // being unable to set the version does not prevent the object from being extracted
} }
return body, node, err return body, node, err
} }
// Implements StorageInterface. // Implements StorageInterface.
func (h *EtcdHelper) ExtractObjToList(key string, listObj runtime.Object) error { func (h *etcdHelper) ExtractObjToList(key string, listObj runtime.Object) error {
trace := util.NewTrace("ExtractObjToList " + getTypeName(listObj)) trace := util.NewTrace("ExtractObjToList " + getTypeName(listObj))
listPtr, err := runtime.GetItemsPtr(listObj) listPtr, err := runtime.GetItemsPtr(listObj)
if err != nil { if err != nil {
@ -228,7 +237,7 @@ func (h *EtcdHelper) ExtractObjToList(key string, listObj runtime.Object) error
key = h.prefixEtcdKey(key) key = h.prefixEtcdKey(key)
startTime := time.Now() startTime := time.Now()
trace.Step("About to read etcd node") trace.Step("About to read etcd node")
response, err := h.Client.Get(key, false, false) response, err := h.client.Get(key, false, false)
metrics.RecordEtcdRequestLatency("get", getTypeName(listPtr), startTime) metrics.RecordEtcdRequestLatency("get", getTypeName(listPtr), startTime)
trace.Step("Etcd node read") trace.Step("Etcd node read")
if err != nil { if err != nil {
@ -245,8 +254,8 @@ func (h *EtcdHelper) ExtractObjToList(key string, listObj runtime.Object) error
return err return err
} }
trace.Step("Object decoded") trace.Step("Object decoded")
if h.Versioner != nil { if h.versioner != nil {
if err := h.Versioner.UpdateList(listObj, response.EtcdIndex); err != nil { if err := h.versioner.UpdateList(listObj, response.EtcdIndex); err != nil {
return err return err
} }
} }
@ -254,7 +263,7 @@ func (h *EtcdHelper) ExtractObjToList(key string, listObj runtime.Object) error
} }
// decodeNodeList walks the tree of each node in the list and decodes into the specified object // decodeNodeList walks the tree of each node in the list and decodes into the specified object
func (h *EtcdHelper) decodeNodeList(nodes []*etcd.Node, slicePtr interface{}) error { func (h *etcdHelper) decodeNodeList(nodes []*etcd.Node, slicePtr interface{}) error {
trace := util.NewTrace("decodeNodeList " + getTypeName(slicePtr)) trace := util.NewTrace("decodeNodeList " + getTypeName(slicePtr))
defer trace.LogIfLong(500 * time.Millisecond) defer trace.LogIfLong(500 * time.Millisecond)
v, err := conversion.EnforcePtr(slicePtr) v, err := conversion.EnforcePtr(slicePtr)
@ -275,12 +284,12 @@ func (h *EtcdHelper) decodeNodeList(nodes []*etcd.Node, slicePtr interface{}) er
v.Set(reflect.Append(v, reflect.ValueOf(obj).Elem())) v.Set(reflect.Append(v, reflect.ValueOf(obj).Elem()))
} else { } else {
obj := reflect.New(v.Type().Elem()) obj := reflect.New(v.Type().Elem())
if err := h.Codec.DecodeInto([]byte(node.Value), obj.Interface().(runtime.Object)); err != nil { if err := h.codec.DecodeInto([]byte(node.Value), obj.Interface().(runtime.Object)); err != nil {
return err return err
} }
if h.Versioner != nil { if h.versioner != nil {
// being unable to set the version does not prevent the object from being extracted // being unable to set the version does not prevent the object from being extracted
_ = h.Versioner.UpdateObject(obj.Interface().(runtime.Object), node.Expiration, node.ModifiedIndex) _ = h.versioner.UpdateObject(obj.Interface().(runtime.Object), node.Expiration, node.ModifiedIndex)
} }
v.Set(reflect.Append(v, obj.Elem())) v.Set(reflect.Append(v, obj.Elem()))
if node.ModifiedIndex != 0 { if node.ModifiedIndex != 0 {
@ -293,7 +302,7 @@ func (h *EtcdHelper) decodeNodeList(nodes []*etcd.Node, slicePtr interface{}) er
} }
// Implements StorageInterface. // Implements StorageInterface.
func (h *EtcdHelper) ExtractToList(key string, listObj runtime.Object) error { func (h *etcdHelper) ExtractToList(key string, listObj runtime.Object) error {
trace := util.NewTrace("ExtractToList " + getTypeName(listObj)) trace := util.NewTrace("ExtractToList " + getTypeName(listObj))
defer trace.LogIfLong(time.Second) defer trace.LogIfLong(time.Second)
listPtr, err := runtime.GetItemsPtr(listObj) listPtr, err := runtime.GetItemsPtr(listObj)
@ -313,16 +322,16 @@ func (h *EtcdHelper) ExtractToList(key string, listObj runtime.Object) error {
return err return err
} }
trace.Step("Node list decoded") trace.Step("Node list decoded")
if h.Versioner != nil { if h.versioner != nil {
if err := h.Versioner.UpdateList(listObj, index); err != nil { if err := h.versioner.UpdateList(listObj, index); err != nil {
return err return err
} }
} }
return nil return nil
} }
func (h *EtcdHelper) listEtcdNode(key string) ([]*etcd.Node, uint64, error) { func (h *etcdHelper) listEtcdNode(key string) ([]*etcd.Node, uint64, error) {
result, err := h.Client.Get(key, true, true) result, err := h.client.Get(key, true, true)
if err != nil { if err != nil {
index, ok := etcdErrorIndex(err) index, ok := etcdErrorIndex(err)
if !ok { if !ok {
@ -349,7 +358,7 @@ func SimpleUpdate(fn SimpleEtcdUpdateFunc) StorageUpdateFunc {
} }
// Implements StorageInterface. // 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 StorageUpdateFunc) error {
v, err := conversion.EnforcePtr(ptrToType) v, err := conversion.EnforcePtr(ptrToType)
if err != nil { if err != nil {
// Panic is appropriate, because this is a programming error. // Panic is appropriate, because this is a programming error.
@ -391,7 +400,7 @@ func (h *EtcdHelper) GuaranteedUpdate(key string, ptrToType runtime.Object, igno
ttl = *newTTL ttl = *newTTL
} }
data, err := h.Codec.Encode(ret) data, err := h.codec.Encode(ret)
if err != nil { if err != nil {
return err return err
} }
@ -399,7 +408,7 @@ func (h *EtcdHelper) GuaranteedUpdate(key string, ptrToType runtime.Object, igno
// First time this key has been used, try creating new value. // First time this key has been used, try creating new value.
if index == 0 { if index == 0 {
startTime := time.Now() startTime := time.Now()
response, err := h.Client.Create(key, string(data), ttl) response, err := h.client.Create(key, string(data), ttl)
metrics.RecordEtcdRequestLatency("create", getTypeName(ptrToType), startTime) metrics.RecordEtcdRequestLatency("create", getTypeName(ptrToType), startTime)
if IsEtcdNodeExist(err) { if IsEtcdNodeExist(err) {
continue continue
@ -414,7 +423,7 @@ func (h *EtcdHelper) GuaranteedUpdate(key string, ptrToType runtime.Object, igno
startTime := time.Now() startTime := time.Now()
// Swap origBody with data, if origBody is the latest etcd data. // Swap origBody with data, if origBody is the latest etcd data.
response, err := h.Client.CompareAndSwap(key, string(data), ttl, origBody, index) response, err := h.client.CompareAndSwap(key, string(data), ttl, origBody, index)
metrics.RecordEtcdRequestLatency("compareAndSwap", getTypeName(ptrToType), startTime) metrics.RecordEtcdRequestLatency("compareAndSwap", getTypeName(ptrToType), startTime)
if IsEtcdTestFailed(err) { if IsEtcdTestFailed(err) {
// Try again. // Try again.
@ -425,11 +434,11 @@ func (h *EtcdHelper) GuaranteedUpdate(key string, ptrToType runtime.Object, igno
} }
} }
func (h *EtcdHelper) prefixEtcdKey(key string) string { func (h *etcdHelper) prefixEtcdKey(key string) string {
if strings.HasPrefix(key, path.Join("/", h.PathPrefix)) { if strings.HasPrefix(key, path.Join("/", h.pathPrefix)) {
return key return key
} }
return path.Join("/", h.PathPrefix, key) return path.Join("/", h.pathPrefix, key)
} }
// etcdCache defines interface used for caching objects stored in etcd. Objects are keyed by // etcdCache defines interface used for caching objects stored in etcd. Objects are keyed by
@ -446,7 +455,7 @@ func getTypeName(obj interface{}) string {
return reflect.TypeOf(obj).String() return reflect.TypeOf(obj).String()
} }
func (h *EtcdHelper) getFromCache(index uint64) (runtime.Object, bool) { func (h *etcdHelper) getFromCache(index uint64) (runtime.Object, bool) {
startTime := time.Now() startTime := time.Now()
defer func() { defer func() {
metrics.ObserveGetCache(startTime) metrics.ObserveGetCache(startTime)
@ -455,7 +464,7 @@ func (h *EtcdHelper) getFromCache(index uint64) (runtime.Object, bool) {
if found { if found {
// We should not return the object itself to avoid poluting the cache if someone // We should not return the object itself to avoid poluting the cache if someone
// modifies returned values. // modifies returned values.
objCopy, err := h.Copier.Copy(obj.(runtime.Object)) objCopy, err := h.copier.Copy(obj.(runtime.Object))
if err != nil { if err != nil {
glog.Errorf("Error during DeepCopy of cached object: %q", err) glog.Errorf("Error during DeepCopy of cached object: %q", err)
return nil, false return nil, false
@ -467,12 +476,12 @@ func (h *EtcdHelper) getFromCache(index uint64) (runtime.Object, bool) {
return nil, false return nil, false
} }
func (h *EtcdHelper) addToCache(index uint64, obj runtime.Object) { func (h *etcdHelper) addToCache(index uint64, obj runtime.Object) {
startTime := time.Now() startTime := time.Now()
defer func() { defer func() {
metrics.ObserveAddCache(startTime) metrics.ObserveAddCache(startTime)
}() }()
objCopy, err := h.Copier.Copy(obj) objCopy, err := h.copier.Copy(obj)
if err != nil { if err != nil {
glog.Errorf("Error during DeepCopy of cached object: %q", err) glog.Errorf("Error during DeepCopy of cached object: %q", err)
return return

View File

@ -65,6 +65,10 @@ func init() {
) )
} }
func newEtcdHelper(client EtcdClient, codec runtime.Codec, prefix string) etcdHelper {
return *NewEtcdStorage(client, codec, prefix).(*etcdHelper)
}
func TestIsEtcdNotFound(t *testing.T) { func TestIsEtcdNotFound(t *testing.T) {
try := func(err error, isNotFound bool) { try := func(err error, isNotFound bool) {
if IsEtcdNotFound(err) != isNotFound { if IsEtcdNotFound(err) != isNotFound {
@ -87,7 +91,7 @@ func getEncodedPod(name string) string {
func TestExtractToList(t *testing.T) { func TestExtractToList(t *testing.T) {
fakeClient := NewFakeEtcdClient(t) fakeClient := NewFakeEtcdClient(t)
helper := NewEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix()) helper := newEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix())
key := etcdtest.AddPrefix("/some/key") key := etcdtest.AddPrefix("/some/key")
fakeClient.Data[key] = EtcdResponseWithError{ fakeClient.Data[key] = EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
@ -157,7 +161,7 @@ func TestExtractToList(t *testing.T) {
// TestExtractToListAcrossDirectories ensures that the client excludes directories and flattens tree-response - simulates cross-namespace query // TestExtractToListAcrossDirectories ensures that the client excludes directories and flattens tree-response - simulates cross-namespace query
func TestExtractToListAcrossDirectories(t *testing.T) { func TestExtractToListAcrossDirectories(t *testing.T) {
fakeClient := NewFakeEtcdClient(t) fakeClient := NewFakeEtcdClient(t)
helper := NewEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix()) helper := newEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix())
key := etcdtest.AddPrefix("/some/key") key := etcdtest.AddPrefix("/some/key")
fakeClient.Data[key] = EtcdResponseWithError{ fakeClient.Data[key] = EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
@ -240,7 +244,7 @@ func TestExtractToListAcrossDirectories(t *testing.T) {
func TestExtractToListExcludesDirectories(t *testing.T) { func TestExtractToListExcludesDirectories(t *testing.T) {
fakeClient := NewFakeEtcdClient(t) fakeClient := NewFakeEtcdClient(t)
helper := NewEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix()) helper := newEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix())
key := etcdtest.AddPrefix("/some/key") key := etcdtest.AddPrefix("/some/key")
fakeClient.Data[key] = EtcdResponseWithError{ fakeClient.Data[key] = EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
@ -311,7 +315,7 @@ func TestExtractToListExcludesDirectories(t *testing.T) {
func TestExtractObj(t *testing.T) { func TestExtractObj(t *testing.T) {
fakeClient := NewFakeEtcdClient(t) fakeClient := NewFakeEtcdClient(t)
helper := NewEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix()) helper := newEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix())
key := etcdtest.AddPrefix("/some/key") key := etcdtest.AddPrefix("/some/key")
expect := api.Pod{ expect := api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo"}, ObjectMeta: api.ObjectMeta{Name: "foo"},
@ -333,7 +337,7 @@ func TestExtractObj(t *testing.T) {
func TestExtractObjNotFoundErr(t *testing.T) { func TestExtractObjNotFoundErr(t *testing.T) {
fakeClient := NewFakeEtcdClient(t) fakeClient := NewFakeEtcdClient(t)
helper := NewEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix()) helper := newEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix())
key1 := etcdtest.AddPrefix("/some/key") key1 := etcdtest.AddPrefix("/some/key")
fakeClient.Data[key1] = EtcdResponseWithError{ fakeClient.Data[key1] = EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
@ -377,7 +381,7 @@ func TestExtractObjNotFoundErr(t *testing.T) {
func TestCreateObj(t *testing.T) { func TestCreateObj(t *testing.T) {
obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}} obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}
fakeClient := NewFakeEtcdClient(t) fakeClient := NewFakeEtcdClient(t)
helper := NewEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix()) helper := newEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix())
returnedObj := &api.Pod{} returnedObj := &api.Pod{}
err := helper.CreateObj("/some/key", obj, returnedObj, 5) err := helper.CreateObj("/some/key", obj, returnedObj, 5)
if err != nil { if err != nil {
@ -403,7 +407,7 @@ func TestCreateObj(t *testing.T) {
func TestCreateObjNilOutParam(t *testing.T) { func TestCreateObjNilOutParam(t *testing.T) {
obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}} obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}
fakeClient := NewFakeEtcdClient(t) fakeClient := NewFakeEtcdClient(t)
helper := NewEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix()) helper := newEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix())
err := helper.CreateObj("/some/key", obj, nil, 5) err := helper.CreateObj("/some/key", obj, nil, 5)
if err != nil { if err != nil {
t.Errorf("Unexpected error %#v", err) t.Errorf("Unexpected error %#v", err)
@ -413,7 +417,7 @@ func TestCreateObjNilOutParam(t *testing.T) {
func TestSetObj(t *testing.T) { func TestSetObj(t *testing.T) {
obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}} obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}
fakeClient := NewFakeEtcdClient(t) fakeClient := NewFakeEtcdClient(t)
helper := NewEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix()) helper := newEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix())
returnedObj := &api.Pod{} returnedObj := &api.Pod{}
err := helper.SetObj("/some/key", obj, returnedObj, 5) err := helper.SetObj("/some/key", obj, returnedObj, 5)
if err != nil { if err != nil {
@ -441,7 +445,7 @@ func TestSetObjFailCAS(t *testing.T) {
obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}} obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}}
fakeClient := NewFakeEtcdClient(t) fakeClient := NewFakeEtcdClient(t)
fakeClient.CasErr = fakeClient.NewError(123) fakeClient.CasErr = fakeClient.NewError(123)
helper := NewEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix()) helper := newEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix())
err := helper.SetObj("/some/key", obj, nil, 5) err := helper.SetObj("/some/key", obj, nil, 5)
if err == nil { if err == nil {
t.Errorf("Expecting error.") t.Errorf("Expecting error.")
@ -452,7 +456,7 @@ func TestSetObjWithVersion(t *testing.T) {
obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}} obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}}
fakeClient := NewFakeEtcdClient(t) fakeClient := NewFakeEtcdClient(t)
fakeClient.TestIndex = true fakeClient.TestIndex = true
helper := NewEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix()) helper := newEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix())
key := etcdtest.AddPrefix("/some/key") key := etcdtest.AddPrefix("/some/key")
fakeClient.Data[key] = EtcdResponseWithError{ fakeClient.Data[key] = EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
@ -488,8 +492,8 @@ func TestSetObjWithVersion(t *testing.T) {
func TestSetObjWithoutResourceVersioner(t *testing.T) { func TestSetObjWithoutResourceVersioner(t *testing.T) {
obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}} obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}
fakeClient := NewFakeEtcdClient(t) fakeClient := NewFakeEtcdClient(t)
helper := NewEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix()) helper := newEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix())
helper.Versioner = nil helper.versioner = nil
returnedObj := &api.Pod{} returnedObj := &api.Pod{}
err := helper.SetObj("/some/key", obj, returnedObj, 3) err := helper.SetObj("/some/key", obj, returnedObj, 3)
key := etcdtest.AddPrefix("/some/key") key := etcdtest.AddPrefix("/some/key")
@ -516,8 +520,8 @@ func TestSetObjWithoutResourceVersioner(t *testing.T) {
func TestSetObjNilOutParam(t *testing.T) { func TestSetObjNilOutParam(t *testing.T) {
obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}} obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}
fakeClient := NewFakeEtcdClient(t) fakeClient := NewFakeEtcdClient(t)
helper := NewEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix()) helper := newEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix())
helper.Versioner = nil helper.versioner = nil
err := helper.SetObj("/some/key", obj, nil, 3) err := helper.SetObj("/some/key", obj, nil, 3)
if err != nil { if err != nil {
t.Errorf("Unexpected error %#v", err) t.Errorf("Unexpected error %#v", err)
@ -527,7 +531,7 @@ func TestSetObjNilOutParam(t *testing.T) {
func TestGuaranteedUpdate(t *testing.T) { func TestGuaranteedUpdate(t *testing.T) {
fakeClient := NewFakeEtcdClient(t) fakeClient := NewFakeEtcdClient(t)
fakeClient.TestIndex = true fakeClient.TestIndex = true
helper := NewEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) helper := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix())
key := etcdtest.AddPrefix("/some/key") key := etcdtest.AddPrefix("/some/key")
// Create a new node. // Create a new node.
@ -582,7 +586,7 @@ func TestGuaranteedUpdate(t *testing.T) {
func TestGuaranteedUpdateTTL(t *testing.T) { func TestGuaranteedUpdateTTL(t *testing.T) {
fakeClient := NewFakeEtcdClient(t) fakeClient := NewFakeEtcdClient(t)
fakeClient.TestIndex = true fakeClient.TestIndex = true
helper := NewEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) helper := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix())
key := etcdtest.AddPrefix("/some/key") key := etcdtest.AddPrefix("/some/key")
// Create a new node. // Create a new node.
@ -683,7 +687,7 @@ func TestGuaranteedUpdateTTL(t *testing.T) {
func TestGuaranteedUpdateNoChange(t *testing.T) { func TestGuaranteedUpdateNoChange(t *testing.T) {
fakeClient := NewFakeEtcdClient(t) fakeClient := NewFakeEtcdClient(t)
fakeClient.TestIndex = true fakeClient.TestIndex = true
helper := NewEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) helper := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix())
key := etcdtest.AddPrefix("/some/key") key := etcdtest.AddPrefix("/some/key")
// Create a new node. // Create a new node.
@ -715,7 +719,7 @@ func TestGuaranteedUpdateNoChange(t *testing.T) {
func TestGuaranteedUpdateKeyNotFound(t *testing.T) { func TestGuaranteedUpdateKeyNotFound(t *testing.T) {
fakeClient := NewFakeEtcdClient(t) fakeClient := NewFakeEtcdClient(t)
fakeClient.TestIndex = true fakeClient.TestIndex = true
helper := NewEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) helper := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix())
key := etcdtest.AddPrefix("/some/key") key := etcdtest.AddPrefix("/some/key")
// Create a new node. // Create a new node.
@ -742,7 +746,7 @@ func TestGuaranteedUpdateKeyNotFound(t *testing.T) {
func TestGuaranteedUpdate_CreateCollision(t *testing.T) { func TestGuaranteedUpdate_CreateCollision(t *testing.T) {
fakeClient := NewFakeEtcdClient(t) fakeClient := NewFakeEtcdClient(t)
fakeClient.TestIndex = true fakeClient.TestIndex = true
helper := NewEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) helper := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix())
key := etcdtest.AddPrefix("/some/key") key := etcdtest.AddPrefix("/some/key")
fakeClient.ExpectNotFoundGet(key) fakeClient.ExpectNotFoundGet(key)
@ -840,7 +844,7 @@ func TestGetEtcdVersion_NotListening(t *testing.T) {
func TestPrefixEtcdKey(t *testing.T) { func TestPrefixEtcdKey(t *testing.T) {
fakeClient := NewFakeEtcdClient(t) fakeClient := NewFakeEtcdClient(t)
prefix := path.Join("/", etcdtest.PathPrefix()) prefix := path.Join("/", etcdtest.PathPrefix())
helper := NewEtcdHelper(fakeClient, testapi.Codec(), prefix) helper := newEtcdHelper(fakeClient, testapi.Codec(), prefix)
baseKey := "/some/key" baseKey := "/some/key"

View File

@ -70,46 +70,23 @@ func ParseWatchResourceVersion(resourceVersion, kind string) (uint64, error) {
// API objects, and any items passing 'filter' are sent down the returned // API objects, and any items passing 'filter' are sent down the returned
// watch.Interface. resourceVersion may be used to specify what version to begin // watch.Interface. resourceVersion may be used to specify what version to begin
// watching (e.g., for reconnecting without missing any updates). // watching (e.g., for reconnecting without missing any updates).
func (h *EtcdHelper) WatchList(key string, resourceVersion uint64, filter FilterFunc) (watch.Interface, error) { func (h *etcdHelper) WatchList(key string, resourceVersion uint64, filter FilterFunc) (watch.Interface, error) {
key = h.prefixEtcdKey(key) key = h.prefixEtcdKey(key)
w := newEtcdWatcher(true, exceptKey(key), filter, h.Codec, h.Versioner, nil, h) w := newEtcdWatcher(true, exceptKey(key), filter, h.codec, h.versioner, nil, h)
go w.etcdWatch(h.Client, key, resourceVersion) go w.etcdWatch(h.client, key, resourceVersion)
return w, nil return w, nil
} }
// Watch begins watching the specified key. Events are decoded into // Watch begins watching the specified key. Events are decoded into
// API objects and sent down the returned watch.Interface. // API objects and sent down the returned watch.Interface.
// Errors will be sent down the channel. // Errors will be sent down the channel.
func (h *EtcdHelper) Watch(key string, resourceVersion uint64, filter FilterFunc) (watch.Interface, error) { func (h *etcdHelper) Watch(key string, resourceVersion uint64, filter FilterFunc) (watch.Interface, error) {
key = h.prefixEtcdKey(key) key = h.prefixEtcdKey(key)
w := newEtcdWatcher(false, nil, filter, h.Codec, h.Versioner, nil, h) w := newEtcdWatcher(false, nil, filter, h.codec, h.versioner, nil, h)
go w.etcdWatch(h.Client, key, resourceVersion) go w.etcdWatch(h.client, key, resourceVersion)
return w, nil return w, nil
} }
// WatchAndTransform begins watching the specified key. Events are decoded into
// API objects and sent down the returned watch.Interface. If the transform
// function is provided, the value decoded from etcd will be passed to the function
// prior to being returned.
//
// The transform function can be used to populate data not available to etcd, or to
// change or wrap the serialized etcd object.
//
// startTime := time.Now()
// helper.WatchAndTransform(key, version, func(input runtime.Object) (runtime.Object, error) {
// value := input.(TimeAwareValue)
// value.Since = startTime
// return value, nil
// })
//
// Errors will be sent down the channel.
/*func (h *EtcdHelper) WatchAndTransform(key string, resourceVersion uint64, transform TransformFunc) watch.Interface {
key = h.prefixEtcdKey(key)
w := newEtcdWatcher(false, nil, Everything, h.Codec, h.Versioner, transform, h)
go w.etcdWatch(h.Client, key, resourceVersion)
return w
}*/
// TransformFunc attempts to convert an object to another object for use with a watcher. // TransformFunc attempts to convert an object to another object for use with a watcher.
type TransformFunc func(runtime.Object) (runtime.Object, error) type TransformFunc func(runtime.Object) (runtime.Object, error)
@ -126,7 +103,7 @@ func exceptKey(except string) includeFunc {
// etcdWatcher converts a native etcd watch to a watch.Interface. // etcdWatcher converts a native etcd watch to a watch.Interface.
type etcdWatcher struct { type etcdWatcher struct {
encoding runtime.Codec encoding runtime.Codec
versioner EtcdVersioner versioner StorageVersioner
transform TransformFunc transform TransformFunc
list bool // If we're doing a recursive watch, should be true. list bool // If we're doing a recursive watch, should be true.
@ -154,7 +131,7 @@ const watchWaitDuration = 100 * time.Millisecond
// newEtcdWatcher returns a new etcdWatcher; if list is true, watch sub-nodes. If you provide a transform // 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. // 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 EtcdVersioner, transform TransformFunc, cache etcdCache) *etcdWatcher { func newEtcdWatcher(list bool, include includeFunc, filter FilterFunc, encoding runtime.Codec, versioner StorageVersioner, transform TransformFunc, cache etcdCache) *etcdWatcher {
w := &etcdWatcher{ w := &etcdWatcher{
encoding: encoding, encoding: encoding,
versioner: versioner, versioner: versioner,

View File

@ -218,7 +218,7 @@ func TestWatchEtcdError(t *testing.T) {
fakeClient := NewFakeEtcdClient(t) fakeClient := NewFakeEtcdClient(t)
fakeClient.expectNotFoundGetSet["/some/key"] = struct{}{} fakeClient.expectNotFoundGetSet["/some/key"] = struct{}{}
fakeClient.WatchImmediateError = fmt.Errorf("immediate error") fakeClient.WatchImmediateError = fmt.Errorf("immediate error")
h := NewEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix())
watching, err := h.Watch("/some/key", 4, Everything) watching, err := h.Watch("/some/key", 4, Everything)
if err != nil { if err != nil {
@ -248,7 +248,7 @@ func TestWatch(t *testing.T) {
key := "/some/key" key := "/some/key"
prefixedKey := etcdtest.AddPrefix(key) prefixedKey := etcdtest.AddPrefix(key)
fakeClient.expectNotFoundGetSet[prefixedKey] = struct{}{} fakeClient.expectNotFoundGetSet[prefixedKey] = struct{}{}
h := NewEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix())
watching, err := h.Watch(key, 0, Everything) watching, err := h.Watch(key, 0, Everything)
if err != nil { if err != nil {
@ -424,7 +424,7 @@ func TestWatchEtcdState(t *testing.T) {
fakeClient.Data[key] = value fakeClient.Data[key] = value
} }
h := NewEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix())
watching, err := h.Watch(baseKey, testCase.From, Everything) watching, err := h.Watch(baseKey, testCase.From, Everything)
if err != nil { if err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
@ -497,7 +497,7 @@ func TestWatchFromZeroIndex(t *testing.T) {
key := "/some/key" key := "/some/key"
prefixedKey := etcdtest.AddPrefix(key) prefixedKey := etcdtest.AddPrefix(key)
fakeClient.Data[prefixedKey] = testCase.Response fakeClient.Data[prefixedKey] = testCase.Response
h := NewEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix())
watching, err := h.Watch(key, 0, Everything) watching, err := h.Watch(key, 0, Everything)
if err != nil { if err != nil {
@ -558,7 +558,7 @@ func TestWatchListFromZeroIndex(t *testing.T) {
EtcdIndex: 3, EtcdIndex: 3,
}, },
} }
h := NewEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix())
watching, err := h.WatchList(key, 0, Everything) watching, err := h.WatchList(key, 0, Everything)
if err != nil { if err != nil {
@ -598,7 +598,7 @@ func TestWatchListIgnoresRootKey(t *testing.T) {
prefixedKey := etcdtest.AddPrefix(key) prefixedKey := etcdtest.AddPrefix(key)
fakeClient := NewFakeEtcdClient(t) fakeClient := NewFakeEtcdClient(t)
h := NewEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix())
watching, err := h.WatchList(key, 1, Everything) watching, err := h.WatchList(key, 1, Everything)
if err != nil { if err != nil {
@ -651,7 +651,7 @@ func TestWatchFromNotFound(t *testing.T) {
ErrorCode: 100, ErrorCode: 100,
}, },
} }
h := NewEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix())
watching, err := h.Watch(key, 0, Everything) watching, err := h.Watch(key, 0, Everything)
if err != nil { if err != nil {
@ -678,7 +678,7 @@ func TestWatchFromOtherError(t *testing.T) {
ErrorCode: 101, ErrorCode: 101,
}, },
} }
h := NewEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix())
watching, err := h.Watch(key, 0, Everything) watching, err := h.Watch(key, 0, Everything)
if err != nil { if err != nil {
@ -710,7 +710,7 @@ func TestWatchFromOtherError(t *testing.T) {
func TestWatchPurposefulShutdown(t *testing.T) { func TestWatchPurposefulShutdown(t *testing.T) {
fakeClient := NewFakeEtcdClient(t) fakeClient := NewFakeEtcdClient(t)
h := NewEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix())
key := "/some/key" key := "/some/key"
prefixedKey := etcdtest.AddPrefix(key) prefixedKey := etcdtest.AddPrefix(key)
fakeClient.expectNotFoundGetSet[prefixedKey] = struct{}{} fakeClient.expectNotFoundGetSet[prefixedKey] = struct{}{}

View File

@ -29,7 +29,7 @@ import (
// for objects that have an embedded ObjectMeta or ListMeta field. // for objects that have an embedded ObjectMeta or ListMeta field.
type APIObjectVersioner struct{} type APIObjectVersioner struct{}
// UpdateObject implements EtcdVersioner // UpdateObject implements StorageVersioner
func (a APIObjectVersioner) UpdateObject(obj runtime.Object, expiration *time.Time, resourceVersion uint64) error { func (a APIObjectVersioner) UpdateObject(obj runtime.Object, expiration *time.Time, resourceVersion uint64) error {
objectMeta, err := api.ObjectMetaFor(obj) objectMeta, err := api.ObjectMetaFor(obj)
if err != nil { if err != nil {
@ -46,7 +46,7 @@ func (a APIObjectVersioner) UpdateObject(obj runtime.Object, expiration *time.Ti
return nil return nil
} }
// UpdateList implements EtcdVersioner // UpdateList implements StorageVersioner
func (a APIObjectVersioner) UpdateList(obj runtime.Object, resourceVersion uint64) error { func (a APIObjectVersioner) UpdateList(obj runtime.Object, resourceVersion uint64) error {
listMeta, err := api.ListMetaFor(obj) listMeta, err := api.ListMetaFor(obj)
if err != nil || listMeta == nil { if err != nil || listMeta == nil {
@ -60,7 +60,7 @@ func (a APIObjectVersioner) UpdateList(obj runtime.Object, resourceVersion uint6
return nil return nil
} }
// ObjectResourceVersion implements EtcdVersioner // ObjectResourceVersion implements StorageVersioner
func (a APIObjectVersioner) ObjectResourceVersion(obj runtime.Object) (uint64, error) { func (a APIObjectVersioner) ObjectResourceVersion(obj runtime.Object) (uint64, error) {
meta, err := api.ObjectMetaFor(obj) meta, err := api.ObjectMetaFor(obj)
if err != nil { if err != nil {
@ -73,5 +73,5 @@ func (a APIObjectVersioner) ObjectResourceVersion(obj runtime.Object) (uint64, e
return strconv.ParseUint(version, 10, 64) return strconv.ParseUint(version, 10, 64)
} }
// APIObjectVersioner implements EtcdVersioner // APIObjectVersioner implements StorageVersioner
var _ EtcdVersioner = APIObjectVersioner{} var _ StorageVersioner = APIObjectVersioner{}

View File

@ -52,9 +52,9 @@ type EtcdClient interface {
Watch(prefix string, waitIndex uint64, recursive bool, receiver chan *etcd.Response, stop chan bool) (*etcd.Response, error) Watch(prefix string, waitIndex uint64, recursive bool, receiver chan *etcd.Response, stop chan bool) (*etcd.Response, error)
} }
// EtcdVersioner abstracts setting and retrieving fields from the etcd response onto the object // StorageVersioner abstracts setting and retrieving metadata fields from the etcd response onto the object
// or list. // or list.
type EtcdVersioner interface { type StorageVersioner interface {
// UpdateObject sets etcd storage metadata into an API object. Returns an error if the object // 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 // cannot be updated correctly. May return nil if the requested object does not need metadata
// from etcd. // from etcd.
@ -91,6 +91,14 @@ type StorageUpdateFunc func(input runtime.Object, res ResponseMeta) (output runt
// StorageInterface offers a common interface for object marshaling/unmarshling operations and // StorageInterface offers a common interface for object marshaling/unmarshling operations and
// hids all the storage-related operations behind it. // hids all the storage-related operations behind it.
type StorageInterface interface { 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
// CreateObj adds a new object at a key unless it already exists. 'ttl' is time-to-live // CreateObj 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 // 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 to the read value from etcd.

View File

@ -392,7 +392,7 @@ func TestAuthModeAlwaysAllow(t *testing.T) {
framework.DeleteAllEtcdKeys() framework.DeleteAllEtcdKeys()
// Set up a master // Set up a master
helper, err := framework.NewHelper() etcdStorage, err := framework.NewEtcdStorage()
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
@ -403,7 +403,7 @@ func TestAuthModeAlwaysAllow(t *testing.T) {
defer s.Close() defer s.Close()
m = master.New(&master.Config{ m = master.New(&master.Config{
EtcdHelper: helper, DatabaseStorage: etcdStorage,
KubeletClient: client.FakeKubeletClient{}, KubeletClient: client.FakeKubeletClient{},
EnableCoreControllers: true, EnableCoreControllers: true,
EnableLogsSupport: false, EnableLogsSupport: false,
@ -507,7 +507,7 @@ func TestAuthModeAlwaysDeny(t *testing.T) {
framework.DeleteAllEtcdKeys() framework.DeleteAllEtcdKeys()
// Set up a master // Set up a master
helper, err := framework.NewHelper() etcdStorage, err := framework.NewEtcdStorage()
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
@ -519,7 +519,7 @@ func TestAuthModeAlwaysDeny(t *testing.T) {
defer s.Close() defer s.Close()
m = master.New(&master.Config{ m = master.New(&master.Config{
EtcdHelper: helper, DatabaseStorage: etcdStorage,
KubeletClient: client.FakeKubeletClient{}, KubeletClient: client.FakeKubeletClient{},
EnableCoreControllers: true, EnableCoreControllers: true,
EnableLogsSupport: false, EnableLogsSupport: false,
@ -574,7 +574,7 @@ func TestAliceNotForbiddenOrUnauthorized(t *testing.T) {
// This file has alice and bob in it. // This file has alice and bob in it.
// Set up a master // Set up a master
helper, err := framework.NewHelper() etcdStorage, err := framework.NewEtcdStorage()
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
@ -586,7 +586,7 @@ func TestAliceNotForbiddenOrUnauthorized(t *testing.T) {
defer s.Close() defer s.Close()
m = master.New(&master.Config{ m = master.New(&master.Config{
EtcdHelper: helper, DatabaseStorage: etcdStorage,
KubeletClient: client.FakeKubeletClient{}, KubeletClient: client.FakeKubeletClient{},
EnableCoreControllers: true, EnableCoreControllers: true,
EnableLogsSupport: false, EnableLogsSupport: false,
@ -661,7 +661,7 @@ func TestBobIsForbidden(t *testing.T) {
framework.DeleteAllEtcdKeys() framework.DeleteAllEtcdKeys()
// This file has alice and bob in it. // This file has alice and bob in it.
helper, err := framework.NewHelper() etcdStorage, err := framework.NewEtcdStorage()
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
@ -673,7 +673,7 @@ func TestBobIsForbidden(t *testing.T) {
defer s.Close() defer s.Close()
m = master.New(&master.Config{ m = master.New(&master.Config{
EtcdHelper: helper, DatabaseStorage: etcdStorage,
KubeletClient: client.FakeKubeletClient{}, KubeletClient: client.FakeKubeletClient{},
EnableCoreControllers: true, EnableCoreControllers: true,
EnableLogsSupport: false, EnableLogsSupport: false,
@ -722,7 +722,7 @@ func TestUnknownUserIsUnauthorized(t *testing.T) {
// This file has alice and bob in it. // This file has alice and bob in it.
// Set up a master // Set up a master
helper, err := framework.NewHelper() etcdStorage, err := framework.NewEtcdStorage()
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
@ -734,7 +734,7 @@ func TestUnknownUserIsUnauthorized(t *testing.T) {
defer s.Close() defer s.Close()
m = master.New(&master.Config{ m = master.New(&master.Config{
EtcdHelper: helper, DatabaseStorage: etcdStorage,
KubeletClient: client.FakeKubeletClient{}, KubeletClient: client.FakeKubeletClient{},
EnableCoreControllers: true, EnableCoreControllers: true,
EnableLogsSupport: false, EnableLogsSupport: false,
@ -799,7 +799,7 @@ func TestNamespaceAuthorization(t *testing.T) {
framework.DeleteAllEtcdKeys() framework.DeleteAllEtcdKeys()
// This file has alice and bob in it. // This file has alice and bob in it.
helper, err := framework.NewHelper() etcdStorage, err := framework.NewEtcdStorage()
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
@ -814,7 +814,7 @@ func TestNamespaceAuthorization(t *testing.T) {
defer s.Close() defer s.Close()
m = master.New(&master.Config{ m = master.New(&master.Config{
EtcdHelper: helper, DatabaseStorage: etcdStorage,
KubeletClient: client.FakeKubeletClient{}, KubeletClient: client.FakeKubeletClient{},
EnableCoreControllers: true, EnableCoreControllers: true,
EnableLogsSupport: false, EnableLogsSupport: false,
@ -914,7 +914,7 @@ func TestKindAuthorization(t *testing.T) {
// This file has alice and bob in it. // This file has alice and bob in it.
// Set up a master // Set up a master
helper, err := framework.NewHelper() etcdStorage, err := framework.NewEtcdStorage()
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
@ -929,7 +929,7 @@ func TestKindAuthorization(t *testing.T) {
defer s.Close() defer s.Close()
m = master.New(&master.Config{ m = master.New(&master.Config{
EtcdHelper: helper, DatabaseStorage: etcdStorage,
KubeletClient: client.FakeKubeletClient{}, KubeletClient: client.FakeKubeletClient{},
EnableCoreControllers: true, EnableCoreControllers: true,
EnableLogsSupport: false, EnableLogsSupport: false,
@ -1017,7 +1017,7 @@ func TestReadOnlyAuthorization(t *testing.T) {
// This file has alice and bob in it. // This file has alice and bob in it.
// Set up a master // Set up a master
helper, err := framework.NewHelper() etcdStorage, err := framework.NewEtcdStorage()
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
@ -1031,7 +1031,7 @@ func TestReadOnlyAuthorization(t *testing.T) {
defer s.Close() defer s.Close()
m = master.New(&master.Config{ m = master.New(&master.Config{
EtcdHelper: helper, DatabaseStorage: etcdStorage,
KubeletClient: client.FakeKubeletClient{}, KubeletClient: client.FakeKubeletClient{},
EnableCoreControllers: true, EnableCoreControllers: true,
EnableLogsSupport: false, EnableLogsSupport: false,

View File

@ -31,66 +31,57 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/test/integration/framework" "github.com/GoogleCloudPlatform/kubernetes/test/integration/framework"
) )
type stringCodec struct{}
type fakeAPIObject string
func (*fakeAPIObject) IsAnAPIObject() {}
func (c stringCodec) Encode(obj runtime.Object) ([]byte, error) {
return []byte(*obj.(*fakeAPIObject)), nil
}
func (c stringCodec) Decode(data []byte) (runtime.Object, error) {
o := fakeAPIObject(data)
return &o, nil
}
func (c stringCodec) DecodeInto(data []byte, obj runtime.Object) error {
o := obj.(*fakeAPIObject)
*o = fakeAPIObject(data)
return nil
}
func TestSetObj(t *testing.T) { func TestSetObj(t *testing.T) {
client := framework.NewEtcdClient() client := framework.NewEtcdClient()
helper := tools.EtcdHelper{Client: client, Codec: stringCodec{}} etcdStorage := tools.NewEtcdStorage(client, testapi.Codec(), "")
framework.WithEtcdKey(func(key string) { framework.WithEtcdKey(func(key string) {
fakeObject := fakeAPIObject("object") testObject := api.ServiceAccount{ObjectMeta: api.ObjectMeta{Name: "foo"}}
if err := helper.SetObj(key, &fakeObject, nil, 0); err != nil { if err := etcdStorage.SetObj(key, &testObject, nil, 0); err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
resp, err := client.Get(key, false, false) resp, err := client.Get(key, false, false)
if err != nil || resp.Node == nil { if err != nil || resp.Node == nil {
t.Fatalf("unexpected error: %v %v", err, resp) t.Fatalf("unexpected error: %v %v", err, resp)
} }
if resp.Node.Value != "object" { decoded, err := testapi.Codec().Decode([]byte(resp.Node.Value))
t.Errorf("unexpected response: %#v", resp.Node) if err != nil {
t.Fatalf("unexpected response: %#v", resp.Node)
}
result := *decoded.(*api.ServiceAccount)
if !api.Semantic.DeepEqual(testObject, result) {
t.Errorf("expected: %#v got: %#v", testObject, result)
} }
}) })
} }
func TestExtractObj(t *testing.T) { func TestExtractObj(t *testing.T) {
client := framework.NewEtcdClient() client := framework.NewEtcdClient()
helper := tools.EtcdHelper{Client: client, Codec: stringCodec{}} etcdStorage := tools.NewEtcdStorage(client, testapi.Codec(), "")
framework.WithEtcdKey(func(key string) { framework.WithEtcdKey(func(key string) {
_, err := client.Set(key, "object", 0) testObject := api.ServiceAccount{ObjectMeta: api.ObjectMeta{Name: "foo"}}
coded, err := testapi.Codec().Encode(&testObject)
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
s := fakeAPIObject("") _, err = client.Set(key, string(coded), 0)
if err := helper.ExtractObj(key, &s, false); err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
if s != "object" { result := api.ServiceAccount{}
t.Errorf("unexpected response: %#v", s) if err := etcdStorage.ExtractObj(key, &result, false); err != nil {
t.Fatalf("unexpected error: %v", err)
}
// Propagate ResourceVersion (it is set automatically).
testObject.ObjectMeta.ResourceVersion = result.ObjectMeta.ResourceVersion
if !api.Semantic.DeepEqual(testObject, result) {
t.Errorf("expected: %#v got: %#v", testObject, result)
} }
}) })
} }
func TestWatch(t *testing.T) { func TestWatch(t *testing.T) {
client := framework.NewEtcdClient() client := framework.NewEtcdClient()
helper := tools.NewEtcdHelper(client, testapi.Codec(), etcdtest.PathPrefix()) etcdStorage := tools.NewEtcdStorage(client, testapi.Codec(), etcdtest.PathPrefix())
framework.WithEtcdKey(func(key string) { framework.WithEtcdKey(func(key string) {
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
resp, err := client.Set(key, runtime.EncodeOrDie(testapi.Codec(), &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}), 0) resp, err := client.Set(key, runtime.EncodeOrDie(testapi.Codec(), &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}), 0)
@ -100,7 +91,7 @@ func TestWatch(t *testing.T) {
expectedVersion := resp.Node.ModifiedIndex expectedVersion := resp.Node.ModifiedIndex
// watch should load the object at the current index // watch should load the object at the current index
w, err := helper.Watch(key, 0, tools.Everything) w, err := etcdStorage.Watch(key, 0, tools.Everything)
if err != nil { if err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }

View File

@ -41,8 +41,8 @@ func NewEtcdClient() *etcd.Client {
return etcd.NewClient([]string{}) return etcd.NewClient([]string{})
} }
func NewHelper() (tools.EtcdHelper, error) { func NewEtcdStorage() (tools.StorageInterface, error) {
return master.NewEtcdHelper(NewEtcdClient(), testapi.Version(), etcdtest.PathPrefix()) return master.NewEtcdStorage(NewEtcdClient(), testapi.Version(), etcdtest.PathPrefix())
} }
func RequireEtcd() { func RequireEtcd() {

View File

@ -61,7 +61,7 @@ const (
type MasterComponents struct { type MasterComponents struct {
// Raw http server in front of the master // Raw http server in front of the master
ApiServer *httptest.Server ApiServer *httptest.Server
// Kubernetes master, contains an embedded etcd helper // Kubernetes master, contains an embedded etcd storage
KubeMaster *master.Master KubeMaster *master.Master
// Restclient used to talk to the kubernetes master // Restclient used to talk to the kubernetes master
RestClient *client.Client RestClient *client.Client
@ -71,8 +71,8 @@ type MasterComponents struct {
rcStopCh chan struct{} rcStopCh chan struct{}
// Used to stop master components individually, and via MasterComponents.Stop // Used to stop master components individually, and via MasterComponents.Stop
once sync.Once once sync.Once
// Kubernetes etcd helper, has embedded etcd client // Kubernetes etcd storage, has embedded etcd client
EtcdHelper *tools.EtcdHelper EtcdStorage tools.StorageInterface
} }
// Config is a struct of configuration directives for NewMasterComponents. // Config is a struct of configuration directives for NewMasterComponents.
@ -91,7 +91,7 @@ type Config struct {
// NewMasterComponents creates, initializes and starts master components based on the given config. // NewMasterComponents creates, initializes and starts master components based on the given config.
func NewMasterComponents(c *Config) *MasterComponents { func NewMasterComponents(c *Config) *MasterComponents {
m, s, h := startMasterOrDie(c.MasterConfig) m, s, e := startMasterOrDie(c.MasterConfig)
// TODO: Allow callers to pipe through a different master url and create a client/start components using it. // TODO: Allow callers to pipe through a different master url and create a client/start components using it.
glog.Infof("Master %+v", s.URL) glog.Infof("Master %+v", s.URL)
if c.DeleteEtcdKeys { if c.DeleteEtcdKeys {
@ -113,27 +113,27 @@ func NewMasterComponents(c *Config) *MasterComponents {
RestClient: restClient, RestClient: restClient,
ControllerManager: controllerManager, ControllerManager: controllerManager,
rcStopCh: rcStopCh, rcStopCh: rcStopCh,
EtcdHelper: h, EtcdStorage: e,
once: once, once: once,
} }
} }
// startMasterOrDie starts a kubernetes master and an httpserver to handle api requests // startMasterOrDie starts a kubernetes master and an httpserver to handle api requests
func startMasterOrDie(masterConfig *master.Config) (*master.Master, *httptest.Server, *tools.EtcdHelper) { func startMasterOrDie(masterConfig *master.Config) (*master.Master, *httptest.Server, tools.StorageInterface) {
var m *master.Master var m *master.Master
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
m.Handler.ServeHTTP(w, req) m.Handler.ServeHTTP(w, req)
})) }))
var helper tools.EtcdHelper var etcdStorage tools.StorageInterface
var err error var err error
if masterConfig == nil { if masterConfig == nil {
helper, err = master.NewEtcdHelper(NewEtcdClient(), "", etcdtest.PathPrefix()) etcdStorage, err = master.NewEtcdStorage(NewEtcdClient(), "", etcdtest.PathPrefix())
if err != nil { if err != nil {
glog.Fatalf("Failed to create etcd helper for master %v", err) glog.Fatalf("Failed to create etcd storage for master %v", err)
} }
masterConfig = &master.Config{ masterConfig = &master.Config{
EtcdHelper: helper, DatabaseStorage: etcdStorage,
KubeletClient: client.FakeKubeletClient{}, KubeletClient: client.FakeKubeletClient{},
EnableLogsSupport: false, EnableLogsSupport: false,
EnableProfiling: true, EnableProfiling: true,
@ -143,10 +143,10 @@ func startMasterOrDie(masterConfig *master.Config) (*master.Master, *httptest.Se
AdmissionControl: admit.NewAlwaysAdmit(), AdmissionControl: admit.NewAlwaysAdmit(),
} }
} else { } else {
helper = masterConfig.EtcdHelper etcdStorage = masterConfig.DatabaseStorage
} }
m = master.New(masterConfig) m = master.New(masterConfig)
return m, s, &helper return m, s, etcdStorage
} }
func (m *MasterComponents) stopRCManager() { func (m *MasterComponents) stopRCManager() {
@ -258,13 +258,13 @@ func StartPods(numPods int, host string, restClient *client.Client) error {
// TODO: Merge this into startMasterOrDie. // TODO: Merge this into startMasterOrDie.
func RunAMaster(t *testing.T) (*master.Master, *httptest.Server) { func RunAMaster(t *testing.T) (*master.Master, *httptest.Server) {
helper, err := master.NewEtcdHelper(NewEtcdClient(), testapi.Version(), etcdtest.PathPrefix()) etcdStorage, err := master.NewEtcdStorage(NewEtcdClient(), testapi.Version(), etcdtest.PathPrefix())
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
m := master.New(&master.Config{ m := master.New(&master.Config{
EtcdHelper: helper, DatabaseStorage: etcdStorage,
KubeletClient: client.FakeKubeletClient{}, KubeletClient: client.FakeKubeletClient{},
EnableLogsSupport: false, EnableLogsSupport: false,
EnableProfiling: true, EnableProfiling: true,

View File

@ -179,7 +179,7 @@ func BenchmarkPodListEtcd(b *testing.B) {
defer func() { defer func() {
glog.V(3).Infof("Worker %d: listing pods took %v", id, time.Since(now)) glog.V(3).Infof("Worker %d: listing pods took %v", id, time.Since(now))
}() }()
if response, err := m.EtcdHelper.Client.Get(key, true, true); err != nil { if response, err := m.EtcdStorage.Client.Get(key, true, true); err != nil {
return err return err
} else if len(response.Node.Nodes) < podsPerNode { } else if len(response.Node.Nodes) < podsPerNode {
glog.Fatalf("List retrieved %d pods, which is less than %d", len(response.Node.Nodes), podsPerNode) glog.Fatalf("List retrieved %d pods, which is less than %d", len(response.Node.Nodes), podsPerNode)

View File

@ -53,9 +53,9 @@ type nodeStateManager struct {
} }
func TestUnschedulableNodes(t *testing.T) { func TestUnschedulableNodes(t *testing.T) {
helper, err := framework.NewHelper() etcdStorage, err := framework.NewEtcdStorage()
if err != nil { if err != nil {
t.Fatalf("Couldn't create etcd helper: %v", err) t.Fatalf("Couldn't create etcd storage: %v", err)
} }
framework.DeleteAllEtcdKeys() framework.DeleteAllEtcdKeys()
@ -66,7 +66,7 @@ func TestUnschedulableNodes(t *testing.T) {
defer s.Close() defer s.Close()
m = master.New(&master.Config{ m = master.New(&master.Config{
EtcdHelper: helper, DatabaseStorage: etcdStorage,
KubeletClient: client.FakeKubeletClient{}, KubeletClient: client.FakeKubeletClient{},
EnableCoreControllers: true, EnableCoreControllers: true,
EnableLogsSupport: false, EnableLogsSupport: false,

View File

@ -47,7 +47,7 @@ func deleteSecretOrErrorf(t *testing.T, c *client.Client, ns, name string) {
// TestSecrets tests apiserver-side behavior of creation of secret objects and their use by pods. // TestSecrets tests apiserver-side behavior of creation of secret objects and their use by pods.
func TestSecrets(t *testing.T) { func TestSecrets(t *testing.T) {
helper, err := framework.NewHelper() etcdStorage, err := framework.NewEtcdStorage()
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
@ -59,7 +59,7 @@ func TestSecrets(t *testing.T) {
defer s.Close() defer s.Close()
m = master.New(&master.Config{ m = master.New(&master.Config{
EtcdHelper: helper, DatabaseStorage: etcdStorage,
KubeletClient: client.FakeKubeletClient{}, KubeletClient: client.FakeKubeletClient{},
EnableCoreControllers: true, EnableCoreControllers: true,
EnableLogsSupport: false, EnableLogsSupport: false,

View File

@ -340,7 +340,7 @@ func startServiceAccountTestServer(t *testing.T) (*client.Client, client.Config,
deleteAllEtcdKeys() deleteAllEtcdKeys()
// Etcd // Etcd
helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version(), etcdtest.PathPrefix()) etcdStorage, err := master.NewEtcdStorage(newEtcdClient(), testapi.Version(), etcdtest.PathPrefix())
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
@ -410,7 +410,7 @@ func startServiceAccountTestServer(t *testing.T) (*client.Client, client.Config,
// Create a master and install handlers into mux. // Create a master and install handlers into mux.
m = master.New(&master.Config{ m = master.New(&master.Config{
EtcdHelper: helper, DatabaseStorage: etcdStorage,
KubeletClient: client.FakeKubeletClient{}, KubeletClient: client.FakeKubeletClient{},
EnableLogsSupport: false, EnableLogsSupport: false,
EnableUISupport: false, EnableUISupport: false,

View File

@ -67,13 +67,13 @@ func deleteAllEtcdKeys() {
} }
func runAMaster(t *testing.T) (*master.Master, *httptest.Server) { func runAMaster(t *testing.T) (*master.Master, *httptest.Server) {
helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version(), etcdtest.PathPrefix()) etcdStorage, err := master.NewEtcdStorage(newEtcdClient(), testapi.Version(), etcdtest.PathPrefix())
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
m := master.New(&master.Config{ m := master.New(&master.Config{
EtcdHelper: helper, DatabaseStorage: etcdStorage,
KubeletClient: client.FakeKubeletClient{}, KubeletClient: client.FakeKubeletClient{},
EnableCoreControllers: true, EnableCoreControllers: true,
EnableLogsSupport: false, EnableLogsSupport: false,