Commit a7623ca6 authored by Karl Beecher's avatar Karl Beecher

Adds ability to define a prefix for etcd paths

The API server can be supplied (via a command line flag) with a custom prefix that is prepended to etcd resources paths. Refs: #3476
parent 2532fe56
...@@ -51,6 +51,7 @@ import ( ...@@ -51,6 +51,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/master" "github.com/GoogleCloudPlatform/kubernetes/pkg/master"
"github.com/GoogleCloudPlatform/kubernetes/pkg/probe" "github.com/GoogleCloudPlatform/kubernetes/pkg/probe"
"github.com/GoogleCloudPlatform/kubernetes/pkg/service" "github.com/GoogleCloudPlatform/kubernetes/pkg/service"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/wait" "github.com/GoogleCloudPlatform/kubernetes/pkg/util/wait"
"github.com/GoogleCloudPlatform/kubernetes/pkg/volume/empty_dir" "github.com/GoogleCloudPlatform/kubernetes/pkg/volume/empty_dir"
...@@ -160,7 +161,7 @@ func startComponents(firstManifestURL, secondManifestURL, apiVersion string) (st ...@@ -160,7 +161,7 @@ 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, "") helper, err := master.NewEtcdHelper(etcdClient, "", etcdtest.PathPrefix())
if err != nil { if err != nil {
glog.Fatalf("Unable to get etcd helper: %v", err) glog.Fatalf("Unable to get etcd helper: %v", err)
} }
......
...@@ -71,6 +71,7 @@ type APIServer struct { ...@@ -71,6 +71,7 @@ type APIServer struct {
AdmissionControlConfigFile string AdmissionControlConfigFile string
EtcdServerList util.StringList EtcdServerList util.StringList
EtcdConfigFile string EtcdConfigFile string
EtcdPathPrefix string
CorsAllowedOriginList util.StringList CorsAllowedOriginList util.StringList
AllowPrivileged bool AllowPrivileged bool
PortalNet util.IPNet // TODO: make this a list PortalNet util.IPNet // TODO: make this a list
...@@ -98,6 +99,7 @@ func NewAPIServer() *APIServer { ...@@ -98,6 +99,7 @@ func NewAPIServer() *APIServer {
EventTTL: 1 * time.Hour, EventTTL: 1 * time.Hour,
AuthorizationMode: "AlwaysAllow", AuthorizationMode: "AlwaysAllow",
AdmissionControl: "AlwaysAdmit", AdmissionControl: "AlwaysAdmit",
EtcdPathPrefix: master.DefaultEtcdPathPrefix,
EnableLogsSupport: true, EnableLogsSupport: true,
MasterServiceNamespace: api.NamespaceDefault, MasterServiceNamespace: api.NamespaceDefault,
ClusterName: "kubernetes", ClusterName: "kubernetes",
...@@ -161,6 +163,7 @@ func (s *APIServer) AddFlags(fs *pflag.FlagSet) { ...@@ -161,6 +163,7 @@ func (s *APIServer) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&s.AdmissionControlConfigFile, "admission_control_config_file", s.AdmissionControlConfigFile, "File with admission control configuration.") fs.StringVar(&s.AdmissionControlConfigFile, "admission_control_config_file", s.AdmissionControlConfigFile, "File with admission control configuration.")
fs.Var(&s.EtcdServerList, "etcd_servers", "List of etcd servers to watch (http://ip:port), comma separated. Mutually exclusive with -etcd_config") fs.Var(&s.EtcdServerList, "etcd_servers", "List of etcd servers to watch (http://ip:port), comma separated. Mutually exclusive with -etcd_config")
fs.StringVar(&s.EtcdConfigFile, "etcd_config", s.EtcdConfigFile, "The config file for the etcd client. Mutually exclusive with -etcd_servers.") fs.StringVar(&s.EtcdConfigFile, "etcd_config", s.EtcdConfigFile, "The config file for the etcd client. Mutually exclusive with -etcd_servers.")
fs.StringVar(&s.EtcdPathPrefix, "etcd_prefix", s.EtcdPathPrefix, "The prefix for all resource paths in etcd.")
fs.Var(&s.CorsAllowedOriginList, "cors_allowed_origins", "List of allowed origins for CORS, comma separated. An allowed origin can be a regular expression to support subdomain matching. If this list is empty CORS will not be enabled.") fs.Var(&s.CorsAllowedOriginList, "cors_allowed_origins", "List of allowed origins for CORS, comma separated. An allowed origin can be a regular expression to support subdomain matching. If this list is empty CORS will not be enabled.")
fs.BoolVar(&s.AllowPrivileged, "allow_privileged", s.AllowPrivileged, "If true, allow privileged containers.") fs.BoolVar(&s.AllowPrivileged, "allow_privileged", s.AllowPrivileged, "If true, allow privileged containers.")
fs.Var(&s.PortalNet, "portal_net", "A CIDR notation IP range from which to assign portal IPs. This must not overlap with any IP ranges assigned to nodes for pods.") fs.Var(&s.PortalNet, "portal_net", "A CIDR notation IP range from which to assign portal IPs. This must not overlap with any IP ranges assigned to nodes for pods.")
...@@ -181,7 +184,7 @@ func (s *APIServer) verifyPortalFlags() { ...@@ -181,7 +184,7 @@ func (s *APIServer) verifyPortalFlags() {
} }
} }
func newEtcd(etcdConfigFile string, etcdServerList util.StringList, storageVersion string) (helper tools.EtcdHelper, err error) { func newEtcd(etcdConfigFile string, etcdServerList util.StringList, storageVersion string, pathPrefix string) (helper tools.EtcdHelper, err error) {
var client tools.EtcdGetSet var client tools.EtcdGetSet
if etcdConfigFile != "" { if etcdConfigFile != "" {
client, err = etcd.NewClientFromFile(etcdConfigFile) client, err = etcd.NewClientFromFile(etcdConfigFile)
...@@ -192,7 +195,7 @@ func newEtcd(etcdConfigFile string, etcdServerList util.StringList, storageVersi ...@@ -192,7 +195,7 @@ func newEtcd(etcdConfigFile string, etcdServerList util.StringList, storageVersi
client = etcd.NewClient(etcdServerList) client = etcd.NewClient(etcdServerList)
} }
return master.NewEtcdHelper(client, storageVersion) return master.NewEtcdHelper(client, storageVersion, pathPrefix)
} }
// Run runs the specified APIServer. This should never exit. // Run runs the specified APIServer. This should never exit.
...@@ -232,7 +235,7 @@ func (s *APIServer) Run(_ []string) error { ...@@ -232,7 +235,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) helper, 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)
} }
......
...@@ -81,7 +81,7 @@ func (h *delegateHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { ...@@ -81,7 +81,7 @@ 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, "") helper, err := master.NewEtcdHelper(etcdClient, "", master.DefaultEtcdPathPrefix)
if err != nil { if err != nil {
glog.Fatalf("Unable to get etcd helper: %v", err) glog.Fatalf("Unable to get etcd helper: %v", err)
} }
......
...@@ -53,6 +53,9 @@ KUBE_RACE=${KUBE_RACE:-} # use KUBE_RACE="-race" to enable race testing ...@@ -53,6 +53,9 @@ KUBE_RACE=${KUBE_RACE:-} # use KUBE_RACE="-race" to enable race testing
KUBE_GOVERALLS_BIN=${KUBE_GOVERALLS_BIN:-} KUBE_GOVERALLS_BIN=${KUBE_GOVERALLS_BIN:-}
# Comma separated list of API Versions that should be tested. # Comma separated list of API Versions that should be tested.
KUBE_TEST_API_VERSIONS=${KUBE_TEST_API_VERSIONS:-"v1beta1,v1beta3"} KUBE_TEST_API_VERSIONS=${KUBE_TEST_API_VERSIONS:-"v1beta1,v1beta3"}
# Prefixes for etcd paths (standard and customized)
ETCD_STANDARD_PREFIX="registry"
ETCD_CUSTOM_PREFIX="kubernetes.io/registry"
kube::test::usage() { kube::test::usage() {
kube::log::usage_from_stdin <<EOF kube::log::usage_from_stdin <<EOF
...@@ -203,10 +206,13 @@ reportCoverageToCoveralls() { ...@@ -203,10 +206,13 @@ reportCoverageToCoveralls() {
# Convert the CSV to an array of API versions to test # Convert the CSV to an array of API versions to test
IFS=',' read -a apiVersions <<< "${KUBE_TEST_API_VERSIONS}" IFS=',' read -a apiVersions <<< "${KUBE_TEST_API_VERSIONS}"
ETCD_PREFIX=${ETCD_STANDARD_PREFIX}
for apiVersion in "${apiVersions[@]}"; do for apiVersion in "${apiVersions[@]}"; do
echo "Running tests for APIVersion: $apiVersion" echo "Running tests for APIVersion: $apiVersion"
KUBE_API_VERSION="${apiVersion}" runTests "$@" KUBE_API_VERSION="${apiVersion}" ETCD_PREFIX=${ETCD_STANDARD_PREFIX} runTests "$@"
done done
echo "Using custom etcd path prefix: ${ETCD_CUSTOM_PREFIX}"
KUBE_API_VERSION="${apiVersions[-1]}" ETCD_PREFIX=${ETCD_CUSTOM_PREFIX} runTests "$@"
# We might run the tests for multiple versions, but we want to report only # We might run the tests for multiple versions, but we want to report only
# one of them to coveralls. Here we report coverage from the last run. # one of them to coveralls. Here we report coverage from the last run.
......
...@@ -271,7 +271,6 @@ func (t *Tester) TestDeleteNoGraceful(createFn func() runtime.Object, wasGracefu ...@@ -271,7 +271,6 @@ func (t *Tester) TestDeleteNoGraceful(createFn func() runtime.Object, wasGracefu
if err != nil { if err != nil {
t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, existing) t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, existing)
} }
ctx := api.WithNamespace(api.NewContext(), objectMeta.Namespace) ctx := api.WithNamespace(api.NewContext(), objectMeta.Namespace)
_, err = t.storage.(rest.GracefulDeleter).Delete(ctx, objectMeta.Name, api.NewDeleteOptions(10)) _, err = t.storage.(rest.GracefulDeleter).Delete(ctx, objectMeta.Name, api.NewDeleteOptions(10))
if err != nil { if err != nil {
......
...@@ -71,6 +71,10 @@ import ( ...@@ -71,6 +71,10 @@ import (
"github.com/golang/glog" "github.com/golang/glog"
) )
const (
DefaultEtcdPathPrefix = "/registry"
)
// 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 EtcdHelper tools.EtcdHelper
...@@ -178,7 +182,7 @@ type Master struct { ...@@ -178,7 +182,7 @@ type Master struct {
// NewEtcdHelper returns an EtcdHelper for the provided arguments or an error if the version // NewEtcdHelper returns an EtcdHelper for the provided arguments or an error if the version
// is incorrect. // is incorrect.
func NewEtcdHelper(client tools.EtcdGetSet, version string) (helper tools.EtcdHelper, err error) { func NewEtcdHelper(client tools.EtcdGetSet, version string, prefix string) (helper tools.EtcdHelper, err error) {
if version == "" { if version == "" {
version = latest.Version version = latest.Version
} }
...@@ -186,7 +190,7 @@ func NewEtcdHelper(client tools.EtcdGetSet, version string) (helper tools.EtcdHe ...@@ -186,7 +190,7 @@ func NewEtcdHelper(client tools.EtcdGetSet, version string) (helper tools.EtcdHe
if err != nil { if err != nil {
return helper, err return helper, err
} }
return tools.NewEtcdHelper(client, versionInterfaces.Codec), nil return tools.NewEtcdHelper(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.
...@@ -363,7 +367,7 @@ func logStackOnRecover(panicReason interface{}, httpWriter http.ResponseWriter) ...@@ -363,7 +367,7 @@ func logStackOnRecover(panicReason interface{}, httpWriter http.ResponseWriter)
func (m *Master) init(c *Config) { func (m *Master) init(c *Config) {
// TODO: make initialization of the helper part of the Master, and allow some storage // TODO: make initialization of the helper part of the Master, and allow some storage
// objects to have a newer storage version than the user's default. // objects to have a newer storage version than the user's default.
newerHelper, err := NewEtcdHelper(c.EtcdHelper.Client, "v1beta3") newerHelper, err := NewEtcdHelper(c.EtcdHelper.Client, "v1beta3", DefaultEtcdPathPrefix)
if err != nil { if err != nil {
glog.Fatalf("Unable to setup storage for v1beta3: %v", err) glog.Fatalf("Unable to setup storage for v1beta3: %v", err)
} }
......
...@@ -23,6 +23,7 @@ import ( ...@@ -23,6 +23,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
) )
func TestGetServersToValidate(t *testing.T) { func TestGetServersToValidate(t *testing.T) {
...@@ -30,7 +31,7 @@ func TestGetServersToValidate(t *testing.T) { ...@@ -30,7 +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.EtcdHelper{fakeClient, latest.Codec, nil} config.EtcdHelper = tools.EtcdHelper{fakeClient, latest.Codec, nil, etcdtest.PathPrefix()}
master.nodeRegistry = registrytest.NewMinionRegistry([]string{"node1", "node2"}, api.NodeResources{}) master.nodeRegistry = registrytest.NewMinionRegistry([]string{"node1", "node2"}, api.NodeResources{})
......
...@@ -34,7 +34,7 @@ type REST struct { ...@@ -34,7 +34,7 @@ type REST struct {
// controllerPrefix is the location for controllers in etcd, only exposed // controllerPrefix is the location for controllers in etcd, only exposed
// for testing // for testing
var controllerPrefix = "/registry/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(h tools.EtcdHelper) *REST {
......
...@@ -31,6 +31,7 @@ import ( ...@@ -31,6 +31,7 @@ import (
etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd" etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/coreos/go-etcd/etcd" "github.com/coreos/go-etcd/etcd"
) )
...@@ -39,11 +40,16 @@ const ( ...@@ -39,11 +40,16 @@ const (
FAIL FAIL
) )
// newStorage creates a REST storage backed by etcd helpers func newHelper(t *testing.T) (*tools.FakeEtcdClient, tools.EtcdHelper) {
func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true fakeEtcdClient.TestIndex = true
h := tools.NewEtcdHelper(fakeEtcdClient, latest.Codec) helper := tools.NewEtcdHelper(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
return fakeEtcdClient, helper
}
// newStorage creates a REST storage backed by etcd helpers
func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
fakeEtcdClient, h := newHelper(t)
storage := NewREST(h) storage := NewREST(h)
return storage, fakeEtcdClient return storage, fakeEtcdClient
} }
...@@ -107,6 +113,7 @@ func TestEtcdCreateController(t *testing.T) { ...@@ -107,6 +113,7 @@ func TestEtcdCreateController(t *testing.T) {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
key, _ := makeControllerKey(ctx, validController.Name) key, _ := makeControllerKey(ctx, validController.Name)
key = etcdtest.AddPrefix(key)
resp, err := fakeClient.Get(key, false, false) resp, err := fakeClient.Get(key, false, false)
if err != nil { if err != nil {
t.Fatalf("Unexpected error %v", err) t.Fatalf("Unexpected error %v", err)
...@@ -126,6 +133,7 @@ func TestEtcdCreateControllerAlreadyExisting(t *testing.T) { ...@@ -126,6 +133,7 @@ func TestEtcdCreateControllerAlreadyExisting(t *testing.T) {
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
key, _ := makeControllerKey(ctx, validController.Name) key, _ := makeControllerKey(ctx, validController.Name)
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &validController), 0) fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &validController), 0)
_, err := storage.Create(ctx, &validController) _, err := storage.Create(ctx, &validController)
...@@ -199,6 +207,7 @@ func TestEtcdGetController(t *testing.T) { ...@@ -199,6 +207,7 @@ func TestEtcdGetController(t *testing.T) {
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
key, _ := makeControllerKey(ctx, validController.Name) key, _ := makeControllerKey(ctx, validController.Name)
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &validController), 0) fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &validController), 0)
ctrl, err := storage.Get(ctx, validController.Name) ctrl, err := storage.Get(ctx, validController.Name)
if err != nil { if err != nil {
...@@ -282,6 +291,9 @@ func TestEtcdGetControllerDifferentNamespace(t *testing.T) { ...@@ -282,6 +291,9 @@ func TestEtcdGetControllerDifferentNamespace(t *testing.T) {
key1, _ := makeControllerKey(ctx1, validController.Name) key1, _ := makeControllerKey(ctx1, validController.Name)
key2, _ := makeControllerKey(ctx2, validController.Name) key2, _ := makeControllerKey(ctx2, validController.Name)
key1 = etcdtest.AddPrefix(key1)
key2 = etcdtest.AddPrefix(key2)
fakeClient.Set(key1, runtime.EncodeOrDie(latest.Codec, &validController), 0) fakeClient.Set(key1, runtime.EncodeOrDie(latest.Codec, &validController), 0)
otherNsController := validController otherNsController := validController
otherNsController.Namespace = otherNs otherNsController.Namespace = otherNs
...@@ -317,6 +329,8 @@ func TestEtcdGetControllerNotFound(t *testing.T) { ...@@ -317,6 +329,8 @@ func TestEtcdGetControllerNotFound(t *testing.T) {
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
key, _ := makeControllerKey(ctx, validController.Name) key, _ := makeControllerKey(ctx, validController.Name)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: nil, Node: nil,
...@@ -336,6 +350,7 @@ func TestEtcdUpdateController(t *testing.T) { ...@@ -336,6 +350,7 @@ func TestEtcdUpdateController(t *testing.T) {
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
key, _ := makeControllerKey(ctx, validController.Name) key, _ := makeControllerKey(ctx, validController.Name)
key = etcdtest.AddPrefix(key)
// set a key, then retrieve the current resource version and try updating it // set a key, then retrieve the current resource version and try updating it
resp, _ := fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &validController), 0) resp, _ := fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &validController), 0)
...@@ -360,6 +375,8 @@ func TestEtcdDeleteController(t *testing.T) { ...@@ -360,6 +375,8 @@ func TestEtcdDeleteController(t *testing.T) {
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
key, _ := makeControllerKey(ctx, validController.Name) key, _ := makeControllerKey(ctx, validController.Name)
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &validController), 0) fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &validController), 0)
obj, err := storage.Delete(ctx, validController.Name, nil) obj, err := storage.Delete(ctx, validController.Name, nil)
if err != nil { if err != nil {
...@@ -382,6 +399,7 @@ func TestEtcdListControllers(t *testing.T) { ...@@ -382,6 +399,7 @@ func TestEtcdListControllers(t *testing.T) {
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
key := makeControllerListKey(ctx) key := makeControllerListKey(ctx)
key = etcdtest.AddPrefix(key)
controller := validController controller := validController
controller.Name = "bar" controller.Name = "bar"
fakeClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
...@@ -413,6 +431,8 @@ func TestEtcdListControllersNotFound(t *testing.T) { ...@@ -413,6 +431,8 @@ func TestEtcdListControllersNotFound(t *testing.T) {
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
key := makeControllerListKey(ctx) key := makeControllerListKey(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{}, R: &etcd.Response{},
E: tools.EtcdErrorNotFound, E: tools.EtcdErrorNotFound,
...@@ -431,6 +451,7 @@ func TestEtcdListControllersLabelsMatch(t *testing.T) { ...@@ -431,6 +451,7 @@ func TestEtcdListControllersLabelsMatch(t *testing.T) {
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
key := makeControllerListKey(ctx) key := makeControllerListKey(ctx)
key = etcdtest.AddPrefix(key)
controller := validController controller := validController
controller.Labels = map[string]string{"k": "v"} controller.Labels = map[string]string{"k": "v"}
...@@ -678,13 +699,16 @@ func TestCreate(t *testing.T) { ...@@ -678,13 +699,16 @@ func TestCreate(t *testing.T) {
} }
func TestDelete(t *testing.T) { func TestDelete(t *testing.T) {
ctx := api.NewDefaultContext()
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeClient.SetError) test := resttest.New(t, storage, fakeClient.SetError)
key, _ := makeControllerKey(ctx, validController.Name)
key = etcdtest.AddPrefix(key)
createFn := func() runtime.Object { createFn := func() runtime.Object {
rc := validController rc := validController
rc.ResourceVersion = "1" rc.ResourceVersion = "1"
fakeClient.Data["/registry/controllers/default/foo"] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, &rc), Value: runtime.EncodeOrDie(latest.Codec, &rc),
...@@ -697,7 +721,7 @@ func TestDelete(t *testing.T) { ...@@ -697,7 +721,7 @@ func TestDelete(t *testing.T) {
gracefulSetFn := func() bool { gracefulSetFn := func() bool {
// If the controller is still around after trying to delete either the delete // If the controller is still around after trying to delete either the delete
// failed, or we're deleting it gracefully. // failed, or we're deleting it gracefully.
if fakeClient.Data["/registry/controllers/default/foo"].R.Node != nil { if fakeClient.Data[key].R.Node != nil {
return true return true
} }
return false return false
......
...@@ -34,7 +34,7 @@ type REST struct { ...@@ -34,7 +34,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(h tools.EtcdHelper) *REST {
prefix := "/registry/services/endpoints" prefix := "/services/endpoints"
return &REST{ return &REST{
&etcdgeneric.Etcd{ &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.Endpoints{} }, NewFunc: func() runtime.Object { return &api.Endpoints{} },
......
...@@ -26,6 +26,7 @@ import ( ...@@ -26,6 +26,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/coreos/go-etcd/etcd" "github.com/coreos/go-etcd/etcd"
...@@ -34,7 +35,7 @@ import ( ...@@ -34,7 +35,7 @@ import (
func newHelper(t *testing.T) (*tools.FakeEtcdClient, tools.EtcdHelper) { func newHelper(t *testing.T) (*tools.FakeEtcdClient, tools.EtcdHelper) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true fakeEtcdClient.TestIndex = true
helper := tools.NewEtcdHelper(fakeEtcdClient, latest.Codec) helper := tools.NewEtcdHelper(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
return fakeEtcdClient, helper return fakeEtcdClient, helper
} }
...@@ -89,6 +90,7 @@ func TestDelete(t *testing.T) { ...@@ -89,6 +90,7 @@ func TestDelete(t *testing.T) {
endpoints := validChangedEndpoints() endpoints := validChangedEndpoints()
key, _ := storage.KeyFunc(ctx, endpoints.Name) key, _ := storage.KeyFunc(ctx, endpoints.Name)
key = etcdtest.AddPrefix(key)
createFn := func() runtime.Object { createFn := func() runtime.Object {
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
...@@ -113,6 +115,7 @@ func TestEtcdListEndpoints(t *testing.T) { ...@@ -113,6 +115,7 @@ func TestEtcdListEndpoints(t *testing.T) {
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
key := storage.KeyRootFunc(ctx) key := storage.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
...@@ -154,6 +157,7 @@ func TestEtcdGetEndpoints(t *testing.T) { ...@@ -154,6 +157,7 @@ func TestEtcdGetEndpoints(t *testing.T) {
endpoints := validNewEndpoints() endpoints := validNewEndpoints()
name := endpoints.Name name := endpoints.Name
key, _ := storage.KeyFunc(ctx, name) key, _ := storage.KeyFunc(ctx, name)
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, endpoints), 0) fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, endpoints), 0)
response, err := fakeClient.Get(key, false, false) response, err := fakeClient.Get(key, false, false)
...@@ -183,6 +187,7 @@ func TestListEmptyEndpointsList(t *testing.T) { ...@@ -183,6 +187,7 @@ func TestListEmptyEndpointsList(t *testing.T) {
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
fakeClient.ChangeIndex = 1 fakeClient.ChangeIndex = 1
key := storage.KeyRootFunc(ctx) key := storage.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{}, R: &etcd.Response{},
E: fakeClient.NewError(tools.EtcdErrorCodeNotFound), E: fakeClient.NewError(tools.EtcdErrorCodeNotFound),
...@@ -206,6 +211,7 @@ func TestListEndpointsList(t *testing.T) { ...@@ -206,6 +211,7 @@ func TestListEndpointsList(t *testing.T) {
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
fakeClient.ChangeIndex = 1 fakeClient.ChangeIndex = 1
key := storage.KeyRootFunc(ctx) key := storage.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
...@@ -266,6 +272,7 @@ func TestEtcdUpdateEndpoints(t *testing.T) { ...@@ -266,6 +272,7 @@ func TestEtcdUpdateEndpoints(t *testing.T) {
endpoints := validChangedEndpoints() endpoints := validChangedEndpoints()
key, _ := storage.KeyFunc(ctx, "foo") key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, validNewEndpoints()), 0) fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, validNewEndpoints()), 0)
_, _, err := storage.Update(ctx, endpoints) _, _, err := storage.Update(ctx, endpoints)
...@@ -295,6 +302,7 @@ func TestDeleteEndpoints(t *testing.T) { ...@@ -295,6 +302,7 @@ func TestDeleteEndpoints(t *testing.T) {
endpoints := validNewEndpoints() endpoints := validNewEndpoints()
name := endpoints.Name name := endpoints.Name
key, _ := storage.KeyFunc(ctx, name) key, _ := storage.KeyFunc(ctx, name)
key = etcdtest.AddPrefix(key)
fakeClient.ChangeIndex = 1 fakeClient.ChangeIndex = 1
fakeClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
......
...@@ -35,9 +35,9 @@ import ( ...@@ -35,9 +35,9 @@ import (
const ( const (
// ControllerPath is the path to controller resources in etcd // ControllerPath is the path to controller resources in etcd
ControllerPath string = "/registry/controllers" ControllerPath string = "/controllers"
// ServicePath is the path to service resources in etcd // ServicePath is the path to service resources in etcd
ServicePath string = "/registry/services/specs" ServicePath string = "/services/specs"
) )
// TODO: Need to add a reconciler loop that makes sure that things in pods are reflected into // TODO: Need to add a reconciler loop that makes sure that things in pods are reflected into
......
...@@ -32,16 +32,17 @@ type registry struct { ...@@ -32,16 +32,17 @@ 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. // EtcdHelper. ttl is the time that Events will be retained by the system.
func NewEtcdRegistry(h tools.EtcdHelper, ttl uint64) generic.Registry { func NewEtcdRegistry(h tools.EtcdHelper, ttl uint64) generic.Registry {
prefix := "/events"
return registry{ return registry{
Etcd: &etcdgeneric.Etcd{ Etcd: &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.Event{} }, NewFunc: func() runtime.Object { return &api.Event{} },
NewListFunc: func() runtime.Object { return &api.EventList{} }, NewListFunc: func() runtime.Object { return &api.EventList{} },
EndpointName: "events", EndpointName: "events",
KeyRootFunc: func(ctx api.Context) string { KeyRootFunc: func(ctx api.Context) string {
return etcdgeneric.NamespaceKeyRootFunc(ctx, "/registry/events") return etcdgeneric.NamespaceKeyRootFunc(ctx, prefix)
}, },
KeyFunc: func(ctx api.Context, id string) (string, error) { KeyFunc: func(ctx api.Context, id string) (string, error) {
return etcdgeneric.NamespaceKeyFunc(ctx, "/registry/events", id) return etcdgeneric.NamespaceKeyFunc(ctx, prefix, id)
}, },
TTLFunc: func(runtime.Object, bool) (uint64, error) { TTLFunc: func(runtime.Object, bool) (uint64, error) {
return ttl, nil return ttl, nil
......
...@@ -27,6 +27,7 @@ import ( ...@@ -27,6 +27,7 @@ import (
etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd" etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/coreos/go-etcd/etcd" "github.com/coreos/go-etcd/etcd"
...@@ -37,7 +38,8 @@ var testTTL uint64 = 60 ...@@ -37,7 +38,8 @@ var testTTL uint64 = 60
func NewTestEventEtcdRegistry(t *testing.T) (*tools.FakeEtcdClient, generic.Registry) { func NewTestEventEtcdRegistry(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())
h := tools.NewEtcdHelper(f, testapi.Codec(), etcdtest.PathPrefix())
return f, NewEtcdRegistry(h, testTTL) return f, NewEtcdRegistry(h, testTTL)
} }
...@@ -70,7 +72,8 @@ func TestEventCreate(t *testing.T) { ...@@ -70,7 +72,8 @@ func TestEventCreate(t *testing.T) {
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
key := "foo" key := "foo"
path, err := etcdgeneric.NamespaceKeyFunc(ctx, "/registry/events", key) path, err := etcdgeneric.NamespaceKeyFunc(ctx, "/events", key)
path = etcdtest.AddPrefix(path)
if err != nil { if err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
} }
...@@ -166,7 +169,8 @@ func TestEventUpdate(t *testing.T) { ...@@ -166,7 +169,8 @@ func TestEventUpdate(t *testing.T) {
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
key := "foo" key := "foo"
path, err := etcdgeneric.NamespaceKeyFunc(ctx, "/registry/events", key) path, err := etcdgeneric.NamespaceKeyFunc(ctx, "/events", key)
path = etcdtest.AddPrefix(path)
if err != nil { if err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
} }
......
...@@ -27,6 +27,7 @@ import ( ...@@ -27,6 +27,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/fielderrors" "github.com/GoogleCloudPlatform/kubernetes/pkg/util/fielderrors"
...@@ -66,17 +67,20 @@ func hasCreated(t *testing.T, pod *api.Pod) func(runtime.Object) bool { ...@@ -66,17 +67,20 @@ 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()) h := tools.NewEtcdHelper(f, testapi.Codec(), etcdtest.PathPrefix())
strategy := &testRESTStrategy{api.Scheme, api.SimpleNameGenerator, true, false} strategy := &testRESTStrategy{api.Scheme, api.SimpleNameGenerator, true, false}
podPrefix := "/pods"
return f, &Etcd{ return f, &Etcd{
NewFunc: func() runtime.Object { return &api.Pod{} }, NewFunc: func() runtime.Object { return &api.Pod{} },
NewListFunc: func() runtime.Object { return &api.PodList{} }, NewListFunc: func() runtime.Object { return &api.PodList{} },
EndpointName: "pods", EndpointName: "pods",
CreateStrategy: strategy, CreateStrategy: strategy,
UpdateStrategy: strategy, UpdateStrategy: strategy,
KeyRootFunc: func(ctx api.Context) string { return "/registry/pods" }, KeyRootFunc: func(ctx api.Context) string {
return podPrefix
},
KeyFunc: func(ctx api.Context, id string) (string, error) { KeyFunc: func(ctx api.Context, id string) (string, error) {
return path.Join("/registry/pods", 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, Helper: h,
...@@ -205,16 +209,18 @@ func TestEtcdList(t *testing.T) { ...@@ -205,16 +209,18 @@ func TestEtcdList(t *testing.T) {
t.Errorf("Couldn't create key for %v", name) t.Errorf("Couldn't create key for %v", name)
continue continue
} }
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = item.in fakeClient.Data[key] = item.in
} else { } else {
fakeClient.Data[registry.KeyRootFunc(api.NewContext())] = item.in key, _ := registry.KeyFunc(api.NewContext(), name)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = item.in
} }
list, err := registry.ListPredicate(api.NewContext(), item.m) list, err := registry.ListPredicate(api.NewContext(), item.m)
if e, a := item.succeed, err == nil; e != a { if e, a := item.succeed, err == nil; e != a {
t.Errorf("%v: expected %v, got %v", name, e, a) t.Errorf("%v: expected %v, got %v", name, e, a)
continue continue
} }
if e, a := item.out, list; !api.Semantic.DeepDerivative(e, a) { if e, a := item.out, list; !api.Semantic.DeepDerivative(e, a) {
t.Errorf("%v: Expected %#v, got %#v", name, e, a) t.Errorf("%v: Expected %#v, got %#v", name, e, a)
} }
...@@ -247,8 +253,6 @@ func TestEtcdCreate(t *testing.T) { ...@@ -247,8 +253,6 @@ func TestEtcdCreate(t *testing.T) {
E: tools.EtcdErrorNotFound, E: tools.EtcdErrorNotFound,
} }
path := "/registry/pods/foo"
table := map[string]struct { table := map[string]struct {
existing tools.EtcdResponseWithError existing tools.EtcdResponseWithError
expect tools.EtcdResponseWithError expect tools.EtcdResponseWithError
...@@ -272,6 +276,7 @@ func TestEtcdCreate(t *testing.T) { ...@@ -272,6 +276,7 @@ func TestEtcdCreate(t *testing.T) {
for name, item := range table { for name, item := range table {
fakeClient, registry := NewTestGenericEtcdRegistry(t) fakeClient, registry := NewTestGenericEtcdRegistry(t)
path := etcdtest.AddPrefix("pods/foo")
fakeClient.Data[path] = item.existing fakeClient.Data[path] = item.existing
obj, err := registry.Create(api.NewDefaultContext(), item.toCreate) obj, err := registry.Create(api.NewDefaultContext(), item.toCreate)
if !item.errOK(err) { if !item.errOK(err) {
...@@ -326,7 +331,6 @@ func TestEtcdCreateWithName(t *testing.T) { ...@@ -326,7 +331,6 @@ func TestEtcdCreateWithName(t *testing.T) {
E: tools.EtcdErrorNotFound, E: tools.EtcdErrorNotFound,
} }
path := "/registry/pods/foo"
key := "foo" key := "foo"
table := map[string]struct { table := map[string]struct {
...@@ -352,6 +356,7 @@ func TestEtcdCreateWithName(t *testing.T) { ...@@ -352,6 +356,7 @@ func TestEtcdCreateWithName(t *testing.T) {
for name, item := range table { for name, item := range table {
fakeClient, registry := NewTestGenericEtcdRegistry(t) fakeClient, registry := NewTestGenericEtcdRegistry(t)
path := etcdtest.AddPrefix("pods/foo")
fakeClient.Data[path] = item.existing fakeClient.Data[path] = item.existing
err := registry.CreateWithName(api.NewDefaultContext(), key, item.toCreate) err := registry.CreateWithName(api.NewDefaultContext(), key, item.toCreate)
if !item.errOK(err) { if !item.errOK(err) {
...@@ -424,8 +429,6 @@ func TestEtcdUpdate(t *testing.T) { ...@@ -424,8 +429,6 @@ func TestEtcdUpdate(t *testing.T) {
E: tools.EtcdErrorNotFound, E: tools.EtcdErrorNotFound,
} }
path := "/registry/pods/foo"
table := map[string]struct { table := map[string]struct {
existing tools.EtcdResponseWithError existing tools.EtcdResponseWithError
expect tools.EtcdResponseWithError expect tools.EtcdResponseWithError
...@@ -464,6 +467,7 @@ func TestEtcdUpdate(t *testing.T) { ...@@ -464,6 +467,7 @@ func TestEtcdUpdate(t *testing.T) {
for name, item := range table { for name, item := range table {
fakeClient, registry := NewTestGenericEtcdRegistry(t) fakeClient, registry := NewTestGenericEtcdRegistry(t)
registry.UpdateStrategy.(*testRESTStrategy).allowCreateOnUpdate = item.allowCreate registry.UpdateStrategy.(*testRESTStrategy).allowCreateOnUpdate = item.allowCreate
path := etcdtest.AddPrefix("pods/foo")
fakeClient.Data[path] = item.existing fakeClient.Data[path] = item.existing
obj, _, err := registry.Update(api.NewDefaultContext(), item.toUpdate) obj, _, err := registry.Update(api.NewDefaultContext(), item.toUpdate)
if !item.errOK(err) { if !item.errOK(err) {
...@@ -529,7 +533,6 @@ func TestEtcdUpdateWithName(t *testing.T) { ...@@ -529,7 +533,6 @@ func TestEtcdUpdateWithName(t *testing.T) {
E: tools.EtcdErrorNotFound, E: tools.EtcdErrorNotFound,
} }
path := "/registry/pods/foo"
key := "foo" key := "foo"
table := map[string]struct { table := map[string]struct {
...@@ -555,6 +558,7 @@ func TestEtcdUpdateWithName(t *testing.T) { ...@@ -555,6 +558,7 @@ func TestEtcdUpdateWithName(t *testing.T) {
for name, item := range table { for name, item := range table {
fakeClient, registry := NewTestGenericEtcdRegistry(t) fakeClient, registry := NewTestGenericEtcdRegistry(t)
path := etcdtest.AddPrefix("pods/foo")
fakeClient.Data[path] = item.existing fakeClient.Data[path] = item.existing
err := registry.UpdateWithName(api.NewContext(), key, item.toUpdate) err := registry.UpdateWithName(api.NewContext(), key, item.toUpdate)
if !item.errOK(err) { if !item.errOK(err) {
...@@ -589,7 +593,6 @@ func TestEtcdGet(t *testing.T) { ...@@ -589,7 +593,6 @@ func TestEtcdGet(t *testing.T) {
E: tools.EtcdErrorNotFound, E: tools.EtcdErrorNotFound,
} }
path := "/registry/pods/foo"
key := "foo" key := "foo"
table := map[string]struct { table := map[string]struct {
...@@ -611,6 +614,7 @@ func TestEtcdGet(t *testing.T) { ...@@ -611,6 +614,7 @@ func TestEtcdGet(t *testing.T) {
for name, item := range table { for name, item := range table {
fakeClient, registry := NewTestGenericEtcdRegistry(t) fakeClient, registry := NewTestGenericEtcdRegistry(t)
path := etcdtest.AddPrefix("pods/foo")
fakeClient.Data[path] = item.existing fakeClient.Data[path] = item.existing
got, err := registry.Get(api.NewContext(), key) got, err := registry.Get(api.NewContext(), key)
if !item.errOK(err) { if !item.errOK(err) {
...@@ -645,7 +649,6 @@ func TestEtcdDelete(t *testing.T) { ...@@ -645,7 +649,6 @@ func TestEtcdDelete(t *testing.T) {
E: tools.EtcdErrorNotFound, E: tools.EtcdErrorNotFound,
} }
path := "/registry/pods/foo"
key := "foo" key := "foo"
table := map[string]struct { table := map[string]struct {
...@@ -667,6 +670,7 @@ func TestEtcdDelete(t *testing.T) { ...@@ -667,6 +670,7 @@ func TestEtcdDelete(t *testing.T) {
for name, item := range table { for name, item := range table {
fakeClient, registry := NewTestGenericEtcdRegistry(t) fakeClient, registry := NewTestGenericEtcdRegistry(t)
path := etcdtest.AddPrefix("pods/foo")
fakeClient.Data[path] = item.existing fakeClient.Data[path] = item.existing
obj, err := registry.Delete(api.NewContext(), key, nil) obj, err := registry.Delete(api.NewContext(), key, nil)
if !item.errOK(err) { if !item.errOK(err) {
......
...@@ -31,16 +31,17 @@ type registry struct { ...@@ -31,16 +31,17 @@ type registry struct {
// NewEtcdRegistry returns a registry which will store LimitRange in the given helper // NewEtcdRegistry returns a registry which will store LimitRange in the given helper
func NewEtcdRegistry(h tools.EtcdHelper) generic.Registry { func NewEtcdRegistry(h tools.EtcdHelper) generic.Registry {
prefix := "/limitranges"
return registry{ return registry{
Etcd: &etcdgeneric.Etcd{ Etcd: &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.LimitRange{} }, NewFunc: func() runtime.Object { return &api.LimitRange{} },
NewListFunc: func() runtime.Object { return &api.LimitRangeList{} }, NewListFunc: func() runtime.Object { return &api.LimitRangeList{} },
EndpointName: "limitranges", EndpointName: "limitranges",
KeyRootFunc: func(ctx api.Context) string { KeyRootFunc: func(ctx api.Context) string {
return etcdgeneric.NamespaceKeyRootFunc(ctx, "/registry/limitranges") return etcdgeneric.NamespaceKeyRootFunc(ctx, prefix)
}, },
KeyFunc: func(ctx api.Context, id string) (string, error) { KeyFunc: func(ctx api.Context, id string) (string, error) {
return etcdgeneric.NamespaceKeyFunc(ctx, "/registry/limitranges", id) return etcdgeneric.NamespaceKeyFunc(ctx, prefix, id)
}, },
Helper: h, Helper: h,
}, },
......
...@@ -28,6 +28,7 @@ import ( ...@@ -28,6 +28,7 @@ import (
etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd" etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/coreos/go-etcd/etcd" "github.com/coreos/go-etcd/etcd"
...@@ -36,7 +37,7 @@ import ( ...@@ -36,7 +37,7 @@ 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()) h := tools.NewEtcdHelper(f, testapi.Codec(), etcdtest.PathPrefix())
return f, NewEtcdRegistry(h) return f, NewEtcdRegistry(h)
} }
...@@ -81,7 +82,9 @@ func TestLimitRangeCreate(t *testing.T) { ...@@ -81,7 +82,9 @@ func TestLimitRangeCreate(t *testing.T) {
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
key := "foo" key := "foo"
path, err := etcdgeneric.NamespaceKeyFunc(ctx, "/registry/limitranges", key) prefix := etcdtest.AddPrefix("limitranges")
path, err := etcdgeneric.NamespaceKeyFunc(ctx, prefix, key)
if err != nil { if err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
} }
......
...@@ -50,7 +50,7 @@ func (r *StatusREST) Update(ctx api.Context, obj runtime.Object) (runtime.Object ...@@ -50,7 +50,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(h tools.EtcdHelper, connection client.ConnectionInfoGetter) (*REST, *StatusREST) {
prefix := "/registry/minions" prefix := "/minions"
store := &etcdgeneric.Etcd{ store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.Node{} }, NewFunc: func() runtime.Object { return &api.Node{} },
NewListFunc: func() runtime.Object { return &api.NodeList{} }, NewListFunc: func() runtime.Object { return &api.NodeList{} },
......
...@@ -30,6 +30,7 @@ import ( ...@@ -30,6 +30,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/coreos/go-etcd/etcd" "github.com/coreos/go-etcd/etcd"
) )
...@@ -49,7 +50,7 @@ func (fakeConnectionInfoGetter) GetConnectionInfo(host string) (string, uint, ht ...@@ -49,7 +50,7 @@ func (fakeConnectionInfoGetter) GetConnectionInfo(host string) (string, uint, ht
func newHelper(t *testing.T) (*tools.FakeEtcdClient, tools.EtcdHelper) { func newHelper(t *testing.T) (*tools.FakeEtcdClient, tools.EtcdHelper) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true fakeEtcdClient.TestIndex = true
helper := tools.NewEtcdHelper(fakeEtcdClient, latest.Codec) helper := tools.NewEtcdHelper(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
return fakeEtcdClient, helper return fakeEtcdClient, helper
} }
...@@ -107,6 +108,7 @@ func TestDelete(t *testing.T) { ...@@ -107,6 +108,7 @@ func TestDelete(t *testing.T) {
node := validChangedNode() node := validChangedNode()
key, _ := storage.KeyFunc(ctx, node.Name) key, _ := storage.KeyFunc(ctx, node.Name)
key = etcdtest.AddPrefix(key)
createFn := func() runtime.Object { createFn := func() runtime.Object {
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
...@@ -131,6 +133,7 @@ func TestEtcdListNodes(t *testing.T) { ...@@ -131,6 +133,7 @@ func TestEtcdListNodes(t *testing.T) {
ctx := api.NewContext() ctx := api.NewContext()
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
key := storage.KeyRootFunc(ctx) key := storage.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
...@@ -165,6 +168,7 @@ func TestEtcdListNodesMatch(t *testing.T) { ...@@ -165,6 +168,7 @@ func TestEtcdListNodesMatch(t *testing.T) {
ctx := api.NewContext() ctx := api.NewContext()
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
key := storage.KeyRootFunc(ctx) key := storage.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
...@@ -209,6 +213,7 @@ func TestEtcdGetNode(t *testing.T) { ...@@ -209,6 +213,7 @@ func TestEtcdGetNode(t *testing.T) {
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
node := validNewNode() node := validNewNode()
key, _ := storage.KeyFunc(ctx, node.Name) key, _ := storage.KeyFunc(ctx, node.Name)
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, node), 0) fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, node), 0)
nodeObj, err := storage.Get(ctx, node.Name) nodeObj, err := storage.Get(ctx, node.Name)
...@@ -229,6 +234,7 @@ func TestEtcdUpdateEndpoints(t *testing.T) { ...@@ -229,6 +234,7 @@ func TestEtcdUpdateEndpoints(t *testing.T) {
node := validChangedNode() node := validChangedNode()
key, _ := storage.KeyFunc(ctx, node.Name) key, _ := storage.KeyFunc(ctx, node.Name)
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, validNewNode()), 0) fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, validNewNode()), 0)
_, _, err := storage.Update(ctx, node) _, _, err := storage.Update(ctx, node)
...@@ -255,7 +261,8 @@ func TestEtcdUpdateEndpoints(t *testing.T) { ...@@ -255,7 +261,8 @@ func TestEtcdUpdateEndpoints(t *testing.T) {
func TestEtcdGetNodeNotFound(t *testing.T) { func TestEtcdGetNodeNotFound(t *testing.T) {
ctx := api.NewContext() ctx := api.NewContext()
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
fakeClient.Data["/registry/minions/foo"] = tools.EtcdResponseWithError{ key := etcdtest.AddPrefix("minions/foo")
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: nil, Node: nil,
}, },
...@@ -273,6 +280,7 @@ func TestEtcdDeleteNode(t *testing.T) { ...@@ -273,6 +280,7 @@ func TestEtcdDeleteNode(t *testing.T) {
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
node := validNewNode() node := validNewNode()
key, _ := storage.KeyFunc(ctx, node.Name) key, _ := storage.KeyFunc(ctx, node.Name)
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, node), 0) fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, node), 0)
_, err := storage.Delete(ctx, node.Name, nil) _, err := storage.Delete(ctx, node.Name, nil)
if err != nil { if err != nil {
......
...@@ -18,6 +18,7 @@ package etcd ...@@ -18,6 +18,7 @@ package etcd
import ( import (
"fmt" "fmt"
"path"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields" "github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
...@@ -48,14 +49,15 @@ type FinalizeREST struct { ...@@ -48,14 +49,15 @@ 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(h tools.EtcdHelper) (*REST, *StatusREST, *FinalizeREST) {
prefix := "/namespaces"
store := &etcdgeneric.Etcd{ store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.Namespace{} }, NewFunc: func() runtime.Object { return &api.Namespace{} },
NewListFunc: func() runtime.Object { return &api.NamespaceList{} }, NewListFunc: func() runtime.Object { return &api.NamespaceList{} },
KeyRootFunc: func(ctx api.Context) string { KeyRootFunc: func(ctx api.Context) string {
return "/registry/namespaces" return prefix
}, },
KeyFunc: func(ctx api.Context, name string) (string, error) { KeyFunc: func(ctx api.Context, name string) (string, error) {
return "/registry/namespaces/" + name, nil return path.Join(prefix, name), nil
}, },
ObjectNameFunc: func(obj runtime.Object) (string, error) { ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*api.Namespace).Name, nil return obj.(*api.Namespace).Name, nil
......
...@@ -27,6 +27,7 @@ import ( ...@@ -27,6 +27,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/namespace" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/namespace"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/coreos/go-etcd/etcd" "github.com/coreos/go-etcd/etcd"
...@@ -35,7 +36,7 @@ import ( ...@@ -35,7 +36,7 @@ import (
func newHelper(t *testing.T) (*tools.FakeEtcdClient, tools.EtcdHelper) { func newHelper(t *testing.T) (*tools.FakeEtcdClient, tools.EtcdHelper) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true fakeEtcdClient.TestIndex = true
helper := tools.NewEtcdHelper(fakeEtcdClient, latest.Codec) helper := tools.NewEtcdHelper(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
return fakeEtcdClient, helper return fakeEtcdClient, helper
} }
...@@ -102,7 +103,12 @@ func TestCreateSetsFields(t *testing.T) { ...@@ -102,7 +103,12 @@ func TestCreateSetsFields(t *testing.T) {
} }
actual := &api.Namespace{} actual := &api.Namespace{}
if err := helper.ExtractObj("/registry/namespaces/foo", actual, false); err != nil { ctx := api.NewDefaultContext()
key, err := storage.Etcd.KeyFunc(ctx, "foo")
if err != nil {
t.Fatalf("unexpected key error: %v", err)
}
if err := helper.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 {
...@@ -119,7 +125,8 @@ func TestCreateSetsFields(t *testing.T) { ...@@ -119,7 +125,8 @@ func TestCreateSetsFields(t *testing.T) {
func TestListEmptyNamespaceList(t *testing.T) { func TestListEmptyNamespaceList(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, helper := newHelper(t)
fakeEtcdClient.ChangeIndex = 1 fakeEtcdClient.ChangeIndex = 1
fakeEtcdClient.Data["/registry/namespaces"] = tools.EtcdResponseWithError{ key := etcdtest.AddPrefix("/namespaces")
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{}, R: &etcd.Response{},
E: fakeEtcdClient.NewError(tools.EtcdErrorCodeNotFound), E: fakeEtcdClient.NewError(tools.EtcdErrorCodeNotFound),
} }
...@@ -139,7 +146,8 @@ func TestListEmptyNamespaceList(t *testing.T) { ...@@ -139,7 +146,8 @@ func TestListEmptyNamespaceList(t *testing.T) {
func TestListNamespaceList(t *testing.T) { func TestListNamespaceList(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, helper := newHelper(t)
fakeEtcdClient.Data["/registry/namespaces"] = tools.EtcdResponseWithError{ key := etcdtest.AddPrefix("/namespaces")
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Nodes: []*etcd.Node{ Nodes: []*etcd.Node{
...@@ -177,7 +185,8 @@ func TestListNamespaceList(t *testing.T) { ...@@ -177,7 +185,8 @@ func TestListNamespaceList(t *testing.T) {
func TestListNamespaceListSelection(t *testing.T) { func TestListNamespaceListSelection(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, helper := newHelper(t)
fakeEtcdClient.Data["/registry/namespaces"] = tools.EtcdResponseWithError{ key := etcdtest.AddPrefix("/namespaces")
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Nodes: []*etcd.Node{ Nodes: []*etcd.Node{
...@@ -275,15 +284,20 @@ func TestNamespaceDecode(t *testing.T) { ...@@ -275,15 +284,20 @@ func TestNamespaceDecode(t *testing.T) {
func TestGet(t *testing.T) { func TestGet(t *testing.T) {
expect := validNewNamespace() expect := validNewNamespace()
expect.Status.Phase = api.NamespaceActive expect.Status.Phase = api.NamespaceActive
fakeEtcdClient, helper := newHelper(t) storage, fakeEtcdClient, _ := newStorage(t)
fakeEtcdClient.Data["/registry/namespaces/foo"] = tools.EtcdResponseWithError{ ctx := api.NewDefaultContext()
key, err := storage.Etcd.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
if err != nil {
t.Fatalf("unexpected key error: %v", err)
}
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, expect), Value: runtime.EncodeOrDie(latest.Codec, expect),
}, },
}, },
} }
storage, _, _ := NewStorage(helper)
obj, err := storage.Get(api.NewContext(), "foo") obj, err := storage.Get(api.NewContext(), "foo")
namespace := obj.(*api.Namespace) namespace := obj.(*api.Namespace)
if err != nil { if err != nil {
...@@ -299,7 +313,11 @@ func TestGet(t *testing.T) { ...@@ -299,7 +313,11 @@ func TestGet(t *testing.T) {
func TestDeleteNamespace(t *testing.T) { func TestDeleteNamespace(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, helper := newHelper(t)
fakeEtcdClient.ChangeIndex = 1 fakeEtcdClient.ChangeIndex = 1
fakeEtcdClient.Data["/registry/namespaces/foo"] = tools.EtcdResponseWithError{ storage, _, _ := NewStorage(helper)
ctx := api.NewDefaultContext()
key, err := storage.Etcd.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, &api.Namespace{ Value: runtime.EncodeOrDie(latest.Codec, &api.Namespace{
...@@ -313,8 +331,7 @@ func TestDeleteNamespace(t *testing.T) { ...@@ -313,8 +331,7 @@ func TestDeleteNamespace(t *testing.T) {
}, },
}, },
} }
storage, _, _ := NewStorage(helper) _, err = storage.Delete(api.NewDefaultContext(), "foo", nil)
_, err := storage.Delete(api.NewDefaultContext(), "foo", nil)
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
...@@ -325,7 +342,8 @@ func TestDeleteNamespaceWithIncompleteFinalizers(t *testing.T) { ...@@ -325,7 +342,8 @@ func TestDeleteNamespaceWithIncompleteFinalizers(t *testing.T) {
now := util.Now() now := util.Now()
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, helper := newHelper(t)
fakeEtcdClient.ChangeIndex = 1 fakeEtcdClient.ChangeIndex = 1
fakeEtcdClient.Data["/registry/namespaces/foo"] = tools.EtcdResponseWithError{ key := etcdtest.AddPrefix("/namespaces/foo")
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, &api.Namespace{ Value: runtime.EncodeOrDie(latest.Codec, &api.Namespace{
...@@ -354,7 +372,8 @@ func TestDeleteNamespaceWithCompleteFinalizers(t *testing.T) { ...@@ -354,7 +372,8 @@ func TestDeleteNamespaceWithCompleteFinalizers(t *testing.T) {
now := util.Now() now := util.Now()
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, helper := newHelper(t)
fakeEtcdClient.ChangeIndex = 1 fakeEtcdClient.ChangeIndex = 1
fakeEtcdClient.Data["/registry/namespaces/foo"] = tools.EtcdResponseWithError{ key := etcdtest.AddPrefix("/namespaces/foo")
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, &api.Namespace{ Value: runtime.EncodeOrDie(latest.Codec, &api.Namespace{
......
...@@ -17,6 +17,8 @@ limitations under the License. ...@@ -17,6 +17,8 @@ limitations under the License.
package etcd package etcd
import ( import (
"path"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields" "github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
...@@ -34,7 +36,7 @@ type REST struct { ...@@ -34,7 +36,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(h tools.EtcdHelper) (*REST, *StatusREST) {
prefix := "/registry/persistentvolumes" prefix := "/persistentvolumes"
store := &etcdgeneric.Etcd{ store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.PersistentVolume{} }, NewFunc: func() runtime.Object { return &api.PersistentVolume{} },
NewListFunc: func() runtime.Object { return &api.PersistentVolumeList{} }, NewListFunc: func() runtime.Object { return &api.PersistentVolumeList{} },
...@@ -42,7 +44,7 @@ func NewStorage(h tools.EtcdHelper) (*REST, *StatusREST) { ...@@ -42,7 +44,7 @@ func NewStorage(h tools.EtcdHelper) (*REST, *StatusREST) {
return prefix return prefix
}, },
KeyFunc: func(ctx api.Context, name string) (string, error) { KeyFunc: func(ctx api.Context, name string) (string, error) {
return prefix + "/" + name, nil return path.Join(prefix, name), nil
}, },
ObjectNameFunc: func(obj runtime.Object) (string, error) { ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*api.PersistentVolume).Name, nil return obj.(*api.PersistentVolume).Name, nil
......
...@@ -28,6 +28,7 @@ import ( ...@@ -28,6 +28,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/coreos/go-etcd/etcd" "github.com/coreos/go-etcd/etcd"
...@@ -40,7 +41,7 @@ type testRegistry struct { ...@@ -40,7 +41,7 @@ type testRegistry struct {
func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient, tools.EtcdHelper) { func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient, tools.EtcdHelper) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true fakeEtcdClient.TestIndex = true
helper := tools.NewEtcdHelper(fakeEtcdClient, latest.Codec) helper := tools.NewEtcdHelper(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
storage, statusStorage := NewStorage(helper) storage, statusStorage := NewStorage(helper)
return storage, statusStorage, fakeEtcdClient, helper return storage, statusStorage, fakeEtcdClient, helper
} }
...@@ -90,6 +91,7 @@ func TestDelete(t *testing.T) { ...@@ -90,6 +91,7 @@ func TestDelete(t *testing.T) {
pv := validChangedPersistentVolume() pv := validChangedPersistentVolume()
key, _ := storage.KeyFunc(ctx, pv.Name) key, _ := storage.KeyFunc(ctx, pv.Name)
key = etcdtest.AddPrefix(key)
createFn := func() runtime.Object { createFn := func() runtime.Object {
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
...@@ -114,6 +116,7 @@ func TestEtcdListPersistentVolumes(t *testing.T) { ...@@ -114,6 +116,7 @@ func TestEtcdListPersistentVolumes(t *testing.T) {
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
storage, _, fakeClient, _ := newStorage(t) storage, _, fakeClient, _ := newStorage(t)
key := storage.KeyRootFunc(ctx) key := storage.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
...@@ -147,6 +150,7 @@ func TestEtcdGetPersistentVolumes(t *testing.T) { ...@@ -147,6 +150,7 @@ func TestEtcdGetPersistentVolumes(t *testing.T) {
persistentVolume := validNewPersistentVolume("foo") persistentVolume := validNewPersistentVolume("foo")
name := persistentVolume.Name name := persistentVolume.Name
key, _ := storage.KeyFunc(ctx, name) key, _ := storage.KeyFunc(ctx, name)
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, persistentVolume), 0) fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, persistentVolume), 0)
response, err := fakeClient.Get(key, false, false) response, err := fakeClient.Get(key, false, false)
...@@ -176,6 +180,7 @@ func TestListEmptyPersistentVolumesList(t *testing.T) { ...@@ -176,6 +180,7 @@ func TestListEmptyPersistentVolumesList(t *testing.T) {
storage, _, fakeClient, _ := newStorage(t) storage, _, fakeClient, _ := newStorage(t)
fakeClient.ChangeIndex = 1 fakeClient.ChangeIndex = 1
key := storage.KeyRootFunc(ctx) key := storage.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{}, R: &etcd.Response{},
E: fakeClient.NewError(tools.EtcdErrorCodeNotFound), E: fakeClient.NewError(tools.EtcdErrorCodeNotFound),
...@@ -199,6 +204,7 @@ func TestListPersistentVolumesList(t *testing.T) { ...@@ -199,6 +204,7 @@ func TestListPersistentVolumesList(t *testing.T) {
storage, _, fakeClient, _ := newStorage(t) storage, _, fakeClient, _ := newStorage(t)
fakeClient.ChangeIndex = 1 fakeClient.ChangeIndex = 1
key := storage.KeyRootFunc(ctx) key := storage.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
...@@ -259,6 +265,7 @@ func TestEtcdUpdatePersistentVolumes(t *testing.T) { ...@@ -259,6 +265,7 @@ func TestEtcdUpdatePersistentVolumes(t *testing.T) {
persistentVolume := validChangedPersistentVolume() persistentVolume := validChangedPersistentVolume()
key, _ := storage.KeyFunc(ctx, "foo") key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, validNewPersistentVolume("foo")), 0) fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, validNewPersistentVolume("foo")), 0)
_, _, err := storage.Update(ctx, persistentVolume) _, _, err := storage.Update(ctx, persistentVolume)
...@@ -288,6 +295,7 @@ func TestDeletePersistentVolumes(t *testing.T) { ...@@ -288,6 +295,7 @@ func TestDeletePersistentVolumes(t *testing.T) {
persistentVolume := validNewPersistentVolume("foo") persistentVolume := validNewPersistentVolume("foo")
name := persistentVolume.Name name := persistentVolume.Name
key, _ := storage.KeyFunc(ctx, name) key, _ := storage.KeyFunc(ctx, name)
key = etcdtest.AddPrefix(key)
fakeClient.ChangeIndex = 1 fakeClient.ChangeIndex = 1
fakeClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
...@@ -310,6 +318,7 @@ func TestEtcdUpdateStatus(t *testing.T) { ...@@ -310,6 +318,7 @@ func TestEtcdUpdateStatus(t *testing.T) {
fakeClient.TestIndex = true fakeClient.TestIndex = true
key, _ := storage.KeyFunc(ctx, "foo") key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
pvStart := validNewPersistentVolume("foo") pvStart := validNewPersistentVolume("foo")
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, pvStart), 1) fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, pvStart), 1)
...@@ -333,6 +342,7 @@ func TestEtcdUpdateStatus(t *testing.T) { ...@@ -333,6 +342,7 @@ func TestEtcdUpdateStatus(t *testing.T) {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
var pvOut api.PersistentVolume var pvOut api.PersistentVolume
key, _ = storage.KeyFunc(ctx, "foo")
if err := helper.ExtractObj(key, &pvOut, false); err != nil { if err := helper.ExtractObj(key, &pvOut, false); err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
......
...@@ -34,7 +34,7 @@ type REST struct { ...@@ -34,7 +34,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(h tools.EtcdHelper) (*REST, *StatusREST) {
prefix := "/registry/persistentvolumeclaims" prefix := "/persistentvolumeclaims"
store := &etcdgeneric.Etcd{ store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.PersistentVolumeClaim{} }, NewFunc: func() runtime.Object { return &api.PersistentVolumeClaim{} },
NewListFunc: func() runtime.Object { return &api.PersistentVolumeClaimList{} }, NewListFunc: func() runtime.Object { return &api.PersistentVolumeClaimList{} },
......
...@@ -28,6 +28,7 @@ import ( ...@@ -28,6 +28,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/coreos/go-etcd/etcd" "github.com/coreos/go-etcd/etcd"
...@@ -40,7 +41,7 @@ type testRegistry struct { ...@@ -40,7 +41,7 @@ type testRegistry struct {
func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient, tools.EtcdHelper) { func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient, tools.EtcdHelper) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true fakeEtcdClient.TestIndex = true
helper := tools.NewEtcdHelper(fakeEtcdClient, latest.Codec) helper := tools.NewEtcdHelper(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
storage, statusStorage := NewStorage(helper) storage, statusStorage := NewStorage(helper)
return storage, statusStorage, fakeEtcdClient, helper return storage, statusStorage, fakeEtcdClient, helper
} }
...@@ -92,6 +93,7 @@ func TestDelete(t *testing.T) { ...@@ -92,6 +93,7 @@ func TestDelete(t *testing.T) {
pv := validChangedPersistentVolumeClaim() pv := validChangedPersistentVolumeClaim()
key, _ := storage.KeyFunc(ctx, pv.Name) key, _ := storage.KeyFunc(ctx, pv.Name)
key = etcdtest.AddPrefix(key)
createFn := func() runtime.Object { createFn := func() runtime.Object {
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
...@@ -116,6 +118,7 @@ func TestEtcdListPersistentVolumeClaims(t *testing.T) { ...@@ -116,6 +118,7 @@ func TestEtcdListPersistentVolumeClaims(t *testing.T) {
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
registry, _, fakeClient, _ := newStorage(t) registry, _, fakeClient, _ := newStorage(t)
key := registry.KeyRootFunc(ctx) key := registry.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
...@@ -149,6 +152,7 @@ func TestEtcdGetPersistentVolumeClaims(t *testing.T) { ...@@ -149,6 +152,7 @@ func TestEtcdGetPersistentVolumeClaims(t *testing.T) {
persistentVolume := validNewPersistentVolumeClaim("foo", api.NamespaceDefault) persistentVolume := validNewPersistentVolumeClaim("foo", api.NamespaceDefault)
name := persistentVolume.Name name := persistentVolume.Name
key, _ := registry.KeyFunc(ctx, name) key, _ := registry.KeyFunc(ctx, name)
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, persistentVolume), 0) fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, persistentVolume), 0)
response, err := fakeClient.Get(key, false, false) response, err := fakeClient.Get(key, false, false)
...@@ -178,6 +182,7 @@ func TestListEmptyPersistentVolumeClaimsList(t *testing.T) { ...@@ -178,6 +182,7 @@ func TestListEmptyPersistentVolumeClaimsList(t *testing.T) {
registry, _, fakeClient, _ := newStorage(t) registry, _, fakeClient, _ := newStorage(t)
fakeClient.ChangeIndex = 1 fakeClient.ChangeIndex = 1
key := registry.KeyRootFunc(ctx) key := registry.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{}, R: &etcd.Response{},
E: fakeClient.NewError(tools.EtcdErrorCodeNotFound), E: fakeClient.NewError(tools.EtcdErrorCodeNotFound),
...@@ -201,6 +206,7 @@ func TestListPersistentVolumeClaimsList(t *testing.T) { ...@@ -201,6 +206,7 @@ func TestListPersistentVolumeClaimsList(t *testing.T) {
registry, _, fakeClient, _ := newStorage(t) registry, _, fakeClient, _ := newStorage(t)
fakeClient.ChangeIndex = 1 fakeClient.ChangeIndex = 1
key := registry.KeyRootFunc(ctx) key := registry.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
...@@ -261,6 +267,7 @@ func TestEtcdUpdatePersistentVolumeClaims(t *testing.T) { ...@@ -261,6 +267,7 @@ func TestEtcdUpdatePersistentVolumeClaims(t *testing.T) {
persistentVolume := validChangedPersistentVolumeClaim() persistentVolume := validChangedPersistentVolumeClaim()
key, _ := registry.KeyFunc(ctx, "foo") key, _ := registry.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, validNewPersistentVolumeClaim("foo", api.NamespaceDefault)), 0) fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, validNewPersistentVolumeClaim("foo", api.NamespaceDefault)), 0)
_, _, err := registry.Update(ctx, persistentVolume) _, _, err := registry.Update(ctx, persistentVolume)
...@@ -290,6 +297,7 @@ func TestDeletePersistentVolumeClaims(t *testing.T) { ...@@ -290,6 +297,7 @@ func TestDeletePersistentVolumeClaims(t *testing.T) {
pvClaim := validNewPersistentVolumeClaim("foo", api.NamespaceDefault) pvClaim := validNewPersistentVolumeClaim("foo", api.NamespaceDefault)
name := pvClaim.Name name := pvClaim.Name
key, _ := registry.KeyFunc(ctx, name) key, _ := registry.KeyFunc(ctx, name)
key = etcdtest.AddPrefix(key)
fakeClient.ChangeIndex = 1 fakeClient.ChangeIndex = 1
fakeClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
...@@ -312,6 +320,7 @@ func TestEtcdUpdateStatus(t *testing.T) { ...@@ -312,6 +320,7 @@ func TestEtcdUpdateStatus(t *testing.T) {
fakeClient.TestIndex = true fakeClient.TestIndex = true
key, _ := storage.KeyFunc(ctx, "foo") key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
pvcStart := validNewPersistentVolumeClaim("foo", api.NamespaceDefault) pvcStart := validNewPersistentVolumeClaim("foo", api.NamespaceDefault)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, pvcStart), 1) fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, pvcStart), 1)
...@@ -336,6 +345,7 @@ func TestEtcdUpdateStatus(t *testing.T) { ...@@ -336,6 +345,7 @@ func TestEtcdUpdateStatus(t *testing.T) {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
var pvcOut api.PersistentVolumeClaim var pvcOut api.PersistentVolumeClaim
key, _ = storage.KeyFunc(ctx, "foo")
if err := helper.ExtractObj(key, &pvcOut, false); err != nil { if err := helper.ExtractObj(key, &pvcOut, false); err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
......
...@@ -56,7 +56,7 @@ type REST struct { ...@@ -56,7 +56,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(h tools.EtcdHelper, k client.ConnectionInfoGetter) PodStorage {
prefix := "/registry/pods" prefix := "/pods"
store := &etcdgeneric.Etcd{ store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.Pod{} }, NewFunc: func() runtime.Object { return &api.Pod{} },
NewListFunc: func() runtime.Object { return &api.PodList{} }, NewListFunc: func() runtime.Object { return &api.PodList{} },
......
...@@ -34,7 +34,7 @@ type REST struct { ...@@ -34,7 +34,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(h tools.EtcdHelper) *REST {
prefix := "/registry/podtemplates" prefix := "/podtemplates"
store := etcdgeneric.Etcd{ store := etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.PodTemplate{} }, NewFunc: func() runtime.Object { return &api.PodTemplate{} },
NewListFunc: func() runtime.Object { return &api.PodTemplateList{} }, NewListFunc: func() runtime.Object { return &api.PodTemplateList{} },
......
...@@ -23,12 +23,13 @@ import ( ...@@ -23,12 +23,13 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest/resttest" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest/resttest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta3" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta3"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
) )
func newHelper(t *testing.T) (*tools.FakeEtcdClient, tools.EtcdHelper) { func newHelper(t *testing.T) (*tools.FakeEtcdClient, tools.EtcdHelper) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true fakeEtcdClient.TestIndex = true
helper := tools.NewEtcdHelper(fakeEtcdClient, v1beta3.Codec) helper := tools.NewEtcdHelper(fakeEtcdClient, v1beta3.Codec, etcdtest.PathPrefix())
return fakeEtcdClient, helper return fakeEtcdClient, helper
} }
...@@ -79,8 +80,9 @@ func TestUpdate(t *testing.T) { ...@@ -79,8 +80,9 @@ func TestUpdate(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, helper := newHelper(t)
storage := NewREST(helper) storage := NewREST(helper)
test := resttest.New(t, storage, fakeEtcdClient.SetError) test := resttest.New(t, storage, fakeEtcdClient.SetError)
key := etcdtest.AddPrefix("podtemplates/default/foo")
fakeEtcdClient.ExpectNotFoundGet("/registry/podtemplates/default/foo") fakeEtcdClient.ExpectNotFoundGet(key)
fakeEtcdClient.ChangeIndex = 2 fakeEtcdClient.ChangeIndex = 2
pod := validNewPodTemplate("foo") pod := validNewPodTemplate("foo")
existing := validNewPodTemplate("exists") existing := validNewPodTemplate("exists")
......
...@@ -34,7 +34,7 @@ type REST struct { ...@@ -34,7 +34,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(h tools.EtcdHelper) (*REST, *StatusREST) {
prefix := "/registry/resourcequotas" prefix := "/resourcequotas"
store := &etcdgeneric.Etcd{ store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.ResourceQuota{} }, NewFunc: func() runtime.Object { return &api.ResourceQuota{} },
NewListFunc: func() runtime.Object { return &api.ResourceQuotaList{} }, NewListFunc: func() runtime.Object { return &api.ResourceQuotaList{} },
......
...@@ -32,6 +32,7 @@ import ( ...@@ -32,6 +32,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequota" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequota"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/coreos/go-etcd/etcd" "github.com/coreos/go-etcd/etcd"
...@@ -40,7 +41,7 @@ import ( ...@@ -40,7 +41,7 @@ import (
func newHelper(t *testing.T) (*tools.FakeEtcdClient, tools.EtcdHelper) { func newHelper(t *testing.T) (*tools.FakeEtcdClient, tools.EtcdHelper) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true fakeEtcdClient.TestIndex = true
helper := tools.NewEtcdHelper(fakeEtcdClient, latest.Codec) helper := tools.NewEtcdHelper(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
return fakeEtcdClient, helper return fakeEtcdClient, helper
} }
...@@ -123,6 +124,7 @@ func TestCreateRegistryError(t *testing.T) { ...@@ -123,6 +124,7 @@ func TestCreateRegistryError(t *testing.T) {
func TestCreateSetsFields(t *testing.T) { func TestCreateSetsFields(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, helper := newHelper(t)
storage, _ := NewStorage(helper) storage, _ := NewStorage(helper)
ctx := api.NewDefaultContext()
resourcequota := validNewResourceQuota() resourcequota := validNewResourceQuota()
_, err := storage.Create(api.NewDefaultContext(), resourcequota) _, err := storage.Create(api.NewDefaultContext(), resourcequota)
if err != fakeEtcdClient.Err { if err != fakeEtcdClient.Err {
...@@ -130,7 +132,8 @@ func TestCreateSetsFields(t *testing.T) { ...@@ -130,7 +132,8 @@ func TestCreateSetsFields(t *testing.T) {
} }
actual := &api.ResourceQuota{} actual := &api.ResourceQuota{}
if err := helper.ExtractObj("/registry/resourcequotas/default/foo", actual, false); err != nil { key, _ := storage.Etcd.KeyFunc(ctx, "foo")
if err := helper.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 {
...@@ -157,12 +160,16 @@ func TestListError(t *testing.T) { ...@@ -157,12 +160,16 @@ func TestListError(t *testing.T) {
func TestListEmptyResourceQuotaList(t *testing.T) { func TestListEmptyResourceQuotaList(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, helper := newHelper(t)
fakeEtcdClient.ChangeIndex = 1 fakeEtcdClient.ChangeIndex = 1
fakeEtcdClient.Data["/registry/resourcequotas"] = tools.EtcdResponseWithError{ storage, _ := NewStorage(helper)
ctx := api.NewContext()
key := storage.Etcd.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{}, R: &etcd.Response{},
E: fakeEtcdClient.NewError(tools.EtcdErrorCodeNotFound), E: fakeEtcdClient.NewError(tools.EtcdErrorCodeNotFound),
} }
storage, _ := NewStorage(helper)
resourcequotas, err := storage.List(api.NewContext(), labels.Everything(), fields.Everything()) resourcequotas, err := storage.List(api.NewContext(), labels.Everything(), fields.Everything())
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
...@@ -178,7 +185,11 @@ func TestListEmptyResourceQuotaList(t *testing.T) { ...@@ -178,7 +185,11 @@ func TestListEmptyResourceQuotaList(t *testing.T) {
func TestListResourceQuotaList(t *testing.T) { func TestListResourceQuotaList(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, helper := newHelper(t)
fakeEtcdClient.Data["/registry/resourcequotas/default"] = tools.EtcdResponseWithError{ storage, _ := NewStorage(helper)
ctx := api.NewDefaultContext()
key := storage.Etcd.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Nodes: []*etcd.Node{ Nodes: []*etcd.Node{
...@@ -196,7 +207,6 @@ func TestListResourceQuotaList(t *testing.T) { ...@@ -196,7 +207,6 @@ func TestListResourceQuotaList(t *testing.T) {
}, },
}, },
} }
storage, _ := NewStorage(helper)
resourcequotasObj, err := storage.List(api.NewDefaultContext(), labels.Everything(), fields.Everything()) resourcequotasObj, err := storage.List(api.NewDefaultContext(), labels.Everything(), fields.Everything())
resourcequotas := resourcequotasObj.(*api.ResourceQuotaList) resourcequotas := resourcequotasObj.(*api.ResourceQuotaList)
if err != nil { if err != nil {
...@@ -216,7 +226,11 @@ func TestListResourceQuotaList(t *testing.T) { ...@@ -216,7 +226,11 @@ func TestListResourceQuotaList(t *testing.T) {
func TestListResourceQuotaListSelection(t *testing.T) { func TestListResourceQuotaListSelection(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, helper := newHelper(t)
fakeEtcdClient.Data["/registry/resourcequotas/default"] = tools.EtcdResponseWithError{ storage, _ := NewStorage(helper)
ctx := api.NewDefaultContext()
key := storage.Etcd.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Nodes: []*etcd.Node{ Nodes: []*etcd.Node{
...@@ -236,8 +250,6 @@ func TestListResourceQuotaListSelection(t *testing.T) { ...@@ -236,8 +250,6 @@ func TestListResourceQuotaListSelection(t *testing.T) {
}, },
}, },
} }
storage, _ := NewStorage(helper)
ctx := api.NewDefaultContext()
table := []struct { table := []struct {
label, field string label, field string
...@@ -302,14 +314,16 @@ func TestResourceQuotaDecode(t *testing.T) { ...@@ -302,14 +314,16 @@ func TestResourceQuotaDecode(t *testing.T) {
func TestGet(t *testing.T) { func TestGet(t *testing.T) {
expect := validNewResourceQuota() expect := validNewResourceQuota()
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, helper := newHelper(t)
fakeEtcdClient.Data["/registry/resourcequotas/test/foo"] = tools.EtcdResponseWithError{ storage, _ := NewStorage(helper)
key := "/resourcequotas/test/foo"
key = etcdtest.AddPrefix(key)
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, expect), Value: runtime.EncodeOrDie(latest.Codec, expect),
}, },
}, },
} }
storage, _ := NewStorage(helper)
obj, err := storage.Get(api.WithNamespace(api.NewContext(), "test"), "foo") obj, err := storage.Get(api.WithNamespace(api.NewContext(), "test"), "foo")
resourcequota := obj.(*api.ResourceQuota) resourcequota := obj.(*api.ResourceQuota)
if err != nil { if err != nil {
...@@ -324,7 +338,11 @@ func TestGet(t *testing.T) { ...@@ -324,7 +338,11 @@ func TestGet(t *testing.T) {
func TestDeleteResourceQuota(t *testing.T) { func TestDeleteResourceQuota(t *testing.T) {
fakeEtcdClient, helper := newHelper(t) fakeEtcdClient, helper := newHelper(t)
fakeEtcdClient.ChangeIndex = 1 fakeEtcdClient.ChangeIndex = 1
fakeEtcdClient.Data["/registry/resourcequotas/default/foo"] = tools.EtcdResponseWithError{ storage, _ := NewStorage(helper)
ctx := api.NewDefaultContext()
key, _ := storage.Etcd.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, &api.ResourceQuota{ Value: runtime.EncodeOrDie(latest.Codec, &api.ResourceQuota{
...@@ -339,7 +357,6 @@ func TestDeleteResourceQuota(t *testing.T) { ...@@ -339,7 +357,6 @@ func TestDeleteResourceQuota(t *testing.T) {
}, },
}, },
} }
storage, _ := NewStorage(helper)
_, err := storage.Delete(api.NewDefaultContext(), "foo", nil) _, err := storage.Delete(api.NewDefaultContext(), "foo", nil)
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
...@@ -356,6 +373,9 @@ func TestEtcdGetDifferentNamespace(t *testing.T) { ...@@ -356,6 +373,9 @@ func TestEtcdGetDifferentNamespace(t *testing.T) {
key1, _ := registry.KeyFunc(ctx1, "foo") key1, _ := registry.KeyFunc(ctx1, "foo")
key2, _ := registry.KeyFunc(ctx2, "foo") key2, _ := registry.KeyFunc(ctx2, "foo")
key1 = etcdtest.AddPrefix(key1)
key2 = etcdtest.AddPrefix(key2)
fakeClient.Set(key1, runtime.EncodeOrDie(latest.Codec, &api.ResourceQuota{ObjectMeta: api.ObjectMeta{Namespace: "default", Name: "foo"}}), 0) fakeClient.Set(key1, runtime.EncodeOrDie(latest.Codec, &api.ResourceQuota{ObjectMeta: api.ObjectMeta{Namespace: "default", Name: "foo"}}), 0)
fakeClient.Set(key2, runtime.EncodeOrDie(latest.Codec, &api.ResourceQuota{ObjectMeta: api.ObjectMeta{Namespace: "other", Name: "foo"}}), 0) fakeClient.Set(key2, runtime.EncodeOrDie(latest.Codec, &api.ResourceQuota{ObjectMeta: api.ObjectMeta{Namespace: "other", Name: "foo"}}), 0)
...@@ -389,6 +409,7 @@ func TestEtcdGet(t *testing.T) { ...@@ -389,6 +409,7 @@ func TestEtcdGet(t *testing.T) {
registry, _, fakeClient, _ := newStorage(t) registry, _, fakeClient, _ := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
key, _ := registry.KeyFunc(ctx, "foo") key, _ := registry.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.ResourceQuota{ObjectMeta: api.ObjectMeta{Name: "foo"}}), 0) fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.ResourceQuota{ObjectMeta: api.ObjectMeta{Name: "foo"}}), 0)
obj, err := registry.Get(ctx, "foo") obj, err := registry.Get(ctx, "foo")
if err != nil { if err != nil {
...@@ -404,6 +425,7 @@ func TestEtcdGetNotFound(t *testing.T) { ...@@ -404,6 +425,7 @@ func TestEtcdGetNotFound(t *testing.T) {
registry, _, fakeClient, _ := newStorage(t) registry, _, fakeClient, _ := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
key, _ := registry.KeyFunc(ctx, "foo") key, _ := registry.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: nil, Node: nil,
...@@ -432,6 +454,7 @@ func TestEtcdCreateAlreadyExisting(t *testing.T) { ...@@ -432,6 +454,7 @@ func TestEtcdCreateAlreadyExisting(t *testing.T) {
registry, _, fakeClient, _ := newStorage(t) registry, _, fakeClient, _ := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
key, _ := registry.KeyFunc(ctx, "foo") key, _ := registry.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
...@@ -452,6 +475,7 @@ func TestEtcdUpdateStatus(t *testing.T) { ...@@ -452,6 +475,7 @@ func TestEtcdUpdateStatus(t *testing.T) {
fakeClient.TestIndex = true fakeClient.TestIndex = true
key, _ := registry.KeyFunc(ctx, "foo") key, _ := registry.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
resourcequotaStart := validNewResourceQuota() resourcequotaStart := validNewResourceQuota()
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, resourcequotaStart), 1) fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, resourcequotaStart), 1)
...@@ -491,6 +515,7 @@ func TestEtcdUpdateStatus(t *testing.T) { ...@@ -491,6 +515,7 @@ func TestEtcdUpdateStatus(t *testing.T) {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
var resourcequotaOut api.ResourceQuota var resourcequotaOut api.ResourceQuota
key, _ = registry.KeyFunc(ctx, "foo")
if err := helper.ExtractObj(key, &resourcequotaOut, false); err != nil { if err := helper.ExtractObj(key, &resourcequotaOut, false); err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
...@@ -503,6 +528,7 @@ func TestEtcdEmptyList(t *testing.T) { ...@@ -503,6 +528,7 @@ func TestEtcdEmptyList(t *testing.T) {
registry, _, fakeClient, _ := newStorage(t) registry, _, fakeClient, _ := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
key := registry.KeyRootFunc(ctx) key := registry.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
...@@ -526,6 +552,7 @@ func TestEtcdListNotFound(t *testing.T) { ...@@ -526,6 +552,7 @@ func TestEtcdListNotFound(t *testing.T) {
registry, _, fakeClient, _ := newStorage(t) registry, _, fakeClient, _ := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
key := registry.KeyRootFunc(ctx) key := registry.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{}, R: &etcd.Response{},
E: tools.EtcdErrorNotFound, E: tools.EtcdErrorNotFound,
...@@ -544,6 +571,7 @@ func TestEtcdList(t *testing.T) { ...@@ -544,6 +571,7 @@ func TestEtcdList(t *testing.T) {
registry, _, fakeClient, _ := newStorage(t) registry, _, fakeClient, _ := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
key := registry.KeyRootFunc(ctx) key := registry.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
......
...@@ -31,16 +31,17 @@ type registry struct { ...@@ -31,16 +31,17 @@ type registry struct {
// NewEtcdRegistry returns a registry which will store Secret in the given helper // NewEtcdRegistry returns a registry which will store Secret in the given helper
func NewEtcdRegistry(h tools.EtcdHelper) generic.Registry { func NewEtcdRegistry(h tools.EtcdHelper) generic.Registry {
prefix := "/secrets"
return registry{ return registry{
Etcd: &etcdgeneric.Etcd{ Etcd: &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.Secret{} }, NewFunc: func() runtime.Object { return &api.Secret{} },
NewListFunc: func() runtime.Object { return &api.SecretList{} }, NewListFunc: func() runtime.Object { return &api.SecretList{} },
EndpointName: "secrets", EndpointName: "secrets",
KeyRootFunc: func(ctx api.Context) string { KeyRootFunc: func(ctx api.Context) string {
return etcdgeneric.NamespaceKeyRootFunc(ctx, "/registry/secrets") return etcdgeneric.NamespaceKeyRootFunc(ctx, prefix)
}, },
KeyFunc: func(ctx api.Context, id string) (string, error) { KeyFunc: func(ctx api.Context, id string) (string, error) {
return etcdgeneric.NamespaceKeyFunc(ctx, "/registry/secrets", id) return etcdgeneric.NamespaceKeyFunc(ctx, prefix, id)
}, },
Helper: h, Helper: h,
}, },
......
...@@ -27,6 +27,7 @@ import ( ...@@ -27,6 +27,7 @@ import (
etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd" etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/coreos/go-etcd/etcd" "github.com/coreos/go-etcd/etcd"
...@@ -35,7 +36,7 @@ import ( ...@@ -35,7 +36,7 @@ import (
func NewTestSecretEtcdRegistry(t *testing.T) (*tools.FakeEtcdClient, generic.Registry) { func NewTestSecretEtcdRegistry(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()) h := tools.NewEtcdHelper(f, testapi.Codec(), etcdtest.PathPrefix())
return f, NewEtcdRegistry(h) return f, NewEtcdRegistry(h)
} }
...@@ -65,10 +66,11 @@ func TestSecretCreate(t *testing.T) { ...@@ -65,10 +66,11 @@ func TestSecretCreate(t *testing.T) {
R: &etcd.Response{}, R: &etcd.Response{},
E: tools.EtcdErrorNotFound, E: tools.EtcdErrorNotFound,
} }
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
key := "foo" key := "foo"
path, err := etcdgeneric.NamespaceKeyFunc(ctx, "/registry/secrets", key) path, err := etcdgeneric.NamespaceKeyFunc(ctx, "/secrets", key)
path = etcdtest.AddPrefix(path)
if err != nil { if err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
} }
......
...@@ -23,7 +23,9 @@ import ( ...@@ -23,7 +23,9 @@ import (
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"os/exec" "os/exec"
"path"
"reflect" "reflect"
"strings"
"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion" "github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
...@@ -38,15 +40,18 @@ type EtcdHelper struct { ...@@ -38,15 +40,18 @@ type EtcdHelper struct {
Codec runtime.Codec Codec runtime.Codec
// optional, no atomic operations can be performed without this interface // optional, no atomic operations can be performed without this interface
Versioner EtcdVersioner Versioner EtcdVersioner
// prefix for all etcd keys
PathPrefix string
} }
// NewEtcdHelper creates a helper that works against objects that use the internal // NewEtcdHelper creates a helper that works against objects that use the internal
// Kubernetes API objects. // Kubernetes API objects.
func NewEtcdHelper(client EtcdGetSet, codec runtime.Codec) EtcdHelper { func NewEtcdHelper(client EtcdGetSet, codec runtime.Codec, prefix string) EtcdHelper {
return EtcdHelper{ return EtcdHelper{
Client: client, Client: client,
Codec: codec, Codec: codec,
Versioner: APIObjectVersioner{}, Versioner: APIObjectVersioner{},
PathPrefix: prefix,
} }
} }
...@@ -136,6 +141,7 @@ func (h *EtcdHelper) ExtractToList(key string, listObj runtime.Object) error { ...@@ -136,6 +141,7 @@ func (h *EtcdHelper) ExtractToList(key string, listObj runtime.Object) error {
if err != nil { if err != nil {
return err return err
} }
key = h.PrefixEtcdKey(key)
nodes, index, err := h.listEtcdNode(key) nodes, index, err := h.listEtcdNode(key)
if err != nil { if err != nil {
return err return err
...@@ -158,7 +164,7 @@ func (h *EtcdHelper) ExtractObjToList(key string, listObj runtime.Object) error ...@@ -158,7 +164,7 @@ func (h *EtcdHelper) ExtractObjToList(key string, listObj runtime.Object) error
if err != nil { if err != nil {
return err return err
} }
key = h.PrefixEtcdKey(key)
response, err := h.Client.Get(key, false, false) response, err := h.Client.Get(key, false, false)
if err != nil { if err != nil {
if IsEtcdNotFound(err) { if IsEtcdNotFound(err) {
...@@ -185,6 +191,7 @@ func (h *EtcdHelper) ExtractObjToList(key string, listObj runtime.Object) error ...@@ -185,6 +191,7 @@ func (h *EtcdHelper) ExtractObjToList(key string, listObj runtime.Object) error
// a zero object of the requested type, or an error, depending on ignoreNotFound. Treats // a zero object of the requested type, or an error, depending on ignoreNotFound. Treats
// empty responses and nil response nodes exactly like a not found error. // empty responses and nil response nodes exactly like a not found error.
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)
_, _, err := h.bodyAndExtractObj(key, objPtr, ignoreNotFound) _, _, err := h.bodyAndExtractObj(key, objPtr, ignoreNotFound)
return err return err
} }
...@@ -233,6 +240,7 @@ func (h *EtcdHelper) extractObj(response *etcd.Response, inErr error, objPtr run ...@@ -233,6 +240,7 @@ func (h *EtcdHelper) extractObj(response *etcd.Response, inErr error, objPtr run
// and 0 means forever. If no error is returned and out is not nil, out will be set to the read value // and 0 means forever. If no error is returned and out is not nil, out will be set to the read value
// from etcd. // from etcd.
func (h *EtcdHelper) CreateObj(key string, obj, out runtime.Object, ttl uint64) error { func (h *EtcdHelper) CreateObj(key string, obj, out runtime.Object, ttl uint64) error {
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
...@@ -242,6 +250,7 @@ func (h *EtcdHelper) CreateObj(key string, obj, out runtime.Object, ttl uint64) ...@@ -242,6 +250,7 @@ func (h *EtcdHelper) CreateObj(key string, obj, out runtime.Object, ttl uint64)
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")
} }
} }
response, err := h.Client.Create(key, string(data), ttl) response, err := h.Client.Create(key, string(data), ttl)
if err != nil { if err != nil {
return err return err
...@@ -257,15 +266,18 @@ func (h *EtcdHelper) CreateObj(key string, obj, out runtime.Object, ttl uint64) ...@@ -257,15 +266,18 @@ func (h *EtcdHelper) CreateObj(key string, obj, out runtime.Object, ttl uint64)
// Delete removes the specified key. // Delete removes the specified key.
func (h *EtcdHelper) Delete(key string, recursive bool) error { func (h *EtcdHelper) Delete(key string, recursive bool) error {
key = h.PrefixEtcdKey(key)
_, err := h.Client.Delete(key, recursive) _, err := h.Client.Delete(key, recursive)
return err return err
} }
// DeleteObj removes the specified key and returns the value that existed at that spot. // DeleteObj removes the specified key and returns the value that existed at that spot.
func (h *EtcdHelper) DeleteObj(key string, out runtime.Object) error { func (h *EtcdHelper) DeleteObj(key string, out runtime.Object) error {
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")
} }
response, err := h.Client.Delete(key, false) response, err := h.Client.Delete(key, false)
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.
...@@ -285,6 +297,7 @@ func (h *EtcdHelper) SetObj(key string, obj, out runtime.Object, ttl uint64) err ...@@ -285,6 +297,7 @@ func (h *EtcdHelper) SetObj(key string, obj, out runtime.Object, ttl uint64) err
if err != nil { if err != nil {
return err return err
} }
key = h.PrefixEtcdKey(key)
create := true create := true
if h.Versioner != nil { if h.Versioner != nil {
...@@ -346,6 +359,7 @@ func (h *EtcdHelper) GuaranteedUpdate(key string, ptrToType runtime.Object, igno ...@@ -346,6 +359,7 @@ func (h *EtcdHelper) GuaranteedUpdate(key string, ptrToType runtime.Object, igno
// Panic is appropriate, because this is a programming error. // Panic is appropriate, because this is a programming error.
panic("need ptr to type") panic("need ptr to type")
} }
key = h.PrefixEtcdKey(key)
for { for {
obj := reflect.New(v.Type()).Interface().(runtime.Object) obj := reflect.New(v.Type()).Interface().(runtime.Object)
origBody, index, err := h.bodyAndExtractObj(key, obj, ignoreNotFound) origBody, index, err := h.bodyAndExtractObj(key, obj, ignoreNotFound)
...@@ -386,6 +400,13 @@ func (h *EtcdHelper) GuaranteedUpdate(key string, ptrToType runtime.Object, igno ...@@ -386,6 +400,13 @@ func (h *EtcdHelper) GuaranteedUpdate(key string, ptrToType runtime.Object, igno
} }
} }
func (h *EtcdHelper) PrefixEtcdKey(key string) string {
if strings.HasPrefix(key, path.Join("/", h.PathPrefix)) {
return key
}
return path.Join("/", h.PathPrefix, key)
}
// GetEtcdVersion performs a version check against the provided Etcd server, returning a triplet // GetEtcdVersion performs a version check against the provided Etcd server, returning a triplet
// of the release version, internal version, and error (if any). // of the release version, internal version, and error (if any).
func GetEtcdVersion(host string) (releaseVersion, internalVersion string, err error) { func GetEtcdVersion(host string) (releaseVersion, internalVersion string, err error) {
......
...@@ -71,6 +71,7 @@ func ParseWatchResourceVersion(resourceVersion, kind string) (uint64, error) { ...@@ -71,6 +71,7 @@ func ParseWatchResourceVersion(resourceVersion, kind string) (uint64, error) {
// 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)
w := newEtcdWatcher(true, exceptKey(key), filter, h.Codec, h.Versioner, nil) w := newEtcdWatcher(true, exceptKey(key), filter, h.Codec, h.Versioner, nil)
go w.etcdWatch(h.Client, key, resourceVersion) go w.etcdWatch(h.Client, key, resourceVersion)
return w, nil return w, nil
...@@ -80,6 +81,7 @@ func (h *EtcdHelper) WatchList(key string, resourceVersion uint64, filter Filter ...@@ -80,6 +81,7 @@ func (h *EtcdHelper) WatchList(key string, resourceVersion uint64, filter Filter
// 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)
w := newEtcdWatcher(false, nil, filter, h.Codec, h.Versioner, nil) w := newEtcdWatcher(false, nil, filter, h.Codec, h.Versioner, nil)
go w.etcdWatch(h.Client, key, resourceVersion) go w.etcdWatch(h.Client, key, resourceVersion)
return w, nil return w, nil
...@@ -102,6 +104,7 @@ func (h *EtcdHelper) Watch(key string, resourceVersion uint64, filter FilterFunc ...@@ -102,6 +104,7 @@ func (h *EtcdHelper) Watch(key string, resourceVersion uint64, filter FilterFunc
// //
// Errors will be sent down the channel. // Errors will be sent down the channel.
func (h *EtcdHelper) WatchAndTransform(key string, resourceVersion uint64, transform TransformFunc) watch.Interface { 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) w := newEtcdWatcher(false, nil, Everything, h.Codec, h.Versioner, transform)
go w.etcdWatch(h.Client, key, resourceVersion) go w.etcdWatch(h.Client, key, resourceVersion)
return w return w
......
...@@ -25,6 +25,7 @@ import ( ...@@ -25,6 +25,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
"github.com/coreos/go-etcd/etcd" "github.com/coreos/go-etcd/etcd"
) )
...@@ -205,7 +206,7 @@ func TestWatchEtcdError(t *testing.T) { ...@@ -205,7 +206,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 := EtcdHelper{fakeClient, codec, versioner} h := EtcdHelper{fakeClient, codec, versioner, etcdtest.PathPrefix()}
watching, err := h.Watch("/some/key", 4, Everything) watching, err := h.Watch("/some/key", 4, Everything)
if err != nil { if err != nil {
...@@ -232,10 +233,12 @@ func TestWatchEtcdError(t *testing.T) { ...@@ -232,10 +233,12 @@ func TestWatchEtcdError(t *testing.T) {
func TestWatch(t *testing.T) { func TestWatch(t *testing.T) {
codec := latest.Codec codec := latest.Codec
fakeClient := NewFakeEtcdClient(t) fakeClient := NewFakeEtcdClient(t)
fakeClient.expectNotFoundGetSet["/some/key"] = struct{}{} key := "/some/key"
h := EtcdHelper{fakeClient, codec, versioner} prefixedKey := etcdtest.AddPrefix(key)
fakeClient.expectNotFoundGetSet[prefixedKey] = struct{}{}
h := EtcdHelper{fakeClient, codec, versioner, etcdtest.PathPrefix()}
watching, err := h.Watch("/some/key", 0, Everything) watching, err := h.Watch(key, 0, Everything)
if err != nil { if err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
...@@ -300,6 +303,8 @@ func makeSubsets(ip string, port int) []api.EndpointSubset { ...@@ -300,6 +303,8 @@ func makeSubsets(ip string, port int) []api.EndpointSubset {
func TestWatchEtcdState(t *testing.T) { func TestWatchEtcdState(t *testing.T) {
codec := latest.Codec codec := latest.Codec
baseKey := "/somekey/foo"
prefixedKey := etcdtest.AddPrefix(baseKey)
type T struct { type T struct {
Type watch.EventType Type watch.EventType
Endpoints []api.EndpointSubset Endpoints []api.EndpointSubset
...@@ -357,7 +362,7 @@ func TestWatchEtcdState(t *testing.T) { ...@@ -357,7 +362,7 @@ func TestWatchEtcdState(t *testing.T) {
}, },
"from initial state": { "from initial state": {
Initial: map[string]EtcdResponseWithError{ Initial: map[string]EtcdResponseWithError{
"/somekey/foo": { prefixedKey: {
R: &etcd.Response{ R: &etcd.Response{
Action: "get", Action: "get",
Node: &etcd.Node{ Node: &etcd.Node{
...@@ -406,8 +411,9 @@ func TestWatchEtcdState(t *testing.T) { ...@@ -406,8 +411,9 @@ func TestWatchEtcdState(t *testing.T) {
for key, value := range testCase.Initial { for key, value := range testCase.Initial {
fakeClient.Data[key] = value fakeClient.Data[key] = value
} }
h := EtcdHelper{fakeClient, codec, versioner}
watching, err := h.Watch("/somekey/foo", testCase.From, Everything) h := EtcdHelper{fakeClient, codec, versioner, etcdtest.PathPrefix()}
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)
} }
...@@ -476,10 +482,12 @@ func TestWatchFromZeroIndex(t *testing.T) { ...@@ -476,10 +482,12 @@ func TestWatchFromZeroIndex(t *testing.T) {
for k, testCase := range testCases { for k, testCase := range testCases {
fakeClient := NewFakeEtcdClient(t) fakeClient := NewFakeEtcdClient(t)
fakeClient.Data["/some/key"] = testCase.Response key := "/some/key"
h := EtcdHelper{fakeClient, codec, versioner} prefixedKey := etcdtest.AddPrefix(key)
fakeClient.Data[prefixedKey] = testCase.Response
h := EtcdHelper{fakeClient, codec, versioner, etcdtest.PathPrefix()}
watching, err := h.Watch("/some/key", 0, Everything) watching, err := h.Watch(key, 0, Everything)
if err != nil { if err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
...@@ -512,9 +520,10 @@ func TestWatchFromZeroIndex(t *testing.T) { ...@@ -512,9 +520,10 @@ func TestWatchFromZeroIndex(t *testing.T) {
func TestWatchListFromZeroIndex(t *testing.T) { func TestWatchListFromZeroIndex(t *testing.T) {
codec := latest.Codec codec := latest.Codec
pod := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}} pod := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}
key := "/some/key"
prefixedKey := etcdtest.AddPrefix(key)
fakeClient := NewFakeEtcdClient(t) fakeClient := NewFakeEtcdClient(t)
fakeClient.Data["/some/key"] = EtcdResponseWithError{ fakeClient.Data[prefixedKey] = EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Dir: true, Dir: true,
...@@ -537,9 +546,9 @@ func TestWatchListFromZeroIndex(t *testing.T) { ...@@ -537,9 +546,9 @@ func TestWatchListFromZeroIndex(t *testing.T) {
EtcdIndex: 3, EtcdIndex: 3,
}, },
} }
h := EtcdHelper{fakeClient, codec, versioner} h := EtcdHelper{fakeClient, codec, versioner, etcdtest.PathPrefix()}
watching, err := h.WatchList("/some/key", 0, Everything) watching, err := h.WatchList(key, 0, Everything)
if err != nil { if err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
...@@ -573,11 +582,13 @@ func TestWatchListFromZeroIndex(t *testing.T) { ...@@ -573,11 +582,13 @@ func TestWatchListFromZeroIndex(t *testing.T) {
func TestWatchListIgnoresRootKey(t *testing.T) { func TestWatchListIgnoresRootKey(t *testing.T) {
codec := latest.Codec codec := latest.Codec
pod := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}} pod := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}
key := "/some/key"
prefixedKey := etcdtest.AddPrefix(key)
fakeClient := NewFakeEtcdClient(t) fakeClient := NewFakeEtcdClient(t)
h := EtcdHelper{fakeClient, codec, versioner} h := EtcdHelper{fakeClient, codec, versioner, etcdtest.PathPrefix()}
watching, err := h.WatchList("/some/key", 1, Everything) watching, err := h.WatchList(key, 1, Everything)
if err != nil { if err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
...@@ -587,7 +598,7 @@ func TestWatchListIgnoresRootKey(t *testing.T) { ...@@ -587,7 +598,7 @@ func TestWatchListIgnoresRootKey(t *testing.T) {
fakeClient.WatchResponse <- &etcd.Response{ fakeClient.WatchResponse <- &etcd.Response{
Action: "delete", Action: "delete",
PrevNode: &etcd.Node{ PrevNode: &etcd.Node{
Key: "/some/key", Key: prefixedKey,
Value: runtime.EncodeOrDie(codec, pod), Value: runtime.EncodeOrDie(codec, pod),
CreatedIndex: 1, CreatedIndex: 1,
ModifiedIndex: 1, ModifiedIndex: 1,
...@@ -598,7 +609,7 @@ func TestWatchListIgnoresRootKey(t *testing.T) { ...@@ -598,7 +609,7 @@ func TestWatchListIgnoresRootKey(t *testing.T) {
fakeClient.WatchResponse <- &etcd.Response{ fakeClient.WatchResponse <- &etcd.Response{
Action: "delete", Action: "delete",
PrevNode: &etcd.Node{ PrevNode: &etcd.Node{
Key: "/some/key", Key: prefixedKey,
Value: "", Value: "",
CreatedIndex: 1, CreatedIndex: 1,
ModifiedIndex: 1, ModifiedIndex: 1,
...@@ -617,7 +628,9 @@ func TestWatchListIgnoresRootKey(t *testing.T) { ...@@ -617,7 +628,9 @@ func TestWatchListIgnoresRootKey(t *testing.T) {
func TestWatchFromNotFound(t *testing.T) { func TestWatchFromNotFound(t *testing.T) {
fakeClient := NewFakeEtcdClient(t) fakeClient := NewFakeEtcdClient(t)
fakeClient.Data["/some/key"] = EtcdResponseWithError{ key := "/some/key"
prefixedKey := etcdtest.AddPrefix(key)
fakeClient.Data[prefixedKey] = EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: nil, Node: nil,
}, },
...@@ -626,13 +639,12 @@ func TestWatchFromNotFound(t *testing.T) { ...@@ -626,13 +639,12 @@ func TestWatchFromNotFound(t *testing.T) {
ErrorCode: 100, ErrorCode: 100,
}, },
} }
h := EtcdHelper{fakeClient, codec, versioner} h := EtcdHelper{fakeClient, codec, versioner, etcdtest.PathPrefix()}
watching, err := h.Watch("/some/key", 0, Everything) watching, err := h.Watch(key, 0, Everything)
if err != nil { if err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
fakeClient.WaitForWatchCompletion() fakeClient.WaitForWatchCompletion()
if fakeClient.WatchIndex != 3 { if fakeClient.WatchIndex != 3 {
t.Errorf("Expected client to wait for %d, got %#v", 3, fakeClient) t.Errorf("Expected client to wait for %d, got %#v", 3, fakeClient)
...@@ -643,7 +655,9 @@ func TestWatchFromNotFound(t *testing.T) { ...@@ -643,7 +655,9 @@ func TestWatchFromNotFound(t *testing.T) {
func TestWatchFromOtherError(t *testing.T) { func TestWatchFromOtherError(t *testing.T) {
fakeClient := NewFakeEtcdClient(t) fakeClient := NewFakeEtcdClient(t)
fakeClient.Data["/some/key"] = EtcdResponseWithError{ key := "/some/key"
prefixedKey := etcdtest.AddPrefix(key)
fakeClient.Data[prefixedKey] = EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: nil, Node: nil,
}, },
...@@ -652,9 +666,8 @@ func TestWatchFromOtherError(t *testing.T) { ...@@ -652,9 +666,8 @@ func TestWatchFromOtherError(t *testing.T) {
ErrorCode: 101, ErrorCode: 101,
}, },
} }
h := EtcdHelper{fakeClient, codec, versioner} h := EtcdHelper{fakeClient, codec, versioner, etcdtest.PathPrefix()}
watching, err := h.Watch(key, 0, Everything)
watching, err := h.Watch("/some/key", 0, Everything)
if err != nil { if err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
...@@ -683,11 +696,13 @@ func TestWatchFromOtherError(t *testing.T) { ...@@ -683,11 +696,13 @@ func TestWatchFromOtherError(t *testing.T) {
func TestWatchPurposefulShutdown(t *testing.T) { func TestWatchPurposefulShutdown(t *testing.T) {
fakeClient := NewFakeEtcdClient(t) fakeClient := NewFakeEtcdClient(t)
h := EtcdHelper{fakeClient, codec, versioner} h := EtcdHelper{fakeClient, codec, versioner, etcdtest.PathPrefix()}
fakeClient.expectNotFoundGetSet["/some/key"] = struct{}{} key := "/some/key"
prefixedKey := etcdtest.AddPrefix(key)
fakeClient.expectNotFoundGetSet[prefixedKey] = struct{}{}
// Test purposeful shutdown // Test purposeful shutdown
watching, err := h.Watch("/some/key", 0, Everything) watching, err := h.Watch(key, 0, Everything)
if err != nil { if err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
......
/*
Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package etcdtest
/*
Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package etcdtest
import (
"os"
"path"
)
// Returns the prefix set via the ETCD_PREFIX environment variable (if any).
func PathPrefix() string {
return path.Join("/", os.Getenv("ETCD_PREFIX"))
}
// Adds the ETCD_PREFIX to the provided key
func AddPrefix(in string) string {
return path.Join(PathPrefix(), in)
}
...@@ -46,6 +46,7 @@ import ( ...@@ -46,6 +46,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/auth/user" "github.com/GoogleCloudPlatform/kubernetes/pkg/auth/user"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/master" "github.com/GoogleCloudPlatform/kubernetes/pkg/master"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/admit" "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/admit"
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/auth/authenticator/token/tokentest" "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/auth/authenticator/token/tokentest"
) )
...@@ -377,7 +378,7 @@ func TestAuthModeAlwaysAllow(t *testing.T) { ...@@ -377,7 +378,7 @@ func TestAuthModeAlwaysAllow(t *testing.T) {
// Set up a master // Set up a master
helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version()) helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version(), etcdtest.PathPrefix())
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
...@@ -516,8 +517,7 @@ func TestAuthModeAlwaysDeny(t *testing.T) { ...@@ -516,8 +517,7 @@ func TestAuthModeAlwaysDeny(t *testing.T) {
deleteAllEtcdKeys() deleteAllEtcdKeys()
// Set up a master // Set up a master
helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version(), etcdtest.PathPrefix())
helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version())
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
...@@ -583,8 +583,7 @@ func TestAliceNotForbiddenOrUnauthorized(t *testing.T) { ...@@ -583,8 +583,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 := master.NewEtcdHelper(newEtcdClient(), testapi.Version(), etcdtest.PathPrefix())
helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version())
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
...@@ -672,8 +671,7 @@ func TestBobIsForbidden(t *testing.T) { ...@@ -672,8 +671,7 @@ func TestBobIsForbidden(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 := master.NewEtcdHelper(newEtcdClient(), testapi.Version(), etcdtest.PathPrefix())
helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version())
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
...@@ -733,8 +731,7 @@ func TestUnknownUserIsUnauthorized(t *testing.T) { ...@@ -733,8 +731,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 := master.NewEtcdHelper(newEtcdClient(), testapi.Version(), etcdtest.PathPrefix())
helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version())
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
...@@ -810,8 +807,7 @@ func TestNamespaceAuthorization(t *testing.T) { ...@@ -810,8 +807,7 @@ func TestNamespaceAuthorization(t *testing.T) {
deleteAllEtcdKeys() deleteAllEtcdKeys()
// This file has alice and bob in it. // This file has alice and bob in it.
helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version(), etcdtest.PathPrefix())
helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version())
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
...@@ -925,8 +921,7 @@ func TestKindAuthorization(t *testing.T) { ...@@ -925,8 +921,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 := master.NewEtcdHelper(newEtcdClient(), testapi.Version(), etcdtest.PathPrefix())
helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version())
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
...@@ -1028,8 +1023,7 @@ func TestReadOnlyAuthorization(t *testing.T) { ...@@ -1028,8 +1023,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 := master.NewEtcdHelper(newEtcdClient(), testapi.Version(), etcdtest.PathPrefix())
helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version())
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
......
...@@ -26,6 +26,7 @@ import ( ...@@ -26,6 +26,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
) )
...@@ -92,8 +93,9 @@ func TestExtractObj(t *testing.T) { ...@@ -92,8 +93,9 @@ func TestExtractObj(t *testing.T) {
func TestWatch(t *testing.T) { func TestWatch(t *testing.T) {
client := newEtcdClient() client := newEtcdClient()
helper := tools.NewEtcdHelper(client, testapi.Codec()) helper := tools.NewEtcdHelper(client, testapi.Codec(), etcdtest.PathPrefix())
withEtcdKey(func(key string) { withEtcdKey(func(key string) {
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)
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
......
...@@ -33,6 +33,7 @@ import ( ...@@ -33,6 +33,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/record" "github.com/GoogleCloudPlatform/kubernetes/pkg/client/record"
"github.com/GoogleCloudPlatform/kubernetes/pkg/master" "github.com/GoogleCloudPlatform/kubernetes/pkg/master"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/wait" "github.com/GoogleCloudPlatform/kubernetes/pkg/util/wait"
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/admit" "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/admit"
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler" "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler"
...@@ -45,7 +46,7 @@ func init() { ...@@ -45,7 +46,7 @@ func init() {
} }
func TestUnschedulableNodes(t *testing.T) { func TestUnschedulableNodes(t *testing.T) {
helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version()) helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version(), etcdtest.PathPrefix())
if err != nil { if err != nil {
t.Fatalf("Couldn't create etcd helper: %v", err) t.Fatalf("Couldn't create etcd helper: %v", err)
} }
......
...@@ -30,6 +30,7 @@ import ( ...@@ -30,6 +30,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver" "github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/master" "github.com/GoogleCloudPlatform/kubernetes/pkg/master"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/admit" "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/admit"
) )
...@@ -50,7 +51,7 @@ func deleteSecretOrErrorf(t *testing.T, c *client.Client, ns, name string) { ...@@ -50,7 +51,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 := master.NewEtcdHelper(newEtcdClient(), testapi.Version()) helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version(), etcdtest.PathPrefix())
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
......
...@@ -29,6 +29,7 @@ import ( ...@@ -29,6 +29,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver" "github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/master" "github.com/GoogleCloudPlatform/kubernetes/pkg/master"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/admit" "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/admit"
"github.com/coreos/go-etcd/etcd" "github.com/coreos/go-etcd/etcd"
...@@ -66,7 +67,7 @@ func deleteAllEtcdKeys() { ...@@ -66,7 +67,7 @@ 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()) helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version(), etcdtest.PathPrefix())
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment