diff --git a/pkg/kubelet/token/BUILD b/pkg/kubelet/token/BUILD index 9f7d4db7caa..3980947498d 100644 --- a/pkg/kubelet/token/BUILD +++ b/pkg/kubelet/token/BUILD @@ -21,6 +21,7 @@ go_library( visibility = ["//visibility:public"], deps = [ "//staging/src/k8s.io/api/authentication/v1:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/clock:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library", diff --git a/pkg/kubelet/token/token_manager.go b/pkg/kubelet/token/token_manager.go index 76819ac72df..6c2a98713c2 100644 --- a/pkg/kubelet/token/token_manager.go +++ b/pkg/kubelet/token/token_manager.go @@ -25,6 +25,7 @@ import ( "time" authenticationv1 "k8s.io/api/authentication/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/clock" "k8s.io/apimachinery/pkg/util/wait" @@ -39,12 +40,35 @@ const ( // NewManager returns a new token manager. func NewManager(c clientset.Interface) *Manager { + // check whether the server supports token requests so we can give a more helpful error message + supported := false + once := &sync.Once{} + tokenRequestsSupported := func() bool { + once.Do(func() { + resources, err := c.Discovery().ServerResourcesForGroupVersion("v1") + if err != nil { + return + } + for _, resource := range resources.APIResources { + if resource.Name == "serviceaccounts/token" { + supported = true + return + } + } + }) + return supported + } + m := &Manager{ getToken: func(name, namespace string, tr *authenticationv1.TokenRequest) (*authenticationv1.TokenRequest, error) { if c == nil { return nil, errors.New("cannot use TokenManager when kubelet is in standalone mode") } - return c.CoreV1().ServiceAccounts(namespace).CreateToken(name, tr) + tokenRequest, err := c.CoreV1().ServiceAccounts(namespace).CreateToken(name, tr) + if apierrors.IsNotFound(err) && !tokenRequestsSupported() { + return nil, fmt.Errorf("the API server does not have TokenRequest endpoints enabled") + } + return tokenRequest, err }, cache: make(map[string]*authenticationv1.TokenRequest), clock: clock.RealClock{},