mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-14 18:53:35 +00:00
Fresh dep ensure
This commit is contained in:
1
vendor/k8s.io/kubernetes/plugin/pkg/auth/OWNERS
generated
vendored
1
vendor/k8s.io/kubernetes/plugin/pkg/auth/OWNERS
generated
vendored
@ -7,6 +7,5 @@ reviewers:
|
||||
- erictune
|
||||
- liggitt
|
||||
- deads2k
|
||||
- ericchiang
|
||||
- enj
|
||||
- mikedanese
|
||||
|
7
vendor/k8s.io/kubernetes/plugin/pkg/auth/authenticator/OWNERS
generated
vendored
Normal file
7
vendor/k8s.io/kubernetes/plugin/pkg/auth/authenticator/OWNERS
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
approvers:
|
||||
- sig-auth-authenticators-approvers
|
||||
reviewers:
|
||||
- sig-auth-authenticators-reviewers
|
||||
labels:
|
||||
- sig/auth
|
||||
|
31
vendor/k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/bootstrap/BUILD
generated
vendored
31
vendor/k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/bootstrap/BUILD
generated
vendored
@ -11,13 +11,13 @@ go_test(
|
||||
srcs = ["bootstrap_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/bootstrap/token/api:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//staging/src/k8s.io/cluster-bootstrap/token/api:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@ -26,14 +26,15 @@ go_library(
|
||||
srcs = ["bootstrap.go"],
|
||||
importpath = "k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/bootstrap",
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/client/listers/core/internalversion:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/bootstrap/token/api:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/bootstrap/token/util:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/listers/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/cluster-bootstrap/token/api:go_default_library",
|
||||
"//staging/src/k8s.io/cluster-bootstrap/token/util:go_default_library",
|
||||
"//vendor/k8s.io/klog:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
46
vendor/k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/bootstrap/bootstrap.go
generated
vendored
46
vendor/k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/bootstrap/bootstrap.go
generated
vendored
@ -20,21 +20,23 @@ Package bootstrap provides a token authenticator for TLS bootstrap secrets.
|
||||
package bootstrap
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/subtle"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/klog"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apiserver/pkg/authentication/authenticator"
|
||||
"k8s.io/apiserver/pkg/authentication/user"
|
||||
bootstrapapi "k8s.io/client-go/tools/bootstrap/token/api"
|
||||
bootstraputil "k8s.io/client-go/tools/bootstrap/token/util"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/client/listers/core/internalversion"
|
||||
corev1listers "k8s.io/client-go/listers/core/v1"
|
||||
bootstrapapi "k8s.io/cluster-bootstrap/token/api"
|
||||
bootstraputil "k8s.io/cluster-bootstrap/token/util"
|
||||
)
|
||||
|
||||
// TODO: A few methods in this package is copied from other sources. Either
|
||||
@ -44,13 +46,13 @@ import (
|
||||
// NewTokenAuthenticator initializes a bootstrap token authenticator.
|
||||
//
|
||||
// Lister is expected to be for the "kube-system" namespace.
|
||||
func NewTokenAuthenticator(lister internalversion.SecretNamespaceLister) *TokenAuthenticator {
|
||||
func NewTokenAuthenticator(lister corev1listers.SecretNamespaceLister) *TokenAuthenticator {
|
||||
return &TokenAuthenticator{lister}
|
||||
}
|
||||
|
||||
// TokenAuthenticator authenticates bootstrap tokens from secrets in the API server.
|
||||
type TokenAuthenticator struct {
|
||||
lister internalversion.SecretNamespaceLister
|
||||
lister corev1listers.SecretNamespaceLister
|
||||
}
|
||||
|
||||
// tokenErrorf prints a error message for a secret that has matched a bearer
|
||||
@ -58,9 +60,9 @@ type TokenAuthenticator struct {
|
||||
//
|
||||
// tokenErrorf(secret, "has invalid value for key %s", key)
|
||||
//
|
||||
func tokenErrorf(s *api.Secret, format string, i ...interface{}) {
|
||||
func tokenErrorf(s *corev1.Secret, format string, i ...interface{}) {
|
||||
format = fmt.Sprintf("Bootstrap secret %s/%s matching bearer token ", s.Namespace, s.Name) + format
|
||||
glog.V(3).Infof(format, i...)
|
||||
klog.V(3).Infof(format, i...)
|
||||
}
|
||||
|
||||
// AuthenticateToken tries to match the provided token to a bootstrap token secret
|
||||
@ -89,7 +91,7 @@ func tokenErrorf(s *api.Secret, format string, i ...interface{}) {
|
||||
//
|
||||
// ( token-id ).( token-secret )
|
||||
//
|
||||
func (t *TokenAuthenticator) AuthenticateToken(token string) (user.Info, bool, error) {
|
||||
func (t *TokenAuthenticator) AuthenticateToken(ctx context.Context, token string) (*authenticator.Response, bool, error) {
|
||||
tokenID, tokenSecret, err := parseToken(token)
|
||||
if err != nil {
|
||||
// Token isn't of the correct form, ignore it.
|
||||
@ -100,7 +102,7 @@ func (t *TokenAuthenticator) AuthenticateToken(token string) (user.Info, bool, e
|
||||
secret, err := t.lister.Get(secretName)
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
glog.V(3).Infof("No secret of name %s to match bootstrap bearer token", secretName)
|
||||
klog.V(3).Infof("No secret of name %s to match bootstrap bearer token", secretName)
|
||||
return nil, false, nil
|
||||
}
|
||||
return nil, false, err
|
||||
@ -144,14 +146,16 @@ func (t *TokenAuthenticator) AuthenticateToken(token string) (user.Info, bool, e
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
return &user.DefaultInfo{
|
||||
Name: bootstrapapi.BootstrapUserPrefix + string(id),
|
||||
Groups: groups,
|
||||
return &authenticator.Response{
|
||||
User: &user.DefaultInfo{
|
||||
Name: bootstrapapi.BootstrapUserPrefix + string(id),
|
||||
Groups: groups,
|
||||
},
|
||||
}, true, nil
|
||||
}
|
||||
|
||||
// Copied from k8s.io/client-go/tools/bootstrap/token/api
|
||||
func getSecretString(secret *api.Secret, key string) string {
|
||||
// Copied from k8s.io/cluster-bootstrap/token/api
|
||||
func getSecretString(secret *corev1.Secret, key string) string {
|
||||
data, ok := secret.Data[key]
|
||||
if !ok {
|
||||
return ""
|
||||
@ -160,18 +164,18 @@ func getSecretString(secret *api.Secret, key string) string {
|
||||
return string(data)
|
||||
}
|
||||
|
||||
// Copied from k8s.io/client-go/tools/bootstrap/token/api
|
||||
func isSecretExpired(secret *api.Secret) bool {
|
||||
// Copied from k8s.io/cluster-bootstrap/token/api
|
||||
func isSecretExpired(secret *corev1.Secret) bool {
|
||||
expiration := getSecretString(secret, bootstrapapi.BootstrapTokenExpirationKey)
|
||||
if len(expiration) > 0 {
|
||||
expTime, err2 := time.Parse(time.RFC3339, expiration)
|
||||
if err2 != nil {
|
||||
glog.V(3).Infof("Unparseable expiration time (%s) in %s/%s Secret: %v. Treating as expired.",
|
||||
klog.V(3).Infof("Unparseable expiration time (%s) in %s/%s Secret: %v. Treating as expired.",
|
||||
expiration, secret.Namespace, secret.Name, err2)
|
||||
return true
|
||||
}
|
||||
if time.Now().After(expTime) {
|
||||
glog.V(3).Infof("Expired bootstrap token in %s/%s Secret: %v",
|
||||
klog.V(3).Infof("Expired bootstrap token in %s/%s Secret: %v",
|
||||
secret.Namespace, secret.Name, expiration)
|
||||
return true
|
||||
}
|
||||
@ -201,7 +205,7 @@ func parseToken(s string) (string, string, error) {
|
||||
// getGroups loads and validates the bootstrapapi.BootstrapTokenExtraGroupsKey
|
||||
// key from the bootstrap token secret, returning a list of group names or an
|
||||
// error if any of the group names are invalid.
|
||||
func getGroups(secret *api.Secret) ([]string, error) {
|
||||
func getGroups(secret *corev1.Secret) ([]string, error) {
|
||||
// always include the default group
|
||||
groups := sets.NewString(bootstrapapi.BootstrapDefaultGroup)
|
||||
|
||||
|
48
vendor/k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/bootstrap/bootstrap_test.go
generated
vendored
48
vendor/k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/bootstrap/bootstrap_test.go
generated
vendored
@ -17,27 +17,28 @@ limitations under the License.
|
||||
package bootstrap
|
||||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apiserver/pkg/authentication/user"
|
||||
bootstrapapi "k8s.io/client-go/tools/bootstrap/token/api"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
bootstrapapi "k8s.io/cluster-bootstrap/token/api"
|
||||
)
|
||||
|
||||
type lister struct {
|
||||
secrets []*api.Secret
|
||||
secrets []*corev1.Secret
|
||||
}
|
||||
|
||||
func (l *lister) List(selector labels.Selector) (ret []*api.Secret, err error) {
|
||||
func (l *lister) List(selector labels.Selector) (ret []*corev1.Secret, err error) {
|
||||
return l.secrets, nil
|
||||
}
|
||||
|
||||
func (l *lister) Get(name string) (*api.Secret, error) {
|
||||
func (l *lister) Get(name string) (*corev1.Secret, error) {
|
||||
for _, s := range l.secrets {
|
||||
if s.Name == name {
|
||||
return s, nil
|
||||
@ -57,7 +58,7 @@ func TestTokenAuthenticator(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
||||
secrets []*api.Secret
|
||||
secrets []*corev1.Secret
|
||||
token string
|
||||
|
||||
wantNotFound bool
|
||||
@ -65,7 +66,7 @@ func TestTokenAuthenticator(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "valid token",
|
||||
secrets: []*api.Secret{
|
||||
secrets: []*corev1.Secret{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: bootstrapapi.BootstrapTokenSecretPrefix + tokenID,
|
||||
@ -86,7 +87,7 @@ func TestTokenAuthenticator(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "valid token with extra group",
|
||||
secrets: []*api.Secret{
|
||||
secrets: []*corev1.Secret{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: bootstrapapi.BootstrapTokenSecretPrefix + tokenID,
|
||||
@ -108,7 +109,7 @@ func TestTokenAuthenticator(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "invalid group",
|
||||
secrets: []*api.Secret{
|
||||
secrets: []*corev1.Secret{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: bootstrapapi.BootstrapTokenSecretPrefix + tokenID,
|
||||
@ -127,7 +128,7 @@ func TestTokenAuthenticator(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "invalid secret name",
|
||||
secrets: []*api.Secret{
|
||||
secrets: []*corev1.Secret{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "bad-name",
|
||||
@ -145,7 +146,7 @@ func TestTokenAuthenticator(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "no usage",
|
||||
secrets: []*api.Secret{
|
||||
secrets: []*corev1.Secret{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: bootstrapapi.BootstrapTokenSecretPrefix + tokenID,
|
||||
@ -162,7 +163,7 @@ func TestTokenAuthenticator(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "wrong token",
|
||||
secrets: []*api.Secret{
|
||||
secrets: []*corev1.Secret{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: bootstrapapi.BootstrapTokenSecretPrefix + tokenID,
|
||||
@ -180,7 +181,7 @@ func TestTokenAuthenticator(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "deleted token",
|
||||
secrets: []*api.Secret{
|
||||
secrets: []*corev1.Secret{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: bootstrapapi.BootstrapTokenSecretPrefix + tokenID,
|
||||
@ -199,7 +200,7 @@ func TestTokenAuthenticator(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "expired token",
|
||||
secrets: []*api.Secret{
|
||||
secrets: []*corev1.Secret{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: bootstrapapi.BootstrapTokenSecretPrefix + tokenID,
|
||||
@ -218,7 +219,7 @@ func TestTokenAuthenticator(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "not expired token",
|
||||
secrets: []*api.Secret{
|
||||
secrets: []*corev1.Secret{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: bootstrapapi.BootstrapTokenSecretPrefix + tokenID,
|
||||
@ -240,7 +241,7 @@ func TestTokenAuthenticator(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "token id wrong length",
|
||||
secrets: []*api.Secret{
|
||||
secrets: []*corev1.Secret{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: bootstrapapi.BootstrapTokenSecretPrefix + "foo",
|
||||
@ -262,7 +263,7 @@ func TestTokenAuthenticator(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
func() {
|
||||
a := NewTokenAuthenticator(&lister{test.secrets})
|
||||
u, found, err := a.AuthenticateToken(test.token)
|
||||
resp, found, err := a.AuthenticateToken(context.Background(), test.token)
|
||||
if err != nil {
|
||||
t.Errorf("test %q returned an error: %v", test.name, err)
|
||||
return
|
||||
@ -280,8 +281,7 @@ func TestTokenAuthenticator(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
gotUser := u.(*user.DefaultInfo)
|
||||
|
||||
gotUser := resp.User.(*user.DefaultInfo)
|
||||
if !reflect.DeepEqual(gotUser, test.wantUser) {
|
||||
t.Errorf("test %q want user=%#v, got=%#v", test.name, test.wantUser, gotUser)
|
||||
}
|
||||
@ -292,13 +292,13 @@ func TestTokenAuthenticator(t *testing.T) {
|
||||
func TestGetGroups(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
secret *api.Secret
|
||||
secret *corev1.Secret
|
||||
expectResult []string
|
||||
expectError bool
|
||||
}{
|
||||
{
|
||||
name: "not set",
|
||||
secret: &api.Secret{
|
||||
secret: &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "test"},
|
||||
Data: map[string][]byte{},
|
||||
},
|
||||
@ -306,7 +306,7 @@ func TestGetGroups(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "set to empty value",
|
||||
secret: &api.Secret{
|
||||
secret: &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "test"},
|
||||
Data: map[string][]byte{
|
||||
bootstrapapi.BootstrapTokenExtraGroupsKey: []byte(""),
|
||||
@ -316,7 +316,7 @@ func TestGetGroups(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "invalid prefix",
|
||||
secret: &api.Secret{
|
||||
secret: &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "test"},
|
||||
Data: map[string][]byte{
|
||||
bootstrapapi.BootstrapTokenExtraGroupsKey: []byte("foo"),
|
||||
@ -326,7 +326,7 @@ func TestGetGroups(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "valid",
|
||||
secret: &api.Secret{
|
||||
secret: &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "test"},
|
||||
Data: map[string][]byte{
|
||||
bootstrapapi.BootstrapTokenExtraGroupsKey: []byte("system:bootstrappers:foo,system:bootstrappers:bar,system:bootstrappers:bar"),
|
||||
|
7
vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/OWNERS
generated
vendored
Normal file
7
vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/OWNERS
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
approvers:
|
||||
- sig-auth-authorizers-approvers
|
||||
reviewers:
|
||||
- sig-auth-authorizers-reviewers
|
||||
labels:
|
||||
- sig/auth
|
||||
|
39
vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/node/BUILD
generated
vendored
39
vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/node/BUILD
generated
vendored
@ -15,17 +15,17 @@ go_test(
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/auth/nodeidentifier:go_default_library",
|
||||
"//pkg/features:go_default_library",
|
||||
"//plugin/pkg/auth/authorizer/rbac/bootstrappolicy:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/storage/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
||||
"//vendor/k8s.io/api/storage/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@ -39,25 +39,28 @@ go_library(
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/plugin/pkg/auth/authorizer/node",
|
||||
deps = [
|
||||
"//pkg/api/persistentvolume:go_default_library",
|
||||
"//pkg/api/pod:go_default_library",
|
||||
"//pkg/api/v1/persistentvolume:go_default_library",
|
||||
"//pkg/api/v1/pod:go_default_library",
|
||||
"//pkg/apis/coordination:go_default_library",
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/apis/storage:go_default_library",
|
||||
"//pkg/auth/nodeidentifier:go_default_library",
|
||||
"//pkg/client/informers/informers_generated/internalversion/core/internalversion:go_default_library",
|
||||
"//pkg/features:go_default_library",
|
||||
"//plugin/pkg/auth/authorizer/rbac:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/rbac/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/storage/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/informers/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/informers/storage/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/tools/cache:go_default_library",
|
||||
"//staging/src/k8s.io/csi-api/pkg/apis/csi/v1alpha1:go_default_library",
|
||||
"//third_party/forked/gonum/graph:go_default_library",
|
||||
"//third_party/forked/gonum/graph/simple:go_default_library",
|
||||
"//third_party/forked/gonum/graph/traverse:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/api/rbac/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/storage/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//vendor/k8s.io/client-go/informers/storage/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
|
||||
"//vendor/k8s.io/klog:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
12
vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/node/OWNERS
generated
vendored
12
vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/node/OWNERS
generated
vendored
@ -1,9 +1,7 @@
|
||||
approvers:
|
||||
- tallclair
|
||||
- liggitt
|
||||
- deads2k
|
||||
- sig-auth-node-isolation-approvers
|
||||
reviewers:
|
||||
- tallclair
|
||||
- liggitt
|
||||
- deads2k
|
||||
- ericchiang
|
||||
- sig-auth-node-isolation-reviewers
|
||||
labels:
|
||||
- sig/auth
|
||||
|
||||
|
17
vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/node/graph.go
generated
vendored
17
vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/node/graph.go
generated
vendored
@ -19,9 +19,9 @@ package node
|
||||
import (
|
||||
"sync"
|
||||
|
||||
pvutil "k8s.io/kubernetes/pkg/api/persistentvolume"
|
||||
podutil "k8s.io/kubernetes/pkg/api/pod"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
pvutil "k8s.io/kubernetes/pkg/api/v1/persistentvolume"
|
||||
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
|
||||
"k8s.io/kubernetes/third_party/forked/gonum/graph"
|
||||
"k8s.io/kubernetes/third_party/forked/gonum/graph/simple"
|
||||
)
|
||||
@ -305,7 +305,7 @@ func (g *Graph) recomputeDestinationIndex_locked(n graph.Node) {
|
||||
// configmap -> pod
|
||||
// pvc -> pod
|
||||
// svcacct -> pod
|
||||
func (g *Graph) AddPod(pod *api.Pod) {
|
||||
func (g *Graph) AddPod(pod *corev1.Pod) {
|
||||
g.lock.Lock()
|
||||
defer g.lock.Unlock()
|
||||
|
||||
@ -314,6 +314,13 @@ func (g *Graph) AddPod(pod *api.Pod) {
|
||||
nodeVertex := g.getOrCreateVertex_locked(nodeVertexType, "", pod.Spec.NodeName)
|
||||
g.graph.SetEdge(newDestinationEdge(podVertex, nodeVertex, nodeVertex))
|
||||
|
||||
// Short-circuit adding edges to other resources for mirror pods.
|
||||
// A node must never be able to create a pod that grants them permissions on other API objects.
|
||||
// The NodeRestriction admission plugin prevents creation of such pods, but short-circuiting here gives us defense in depth.
|
||||
if _, isMirrorPod := pod.Annotations[corev1.MirrorPodAnnotationKey]; isMirrorPod {
|
||||
return
|
||||
}
|
||||
|
||||
// TODO(mikedanese): If the pod doesn't mount the service account secrets,
|
||||
// should the node still get access to the service account?
|
||||
//
|
||||
@ -357,7 +364,7 @@ func (g *Graph) DeletePod(name, namespace string) {
|
||||
// secret -> pv
|
||||
//
|
||||
// pv -> pvc
|
||||
func (g *Graph) AddPV(pv *api.PersistentVolume) {
|
||||
func (g *Graph) AddPV(pv *corev1.PersistentVolume) {
|
||||
g.lock.Lock()
|
||||
defer g.lock.Unlock()
|
||||
|
||||
|
52
vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/node/graph_populator.go
generated
vendored
52
vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/node/graph_populator.go
generated
vendored
@ -18,14 +18,14 @@ package node
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/klog"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
storagev1beta1 "k8s.io/api/storage/v1beta1"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
corev1informers "k8s.io/client-go/informers/core/v1"
|
||||
storageinformers "k8s.io/client-go/informers/storage/v1beta1"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
coreinformers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/core/internalversion"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
)
|
||||
|
||||
@ -35,9 +35,9 @@ type graphPopulator struct {
|
||||
|
||||
func AddGraphEventHandlers(
|
||||
graph *Graph,
|
||||
nodes coreinformers.NodeInformer,
|
||||
pods coreinformers.PodInformer,
|
||||
pvs coreinformers.PersistentVolumeInformer,
|
||||
nodes corev1informers.NodeInformer,
|
||||
pods corev1informers.PodInformer,
|
||||
pvs corev1informers.PersistentVolumeInformer,
|
||||
attachments storageinformers.VolumeAttachmentInformer,
|
||||
) {
|
||||
g := &graphPopulator{
|
||||
@ -78,10 +78,10 @@ func (g *graphPopulator) addNode(obj interface{}) {
|
||||
}
|
||||
|
||||
func (g *graphPopulator) updateNode(oldObj, obj interface{}) {
|
||||
node := obj.(*api.Node)
|
||||
var oldNode *api.Node
|
||||
node := obj.(*corev1.Node)
|
||||
var oldNode *corev1.Node
|
||||
if oldObj != nil {
|
||||
oldNode = oldObj.(*api.Node)
|
||||
oldNode = oldObj.(*corev1.Node)
|
||||
}
|
||||
|
||||
// we only set up rules for ConfigMap today, because that is the only reference type
|
||||
@ -109,7 +109,7 @@ func (g *graphPopulator) updateNode(oldObj, obj interface{}) {
|
||||
if node.Spec.ConfigSource != nil {
|
||||
path = fmt.Sprintf("%s/%s", namespace, name)
|
||||
}
|
||||
glog.V(4).Infof("updateNode configSource reference to %s for node %s", path, node.Name)
|
||||
klog.V(4).Infof("updateNode configSource reference to %s for node %s", path, node.Name)
|
||||
g.graph.SetNodeConfigMap(node.Name, name, namespace)
|
||||
}
|
||||
|
||||
@ -117,9 +117,9 @@ func (g *graphPopulator) deleteNode(obj interface{}) {
|
||||
if tombstone, ok := obj.(cache.DeletedFinalStateUnknown); ok {
|
||||
obj = tombstone.Obj
|
||||
}
|
||||
node, ok := obj.(*api.Node)
|
||||
node, ok := obj.(*corev1.Node)
|
||||
if !ok {
|
||||
glog.Infof("unexpected type %T", obj)
|
||||
klog.Infof("unexpected type %T", obj)
|
||||
return
|
||||
}
|
||||
|
||||
@ -134,20 +134,20 @@ func (g *graphPopulator) addPod(obj interface{}) {
|
||||
}
|
||||
|
||||
func (g *graphPopulator) updatePod(oldObj, obj interface{}) {
|
||||
pod := obj.(*api.Pod)
|
||||
pod := obj.(*corev1.Pod)
|
||||
if len(pod.Spec.NodeName) == 0 {
|
||||
// No node assigned
|
||||
glog.V(5).Infof("updatePod %s/%s, no node", pod.Namespace, pod.Name)
|
||||
klog.V(5).Infof("updatePod %s/%s, no node", pod.Namespace, pod.Name)
|
||||
return
|
||||
}
|
||||
if oldPod, ok := oldObj.(*api.Pod); ok && oldPod != nil {
|
||||
if oldPod, ok := oldObj.(*corev1.Pod); ok && oldPod != nil {
|
||||
if (pod.Spec.NodeName == oldPod.Spec.NodeName) && (pod.UID == oldPod.UID) {
|
||||
// Node and uid are unchanged, all object references in the pod spec are immutable
|
||||
glog.V(5).Infof("updatePod %s/%s, node unchanged", pod.Namespace, pod.Name)
|
||||
klog.V(5).Infof("updatePod %s/%s, node unchanged", pod.Namespace, pod.Name)
|
||||
return
|
||||
}
|
||||
}
|
||||
glog.V(4).Infof("updatePod %s/%s for node %s", pod.Namespace, pod.Name, pod.Spec.NodeName)
|
||||
klog.V(4).Infof("updatePod %s/%s for node %s", pod.Namespace, pod.Name, pod.Spec.NodeName)
|
||||
g.graph.AddPod(pod)
|
||||
}
|
||||
|
||||
@ -155,16 +155,16 @@ func (g *graphPopulator) deletePod(obj interface{}) {
|
||||
if tombstone, ok := obj.(cache.DeletedFinalStateUnknown); ok {
|
||||
obj = tombstone.Obj
|
||||
}
|
||||
pod, ok := obj.(*api.Pod)
|
||||
pod, ok := obj.(*corev1.Pod)
|
||||
if !ok {
|
||||
glog.Infof("unexpected type %T", obj)
|
||||
klog.Infof("unexpected type %T", obj)
|
||||
return
|
||||
}
|
||||
if len(pod.Spec.NodeName) == 0 {
|
||||
glog.V(5).Infof("deletePod %s/%s, no node", pod.Namespace, pod.Name)
|
||||
klog.V(5).Infof("deletePod %s/%s, no node", pod.Namespace, pod.Name)
|
||||
return
|
||||
}
|
||||
glog.V(4).Infof("deletePod %s/%s for node %s", pod.Namespace, pod.Name, pod.Spec.NodeName)
|
||||
klog.V(4).Infof("deletePod %s/%s for node %s", pod.Namespace, pod.Name, pod.Spec.NodeName)
|
||||
g.graph.DeletePod(pod.Name, pod.Namespace)
|
||||
}
|
||||
|
||||
@ -173,7 +173,7 @@ func (g *graphPopulator) addPV(obj interface{}) {
|
||||
}
|
||||
|
||||
func (g *graphPopulator) updatePV(oldObj, obj interface{}) {
|
||||
pv := obj.(*api.PersistentVolume)
|
||||
pv := obj.(*corev1.PersistentVolume)
|
||||
// TODO: skip add if uid, pvc, and secrets are all identical between old and new
|
||||
g.graph.AddPV(pv)
|
||||
}
|
||||
@ -182,9 +182,9 @@ func (g *graphPopulator) deletePV(obj interface{}) {
|
||||
if tombstone, ok := obj.(cache.DeletedFinalStateUnknown); ok {
|
||||
obj = tombstone.Obj
|
||||
}
|
||||
pv, ok := obj.(*api.PersistentVolume)
|
||||
pv, ok := obj.(*corev1.PersistentVolume)
|
||||
if !ok {
|
||||
glog.Infof("unexpected type %T", obj)
|
||||
klog.Infof("unexpected type %T", obj)
|
||||
return
|
||||
}
|
||||
g.graph.DeletePV(pv.Name)
|
||||
@ -210,9 +210,9 @@ func (g *graphPopulator) deleteVolumeAttachment(obj interface{}) {
|
||||
if tombstone, ok := obj.(cache.DeletedFinalStateUnknown); ok {
|
||||
obj = tombstone.Obj
|
||||
}
|
||||
attachment, ok := obj.(*api.PersistentVolume)
|
||||
attachment, ok := obj.(*storagev1beta1.VolumeAttachment)
|
||||
if !ok {
|
||||
glog.Infof("unexpected type %T", obj)
|
||||
klog.Infof("unexpected type %T", obj)
|
||||
return
|
||||
}
|
||||
g.graph.DeleteVolumeAttachment(attachment.Name)
|
||||
|
118
vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/node/node_authorizer.go
generated
vendored
118
vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/node/node_authorizer.go
generated
vendored
@ -19,12 +19,14 @@ package node
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/klog"
|
||||
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
csiv1alpha1 "k8s.io/csi-api/pkg/apis/csi/v1alpha1"
|
||||
coordapi "k8s.io/kubernetes/pkg/apis/coordination"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
storageapi "k8s.io/kubernetes/pkg/apis/storage"
|
||||
"k8s.io/kubernetes/pkg/auth/nodeidentifier"
|
||||
@ -66,12 +68,14 @@ func NewAuthorizer(graph *Graph, identifier nodeidentifier.NodeIdentifier, rules
|
||||
}
|
||||
|
||||
var (
|
||||
configMapResource = api.Resource("configmaps")
|
||||
secretResource = api.Resource("secrets")
|
||||
pvcResource = api.Resource("persistentvolumeclaims")
|
||||
pvResource = api.Resource("persistentvolumes")
|
||||
vaResource = storageapi.Resource("volumeattachments")
|
||||
svcAcctResource = api.Resource("serviceaccounts")
|
||||
configMapResource = api.Resource("configmaps")
|
||||
secretResource = api.Resource("secrets")
|
||||
pvcResource = api.Resource("persistentvolumeclaims")
|
||||
pvResource = api.Resource("persistentvolumes")
|
||||
vaResource = storageapi.Resource("volumeattachments")
|
||||
svcAcctResource = api.Resource("serviceaccounts")
|
||||
leaseResource = coordapi.Resource("leases")
|
||||
csiNodeInfoResource = csiv1alpha1.Resource("csinodeinfos")
|
||||
)
|
||||
|
||||
func (r *NodeAuthorizer) Authorize(attrs authorizer.Attributes) (authorizer.Decision, string, error) {
|
||||
@ -82,7 +86,7 @@ func (r *NodeAuthorizer) Authorize(attrs authorizer.Attributes) (authorizer.Deci
|
||||
}
|
||||
if len(nodeName) == 0 {
|
||||
// reject requests from unidentifiable nodes
|
||||
glog.V(2).Infof("NODE DENY: unknown node for user %q", attrs.GetUser().GetName())
|
||||
klog.V(2).Infof("NODE DENY: unknown node for user %q", attrs.GetUser().GetName())
|
||||
return authorizer.DecisionNoOpinion, fmt.Sprintf("unknown node for user %q", attrs.GetUser().GetName()), nil
|
||||
}
|
||||
|
||||
@ -113,7 +117,18 @@ func (r *NodeAuthorizer) Authorize(attrs authorizer.Attributes) (authorizer.Deci
|
||||
return r.authorizeCreateToken(nodeName, serviceAccountVertexType, attrs)
|
||||
}
|
||||
return authorizer.DecisionNoOpinion, fmt.Sprintf("disabled by feature gate %s", features.TokenRequest), nil
|
||||
case leaseResource:
|
||||
if r.features.Enabled(features.NodeLease) {
|
||||
return r.authorizeLease(nodeName, attrs)
|
||||
}
|
||||
return authorizer.DecisionNoOpinion, fmt.Sprintf("disabled by feature gate %s", features.NodeLease), nil
|
||||
case csiNodeInfoResource:
|
||||
if r.features.Enabled(features.KubeletPluginsWatcher) && r.features.Enabled(features.CSINodeInfo) {
|
||||
return r.authorizeCSINodeInfo(nodeName, attrs)
|
||||
}
|
||||
return authorizer.DecisionNoOpinion, fmt.Sprintf("disabled by feature gates %s and %s", features.KubeletPluginsWatcher, features.CSINodeInfo), nil
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Access to other resources is not subdivided, so just evaluate against the statically defined node rules
|
||||
@ -129,12 +144,12 @@ func (r *NodeAuthorizer) authorizeStatusUpdate(nodeName string, startingType ver
|
||||
case "update", "patch":
|
||||
// ok
|
||||
default:
|
||||
glog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs)
|
||||
klog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs)
|
||||
return authorizer.DecisionNoOpinion, "can only get/update/patch this type", nil
|
||||
}
|
||||
|
||||
if attrs.GetSubresource() != "status" {
|
||||
glog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs)
|
||||
klog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs)
|
||||
return authorizer.DecisionNoOpinion, "can only update status subresource", nil
|
||||
}
|
||||
|
||||
@ -144,11 +159,11 @@ func (r *NodeAuthorizer) authorizeStatusUpdate(nodeName string, startingType ver
|
||||
// authorizeGet authorizes "get" requests to objects of the specified type if they are related to the specified node
|
||||
func (r *NodeAuthorizer) authorizeGet(nodeName string, startingType vertexType, attrs authorizer.Attributes) (authorizer.Decision, string, error) {
|
||||
if attrs.GetVerb() != "get" {
|
||||
glog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs)
|
||||
klog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs)
|
||||
return authorizer.DecisionNoOpinion, "can only get individual resources of this type", nil
|
||||
}
|
||||
if len(attrs.GetSubresource()) > 0 {
|
||||
glog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs)
|
||||
klog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs)
|
||||
return authorizer.DecisionNoOpinion, "cannot get subresource", nil
|
||||
}
|
||||
return r.authorize(nodeName, startingType, attrs)
|
||||
@ -158,15 +173,15 @@ func (r *NodeAuthorizer) authorizeGet(nodeName string, startingType vertexType,
|
||||
// specified types if they are related to the specified node.
|
||||
func (r *NodeAuthorizer) authorizeReadNamespacedObject(nodeName string, startingType vertexType, attrs authorizer.Attributes) (authorizer.Decision, string, error) {
|
||||
if attrs.GetVerb() != "get" && attrs.GetVerb() != "list" && attrs.GetVerb() != "watch" {
|
||||
glog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs)
|
||||
klog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs)
|
||||
return authorizer.DecisionNoOpinion, "can only read resources of this type", nil
|
||||
}
|
||||
if len(attrs.GetSubresource()) > 0 {
|
||||
glog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs)
|
||||
klog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs)
|
||||
return authorizer.DecisionNoOpinion, "cannot read subresource", nil
|
||||
}
|
||||
if len(attrs.GetNamespace()) == 0 {
|
||||
glog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs)
|
||||
klog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs)
|
||||
return authorizer.DecisionNoOpinion, "can only read namespaced object of this type", nil
|
||||
}
|
||||
return r.authorize(nodeName, startingType, attrs)
|
||||
@ -174,17 +189,17 @@ func (r *NodeAuthorizer) authorizeReadNamespacedObject(nodeName string, starting
|
||||
|
||||
func (r *NodeAuthorizer) authorize(nodeName string, startingType vertexType, attrs authorizer.Attributes) (authorizer.Decision, string, error) {
|
||||
if len(attrs.GetName()) == 0 {
|
||||
glog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs)
|
||||
klog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs)
|
||||
return authorizer.DecisionNoOpinion, "No Object name found", nil
|
||||
}
|
||||
|
||||
ok, err := r.hasPathFrom(nodeName, startingType, attrs.GetNamespace(), attrs.GetName())
|
||||
if err != nil {
|
||||
glog.V(2).Infof("NODE DENY: %v", err)
|
||||
klog.V(2).Infof("NODE DENY: %v", err)
|
||||
return authorizer.DecisionNoOpinion, "no path found to object", nil
|
||||
}
|
||||
if !ok {
|
||||
glog.V(2).Infof("NODE DENY: %q %#v", nodeName, attrs)
|
||||
klog.V(2).Infof("NODE DENY: %q %#v", nodeName, attrs)
|
||||
return authorizer.DecisionNoOpinion, "no path found to object", nil
|
||||
}
|
||||
return authorizer.DecisionAllow, "", nil
|
||||
@ -194,27 +209,86 @@ func (r *NodeAuthorizer) authorize(nodeName string, startingType vertexType, att
|
||||
// subresource of pods running on a node
|
||||
func (r *NodeAuthorizer) authorizeCreateToken(nodeName string, startingType vertexType, attrs authorizer.Attributes) (authorizer.Decision, string, error) {
|
||||
if attrs.GetVerb() != "create" || len(attrs.GetName()) == 0 {
|
||||
glog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs)
|
||||
klog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs)
|
||||
return authorizer.DecisionNoOpinion, "can only create tokens for individual service accounts", nil
|
||||
}
|
||||
|
||||
if attrs.GetSubresource() != "token" {
|
||||
glog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs)
|
||||
klog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs)
|
||||
return authorizer.DecisionNoOpinion, "can only create token subresource of serviceaccount", nil
|
||||
}
|
||||
|
||||
ok, err := r.hasPathFrom(nodeName, startingType, attrs.GetNamespace(), attrs.GetName())
|
||||
if err != nil {
|
||||
glog.V(2).Infof("NODE DENY: %v", err)
|
||||
klog.V(2).Infof("NODE DENY: %v", err)
|
||||
return authorizer.DecisionNoOpinion, "no path found to object", nil
|
||||
}
|
||||
if !ok {
|
||||
glog.V(2).Infof("NODE DENY: %q %#v", nodeName, attrs)
|
||||
klog.V(2).Infof("NODE DENY: %q %#v", nodeName, attrs)
|
||||
return authorizer.DecisionNoOpinion, "no path found to object", nil
|
||||
}
|
||||
return authorizer.DecisionAllow, "", nil
|
||||
}
|
||||
|
||||
// authorizeLease authorizes node requests to coordination.k8s.io/leases.
|
||||
func (r *NodeAuthorizer) authorizeLease(nodeName string, attrs authorizer.Attributes) (authorizer.Decision, string, error) {
|
||||
// allowed verbs: get, create, update, patch, delete
|
||||
verb := attrs.GetVerb()
|
||||
if verb != "get" &&
|
||||
verb != "create" &&
|
||||
verb != "update" &&
|
||||
verb != "patch" &&
|
||||
verb != "delete" {
|
||||
klog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs)
|
||||
return authorizer.DecisionNoOpinion, "can only get, create, update, patch, or delete a node lease", nil
|
||||
}
|
||||
|
||||
// the request must be against the system namespace reserved for node leases
|
||||
if attrs.GetNamespace() != api.NamespaceNodeLease {
|
||||
klog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs)
|
||||
return authorizer.DecisionNoOpinion, fmt.Sprintf("can only access leases in the %q system namespace", api.NamespaceNodeLease), nil
|
||||
}
|
||||
|
||||
// the request must come from a node with the same name as the lease
|
||||
// note we skip this check for create, since the authorizer doesn't know the name on create
|
||||
// the noderestriction admission plugin is capable of performing this check at create time
|
||||
if verb != "create" && attrs.GetName() != nodeName {
|
||||
klog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs)
|
||||
return authorizer.DecisionNoOpinion, "can only access node lease with the same name as the requesting node", nil
|
||||
}
|
||||
|
||||
return authorizer.DecisionAllow, "", nil
|
||||
}
|
||||
|
||||
// authorizeCSINodeInfo authorizes node requests to CSINodeInfo csi.storage.k8s.io/csinodeinfos
|
||||
func (r *NodeAuthorizer) authorizeCSINodeInfo(nodeName string, attrs authorizer.Attributes) (authorizer.Decision, string, error) {
|
||||
// allowed verbs: get, create, update, patch, delete
|
||||
verb := attrs.GetVerb()
|
||||
if verb != "get" &&
|
||||
verb != "create" &&
|
||||
verb != "update" &&
|
||||
verb != "patch" &&
|
||||
verb != "delete" {
|
||||
klog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs)
|
||||
return authorizer.DecisionNoOpinion, "can only get, create, update, patch, or delete a CSINodeInfo", nil
|
||||
}
|
||||
|
||||
if len(attrs.GetSubresource()) > 0 {
|
||||
klog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs)
|
||||
return authorizer.DecisionNoOpinion, "cannot authorize CSINodeInfo subresources", nil
|
||||
}
|
||||
|
||||
// the request must come from a node with the same name as the CSINodeInfo
|
||||
// note we skip this check for create, since the authorizer doesn't know the name on create
|
||||
// the noderestriction admission plugin is capable of performing this check at create time
|
||||
if verb != "create" && attrs.GetName() != nodeName {
|
||||
klog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs)
|
||||
return authorizer.DecisionNoOpinion, "can only access CSINodeInfo with the same name as the requesting node", nil
|
||||
}
|
||||
|
||||
return authorizer.DecisionAllow, "", nil
|
||||
}
|
||||
|
||||
// hasPathFrom returns true if there is a directed path from the specified type/namespace/name to the specified Node
|
||||
func (r *NodeAuthorizer) hasPathFrom(nodeName string, startingType vertexType, startingNamespace, startingName string) (bool, error) {
|
||||
r.graph.lock.RLock()
|
||||
|
307
vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/node/node_authorizer_test.go
generated
vendored
307
vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/node/node_authorizer_test.go
generated
vendored
@ -26,23 +26,27 @@ import (
|
||||
|
||||
"os"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
storagev1beta1 "k8s.io/api/storage/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apiserver/pkg/authentication/user"
|
||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/auth/nodeidentifier"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
"k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/bootstrappolicy"
|
||||
)
|
||||
|
||||
var (
|
||||
csiEnabledFeature = utilfeature.NewFeatureGate()
|
||||
csiDisabledFeature = utilfeature.NewFeatureGate()
|
||||
trEnabledFeature = utilfeature.NewFeatureGate()
|
||||
trDisabledFeature = utilfeature.NewFeatureGate()
|
||||
csiEnabledFeature = utilfeature.NewFeatureGate()
|
||||
csiDisabledFeature = utilfeature.NewFeatureGate()
|
||||
trEnabledFeature = utilfeature.NewFeatureGate()
|
||||
trDisabledFeature = utilfeature.NewFeatureGate()
|
||||
leaseEnabledFeature = utilfeature.NewFeatureGate()
|
||||
leaseDisabledFeature = utilfeature.NewFeatureGate()
|
||||
csiNodeInfoEnabledFeature = utilfeature.NewFeatureGate()
|
||||
csiNodeInfoDisabledFeature = utilfeature.NewFeatureGate()
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -58,6 +62,24 @@ func init() {
|
||||
if err := trDisabledFeature.Add(map[utilfeature.Feature]utilfeature.FeatureSpec{features.TokenRequest: {Default: false}}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := leaseEnabledFeature.Add(map[utilfeature.Feature]utilfeature.FeatureSpec{features.NodeLease: {Default: true}}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := leaseDisabledFeature.Add(map[utilfeature.Feature]utilfeature.FeatureSpec{features.NodeLease: {Default: false}}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := csiNodeInfoEnabledFeature.Add(map[utilfeature.Feature]utilfeature.FeatureSpec{features.KubeletPluginsWatcher: {Default: true}}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := csiNodeInfoEnabledFeature.Add(map[utilfeature.Feature]utilfeature.FeatureSpec{features.CSINodeInfo: {Default: true}}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := csiNodeInfoDisabledFeature.Add(map[utilfeature.Feature]utilfeature.FeatureSpec{features.KubeletPluginsWatcher: {Default: false}}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := csiNodeInfoDisabledFeature.Add(map[utilfeature.Feature]utilfeature.FeatureSpec{features.CSINodeInfo: {Default: false}}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthorizer(t *testing.T) {
|
||||
@ -228,6 +250,187 @@ func TestAuthorizer(t *testing.T) {
|
||||
features: trEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed node lease - feature disabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "leases", APIGroup: "coordination.k8s.io", Name: "node0", Namespace: corev1.NamespaceNodeLease},
|
||||
features: leaseDisabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed get lease in namespace other than kube-node-lease - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "leases", APIGroup: "coordination.k8s.io", Name: "node0", Namespace: "foo"},
|
||||
features: leaseEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed create lease in namespace other than kube-node-lease - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "create", Resource: "leases", APIGroup: "coordination.k8s.io", Name: "node0", Namespace: "foo"},
|
||||
features: leaseEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed update lease in namespace other than kube-node-lease - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "update", Resource: "leases", APIGroup: "coordination.k8s.io", Name: "node0", Namespace: "foo"},
|
||||
features: leaseEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed patch lease in namespace other than kube-node-lease - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "patch", Resource: "leases", APIGroup: "coordination.k8s.io", Name: "node0", Namespace: "foo"},
|
||||
features: leaseEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed delete lease in namespace other than kube-node-lease - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "delete", Resource: "leases", APIGroup: "coordination.k8s.io", Name: "node0", Namespace: "foo"},
|
||||
features: leaseEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed get another node's lease - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "leases", APIGroup: "coordination.k8s.io", Name: "node1", Namespace: corev1.NamespaceNodeLease},
|
||||
features: leaseEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed update another node's lease - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "update", Resource: "leases", APIGroup: "coordination.k8s.io", Name: "node1", Namespace: corev1.NamespaceNodeLease},
|
||||
features: leaseEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed patch another node's lease - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "patch", Resource: "leases", APIGroup: "coordination.k8s.io", Name: "node1", Namespace: corev1.NamespaceNodeLease},
|
||||
features: leaseEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed delete another node's lease - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "delete", Resource: "leases", APIGroup: "coordination.k8s.io", Name: "node1", Namespace: corev1.NamespaceNodeLease},
|
||||
features: leaseEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed list node leases - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "list", Resource: "leases", APIGroup: "coordination.k8s.io", Namespace: corev1.NamespaceNodeLease},
|
||||
features: leaseEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed watch node leases - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "watch", Resource: "leases", APIGroup: "coordination.k8s.io", Namespace: corev1.NamespaceNodeLease},
|
||||
features: leaseEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "allowed get node lease - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "leases", APIGroup: "coordination.k8s.io", Name: "node0", Namespace: corev1.NamespaceNodeLease},
|
||||
features: leaseEnabledFeature,
|
||||
expect: authorizer.DecisionAllow,
|
||||
},
|
||||
{
|
||||
name: "allowed create node lease - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "create", Resource: "leases", APIGroup: "coordination.k8s.io", Name: "node0", Namespace: corev1.NamespaceNodeLease},
|
||||
features: leaseEnabledFeature,
|
||||
expect: authorizer.DecisionAllow,
|
||||
},
|
||||
{
|
||||
name: "allowed update node lease - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "update", Resource: "leases", APIGroup: "coordination.k8s.io", Name: "node0", Namespace: corev1.NamespaceNodeLease},
|
||||
features: leaseEnabledFeature,
|
||||
expect: authorizer.DecisionAllow,
|
||||
},
|
||||
{
|
||||
name: "allowed patch node lease - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "patch", Resource: "leases", APIGroup: "coordination.k8s.io", Name: "node0", Namespace: corev1.NamespaceNodeLease},
|
||||
features: leaseEnabledFeature,
|
||||
expect: authorizer.DecisionAllow,
|
||||
},
|
||||
{
|
||||
name: "allowed delete node lease - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "delete", Resource: "leases", APIGroup: "coordination.k8s.io", Name: "node0", Namespace: corev1.NamespaceNodeLease},
|
||||
features: leaseEnabledFeature,
|
||||
expect: authorizer.DecisionAllow,
|
||||
},
|
||||
// CSINodeInfo
|
||||
{
|
||||
name: "disallowed CSINodeInfo - feature disabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "csinodeinfos", APIGroup: "csi.storage.k8s.io", Name: "node0"},
|
||||
features: csiNodeInfoDisabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed CSINodeInfo with subresource - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "csinodeinfos", Subresource: "csiDrivers", APIGroup: "csi.storage.k8s.io", Name: "node0"},
|
||||
features: csiNodeInfoEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed get another node's CSINodeInfo - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "csinodeinfos", APIGroup: "csi.storage.k8s.io", Name: "node1"},
|
||||
features: csiNodeInfoEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed update another node's CSINodeInfo - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "update", Resource: "csinodeinfos", APIGroup: "csi.storage.k8s.io", Name: "node1"},
|
||||
features: csiNodeInfoEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed patch another node's CSINodeInfo - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "patch", Resource: "csinodeinfos", APIGroup: "csi.storage.k8s.io", Name: "node1"},
|
||||
features: csiNodeInfoEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed delete another node's CSINodeInfo - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "delete", Resource: "csinodeinfos", APIGroup: "csi.storage.k8s.io", Name: "node1"},
|
||||
features: csiNodeInfoEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed list CSINodeInfos - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "list", Resource: "csinodeinfos", APIGroup: "csi.storage.k8s.io"},
|
||||
features: csiNodeInfoEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed watch CSINodeInfos - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "watch", Resource: "csinodeinfos", APIGroup: "csi.storage.k8s.io"},
|
||||
features: csiNodeInfoEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "allowed get CSINodeInfo - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "csinodeinfos", APIGroup: "csi.storage.k8s.io", Name: "node0"},
|
||||
features: csiNodeInfoEnabledFeature,
|
||||
expect: authorizer.DecisionAllow,
|
||||
},
|
||||
{
|
||||
name: "allowed create CSINodeInfo - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "create", Resource: "csinodeinfos", APIGroup: "csi.storage.k8s.io", Name: "node0"},
|
||||
features: csiNodeInfoEnabledFeature,
|
||||
expect: authorizer.DecisionAllow,
|
||||
},
|
||||
{
|
||||
name: "allowed update CSINodeInfo - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "update", Resource: "csinodeinfos", APIGroup: "csi.storage.k8s.io", Name: "node0"},
|
||||
features: csiNodeInfoEnabledFeature,
|
||||
expect: authorizer.DecisionAllow,
|
||||
},
|
||||
{
|
||||
name: "allowed patch CSINodeInfo - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "patch", Resource: "csinodeinfos", APIGroup: "csi.storage.k8s.io", Name: "node0"},
|
||||
features: csiNodeInfoEnabledFeature,
|
||||
expect: authorizer.DecisionAllow,
|
||||
},
|
||||
{
|
||||
name: "allowed delete CSINodeInfo - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "delete", Resource: "csinodeinfos", APIGroup: "csi.storage.k8s.io", Name: "node0"},
|
||||
features: csiNodeInfoEnabledFeature,
|
||||
expect: authorizer.DecisionAllow,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
@ -255,34 +458,34 @@ func TestAuthorizerSharedResources(t *testing.T) {
|
||||
node2 := &user.DefaultInfo{Name: "system:node:node2", Groups: []string{"system:nodes"}}
|
||||
node3 := &user.DefaultInfo{Name: "system:node:node3", Groups: []string{"system:nodes"}}
|
||||
|
||||
g.AddPod(&api.Pod{
|
||||
g.AddPod(&corev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "pod1-node1", Namespace: "ns1"},
|
||||
Spec: api.PodSpec{
|
||||
Spec: corev1.PodSpec{
|
||||
NodeName: "node1",
|
||||
Volumes: []api.Volume{
|
||||
{VolumeSource: api.VolumeSource{Secret: &api.SecretVolumeSource{SecretName: "node1-only"}}},
|
||||
{VolumeSource: api.VolumeSource{Secret: &api.SecretVolumeSource{SecretName: "node1-node2-only"}}},
|
||||
{VolumeSource: api.VolumeSource{Secret: &api.SecretVolumeSource{SecretName: "shared-all"}}},
|
||||
Volumes: []corev1.Volume{
|
||||
{VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{SecretName: "node1-only"}}},
|
||||
{VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{SecretName: "node1-node2-only"}}},
|
||||
{VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{SecretName: "shared-all"}}},
|
||||
},
|
||||
},
|
||||
})
|
||||
g.AddPod(&api.Pod{
|
||||
g.AddPod(&corev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "pod2-node2", Namespace: "ns1"},
|
||||
Spec: api.PodSpec{
|
||||
Spec: corev1.PodSpec{
|
||||
NodeName: "node2",
|
||||
Volumes: []api.Volume{
|
||||
{VolumeSource: api.VolumeSource{Secret: &api.SecretVolumeSource{SecretName: "node1-node2-only"}}},
|
||||
{VolumeSource: api.VolumeSource{Secret: &api.SecretVolumeSource{SecretName: "shared-all"}}},
|
||||
Volumes: []corev1.Volume{
|
||||
{VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{SecretName: "node1-node2-only"}}},
|
||||
{VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{SecretName: "shared-all"}}},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
pod3 := &api.Pod{
|
||||
pod3 := &corev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "pod3-node3", Namespace: "ns1"},
|
||||
Spec: api.PodSpec{
|
||||
Spec: corev1.PodSpec{
|
||||
NodeName: "node3",
|
||||
Volumes: []api.Volume{
|
||||
{VolumeSource: api.VolumeSource{Secret: &api.SecretVolumeSource{SecretName: "shared-all"}}},
|
||||
Volumes: []corev1.Volume{
|
||||
{VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{SecretName: "shared-all"}}},
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -615,13 +818,13 @@ func BenchmarkAuthorization(b *testing.B) {
|
||||
for shouldWrite == 1 {
|
||||
go func() {
|
||||
start := time.Now()
|
||||
authz.graph.AddPod(&api.Pod{
|
||||
authz.graph.AddPod(&corev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "testwrite", Namespace: "ns0"},
|
||||
Spec: api.PodSpec{
|
||||
Spec: corev1.PodSpec{
|
||||
NodeName: "node0",
|
||||
ServiceAccountName: "default",
|
||||
Volumes: []api.Volume{
|
||||
{Name: "token", VolumeSource: api.VolumeSource{Secret: &api.SecretVolumeSource{SecretName: "secret0-shared"}}},
|
||||
Volumes: []corev1.Volume{
|
||||
{Name: "token", VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{SecretName: "secret0-shared"}}},
|
||||
},
|
||||
},
|
||||
})
|
||||
@ -683,7 +886,7 @@ func BenchmarkAuthorization(b *testing.B) {
|
||||
}
|
||||
}
|
||||
|
||||
func populate(graph *Graph, nodes []*api.Node, pods []*api.Pod, pvs []*api.PersistentVolume, attachments []*storagev1beta1.VolumeAttachment) {
|
||||
func populate(graph *Graph, nodes []*corev1.Node, pods []*corev1.Pod, pvs []*corev1.PersistentVolume, attachments []*storagev1beta1.VolumeAttachment) {
|
||||
p := &graphPopulator{}
|
||||
p.graph = graph
|
||||
for _, node := range nodes {
|
||||
@ -704,63 +907,63 @@ func populate(graph *Graph, nodes []*api.Node, pods []*api.Pod, pvs []*api.Persi
|
||||
// the secret/configmap/pvc/node references in the pod and pv objects are named to indicate the connections between the objects.
|
||||
// for example, secret0-pod0-node0 is a secret referenced by pod0 which is bound to node0.
|
||||
// when populated into the graph, the node authorizer should allow node0 to access that secret, but not node1.
|
||||
func generate(opts sampleDataOpts) ([]*api.Node, []*api.Pod, []*api.PersistentVolume, []*storagev1beta1.VolumeAttachment) {
|
||||
nodes := make([]*api.Node, 0, opts.nodes)
|
||||
pods := make([]*api.Pod, 0, opts.nodes*opts.podsPerNode)
|
||||
pvs := make([]*api.PersistentVolume, 0, (opts.nodes*opts.podsPerNode*opts.uniquePVCsPerPod)+(opts.sharedPVCsPerPod*opts.namespaces))
|
||||
func generate(opts sampleDataOpts) ([]*corev1.Node, []*corev1.Pod, []*corev1.PersistentVolume, []*storagev1beta1.VolumeAttachment) {
|
||||
nodes := make([]*corev1.Node, 0, opts.nodes)
|
||||
pods := make([]*corev1.Pod, 0, opts.nodes*opts.podsPerNode)
|
||||
pvs := make([]*corev1.PersistentVolume, 0, (opts.nodes*opts.podsPerNode*opts.uniquePVCsPerPod)+(opts.sharedPVCsPerPod*opts.namespaces))
|
||||
attachments := make([]*storagev1beta1.VolumeAttachment, 0, opts.nodes*opts.attachmentsPerNode)
|
||||
|
||||
for n := 0; n < opts.nodes; n++ {
|
||||
nodeName := fmt.Sprintf("node%d", n)
|
||||
for p := 0; p < opts.podsPerNode; p++ {
|
||||
pod := &api.Pod{}
|
||||
pod := &corev1.Pod{}
|
||||
pod.Namespace = fmt.Sprintf("ns%d", p%opts.namespaces)
|
||||
pod.Name = fmt.Sprintf("pod%d-%s", p, nodeName)
|
||||
pod.Spec.NodeName = nodeName
|
||||
pod.Spec.ServiceAccountName = fmt.Sprintf("svcacct%d-%s", p, nodeName)
|
||||
|
||||
for i := 0; i < opts.uniqueSecretsPerPod; i++ {
|
||||
pod.Spec.Volumes = append(pod.Spec.Volumes, api.Volume{VolumeSource: api.VolumeSource{
|
||||
Secret: &api.SecretVolumeSource{SecretName: fmt.Sprintf("secret%d-%s", i, pod.Name)},
|
||||
pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{VolumeSource: corev1.VolumeSource{
|
||||
Secret: &corev1.SecretVolumeSource{SecretName: fmt.Sprintf("secret%d-%s", i, pod.Name)},
|
||||
}})
|
||||
}
|
||||
for i := 0; i < opts.sharedSecretsPerPod; i++ {
|
||||
pod.Spec.Volumes = append(pod.Spec.Volumes, api.Volume{VolumeSource: api.VolumeSource{
|
||||
Secret: &api.SecretVolumeSource{SecretName: fmt.Sprintf("secret%d-shared", i)},
|
||||
pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{VolumeSource: corev1.VolumeSource{
|
||||
Secret: &corev1.SecretVolumeSource{SecretName: fmt.Sprintf("secret%d-shared", i)},
|
||||
}})
|
||||
}
|
||||
|
||||
for i := 0; i < opts.uniqueConfigMapsPerPod; i++ {
|
||||
pod.Spec.Volumes = append(pod.Spec.Volumes, api.Volume{VolumeSource: api.VolumeSource{
|
||||
ConfigMap: &api.ConfigMapVolumeSource{LocalObjectReference: api.LocalObjectReference{Name: fmt.Sprintf("configmap%d-%s", i, pod.Name)}},
|
||||
pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{VolumeSource: corev1.VolumeSource{
|
||||
ConfigMap: &corev1.ConfigMapVolumeSource{LocalObjectReference: corev1.LocalObjectReference{Name: fmt.Sprintf("configmap%d-%s", i, pod.Name)}},
|
||||
}})
|
||||
}
|
||||
for i := 0; i < opts.sharedConfigMapsPerPod; i++ {
|
||||
pod.Spec.Volumes = append(pod.Spec.Volumes, api.Volume{VolumeSource: api.VolumeSource{
|
||||
ConfigMap: &api.ConfigMapVolumeSource{LocalObjectReference: api.LocalObjectReference{Name: fmt.Sprintf("configmap%d-shared", i)}},
|
||||
pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{VolumeSource: corev1.VolumeSource{
|
||||
ConfigMap: &corev1.ConfigMapVolumeSource{LocalObjectReference: corev1.LocalObjectReference{Name: fmt.Sprintf("configmap%d-shared", i)}},
|
||||
}})
|
||||
}
|
||||
|
||||
for i := 0; i < opts.uniquePVCsPerPod; i++ {
|
||||
pv := &api.PersistentVolume{}
|
||||
pv := &corev1.PersistentVolume{}
|
||||
pv.Name = fmt.Sprintf("pv%d-%s-%s", i, pod.Name, pod.Namespace)
|
||||
pv.Spec.FlexVolume = &api.FlexPersistentVolumeSource{SecretRef: &api.SecretReference{Name: fmt.Sprintf("secret-%s", pv.Name)}}
|
||||
pv.Spec.ClaimRef = &api.ObjectReference{Name: fmt.Sprintf("pvc%d-%s", i, pod.Name), Namespace: pod.Namespace}
|
||||
pv.Spec.FlexVolume = &corev1.FlexPersistentVolumeSource{SecretRef: &corev1.SecretReference{Name: fmt.Sprintf("secret-%s", pv.Name)}}
|
||||
pv.Spec.ClaimRef = &corev1.ObjectReference{Name: fmt.Sprintf("pvc%d-%s", i, pod.Name), Namespace: pod.Namespace}
|
||||
pvs = append(pvs, pv)
|
||||
|
||||
pod.Spec.Volumes = append(pod.Spec.Volumes, api.Volume{VolumeSource: api.VolumeSource{
|
||||
PersistentVolumeClaim: &api.PersistentVolumeClaimVolumeSource{ClaimName: pv.Spec.ClaimRef.Name},
|
||||
pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{VolumeSource: corev1.VolumeSource{
|
||||
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ClaimName: pv.Spec.ClaimRef.Name},
|
||||
}})
|
||||
}
|
||||
for i := 0; i < opts.sharedPVCsPerPod; i++ {
|
||||
pv := &api.PersistentVolume{}
|
||||
pv := &corev1.PersistentVolume{}
|
||||
pv.Name = fmt.Sprintf("pv%d-shared-%s", i, pod.Namespace)
|
||||
pv.Spec.FlexVolume = &api.FlexPersistentVolumeSource{SecretRef: &api.SecretReference{Name: fmt.Sprintf("secret-%s", pv.Name)}}
|
||||
pv.Spec.ClaimRef = &api.ObjectReference{Name: fmt.Sprintf("pvc%d-shared", i), Namespace: pod.Namespace}
|
||||
pv.Spec.FlexVolume = &corev1.FlexPersistentVolumeSource{SecretRef: &corev1.SecretReference{Name: fmt.Sprintf("secret-%s", pv.Name)}}
|
||||
pv.Spec.ClaimRef = &corev1.ObjectReference{Name: fmt.Sprintf("pvc%d-shared", i), Namespace: pod.Namespace}
|
||||
pvs = append(pvs, pv)
|
||||
|
||||
pod.Spec.Volumes = append(pod.Spec.Volumes, api.Volume{VolumeSource: api.VolumeSource{
|
||||
PersistentVolumeClaim: &api.PersistentVolumeClaimVolumeSource{ClaimName: pv.Spec.ClaimRef.Name},
|
||||
pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{VolumeSource: corev1.VolumeSource{
|
||||
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ClaimName: pv.Spec.ClaimRef.Name},
|
||||
}})
|
||||
}
|
||||
|
||||
@ -774,11 +977,11 @@ func generate(opts sampleDataOpts) ([]*api.Node, []*api.Pod, []*api.PersistentVo
|
||||
}
|
||||
|
||||
name := fmt.Sprintf("%s-configmap", nodeName)
|
||||
nodes = append(nodes, &api.Node{
|
||||
nodes = append(nodes, &corev1.Node{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: nodeName},
|
||||
Spec: api.NodeSpec{
|
||||
ConfigSource: &api.NodeConfigSource{
|
||||
ConfigMap: &api.ConfigMapNodeConfigSource{
|
||||
Spec: corev1.NodeSpec{
|
||||
ConfigSource: &corev1.NodeConfigSource{
|
||||
ConfigMap: &corev1.ConfigMapNodeConfigSource{
|
||||
Name: name,
|
||||
Namespace: "ns0",
|
||||
UID: types.UID(fmt.Sprintf("ns0-%s", name)),
|
||||
|
22
vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/BUILD
generated
vendored
22
vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/BUILD
generated
vendored
@ -16,13 +16,13 @@ go_library(
|
||||
deps = [
|
||||
"//pkg/apis/rbac/v1:go_default_library",
|
||||
"//pkg/registry/rbac/validation:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/api/rbac/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
||||
"//vendor/k8s.io/client-go/listers/rbac/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/rbac/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/listers/rbac/v1:go_default_library",
|
||||
"//vendor/k8s.io/klog:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@ -37,10 +37,10 @@ go_test(
|
||||
"//pkg/apis/rbac/v1:go_default_library",
|
||||
"//pkg/registry/rbac/validation:go_default_library",
|
||||
"//plugin/pkg/auth/authorizer/rbac/bootstrappolicy:go_default_library",
|
||||
"//vendor/k8s.io/api/rbac/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
||||
"//staging/src/k8s.io/api/rbac/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
52
vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/BUILD
generated
vendored
52
vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/BUILD
generated
vendored
@ -17,48 +17,38 @@ go_library(
|
||||
deps = [
|
||||
"//pkg/apis/rbac/v1:go_default_library",
|
||||
"//pkg/features:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/api/rbac/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//staging/src/k8s.io/api/rbac/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//vendor/k8s.io/klog:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_xtest",
|
||||
srcs = ["policy_test.go"],
|
||||
data = glob([
|
||||
"testdata/*",
|
||||
]),
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"controller_policy_test.go",
|
||||
"policy_test.go",
|
||||
],
|
||||
data = glob(["testdata/**"]),
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
":go_default_library",
|
||||
"//pkg/api/legacyscheme:go_default_library",
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/apis/core/install:go_default_library",
|
||||
"//pkg/apis/rbac/install:go_default_library",
|
||||
"//pkg/apis/rbac/v1:go_default_library",
|
||||
"//pkg/registry/rbac/validation:go_default_library",
|
||||
"//vendor/github.com/ghodss/yaml:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/rbac/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["controller_policy_test.go"],
|
||||
data = glob(["testdata/**"]),
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/rbac/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//vendor/sigs.k8s.io/yaml:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -19,7 +19,7 @@ package bootstrappolicy
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/klog"
|
||||
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@ -32,12 +32,12 @@ const saRolePrefix = "system:controller:"
|
||||
|
||||
func addControllerRole(controllerRoles *[]rbacv1.ClusterRole, controllerRoleBindings *[]rbacv1.ClusterRoleBinding, role rbacv1.ClusterRole) {
|
||||
if !strings.HasPrefix(role.Name, saRolePrefix) {
|
||||
glog.Fatalf(`role %q must start with %q`, role.Name, saRolePrefix)
|
||||
klog.Fatalf(`role %q must start with %q`, role.Name, saRolePrefix)
|
||||
}
|
||||
|
||||
for _, existingRole := range *controllerRoles {
|
||||
if role.Name == existingRole.Name {
|
||||
glog.Fatalf("role %q was already registered", role.Name)
|
||||
klog.Fatalf("role %q was already registered", role.Name)
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,6 +73,9 @@ func buildControllerRoles() ([]rbacv1.ClusterRole, []rbacv1.ClusterRoleBinding)
|
||||
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.CSIPersistentVolume) {
|
||||
role.Rules = append(role.Rules, rbacv1helpers.NewRule("get", "create", "delete", "list", "watch").Groups(storageGroup).Resources("volumeattachments").RuleOrDie())
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.CSIDriverRegistry) {
|
||||
role.Rules = append(role.Rules, rbacv1helpers.NewRule("get", "watch", "list").Groups("csi.storage.k8s.io").Resources("csidrivers").RuleOrDie())
|
||||
}
|
||||
}
|
||||
|
||||
return role
|
||||
@ -340,6 +343,25 @@ func buildControllerRoles() ([]rbacv1.ClusterRole, []rbacv1.ClusterRoleBinding)
|
||||
eventsRule(),
|
||||
},
|
||||
})
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.TTLAfterFinished) {
|
||||
addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "ttl-after-finished-controller"},
|
||||
Rules: []rbacv1.PolicyRule{
|
||||
rbacv1helpers.NewRule("get", "list", "watch", "delete").Groups(batchGroup).Resources("jobs").RuleOrDie(),
|
||||
eventsRule(),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.BoundServiceAccountTokenVolume) {
|
||||
addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "root-ca-cert-publisher"},
|
||||
Rules: []rbacv1.PolicyRule{
|
||||
rbacv1helpers.NewRule("create", "update").Groups(legacyGroup).Resources("configmaps").RuleOrDie(),
|
||||
eventsRule(),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
return controllerRoles, controllerRoleBindings
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ package bootstrappolicy
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/klog"
|
||||
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@ -36,13 +36,13 @@ var (
|
||||
|
||||
func addNamespaceRole(namespace string, role rbacv1.Role) {
|
||||
if !strings.HasPrefix(namespace, "kube-") {
|
||||
glog.Fatalf(`roles can only be bootstrapped into reserved namespaces starting with "kube-", not %q`, namespace)
|
||||
klog.Fatalf(`roles can only be bootstrapped into reserved namespaces starting with "kube-", not %q`, namespace)
|
||||
}
|
||||
|
||||
existingRoles := namespaceRoles[namespace]
|
||||
for _, existingRole := range existingRoles {
|
||||
if role.Name == existingRole.Name {
|
||||
glog.Fatalf("role %q was already registered in %q", role.Name, namespace)
|
||||
klog.Fatalf("role %q was already registered in %q", role.Name, namespace)
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,13 +54,13 @@ func addNamespaceRole(namespace string, role rbacv1.Role) {
|
||||
|
||||
func addNamespaceRoleBinding(namespace string, roleBinding rbacv1.RoleBinding) {
|
||||
if !strings.HasPrefix(namespace, "kube-") {
|
||||
glog.Fatalf(`rolebindings can only be bootstrapped into reserved namespaces starting with "kube-", not %q`, namespace)
|
||||
klog.Fatalf(`rolebindings can only be bootstrapped into reserved namespaces starting with "kube-", not %q`, namespace)
|
||||
}
|
||||
|
||||
existingRoleBindings := namespaceRoleBindings[namespace]
|
||||
for _, existingRoleBinding := range existingRoleBindings {
|
||||
if roleBinding.Name == existingRoleBinding.Name {
|
||||
glog.Fatalf("rolebinding %q was already registered in %q", roleBinding.Name, namespace)
|
||||
klog.Fatalf("rolebinding %q was already registered in %q", roleBinding.Name, namespace)
|
||||
}
|
||||
}
|
||||
|
||||
|
135
vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy.go
generated
vendored
135
vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy.go
generated
vendored
@ -28,6 +28,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
Write = []string{"create", "update", "patch", "delete", "deletecollection"}
|
||||
ReadWrite = []string{"get", "list", "watch", "create", "update", "patch", "delete", "deletecollection"}
|
||||
Read = []string{"get", "list", "watch"}
|
||||
ReadUpdate = []string{"get", "list", "watch", "update", "patch"}
|
||||
@ -106,7 +107,7 @@ func NodeRules() []rbacv1.PolicyRule {
|
||||
// Use the NodeRestriction admission plugin to limit a node to creating/updating its own API object.
|
||||
rbacv1helpers.NewRule("create", "get", "list", "watch").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
|
||||
rbacv1helpers.NewRule("update", "patch").Groups(legacyGroup).Resources("nodes/status").RuleOrDie(),
|
||||
rbacv1helpers.NewRule("update", "patch", "delete").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
|
||||
rbacv1helpers.NewRule("update", "patch").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
|
||||
|
||||
// TODO: restrict to the bound node as creator in the NodeRestrictions admission plugin
|
||||
rbacv1helpers.NewRule("create", "update", "patch").Groups(legacyGroup).Resources("events").RuleOrDie(),
|
||||
@ -158,6 +159,25 @@ func NodeRules() []rbacv1.PolicyRule {
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.CSIPersistentVolume) {
|
||||
volAttachRule := rbacv1helpers.NewRule("get").Groups(storageGroup).Resources("volumeattachments").RuleOrDie()
|
||||
nodePolicyRules = append(nodePolicyRules, volAttachRule)
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.CSIDriverRegistry) {
|
||||
csiDriverRule := rbacv1helpers.NewRule("get", "watch", "list").Groups("csi.storage.k8s.io").Resources("csidrivers").RuleOrDie()
|
||||
nodePolicyRules = append(nodePolicyRules, csiDriverRule)
|
||||
}
|
||||
}
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.KubeletPluginsWatcher) &&
|
||||
utilfeature.DefaultFeatureGate.Enabled(features.CSINodeInfo) {
|
||||
csiNodeInfoRule := rbacv1helpers.NewRule("get", "create", "update", "patch", "delete").Groups("csi.storage.k8s.io").Resources("csinodeinfos").RuleOrDie()
|
||||
nodePolicyRules = append(nodePolicyRules, csiNodeInfoRule)
|
||||
}
|
||||
|
||||
// Node leases
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.NodeLease) {
|
||||
nodePolicyRules = append(nodePolicyRules, rbacv1helpers.NewRule("get", "create", "update", "patch", "delete").Groups("coordination.k8s.io").Resources("leases").RuleOrDie())
|
||||
}
|
||||
|
||||
// RuntimeClass
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.RuntimeClass) {
|
||||
nodePolicyRules = append(nodePolicyRules, rbacv1helpers.NewRule("get", "list", "watch").Groups("node.k8s.io").Resources("runtimeclasses").RuleOrDie())
|
||||
}
|
||||
return nodePolicyRules
|
||||
}
|
||||
@ -203,59 +223,36 @@ func ClusterRoles() []rbacv1.ClusterRole {
|
||||
// a role for a namespace level admin. It is `edit` plus the power to grant permissions to other users.
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "admin"},
|
||||
AggregationRule: &rbacv1.AggregationRule{
|
||||
ClusterRoleSelectors: []metav1.LabelSelector{{MatchLabels: map[string]string{"rbac.authorization.k8s.io/aggregate-to-admin": "true"}}},
|
||||
ClusterRoleSelectors: []metav1.LabelSelector{
|
||||
{MatchLabels: map[string]string{"rbac.authorization.k8s.io/aggregate-to-admin": "true"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
// a role for a namespace level editor. It grants access to all user level actions in a namespace.
|
||||
// It does not grant powers for "privileged" resources which are domain of the system: `/status`
|
||||
// subresources or `quota`/`limits` which are used to control namespaces
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "edit"},
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "edit", Labels: map[string]string{"rbac.authorization.k8s.io/aggregate-to-admin": "true"}},
|
||||
AggregationRule: &rbacv1.AggregationRule{
|
||||
ClusterRoleSelectors: []metav1.LabelSelector{{MatchLabels: map[string]string{"rbac.authorization.k8s.io/aggregate-to-edit": "true"}}},
|
||||
ClusterRoleSelectors: []metav1.LabelSelector{
|
||||
{MatchLabels: map[string]string{"rbac.authorization.k8s.io/aggregate-to-edit": "true"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
// a role for namespace level viewing. It grants Read-only access to non-escalating resources in
|
||||
// a namespace.
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "view"},
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "view", Labels: map[string]string{"rbac.authorization.k8s.io/aggregate-to-edit": "true"}},
|
||||
AggregationRule: &rbacv1.AggregationRule{
|
||||
ClusterRoleSelectors: []metav1.LabelSelector{{MatchLabels: map[string]string{"rbac.authorization.k8s.io/aggregate-to-view": "true"}}},
|
||||
ClusterRoleSelectors: []metav1.LabelSelector{
|
||||
{MatchLabels: map[string]string{"rbac.authorization.k8s.io/aggregate-to-view": "true"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
// a role for a namespace level admin. It is `edit` plus the power to grant permissions to other users.
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "system:aggregate-to-admin", Labels: map[string]string{"rbac.authorization.k8s.io/aggregate-to-admin": "true"}},
|
||||
Rules: []rbacv1.PolicyRule{
|
||||
rbacv1helpers.NewRule(ReadWrite...).Groups(legacyGroup).Resources("pods", "pods/attach", "pods/proxy", "pods/exec", "pods/portforward").RuleOrDie(),
|
||||
rbacv1helpers.NewRule(ReadWrite...).Groups(legacyGroup).Resources("replicationcontrollers", "replicationcontrollers/scale", "serviceaccounts",
|
||||
"services", "services/proxy", "endpoints", "persistentvolumeclaims", "configmaps", "secrets").RuleOrDie(),
|
||||
rbacv1helpers.NewRule(Read...).Groups(legacyGroup).Resources("limitranges", "resourcequotas", "bindings", "events",
|
||||
"pods/status", "resourcequotas/status", "namespaces/status", "replicationcontrollers/status", "pods/log").RuleOrDie(),
|
||||
// read access to namespaces at the namespace scope means you can read *this* namespace. This can be used as an
|
||||
// indicator of which namespaces you have access to.
|
||||
rbacv1helpers.NewRule(Read...).Groups(legacyGroup).Resources("namespaces").RuleOrDie(),
|
||||
rbacv1helpers.NewRule("impersonate").Groups(legacyGroup).Resources("serviceaccounts").RuleOrDie(),
|
||||
|
||||
rbacv1helpers.NewRule(ReadWrite...).Groups(appsGroup).Resources(
|
||||
"statefulsets", "statefulsets/scale",
|
||||
"daemonsets",
|
||||
"deployments", "deployments/scale", "deployments/rollback",
|
||||
"replicasets", "replicasets/scale").RuleOrDie(),
|
||||
|
||||
rbacv1helpers.NewRule(ReadWrite...).Groups(autoscalingGroup).Resources("horizontalpodautoscalers").RuleOrDie(),
|
||||
|
||||
rbacv1helpers.NewRule(ReadWrite...).Groups(batchGroup).Resources("jobs", "cronjobs").RuleOrDie(),
|
||||
|
||||
rbacv1helpers.NewRule(ReadWrite...).Groups(extensionsGroup).Resources("daemonsets",
|
||||
"deployments", "deployments/scale", "deployments/rollback", "ingresses",
|
||||
"replicasets", "replicasets/scale", "replicationcontrollers/scale",
|
||||
"networkpolicies").RuleOrDie(),
|
||||
|
||||
rbacv1helpers.NewRule(ReadWrite...).Groups(policyGroup).Resources("poddisruptionbudgets").RuleOrDie(),
|
||||
|
||||
rbacv1helpers.NewRule(ReadWrite...).Groups(networkingGroup).Resources("networkpolicies").RuleOrDie(),
|
||||
|
||||
// additional admin powers
|
||||
rbacv1helpers.NewRule("create").Groups(authorizationGroup).Resources("localsubjectaccessreviews").RuleOrDie(),
|
||||
rbacv1helpers.NewRule(ReadWrite...).Groups(rbacGroup).Resources("roles", "rolebindings").RuleOrDie(),
|
||||
@ -267,34 +264,32 @@ func ClusterRoles() []rbacv1.ClusterRole {
|
||||
// subresources or `quota`/`limits` which are used to control namespaces
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "system:aggregate-to-edit", Labels: map[string]string{"rbac.authorization.k8s.io/aggregate-to-edit": "true"}},
|
||||
Rules: []rbacv1.PolicyRule{
|
||||
rbacv1helpers.NewRule(ReadWrite...).Groups(legacyGroup).Resources("pods", "pods/attach", "pods/proxy", "pods/exec", "pods/portforward").RuleOrDie(),
|
||||
rbacv1helpers.NewRule(ReadWrite...).Groups(legacyGroup).Resources("replicationcontrollers", "replicationcontrollers/scale", "serviceaccounts",
|
||||
"services", "services/proxy", "endpoints", "persistentvolumeclaims", "configmaps", "secrets").RuleOrDie(),
|
||||
rbacv1helpers.NewRule(Read...).Groups(legacyGroup).Resources("limitranges", "resourcequotas", "bindings", "events",
|
||||
"pods/status", "resourcequotas/status", "namespaces/status", "replicationcontrollers/status", "pods/log").RuleOrDie(),
|
||||
// read access to namespaces at the namespace scope means you can read *this* namespace. This can be used as an
|
||||
// indicator of which namespaces you have access to.
|
||||
rbacv1helpers.NewRule(Read...).Groups(legacyGroup).Resources("namespaces").RuleOrDie(),
|
||||
// Allow read on escalating resources
|
||||
rbacv1helpers.NewRule(Read...).Groups(legacyGroup).Resources("pods/attach", "pods/proxy", "pods/exec", "pods/portforward", "secrets", "services/proxy").RuleOrDie(),
|
||||
rbacv1helpers.NewRule("impersonate").Groups(legacyGroup).Resources("serviceaccounts").RuleOrDie(),
|
||||
|
||||
rbacv1helpers.NewRule(ReadWrite...).Groups(appsGroup).Resources(
|
||||
rbacv1helpers.NewRule(Write...).Groups(legacyGroup).Resources("pods", "pods/attach", "pods/proxy", "pods/exec", "pods/portforward").RuleOrDie(),
|
||||
rbacv1helpers.NewRule(Write...).Groups(legacyGroup).Resources("replicationcontrollers", "replicationcontrollers/scale", "serviceaccounts",
|
||||
"services", "services/proxy", "endpoints", "persistentvolumeclaims", "configmaps", "secrets").RuleOrDie(),
|
||||
|
||||
rbacv1helpers.NewRule(Write...).Groups(appsGroup).Resources(
|
||||
"statefulsets", "statefulsets/scale",
|
||||
"daemonsets",
|
||||
"deployments", "deployments/scale", "deployments/rollback",
|
||||
"replicasets", "replicasets/scale").RuleOrDie(),
|
||||
|
||||
rbacv1helpers.NewRule(ReadWrite...).Groups(autoscalingGroup).Resources("horizontalpodautoscalers").RuleOrDie(),
|
||||
rbacv1helpers.NewRule(Write...).Groups(autoscalingGroup).Resources("horizontalpodautoscalers").RuleOrDie(),
|
||||
|
||||
rbacv1helpers.NewRule(ReadWrite...).Groups(batchGroup).Resources("jobs", "cronjobs").RuleOrDie(),
|
||||
rbacv1helpers.NewRule(Write...).Groups(batchGroup).Resources("jobs", "cronjobs").RuleOrDie(),
|
||||
|
||||
rbacv1helpers.NewRule(ReadWrite...).Groups(extensionsGroup).Resources("daemonsets",
|
||||
rbacv1helpers.NewRule(Write...).Groups(extensionsGroup).Resources("daemonsets",
|
||||
"deployments", "deployments/scale", "deployments/rollback", "ingresses",
|
||||
"replicasets", "replicasets/scale", "replicationcontrollers/scale",
|
||||
"networkpolicies").RuleOrDie(),
|
||||
|
||||
rbacv1helpers.NewRule(ReadWrite...).Groups(policyGroup).Resources("poddisruptionbudgets").RuleOrDie(),
|
||||
rbacv1helpers.NewRule(Write...).Groups(policyGroup).Resources("poddisruptionbudgets").RuleOrDie(),
|
||||
|
||||
rbacv1helpers.NewRule(ReadWrite...).Groups(networkingGroup).Resources("networkpolicies").RuleOrDie(),
|
||||
rbacv1helpers.NewRule(Write...).Groups(networkingGroup).Resources("networkpolicies").RuleOrDie(),
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -311,6 +306,7 @@ func ClusterRoles() []rbacv1.ClusterRole {
|
||||
rbacv1helpers.NewRule(Read...).Groups(legacyGroup).Resources("namespaces").RuleOrDie(),
|
||||
|
||||
rbacv1helpers.NewRule(Read...).Groups(appsGroup).Resources(
|
||||
"controllerrevisions",
|
||||
"statefulsets", "statefulsets/scale",
|
||||
"daemonsets",
|
||||
"deployments", "deployments/scale",
|
||||
@ -407,7 +403,7 @@ func ClusterRoles() []rbacv1.ClusterRole {
|
||||
eventsRule(),
|
||||
rbacv1helpers.NewRule("create").Groups(legacyGroup).Resources("endpoints", "secrets", "serviceaccounts").RuleOrDie(),
|
||||
rbacv1helpers.NewRule("delete").Groups(legacyGroup).Resources("secrets").RuleOrDie(),
|
||||
rbacv1helpers.NewRule("get").Groups(legacyGroup).Resources("endpoints", "namespaces", "secrets", "serviceaccounts").RuleOrDie(),
|
||||
rbacv1helpers.NewRule("get").Groups(legacyGroup).Resources("endpoints", "namespaces", "secrets", "serviceaccounts", "configmaps").RuleOrDie(),
|
||||
rbacv1helpers.NewRule("update").Groups(legacyGroup).Resources("endpoints", "secrets", "serviceaccounts").RuleOrDie(),
|
||||
// Needed to check API access. These creates are non-mutating
|
||||
rbacv1helpers.NewRule("create").Groups(authenticationGroup).Resources("tokenreviews").RuleOrDie(),
|
||||
@ -462,16 +458,6 @@ func ClusterRoles() []rbacv1.ClusterRole {
|
||||
eventsRule(),
|
||||
},
|
||||
},
|
||||
{
|
||||
// a role for the csi external provisioner
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "system:csi-external-provisioner"},
|
||||
Rules: []rbacv1.PolicyRule{
|
||||
rbacv1helpers.NewRule("create", "delete", "get", "list", "watch").Groups(legacyGroup).Resources("persistentvolumes").RuleOrDie(),
|
||||
rbacv1helpers.NewRule("get", "list", "watch", "update", "patch").Groups(legacyGroup).Resources("persistentvolumeclaims").RuleOrDie(),
|
||||
rbacv1helpers.NewRule("list", "watch").Groups(storageGroup).Resources("storageclasses").RuleOrDie(),
|
||||
rbacv1helpers.NewRule("get", "list", "watch", "create", "update", "patch").Groups(legacyGroup).Resources("events").RuleOrDie(),
|
||||
},
|
||||
},
|
||||
{
|
||||
// a role for the csi external attacher
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "system:csi-external-attacher"},
|
||||
@ -506,19 +492,32 @@ func ClusterRoles() []rbacv1.ClusterRole {
|
||||
}
|
||||
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.VolumeScheduling) {
|
||||
rules := []rbacv1.PolicyRule{
|
||||
rbacv1helpers.NewRule(ReadUpdate...).Groups(legacyGroup).Resources("persistentvolumes").RuleOrDie(),
|
||||
rbacv1helpers.NewRule(Read...).Groups(storageGroup).Resources("storageclasses").RuleOrDie(),
|
||||
}
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.DynamicProvisioningScheduling) {
|
||||
rules = append(rules, rbacv1helpers.NewRule(ReadUpdate...).Groups(legacyGroup).Resources("persistentvolumeclaims").RuleOrDie())
|
||||
}
|
||||
roles = append(roles, rbacv1.ClusterRole{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "system:volume-scheduler"},
|
||||
Rules: rules,
|
||||
Rules: []rbacv1.PolicyRule{
|
||||
rbacv1helpers.NewRule(ReadUpdate...).Groups(legacyGroup).Resources("persistentvolumes").RuleOrDie(),
|
||||
rbacv1helpers.NewRule(Read...).Groups(storageGroup).Resources("storageclasses").RuleOrDie(),
|
||||
rbacv1helpers.NewRule(ReadUpdate...).Groups(legacyGroup).Resources("persistentvolumeclaims").RuleOrDie(),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
externalProvisionerRules := []rbacv1.PolicyRule{
|
||||
rbacv1helpers.NewRule("create", "delete", "get", "list", "watch").Groups(legacyGroup).Resources("persistentvolumes").RuleOrDie(),
|
||||
rbacv1helpers.NewRule("get", "list", "watch", "update", "patch").Groups(legacyGroup).Resources("persistentvolumeclaims").RuleOrDie(),
|
||||
rbacv1helpers.NewRule("list", "watch").Groups(storageGroup).Resources("storageclasses").RuleOrDie(),
|
||||
rbacv1helpers.NewRule("get", "list", "watch", "create", "update", "patch").Groups(legacyGroup).Resources("events").RuleOrDie(),
|
||||
rbacv1helpers.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
|
||||
}
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.CSINodeInfo) {
|
||||
externalProvisionerRules = append(externalProvisionerRules, rbacv1helpers.NewRule("get", "watch", "list").Groups("csi.storage.k8s.io").Resources("csinodeinfos").RuleOrDie())
|
||||
}
|
||||
roles = append(roles, rbacv1.ClusterRole{
|
||||
// a role for the csi external provisioner
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "system:csi-external-provisioner"},
|
||||
Rules: externalProvisionerRules,
|
||||
})
|
||||
|
||||
addClusterRoleLabel(roles)
|
||||
return roles
|
||||
}
|
||||
|
53
vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy_test.go
generated
vendored
53
vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy_test.go
generated
vendored
@ -23,7 +23,7 @@ import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
@ -64,49 +64,6 @@ func getSemanticRoles(roles []rbacv1.ClusterRole) semanticRoles {
|
||||
return ret
|
||||
}
|
||||
|
||||
// Some roles should always cover others
|
||||
func TestCovers(t *testing.T) {
|
||||
semanticRoles := getSemanticRoles(bootstrappolicy.ClusterRoles())
|
||||
|
||||
if covers, miss := rbacregistryvalidation.Covers(semanticRoles.admin.Rules, semanticRoles.edit.Rules); !covers {
|
||||
t.Errorf("failed to cover: %#v", miss)
|
||||
}
|
||||
if covers, miss := rbacregistryvalidation.Covers(semanticRoles.admin.Rules, semanticRoles.view.Rules); !covers {
|
||||
t.Errorf("failed to cover: %#v", miss)
|
||||
}
|
||||
if covers, miss := rbacregistryvalidation.Covers(semanticRoles.edit.Rules, semanticRoles.view.Rules); !covers {
|
||||
t.Errorf("failed to cover: %#v", miss)
|
||||
}
|
||||
}
|
||||
|
||||
// additionalAdminPowers is the list of powers that we expect to be different than the editor role.
|
||||
// one resource per rule to make the "does not already contain" check easy
|
||||
var additionalAdminPowers = []rbacv1.PolicyRule{
|
||||
rbacv1helpers.NewRule("create").Groups("authorization.k8s.io").Resources("localsubjectaccessreviews").RuleOrDie(),
|
||||
rbacv1helpers.NewRule(bootstrappolicy.ReadWrite...).Groups("rbac.authorization.k8s.io").Resources("rolebindings").RuleOrDie(),
|
||||
rbacv1helpers.NewRule(bootstrappolicy.ReadWrite...).Groups("rbac.authorization.k8s.io").Resources("roles").RuleOrDie(),
|
||||
}
|
||||
|
||||
func TestAdminEditRelationship(t *testing.T) {
|
||||
semanticRoles := getSemanticRoles(bootstrappolicy.ClusterRoles())
|
||||
|
||||
// confirm that the edit role doesn't already have extra powers
|
||||
for _, rule := range additionalAdminPowers {
|
||||
if covers, _ := rbacregistryvalidation.Covers(semanticRoles.edit.Rules, []rbacv1.PolicyRule{rule}); covers {
|
||||
t.Errorf("edit has extra powers: %#v", rule)
|
||||
}
|
||||
}
|
||||
semanticRoles.edit.Rules = append(semanticRoles.edit.Rules, additionalAdminPowers...)
|
||||
|
||||
// at this point, we should have a two way covers relationship
|
||||
if covers, miss := rbacregistryvalidation.Covers(semanticRoles.admin.Rules, semanticRoles.edit.Rules); !covers {
|
||||
t.Errorf("admin has lost rules for: %#v", miss)
|
||||
}
|
||||
if covers, miss := rbacregistryvalidation.Covers(semanticRoles.edit.Rules, semanticRoles.admin.Rules); !covers {
|
||||
t.Errorf("edit is missing rules for: %#v\nIf these should only be admin powers, add them to the list. Otherwise, add them to the edit role.", miss)
|
||||
}
|
||||
}
|
||||
|
||||
// viewEscalatingNamespaceResources is the list of rules that would allow privilege escalation attacks based on
|
||||
// ability to view (GET) them
|
||||
var viewEscalatingNamespaceResources = []rbacv1.PolicyRule{
|
||||
@ -156,14 +113,6 @@ func TestEditViewRelationship(t *testing.T) {
|
||||
}
|
||||
}
|
||||
semanticRoles.view.Rules = append(semanticRoles.view.Rules, ungettableResources...)
|
||||
|
||||
// at this point, we should have a two way covers relationship
|
||||
if covers, miss := rbacregistryvalidation.Covers(semanticRoles.edit.Rules, semanticRoles.view.Rules); !covers {
|
||||
t.Errorf("edit has lost rules for: %#v", miss)
|
||||
}
|
||||
if covers, miss := rbacregistryvalidation.Covers(semanticRoles.view.Rules, semanticRoles.edit.Rules); !covers {
|
||||
t.Errorf("view is missing rules for: %#v\nIf these are escalating powers, add them to the list. Otherwise, add them to the view role.", miss)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBootstrapNamespaceRoles(t *testing.T) {
|
||||
|
@ -46,6 +46,7 @@ items:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
kubernetes.io/bootstrapping: rbac-defaults
|
||||
rbac.authorization.k8s.io/aggregate-to-admin: "true"
|
||||
name: edit
|
||||
rules: null
|
||||
- apiVersion: rbac.authorization.k8s.io/v1
|
||||
@ -59,168 +60,6 @@ items:
|
||||
rbac.authorization.k8s.io/aggregate-to-admin: "true"
|
||||
name: system:aggregate-to-admin
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods
|
||||
- pods/attach
|
||||
- pods/exec
|
||||
- pods/portforward
|
||||
- pods/proxy
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- deletecollection
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- configmaps
|
||||
- endpoints
|
||||
- persistentvolumeclaims
|
||||
- replicationcontrollers
|
||||
- replicationcontrollers/scale
|
||||
- secrets
|
||||
- serviceaccounts
|
||||
- services
|
||||
- services/proxy
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- deletecollection
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- bindings
|
||||
- events
|
||||
- limitranges
|
||||
- namespaces/status
|
||||
- pods/log
|
||||
- pods/status
|
||||
- replicationcontrollers/status
|
||||
- resourcequotas
|
||||
- resourcequotas/status
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- namespaces
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- serviceaccounts
|
||||
verbs:
|
||||
- impersonate
|
||||
- apiGroups:
|
||||
- apps
|
||||
resources:
|
||||
- daemonsets
|
||||
- deployments
|
||||
- deployments/rollback
|
||||
- deployments/scale
|
||||
- replicasets
|
||||
- replicasets/scale
|
||||
- statefulsets
|
||||
- statefulsets/scale
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- deletecollection
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- autoscaling
|
||||
resources:
|
||||
- horizontalpodautoscalers
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- deletecollection
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- batch
|
||||
resources:
|
||||
- cronjobs
|
||||
- jobs
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- deletecollection
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- extensions
|
||||
resources:
|
||||
- daemonsets
|
||||
- deployments
|
||||
- deployments/rollback
|
||||
- deployments/scale
|
||||
- ingresses
|
||||
- networkpolicies
|
||||
- replicasets
|
||||
- replicasets/scale
|
||||
- replicationcontrollers/scale
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- deletecollection
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- policy
|
||||
resources:
|
||||
- poddisruptionbudgets
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- deletecollection
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- networking.k8s.io
|
||||
resources:
|
||||
- networkpolicies
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- deletecollection
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- authorization.k8s.io
|
||||
resources:
|
||||
@ -252,6 +91,25 @@ items:
|
||||
rbac.authorization.k8s.io/aggregate-to-edit: "true"
|
||||
name: system:aggregate-to-edit
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods/attach
|
||||
- pods/exec
|
||||
- pods/portforward
|
||||
- pods/proxy
|
||||
- secrets
|
||||
- services/proxy
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- serviceaccounts
|
||||
verbs:
|
||||
- impersonate
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
@ -264,11 +122,8 @@ items:
|
||||
- create
|
||||
- delete
|
||||
- deletecollection
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
@ -285,41 +140,8 @@ items:
|
||||
- create
|
||||
- delete
|
||||
- deletecollection
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- bindings
|
||||
- events
|
||||
- limitranges
|
||||
- namespaces/status
|
||||
- pods/log
|
||||
- pods/status
|
||||
- replicationcontrollers/status
|
||||
- resourcequotas
|
||||
- resourcequotas/status
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- namespaces
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- serviceaccounts
|
||||
verbs:
|
||||
- impersonate
|
||||
- apiGroups:
|
||||
- apps
|
||||
resources:
|
||||
@ -335,11 +157,8 @@ items:
|
||||
- create
|
||||
- delete
|
||||
- deletecollection
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- autoscaling
|
||||
resources:
|
||||
@ -348,11 +167,8 @@ items:
|
||||
- create
|
||||
- delete
|
||||
- deletecollection
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- batch
|
||||
resources:
|
||||
@ -362,11 +178,8 @@ items:
|
||||
- create
|
||||
- delete
|
||||
- deletecollection
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- extensions
|
||||
resources:
|
||||
@ -383,11 +196,8 @@ items:
|
||||
- create
|
||||
- delete
|
||||
- deletecollection
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- policy
|
||||
resources:
|
||||
@ -396,11 +206,8 @@ items:
|
||||
- create
|
||||
- delete
|
||||
- deletecollection
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- networking.k8s.io
|
||||
resources:
|
||||
@ -409,11 +216,8 @@ items:
|
||||
- create
|
||||
- delete
|
||||
- deletecollection
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
@ -467,6 +271,7 @@ items:
|
||||
- apiGroups:
|
||||
- apps
|
||||
resources:
|
||||
- controllerrevisions
|
||||
- daemonsets
|
||||
- deployments
|
||||
- deployments/scale
|
||||
@ -719,6 +524,14 @@ items:
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- nodes
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
@ -828,6 +641,7 @@ items:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- configmaps
|
||||
- endpoints
|
||||
- namespaces
|
||||
- secrets
|
||||
@ -1068,7 +882,6 @@ items:
|
||||
resources:
|
||||
- nodes
|
||||
verbs:
|
||||
- delete
|
||||
- patch
|
||||
- update
|
||||
- apiGroups:
|
||||
@ -1146,6 +959,12 @@ items:
|
||||
- get
|
||||
- patch
|
||||
- update
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- serviceaccounts/token
|
||||
verbs:
|
||||
- create
|
||||
- apiGroups:
|
||||
- storage.k8s.io
|
||||
resources:
|
||||
@ -1312,6 +1131,16 @@ items:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- persistentvolumeclaims
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- aggregationRule:
|
||||
clusterRoleSelectors:
|
||||
- matchLabels:
|
||||
@ -1324,6 +1153,7 @@ items:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
kubernetes.io/bootstrapping: rbac-defaults
|
||||
rbac.authorization.k8s.io/aggregate-to-edit: "true"
|
||||
name: view
|
||||
rules: null
|
||||
kind: List
|
||||
|
6
vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/rbac.go
generated
vendored
6
vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/rbac.go
generated
vendored
@ -21,7 +21,7 @@ import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/klog"
|
||||
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
@ -81,7 +81,7 @@ func (r *RBACAuthorizer) Authorize(requestAttributes authorizer.Attributes) (aut
|
||||
|
||||
// Build a detailed log of the denial.
|
||||
// Make the whole block conditional so we don't do a lot of string-building we won't use.
|
||||
if glog.V(5) {
|
||||
if klog.V(5) {
|
||||
var operation string
|
||||
if requestAttributes.IsResourceRequest() {
|
||||
b := &bytes.Buffer{}
|
||||
@ -115,7 +115,7 @@ func (r *RBACAuthorizer) Authorize(requestAttributes authorizer.Attributes) (aut
|
||||
scope = "cluster-wide"
|
||||
}
|
||||
|
||||
glog.Infof("RBAC DENY: user %q groups %q cannot %s %s", requestAttributes.GetUser().GetName(), requestAttributes.GetUser().GetGroups(), operation, scope)
|
||||
klog.Infof("RBAC DENY: user %q groups %q cannot %s %s", requestAttributes.GetUser().GetName(), requestAttributes.GetUser().GetGroups(), operation, scope)
|
||||
}
|
||||
|
||||
reason := ""
|
||||
|
Reference in New Issue
Block a user