mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 03:41:45 +00:00
Merge pull request #19088 from smarterclayton/separate_service_account
Auto commit by PR queue bot
This commit is contained in:
commit
cd097e3f86
@ -41,13 +41,16 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/api/validation"
|
"k8s.io/kubernetes/pkg/api/validation"
|
||||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||||
"k8s.io/kubernetes/pkg/apiserver"
|
"k8s.io/kubernetes/pkg/apiserver"
|
||||||
|
"k8s.io/kubernetes/pkg/apiserver/authenticator"
|
||||||
"k8s.io/kubernetes/pkg/capabilities"
|
"k8s.io/kubernetes/pkg/capabilities"
|
||||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||||
"k8s.io/kubernetes/pkg/cloudprovider"
|
"k8s.io/kubernetes/pkg/cloudprovider"
|
||||||
|
serviceaccountcontroller "k8s.io/kubernetes/pkg/controller/serviceaccount"
|
||||||
"k8s.io/kubernetes/pkg/genericapiserver"
|
"k8s.io/kubernetes/pkg/genericapiserver"
|
||||||
kubeletclient "k8s.io/kubernetes/pkg/kubelet/client"
|
kubeletclient "k8s.io/kubernetes/pkg/kubelet/client"
|
||||||
"k8s.io/kubernetes/pkg/master"
|
"k8s.io/kubernetes/pkg/master"
|
||||||
"k8s.io/kubernetes/pkg/master/ports"
|
"k8s.io/kubernetes/pkg/master/ports"
|
||||||
|
"k8s.io/kubernetes/pkg/serviceaccount"
|
||||||
"k8s.io/kubernetes/pkg/storage"
|
"k8s.io/kubernetes/pkg/storage"
|
||||||
etcdstorage "k8s.io/kubernetes/pkg/storage/etcd"
|
etcdstorage "k8s.io/kubernetes/pkg/storage/etcd"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
"k8s.io/kubernetes/pkg/util"
|
||||||
@ -485,24 +488,32 @@ func (s *APIServer) Run(_ []string) error {
|
|||||||
|
|
||||||
// Default to the private server key for service account token signing
|
// Default to the private server key for service account token signing
|
||||||
if s.ServiceAccountKeyFile == "" && s.TLSPrivateKeyFile != "" {
|
if s.ServiceAccountKeyFile == "" && s.TLSPrivateKeyFile != "" {
|
||||||
if apiserver.IsValidServiceAccountKeyFile(s.TLSPrivateKeyFile) {
|
if authenticator.IsValidServiceAccountKeyFile(s.TLSPrivateKeyFile) {
|
||||||
s.ServiceAccountKeyFile = s.TLSPrivateKeyFile
|
s.ServiceAccountKeyFile = s.TLSPrivateKeyFile
|
||||||
} else {
|
} else {
|
||||||
glog.Warning("No RSA key provided, service account token authentication disabled")
|
glog.Warning("No RSA key provided, service account token authentication disabled")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
authenticator, err := apiserver.NewAuthenticator(apiserver.AuthenticatorConfig{
|
|
||||||
BasicAuthFile: s.BasicAuthFile,
|
var serviceAccountGetter serviceaccount.ServiceAccountTokenGetter
|
||||||
ClientCAFile: s.ClientCAFile,
|
if s.ServiceAccountLookup {
|
||||||
TokenAuthFile: s.TokenAuthFile,
|
// If we need to look up service accounts and tokens,
|
||||||
OIDCIssuerURL: s.OIDCIssuerURL,
|
// go directly to etcd to avoid recursive auth insanity
|
||||||
OIDCClientID: s.OIDCClientID,
|
serviceAccountGetter = serviceaccountcontroller.NewGetterFromStorageInterface(etcdStorage)
|
||||||
OIDCCAFile: s.OIDCCAFile,
|
}
|
||||||
OIDCUsernameClaim: s.OIDCUsernameClaim,
|
|
||||||
ServiceAccountKeyFile: s.ServiceAccountKeyFile,
|
authenticator, err := authenticator.New(authenticator.AuthenticatorConfig{
|
||||||
ServiceAccountLookup: s.ServiceAccountLookup,
|
BasicAuthFile: s.BasicAuthFile,
|
||||||
Storage: etcdStorage,
|
ClientCAFile: s.ClientCAFile,
|
||||||
KeystoneURL: s.KeystoneURL,
|
TokenAuthFile: s.TokenAuthFile,
|
||||||
|
OIDCIssuerURL: s.OIDCIssuerURL,
|
||||||
|
OIDCClientID: s.OIDCClientID,
|
||||||
|
OIDCCAFile: s.OIDCCAFile,
|
||||||
|
OIDCUsernameClaim: s.OIDCUsernameClaim,
|
||||||
|
ServiceAccountKeyFile: s.ServiceAccountKeyFile,
|
||||||
|
ServiceAccountLookup: s.ServiceAccountLookup,
|
||||||
|
ServiceAccountTokenGetter: serviceAccountGetter,
|
||||||
|
KeystoneURL: s.KeystoneURL,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -51,9 +51,10 @@ import (
|
|||||||
resourcequotacontroller "k8s.io/kubernetes/pkg/controller/resourcequota"
|
resourcequotacontroller "k8s.io/kubernetes/pkg/controller/resourcequota"
|
||||||
routecontroller "k8s.io/kubernetes/pkg/controller/route"
|
routecontroller "k8s.io/kubernetes/pkg/controller/route"
|
||||||
servicecontroller "k8s.io/kubernetes/pkg/controller/service"
|
servicecontroller "k8s.io/kubernetes/pkg/controller/service"
|
||||||
"k8s.io/kubernetes/pkg/controller/serviceaccount"
|
serviceaccountcontroller "k8s.io/kubernetes/pkg/controller/serviceaccount"
|
||||||
"k8s.io/kubernetes/pkg/healthz"
|
"k8s.io/kubernetes/pkg/healthz"
|
||||||
"k8s.io/kubernetes/pkg/master/ports"
|
"k8s.io/kubernetes/pkg/master/ports"
|
||||||
|
"k8s.io/kubernetes/pkg/serviceaccount"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
"k8s.io/kubernetes/pkg/util"
|
||||||
"k8s.io/kubernetes/pkg/util/wait"
|
"k8s.io/kubernetes/pkg/util/wait"
|
||||||
|
|
||||||
@ -433,9 +434,9 @@ func (s *CMServer) Run(_ []string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Errorf("Error reading key for service account token controller: %v", err)
|
glog.Errorf("Error reading key for service account token controller: %v", err)
|
||||||
} else {
|
} else {
|
||||||
serviceaccount.NewTokensController(
|
serviceaccountcontroller.NewTokensController(
|
||||||
clientForUserAgentOrDie(*kubeconfig, "tokens-controller"),
|
clientForUserAgentOrDie(*kubeconfig, "tokens-controller"),
|
||||||
serviceaccount.TokensControllerOptions{
|
serviceaccountcontroller.TokensControllerOptions{
|
||||||
TokenGenerator: serviceaccount.JWTTokenGenerator(privateKey),
|
TokenGenerator: serviceaccount.JWTTokenGenerator(privateKey),
|
||||||
RootCA: rootCA,
|
RootCA: rootCA,
|
||||||
},
|
},
|
||||||
@ -443,9 +444,9 @@ func (s *CMServer) Run(_ []string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
serviceaccount.NewServiceAccountsController(
|
serviceaccountcontroller.NewServiceAccountsController(
|
||||||
clientForUserAgentOrDie(*kubeconfig, "service-account-controller"),
|
clientForUserAgentOrDie(*kubeconfig, "service-account-controller"),
|
||||||
serviceaccount.DefaultServiceAccountsControllerOptions(),
|
serviceaccountcontroller.DefaultServiceAccountsControllerOptions(),
|
||||||
).Run()
|
).Run()
|
||||||
|
|
||||||
select {}
|
select {}
|
||||||
|
@ -43,8 +43,9 @@ import (
|
|||||||
resourcequotacontroller "k8s.io/kubernetes/pkg/controller/resourcequota"
|
resourcequotacontroller "k8s.io/kubernetes/pkg/controller/resourcequota"
|
||||||
routecontroller "k8s.io/kubernetes/pkg/controller/route"
|
routecontroller "k8s.io/kubernetes/pkg/controller/route"
|
||||||
servicecontroller "k8s.io/kubernetes/pkg/controller/service"
|
servicecontroller "k8s.io/kubernetes/pkg/controller/service"
|
||||||
"k8s.io/kubernetes/pkg/controller/serviceaccount"
|
serviceaccountcontroller "k8s.io/kubernetes/pkg/controller/serviceaccount"
|
||||||
"k8s.io/kubernetes/pkg/healthz"
|
"k8s.io/kubernetes/pkg/healthz"
|
||||||
|
"k8s.io/kubernetes/pkg/serviceaccount"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
"k8s.io/kubernetes/pkg/util"
|
||||||
|
|
||||||
"k8s.io/kubernetes/contrib/mesos/pkg/profile"
|
"k8s.io/kubernetes/contrib/mesos/pkg/profile"
|
||||||
@ -209,9 +210,9 @@ func (s *CMServer) Run(_ []string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Errorf("Error reading key for service account token controller: %v", err)
|
glog.Errorf("Error reading key for service account token controller: %v", err)
|
||||||
} else {
|
} else {
|
||||||
serviceaccount.NewTokensController(
|
serviceaccountcontroller.NewTokensController(
|
||||||
kubeClient,
|
kubeClient,
|
||||||
serviceaccount.TokensControllerOptions{
|
serviceaccountcontroller.TokensControllerOptions{
|
||||||
TokenGenerator: serviceaccount.JWTTokenGenerator(privateKey),
|
TokenGenerator: serviceaccount.JWTTokenGenerator(privateKey),
|
||||||
RootCA: rootCA,
|
RootCA: rootCA,
|
||||||
},
|
},
|
||||||
@ -219,9 +220,9 @@ func (s *CMServer) Run(_ []string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
serviceaccount.NewServiceAccountsController(
|
serviceaccountcontroller.NewServiceAccountsController(
|
||||||
kubeClient,
|
kubeClient,
|
||||||
serviceaccount.DefaultServiceAccountsControllerOptions(),
|
serviceaccountcontroller.DefaultServiceAccountsControllerOptions(),
|
||||||
).Run()
|
).Run()
|
||||||
|
|
||||||
select {}
|
select {}
|
||||||
|
@ -14,15 +14,14 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package apiserver
|
package authenticator
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/auth/authenticator"
|
"k8s.io/kubernetes/pkg/auth/authenticator"
|
||||||
"k8s.io/kubernetes/pkg/auth/authenticator/bearertoken"
|
"k8s.io/kubernetes/pkg/auth/authenticator/bearertoken"
|
||||||
"k8s.io/kubernetes/pkg/controller/serviceaccount"
|
"k8s.io/kubernetes/pkg/serviceaccount"
|
||||||
"k8s.io/kubernetes/pkg/storage"
|
|
||||||
"k8s.io/kubernetes/pkg/util"
|
"k8s.io/kubernetes/pkg/util"
|
||||||
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/password/passwordfile"
|
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/password/passwordfile"
|
||||||
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/basicauth"
|
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/basicauth"
|
||||||
@ -34,21 +33,22 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type AuthenticatorConfig struct {
|
type AuthenticatorConfig struct {
|
||||||
BasicAuthFile string
|
BasicAuthFile string
|
||||||
ClientCAFile string
|
ClientCAFile string
|
||||||
TokenAuthFile string
|
TokenAuthFile string
|
||||||
OIDCIssuerURL string
|
OIDCIssuerURL string
|
||||||
OIDCClientID string
|
OIDCClientID string
|
||||||
OIDCCAFile string
|
OIDCCAFile string
|
||||||
OIDCUsernameClaim string
|
OIDCUsernameClaim string
|
||||||
ServiceAccountKeyFile string
|
ServiceAccountKeyFile string
|
||||||
ServiceAccountLookup bool
|
ServiceAccountLookup bool
|
||||||
Storage storage.Interface
|
ServiceAccountTokenGetter serviceaccount.ServiceAccountTokenGetter
|
||||||
KeystoneURL string
|
KeystoneURL string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewAuthenticator returns an authenticator.Request or an error
|
// New returns an authenticator.Request or an error that supports the standard
|
||||||
func NewAuthenticator(config AuthenticatorConfig) (authenticator.Request, error) {
|
// Kubernetes authentication mechanisms.
|
||||||
|
func New(config AuthenticatorConfig) (authenticator.Request, error) {
|
||||||
var authenticators []authenticator.Request
|
var authenticators []authenticator.Request
|
||||||
|
|
||||||
if len(config.BasicAuthFile) > 0 {
|
if len(config.BasicAuthFile) > 0 {
|
||||||
@ -84,7 +84,7 @@ func NewAuthenticator(config AuthenticatorConfig) (authenticator.Request, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(config.ServiceAccountKeyFile) > 0 {
|
if len(config.ServiceAccountKeyFile) > 0 {
|
||||||
serviceAccountAuth, err := newServiceAccountAuthenticator(config.ServiceAccountKeyFile, config.ServiceAccountLookup, config.Storage)
|
serviceAccountAuth, err := newServiceAccountAuthenticator(config.ServiceAccountKeyFile, config.ServiceAccountLookup, config.ServiceAccountTokenGetter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -146,19 +146,12 @@ func newAuthenticatorFromOIDCIssuerURL(issuerURL, clientID, caFile, usernameClai
|
|||||||
}
|
}
|
||||||
|
|
||||||
// newServiceAccountAuthenticator returns an authenticator.Request or an error
|
// newServiceAccountAuthenticator returns an authenticator.Request or an error
|
||||||
func newServiceAccountAuthenticator(keyfile string, lookup bool, storage storage.Interface) (authenticator.Request, error) {
|
func newServiceAccountAuthenticator(keyfile string, lookup bool, serviceAccountGetter serviceaccount.ServiceAccountTokenGetter) (authenticator.Request, error) {
|
||||||
publicKey, err := serviceaccount.ReadPublicKey(keyfile)
|
publicKey, err := serviceaccount.ReadPublicKey(keyfile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var serviceAccountGetter serviceaccount.ServiceAccountTokenGetter
|
|
||||||
if lookup {
|
|
||||||
// If we need to look up service accounts and tokens,
|
|
||||||
// go directly to etcd to avoid recursive auth insanity
|
|
||||||
serviceAccountGetter = serviceaccount.NewGetterFromStorageInterface(storage)
|
|
||||||
}
|
|
||||||
|
|
||||||
tokenAuthenticator := serviceaccount.JWTTokenAuthenticator([]*rsa.PublicKey{publicKey}, lookup, serviceAccountGetter)
|
tokenAuthenticator := serviceaccount.JWTTokenAuthenticator([]*rsa.PublicKey{publicKey}, lookup, serviceAccountGetter)
|
||||||
return bearertoken.New(tokenAuthenticator), nil
|
return bearertoken.New(tokenAuthenticator), nil
|
||||||
}
|
}
|
@ -22,17 +22,12 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/registry/generic"
|
"k8s.io/kubernetes/pkg/registry/generic"
|
||||||
"k8s.io/kubernetes/pkg/registry/secret"
|
"k8s.io/kubernetes/pkg/registry/secret"
|
||||||
secretetcd "k8s.io/kubernetes/pkg/registry/secret/etcd"
|
secretetcd "k8s.io/kubernetes/pkg/registry/secret/etcd"
|
||||||
"k8s.io/kubernetes/pkg/registry/serviceaccount"
|
serviceaccountregistry "k8s.io/kubernetes/pkg/registry/serviceaccount"
|
||||||
serviceaccountetcd "k8s.io/kubernetes/pkg/registry/serviceaccount/etcd"
|
serviceaccountetcd "k8s.io/kubernetes/pkg/registry/serviceaccount/etcd"
|
||||||
|
"k8s.io/kubernetes/pkg/serviceaccount"
|
||||||
"k8s.io/kubernetes/pkg/storage"
|
"k8s.io/kubernetes/pkg/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ServiceAccountTokenGetter defines functions to retrieve a named service account and secret
|
|
||||||
type ServiceAccountTokenGetter interface {
|
|
||||||
GetServiceAccount(namespace, name string) (*api.ServiceAccount, error)
|
|
||||||
GetSecret(namespace, name string) (*api.Secret, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// clientGetter implements ServiceAccountTokenGetter using a client.Interface
|
// clientGetter implements ServiceAccountTokenGetter using a client.Interface
|
||||||
type clientGetter struct {
|
type clientGetter struct {
|
||||||
client client.Interface
|
client client.Interface
|
||||||
@ -42,7 +37,7 @@ type clientGetter struct {
|
|||||||
// uses the specified client to retrieve service accounts and secrets.
|
// uses the specified client to retrieve service accounts and secrets.
|
||||||
// The client should NOT authenticate using a service account token
|
// The client should NOT authenticate using a service account token
|
||||||
// the returned getter will be used to retrieve, or recursion will result.
|
// the returned getter will be used to retrieve, or recursion will result.
|
||||||
func NewGetterFromClient(c client.Interface) ServiceAccountTokenGetter {
|
func NewGetterFromClient(c client.Interface) serviceaccount.ServiceAccountTokenGetter {
|
||||||
return clientGetter{c}
|
return clientGetter{c}
|
||||||
}
|
}
|
||||||
func (c clientGetter) GetServiceAccount(namespace, name string) (*api.ServiceAccount, error) {
|
func (c clientGetter) GetServiceAccount(namespace, name string) (*api.ServiceAccount, error) {
|
||||||
@ -54,13 +49,13 @@ func (c clientGetter) GetSecret(namespace, name string) (*api.Secret, error) {
|
|||||||
|
|
||||||
// registryGetter implements ServiceAccountTokenGetter using a service account and secret registry
|
// registryGetter implements ServiceAccountTokenGetter using a service account and secret registry
|
||||||
type registryGetter struct {
|
type registryGetter struct {
|
||||||
serviceAccounts serviceaccount.Registry
|
serviceAccounts serviceaccountregistry.Registry
|
||||||
secrets secret.Registry
|
secrets secret.Registry
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewGetterFromRegistries returns a ServiceAccountTokenGetter that
|
// NewGetterFromRegistries returns a ServiceAccountTokenGetter that
|
||||||
// uses the specified registries to retrieve service accounts and secrets.
|
// uses the specified registries to retrieve service accounts and secrets.
|
||||||
func NewGetterFromRegistries(serviceAccounts serviceaccount.Registry, secrets secret.Registry) ServiceAccountTokenGetter {
|
func NewGetterFromRegistries(serviceAccounts serviceaccountregistry.Registry, secrets secret.Registry) serviceaccount.ServiceAccountTokenGetter {
|
||||||
return ®istryGetter{serviceAccounts, secrets}
|
return ®istryGetter{serviceAccounts, secrets}
|
||||||
}
|
}
|
||||||
func (r *registryGetter) GetServiceAccount(namespace, name string) (*api.ServiceAccount, error) {
|
func (r *registryGetter) GetServiceAccount(namespace, name string) (*api.ServiceAccount, error) {
|
||||||
@ -74,9 +69,9 @@ func (r *registryGetter) GetSecret(namespace, name string) (*api.Secret, error)
|
|||||||
|
|
||||||
// NewGetterFromStorageInterface returns a ServiceAccountTokenGetter that
|
// NewGetterFromStorageInterface returns a ServiceAccountTokenGetter that
|
||||||
// uses the specified storage to retrieve service accounts and secrets.
|
// uses the specified storage to retrieve service accounts and secrets.
|
||||||
func NewGetterFromStorageInterface(s storage.Interface) ServiceAccountTokenGetter {
|
func NewGetterFromStorageInterface(s storage.Interface) serviceaccount.ServiceAccountTokenGetter {
|
||||||
return NewGetterFromRegistries(
|
return NewGetterFromRegistries(
|
||||||
serviceaccount.NewRegistry(serviceaccountetcd.NewREST(s, generic.UndecoratedStorage)),
|
serviceaccountregistry.NewRegistry(serviceaccountetcd.NewREST(s, generic.UndecoratedStorage)),
|
||||||
secret.NewRegistry(secretetcd.NewREST(s, generic.UndecoratedStorage)),
|
secret.NewRegistry(secretetcd.NewREST(s, generic.UndecoratedStorage)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/fields"
|
"k8s.io/kubernetes/pkg/fields"
|
||||||
"k8s.io/kubernetes/pkg/registry/secret"
|
"k8s.io/kubernetes/pkg/registry/secret"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
|
"k8s.io/kubernetes/pkg/serviceaccount"
|
||||||
"k8s.io/kubernetes/pkg/util/sets"
|
"k8s.io/kubernetes/pkg/util/sets"
|
||||||
"k8s.io/kubernetes/pkg/util/wait"
|
"k8s.io/kubernetes/pkg/util/wait"
|
||||||
"k8s.io/kubernetes/pkg/watch"
|
"k8s.io/kubernetes/pkg/watch"
|
||||||
@ -40,7 +41,7 @@ const NumServiceAccountRemoveReferenceRetries = 10
|
|||||||
// TokensControllerOptions contains options for the TokensController
|
// TokensControllerOptions contains options for the TokensController
|
||||||
type TokensControllerOptions struct {
|
type TokensControllerOptions struct {
|
||||||
// TokenGenerator is the generator to use to create new tokens
|
// TokenGenerator is the generator to use to create new tokens
|
||||||
TokenGenerator TokenGenerator
|
TokenGenerator serviceaccount.TokenGenerator
|
||||||
// ServiceAccountResync is the time.Duration at which to fully re-list service accounts.
|
// ServiceAccountResync is the time.Duration at which to fully re-list service accounts.
|
||||||
// If zero, re-list will be delayed as long as possible
|
// If zero, re-list will be delayed as long as possible
|
||||||
ServiceAccountResync time.Duration
|
ServiceAccountResync time.Duration
|
||||||
@ -111,7 +112,7 @@ type TokensController struct {
|
|||||||
stopChan chan struct{}
|
stopChan chan struct{}
|
||||||
|
|
||||||
client client.Interface
|
client client.Interface
|
||||||
token TokenGenerator
|
token serviceaccount.TokenGenerator
|
||||||
|
|
||||||
rootCA []byte
|
rootCA []byte
|
||||||
|
|
||||||
@ -451,7 +452,7 @@ func (e *TokensController) getServiceAccount(secret *api.Secret, fetchOnCacheMis
|
|||||||
for _, obj := range namespaceAccounts {
|
for _, obj := range namespaceAccounts {
|
||||||
serviceAccount := obj.(*api.ServiceAccount)
|
serviceAccount := obj.(*api.ServiceAccount)
|
||||||
|
|
||||||
if IsServiceAccountToken(secret, serviceAccount) {
|
if serviceaccount.IsServiceAccountToken(secret, serviceAccount) {
|
||||||
return serviceAccount, nil
|
return serviceAccount, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -465,7 +466,7 @@ func (e *TokensController) getServiceAccount(secret *api.Secret, fetchOnCacheMis
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if IsServiceAccountToken(secret, serviceAccount) {
|
if serviceaccount.IsServiceAccountToken(secret, serviceAccount) {
|
||||||
return serviceAccount, nil
|
return serviceAccount, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -486,7 +487,7 @@ func (e *TokensController) listTokenSecrets(serviceAccount *api.ServiceAccount)
|
|||||||
for _, obj := range namespaceSecrets {
|
for _, obj := range namespaceSecrets {
|
||||||
secret := obj.(*api.Secret)
|
secret := obj.(*api.Secret)
|
||||||
|
|
||||||
if IsServiceAccountToken(secret, serviceAccount) {
|
if serviceaccount.IsServiceAccountToken(secret, serviceAccount) {
|
||||||
items = append(items, secret)
|
items = append(items, secret)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,12 @@ const (
|
|||||||
NamespaceClaim = "kubernetes.io/serviceaccount/namespace"
|
NamespaceClaim = "kubernetes.io/serviceaccount/namespace"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ServiceAccountTokenGetter defines functions to retrieve a named service account and secret
|
||||||
|
type ServiceAccountTokenGetter interface {
|
||||||
|
GetServiceAccount(namespace, name string) (*api.ServiceAccount, error)
|
||||||
|
GetSecret(namespace, name string) (*api.Secret, error)
|
||||||
|
}
|
||||||
|
|
||||||
type TokenGenerator interface {
|
type TokenGenerator interface {
|
||||||
// GenerateToken generates a token which will identify the given ServiceAccount.
|
// GenerateToken generates a token which will identify the given ServiceAccount.
|
||||||
// The returned token will be stored in the given (and yet-unpersisted) Secret.
|
// The returned token will be stored in the given (and yet-unpersisted) Secret.
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package serviceaccount
|
package serviceaccount_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
@ -24,9 +24,12 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/dgrijalva/jwt-go"
|
"github.com/dgrijalva/jwt-go"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||||
"k8s.io/kubernetes/pkg/client/unversioned/testclient"
|
"k8s.io/kubernetes/pkg/client/unversioned/testclient"
|
||||||
|
serviceaccountcontroller "k8s.io/kubernetes/pkg/controller/serviceaccount"
|
||||||
|
"k8s.io/kubernetes/pkg/serviceaccount"
|
||||||
)
|
)
|
||||||
|
|
||||||
const otherPublicKey = `-----BEGIN PUBLIC KEY-----
|
const otherPublicKey = `-----BEGIN PUBLIC KEY-----
|
||||||
@ -100,7 +103,7 @@ func TestReadPrivateKey(t *testing.T) {
|
|||||||
t.Fatalf("error creating tmpfile: %v", err)
|
t.Fatalf("error creating tmpfile: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := ReadPrivateKey(f.Name()); err != nil {
|
if _, err := serviceaccount.ReadPrivateKey(f.Name()); err != nil {
|
||||||
t.Fatalf("error reading key: %v", err)
|
t.Fatalf("error reading key: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -116,7 +119,7 @@ func TestReadPublicKey(t *testing.T) {
|
|||||||
t.Fatalf("error creating tmpfile: %v", err)
|
t.Fatalf("error creating tmpfile: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := ReadPublicKey(f.Name()); err != nil {
|
if _, err := serviceaccount.ReadPublicKey(f.Name()); err != nil {
|
||||||
t.Fatalf("error reading key: %v", err)
|
t.Fatalf("error reading key: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -141,7 +144,7 @@ func TestTokenGenerateAndValidate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate the token
|
// Generate the token
|
||||||
generator := JWTTokenGenerator(getPrivateKey(privateKey))
|
generator := serviceaccount.JWTTokenGenerator(getPrivateKey(privateKey))
|
||||||
token, err := generator.GenerateToken(*serviceAccount, *secret)
|
token, err := generator.GenerateToken(*serviceAccount, *secret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error generating token: %v", err)
|
t.Fatalf("error generating token: %v", err)
|
||||||
@ -219,8 +222,8 @@ func TestTokenGenerateAndValidate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for k, tc := range testCases {
|
for k, tc := range testCases {
|
||||||
getter := NewGetterFromClient(tc.Client)
|
getter := serviceaccountcontroller.NewGetterFromClient(tc.Client)
|
||||||
authenticator := JWTTokenAuthenticator(tc.Keys, tc.Client != nil, getter)
|
authenticator := serviceaccount.JWTTokenAuthenticator(tc.Keys, tc.Client != nil, getter)
|
||||||
|
|
||||||
user, ok, err := authenticator.AuthenticateToken(token)
|
user, ok, err := authenticator.AuthenticateToken(token)
|
||||||
if (err != nil) != tc.ExpectedErr {
|
if (err != nil) != tc.ExpectedErr {
|
||||||
@ -253,8 +256,8 @@ func TestTokenGenerateAndValidate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMakeSplitUsername(t *testing.T) {
|
func TestMakeSplitUsername(t *testing.T) {
|
||||||
username := MakeUsername("ns", "name")
|
username := serviceaccount.MakeUsername("ns", "name")
|
||||||
ns, name, err := SplitUsername(username)
|
ns, name, err := serviceaccount.SplitUsername(username)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error %v", err)
|
t.Errorf("Unexpected error %v", err)
|
||||||
}
|
}
|
||||||
@ -264,7 +267,7 @@ func TestMakeSplitUsername(t *testing.T) {
|
|||||||
|
|
||||||
invalid := []string{"test", "system:serviceaccount", "system:serviceaccount:", "system:serviceaccount:ns", "system:serviceaccount:ns:name:extra"}
|
invalid := []string{"test", "system:serviceaccount", "system:serviceaccount:", "system:serviceaccount:ns", "system:serviceaccount:ns:name:extra"}
|
||||||
for _, n := range invalid {
|
for _, n := range invalid {
|
||||||
_, _, err := SplitUsername("test")
|
_, _, err := serviceaccount.SplitUsername("test")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Expected error for %s", n)
|
t.Errorf("Expected error for %s", n)
|
||||||
}
|
}
|
@ -28,10 +28,10 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/api/errors"
|
"k8s.io/kubernetes/pkg/api/errors"
|
||||||
"k8s.io/kubernetes/pkg/client/cache"
|
"k8s.io/kubernetes/pkg/client/cache"
|
||||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||||
"k8s.io/kubernetes/pkg/controller/serviceaccount"
|
|
||||||
"k8s.io/kubernetes/pkg/fields"
|
"k8s.io/kubernetes/pkg/fields"
|
||||||
kubelet "k8s.io/kubernetes/pkg/kubelet/types"
|
kubelet "k8s.io/kubernetes/pkg/kubelet/types"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
|
"k8s.io/kubernetes/pkg/serviceaccount"
|
||||||
"k8s.io/kubernetes/pkg/util/sets"
|
"k8s.io/kubernetes/pkg/util/sets"
|
||||||
"k8s.io/kubernetes/pkg/watch"
|
"k8s.io/kubernetes/pkg/watch"
|
||||||
)
|
)
|
||||||
|
@ -39,8 +39,9 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/auth/authorizer"
|
"k8s.io/kubernetes/pkg/auth/authorizer"
|
||||||
"k8s.io/kubernetes/pkg/auth/user"
|
"k8s.io/kubernetes/pkg/auth/user"
|
||||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||||
"k8s.io/kubernetes/pkg/controller/serviceaccount"
|
serviceaccountcontroller "k8s.io/kubernetes/pkg/controller/serviceaccount"
|
||||||
"k8s.io/kubernetes/pkg/master"
|
"k8s.io/kubernetes/pkg/master"
|
||||||
|
"k8s.io/kubernetes/pkg/serviceaccount"
|
||||||
"k8s.io/kubernetes/pkg/util/sets"
|
"k8s.io/kubernetes/pkg/util/sets"
|
||||||
"k8s.io/kubernetes/pkg/util/wait"
|
"k8s.io/kubernetes/pkg/util/wait"
|
||||||
serviceaccountadmission "k8s.io/kubernetes/plugin/pkg/admission/serviceaccount"
|
serviceaccountadmission "k8s.io/kubernetes/plugin/pkg/admission/serviceaccount"
|
||||||
@ -358,7 +359,7 @@ func startServiceAccountTestServer(t *testing.T) (*client.Client, client.Config,
|
|||||||
return nil, false, nil
|
return nil, false, nil
|
||||||
})
|
})
|
||||||
serviceAccountKey, _ := rsa.GenerateKey(rand.Reader, 2048)
|
serviceAccountKey, _ := rsa.GenerateKey(rand.Reader, 2048)
|
||||||
serviceAccountTokenGetter := serviceaccount.NewGetterFromClient(rootClient)
|
serviceAccountTokenGetter := serviceaccountcontroller.NewGetterFromClient(rootClient)
|
||||||
serviceAccountTokenAuth := serviceaccount.JWTTokenAuthenticator([]*rsa.PublicKey{&serviceAccountKey.PublicKey}, true, serviceAccountTokenGetter)
|
serviceAccountTokenAuth := serviceaccount.JWTTokenAuthenticator([]*rsa.PublicKey{&serviceAccountKey.PublicKey}, true, serviceAccountTokenGetter)
|
||||||
authenticator := union.New(
|
authenticator := union.New(
|
||||||
bearertoken.New(rootTokenAuth),
|
bearertoken.New(rootTokenAuth),
|
||||||
@ -410,9 +411,9 @@ func startServiceAccountTestServer(t *testing.T) (*client.Client, client.Config,
|
|||||||
m = master.New(masterConfig)
|
m = master.New(masterConfig)
|
||||||
|
|
||||||
// Start the service account and service account token controllers
|
// Start the service account and service account token controllers
|
||||||
tokenController := serviceaccount.NewTokensController(rootClient, serviceaccount.TokensControllerOptions{TokenGenerator: serviceaccount.JWTTokenGenerator(serviceAccountKey)})
|
tokenController := serviceaccountcontroller.NewTokensController(rootClient, serviceaccountcontroller.TokensControllerOptions{TokenGenerator: serviceaccount.JWTTokenGenerator(serviceAccountKey)})
|
||||||
tokenController.Run()
|
tokenController.Run()
|
||||||
serviceAccountController := serviceaccount.NewServiceAccountsController(rootClient, serviceaccount.DefaultServiceAccountsControllerOptions())
|
serviceAccountController := serviceaccountcontroller.NewServiceAccountsController(rootClient, serviceaccountcontroller.DefaultServiceAccountsControllerOptions())
|
||||||
serviceAccountController.Run()
|
serviceAccountController.Run()
|
||||||
// Start the admission plugin reflectors
|
// Start the admission plugin reflectors
|
||||||
serviceAccountAdmission.Run()
|
serviceAccountAdmission.Run()
|
||||||
|
Loading…
Reference in New Issue
Block a user