mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-24 12:15:52 +00:00
Merge pull request #2899 from derekwaynecarr/update_generic_etcd
Update generic etcd to enable namespace scoped resources
This commit is contained in:
commit
a2638da2a7
@ -35,7 +35,11 @@ type registry struct {
|
||||
|
||||
// Create stores the object with a ttl, so that events don't stay in the system forever.
|
||||
func (r registry) Create(ctx api.Context, id string, obj runtime.Object) error {
|
||||
err := r.Etcd.Helper.CreateObj(r.Etcd.KeyFunc(id), obj, r.ttl)
|
||||
key, err := r.Etcd.KeyFunc(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = r.Etcd.Helper.CreateObj(key, obj, r.ttl)
|
||||
return etcderr.InterpretCreateError(err, r.Etcd.EndpointName, id)
|
||||
}
|
||||
|
||||
@ -47,9 +51,12 @@ func NewEtcdRegistry(h tools.EtcdHelper, ttl uint64) generic.Registry {
|
||||
NewFunc: func() runtime.Object { return &api.Event{} },
|
||||
NewListFunc: func() runtime.Object { return &api.EventList{} },
|
||||
EndpointName: "events",
|
||||
KeyRoot: "/registry/events",
|
||||
KeyFunc: func(id string) string {
|
||||
return path.Join("/registry/events", id)
|
||||
KeyRootFunc: func(ctx api.Context) string {
|
||||
return "/registry/events"
|
||||
},
|
||||
KeyFunc: func(ctx api.Context, id string) (string, error) {
|
||||
// TODO - we need to store this in a namespace relative path
|
||||
return path.Join("/registry/events", id), nil
|
||||
},
|
||||
Helper: h,
|
||||
},
|
||||
|
@ -18,6 +18,7 @@ package etcd
|
||||
|
||||
import (
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
kubeerr "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
|
||||
etcderr "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors/etcd"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
@ -41,19 +42,44 @@ type Etcd struct {
|
||||
EndpointName string
|
||||
|
||||
// Used for listing/watching; should not include trailing "/"
|
||||
KeyRoot string
|
||||
KeyRootFunc func(ctx api.Context) string
|
||||
|
||||
// Called for Create/Update/Get/Delete
|
||||
KeyFunc func(id string) string
|
||||
KeyFunc func(ctx api.Context, id string) (string, error)
|
||||
|
||||
// Used for all etcd access functions
|
||||
Helper tools.EtcdHelper
|
||||
}
|
||||
|
||||
// NamespaceKeyRootFunc is the default function for constructing etcd paths to resource directories enforcing namespace rules.
|
||||
func NamespaceKeyRootFunc(ctx api.Context, prefix string) string {
|
||||
key := prefix
|
||||
ns, ok := api.NamespaceFrom(ctx)
|
||||
if ok && len(ns) > 0 {
|
||||
key = key + "/" + ns
|
||||
}
|
||||
return key
|
||||
}
|
||||
|
||||
// NamespaceKeyFunc is the default function for constructing etcd paths to a resource relative to prefix enforcing namespace rules.
|
||||
// If no namespace is on context, it errors.
|
||||
func NamespaceKeyFunc(ctx api.Context, prefix string, id string) (string, error) {
|
||||
key := NamespaceKeyRootFunc(ctx, prefix)
|
||||
ns, ok := api.NamespaceFrom(ctx)
|
||||
if !ok || len(ns) == 0 {
|
||||
return "", kubeerr.NewBadRequest("Namespace parameter required.")
|
||||
}
|
||||
if len(id) == 0 {
|
||||
return "", kubeerr.NewBadRequest("Namespace parameter required.")
|
||||
}
|
||||
key = key + "/" + id
|
||||
return key, nil
|
||||
}
|
||||
|
||||
// List returns a list of all the items matching m.
|
||||
func (e *Etcd) List(ctx api.Context, m generic.Matcher) (runtime.Object, error) {
|
||||
list := e.NewListFunc()
|
||||
err := e.Helper.ExtractToList(e.KeyRoot, list)
|
||||
err := e.Helper.ExtractToList(e.KeyRootFunc(ctx), list)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -62,21 +88,33 @@ func (e *Etcd) List(ctx api.Context, m generic.Matcher) (runtime.Object, error)
|
||||
|
||||
// Create inserts a new item.
|
||||
func (e *Etcd) Create(ctx api.Context, id string, obj runtime.Object) error {
|
||||
err := e.Helper.CreateObj(e.KeyFunc(id), obj, 0)
|
||||
key, err := e.KeyFunc(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = e.Helper.CreateObj(key, obj, 0)
|
||||
return etcderr.InterpretCreateError(err, e.EndpointName, id)
|
||||
}
|
||||
|
||||
// Update updates the item.
|
||||
func (e *Etcd) Update(ctx api.Context, id string, obj runtime.Object) error {
|
||||
key, err := e.KeyFunc(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// TODO: verify that SetObj checks ResourceVersion before succeeding.
|
||||
err := e.Helper.SetObj(e.KeyFunc(id), obj)
|
||||
err = e.Helper.SetObj(key, obj)
|
||||
return etcderr.InterpretUpdateError(err, e.EndpointName, id)
|
||||
}
|
||||
|
||||
// Get retrieves the item from etcd.
|
||||
func (e *Etcd) Get(ctx api.Context, id string) (runtime.Object, error) {
|
||||
obj := e.NewFunc()
|
||||
err := e.Helper.ExtractObj(e.KeyFunc(id), obj, false)
|
||||
key, err := e.KeyFunc(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = e.Helper.ExtractObj(key, obj, false)
|
||||
if err != nil {
|
||||
return nil, etcderr.InterpretGetError(err, e.EndpointName, id)
|
||||
}
|
||||
@ -85,7 +123,11 @@ func (e *Etcd) Get(ctx api.Context, id string) (runtime.Object, error) {
|
||||
|
||||
// Delete removes the item from etcd.
|
||||
func (e *Etcd) Delete(ctx api.Context, id string) error {
|
||||
err := e.Helper.Delete(e.KeyFunc(id), false)
|
||||
key, err := e.KeyFunc(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = e.Helper.Delete(key, false)
|
||||
return etcderr.InterpretDeleteError(err, e.EndpointName, id)
|
||||
}
|
||||
|
||||
@ -96,7 +138,7 @@ func (e *Etcd) Watch(ctx api.Context, m generic.Matcher, resourceVersion string)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return e.Helper.WatchList(e.KeyRoot, version, func(obj runtime.Object) bool {
|
||||
return e.Helper.WatchList(e.KeyRootFunc(ctx), version, func(obj runtime.Object) bool {
|
||||
matches, err := m.Matches(obj)
|
||||
return err == nil && matches
|
||||
})
|
||||
|
@ -41,9 +41,9 @@ func NewTestGenericEtcdRegistry(t *testing.T) (*tools.FakeEtcdClient, *Etcd) {
|
||||
NewFunc: func() runtime.Object { return &api.Pod{} },
|
||||
NewListFunc: func() runtime.Object { return &api.PodList{} },
|
||||
EndpointName: "pods",
|
||||
KeyRoot: "/registry/pods",
|
||||
KeyFunc: func(id string) string {
|
||||
return path.Join("/registry/pods", id)
|
||||
KeyRootFunc: func(ctx api.Context) string { return "/registry/pods" },
|
||||
KeyFunc: func(ctx api.Context, id string) (string, error) {
|
||||
return path.Join("/registry/pods", id), nil
|
||||
},
|
||||
Helper: h,
|
||||
}
|
||||
@ -139,7 +139,7 @@ func TestEtcdList(t *testing.T) {
|
||||
|
||||
for name, item := range table {
|
||||
fakeClient, registry := NewTestGenericEtcdRegistry(t)
|
||||
fakeClient.Data[registry.KeyRoot] = item.in
|
||||
fakeClient.Data[registry.KeyRootFunc(api.NewContext())] = item.in
|
||||
list, err := registry.List(api.NewContext(), item.m)
|
||||
if e, a := item.succeed, err == nil; e != a {
|
||||
t.Errorf("%v: expected %v, got %v", name, e, a)
|
||||
|
Loading…
Reference in New Issue
Block a user