Merge pull request #5707 from endocode/kbeecher/etcd_prefix

Adds ability to define a prefix for etcd paths
pull/6/head
Daniel Smith 2015-04-27 13:37:43 -07:00
commit 83093af8b0
45 changed files with 562 additions and 227 deletions

View File

@ -51,6 +51,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/master"
"github.com/GoogleCloudPlatform/kubernetes/pkg/probe"
"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/wait"
"github.com/GoogleCloudPlatform/kubernetes/pkg/volume/empty_dir"
@ -160,7 +161,7 @@ func startComponents(firstManifestURL, secondManifestURL, apiVersion string) (st
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 {
glog.Fatalf("Unable to get etcd helper: %v", err)
}

View File

@ -71,6 +71,7 @@ type APIServer struct {
AdmissionControlConfigFile string
EtcdServerList util.StringList
EtcdConfigFile string
EtcdPathPrefix string
CorsAllowedOriginList util.StringList
AllowPrivileged bool
PortalNet util.IPNet // TODO: make this a list
@ -98,6 +99,7 @@ func NewAPIServer() *APIServer {
EventTTL: 1 * time.Hour,
AuthorizationMode: "AlwaysAllow",
AdmissionControl: "AlwaysAdmit",
EtcdPathPrefix: master.DefaultEtcdPathPrefix,
EnableLogsSupport: true,
MasterServiceNamespace: api.NamespaceDefault,
ClusterName: "kubernetes",
@ -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.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.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.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.")
@ -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
if etcdConfigFile != "" {
client, err = etcd.NewClientFromFile(etcdConfigFile)
@ -192,7 +195,7 @@ func newEtcd(etcdConfigFile string, etcdServerList util.StringList, storageVersi
client = etcd.NewClient(etcdServerList)
}
return master.NewEtcdHelper(client, storageVersion)
return master.NewEtcdHelper(client, storageVersion, pathPrefix)
}
// Run runs the specified APIServer. This should never exit.
@ -232,7 +235,7 @@ func (s *APIServer) Run(_ []string) error {
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 {
glog.Fatalf("Invalid storage version or misconfigured etcd: %v", err)
}

View File

@ -82,7 +82,7 @@ func (h *delegateHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
func runApiServer(etcdClient tools.EtcdClient, addr net.IP, port int, masterServiceNamespace string) {
handler := delegateHandler{}
helper, err := master.NewEtcdHelper(etcdClient, "")
helper, err := master.NewEtcdHelper(etcdClient, "", master.DefaultEtcdPathPrefix)
if err != nil {
glog.Fatalf("Unable to get etcd helper: %v", err)
}

View File

@ -53,6 +53,9 @@ KUBE_RACE=${KUBE_RACE:-} # use KUBE_RACE="-race" to enable race testing
KUBE_GOVERALLS_BIN=${KUBE_GOVERALLS_BIN:-}
# Comma separated list of API Versions that should be tested.
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::log::usage_from_stdin <<EOF
@ -203,10 +206,13 @@ reportCoverageToCoveralls() {
# Convert the CSV to an array of API versions to test
IFS=',' read -a apiVersions <<< "${KUBE_TEST_API_VERSIONS}"
ETCD_PREFIX=${ETCD_STANDARD_PREFIX}
for apiVersion in "${apiVersions[@]}"; do
echo "Running tests for APIVersion: $apiVersion"
KUBE_API_VERSION="${apiVersion}" runTests "$@"
KUBE_API_VERSION="${apiVersion}" ETCD_PREFIX=${ETCD_STANDARD_PREFIX} runTests "$@"
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
# one of them to coveralls. Here we report coverage from the last run.

View File

@ -271,7 +271,6 @@ func (t *Tester) TestDeleteNoGraceful(createFn func() runtime.Object, wasGracefu
if err != nil {
t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, existing)
}
ctx := api.WithNamespace(api.NewContext(), objectMeta.Namespace)
_, err = t.storage.(rest.GracefulDeleter).Delete(ctx, objectMeta.Name, api.NewDeleteOptions(10))
if err != nil {

View File

@ -71,6 +71,10 @@ import (
"github.com/golang/glog"
)
const (
DefaultEtcdPathPrefix = "/registry"
)
// Config is a structure used to configure a Master.
type Config struct {
EtcdHelper tools.EtcdHelper
@ -178,7 +182,7 @@ type Master struct {
// NewEtcdHelper returns an EtcdHelper for the provided arguments or an error if the version
// 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 == "" {
version = latest.Version
}
@ -186,7 +190,7 @@ func NewEtcdHelper(client tools.EtcdGetSet, version string) (helper tools.EtcdHe
if err != nil {
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.
@ -363,7 +367,7 @@ func logStackOnRecover(panicReason interface{}, httpWriter http.ResponseWriter)
func (m *Master) init(c *Config) {
// 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.
newerHelper, err := NewEtcdHelper(c.EtcdHelper.Client, "v1beta3")
newerHelper, err := NewEtcdHelper(c.EtcdHelper.Client, "v1beta3", DefaultEtcdPathPrefix)
if err != nil {
glog.Fatalf("Unable to setup storage for v1beta3: %v", err)
}

View File

@ -23,6 +23,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
)
func TestGetServersToValidate(t *testing.T) {
@ -30,7 +31,7 @@ func TestGetServersToValidate(t *testing.T) {
config := Config{}
fakeClient := tools.NewFakeEtcdClient(t)
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{})

View File

@ -34,7 +34,7 @@ type REST struct {
// controllerPrefix is the location for controllers in etcd, only exposed
// for testing
var controllerPrefix = "/registry/controllers"
var controllerPrefix = "/controllers"
// NewREST returns a RESTStorage object that will work against replication controllers.
func NewREST(h tools.EtcdHelper) *REST {

View File

@ -31,6 +31,7 @@ import (
etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/coreos/go-etcd/etcd"
)
@ -39,11 +40,16 @@ const (
FAIL
)
// newStorage creates a REST storage backed by etcd helpers
func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
func newHelper(t *testing.T) (*tools.FakeEtcdClient, tools.EtcdHelper) {
fakeEtcdClient := tools.NewFakeEtcdClient(t)
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)
return storage, fakeEtcdClient
}
@ -107,6 +113,7 @@ func TestEtcdCreateController(t *testing.T) {
t.Errorf("unexpected error: %v", err)
}
key, _ := makeControllerKey(ctx, validController.Name)
key = etcdtest.AddPrefix(key)
resp, err := fakeClient.Get(key, false, false)
if err != nil {
t.Fatalf("Unexpected error %v", err)
@ -126,6 +133,7 @@ func TestEtcdCreateControllerAlreadyExisting(t *testing.T) {
ctx := api.NewDefaultContext()
storage, fakeClient := newStorage(t)
key, _ := makeControllerKey(ctx, validController.Name)
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &validController), 0)
_, err := storage.Create(ctx, &validController)
@ -199,6 +207,7 @@ func TestEtcdGetController(t *testing.T) {
ctx := api.NewDefaultContext()
storage, fakeClient := newStorage(t)
key, _ := makeControllerKey(ctx, validController.Name)
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &validController), 0)
ctrl, err := storage.Get(ctx, validController.Name)
if err != nil {
@ -282,6 +291,9 @@ func TestEtcdGetControllerDifferentNamespace(t *testing.T) {
key1, _ := makeControllerKey(ctx1, validController.Name)
key2, _ := makeControllerKey(ctx2, validController.Name)
key1 = etcdtest.AddPrefix(key1)
key2 = etcdtest.AddPrefix(key2)
fakeClient.Set(key1, runtime.EncodeOrDie(latest.Codec, &validController), 0)
otherNsController := validController
otherNsController.Namespace = otherNs
@ -317,6 +329,8 @@ func TestEtcdGetControllerNotFound(t *testing.T) {
ctx := api.NewDefaultContext()
storage, fakeClient := newStorage(t)
key, _ := makeControllerKey(ctx, validController.Name)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: nil,
@ -336,6 +350,7 @@ func TestEtcdUpdateController(t *testing.T) {
ctx := api.NewDefaultContext()
storage, fakeClient := newStorage(t)
key, _ := makeControllerKey(ctx, validController.Name)
key = etcdtest.AddPrefix(key)
// set a key, then retrieve the current resource version and try updating it
resp, _ := fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &validController), 0)
@ -360,6 +375,8 @@ func TestEtcdDeleteController(t *testing.T) {
ctx := api.NewDefaultContext()
storage, fakeClient := newStorage(t)
key, _ := makeControllerKey(ctx, validController.Name)
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &validController), 0)
obj, err := storage.Delete(ctx, validController.Name, nil)
if err != nil {
@ -382,6 +399,7 @@ func TestEtcdListControllers(t *testing.T) {
storage, fakeClient := newStorage(t)
ctx := api.NewDefaultContext()
key := makeControllerListKey(ctx)
key = etcdtest.AddPrefix(key)
controller := validController
controller.Name = "bar"
fakeClient.Data[key] = tools.EtcdResponseWithError{
@ -413,6 +431,8 @@ func TestEtcdListControllersNotFound(t *testing.T) {
storage, fakeClient := newStorage(t)
ctx := api.NewDefaultContext()
key := makeControllerListKey(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{},
E: tools.EtcdErrorNotFound,
@ -431,6 +451,7 @@ func TestEtcdListControllersLabelsMatch(t *testing.T) {
storage, fakeClient := newStorage(t)
ctx := api.NewDefaultContext()
key := makeControllerListKey(ctx)
key = etcdtest.AddPrefix(key)
controller := validController
controller.Labels = map[string]string{"k": "v"}
@ -678,13 +699,16 @@ func TestCreate(t *testing.T) {
}
func TestDelete(t *testing.T) {
ctx := api.NewDefaultContext()
storage, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeClient.SetError)
key, _ := makeControllerKey(ctx, validController.Name)
key = etcdtest.AddPrefix(key)
createFn := func() runtime.Object {
rc := validController
rc.ResourceVersion = "1"
fakeClient.Data["/registry/controllers/default/foo"] = tools.EtcdResponseWithError{
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, &rc),
@ -697,7 +721,7 @@ func TestDelete(t *testing.T) {
gracefulSetFn := func() bool {
// If the controller is still around after trying to delete either the delete
// 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 false

View File

@ -34,7 +34,7 @@ type REST struct {
// NewStorage returns a RESTStorage object that will work against endpoints.
func NewStorage(h tools.EtcdHelper) *REST {
prefix := "/registry/services/endpoints"
prefix := "/services/endpoints"
return &REST{
&etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.Endpoints{} },

View File

@ -26,6 +26,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/coreos/go-etcd/etcd"
@ -34,7 +35,7 @@ import (
func newHelper(t *testing.T) (*tools.FakeEtcdClient, tools.EtcdHelper) {
fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true
helper := tools.NewEtcdHelper(fakeEtcdClient, latest.Codec)
helper := tools.NewEtcdHelper(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
return fakeEtcdClient, helper
}
@ -89,6 +90,7 @@ func TestDelete(t *testing.T) {
endpoints := validChangedEndpoints()
key, _ := storage.KeyFunc(ctx, endpoints.Name)
key = etcdtest.AddPrefix(key)
createFn := func() runtime.Object {
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
@ -113,6 +115,7 @@ func TestEtcdListEndpoints(t *testing.T) {
ctx := api.NewDefaultContext()
storage, fakeClient := newStorage(t)
key := storage.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
@ -154,6 +157,7 @@ func TestEtcdGetEndpoints(t *testing.T) {
endpoints := validNewEndpoints()
name := endpoints.Name
key, _ := storage.KeyFunc(ctx, name)
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, endpoints), 0)
response, err := fakeClient.Get(key, false, false)
@ -183,6 +187,7 @@ func TestListEmptyEndpointsList(t *testing.T) {
storage, fakeClient := newStorage(t)
fakeClient.ChangeIndex = 1
key := storage.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{},
E: fakeClient.NewError(tools.EtcdErrorCodeNotFound),
@ -206,6 +211,7 @@ func TestListEndpointsList(t *testing.T) {
storage, fakeClient := newStorage(t)
fakeClient.ChangeIndex = 1
key := storage.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
@ -266,6 +272,7 @@ func TestEtcdUpdateEndpoints(t *testing.T) {
endpoints := validChangedEndpoints()
key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, validNewEndpoints()), 0)
_, _, err := storage.Update(ctx, endpoints)
@ -295,6 +302,7 @@ func TestDeleteEndpoints(t *testing.T) {
endpoints := validNewEndpoints()
name := endpoints.Name
key, _ := storage.KeyFunc(ctx, name)
key = etcdtest.AddPrefix(key)
fakeClient.ChangeIndex = 1
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{

View File

@ -35,9 +35,9 @@ import (
const (
// 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 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

View File

@ -33,17 +33,19 @@ import (
podetcd "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/coreos/go-etcd/etcd"
)
func NewTestEtcdRegistry(client tools.EtcdClient) *Registry {
registry := NewRegistry(tools.NewEtcdHelper(client, latest.Codec), nil, nil)
helper := tools.NewEtcdHelper(client, latest.Codec, etcdtest.PathPrefix())
registry := NewRegistry(helper, nil, nil)
return registry
}
func NewTestEtcdRegistryWithPods(client tools.EtcdClient) *Registry {
helper := tools.NewEtcdHelper(client, latest.Codec)
helper := tools.NewEtcdHelper(client, latest.Codec, etcdtest.PathPrefix())
podStorage := podetcd.NewStorage(helper, nil)
endpointStorage := endpointetcd.NewStorage(helper)
registry := NewRegistry(helper, pod.NewRegistry(podStorage.Pod), endpoint.NewRegistry(endpointStorage))
@ -54,6 +56,7 @@ func TestEtcdListControllersNotFound(t *testing.T) {
fakeClient := tools.NewFakeEtcdClient(t)
ctx := api.NewDefaultContext()
key := makeControllerListKey(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{},
E: tools.EtcdErrorNotFound,
@ -71,13 +74,14 @@ func TestEtcdListControllersNotFound(t *testing.T) {
func TestEtcdListServicesNotFound(t *testing.T) {
fakeClient := tools.NewFakeEtcdClient(t)
registry := NewTestEtcdRegistry(fakeClient)
ctx := api.NewDefaultContext()
key := makeServiceListKey(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{},
E: tools.EtcdErrorNotFound,
}
registry := NewTestEtcdRegistry(fakeClient)
services, err := registry.ListServices(ctx)
if err != nil {
t.Errorf("unexpected error: %v", err)
@ -90,8 +94,10 @@ func TestEtcdListServicesNotFound(t *testing.T) {
func TestEtcdListControllers(t *testing.T) {
fakeClient := tools.NewFakeEtcdClient(t)
registry := NewTestEtcdRegistry(fakeClient)
ctx := api.NewDefaultContext()
key := makeControllerListKey(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
@ -107,7 +113,6 @@ func TestEtcdListControllers(t *testing.T) {
},
E: nil,
}
registry := NewTestEtcdRegistry(fakeClient)
controllers, err := registry.ListControllers(ctx)
if err != nil {
t.Errorf("unexpected error: %v", err)
@ -121,6 +126,7 @@ func TestEtcdListControllers(t *testing.T) {
// TestEtcdGetControllerDifferentNamespace ensures same-name controllers in different namespaces do not clash
func TestEtcdGetControllerDifferentNamespace(t *testing.T) {
fakeClient := tools.NewFakeEtcdClient(t)
registry := NewTestEtcdRegistry(fakeClient)
ctx1 := api.NewDefaultContext()
ctx2 := api.WithNamespace(api.NewContext(), "other")
@ -128,11 +134,12 @@ func TestEtcdGetControllerDifferentNamespace(t *testing.T) {
key1, _ := makeControllerKey(ctx1, "foo")
key2, _ := makeControllerKey(ctx2, "foo")
key1 = etcdtest.AddPrefix(key1)
key2 = etcdtest.AddPrefix(key2)
fakeClient.Set(key1, runtime.EncodeOrDie(latest.Codec, &api.ReplicationController{ObjectMeta: api.ObjectMeta{Namespace: "default", Name: "foo"}}), 0)
fakeClient.Set(key2, runtime.EncodeOrDie(latest.Codec, &api.ReplicationController{ObjectMeta: api.ObjectMeta{Namespace: "other", Name: "foo"}}), 0)
registry := NewTestEtcdRegistry(fakeClient)
ctrl1, err := registry.GetController(ctx1, "foo")
if err != nil {
t.Errorf("unexpected error: %v", err)
@ -154,15 +161,15 @@ func TestEtcdGetControllerDifferentNamespace(t *testing.T) {
if ctrl2.Namespace != "other" {
t.Errorf("Unexpected controller: %#v", ctrl2)
}
}
func TestEtcdGetController(t *testing.T) {
ctx := api.NewDefaultContext()
fakeClient := tools.NewFakeEtcdClient(t)
key, _ := makeControllerKey(ctx, "foo")
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.ReplicationController{ObjectMeta: api.ObjectMeta{Name: "foo"}}), 0)
registry := NewTestEtcdRegistry(fakeClient)
key, _ := makeControllerKey(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.ReplicationController{ObjectMeta: api.ObjectMeta{Name: "foo"}}), 0)
ctrl, err := registry.GetController(ctx, "foo")
if err != nil {
t.Errorf("unexpected error: %v", err)
@ -176,14 +183,15 @@ func TestEtcdGetController(t *testing.T) {
func TestEtcdGetControllerNotFound(t *testing.T) {
ctx := api.NewDefaultContext()
fakeClient := tools.NewFakeEtcdClient(t)
registry := NewTestEtcdRegistry(fakeClient)
key, _ := makeControllerKey(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: nil,
},
E: tools.EtcdErrorNotFound,
}
registry := NewTestEtcdRegistry(fakeClient)
ctrl, err := registry.GetController(ctx, "foo")
if ctrl != nil {
t.Errorf("Unexpected non-nil controller: %#v", ctrl)
@ -198,6 +206,7 @@ func TestEtcdDeleteController(t *testing.T) {
fakeClient := tools.NewFakeEtcdClient(t)
registry := NewTestEtcdRegistry(fakeClient)
key, _ := makeControllerKey(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.ReplicationController{ObjectMeta: api.ObjectMeta{Name: "foo"}}), 0)
err := registry.DeleteController(ctx, "foo")
if err != nil {
@ -217,6 +226,7 @@ func TestEtcdCreateController(t *testing.T) {
fakeClient := tools.NewFakeEtcdClient(t)
registry := NewTestEtcdRegistry(fakeClient)
key, _ := makeControllerKey(ctx, "foo")
key = etcdtest.AddPrefix(key)
_, err := registry.CreateController(ctx, &api.ReplicationController{
ObjectMeta: api.ObjectMeta{
Name: "foo",
@ -243,10 +253,11 @@ func TestEtcdCreateController(t *testing.T) {
func TestEtcdCreateControllerAlreadyExisting(t *testing.T) {
ctx := api.NewDefaultContext()
fakeClient := tools.NewFakeEtcdClient(t)
registry := NewTestEtcdRegistry(fakeClient)
key, _ := makeControllerKey(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.ReplicationController{ObjectMeta: api.ObjectMeta{Name: "foo"}}), 0)
registry := NewTestEtcdRegistry(fakeClient)
_, err := registry.CreateController(ctx, &api.ReplicationController{
ObjectMeta: api.ObjectMeta{
Name: "foo",
@ -260,10 +271,11 @@ func TestEtcdCreateControllerAlreadyExisting(t *testing.T) {
func TestEtcdUpdateController(t *testing.T) {
ctx := api.NewDefaultContext()
fakeClient := tools.NewFakeEtcdClient(t)
registry := NewTestEtcdRegistry(fakeClient)
fakeClient.TestIndex = true
key, _ := makeControllerKey(ctx, "foo")
key = etcdtest.AddPrefix(key)
resp, _ := fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.ReplicationController{ObjectMeta: api.ObjectMeta{Name: "foo"}}), 0)
registry := NewTestEtcdRegistry(fakeClient)
_, err := registry.UpdateController(ctx, &api.ReplicationController{
ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: strconv.FormatUint(resp.Node.ModifiedIndex, 10)},
Spec: api.ReplicationControllerSpec{
@ -311,8 +323,10 @@ func TestEtcdWatchController(t *testing.T) {
func TestEtcdWatchControllersMatch(t *testing.T) {
ctx := api.NewDefaultContext()
fakeClient := tools.NewFakeEtcdClient(t)
fakeClient.ExpectNotFoundGet(etcdgeneric.NamespaceKeyRootFunc(ctx, "/registry/pods"))
registry := NewTestEtcdRegistryWithPods(fakeClient)
path := etcdgeneric.NamespaceKeyRootFunc(ctx, "/pods")
path = etcdtest.AddPrefix(path)
fakeClient.ExpectNotFoundGet(path)
watching, err := registry.WatchControllers(ctx,
labels.SelectorFromSet(labels.Set{"name": "foo"}),
fields.Everything(),
@ -391,7 +405,9 @@ func TestEtcdWatchControllersNotMatch(t *testing.T) {
func TestEtcdListServices(t *testing.T) {
ctx := api.NewDefaultContext()
fakeClient := tools.NewFakeEtcdClient(t)
registry := NewTestEtcdRegistry(fakeClient)
key := makeServiceListKey(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
@ -407,7 +423,6 @@ func TestEtcdListServices(t *testing.T) {
},
E: nil,
}
registry := NewTestEtcdRegistry(fakeClient)
services, err := registry.ListServices(ctx)
if err != nil {
t.Errorf("unexpected error: %v", err)
@ -430,6 +445,7 @@ func TestEtcdCreateService(t *testing.T) {
}
key, _ := makeServiceKey(ctx, "foo")
key = etcdtest.AddPrefix(key)
resp, err := fakeClient.Get(key, false, false)
if err != nil {
t.Errorf("unexpected error: %v", err)
@ -449,9 +465,10 @@ func TestEtcdCreateService(t *testing.T) {
func TestEtcdCreateServiceAlreadyExisting(t *testing.T) {
ctx := api.NewDefaultContext()
fakeClient := tools.NewFakeEtcdClient(t)
key, _ := makeServiceKey(ctx, "foo")
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.Service{ObjectMeta: api.ObjectMeta{Name: "foo"}}), 0)
registry := NewTestEtcdRegistry(fakeClient)
key, _ := makeServiceKey(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.Service{ObjectMeta: api.ObjectMeta{Name: "foo"}}), 0)
_, err := registry.CreateService(ctx, &api.Service{
ObjectMeta: api.ObjectMeta{Name: "foo"},
})
@ -463,6 +480,7 @@ func TestEtcdCreateServiceAlreadyExisting(t *testing.T) {
// TestEtcdGetServiceDifferentNamespace ensures same-name services in different namespaces do not clash
func TestEtcdGetServiceDifferentNamespace(t *testing.T) {
fakeClient := tools.NewFakeEtcdClient(t)
registry := NewTestEtcdRegistry(fakeClient)
ctx1 := api.NewDefaultContext()
ctx2 := api.WithNamespace(api.NewContext(), "other")
@ -470,11 +488,12 @@ func TestEtcdGetServiceDifferentNamespace(t *testing.T) {
key1, _ := makeServiceKey(ctx1, "foo")
key2, _ := makeServiceKey(ctx2, "foo")
key1 = etcdtest.AddPrefix(key1)
key2 = etcdtest.AddPrefix(key2)
fakeClient.Set(key1, runtime.EncodeOrDie(latest.Codec, &api.Service{ObjectMeta: api.ObjectMeta{Namespace: "default", Name: "foo"}}), 0)
fakeClient.Set(key2, runtime.EncodeOrDie(latest.Codec, &api.Service{ObjectMeta: api.ObjectMeta{Namespace: "other", Name: "foo"}}), 0)
registry := NewTestEtcdRegistry(fakeClient)
service1, err := registry.GetService(ctx1, "foo")
if err != nil {
t.Errorf("unexpected error: %v", err)
@ -502,9 +521,10 @@ func TestEtcdGetServiceDifferentNamespace(t *testing.T) {
func TestEtcdGetService(t *testing.T) {
ctx := api.NewDefaultContext()
fakeClient := tools.NewFakeEtcdClient(t)
key, _ := makeServiceKey(ctx, "foo")
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.Service{ObjectMeta: api.ObjectMeta{Name: "foo"}}), 0)
registry := NewTestEtcdRegistry(fakeClient)
key, _ := makeServiceKey(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.Service{ObjectMeta: api.ObjectMeta{Name: "foo"}}), 0)
service, err := registry.GetService(ctx, "foo")
if err != nil {
t.Errorf("unexpected error: %v", err)
@ -518,14 +538,15 @@ func TestEtcdGetService(t *testing.T) {
func TestEtcdGetServiceNotFound(t *testing.T) {
ctx := api.NewDefaultContext()
fakeClient := tools.NewFakeEtcdClient(t)
registry := NewTestEtcdRegistry(fakeClient)
key, _ := makeServiceKey(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: nil,
},
E: tools.EtcdErrorNotFound,
}
registry := NewTestEtcdRegistry(fakeClient)
_, err := registry.GetService(ctx, "foo")
if !errors.IsNotFound(err) {
t.Errorf("Unexpected error returned: %#v", err)
@ -536,9 +557,11 @@ func TestEtcdDeleteService(t *testing.T) {
ctx := api.NewDefaultContext()
fakeClient := tools.NewFakeEtcdClient(t)
registry := NewTestEtcdRegistryWithPods(fakeClient)
key, _ := makeServiceKey(ctx, "foo")
key, _ := etcdgeneric.NamespaceKeyFunc(ctx, "/services/specs", "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.Service{ObjectMeta: api.ObjectMeta{Name: "foo"}}), 0)
endpointsKey, _ := etcdgeneric.NamespaceKeyFunc(ctx, "/registry/services/endpoints", "foo")
path, _ := etcdgeneric.NamespaceKeyFunc(ctx, "/services/endpoints", "foo")
endpointsKey := etcdtest.AddPrefix(path)
fakeClient.Set(endpointsKey, runtime.EncodeOrDie(latest.Codec, &api.Endpoints{ObjectMeta: api.ObjectMeta{Name: "foo"}}), 0)
err := registry.DeleteService(ctx, "foo")
@ -561,9 +584,10 @@ func TestEtcdUpdateService(t *testing.T) {
ctx := api.NewDefaultContext()
fakeClient := tools.NewFakeEtcdClient(t)
fakeClient.TestIndex = true
key, _ := makeServiceKey(ctx, "uniquefoo")
resp, _ := fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.Service{ObjectMeta: api.ObjectMeta{Name: "uniquefoo"}}), 0)
registry := NewTestEtcdRegistry(fakeClient)
key, _ := makeServiceKey(ctx, "uniquefoo")
key = etcdtest.AddPrefix(key)
resp, _ := fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.Service{ObjectMeta: api.ObjectMeta{Name: "uniquefoo"}}), 0)
testService := api.Service{
ObjectMeta: api.ObjectMeta{
Name: "uniquefoo",

View File

@ -32,16 +32,17 @@ type registry struct {
// NewEtcdRegistry returns a registry which will store Events in the given
// EtcdHelper. ttl is the time that Events will be retained by the system.
func NewEtcdRegistry(h tools.EtcdHelper, ttl uint64) generic.Registry {
prefix := "/events"
return registry{
Etcd: &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.Event{} },
NewListFunc: func() runtime.Object { return &api.EventList{} },
EndpointName: "events",
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) {
return etcdgeneric.NamespaceKeyFunc(ctx, "/registry/events", id)
return etcdgeneric.NamespaceKeyFunc(ctx, prefix, id)
},
TTLFunc: func(runtime.Object, bool) (uint64, error) {
return ttl, nil

View File

@ -27,6 +27,7 @@ import (
etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/coreos/go-etcd/etcd"
@ -37,7 +38,8 @@ var testTTL uint64 = 60
func NewTestEventEtcdRegistry(t *testing.T) (*tools.FakeEtcdClient, generic.Registry) {
f := tools.NewFakeEtcdClient(t)
f.TestIndex = true
h := tools.NewEtcdHelper(f, testapi.Codec())
h := tools.NewEtcdHelper(f, testapi.Codec(), etcdtest.PathPrefix())
return f, NewEtcdRegistry(h, testTTL)
}
@ -70,7 +72,8 @@ func TestEventCreate(t *testing.T) {
ctx := api.NewDefaultContext()
key := "foo"
path, err := etcdgeneric.NamespaceKeyFunc(ctx, "/registry/events", key)
path, err := etcdgeneric.NamespaceKeyFunc(ctx, "/events", key)
path = etcdtest.AddPrefix(path)
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
@ -166,7 +169,8 @@ func TestEventUpdate(t *testing.T) {
ctx := api.NewDefaultContext()
key := "foo"
path, err := etcdgeneric.NamespaceKeyFunc(ctx, "/registry/events", key)
path, err := etcdgeneric.NamespaceKeyFunc(ctx, "/events", key)
path = etcdtest.AddPrefix(path)
if err != nil {
t.Errorf("Unexpected error: %v", err)
}

View File

@ -27,6 +27,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"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/fielderrors"
@ -66,17 +67,20 @@ func hasCreated(t *testing.T, pod *api.Pod) func(runtime.Object) bool {
func NewTestGenericEtcdRegistry(t *testing.T) (*tools.FakeEtcdClient, *Etcd) {
f := tools.NewFakeEtcdClient(t)
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}
podPrefix := "/pods"
return f, &Etcd{
NewFunc: func() runtime.Object { return &api.Pod{} },
NewListFunc: func() runtime.Object { return &api.PodList{} },
EndpointName: "pods",
CreateStrategy: 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) {
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 },
Helper: h,
@ -205,16 +209,18 @@ func TestEtcdList(t *testing.T) {
t.Errorf("Couldn't create key for %v", name)
continue
}
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = item.in
} 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)
if e, a := item.succeed, err == nil; e != a {
t.Errorf("%v: expected %v, got %v", name, e, a)
continue
}
if e, a := item.out, list; !api.Semantic.DeepDerivative(e, a) {
t.Errorf("%v: Expected %#v, got %#v", name, e, a)
}
@ -247,8 +253,6 @@ func TestEtcdCreate(t *testing.T) {
E: tools.EtcdErrorNotFound,
}
path := "/registry/pods/foo"
table := map[string]struct {
existing tools.EtcdResponseWithError
expect tools.EtcdResponseWithError
@ -272,6 +276,7 @@ func TestEtcdCreate(t *testing.T) {
for name, item := range table {
fakeClient, registry := NewTestGenericEtcdRegistry(t)
path := etcdtest.AddPrefix("pods/foo")
fakeClient.Data[path] = item.existing
obj, err := registry.Create(api.NewDefaultContext(), item.toCreate)
if !item.errOK(err) {
@ -326,7 +331,6 @@ func TestEtcdCreateWithName(t *testing.T) {
E: tools.EtcdErrorNotFound,
}
path := "/registry/pods/foo"
key := "foo"
table := map[string]struct {
@ -352,6 +356,7 @@ func TestEtcdCreateWithName(t *testing.T) {
for name, item := range table {
fakeClient, registry := NewTestGenericEtcdRegistry(t)
path := etcdtest.AddPrefix("pods/foo")
fakeClient.Data[path] = item.existing
err := registry.CreateWithName(api.NewDefaultContext(), key, item.toCreate)
if !item.errOK(err) {
@ -424,8 +429,6 @@ func TestEtcdUpdate(t *testing.T) {
E: tools.EtcdErrorNotFound,
}
path := "/registry/pods/foo"
table := map[string]struct {
existing tools.EtcdResponseWithError
expect tools.EtcdResponseWithError
@ -464,6 +467,7 @@ func TestEtcdUpdate(t *testing.T) {
for name, item := range table {
fakeClient, registry := NewTestGenericEtcdRegistry(t)
registry.UpdateStrategy.(*testRESTStrategy).allowCreateOnUpdate = item.allowCreate
path := etcdtest.AddPrefix("pods/foo")
fakeClient.Data[path] = item.existing
obj, _, err := registry.Update(api.NewDefaultContext(), item.toUpdate)
if !item.errOK(err) {
@ -529,7 +533,6 @@ func TestEtcdUpdateWithName(t *testing.T) {
E: tools.EtcdErrorNotFound,
}
path := "/registry/pods/foo"
key := "foo"
table := map[string]struct {
@ -555,6 +558,7 @@ func TestEtcdUpdateWithName(t *testing.T) {
for name, item := range table {
fakeClient, registry := NewTestGenericEtcdRegistry(t)
path := etcdtest.AddPrefix("pods/foo")
fakeClient.Data[path] = item.existing
err := registry.UpdateWithName(api.NewContext(), key, item.toUpdate)
if !item.errOK(err) {
@ -589,7 +593,6 @@ func TestEtcdGet(t *testing.T) {
E: tools.EtcdErrorNotFound,
}
path := "/registry/pods/foo"
key := "foo"
table := map[string]struct {
@ -611,6 +614,7 @@ func TestEtcdGet(t *testing.T) {
for name, item := range table {
fakeClient, registry := NewTestGenericEtcdRegistry(t)
path := etcdtest.AddPrefix("pods/foo")
fakeClient.Data[path] = item.existing
got, err := registry.Get(api.NewContext(), key)
if !item.errOK(err) {
@ -645,7 +649,6 @@ func TestEtcdDelete(t *testing.T) {
E: tools.EtcdErrorNotFound,
}
path := "/registry/pods/foo"
key := "foo"
table := map[string]struct {
@ -667,6 +670,7 @@ func TestEtcdDelete(t *testing.T) {
for name, item := range table {
fakeClient, registry := NewTestGenericEtcdRegistry(t)
path := etcdtest.AddPrefix("pods/foo")
fakeClient.Data[path] = item.existing
obj, err := registry.Delete(api.NewContext(), key, nil)
if !item.errOK(err) {

View File

@ -31,16 +31,17 @@ type registry struct {
// NewEtcdRegistry returns a registry which will store LimitRange in the given helper
func NewEtcdRegistry(h tools.EtcdHelper) generic.Registry {
prefix := "/limitranges"
return registry{
Etcd: &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.LimitRange{} },
NewListFunc: func() runtime.Object { return &api.LimitRangeList{} },
EndpointName: "limitranges",
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) {
return etcdgeneric.NamespaceKeyFunc(ctx, "/registry/limitranges", id)
return etcdgeneric.NamespaceKeyFunc(ctx, prefix, id)
},
Helper: h,
},

View File

@ -28,6 +28,7 @@ import (
etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/coreos/go-etcd/etcd"
@ -36,7 +37,7 @@ import (
func NewTestLimitRangeEtcdRegistry(t *testing.T) (*tools.FakeEtcdClient, generic.Registry) {
f := tools.NewFakeEtcdClient(t)
f.TestIndex = true
h := tools.NewEtcdHelper(f, testapi.Codec())
h := tools.NewEtcdHelper(f, testapi.Codec(), etcdtest.PathPrefix())
return f, NewEtcdRegistry(h)
}
@ -81,7 +82,9 @@ func TestLimitRangeCreate(t *testing.T) {
ctx := api.NewDefaultContext()
key := "foo"
path, err := etcdgeneric.NamespaceKeyFunc(ctx, "/registry/limitranges", key)
prefix := etcdtest.AddPrefix("limitranges")
path, err := etcdgeneric.NamespaceKeyFunc(ctx, prefix, key)
if err != nil {
t.Errorf("Unexpected error: %v", err)
}

View File

@ -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.
func NewStorage(h tools.EtcdHelper, connection client.ConnectionInfoGetter) (*REST, *StatusREST) {
prefix := "/registry/minions"
prefix := "/minions"
store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.Node{} },
NewListFunc: func() runtime.Object { return &api.NodeList{} },

View File

@ -30,6 +30,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/coreos/go-etcd/etcd"
)
@ -49,7 +50,7 @@ func (fakeConnectionInfoGetter) GetConnectionInfo(host string) (string, uint, ht
func newHelper(t *testing.T) (*tools.FakeEtcdClient, tools.EtcdHelper) {
fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true
helper := tools.NewEtcdHelper(fakeEtcdClient, latest.Codec)
helper := tools.NewEtcdHelper(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
return fakeEtcdClient, helper
}
@ -107,6 +108,7 @@ func TestDelete(t *testing.T) {
node := validChangedNode()
key, _ := storage.KeyFunc(ctx, node.Name)
key = etcdtest.AddPrefix(key)
createFn := func() runtime.Object {
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
@ -131,6 +133,7 @@ func TestEtcdListNodes(t *testing.T) {
ctx := api.NewContext()
storage, fakeClient := newStorage(t)
key := storage.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
@ -165,6 +168,7 @@ func TestEtcdListNodesMatch(t *testing.T) {
ctx := api.NewContext()
storage, fakeClient := newStorage(t)
key := storage.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
@ -209,6 +213,7 @@ func TestEtcdGetNode(t *testing.T) {
storage, fakeClient := newStorage(t)
node := validNewNode()
key, _ := storage.KeyFunc(ctx, node.Name)
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, node), 0)
nodeObj, err := storage.Get(ctx, node.Name)
@ -229,6 +234,7 @@ func TestEtcdUpdateEndpoints(t *testing.T) {
node := validChangedNode()
key, _ := storage.KeyFunc(ctx, node.Name)
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, validNewNode()), 0)
_, _, err := storage.Update(ctx, node)
@ -255,7 +261,8 @@ func TestEtcdUpdateEndpoints(t *testing.T) {
func TestEtcdGetNodeNotFound(t *testing.T) {
ctx := api.NewContext()
storage, fakeClient := newStorage(t)
fakeClient.Data["/registry/minions/foo"] = tools.EtcdResponseWithError{
key := etcdtest.AddPrefix("minions/foo")
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: nil,
},
@ -273,6 +280,7 @@ func TestEtcdDeleteNode(t *testing.T) {
storage, fakeClient := newStorage(t)
node := validNewNode()
key, _ := storage.KeyFunc(ctx, node.Name)
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, node), 0)
_, err := storage.Delete(ctx, node.Name, nil)
if err != nil {

View File

@ -18,6 +18,7 @@ package etcd
import (
"fmt"
"path"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
@ -48,14 +49,15 @@ type FinalizeREST struct {
// NewStorage returns a RESTStorage object that will work against namespaces
func NewStorage(h tools.EtcdHelper) (*REST, *StatusREST, *FinalizeREST) {
prefix := "/namespaces"
store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.Namespace{} },
NewListFunc: func() runtime.Object { return &api.NamespaceList{} },
KeyRootFunc: func(ctx api.Context) string {
return "/registry/namespaces"
return prefix
},
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) {
return obj.(*api.Namespace).Name, nil

View File

@ -27,6 +27,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/namespace"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/coreos/go-etcd/etcd"
@ -35,7 +36,7 @@ import (
func newHelper(t *testing.T) (*tools.FakeEtcdClient, tools.EtcdHelper) {
fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true
helper := tools.NewEtcdHelper(fakeEtcdClient, latest.Codec)
helper := tools.NewEtcdHelper(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
return fakeEtcdClient, helper
}
@ -102,7 +103,12 @@ func TestCreateSetsFields(t *testing.T) {
}
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)
}
if actual.Name != namespace.Name {
@ -119,7 +125,8 @@ func TestCreateSetsFields(t *testing.T) {
func TestListEmptyNamespaceList(t *testing.T) {
fakeEtcdClient, helper := newHelper(t)
fakeEtcdClient.ChangeIndex = 1
fakeEtcdClient.Data["/registry/namespaces"] = tools.EtcdResponseWithError{
key := etcdtest.AddPrefix("/namespaces")
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{},
E: fakeEtcdClient.NewError(tools.EtcdErrorCodeNotFound),
}
@ -139,7 +146,8 @@ func TestListEmptyNamespaceList(t *testing.T) {
func TestListNamespaceList(t *testing.T) {
fakeEtcdClient, helper := newHelper(t)
fakeEtcdClient.Data["/registry/namespaces"] = tools.EtcdResponseWithError{
key := etcdtest.AddPrefix("/namespaces")
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Nodes: []*etcd.Node{
@ -177,7 +185,8 @@ func TestListNamespaceList(t *testing.T) {
func TestListNamespaceListSelection(t *testing.T) {
fakeEtcdClient, helper := newHelper(t)
fakeEtcdClient.Data["/registry/namespaces"] = tools.EtcdResponseWithError{
key := etcdtest.AddPrefix("/namespaces")
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Nodes: []*etcd.Node{
@ -275,15 +284,20 @@ func TestNamespaceDecode(t *testing.T) {
func TestGet(t *testing.T) {
expect := validNewNamespace()
expect.Status.Phase = api.NamespaceActive
fakeEtcdClient, helper := newHelper(t)
fakeEtcdClient.Data["/registry/namespaces/foo"] = tools.EtcdResponseWithError{
storage, fakeEtcdClient, _ := newStorage(t)
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{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, expect),
},
},
}
storage, _, _ := NewStorage(helper)
obj, err := storage.Get(api.NewContext(), "foo")
namespace := obj.(*api.Namespace)
if err != nil {
@ -299,7 +313,11 @@ func TestGet(t *testing.T) {
func TestDeleteNamespace(t *testing.T) {
fakeEtcdClient, helper := newHelper(t)
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{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, &api.Namespace{
@ -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 {
t.Fatalf("unexpected error: %v", err)
@ -325,7 +342,8 @@ func TestDeleteNamespaceWithIncompleteFinalizers(t *testing.T) {
now := util.Now()
fakeEtcdClient, helper := newHelper(t)
fakeEtcdClient.ChangeIndex = 1
fakeEtcdClient.Data["/registry/namespaces/foo"] = tools.EtcdResponseWithError{
key := etcdtest.AddPrefix("/namespaces/foo")
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, &api.Namespace{
@ -354,7 +372,8 @@ func TestDeleteNamespaceWithCompleteFinalizers(t *testing.T) {
now := util.Now()
fakeEtcdClient, helper := newHelper(t)
fakeEtcdClient.ChangeIndex = 1
fakeEtcdClient.Data["/registry/namespaces/foo"] = tools.EtcdResponseWithError{
key := etcdtest.AddPrefix("/namespaces/foo")
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, &api.Namespace{

View File

@ -17,6 +17,8 @@ limitations under the License.
package etcd
import (
"path"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
@ -34,7 +36,7 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against PersistentVolume objects.
func NewStorage(h tools.EtcdHelper) (*REST, *StatusREST) {
prefix := "/registry/persistentvolumes"
prefix := "/persistentvolumes"
store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.PersistentVolume{} },
NewListFunc: func() runtime.Object { return &api.PersistentVolumeList{} },
@ -42,7 +44,7 @@ func NewStorage(h tools.EtcdHelper) (*REST, *StatusREST) {
return prefix
},
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) {
return obj.(*api.PersistentVolume).Name, nil

View File

@ -28,6 +28,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/coreos/go-etcd/etcd"
@ -40,7 +41,7 @@ type testRegistry struct {
func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient, tools.EtcdHelper) {
fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true
helper := tools.NewEtcdHelper(fakeEtcdClient, latest.Codec)
helper := tools.NewEtcdHelper(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
storage, statusStorage := NewStorage(helper)
return storage, statusStorage, fakeEtcdClient, helper
}
@ -93,6 +94,7 @@ func TestDelete(t *testing.T) {
pv := validChangedPersistentVolume()
key, _ := storage.KeyFunc(ctx, pv.Name)
key = etcdtest.AddPrefix(key)
createFn := func() runtime.Object {
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
@ -117,6 +119,7 @@ func TestEtcdListPersistentVolumes(t *testing.T) {
ctx := api.NewDefaultContext()
storage, _, fakeClient, _ := newStorage(t)
key := storage.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
@ -150,6 +153,7 @@ func TestEtcdGetPersistentVolumes(t *testing.T) {
persistentVolume := validNewPersistentVolume("foo")
name := persistentVolume.Name
key, _ := storage.KeyFunc(ctx, name)
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, persistentVolume), 0)
response, err := fakeClient.Get(key, false, false)
@ -179,6 +183,7 @@ func TestListEmptyPersistentVolumesList(t *testing.T) {
storage, _, fakeClient, _ := newStorage(t)
fakeClient.ChangeIndex = 1
key := storage.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{},
E: fakeClient.NewError(tools.EtcdErrorCodeNotFound),
@ -202,6 +207,7 @@ func TestListPersistentVolumesList(t *testing.T) {
storage, _, fakeClient, _ := newStorage(t)
fakeClient.ChangeIndex = 1
key := storage.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
@ -262,6 +268,7 @@ func TestEtcdUpdatePersistentVolumes(t *testing.T) {
persistentVolume := validChangedPersistentVolume()
key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, validNewPersistentVolume("foo")), 0)
_, _, err := storage.Update(ctx, persistentVolume)
@ -291,6 +298,7 @@ func TestDeletePersistentVolumes(t *testing.T) {
persistentVolume := validNewPersistentVolume("foo")
name := persistentVolume.Name
key, _ := storage.KeyFunc(ctx, name)
key = etcdtest.AddPrefix(key)
fakeClient.ChangeIndex = 1
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
@ -313,6 +321,7 @@ func TestEtcdUpdateStatus(t *testing.T) {
fakeClient.TestIndex = true
key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
pvStart := validNewPersistentVolume("foo")
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, pvStart), 1)
@ -336,6 +345,7 @@ func TestEtcdUpdateStatus(t *testing.T) {
t.Fatalf("Unexpected error: %v", err)
}
var pvOut api.PersistentVolume
key, _ = storage.KeyFunc(ctx, "foo")
if err := helper.ExtractObj(key, &pvOut, false); err != nil {
t.Fatalf("Unexpected error: %v", err)
}

View File

@ -34,7 +34,7 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against PersistentVolumeClaim objects.
func NewStorage(h tools.EtcdHelper) (*REST, *StatusREST) {
prefix := "/registry/persistentvolumeclaims"
prefix := "/persistentvolumeclaims"
store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.PersistentVolumeClaim{} },
NewListFunc: func() runtime.Object { return &api.PersistentVolumeClaimList{} },

View File

@ -28,6 +28,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/coreos/go-etcd/etcd"
@ -40,7 +41,7 @@ type testRegistry struct {
func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient, tools.EtcdHelper) {
fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true
helper := tools.NewEtcdHelper(fakeEtcdClient, latest.Codec)
helper := tools.NewEtcdHelper(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
storage, statusStorage := NewStorage(helper)
return storage, statusStorage, fakeEtcdClient, helper
}
@ -95,6 +96,7 @@ func TestDelete(t *testing.T) {
pv := validChangedPersistentVolumeClaim()
key, _ := storage.KeyFunc(ctx, pv.Name)
key = etcdtest.AddPrefix(key)
createFn := func() runtime.Object {
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
@ -119,6 +121,7 @@ func TestEtcdListPersistentVolumeClaims(t *testing.T) {
ctx := api.NewDefaultContext()
registry, _, fakeClient, _ := newStorage(t)
key := registry.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
@ -152,6 +155,7 @@ func TestEtcdGetPersistentVolumeClaims(t *testing.T) {
persistentVolume := validNewPersistentVolumeClaim("foo", api.NamespaceDefault)
name := persistentVolume.Name
key, _ := registry.KeyFunc(ctx, name)
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, persistentVolume), 0)
response, err := fakeClient.Get(key, false, false)
@ -181,6 +185,7 @@ func TestListEmptyPersistentVolumeClaimsList(t *testing.T) {
registry, _, fakeClient, _ := newStorage(t)
fakeClient.ChangeIndex = 1
key := registry.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{},
E: fakeClient.NewError(tools.EtcdErrorCodeNotFound),
@ -204,6 +209,7 @@ func TestListPersistentVolumeClaimsList(t *testing.T) {
registry, _, fakeClient, _ := newStorage(t)
fakeClient.ChangeIndex = 1
key := registry.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
@ -264,6 +270,7 @@ func TestEtcdUpdatePersistentVolumeClaims(t *testing.T) {
persistentVolume := validChangedPersistentVolumeClaim()
key, _ := registry.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, validNewPersistentVolumeClaim("foo", api.NamespaceDefault)), 0)
_, _, err := registry.Update(ctx, persistentVolume)
@ -293,6 +300,7 @@ func TestDeletePersistentVolumeClaims(t *testing.T) {
pvClaim := validNewPersistentVolumeClaim("foo", api.NamespaceDefault)
name := pvClaim.Name
key, _ := registry.KeyFunc(ctx, name)
key = etcdtest.AddPrefix(key)
fakeClient.ChangeIndex = 1
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
@ -315,6 +323,7 @@ func TestEtcdUpdateStatus(t *testing.T) {
fakeClient.TestIndex = true
key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
pvcStart := validNewPersistentVolumeClaim("foo", api.NamespaceDefault)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, pvcStart), 1)
@ -339,6 +348,7 @@ func TestEtcdUpdateStatus(t *testing.T) {
t.Fatalf("Unexpected error: %v", err)
}
var pvcOut api.PersistentVolumeClaim
key, _ = storage.KeyFunc(ctx, "foo")
if err := helper.ExtractObj(key, &pvcOut, false); err != nil {
t.Fatalf("Unexpected error: %v", err)
}

View File

@ -56,7 +56,7 @@ type REST struct {
// NewStorage returns a RESTStorage object that will work against pods.
func NewStorage(h tools.EtcdHelper, k client.ConnectionInfoGetter) PodStorage {
prefix := "/registry/pods"
prefix := "/pods"
store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.Pod{} },
NewListFunc: func() runtime.Object { return &api.PodList{} },

View File

@ -33,6 +33,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/coreos/go-etcd/etcd"
@ -41,7 +42,7 @@ import (
func newHelper(t *testing.T) (*tools.FakeEtcdClient, tools.EtcdHelper) {
fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true
helper := tools.NewEtcdHelper(fakeEtcdClient, latest.Codec)
helper := tools.NewEtcdHelper(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
return fakeEtcdClient, helper
}
@ -108,11 +109,14 @@ func TestCreate(t *testing.T) {
func TestDelete(t *testing.T) {
fakeEtcdClient, helper := newHelper(t)
storage := NewStorage(helper, nil).Pod
ctx := api.NewDefaultContext()
key, _ := storage.Etcd.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
test := resttest.New(t, storage, fakeEtcdClient.SetError)
createFn := func() runtime.Object {
pod := validChangedPod()
fakeEtcdClient.Data["/registry/pods/default/foo"] = tools.EtcdResponseWithError{
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, pod),
@ -123,10 +127,10 @@ func TestDelete(t *testing.T) {
return pod
}
gracefulSetFn := func() bool {
if fakeEtcdClient.Data["/registry/pods/default/foo"].R.Node == nil {
if fakeEtcdClient.Data[key].R.Node == nil {
return false
}
return fakeEtcdClient.Data["/registry/pods/default/foo"].R.Node.TTL == 30
return fakeEtcdClient.Data[key].R.Node.TTL == 30
}
test.TestDelete(createFn, gracefulSetFn)
}
@ -160,9 +164,10 @@ func TestCreateSetsFields(t *testing.T) {
if err != fakeEtcdClient.Err {
t.Fatalf("unexpected error: %v", err)
}
ctx := api.NewDefaultContext()
key, _ := storage.Etcd.KeyFunc(ctx, "foo")
actual := &api.Pod{}
if err := helper.ExtractObj("/registry/pods/default/foo", actual, false); err != nil {
if err := helper.ExtractObj(key, actual, false); err != nil {
t.Fatalf("unexpected extraction error: %v", err)
}
if actual.Name != pod.Name {
@ -189,12 +194,15 @@ func TestListError(t *testing.T) {
func TestListEmptyPodList(t *testing.T) {
fakeEtcdClient, helper := newHelper(t)
fakeEtcdClient.ChangeIndex = 1
fakeEtcdClient.Data["/registry/pods"] = tools.EtcdResponseWithError{
ctx := api.NewContext()
storage := NewStorage(helper, nil).Pod
key := storage.Etcd.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{},
E: fakeEtcdClient.NewError(tools.EtcdErrorCodeNotFound),
}
storage := NewStorage(helper, nil).Pod
pods, err := storage.List(api.NewContext(), labels.Everything(), fields.Everything())
if err != nil {
t.Fatalf("unexpected error: %v", err)
@ -210,7 +218,11 @@ func TestListEmptyPodList(t *testing.T) {
func TestListPodList(t *testing.T) {
fakeEtcdClient, helper := newHelper(t)
fakeEtcdClient.Data["/registry/pods/default"] = tools.EtcdResponseWithError{
ctx := api.NewDefaultContext()
storage := NewStorage(helper, nil).Pod
key := storage.Etcd.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Nodes: []*etcd.Node{
@ -231,7 +243,6 @@ func TestListPodList(t *testing.T) {
},
},
}
storage := NewStorage(helper, nil).Pod
podsObj, err := storage.List(api.NewDefaultContext(), labels.Everything(), fields.Everything())
pods := podsObj.(*api.PodList)
@ -252,7 +263,11 @@ func TestListPodList(t *testing.T) {
func TestListPodListSelection(t *testing.T) {
fakeEtcdClient, helper := newHelper(t)
fakeEtcdClient.Data["/registry/pods/default"] = tools.EtcdResponseWithError{
ctx := api.NewDefaultContext()
storage := NewStorage(helper, nil).Pod
rootKey := etcdtest.AddPrefix("pods/default")
key := etcdtest.AddPrefix("pods/default/zot")
fakeEtcdClient.Data[rootKey] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Nodes: []*etcd.Node{
@ -280,7 +295,7 @@ func TestListPodListSelection(t *testing.T) {
},
},
}
fakeEtcdClient.Data["/registry/pods/default/zot"] = tools.EtcdResponseWithError{
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, &api.Pod{
@ -289,9 +304,6 @@ func TestListPodListSelection(t *testing.T) {
},
},
}
storage := NewStorage(helper, nil).Pod
ctx := api.NewDefaultContext()
table := []struct {
label, field string
@ -377,7 +389,8 @@ func TestGet(t *testing.T) {
expect.Spec.Host = "machine"
fakeEtcdClient, helper := newHelper(t)
fakeEtcdClient.Data["/registry/pods/test/foo"] = tools.EtcdResponseWithError{
key := etcdtest.AddPrefix("/pods/test/foo")
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, expect),
@ -420,6 +433,8 @@ func TestPodStorageValidatesCreate(t *testing.T) {
func TestCreatePod(t *testing.T) {
_, helper := newHelper(t)
storage := NewStorage(helper, nil).Pod
ctx := api.NewDefaultContext()
key, _ := storage.Etcd.KeyFunc(ctx, "foo")
pod := validNewPod()
obj, err := storage.Create(api.NewDefaultContext(), pod)
@ -430,7 +445,7 @@ func TestCreatePod(t *testing.T) {
t.Fatalf("unexpected object: %#v", obj)
}
actual := &api.Pod{}
if err := helper.ExtractObj("/registry/pods/default/foo", actual, false); err != nil {
if err := helper.ExtractObj(key, actual, false); err != nil {
t.Fatalf("unexpected extraction error: %v", err)
}
if !api.HasObjectMetaSystemFieldValues(&actual.ObjectMeta) {
@ -459,7 +474,11 @@ func TestCreateWithConflictingNamespace(t *testing.T) {
func TestUpdateWithConflictingNamespace(t *testing.T) {
fakeEtcdClient, helper := newHelper(t)
fakeEtcdClient.Data["/registry/pods/default/foo"] = tools.EtcdResponseWithError{
storage := NewStorage(helper, nil).Pod
ctx := api.NewDefaultContext()
key, _ := storage.Etcd.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, &api.Pod{
@ -470,7 +489,6 @@ func TestUpdateWithConflictingNamespace(t *testing.T) {
},
},
}
storage := NewStorage(helper, nil).Pod
pod := validChangedPod()
pod.Namespace = "not-default"
@ -578,16 +596,19 @@ func TestResourceLocation(t *testing.T) {
},
}
ctx := api.NewDefaultContext()
for _, tc := range testCases {
fakeEtcdClient, helper := newHelper(t)
fakeEtcdClient.Data["/registry/pods/default/foo"] = tools.EtcdResponseWithError{
storage := NewStorage(helper, nil).Pod
key, _ := storage.Etcd.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, &tc.pod),
},
},
}
storage := NewStorage(helper, nil).Pod
redirector := rest.Redirector(storage)
location, _, err := redirector.ResourceLocation(api.NewDefaultContext(), tc.query)
@ -610,7 +631,11 @@ func TestResourceLocation(t *testing.T) {
func TestDeletePod(t *testing.T) {
fakeEtcdClient, helper := newHelper(t)
fakeEtcdClient.ChangeIndex = 1
fakeEtcdClient.Data["/registry/pods/default/foo"] = tools.EtcdResponseWithError{
storage := NewStorage(helper, nil).Pod
ctx := api.NewDefaultContext()
key, _ := storage.Etcd.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, &api.Pod{
@ -625,8 +650,6 @@ func TestDeletePod(t *testing.T) {
},
},
}
storage := NewStorage(helper, nil).Pod
_, err := storage.Delete(api.NewDefaultContext(), "foo", nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
@ -643,6 +666,9 @@ func TestEtcdGetDifferentNamespace(t *testing.T) {
key1, _ := registry.KeyFunc(ctx1, "foo")
key2, _ := registry.KeyFunc(ctx2, "foo")
key1 = etcdtest.AddPrefix(key1)
key2 = etcdtest.AddPrefix(key2)
fakeClient.Set(key1, runtime.EncodeOrDie(latest.Codec, &api.Pod{ObjectMeta: api.ObjectMeta{Namespace: "default", Name: "foo"}}), 0)
fakeClient.Set(key2, runtime.EncodeOrDie(latest.Codec, &api.Pod{ObjectMeta: api.ObjectMeta{Namespace: "other", Name: "foo"}}), 0)
@ -676,6 +702,7 @@ func TestEtcdGet(t *testing.T) {
registry, _, _, fakeClient, _ := newStorage(t)
ctx := api.NewDefaultContext()
key, _ := registry.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}), 0)
obj, err := registry.Get(ctx, "foo")
if err != nil {
@ -691,6 +718,7 @@ func TestEtcdGetNotFound(t *testing.T) {
registry, _, _, fakeClient, _ := newStorage(t)
ctx := api.NewDefaultContext()
key, _ := registry.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: nil,
@ -708,6 +736,7 @@ func TestEtcdCreate(t *testing.T) {
ctx := api.NewDefaultContext()
fakeClient.TestIndex = true
key, _ := registry.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: nil,
@ -752,6 +781,7 @@ func TestEtcdCreateBindingNoPod(t *testing.T) {
fakeClient.TestIndex = true
key, _ := registry.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: nil,
@ -798,6 +828,7 @@ func TestEtcdCreateAlreadyExisting(t *testing.T) {
registry, _, _, fakeClient, _ := newStorage(t)
ctx := api.NewDefaultContext()
key, _ := registry.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
@ -817,6 +848,7 @@ func TestEtcdCreateWithContainersNotFound(t *testing.T) {
ctx := api.NewDefaultContext()
fakeClient.TestIndex = true
key, _ := registry.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: nil,
@ -901,6 +933,7 @@ func TestEtcdCreateWithExistingContainers(t *testing.T) {
ctx := api.NewDefaultContext()
fakeClient.TestIndex = true
key, _ := registry.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: nil,
@ -983,6 +1016,7 @@ func TestEtcdCreateBinding(t *testing.T) {
}
for k, test := range testCases {
key, _ := registry.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: nil,
@ -1012,6 +1046,7 @@ func TestEtcdUpdateNotFound(t *testing.T) {
fakeClient.TestIndex = true
key, _ := registry.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{},
E: tools.EtcdErrorNotFound,
@ -1038,6 +1073,7 @@ func TestEtcdUpdateNotScheduled(t *testing.T) {
fakeClient.TestIndex = true
key, _ := registry.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, validNewPod()), 1)
podIn := validChangedPod()
@ -1062,6 +1098,7 @@ func TestEtcdUpdateScheduled(t *testing.T) {
fakeClient.TestIndex = true
key, _ := registry.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.Pod{
ObjectMeta: api.ObjectMeta{
Name: "foo",
@ -1122,6 +1159,7 @@ func TestEtcdUpdateStatus(t *testing.T) {
fakeClient.TestIndex = true
key, _ := registry.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
podStart := api.Pod{
ObjectMeta: api.ObjectMeta{
Name: "foo",
@ -1177,6 +1215,7 @@ func TestEtcdUpdateStatus(t *testing.T) {
t.Fatalf("Unexpected error: %v", err)
}
var podOut api.Pod
key, _ = registry.KeyFunc(ctx, "foo")
if err := helper.ExtractObj(key, &podOut, false); err != nil {
t.Fatalf("Unexpected error: %v", err)
}
@ -1191,6 +1230,7 @@ func TestEtcdDeletePod(t *testing.T) {
fakeClient.TestIndex = true
key, _ := registry.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo"},
Spec: api.PodSpec{Host: "machine"},
@ -1212,6 +1252,7 @@ func TestEtcdDeletePodMultipleContainers(t *testing.T) {
ctx := api.NewDefaultContext()
fakeClient.TestIndex = true
key, _ := registry.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo"},
Spec: api.PodSpec{Host: "machine"},
@ -1233,6 +1274,7 @@ func TestEtcdEmptyList(t *testing.T) {
registry, _, _, fakeClient, _ := newStorage(t)
ctx := api.NewDefaultContext()
key := registry.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
@ -1256,6 +1298,7 @@ func TestEtcdListNotFound(t *testing.T) {
registry, _, _, fakeClient, _ := newStorage(t)
ctx := api.NewDefaultContext()
key := registry.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{},
E: tools.EtcdErrorNotFound,
@ -1274,6 +1317,7 @@ func TestEtcdList(t *testing.T) {
registry, _, _, fakeClient, _ := newStorage(t)
ctx := api.NewDefaultContext()
key := registry.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{

View File

@ -34,7 +34,7 @@ type REST struct {
// NewREST returns a RESTStorage object that will work against pod templates.
func NewREST(h tools.EtcdHelper) *REST {
prefix := "/registry/podtemplates"
prefix := "/podtemplates"
store := etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.PodTemplate{} },
NewListFunc: func() runtime.Object { return &api.PodTemplateList{} },

View File

@ -23,12 +23,13 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest/resttest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta3"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
)
func newHelper(t *testing.T) (*tools.FakeEtcdClient, tools.EtcdHelper) {
fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true
helper := tools.NewEtcdHelper(fakeEtcdClient, v1beta3.Codec)
helper := tools.NewEtcdHelper(fakeEtcdClient, v1beta3.Codec, etcdtest.PathPrefix())
return fakeEtcdClient, helper
}
@ -79,8 +80,9 @@ func TestUpdate(t *testing.T) {
fakeEtcdClient, helper := newHelper(t)
storage := NewREST(helper)
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
pod := validNewPodTemplate("foo")
existing := validNewPodTemplate("exists")

View File

@ -34,7 +34,7 @@ type REST struct {
// NewStorage returns a RESTStorage object that will work against ResourceQuota objects.
func NewStorage(h tools.EtcdHelper) (*REST, *StatusREST) {
prefix := "/registry/resourcequotas"
prefix := "/resourcequotas"
store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.ResourceQuota{} },
NewListFunc: func() runtime.Object { return &api.ResourceQuotaList{} },

View File

@ -32,6 +32,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequota"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/coreos/go-etcd/etcd"
@ -40,7 +41,7 @@ import (
func newHelper(t *testing.T) (*tools.FakeEtcdClient, tools.EtcdHelper) {
fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true
helper := tools.NewEtcdHelper(fakeEtcdClient, latest.Codec)
helper := tools.NewEtcdHelper(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
return fakeEtcdClient, helper
}
@ -123,6 +124,7 @@ func TestCreateRegistryError(t *testing.T) {
func TestCreateSetsFields(t *testing.T) {
fakeEtcdClient, helper := newHelper(t)
storage, _ := NewStorage(helper)
ctx := api.NewDefaultContext()
resourcequota := validNewResourceQuota()
_, err := storage.Create(api.NewDefaultContext(), resourcequota)
if err != fakeEtcdClient.Err {
@ -130,7 +132,8 @@ func TestCreateSetsFields(t *testing.T) {
}
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)
}
if actual.Name != resourcequota.Name {
@ -157,12 +160,16 @@ func TestListError(t *testing.T) {
func TestListEmptyResourceQuotaList(t *testing.T) {
fakeEtcdClient, helper := newHelper(t)
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{},
E: fakeEtcdClient.NewError(tools.EtcdErrorCodeNotFound),
}
storage, _ := NewStorage(helper)
resourcequotas, err := storage.List(api.NewContext(), labels.Everything(), fields.Everything())
if err != nil {
t.Fatalf("unexpected error: %v", err)
@ -178,7 +185,11 @@ func TestListEmptyResourceQuotaList(t *testing.T) {
func TestListResourceQuotaList(t *testing.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{
Node: &etcd.Node{
Nodes: []*etcd.Node{
@ -196,7 +207,6 @@ func TestListResourceQuotaList(t *testing.T) {
},
},
}
storage, _ := NewStorage(helper)
resourcequotasObj, err := storage.List(api.NewDefaultContext(), labels.Everything(), fields.Everything())
resourcequotas := resourcequotasObj.(*api.ResourceQuotaList)
if err != nil {
@ -216,7 +226,11 @@ func TestListResourceQuotaList(t *testing.T) {
func TestListResourceQuotaListSelection(t *testing.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{
Node: &etcd.Node{
Nodes: []*etcd.Node{
@ -236,8 +250,6 @@ func TestListResourceQuotaListSelection(t *testing.T) {
},
},
}
storage, _ := NewStorage(helper)
ctx := api.NewDefaultContext()
table := []struct {
label, field string
@ -302,14 +314,16 @@ func TestResourceQuotaDecode(t *testing.T) {
func TestGet(t *testing.T) {
expect := validNewResourceQuota()
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{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, expect),
},
},
}
storage, _ := NewStorage(helper)
obj, err := storage.Get(api.WithNamespace(api.NewContext(), "test"), "foo")
resourcequota := obj.(*api.ResourceQuota)
if err != nil {
@ -324,7 +338,11 @@ func TestGet(t *testing.T) {
func TestDeleteResourceQuota(t *testing.T) {
fakeEtcdClient, helper := newHelper(t)
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{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, &api.ResourceQuota{
@ -339,7 +357,6 @@ func TestDeleteResourceQuota(t *testing.T) {
},
},
}
storage, _ := NewStorage(helper)
_, err := storage.Delete(api.NewDefaultContext(), "foo", nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
@ -356,6 +373,9 @@ func TestEtcdGetDifferentNamespace(t *testing.T) {
key1, _ := registry.KeyFunc(ctx1, "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(key2, runtime.EncodeOrDie(latest.Codec, &api.ResourceQuota{ObjectMeta: api.ObjectMeta{Namespace: "other", Name: "foo"}}), 0)
@ -389,6 +409,7 @@ func TestEtcdGet(t *testing.T) {
registry, _, fakeClient, _ := newStorage(t)
ctx := api.NewDefaultContext()
key, _ := registry.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.ResourceQuota{ObjectMeta: api.ObjectMeta{Name: "foo"}}), 0)
obj, err := registry.Get(ctx, "foo")
if err != nil {
@ -404,6 +425,7 @@ func TestEtcdGetNotFound(t *testing.T) {
registry, _, fakeClient, _ := newStorage(t)
ctx := api.NewDefaultContext()
key, _ := registry.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: nil,
@ -432,6 +454,7 @@ func TestEtcdCreateAlreadyExisting(t *testing.T) {
registry, _, fakeClient, _ := newStorage(t)
ctx := api.NewDefaultContext()
key, _ := registry.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
@ -452,6 +475,7 @@ func TestEtcdUpdateStatus(t *testing.T) {
fakeClient.TestIndex = true
key, _ := registry.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
resourcequotaStart := validNewResourceQuota()
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, resourcequotaStart), 1)
@ -491,6 +515,7 @@ func TestEtcdUpdateStatus(t *testing.T) {
t.Fatalf("Unexpected error: %v", err)
}
var resourcequotaOut api.ResourceQuota
key, _ = registry.KeyFunc(ctx, "foo")
if err := helper.ExtractObj(key, &resourcequotaOut, false); err != nil {
t.Fatalf("Unexpected error: %v", err)
}
@ -503,6 +528,7 @@ func TestEtcdEmptyList(t *testing.T) {
registry, _, fakeClient, _ := newStorage(t)
ctx := api.NewDefaultContext()
key := registry.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
@ -526,6 +552,7 @@ func TestEtcdListNotFound(t *testing.T) {
registry, _, fakeClient, _ := newStorage(t)
ctx := api.NewDefaultContext()
key := registry.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{},
E: tools.EtcdErrorNotFound,
@ -544,6 +571,7 @@ func TestEtcdList(t *testing.T) {
registry, _, fakeClient, _ := newStorage(t)
ctx := api.NewDefaultContext()
key := registry.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{

View File

@ -31,16 +31,17 @@ type registry struct {
// NewEtcdRegistry returns a registry which will store Secret in the given helper
func NewEtcdRegistry(h tools.EtcdHelper) generic.Registry {
prefix := "/secrets"
return registry{
Etcd: &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.Secret{} },
NewListFunc: func() runtime.Object { return &api.SecretList{} },
EndpointName: "secrets",
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) {
return etcdgeneric.NamespaceKeyFunc(ctx, "/registry/secrets", id)
return etcdgeneric.NamespaceKeyFunc(ctx, prefix, id)
},
Helper: h,
},

View File

@ -27,6 +27,7 @@ import (
etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/coreos/go-etcd/etcd"
@ -35,7 +36,7 @@ import (
func NewTestSecretEtcdRegistry(t *testing.T) (*tools.FakeEtcdClient, generic.Registry) {
f := tools.NewFakeEtcdClient(t)
f.TestIndex = true
h := tools.NewEtcdHelper(f, testapi.Codec())
h := tools.NewEtcdHelper(f, testapi.Codec(), etcdtest.PathPrefix())
return f, NewEtcdRegistry(h)
}
@ -65,10 +66,11 @@ func TestSecretCreate(t *testing.T) {
R: &etcd.Response{},
E: tools.EtcdErrorNotFound,
}
ctx := api.NewDefaultContext()
key := "foo"
path, err := etcdgeneric.NamespaceKeyFunc(ctx, "/registry/secrets", key)
path, err := etcdgeneric.NamespaceKeyFunc(ctx, "/secrets", key)
path = etcdtest.AddPrefix(path)
if err != nil {
t.Errorf("Unexpected error: %v", err)
}

View File

@ -23,7 +23,9 @@ import (
"io/ioutil"
"net/http"
"os/exec"
"path"
"reflect"
"strings"
"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
@ -38,15 +40,18 @@ type EtcdHelper struct {
Codec runtime.Codec
// optional, no atomic operations can be performed without this interface
Versioner EtcdVersioner
// prefix for all etcd keys
PathPrefix string
}
// NewEtcdHelper creates a helper that works against objects that use the internal
// Kubernetes API objects.
func NewEtcdHelper(client EtcdGetSet, codec runtime.Codec) EtcdHelper {
func NewEtcdHelper(client EtcdGetSet, codec runtime.Codec, prefix string) EtcdHelper {
return EtcdHelper{
Client: client,
Codec: codec,
Versioner: APIObjectVersioner{},
Client: client,
Codec: codec,
Versioner: APIObjectVersioner{},
PathPrefix: prefix,
}
}
@ -136,6 +141,7 @@ func (h *EtcdHelper) ExtractToList(key string, listObj runtime.Object) error {
if err != nil {
return err
}
key = h.PrefixEtcdKey(key)
nodes, index, err := h.listEtcdNode(key)
if err != nil {
return err
@ -158,7 +164,7 @@ func (h *EtcdHelper) ExtractObjToList(key string, listObj runtime.Object) error
if err != nil {
return err
}
key = h.PrefixEtcdKey(key)
response, err := h.Client.Get(key, false, false)
if err != nil {
if IsEtcdNotFound(err) {
@ -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
// empty responses and nil response nodes exactly like a not found error.
func (h *EtcdHelper) ExtractObj(key string, objPtr runtime.Object, ignoreNotFound bool) error {
key = h.PrefixEtcdKey(key)
_, _, err := h.bodyAndExtractObj(key, objPtr, ignoreNotFound)
return err
}
@ -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
// from etcd.
func (h *EtcdHelper) CreateObj(key string, obj, out runtime.Object, ttl uint64) error {
key = h.PrefixEtcdKey(key)
data, err := h.Codec.Encode(obj)
if err != nil {
return err
@ -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")
}
}
response, err := h.Client.Create(key, string(data), ttl)
if err != nil {
return err
@ -257,15 +266,18 @@ func (h *EtcdHelper) CreateObj(key string, obj, out runtime.Object, ttl uint64)
// Delete removes the specified key.
func (h *EtcdHelper) Delete(key string, recursive bool) error {
key = h.PrefixEtcdKey(key)
_, err := h.Client.Delete(key, recursive)
return err
}
// DeleteObj removes the specified key and returns the value that existed at that spot.
func (h *EtcdHelper) DeleteObj(key string, out runtime.Object) error {
key = h.PrefixEtcdKey(key)
if _, err := conversion.EnforcePtr(out); err != nil {
panic("unable to convert output object to pointer")
}
response, err := h.Client.Delete(key, false)
if !IsEtcdNotFound(err) {
// 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
if err != nil {
return err
}
key = h.PrefixEtcdKey(key)
create := true
if h.Versioner != nil {
@ -346,6 +359,7 @@ func (h *EtcdHelper) GuaranteedUpdate(key string, ptrToType runtime.Object, igno
// Panic is appropriate, because this is a programming error.
panic("need ptr to type")
}
key = h.PrefixEtcdKey(key)
for {
obj := reflect.New(v.Type()).Interface().(runtime.Object)
origBody, index, err := h.bodyAndExtractObj(key, obj, ignoreNotFound)
@ -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
// of the release version, internal version, and error (if any).
func GetEtcdVersion(host string) (releaseVersion, internalVersion string, err error) {

View File

@ -21,6 +21,7 @@ import (
"fmt"
"net/http"
"net/http/httptest"
"path"
"reflect"
"sync"
"testing"
@ -29,6 +30,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi"
"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/coreos/go-etcd/etcd"
"github.com/stretchr/testify/assert"
)
@ -79,7 +81,9 @@ func getEncodedPod(name string) string {
func TestExtractToList(t *testing.T) {
fakeClient := NewFakeEtcdClient(t)
fakeClient.Data["/some/key"] = EtcdResponseWithError{
helper := NewEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix())
key := etcdtest.AddPrefix("/some/key")
fakeClient.Data[key] = EtcdResponseWithError{
R: &etcd.Response{
EtcdIndex: 10,
Node: &etcd.Node{
@ -135,7 +139,6 @@ func TestExtractToList(t *testing.T) {
}
var got api.PodList
helper := NewEtcdHelper(fakeClient, testapi.Codec())
err := helper.ExtractToList("/some/key", &got)
if err != nil {
t.Errorf("Unexpected error %v", err)
@ -148,7 +151,9 @@ func TestExtractToList(t *testing.T) {
// TestExtractToListAcrossDirectories ensures that the client excludes directories and flattens tree-response - simulates cross-namespace query
func TestExtractToListAcrossDirectories(t *testing.T) {
fakeClient := NewFakeEtcdClient(t)
fakeClient.Data["/some/key"] = EtcdResponseWithError{
helper := NewEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix())
key := etcdtest.AddPrefix("/some/key")
fakeClient.Data[key] = EtcdResponseWithError{
R: &etcd.Response{
EtcdIndex: 10,
Node: &etcd.Node{
@ -218,7 +223,6 @@ func TestExtractToListAcrossDirectories(t *testing.T) {
}
var got api.PodList
helper := NewEtcdHelper(fakeClient, testapi.Codec())
err := helper.ExtractToList("/some/key", &got)
if err != nil {
t.Errorf("Unexpected error %v", err)
@ -230,7 +234,9 @@ func TestExtractToListAcrossDirectories(t *testing.T) {
func TestExtractToListExcludesDirectories(t *testing.T) {
fakeClient := NewFakeEtcdClient(t)
fakeClient.Data["/some/key"] = EtcdResponseWithError{
helper := NewEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix())
key := etcdtest.AddPrefix("/some/key")
fakeClient.Data[key] = EtcdResponseWithError{
R: &etcd.Response{
EtcdIndex: 10,
Node: &etcd.Node{
@ -288,7 +294,6 @@ func TestExtractToListExcludesDirectories(t *testing.T) {
}
var got api.PodList
helper := NewEtcdHelper(fakeClient, testapi.Codec())
err := helper.ExtractToList("/some/key", &got)
if err != nil {
t.Errorf("Unexpected error %v", err)
@ -300,6 +305,8 @@ func TestExtractToListExcludesDirectories(t *testing.T) {
func TestExtractObj(t *testing.T) {
fakeClient := NewFakeEtcdClient(t)
helper := NewEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix())
key := etcdtest.AddPrefix("/some/key")
expect := api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo"},
Spec: api.PodSpec{
@ -307,8 +314,7 @@ func TestExtractObj(t *testing.T) {
DNSPolicy: api.DNSClusterFirst,
},
}
fakeClient.Set("/some/key", runtime.EncodeOrDie(testapi.Codec(), &expect), 0)
helper := NewEtcdHelper(fakeClient, testapi.Codec())
fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), &expect), 0)
var got api.Pod
err := helper.ExtractObj("/some/key", &got, false)
if err != nil {
@ -321,7 +327,9 @@ func TestExtractObj(t *testing.T) {
func TestExtractObjNotFoundErr(t *testing.T) {
fakeClient := NewFakeEtcdClient(t)
fakeClient.Data["/some/key"] = EtcdResponseWithError{
helper := NewEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix())
key1 := etcdtest.AddPrefix("/some/key")
fakeClient.Data[key1] = EtcdResponseWithError{
R: &etcd.Response{
Node: nil,
},
@ -329,19 +337,20 @@ func TestExtractObjNotFoundErr(t *testing.T) {
ErrorCode: 100,
},
}
fakeClient.Data["/some/key2"] = EtcdResponseWithError{
key2 := etcdtest.AddPrefix("/some/key2")
fakeClient.Data[key2] = EtcdResponseWithError{
R: &etcd.Response{
Node: nil,
},
}
fakeClient.Data["/some/key3"] = EtcdResponseWithError{
key3 := etcdtest.AddPrefix("/some/key3")
fakeClient.Data[key3] = EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Value: "",
},
},
}
helper := NewEtcdHelper(fakeClient, codec)
try := func(key string) {
var got api.Pod
err := helper.ExtractObj(key, &got, false)
@ -362,7 +371,7 @@ func TestExtractObjNotFoundErr(t *testing.T) {
func TestCreateObj(t *testing.T) {
obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}
fakeClient := NewFakeEtcdClient(t)
helper := NewEtcdHelper(fakeClient, testapi.Codec())
helper := NewEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix())
returnedObj := &api.Pod{}
err := helper.CreateObj("/some/key", obj, returnedObj, 5)
if err != nil {
@ -372,7 +381,8 @@ func TestCreateObj(t *testing.T) {
if err != nil {
t.Errorf("Unexpected error %#v", err)
}
node := fakeClient.Data["/some/key"].R.Node
key := etcdtest.AddPrefix("/some/key")
node := fakeClient.Data[key].R.Node
if e, a := string(data), node.Value; e != a {
t.Errorf("Wanted %v, got %v", e, a)
}
@ -387,7 +397,7 @@ func TestCreateObj(t *testing.T) {
func TestCreateObjNilOutParam(t *testing.T) {
obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}
fakeClient := NewFakeEtcdClient(t)
helper := NewEtcdHelper(fakeClient, testapi.Codec())
helper := NewEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix())
err := helper.CreateObj("/some/key", obj, nil, 5)
if err != nil {
t.Errorf("Unexpected error %#v", err)
@ -397,7 +407,7 @@ func TestCreateObjNilOutParam(t *testing.T) {
func TestSetObj(t *testing.T) {
obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}
fakeClient := NewFakeEtcdClient(t)
helper := NewEtcdHelper(fakeClient, testapi.Codec())
helper := NewEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix())
returnedObj := &api.Pod{}
err := helper.SetObj("/some/key", obj, returnedObj, 5)
if err != nil {
@ -408,7 +418,8 @@ func TestSetObj(t *testing.T) {
t.Errorf("Unexpected error %#v", err)
}
expect := string(data)
got := fakeClient.Data["/some/key"].R.Node.Value
key := etcdtest.AddPrefix("/some/key")
got := fakeClient.Data[key].R.Node.Value
if expect != got {
t.Errorf("Wanted %v, got %v", expect, got)
}
@ -424,7 +435,7 @@ func TestSetObjFailCAS(t *testing.T) {
obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}}
fakeClient := NewFakeEtcdClient(t)
fakeClient.CasErr = fakeClient.NewError(123)
helper := NewEtcdHelper(fakeClient, testapi.Codec())
helper := NewEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix())
err := helper.SetObj("/some/key", obj, nil, 5)
if err == nil {
t.Errorf("Expecting error.")
@ -435,7 +446,9 @@ func TestSetObjWithVersion(t *testing.T) {
obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}}
fakeClient := NewFakeEtcdClient(t)
fakeClient.TestIndex = true
fakeClient.Data["/some/key"] = EtcdResponseWithError{
helper := NewEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix())
key := etcdtest.AddPrefix("/some/key")
fakeClient.Data[key] = EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(testapi.Codec(), obj),
@ -444,7 +457,6 @@ func TestSetObjWithVersion(t *testing.T) {
},
}
helper := NewEtcdHelper(fakeClient, testapi.Codec())
returnedObj := &api.Pod{}
err := helper.SetObj("/some/key", obj, returnedObj, 7)
if err != nil {
@ -455,7 +467,7 @@ func TestSetObjWithVersion(t *testing.T) {
t.Fatalf("Unexpected error %#v", err)
}
expect := string(data)
got := fakeClient.Data["/some/key"].R.Node.Value
got := fakeClient.Data[key].R.Node.Value
if expect != got {
t.Errorf("Wanted %v, got %v", expect, got)
}
@ -470,9 +482,10 @@ func TestSetObjWithVersion(t *testing.T) {
func TestSetObjWithoutResourceVersioner(t *testing.T) {
obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}
fakeClient := NewFakeEtcdClient(t)
helper := EtcdHelper{fakeClient, testapi.Codec(), nil}
helper := EtcdHelper{fakeClient, testapi.Codec(), nil, etcdtest.PathPrefix()}
returnedObj := &api.Pod{}
err := helper.SetObj("/some/key", obj, returnedObj, 3)
key := etcdtest.AddPrefix("/some/key")
if err != nil {
t.Errorf("Unexpected error %#v", err)
}
@ -481,7 +494,7 @@ func TestSetObjWithoutResourceVersioner(t *testing.T) {
t.Errorf("Unexpected error %#v", err)
}
expect := string(data)
got := fakeClient.Data["/some/key"].R.Node.Value
got := fakeClient.Data[key].R.Node.Value
if expect != got {
t.Errorf("Wanted %v, got %v", expect, got)
}
@ -496,7 +509,7 @@ func TestSetObjWithoutResourceVersioner(t *testing.T) {
func TestSetObjNilOutParam(t *testing.T) {
obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}
fakeClient := NewFakeEtcdClient(t)
helper := EtcdHelper{fakeClient, testapi.Codec(), nil}
helper := EtcdHelper{fakeClient, testapi.Codec(), nil, etcdtest.PathPrefix()}
err := helper.SetObj("/some/key", obj, nil, 3)
if err != nil {
t.Errorf("Unexpected error %#v", err)
@ -506,10 +519,11 @@ func TestSetObjNilOutParam(t *testing.T) {
func TestGuaranteedUpdate(t *testing.T) {
fakeClient := NewFakeEtcdClient(t)
fakeClient.TestIndex = true
helper := NewEtcdHelper(fakeClient, codec)
helper := NewEtcdHelper(fakeClient, codec, etcdtest.PathPrefix())
key := etcdtest.AddPrefix("/some/key")
// Create a new node.
fakeClient.ExpectNotFoundGet("/some/key")
fakeClient.ExpectNotFoundGet(key)
obj := &TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: 1}
err := helper.GuaranteedUpdate("/some/key", &TestResource{}, true, func(in runtime.Object) (runtime.Object, uint64, error) {
return obj, 0, nil
@ -522,7 +536,7 @@ func TestGuaranteedUpdate(t *testing.T) {
t.Errorf("Unexpected error %#v", err)
}
expect := string(data)
got := fakeClient.Data["/some/key"].R.Node.Value
got := fakeClient.Data[key].R.Node.Value
if expect != got {
t.Errorf("Wanted %v, got %v", expect, got)
}
@ -547,7 +561,7 @@ func TestGuaranteedUpdate(t *testing.T) {
t.Errorf("Unexpected error %#v", err)
}
expect = string(data)
got = fakeClient.Data["/some/key"].R.Node.Value
got = fakeClient.Data[key].R.Node.Value
if expect != got {
t.Errorf("Wanted %v, got %v", expect, got)
}
@ -560,10 +574,11 @@ func TestGuaranteedUpdate(t *testing.T) {
func TestGuaranteedUpdateNoChange(t *testing.T) {
fakeClient := NewFakeEtcdClient(t)
fakeClient.TestIndex = true
helper := NewEtcdHelper(fakeClient, codec)
helper := NewEtcdHelper(fakeClient, codec, etcdtest.PathPrefix())
key := etcdtest.AddPrefix("/some/key")
// Create a new node.
fakeClient.ExpectNotFoundGet("/some/key")
fakeClient.ExpectNotFoundGet(key)
obj := &TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: 1}
err := helper.GuaranteedUpdate("/some/key", &TestResource{}, true, func(in runtime.Object) (runtime.Object, uint64, error) {
return obj, 0, nil
@ -591,10 +606,11 @@ func TestGuaranteedUpdateNoChange(t *testing.T) {
func TestGuaranteedUpdateKeyNotFound(t *testing.T) {
fakeClient := NewFakeEtcdClient(t)
fakeClient.TestIndex = true
helper := NewEtcdHelper(fakeClient, codec)
helper := NewEtcdHelper(fakeClient, codec, etcdtest.PathPrefix())
key := etcdtest.AddPrefix("/some/key")
// Create a new node.
fakeClient.ExpectNotFoundGet("/some/key")
fakeClient.ExpectNotFoundGet(key)
obj := &TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: 1}
f := func(in runtime.Object) (runtime.Object, uint64, error) {
@ -617,9 +633,10 @@ func TestGuaranteedUpdateKeyNotFound(t *testing.T) {
func TestGuaranteedUpdate_CreateCollision(t *testing.T) {
fakeClient := NewFakeEtcdClient(t)
fakeClient.TestIndex = true
helper := NewEtcdHelper(fakeClient, codec)
helper := NewEtcdHelper(fakeClient, codec, etcdtest.PathPrefix())
key := etcdtest.AddPrefix("/some/key")
fakeClient.ExpectNotFoundGet("/some/key")
fakeClient.ExpectNotFoundGet(key)
const concurrency = 10
var wgDone sync.WaitGroup
@ -654,7 +671,7 @@ func TestGuaranteedUpdate_CreateCollision(t *testing.T) {
wgDone.Wait()
// Check that stored TestResource has received all updates.
body := fakeClient.Data["/some/key"].R.Node.Value
body := fakeClient.Data[key].R.Node.Value
stored := &TestResource{}
if err := codec.DecodeInto([]byte(body), stored); err != nil {
t.Errorf("Error decoding stored value: %v", body)
@ -708,3 +725,23 @@ func TestGetEtcdVersion_ErrorStatus(t *testing.T) {
_, _, err = GetEtcdVersion(testServer.URL)
assert.NotNil(t, err)
}
func TestPrefixEtcdKey(t *testing.T) {
fakeClient := NewFakeEtcdClient(t)
prefix := path.Join("/", etcdtest.PathPrefix())
helper := NewEtcdHelper(fakeClient, testapi.Codec(), prefix)
baseKey := "/some/key"
// Verify prefix is added
keyBefore := baseKey
keyAfter := helper.PrefixEtcdKey(keyBefore)
assert.Equal(t, keyAfter, path.Join(prefix, baseKey), "Prefix incorrectly added by EtcdHelper")
// Verify prefix is not added
keyBefore = path.Join(prefix, baseKey)
keyAfter = helper.PrefixEtcdKey(keyBefore)
assert.Equal(t, keyBefore, keyAfter, "Prefix incorrectly added by EtcdHelper")
}

View File

@ -71,6 +71,7 @@ func ParseWatchResourceVersion(resourceVersion, kind string) (uint64, error) {
// watch.Interface. resourceVersion may be used to specify what version to begin
// watching (e.g., for reconnecting without missing any updates).
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)
go w.etcdWatch(h.Client, key, resourceVersion)
return w, nil
@ -80,6 +81,7 @@ func (h *EtcdHelper) WatchList(key string, resourceVersion uint64, filter Filter
// API objects and sent down the returned watch.Interface.
// Errors will be sent down the channel.
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)
go w.etcdWatch(h.Client, key, resourceVersion)
return w, nil
@ -102,6 +104,7 @@ func (h *EtcdHelper) Watch(key string, resourceVersion uint64, filter FilterFunc
//
// Errors will be sent down the channel.
func (h *EtcdHelper) WatchAndTransform(key string, resourceVersion uint64, transform TransformFunc) watch.Interface {
key = h.PrefixEtcdKey(key)
w := newEtcdWatcher(false, nil, Everything, h.Codec, h.Versioner, transform)
go w.etcdWatch(h.Client, key, resourceVersion)
return w

View File

@ -25,6 +25,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
"github.com/coreos/go-etcd/etcd"
)
@ -205,7 +206,7 @@ func TestWatchEtcdError(t *testing.T) {
fakeClient := NewFakeEtcdClient(t)
fakeClient.expectNotFoundGetSet["/some/key"] = struct{}{}
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)
if err != nil {
@ -232,10 +233,12 @@ func TestWatchEtcdError(t *testing.T) {
func TestWatch(t *testing.T) {
codec := latest.Codec
fakeClient := NewFakeEtcdClient(t)
fakeClient.expectNotFoundGetSet["/some/key"] = struct{}{}
h := EtcdHelper{fakeClient, codec, versioner}
key := "/some/key"
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 {
t.Fatalf("Unexpected error: %v", err)
}
@ -300,6 +303,8 @@ func makeSubsets(ip string, port int) []api.EndpointSubset {
func TestWatchEtcdState(t *testing.T) {
codec := latest.Codec
baseKey := "/somekey/foo"
prefixedKey := etcdtest.AddPrefix(baseKey)
type T struct {
Type watch.EventType
Endpoints []api.EndpointSubset
@ -357,7 +362,7 @@ func TestWatchEtcdState(t *testing.T) {
},
"from initial state": {
Initial: map[string]EtcdResponseWithError{
"/somekey/foo": {
prefixedKey: {
R: &etcd.Response{
Action: "get",
Node: &etcd.Node{
@ -406,8 +411,9 @@ func TestWatchEtcdState(t *testing.T) {
for key, value := range testCase.Initial {
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 {
t.Fatalf("Unexpected error: %v", err)
}
@ -476,10 +482,12 @@ func TestWatchFromZeroIndex(t *testing.T) {
for k, testCase := range testCases {
fakeClient := NewFakeEtcdClient(t)
fakeClient.Data["/some/key"] = testCase.Response
h := EtcdHelper{fakeClient, codec, versioner}
key := "/some/key"
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 {
t.Fatalf("Unexpected error: %v", err)
}
@ -512,9 +520,10 @@ func TestWatchFromZeroIndex(t *testing.T) {
func TestWatchListFromZeroIndex(t *testing.T) {
codec := latest.Codec
pod := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}
key := "/some/key"
prefixedKey := etcdtest.AddPrefix(key)
fakeClient := NewFakeEtcdClient(t)
fakeClient.Data["/some/key"] = EtcdResponseWithError{
fakeClient.Data[prefixedKey] = EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Dir: true,
@ -537,9 +546,9 @@ func TestWatchListFromZeroIndex(t *testing.T) {
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 {
t.Fatalf("Unexpected error: %v", err)
}
@ -573,11 +582,13 @@ func TestWatchListFromZeroIndex(t *testing.T) {
func TestWatchListIgnoresRootKey(t *testing.T) {
codec := latest.Codec
pod := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}
key := "/some/key"
prefixedKey := etcdtest.AddPrefix(key)
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 {
t.Fatalf("Unexpected error: %v", err)
}
@ -587,7 +598,7 @@ func TestWatchListIgnoresRootKey(t *testing.T) {
fakeClient.WatchResponse <- &etcd.Response{
Action: "delete",
PrevNode: &etcd.Node{
Key: "/some/key",
Key: prefixedKey,
Value: runtime.EncodeOrDie(codec, pod),
CreatedIndex: 1,
ModifiedIndex: 1,
@ -598,7 +609,7 @@ func TestWatchListIgnoresRootKey(t *testing.T) {
fakeClient.WatchResponse <- &etcd.Response{
Action: "delete",
PrevNode: &etcd.Node{
Key: "/some/key",
Key: prefixedKey,
Value: "",
CreatedIndex: 1,
ModifiedIndex: 1,
@ -617,7 +628,9 @@ func TestWatchListIgnoresRootKey(t *testing.T) {
func TestWatchFromNotFound(t *testing.T) {
fakeClient := NewFakeEtcdClient(t)
fakeClient.Data["/some/key"] = EtcdResponseWithError{
key := "/some/key"
prefixedKey := etcdtest.AddPrefix(key)
fakeClient.Data[prefixedKey] = EtcdResponseWithError{
R: &etcd.Response{
Node: nil,
},
@ -626,13 +639,12 @@ func TestWatchFromNotFound(t *testing.T) {
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 {
t.Fatalf("Unexpected error: %v", err)
}
fakeClient.WaitForWatchCompletion()
if fakeClient.WatchIndex != 3 {
t.Errorf("Expected client to wait for %d, got %#v", 3, fakeClient)
@ -643,7 +655,9 @@ func TestWatchFromNotFound(t *testing.T) {
func TestWatchFromOtherError(t *testing.T) {
fakeClient := NewFakeEtcdClient(t)
fakeClient.Data["/some/key"] = EtcdResponseWithError{
key := "/some/key"
prefixedKey := etcdtest.AddPrefix(key)
fakeClient.Data[prefixedKey] = EtcdResponseWithError{
R: &etcd.Response{
Node: nil,
},
@ -652,9 +666,8 @@ func TestWatchFromOtherError(t *testing.T) {
ErrorCode: 101,
},
}
h := EtcdHelper{fakeClient, codec, versioner}
watching, err := h.Watch("/some/key", 0, Everything)
h := EtcdHelper{fakeClient, codec, versioner, etcdtest.PathPrefix()}
watching, err := h.Watch(key, 0, Everything)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
@ -683,11 +696,13 @@ func TestWatchFromOtherError(t *testing.T) {
func TestWatchPurposefulShutdown(t *testing.T) {
fakeClient := NewFakeEtcdClient(t)
h := EtcdHelper{fakeClient, codec, versioner}
fakeClient.expectNotFoundGetSet["/some/key"] = struct{}{}
h := EtcdHelper{fakeClient, codec, versioner, etcdtest.PathPrefix()}
key := "/some/key"
prefixedKey := etcdtest.AddPrefix(key)
fakeClient.expectNotFoundGetSet[prefixedKey] = struct{}{}
// Test purposeful shutdown
watching, err := h.Watch("/some/key", 0, Everything)
watching, err := h.Watch(key, 0, Everything)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}

17
pkg/tools/etcdtest/doc.go Normal file
View File

@ -0,0 +1,17 @@
/*
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

View File

@ -0,0 +1,32 @@
/*
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)
}

View File

@ -46,6 +46,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/auth/user"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"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/auth/authenticator/token/tokentest"
)
@ -377,7 +378,7 @@ func TestAuthModeAlwaysAllow(t *testing.T) {
// Set up a master
helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version())
helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version(), etcdtest.PathPrefix())
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
@ -516,8 +517,7 @@ func TestAuthModeAlwaysDeny(t *testing.T) {
deleteAllEtcdKeys()
// Set up a master
helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version())
helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version(), etcdtest.PathPrefix())
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
@ -583,8 +583,7 @@ func TestAliceNotForbiddenOrUnauthorized(t *testing.T) {
// This file has alice and bob in it.
// Set up a master
helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version())
helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version(), etcdtest.PathPrefix())
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
@ -672,8 +671,7 @@ func TestBobIsForbidden(t *testing.T) {
// This file has alice and bob in it.
// Set up a master
helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version())
helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version(), etcdtest.PathPrefix())
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
@ -733,8 +731,7 @@ func TestUnknownUserIsUnauthorized(t *testing.T) {
// This file has alice and bob in it.
// Set up a master
helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version())
helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version(), etcdtest.PathPrefix())
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
@ -810,8 +807,7 @@ func TestNamespaceAuthorization(t *testing.T) {
deleteAllEtcdKeys()
// This file has alice and bob in it.
helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version())
helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version(), etcdtest.PathPrefix())
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
@ -925,8 +921,7 @@ func TestKindAuthorization(t *testing.T) {
// This file has alice and bob in it.
// Set up a master
helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version())
helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version(), etcdtest.PathPrefix())
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
@ -1028,8 +1023,7 @@ func TestReadOnlyAuthorization(t *testing.T) {
// This file has alice and bob in it.
// Set up a master
helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version())
helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version(), etcdtest.PathPrefix())
if err != nil {
t.Fatalf("unexpected error: %v", err)
}

View File

@ -26,6 +26,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
)
@ -92,8 +93,9 @@ func TestExtractObj(t *testing.T) {
func TestWatch(t *testing.T) {
client := newEtcdClient()
helper := tools.NewEtcdHelper(client, testapi.Codec())
helper := tools.NewEtcdHelper(client, testapi.Codec(), etcdtest.PathPrefix())
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)
if err != nil {
t.Fatalf("unexpected error: %v", err)

View File

@ -33,6 +33,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/record"
"github.com/GoogleCloudPlatform/kubernetes/pkg/master"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/wait"
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/admit"
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler"
@ -45,7 +46,7 @@ func init() {
}
func TestUnschedulableNodes(t *testing.T) {
helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version())
helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version(), etcdtest.PathPrefix())
if err != nil {
t.Fatalf("Couldn't create etcd helper: %v", err)
}

View File

@ -30,6 +30,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/master"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/admit"
)
@ -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.
func TestSecrets(t *testing.T) {
helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version())
helper, err := master.NewEtcdHelper(newEtcdClient(), testapi.Version(), etcdtest.PathPrefix())
if err != nil {
t.Fatalf("unexpected error: %v", err)
}

View File

@ -29,6 +29,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/master"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/admit"
"github.com/coreos/go-etcd/etcd"
@ -66,7 +67,7 @@ func deleteAllEtcdKeys() {
}
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 {
t.Fatalf("unexpected error: %v", err)
}