mirror of https://github.com/k3s-io/k3s
*: remove --insecure-allow-any-token option
e2e and integration tests have been switched over to the tokenfile authenticator instead. ```release-note The --insecure-allow-any-token flag has been removed from kube-apiserver. Users of the flag should use impersonation headers instead for debugging. ```pull/6/head
parent
ebf24c14a9
commit
e2f2ab67f2
|
@ -691,7 +691,6 @@ staging/src/k8s.io/apiserver/plugin/pkg/audit
|
||||||
staging/src/k8s.io/apiserver/plugin/pkg/audit/log
|
staging/src/k8s.io/apiserver/plugin/pkg/audit/log
|
||||||
staging/src/k8s.io/apiserver/plugin/pkg/authenticator/password/keystone
|
staging/src/k8s.io/apiserver/plugin/pkg/authenticator/password/keystone
|
||||||
staging/src/k8s.io/apiserver/plugin/pkg/authenticator/password/passwordfile
|
staging/src/k8s.io/apiserver/plugin/pkg/authenticator/password/passwordfile
|
||||||
staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/anytoken
|
|
||||||
staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc
|
staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc
|
||||||
staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc/testing
|
staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc/testing
|
||||||
staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/tokentest
|
staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/tokentest
|
||||||
|
|
|
@ -76,7 +76,6 @@ ENABLE_CLUSTER_DASHBOARD=${KUBE_ENABLE_CLUSTER_DASHBOARD:-false}
|
||||||
ENABLE_APISERVER_BASIC_AUDIT=${ENABLE_APISERVER_BASIC_AUDIT:-false}
|
ENABLE_APISERVER_BASIC_AUDIT=${ENABLE_APISERVER_BASIC_AUDIT:-false}
|
||||||
|
|
||||||
# RBAC Mode options
|
# RBAC Mode options
|
||||||
ALLOW_ANY_TOKEN=${ALLOW_ANY_TOKEN:-false}
|
|
||||||
ENABLE_RBAC=${ENABLE_RBAC:-false}
|
ENABLE_RBAC=${ENABLE_RBAC:-false}
|
||||||
AUTHORIZATION_MODE=${AUTHORIZATION_MODE:-""}
|
AUTHORIZATION_MODE=${AUTHORIZATION_MODE:-""}
|
||||||
KUBECONFIG_TOKEN=${KUBECONFIG_TOKEN:-""}
|
KUBECONFIG_TOKEN=${KUBECONFIG_TOKEN:-""}
|
||||||
|
@ -434,11 +433,6 @@ function start_apiserver {
|
||||||
swagger_arg="--enable-swagger-ui=true "
|
swagger_arg="--enable-swagger-ui=true "
|
||||||
fi
|
fi
|
||||||
|
|
||||||
anytoken_arg=""
|
|
||||||
if [[ "${ALLOW_ANY_TOKEN}" = true ]]; then
|
|
||||||
anytoken_arg="--insecure-allow-any-token "
|
|
||||||
KUBECONFIG_TOKEN="${KUBECONFIG_TOKEN:-system:admin/system:masters}"
|
|
||||||
fi
|
|
||||||
authorizer_arg=""
|
authorizer_arg=""
|
||||||
if [[ "${ENABLE_RBAC}" = true ]]; then
|
if [[ "${ENABLE_RBAC}" = true ]]; then
|
||||||
authorizer_arg="--authorization-mode=RBAC "
|
authorizer_arg="--authorization-mode=RBAC "
|
||||||
|
@ -498,7 +492,7 @@ function start_apiserver {
|
||||||
|
|
||||||
|
|
||||||
APISERVER_LOG=${LOG_DIR}/kube-apiserver.log
|
APISERVER_LOG=${LOG_DIR}/kube-apiserver.log
|
||||||
${CONTROLPLANE_SUDO} "${GO_OUT}/hyperkube" apiserver ${swagger_arg} ${audit_arg} ${anytoken_arg} ${authorizer_arg} ${priv_arg} ${runtime_config}\
|
${CONTROLPLANE_SUDO} "${GO_OUT}/hyperkube" apiserver ${swagger_arg} ${audit_arg} ${authorizer_arg} ${priv_arg} ${runtime_config}\
|
||||||
${advertise_address} \
|
${advertise_address} \
|
||||||
--v=${LOG_LEVEL} \
|
--v=${LOG_LEVEL} \
|
||||||
--vmodule="${LOG_SPEC}" \
|
--vmodule="${LOG_SPEC}" \
|
||||||
|
@ -548,17 +542,7 @@ function start_apiserver {
|
||||||
kube::util::write_client_kubeconfig "${CONTROLPLANE_SUDO}" "${CERT_DIR}" "${ROOT_CA_FILE}" "${API_HOST}" "${API_SECURE_PORT}" scheduler
|
kube::util::write_client_kubeconfig "${CONTROLPLANE_SUDO}" "${CERT_DIR}" "${ROOT_CA_FILE}" "${API_HOST}" "${API_SECURE_PORT}" scheduler
|
||||||
|
|
||||||
if [[ -z "${AUTH_ARGS}" ]]; then
|
if [[ -z "${AUTH_ARGS}" ]]; then
|
||||||
if [[ "${ALLOW_ANY_TOKEN}" = true ]]; then
|
AUTH_ARGS="--client-key=${CERT_DIR}/client-admin.key --client-certificate=${CERT_DIR}/client-admin.crt"
|
||||||
# use token authentication
|
|
||||||
if [[ -n "${KUBECONFIG_TOKEN}" ]]; then
|
|
||||||
AUTH_ARGS="--token=${KUBECONFIG_TOKEN}"
|
|
||||||
else
|
|
||||||
AUTH_ARGS="--token=system:admin/system:masters"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
# default to the admin client cert/key
|
|
||||||
AUTH_ARGS="--client-key=${CERT_DIR}/client-admin.key --client-certificate=${CERT_DIR}/client-admin.crt"
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
${CONTROLPLANE_SUDO} cp "${CERT_DIR}/admin.kubeconfig" "${CERT_DIR}/admin-kube-aggregator.kubeconfig"
|
${CONTROLPLANE_SUDO} cp "${CERT_DIR}/admin.kubeconfig" "${CERT_DIR}/admin-kube-aggregator.kubeconfig"
|
||||||
|
|
|
@ -4132,8 +4132,9 @@ runTests() {
|
||||||
-s "http://127.0.0.1:${API_PORT}"
|
-s "http://127.0.0.1:${API_PORT}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# token defined in hack/testdata/auth-tokens.csv
|
||||||
kube_flags_with_token=(
|
kube_flags_with_token=(
|
||||||
-s "https://127.0.0.1:${SECURE_API_PORT}" --token=admin/system:masters --insecure-skip-tls-verify=true
|
-s "https://127.0.0.1:${SECURE_API_PORT}" --token=admin-token --insecure-skip-tls-verify=true
|
||||||
)
|
)
|
||||||
|
|
||||||
if [[ -z "${ALLOW_SKEW:-}" ]]; then
|
if [[ -z "${ALLOW_SKEW:-}" ]]; then
|
||||||
|
|
|
@ -51,7 +51,7 @@ function run_kube_apiserver() {
|
||||||
--storage-media-type="${KUBE_TEST_API_STORAGE_TYPE-}" \
|
--storage-media-type="${KUBE_TEST_API_STORAGE_TYPE-}" \
|
||||||
--cert-dir="${TMPDIR:-/tmp/}" \
|
--cert-dir="${TMPDIR:-/tmp/}" \
|
||||||
--service-cluster-ip-range="10.0.0.0/24" \
|
--service-cluster-ip-range="10.0.0.0/24" \
|
||||||
--insecure-allow-any-token 1>&2 &
|
--token-auth-file=hack/testdata/auth-tokens.csv 1>&2 &
|
||||||
APISERVER_PID=$!
|
APISERVER_PID=$!
|
||||||
|
|
||||||
kube::util::wait_for_url "http://127.0.0.1:${API_PORT}/healthz" "apiserver"
|
kube::util::wait_for_url "http://127.0.0.1:${API_PORT}/healthz" "apiserver"
|
||||||
|
|
|
@ -43,7 +43,7 @@ function run_federation_apiserver() {
|
||||||
--etcd-servers="http://${ETCD_HOST}:${ETCD_PORT}" \
|
--etcd-servers="http://${ETCD_HOST}:${ETCD_PORT}" \
|
||||||
--storage-media-type="${KUBE_TEST_API_STORAGE_TYPE-}" \
|
--storage-media-type="${KUBE_TEST_API_STORAGE_TYPE-}" \
|
||||||
--cert-dir="${TMPDIR:-/tmp/}" \
|
--cert-dir="${TMPDIR:-/tmp/}" \
|
||||||
--insecure-allow-any-token 1>&2 &
|
--token-auth-file=hack/testdata/auth-tokens.csv 1>&2 &
|
||||||
APISERVER_PID=$!
|
APISERVER_PID=$!
|
||||||
|
|
||||||
kube::util::wait_for_url "http://127.0.0.1:${API_PORT}/healthz" "apiserver"
|
kube::util::wait_for_url "http://127.0.0.1:${API_PORT}/healthz" "apiserver"
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
admin-token,admin,,"system:masters"
|
|
|
@ -348,7 +348,6 @@ include-extended-apis
|
||||||
initial-sync-timeout
|
initial-sync-timeout
|
||||||
input-base
|
input-base
|
||||||
input-dirs
|
input-dirs
|
||||||
insecure-allow-any-token
|
|
||||||
insecure-bind-address
|
insecure-bind-address
|
||||||
insecure-experimental-approve-all-kubelet-csrs-for-group
|
insecure-experimental-approve-all-kubelet-csrs-for-group
|
||||||
insecure-port
|
insecure-port
|
||||||
|
|
|
@ -27,7 +27,6 @@ go_library(
|
||||||
"//vendor/k8s.io/apiserver/plugin/pkg/authenticator/password/keystone:go_default_library",
|
"//vendor/k8s.io/apiserver/plugin/pkg/authenticator/password/keystone:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/plugin/pkg/authenticator/password/passwordfile:go_default_library",
|
"//vendor/k8s.io/apiserver/plugin/pkg/authenticator/password/passwordfile:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/plugin/pkg/authenticator/request/basicauth:go_default_library",
|
"//vendor/k8s.io/apiserver/plugin/pkg/authenticator/request/basicauth:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/plugin/pkg/authenticator/token/anytoken:go_default_library",
|
|
||||||
"//vendor/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc:go_default_library",
|
"//vendor/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook:go_default_library",
|
"//vendor/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/plugin/pkg/client/auth/gcp:go_default_library",
|
"//vendor/k8s.io/client-go/plugin/pkg/client/auth/gcp:go_default_library",
|
||||||
|
|
|
@ -34,7 +34,6 @@ import (
|
||||||
"k8s.io/apiserver/plugin/pkg/authenticator/password/keystone"
|
"k8s.io/apiserver/plugin/pkg/authenticator/password/keystone"
|
||||||
"k8s.io/apiserver/plugin/pkg/authenticator/password/passwordfile"
|
"k8s.io/apiserver/plugin/pkg/authenticator/password/passwordfile"
|
||||||
"k8s.io/apiserver/plugin/pkg/authenticator/request/basicauth"
|
"k8s.io/apiserver/plugin/pkg/authenticator/request/basicauth"
|
||||||
"k8s.io/apiserver/plugin/pkg/authenticator/token/anytoken"
|
|
||||||
"k8s.io/apiserver/plugin/pkg/authenticator/token/oidc"
|
"k8s.io/apiserver/plugin/pkg/authenticator/token/oidc"
|
||||||
"k8s.io/apiserver/plugin/pkg/authenticator/token/webhook"
|
"k8s.io/apiserver/plugin/pkg/authenticator/token/webhook"
|
||||||
certutil "k8s.io/client-go/util/cert"
|
certutil "k8s.io/client-go/util/cert"
|
||||||
|
@ -47,7 +46,6 @@ import (
|
||||||
|
|
||||||
type AuthenticatorConfig struct {
|
type AuthenticatorConfig struct {
|
||||||
Anonymous bool
|
Anonymous bool
|
||||||
AnyToken bool
|
|
||||||
BasicAuthFile string
|
BasicAuthFile string
|
||||||
BootstrapToken bool
|
BootstrapToken bool
|
||||||
ClientCAFile string
|
ClientCAFile string
|
||||||
|
@ -168,12 +166,6 @@ func (config AuthenticatorConfig) New() (authenticator.Request, *spec.SecurityDe
|
||||||
hasTokenAuth = true
|
hasTokenAuth = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// always add anytoken last, so that every other token authenticator gets to try first
|
|
||||||
if config.AnyToken {
|
|
||||||
authenticators = append(authenticators, bearertoken.New(anytoken.AnyTokenAuthenticator{}), websocket.NewProtocolAuthenticator(anytoken.AnyTokenAuthenticator{}))
|
|
||||||
hasTokenAuth = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if hasBasicAuth {
|
if hasBasicAuth {
|
||||||
securityDefinitions["HTTPBasic"] = &spec.SecurityScheme{
|
securityDefinitions["HTTPBasic"] = &spec.SecurityScheme{
|
||||||
SecuritySchemeProps: spec.SecuritySchemeProps{
|
SecuritySchemeProps: spec.SecuritySchemeProps{
|
||||||
|
|
|
@ -32,7 +32,6 @@ import (
|
||||||
|
|
||||||
type BuiltInAuthenticationOptions struct {
|
type BuiltInAuthenticationOptions struct {
|
||||||
Anonymous *AnonymousAuthenticationOptions
|
Anonymous *AnonymousAuthenticationOptions
|
||||||
AnyToken *AnyTokenAuthenticationOptions
|
|
||||||
BootstrapToken *BootstrapTokenAuthenticationOptions
|
BootstrapToken *BootstrapTokenAuthenticationOptions
|
||||||
ClientCert *genericoptions.ClientCertAuthenticationOptions
|
ClientCert *genericoptions.ClientCertAuthenticationOptions
|
||||||
Keystone *KeystoneAuthenticationOptions
|
Keystone *KeystoneAuthenticationOptions
|
||||||
|
@ -44,10 +43,6 @@ type BuiltInAuthenticationOptions struct {
|
||||||
WebHook *WebHookAuthenticationOptions
|
WebHook *WebHookAuthenticationOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
type AnyTokenAuthenticationOptions struct {
|
|
||||||
Allow bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type AnonymousAuthenticationOptions struct {
|
type AnonymousAuthenticationOptions struct {
|
||||||
Allow bool
|
Allow bool
|
||||||
}
|
}
|
||||||
|
@ -94,7 +89,6 @@ func NewBuiltInAuthenticationOptions() *BuiltInAuthenticationOptions {
|
||||||
func (s *BuiltInAuthenticationOptions) WithAll() *BuiltInAuthenticationOptions {
|
func (s *BuiltInAuthenticationOptions) WithAll() *BuiltInAuthenticationOptions {
|
||||||
return s.
|
return s.
|
||||||
WithAnyonymous().
|
WithAnyonymous().
|
||||||
WithAnyToken().
|
|
||||||
WithBootstrapToken().
|
WithBootstrapToken().
|
||||||
WithClientCert().
|
WithClientCert().
|
||||||
WithKeystone().
|
WithKeystone().
|
||||||
|
@ -111,11 +105,6 @@ func (s *BuiltInAuthenticationOptions) WithAnyonymous() *BuiltInAuthenticationOp
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *BuiltInAuthenticationOptions) WithAnyToken() *BuiltInAuthenticationOptions {
|
|
||||||
s.AnyToken = &AnyTokenAuthenticationOptions{}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *BuiltInAuthenticationOptions) WithBootstrapToken() *BuiltInAuthenticationOptions {
|
func (s *BuiltInAuthenticationOptions) WithBootstrapToken() *BuiltInAuthenticationOptions {
|
||||||
s.BootstrapToken = &BootstrapTokenAuthenticationOptions{}
|
s.BootstrapToken = &BootstrapTokenAuthenticationOptions{}
|
||||||
return s
|
return s
|
||||||
|
@ -182,13 +171,6 @@ func (s *BuiltInAuthenticationOptions) AddFlags(fs *pflag.FlagSet) {
|
||||||
"Anonymous requests have a username of system:anonymous, and a group name of system:unauthenticated.")
|
"Anonymous requests have a username of system:anonymous, and a group name of system:unauthenticated.")
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.AnyToken != nil {
|
|
||||||
fs.BoolVar(&s.AnyToken.Allow, "insecure-allow-any-token", s.AnyToken.Allow, ""+
|
|
||||||
"If set, your server will be INSECURE. Any token will be allowed and user information will be parsed "+
|
|
||||||
"from the token as `username/group1,group2`")
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if s.BootstrapToken != nil {
|
if s.BootstrapToken != nil {
|
||||||
fs.BoolVar(&s.BootstrapToken.Allow, "experimental-bootstrap-token-auth", s.BootstrapToken.Allow, ""+
|
fs.BoolVar(&s.BootstrapToken.Allow, "experimental-bootstrap-token-auth", s.BootstrapToken.Allow, ""+
|
||||||
"Enable to allow secrets of type 'bootstrap.kubernetes.io/token' in the 'kube-system' "+
|
"Enable to allow secrets of type 'bootstrap.kubernetes.io/token' in the 'kube-system' "+
|
||||||
|
@ -274,10 +256,6 @@ func (s *BuiltInAuthenticationOptions) ToAuthenticationConfig() authenticator.Au
|
||||||
ret.Anonymous = s.Anonymous.Allow
|
ret.Anonymous = s.Anonymous.Allow
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.AnyToken != nil {
|
|
||||||
ret.AnyToken = s.AnyToken.Allow
|
|
||||||
}
|
|
||||||
|
|
||||||
if s.BootstrapToken != nil {
|
if s.BootstrapToken != nil {
|
||||||
ret.BootstrapToken = s.BootstrapToken.Allow
|
ret.BootstrapToken = s.BootstrapToken.Allow
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
package(default_visibility = ["//visibility:public"])
|
|
||||||
|
|
||||||
licenses(["notice"])
|
|
||||||
|
|
||||||
load(
|
|
||||||
"@io_bazel_rules_go//go:def.bzl",
|
|
||||||
"go_library",
|
|
||||||
"go_test",
|
|
||||||
)
|
|
||||||
|
|
||||||
go_test(
|
|
||||||
name = "go_default_test",
|
|
||||||
srcs = ["anytoken_test.go"],
|
|
||||||
library = ":go_default_library",
|
|
||||||
tags = ["automanaged"],
|
|
||||||
deps = ["//vendor/k8s.io/apiserver/pkg/authentication/user:go_default_library"],
|
|
||||||
)
|
|
||||||
|
|
||||||
go_library(
|
|
||||||
name = "go_default_library",
|
|
||||||
srcs = ["anytoken.go"],
|
|
||||||
tags = ["automanaged"],
|
|
||||||
deps = ["//vendor/k8s.io/apiserver/pkg/authentication/user:go_default_library"],
|
|
||||||
)
|
|
|
@ -1,42 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2016 The Kubernetes Authors.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package anytoken
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"k8s.io/apiserver/pkg/authentication/user"
|
|
||||||
)
|
|
||||||
|
|
||||||
type AnyTokenAuthenticator struct{}
|
|
||||||
|
|
||||||
func (AnyTokenAuthenticator) AuthenticateToken(value string) (user.Info, bool, error) {
|
|
||||||
lastSlash := strings.LastIndex(value, "/")
|
|
||||||
if lastSlash == -1 {
|
|
||||||
return &user.DefaultInfo{Name: value}, true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
ret := &user.DefaultInfo{Name: value[:lastSlash]}
|
|
||||||
|
|
||||||
groupString := value[lastSlash+1:]
|
|
||||||
if len(groupString) == 0 {
|
|
||||||
return ret, true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
ret.Groups = strings.Split(groupString, ",")
|
|
||||||
return ret, true, nil
|
|
||||||
}
|
|
|
@ -1,71 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2016 The Kubernetes Authors.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package anytoken
|
|
||||||
|
|
||||||
import (
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"k8s.io/apiserver/pkg/authentication/user"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestAnyTokenAuthenticator(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
token string
|
|
||||||
|
|
||||||
expectedUser user.Info
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "user only",
|
|
||||||
token: "joe",
|
|
||||||
expectedUser: &user.DefaultInfo{Name: "joe"},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "user with slash",
|
|
||||||
token: "scheme/joe/",
|
|
||||||
expectedUser: &user.DefaultInfo{Name: "scheme/joe"},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "user with groups",
|
|
||||||
token: "joe/group1,group2",
|
|
||||||
expectedUser: &user.DefaultInfo{Name: "joe", Groups: []string{"group1", "group2"}},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "user with slash and groups",
|
|
||||||
token: "scheme/joe/group1,group2",
|
|
||||||
expectedUser: &user.DefaultInfo{Name: "scheme/joe", Groups: []string{"group1", "group2"}},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tc := range tests {
|
|
||||||
actualUser, _, _ := AnyTokenAuthenticator{}.AuthenticateToken(tc.token)
|
|
||||||
|
|
||||||
if len(actualUser.GetExtra()) != 0 {
|
|
||||||
t.Errorf("%q: got extra: %v", tc.name, actualUser.GetExtra())
|
|
||||||
}
|
|
||||||
if len(actualUser.GetUID()) != 0 {
|
|
||||||
t.Errorf("%q: got extra: %v", tc.name, actualUser.GetUID())
|
|
||||||
}
|
|
||||||
if e, a := tc.expectedUser.GetName(), actualUser.GetName(); e != a {
|
|
||||||
t.Errorf("%q: expected %v, got %v", tc.name, e, a)
|
|
||||||
}
|
|
||||||
if e, a := tc.expectedUser.GetGroups(), actualUser.GetGroups(); !reflect.DeepEqual(e, a) {
|
|
||||||
t.Errorf("%q: expected %v, got %v", tc.name, e, a)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -59,11 +59,11 @@ go_test(
|
||||||
"//vendor/k8s.io/apiserver/pkg/authentication/group:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/authentication/group:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/authentication/request/bearertoken:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/authentication/request/bearertoken:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/authentication/serviceaccount:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/authentication/serviceaccount:go_default_library",
|
||||||
|
"//vendor/k8s.io/apiserver/pkg/authentication/token/tokenfile:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/authentication/user: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/authorization/authorizer:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/authorization/authorizerfactory:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/authorization/authorizerfactory:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/registry/generic:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/registry/generic:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/plugin/pkg/authenticator/token/anytoken:go_default_library",
|
|
||||||
"//vendor/k8s.io/apiserver/plugin/pkg/authenticator/token/tokentest:go_default_library",
|
"//vendor/k8s.io/apiserver/plugin/pkg/authenticator/token/tokentest:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook:go_default_library",
|
"//vendor/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/rest:go_default_library",
|
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||||
|
|
|
@ -27,6 +27,9 @@ import (
|
||||||
"k8s.io/apimachinery/pkg/api/errors"
|
"k8s.io/apimachinery/pkg/api/errors"
|
||||||
"k8s.io/apimachinery/pkg/api/resource"
|
"k8s.io/apimachinery/pkg/api/resource"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apiserver/pkg/authentication/request/bearertoken"
|
||||||
|
"k8s.io/apiserver/pkg/authentication/token/tokenfile"
|
||||||
|
"k8s.io/apiserver/pkg/authentication/user"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/auth/nodeidentifier"
|
"k8s.io/kubernetes/pkg/auth/nodeidentifier"
|
||||||
|
@ -46,9 +49,24 @@ func TestNodeAuthorizer(t *testing.T) {
|
||||||
h.M.GenericAPIServer.Handler.ServeHTTP(w, req)
|
h.M.GenericAPIServer.Handler.ServeHTTP(w, req)
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Define credentials
|
||||||
|
tokenMaster = "master-token"
|
||||||
|
tokenNodeUnknown = "unknown-token"
|
||||||
|
tokenNode1 = "node1-token"
|
||||||
|
tokenNode2 = "node2-token"
|
||||||
|
)
|
||||||
|
|
||||||
|
authenticator := bearertoken.New(tokenfile.New(map[string]*user.DefaultInfo{
|
||||||
|
tokenMaster: {Name: "admin", Groups: []string{"system:masters"}},
|
||||||
|
tokenNodeUnknown: {Name: "unknown", Groups: []string{"system:nodes"}},
|
||||||
|
tokenNode1: {Name: "system:node:node1", Groups: []string{"system:nodes"}},
|
||||||
|
tokenNode2: {Name: "system:node:node2", Groups: []string{"system:nodes"}},
|
||||||
|
}))
|
||||||
|
|
||||||
// Build client config, clientset, and informers
|
// Build client config, clientset, and informers
|
||||||
clientConfig := &restclient.Config{Host: apiServer.URL, ContentConfig: restclient.ContentConfig{NegotiatedSerializer: api.Codecs}}
|
clientConfig := &restclient.Config{Host: apiServer.URL, ContentConfig: restclient.ContentConfig{NegotiatedSerializer: api.Codecs}}
|
||||||
superuserClient := clientsetForUser("admin/system:masters", clientConfig)
|
superuserClient := clientsetForToken(tokenMaster, clientConfig)
|
||||||
informerFactory := informers.NewSharedInformerFactory(superuserClient, time.Minute)
|
informerFactory := informers.NewSharedInformerFactory(superuserClient, time.Minute)
|
||||||
|
|
||||||
// Set up Node+RBAC authorizer
|
// Set up Node+RBAC authorizer
|
||||||
|
@ -71,7 +89,8 @@ func TestNodeAuthorizer(t *testing.T) {
|
||||||
|
|
||||||
// Start the server
|
// Start the server
|
||||||
masterConfig := framework.NewIntegrationTestMasterConfig()
|
masterConfig := framework.NewIntegrationTestMasterConfig()
|
||||||
masterConfig.GenericConfig.Authenticator = newFakeAuthenticator()
|
masterConfig.GenericConfig.Authenticator = authenticator
|
||||||
|
|
||||||
masterConfig.GenericConfig.Authorizer = nodeRBACAuthorizer
|
masterConfig.GenericConfig.Authorizer = nodeRBACAuthorizer
|
||||||
masterConfig.GenericConfig.AdmissionControl = nodeRestrictionAdmission
|
masterConfig.GenericConfig.AdmissionControl = nodeRestrictionAdmission
|
||||||
_, _, closeFn := framework.RunAMasterUsingServer(masterConfig, apiServer, h)
|
_, _, closeFn := framework.RunAMasterUsingServer(masterConfig, apiServer, h)
|
||||||
|
@ -206,9 +225,9 @@ func TestNodeAuthorizer(t *testing.T) {
|
||||||
return client.Core().Nodes().Delete("node2", nil)
|
return client.Core().Nodes().Delete("node2", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
nodeanonClient := clientsetForUser("unknown/system:nodes", clientConfig)
|
nodeanonClient := clientsetForToken(tokenNodeUnknown, clientConfig)
|
||||||
node1Client := clientsetForUser("system:node:node1/system:nodes", clientConfig)
|
node1Client := clientsetForToken(tokenNode1, clientConfig)
|
||||||
node2Client := clientsetForUser("system:node:node2/system:nodes", clientConfig)
|
node2Client := clientsetForToken(tokenNode2, clientConfig)
|
||||||
|
|
||||||
// all node requests from node1 and unknown node fail
|
// all node requests from node1 and unknown node fail
|
||||||
expectForbidden(t, getSecret(nodeanonClient))
|
expectForbidden(t, getSecret(nodeanonClient))
|
||||||
|
|
|
@ -31,11 +31,11 @@ import (
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/apimachinery/pkg/watch"
|
"k8s.io/apimachinery/pkg/watch"
|
||||||
"k8s.io/apiserver/pkg/authentication/authenticator"
|
|
||||||
"k8s.io/apiserver/pkg/authentication/request/bearertoken"
|
"k8s.io/apiserver/pkg/authentication/request/bearertoken"
|
||||||
|
"k8s.io/apiserver/pkg/authentication/token/tokenfile"
|
||||||
|
"k8s.io/apiserver/pkg/authentication/user"
|
||||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||||
"k8s.io/apiserver/pkg/registry/generic"
|
"k8s.io/apiserver/pkg/registry/generic"
|
||||||
"k8s.io/apiserver/plugin/pkg/authenticator/token/anytoken"
|
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
"k8s.io/client-go/transport"
|
"k8s.io/client-go/transport"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
@ -55,11 +55,7 @@ import (
|
||||||
"k8s.io/kubernetes/test/integration/framework"
|
"k8s.io/kubernetes/test/integration/framework"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newFakeAuthenticator() authenticator.Request {
|
func clientForToken(user string) *http.Client {
|
||||||
return bearertoken.New(anytoken.AnyTokenAuthenticator{})
|
|
||||||
}
|
|
||||||
|
|
||||||
func clientForUser(user string) *http.Client {
|
|
||||||
return &http.Client{
|
return &http.Client{
|
||||||
Transport: transport.NewBearerAuthRoundTripper(
|
Transport: transport.NewBearerAuthRoundTripper(
|
||||||
user,
|
user,
|
||||||
|
@ -68,7 +64,7 @@ func clientForUser(user string) *http.Client {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func clientsetForUser(user string, config *restclient.Config) clientset.Interface {
|
func clientsetForToken(user string, config *restclient.Config) clientset.Interface {
|
||||||
configCopy := *config
|
configCopy := *config
|
||||||
configCopy.BearerToken = user
|
configCopy.BearerToken = user
|
||||||
return clientset.NewForConfigOrDie(&configCopy)
|
return clientset.NewForConfigOrDie(&configCopy)
|
||||||
|
@ -137,8 +133,8 @@ func (b bootstrapRoles) bootstrap(client clientset.Interface) error {
|
||||||
|
|
||||||
// request is a test case which can.
|
// request is a test case which can.
|
||||||
type request struct {
|
type request struct {
|
||||||
// The username attempting to send the request.
|
// The bearer token sent as part of the request
|
||||||
user string
|
token string
|
||||||
|
|
||||||
// Resource metadata
|
// Resource metadata
|
||||||
verb string
|
verb string
|
||||||
|
@ -155,7 +151,7 @@ type request struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r request) String() string {
|
func (r request) String() string {
|
||||||
return fmt.Sprintf("%s %s %s", r.user, r.verb, r.resource)
|
return fmt.Sprintf("%s %s %s", r.token, r.verb, r.resource)
|
||||||
}
|
}
|
||||||
|
|
||||||
type statusCode int
|
type statusCode int
|
||||||
|
@ -414,14 +410,24 @@ func TestRBAC(t *testing.T) {
|
||||||
// Create an API Server.
|
// Create an API Server.
|
||||||
masterConfig := framework.NewIntegrationTestMasterConfig()
|
masterConfig := framework.NewIntegrationTestMasterConfig()
|
||||||
masterConfig.GenericConfig.Authorizer = newRBACAuthorizer(masterConfig)
|
masterConfig.GenericConfig.Authorizer = newRBACAuthorizer(masterConfig)
|
||||||
masterConfig.GenericConfig.Authenticator = newFakeAuthenticator()
|
masterConfig.GenericConfig.Authenticator = bearertoken.New(tokenfile.New(map[string]*user.DefaultInfo{
|
||||||
|
superUser: {Name: "admin", Groups: []string{"system:masters"}},
|
||||||
|
"any-rolebinding-writer": {Name: "any-rolebinding-writer"},
|
||||||
|
"any-rolebinding-writer-namespace": {Name: "any-rolebinding-writer-namespace"},
|
||||||
|
"bob": {Name: "bob"},
|
||||||
|
"job-writer": {Name: "job-writer"},
|
||||||
|
"job-writer-namespace": {Name: "job-writer-namespace"},
|
||||||
|
"nonescalating-rolebinding-writer": {Name: "nonescalating-rolebinding-writer"},
|
||||||
|
"pod-reader": {Name: "pod-reader"},
|
||||||
|
"user-with-no-permissions": {Name: "user-with-no-permissions"},
|
||||||
|
}))
|
||||||
_, s, closeFn := framework.RunAMaster(masterConfig)
|
_, s, closeFn := framework.RunAMaster(masterConfig)
|
||||||
defer closeFn()
|
defer closeFn()
|
||||||
|
|
||||||
clientConfig := &restclient.Config{Host: s.URL, ContentConfig: restclient.ContentConfig{NegotiatedSerializer: api.Codecs}}
|
clientConfig := &restclient.Config{Host: s.URL, ContentConfig: restclient.ContentConfig{NegotiatedSerializer: api.Codecs}}
|
||||||
|
|
||||||
// Bootstrap the API Server with the test case's initial roles.
|
// Bootstrap the API Server with the test case's initial roles.
|
||||||
if err := tc.bootstrapRoles.bootstrap(clientsetForUser(superUser, clientConfig)); err != nil {
|
if err := tc.bootstrapRoles.bootstrap(clientsetForToken(superUser, clientConfig)); err != nil {
|
||||||
t.Errorf("case %d: failed to apply initial roles: %v", i, err)
|
t.Errorf("case %d: failed to apply initial roles: %v", i, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -459,7 +465,7 @@ func TestRBAC(t *testing.T) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := clientForUser(r.user).Do(req)
|
resp, err := clientForToken(r.token).Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("case %d, req %d: failed to make request: %v", i, j, err)
|
t.Errorf("case %d, req %d: failed to make request: %v", i, j, err)
|
||||||
return
|
return
|
||||||
|
@ -506,7 +512,9 @@ func TestBootstrapping(t *testing.T) {
|
||||||
|
|
||||||
masterConfig := framework.NewIntegrationTestMasterConfig()
|
masterConfig := framework.NewIntegrationTestMasterConfig()
|
||||||
masterConfig.GenericConfig.Authorizer = newRBACAuthorizer(masterConfig)
|
masterConfig.GenericConfig.Authorizer = newRBACAuthorizer(masterConfig)
|
||||||
masterConfig.GenericConfig.Authenticator = newFakeAuthenticator()
|
masterConfig.GenericConfig.Authenticator = bearertoken.New(tokenfile.New(map[string]*user.DefaultInfo{
|
||||||
|
superUser: {Name: "admin", Groups: []string{"system:masters"}},
|
||||||
|
}))
|
||||||
_, s, closeFn := framework.RunAMaster(masterConfig)
|
_, s, closeFn := framework.RunAMaster(masterConfig)
|
||||||
defer closeFn()
|
defer closeFn()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue