func NewTestGenericEtcdRegistry(t *testing.T) (*tools.FakeEtcdClient, *Etcd) { f := tools.NewFakeEtcdClient(t) f.TestIndex = true s := etcdstorage.NewEtcdStorage(f, testapi.Default.Codec(), etcdtest.PathPrefix()) strategy := &testRESTStrategy{api.Scheme, api.SimpleNameGenerator, true, false, true} 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 podPrefix }, KeyFunc: func(ctx api.Context, id string) (string, error) { if _, ok := api.NamespaceFrom(ctx); !ok { return "", fmt.Errorf("namespace is required") } return path.Join(podPrefix, id), nil }, ObjectNameFunc: func(obj runtime.Object) (string, error) { return obj.(*api.Pod).Name, nil }, Storage: s, } }
// TestValidNamespace validates that namespace rules are enforced on a resource prior to create or update func TestValidNamespace(t *testing.T) { ctx := api.NewDefaultContext() namespace, _ := api.NamespaceFrom(ctx) resource := api.ReplicationController{} if !api.ValidNamespace(ctx, &resource.ObjectMeta) { t.Errorf("expected success") } if namespace != resource.Namespace { t.Errorf("expected resource to have the default namespace assigned during validation") } resource = api.ReplicationController{ObjectMeta: api.ObjectMeta{Namespace: "other"}} if api.ValidNamespace(ctx, &resource.ObjectMeta) { t.Errorf("Expected error that resource and context errors do not match because resource has different namespace") } ctx = api.NewContext() if api.ValidNamespace(ctx, &resource.ObjectMeta) { t.Errorf("Expected error that resource and context errors do not match since context has no namespace") } ctx = api.NewContext() ns := api.NamespaceValue(ctx) if ns != "" { t.Errorf("Expected the empty string") } }
// TestNamespaceContext validates that a namespace can be get/set on a context object func TestNamespaceContext(t *testing.T) { ctx := api.NewDefaultContext() result, ok := api.NamespaceFrom(ctx) if !ok { t.Errorf("Error getting namespace") } if api.NamespaceDefault != result { t.Errorf("Expected: %v, Actual: %v", api.NamespaceDefault, result) } ctx = api.NewContext() result, ok = api.NamespaceFrom(ctx) if ok { t.Errorf("Should not be ok because there is no namespace on the context") } }
// 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, name 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(name) == 0 { return "", kubeerr.NewBadRequest("Name parameter required.") } if ok, msg := validation.ValidatePathSegmentName(name, false); !ok { return "", kubeerr.NewBadRequest(fmt.Sprintf("Name parameter invalid: %v.", msg)) } key = key + "/" + name return key, nil }
func (r *ServiceRegistry) ListServices(ctx api.Context, label labels.Selector, field fields.Selector) (*api.ServiceList, error) { r.mu.Lock() defer r.mu.Unlock() ns, _ := api.NamespaceFrom(ctx) // Copy metadata from internal list into result res := new(api.ServiceList) res.TypeMeta = r.List.TypeMeta res.ListMeta = r.List.ListMeta if ns != api.NamespaceAll { for _, service := range r.List.Items { if ns == service.Namespace { res.Items = append(res.Items, service) } } } else { res.Items = append([]api.Service{}, r.List.Items...) } return res, r.Err }