allow subject access review to non-existent namespace

pull/6/head
deads2k 2017-02-28 08:29:16 -05:00
parent bf984aa328
commit bde5f800ad
3 changed files with 37 additions and 0 deletions

View File

@ -21,6 +21,7 @@ go_library(
"//vendor:github.com/golang/glog",
"//vendor:k8s.io/apimachinery/pkg/api/errors",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
"//vendor:k8s.io/apimachinery/pkg/util/sets",
"//vendor:k8s.io/apiserver/pkg/admission",
"//vendor:k8s.io/apiserver/pkg/util/cache",
@ -41,6 +42,7 @@ go_test(
"//pkg/kubeapiserver/admission:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/runtime",
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
"//vendor:k8s.io/apimachinery/pkg/util/sets",
"//vendor:k8s.io/apimachinery/pkg/util/wait",
"//vendor:k8s.io/apiserver/pkg/admission",

View File

@ -25,6 +25,7 @@ import (
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apiserver/pkg/admission"
utilcache "k8s.io/apiserver/pkg/util/cache"
@ -103,6 +104,11 @@ func (l *lifecycle) Admit(a admission.Attributes) error {
return nil
}
// always allow access review checks. Returning status about the namespace would be leaking information
if isAccessReview(a) {
return nil
}
// we need to wait for our caches to warm
if !l.WaitForReady() {
return admission.NewForbidden(a, fmt.Errorf("not yet ready to handle request"))
@ -206,3 +212,13 @@ func (l *lifecycle) Validate() error {
}
return nil
}
// accessReviewResources are resources which give a view into permissions in a namespace. Users must be allowed to create these
// resources because returning "not found" errors allows someone to search for the "people I'm going to fire in 2017" namespace.
var accessReviewResources = map[schema.GroupResource]bool{
schema.GroupResource{Group: "authorization.k8s.io", Resource: "localsubjectaccessreviews"}: true,
}
func isAccessReview(a admission.Attributes) bool {
return accessReviewResources[a.GetResource().GroupResource()]
}

View File

@ -23,6 +23,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/apiserver/pkg/admission"
@ -91,6 +92,24 @@ func newPod(namespace string) api.Pod {
}
}
func TestAccessReviewCheckOnMissingNamespace(t *testing.T) {
namespace := "test"
mockClient := newMockClientForTest(map[string]api.NamespacePhase{})
mockClient.AddReactor("get", "namespaces", func(action core.Action) (bool, runtime.Object, error) {
return true, nil, fmt.Errorf("nope, out of luck")
})
handler, informerFactory, err := newHandlerForTest(mockClient)
if err != nil {
t.Errorf("unexpected error initializing handler: %v", err)
}
informerFactory.Start(wait.NeverStop)
err = handler.Admit(admission.NewAttributesRecord(nil, nil, schema.GroupVersionKind{Group: "authorization.k8s.io", Version: "v1", Kind: "LocalSubjectAccesReview"}, namespace, "", schema.GroupVersionResource{Group: "authorization.k8s.io", Version: "v1", Resource: "localsubjectaccessreviews"}, "", admission.Create, nil))
if err != nil {
t.Error(err)
}
}
// TestAdmissionNamespaceDoesNotExist verifies pod is not admitted if namespace does not exist.
func TestAdmissionNamespaceDoesNotExist(t *testing.T) {
namespace := "test"